PeekMessage, TranslateMessage, and DispatchMessage often take a long time (sometimes more than a millisecond for a single message). Is this normal? How do people deal with this? I thought about handling messages on a separate thread, but that would introduce unnecessary complexity and wouldn't really solve the problem.
Here's what my game loop looks like:
int WINAPI WinMain(...)
{
// ...
bool running = true;
while( running )
{
running = poll_messages();
update();
render();
SwapBuffers( whatever );
}
// ...
}
bool poll_messages()
{
bool keep_running = true;
MSG msg;
while( PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE) )
{
TranslateMessage( &msg );
DispatchMessageA( &msg );
if( msg.message == WM_QUIT )
keep_running = false;
}
return keep_running;
}
And part of the window proc:
LRESULT CALLBACK wnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
LRESULT result = 0;
switch( msg )
{
// ...
// I removed most cases, but here's one of the most frequent offenders.
// pretty much all the time is spent in GetRawInputData when handling this message.
case WM_INPUT:
{
BYTE data[ sizeof(RAWINPUT) ];
UINT data_size = furo_arr_cnt(data);
UINT bytes_written = GetRawInputData( HRAWINPUT(lparam), RID_INPUT, data, &data_size, sizeof(RAWINPUTHEADER) );
if( bytes_written == data_size )
{
RAWINPUT* raw_input = (RAWINPUT*)data;
if( raw_input->header.dwType == RIM_TYPEMOUSE &&
raw_input->data.mouse.usFlags == MOUSE_MOVE_RELATIVE )
{
int x_relative = raw_input->data.mouse.lLastX;
int y_relative = raw_input->data.mouse.lLastY;
// convert from screen space to OpenGL viewport space
y_relative = -y_relative;
platform_raw_mouse_delta_event( x_relative, y_relative );
}
}
else
log_err( "failed to get raw mouse input (ec=%u)", GetLastError() );
break;
}
// ...
default:
result = DefWindowProcA( hwnd, msg, wparam, lparam );
break;
}
return result;
}