2014-11-03 66 views
2

我一直在尋找OpenGL編程作爲C++程序員,並且看到了處理事件驅動編程的兩種主要方式:消息輪詢或回調函數。事件驅動的編程:回調與消息輪詢

  • 我看到原生的Win32API使用了一個回調函數,該函數由DispatchMessage函數觸發。

  • SDL(基於教程)也使用某種回調或回調式編程。

  • GLFW也使用回調。

  • SFML允許程序員在代碼中的任何地方輪詢單個消息,通常在循環中形成消息循環。

  • X Window系統基於我所見,也使用消息輪詢。

顯然,由於事件系統存在於突出的環境中,每個系統都必須具有優勢。我希望有人能告訴我每個人的優點和缺點。我正在考慮編寫一些將嚴重依賴於事件驅動編程的程序,並且希望能夠做出關於採取哪條路徑的最佳決策。

回答

1

這不會是完整的,但這裏是我想到一些東西......

我只用過GL三維,並沒有做太多的方式圖形用戶界面。投票事件很常見。更確切地說,在主要渲染循環中進行輪詢,該循環處理隊列中的所有事件,然後轉到渲染。這是因爲在收集所有事件並使用它們更新場景的3D狀態後,您會在每幀從頭開始重新渲染所有內容。由於屏幕只能以有限的幀速率顯示圖像,因此在輪詢期間休眠也很常見,因爲任何狀態更新都不會在以後顯示,即使它們的事件被更早觸發也是如此。

  • 如果你是通過繪畫來處理事件,正是因爲他們發生,如部分的方式,那麼你有競爭條件。處理這可能是一個不必要的ha。。

  • 如果你有任何動畫,那麼你已經有一個循環,輪詢是一個微不足道的成本。

  • 如果您的事件非常罕見,那麼您不需要經常重新繪製,因此線程處於活動狀態並且輪詢效率稍低。

  • 如果事件堆積如山,並且你正在爲每一個重新繪製,這將是非常糟糕的。您可能會發現您比使用循環處理所有事件和渲染一次更經常重繪。

我認爲輪詢的主要問題是非活動的窗口不重點。讓我們說你最小化你的GL應用程序。你知道它不會收到任何事件,所以投票是無用的。那就是爲此畫畫。

另一個問題是響應延遲。這對於捕捉遊戲中的鼠標移動等非常重要。只要您以正確的順序輪詢事件(輸入→更新→顯示),這通常是可以的。但是,通過延遲幀顯示,vsync可能會混淆時間。

0

我目前正在創建基於openglevdev爲Linux輕型GUI庫。

的第一個,在Ç developped使我實現消息架構,通過使用多線程通信啓發。

對於第二個,在C++,我只使用回調,但evdev堆在linux是消息驅動。我的結論是,對於能夠比程序響應更快地觸發中斷的外圍設備(例如:鼠標),您需要一個fifo層(通常是一個管道)來使兩個上下文之間的通信異步。因此:消息只是異步緩衝在多線程環境中的回調。

您也可以使用回調fifo來緩衝您的事件。但是在線程之間組織變量並不總是那麼容易(信號量,鎖定等)。使用消息作爲唯一的進程間同步機制有助於清除這一點。