【问题标题】:Use of CreateEvent() in Quake在 Quake 中使用 CreateEvent()
【发布时间】:2012-08-16 14:48:51
【问题描述】:

我很好奇 Quake 中 CreateEvent() 函数的使用。

我们在定义 WinMain() 的 c 文件中有以下全局:

static HANDLE tevent;

在 WinMain() 函数本身中,我们看到:

tevent = CreateEvent(NULL, FALSE, FALSE, NULL);

如果创建失败则游戏退出。

然后它出现在以下函数中:

void SleepUntilInput (int time)
{
    MsgWaitForMultipleObjects (1, &tevent, FALSE, time, QS_ALLINPUT);
}

最后在 Quit 函数中调用 CloseHandle(tevent)。

我不熟悉 WinAPI,所以这给我留下了两个问题。

- CreateEvent() 的使用返回什么?

-这如何使 SleepUntilInput() 函数正常工作?

【问题讨论】:

    标签: c winapi events game-engine quake


    【解决方案1】:

    CreateEvent 返回新创建事件的句柄。

    SleepUntilInput 使用 `MsgWaitForMultipleObjcts 函数等待三件事之一发生:

    1. 事件已发出信号,或
    2. 输入可用,或
    3. time 毫秒已经过去。

    由于代码从不发出事件信号,因此条件 (1) 永远不会发生,因此唯一能唤醒它的是 (2) 或 (3)。

    请注意,该事件实际上不是必需的。代码可以完成

    void SleepUntilInput (int time) 
    { 
        MsgWaitForMultipleObjects (0, NULL, FALSE, time, QS_ALLINPUT); 
    } 
    

    但是编写代码的人没有想到这一点,所以他们转而传递了一个虚拟事件。

    【讨论】:

    • 确定事件是在真实代码中发出信号的吗?意图一定是:如果用户想退出,那么停止等待并退出。 WaitForMultipleObjects()的第三个参数是WaitAll = FALSE,意思是如果它等待的任何事情发生,它就会停止等待(而不是它等待的所有事情)。
    • 代码中的任何地方都没有其他对 tevent 的引用,所以除非有一些我不知道的隐式使用,否则不,它没有被引用。或许 Carmack 在发货前去掉了一些东西——我发现了很多这样的例子。
    • MsgWaitForMultipleObjects 的 MSDN 页面没有说明如果没有传入对象时的预期行为 - 并且还指定 pHandles 应该是“对象句柄数组”,而 NULL 不是一个数组;也许他是保守的,而不是依赖于无证行为?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多