现在的位置: 首页 > 综合 > 正文

WebKit事件派发

2013年01月08日 ⁄ 综合 ⁄ 共 6192字 ⁄ 字号 评论关闭

一般在一个网络应用系统中,都会一下几类事件: 网络事件, timer事件,以及设备事件,设备事件主要指鼠标,按键,以及paint等消息事件

webkit也不例外,小弟分析了一下32平台的实现,也无特殊之处

1. 设备事件

 设备事件仍然是通过win32平台的消息循环来派发,消息处理函数如下:

 

 

在32平台,webView仅仅需要实现消息处理函数,然后创建窗口,将其消息处理函数注册给目的窗口

2. 网络事件

 32平台是用的curl网络库,通过调用网络库的异步函数, webkit引擎与网络库的接口是ResouceHandler,发起网络请求,需要调用ResouceHandle::start(NetworkingContext* context),函数当网络事件到达,会调用如下函数:

 

  1. void didReceiveData(CFURLConnectionRef conn, CFDataRef data, CFIndex originalLength, const void* clientInfo)   
  2. {  
  3.     ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));  
  4.     const UInt8* bytes = CFDataGetBytePtr(data);  
  5.     CFIndex length = CFDataGetLength(data);  
  6.   
  7.     LOG(Network, "CFNet - didReceiveData(conn=%p, handle=%p, bytes=%d) (%s)", conn, handle, length, handle->firstRequest().url().string().utf8().data());  
  8.   
  9.     if (handle->client())  
  10.         handle->client()->didReceiveData(handle, (const char*)bytes, length, originalLength);  
  11. }  

 

3.timer事件

timer事件的处理类似于设备事件,timer的平台初始化函数:

 

  1. static void initializeOffScreenTimerWindow()  
  2. {  
  3.     if (timerWindowHandle)  
  4.         return;  
  5.       
  6.     WNDCLASSEX wcex;  
  7.     memset(&wcex, 0, sizeof(WNDCLASSEX));  
  8.     wcex.cbSize = sizeof(WNDCLASSEX);  
  9.     wcex.lpfnWndProc    = TimerWindowWndProc;  
  10.     wcex.hInstance      = WebCore::instanceHandle();  
  11.     wcex.lpszClassName  = kTimerWindowClassName;  
  12.     RegisterClassEx(&wcex);  
  13.   
  14.     timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,  
  15.        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, WebCore::instanceHandle(), 0);  
  16.     timerFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.TimerFired");  
  17. }  

 

timer的消息处理函数如下:

 

  1. LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3. #if PLATFORM(WIN)  
  4.     // Windows Media Player has a modal message loop that will deliver messages  
  5.     // to us at inappropriate times and we will crash if we handle them when  
  6.     // they are delivered. We repost all messages so that we will get to handle  
  7.     // them once the modal loop exits.  
  8.     if (PluginView::isCallingPlugin()) {  
  9.         PostMessage(hWnd, message, wParam, lParam);  
  10.         return 0;  
  11.     }  
  12. #endif  
  13.   
  14.     if (message == timerFiredMessage) {  
  15.         InterlockedExchange(&pendingTimers, 0);  
  16.         processingCustomTimerMessage = true;  
  17.         sharedTimerFiredFunction();  
  18.         processingCustomTimerMessage = false;  
  19.     } else if (message == WM_TIMER) {  
  20.         if (wParam == sharedTimerID) {  
  21.             KillTimer(timerWindowHandle, sharedTimerID);  
  22.             sharedTimerFiredFunction();  
  23.         } else if (wParam == endHighResTimerID) {  
  24.             KillTimer(timerWindowHandle, endHighResTimerID);  
  25.             highResTimerActive = false;  
  26.             timeEndPeriod(timerResolution);  
  27.         }  
  28.     } else  
  29.         return DefWindowProc(hWnd, message, wParam, lParam);  
  30.   
  31.     return 0;  
  32. }  

 

引擎内部事件如何处理?

通过分析发现引擎内部的异步是通过timer来实现,具体请参照前面讲解timer的文章

通过上面的分析发现,webkit没有将事件的处理统一起来,如果在引擎中自己有一个事件的处理者,或者将以上事件的处理统一起来,其架构看起来会不会更加优美?

一般在一个网络应用系统中,都会一下几类事件: 网络事件, timer事件,以及设备事件,设备事件主要指鼠标,按键,以及paint等消息事件

webkit也不例外,小弟分析了一下32平台的实现,也无特殊之处

1. 设备事件

 设备事件仍然是通过win32平台的消息循环来派发,消息处理函数如下:

 

 

在32平台,webView仅仅需要实现消息处理函数,然后创建窗口,将其消息处理函数注册给目的窗口

2. 网络事件

 32平台是用的curl网络库,通过调用网络库的异步函数, webkit引擎与网络库的接口是ResouceHandler,发起网络请求,需要调用ResouceHandle::start(NetworkingContext* context),函数当网络事件到达,会调用如下函数:

 

  1. void didReceiveData(CFURLConnectionRef conn, CFDataRef data, CFIndex originalLength, const void* clientInfo)   
  2. {  
  3.     ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));  
  4.     const UInt8* bytes = CFDataGetBytePtr(data);  
  5.     CFIndex length = CFDataGetLength(data);  
  6.   
  7.     LOG(Network, "CFNet - didReceiveData(conn=%p, handle=%p, bytes=%d) (%s)", conn, handle, length, handle->firstRequest().url().string().utf8().data());  
  8.   
  9.     if (handle->client())  
  10.         handle->client()->didReceiveData(handle, (const char*)bytes, length, originalLength);  
  11. }  

 

3.timer事件

timer事件的处理类似于设备事件,timer的平台初始化函数:

 

  1. static void initializeOffScreenTimerWindow()  
  2. {  
  3.     if (timerWindowHandle)  
  4.         return;  
  5.       
  6.     WNDCLASSEX wcex;  
  7.     memset(&wcex, 0, sizeof(WNDCLASSEX));  
  8.     wcex.cbSize = sizeof(WNDCLASSEX);  
  9.     wcex.lpfnWndProc    = TimerWindowWndProc;  
  10.     wcex.hInstance      = WebCore::instanceHandle();  
  11.     wcex.lpszClassName  = kTimerWindowClassName;  
  12.     RegisterClassEx(&wcex);  
  13.   
  14.     timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,  
  15.        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, WebCore::instanceHandle(), 0);  
  16.     timerFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.TimerFired");  
  17. }  

 

timer的消息处理函数如下:

 

  1. LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3. #if PLATFORM(WIN)  
  4.     // Windows Media Player has a modal message loop that will deliver messages  
  5.     // to us at inappropriate times and we will crash if we handle them when  
  6.     // they are delivered. We repost all messages so that we will get to handle  
  7.     // them once the modal loop exits.  
  8.     if (PluginView::isCallingPlugin()) {  
  9.         PostMessage(hWnd, message, wParam, lParam);  
  10.         return 0;  
  11.     }  
  12. #endif  
  13.   
  14.     if (message == timerFiredMessage) {  
  15.         InterlockedExchange(&pendingTimers, 0);  
  16.         processingCustomTimerMessage = true;  
  17.         sharedTimerFiredFunction();  
  18.         processingCustomTimerMessage = false;  
  19.     } else if (message == WM_TIMER) {  
  20.         if (wParam == sharedTimerID) {  
  21.             KillTimer(timerWindowHandle, sharedTimerID);  
  22.             sharedTimerFiredFunction();  
  23.         } else if (wParam == endHighResTimerID) {  
  24.             KillTimer(timerWindowHandle, endHighResTimerID);  
  25.             highResTimerActive = false;  
  26.             timeEndPeriod(timerResolution);  
  27.         }  
  28.     } else  
  29.         return DefWindowProc(hWnd, message, wParam, lParam);  
  30.   
  31.     return 0;  
  32. }  

 

引擎内部事件如何处理?

通过分析发现引擎内部的异步是通过timer来实现,具体请参照前面讲解timer的文章

通过上面的分析发现,webkit没有将事件的处理统一起来,如果在引擎中自己有一个事件的处理者,或者将以上事件的处理统一起来,其架构看起来会不会更加优美?

抱歉!评论已关闭.