天龙源码分析 - 主循环驱动方式

天龙逻辑驱动使用的是事件方式

1 游戏初始化的时候,创建一个事件,并设置定时触发函数

    m_hTickEvent  =  ::CreateEvent(NULL, FALSE, FALSE, NULL);
    ::ResetEvent(m_hTickEvent);
    m_hEventTimer 
=  ::timeSetEvent((INT)( 1000.0f / nMaxFPS), (INT)( 1000.0f / nMaxFPS), EventTimerProc,  0 , TIME_PERIODIC | TIME_CALLBACK_FUNCTION); 

 

2 每隔一段时间,调用下面函数,触发事件

VOID CALLBACK CGameProcedure::EventTimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) 

    SetEvent(m_hTickEvent);

 

 

3 然后就是主逻辑了

 

VOID CGameProcedure::MainLoop(VOID)
{
    MSG msg;
    ZeroMemory(
& msg,  sizeof (MSG));

    
while  (TRUE)
    {
        AUTO_SAMPLING theAutoSampling;

//         AxProfile::AxProfile_PushNode("Msg");
        
// 读取出消息队列中的所有消息并处理
         while (PeekMessage( & msg, NULL,  0 0 , PM_REMOVE)) 
        { 
            
// 如果是退出消息,退出
             if  (msg.message  ==  WM_QUIT)   return ;

            
// 处理其他消息
            TranslateMessage( & msg);
            DispatchMessage(
& msg);
        };
//         AxProfile::AxProfile_PopNode("Msg");

        
//  等待有新的消息进入消息队列或者到达渲染时间
        UINT dwResult  =  MsgWaitForMultipleObjects( 1 & m_hTickEvent, 
                            FALSE, INFINITE, QS_ALLINPUT); 

        
if  (dwResult  ==  WAIT_OBJECT_0)
        {
            
// 进入逻辑Tick和渲染
//             AxProfile::AxProfile_PushNode("Tick");
            TickActive();
//             AxProfile::AxProfile_PopNode("Tick");

//             AxProfile::AxProfile_PushNode("Render");
            RenderActive();
//             AxProfile::AxProfile_PopNode("Render");

//             AxProfile::AxProfile_PushNode("Event");
            ProcessGameEvent();
//             AxProfile::AxProfile_PopNode("Event");
        }
        
// 有新消息进入消息循环,处理消息
         else   continue ;
    }

}

 

 

使用了MsgWaitForMultipleObjects,空闲,或者事件触发,就会调用逻辑更新函数,和渲染函数

4 可见,天龙不是使用常见的时间判断方式

你可能感兴趣的:(源码分析)