From ac1d2390b224e29d5fe3f1d8db17bfeb320ae0bd Mon Sep 17 00:00:00 2001 From: yixy-only Date: Fri, 18 Jul 2025 23:49:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20INIT=5FEVENTLOOP?= =?UTF-8?q?=20=E5=88=9D=E5=A7=8B=E5=8C=96=E6=A8=A1=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=BE=AA=E7=8E=AF=E7=94=B1=E4=B8=BB=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/game_tetris.cpp | 4 +- demo/test_doubleclick.cpp | 2 +- include/ege.h | 2 + src/ege_graph.h | 6 +++ src/ege_head.h | 1 + src/egegapi.cpp | 9 ++++- src/graphics.cpp | 83 ++++++++++++++++++++++++++------------- src/time.cpp | 13 ++++++ 8 files changed, 88 insertions(+), 32 deletions(-) diff --git a/demo/game_tetris.cpp b/demo/game_tetris.cpp index 96a2df80..90d523b1 100644 --- a/demo/game_tetris.cpp +++ b/demo/game_tetris.cpp @@ -17,7 +17,7 @@ static int g_map_mod[] = {1, 4, 4, 4, 2, 2, 2, 1, 0}; /* 初始化全局数据及图形显示 */ void initgr() { - initgraph(g_width, g_height); + initgraph(g_width, g_height, INIT_RENDERMANUAL | INIT_EVENTLOOP); setfont(12, 6, "宋体"); int Trs_map[8][4][4][4] = { @@ -385,7 +385,7 @@ int main() { game.m_droptime = nfps / 2; game.m_movxtime = 10; - setrendermode(RENDER_MANUAL); + //setrendermode(RENDER_MANUAL); for ( ; is_run(); delay_fps(nfps)) { game.update(); game.render(); diff --git a/demo/test_doubleclick.cpp b/demo/test_doubleclick.cpp index 362432f7..49377419 100644 --- a/demo/test_doubleclick.cpp +++ b/demo/test_doubleclick.cpp @@ -16,7 +16,7 @@ int mouseKeyToIndex(int keyMask) int main() { const int winWidth = 1200, winHeight = 300; - initgraph(winWidth, winHeight, INIT_RENDERMANUAL); + initgraph(winWidth, winHeight, INIT_RENDERMANUAL | INIT_EVENTLOOP); ege_enable_aa(true); setlinecolor(EGEARGB(128, 81, 128, 222)); diff --git a/include/ege.h b/include/ege.h index f3cea5c9..30ec0203 100644 --- a/include/ege.h +++ b/include/ege.h @@ -217,6 +217,8 @@ enum initmode_flag INIT_UNICODE = 0x20, ///< Unicode character messages (equivalent to setunicodecharmessage(true)) INIT_HIDE = 0x40, ///< Hidden window INIT_WITHLOGO = 0x100, ///< Show EGE Logo animation on startup (not shown by default in Debug version) + INIT_EVENTLOOP = 0x200, ///< Event loop + INIT_ANIMATION = INIT_DEFAULT | INIT_RENDERMANUAL | INIT_NOFORCEEXIT ///< Animation mode }; diff --git a/src/ege_graph.h b/src/ege_graph.h index 4f16a6cb..bf877719 100644 --- a/src/ege_graph.h +++ b/src/ege_graph.h @@ -18,14 +18,20 @@ class egeControlBase; // 前置声明 initmode_flag getinitmode(); +int initWindow(_graph_setting* pg); + void logoscene(); +int messageHandle(); + int dealmessage(_graph_setting* pg, bool force_update); bool needToUpdate(_graph_setting* pg); int graphupdate(_graph_setting* pg); +int graphInitOption(); + void guiupdate(_graph_setting* pg, egeControlBase* root); int waitdealmessage(_graph_setting* pg); diff --git a/src/ege_head.h b/src/ege_head.h index 879094c1..ae4b25cd 100644 --- a/src/ege_head.h +++ b/src/ege_head.h @@ -195,6 +195,7 @@ struct _graph_setting std::wstring window_caption; HICON window_hicon; color_t window_initial_color; + int init_option; int exit_flag; int exit_window; int update_mark_count; // 更新标记 diff --git a/src/egegapi.cpp b/src/egegapi.cpp index b51e4523..5063a338 100644 --- a/src/egegapi.cpp +++ b/src/egegapi.cpp @@ -1450,8 +1450,13 @@ void setfillstyle(int pattern, color_t color, PIMAGE pimg) void setrendermode(rendermode_e mode) { + struct _graph_setting* pg = &graph_setting; + /* INIT_EVENTLOOP 模式下,固定为 RENDER_MANUAL 模式*/ + if (pg->init_option & INIT_EVENTLOOP) { + return; + } + if (mode == RENDER_MANUAL) { - struct _graph_setting* pg = &graph_setting; if (pg->lock_window) { ; } else { @@ -1459,12 +1464,12 @@ void setrendermode(rendermode_e mode) pg->timer_stop_mark = true; PostMessageW(pg->hwnd, WM_TIMER, RENDER_TIMER_ID, 0); pg->lock_window = true; + while (pg->timer_stop_mark) { ::Sleep(1); } } } else { - struct _graph_setting* pg = &graph_setting; delay_ms(0); SetTimer(pg->hwnd, RENDER_TIMER_ID, 50, NULL); pg->skip_timer_mark = false; diff --git a/src/graphics.cpp b/src/graphics.cpp index 3a4264a2..c6bbf4ff 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -99,7 +99,7 @@ unsigned long getlogodatasize(); } #endif -DWORD WINAPI messageloopthread(LPVOID lpParameter); +DWORD WINAPI messageLoopThread(LPVOID lpParameter); _graph_setting::_graph_setting() { @@ -285,10 +285,12 @@ void guiupdate(_graph_setting* pg, egeControlBase* root) root->update(); } -/*private function*/ int waitdealmessage(_graph_setting* pg) { - // MSG msg; + if (pg->init_option & INIT_EVENTLOOP) { + messageHandle(); + } + if (pg->update_mark_count < UPDATE_MAX_CALL) { egeControlBase* root = pg->egectrl_root; root->draw(NULL); @@ -857,6 +859,7 @@ void initgraph(int* gdriver, int* gmode, const char* path) { struct _graph_setting* pg = &graph_setting; + pg->init_option = getinitmode(); pg->exit_flag = 0; pg->exit_window = 0; @@ -886,17 +889,22 @@ void initgraph(int* gdriver, int* gmode, const char* path) register_classW(pg, pg->instance); // SECURITY_ATTRIBUTES sa = {0}; - DWORD pid; - pg->threadui_handle = CreateThread(NULL, 0, messageloopthread, pg, CREATE_SUSPENDED, &pid); - ResumeThread(pg->threadui_handle); - while (!pg->has_init) { - ::Sleep(1); + if (pg->init_option & INIT_EVENTLOOP) { + initWindow(pg); + } else { + DWORD pid; + pg->threadui_handle = CreateThread(NULL, 0, messageLoopThread, pg, CREATE_SUSPENDED, &pid); + ResumeThread(pg->threadui_handle); + + while (!pg->has_init) { + ::Sleep(1); + } } UpdateWindow(pg->hwnd); - if (!(g_initoption & INIT_HIDE)) { + if (!(pg->init_option & INIT_HIDE)) { ShowWindow(pg->hwnd, SW_SHOWNORMAL); BringWindowToTop(pg->hwnd); SetForegroundWindow(pg->hwnd); @@ -914,11 +922,11 @@ void initgraph(int* gdriver, int* gmode, const char* path) static egeControlBase _egeControlBase; - if ((g_initoption & INIT_WITHLOGO) && !(g_initoption & INIT_HIDE)) { + if ((pg->init_option & INIT_WITHLOGO) && !(pg->init_option & INIT_HIDE)) { logoscene(); } - if (g_initoption & INIT_RENDERMANUAL) { + if (pg->init_option & INIT_RENDERMANUAL) { setrendermode(RENDER_MANUAL); } @@ -945,12 +953,8 @@ void closegraph() ShowWindow(pg->hwnd, SW_HIDE); } -/*private function*/ -DWORD WINAPI messageloopthread(LPVOID lpParameter) +int initWindow(_graph_setting* pg) { - _graph_setting* pg = (_graph_setting*)lpParameter; - MSG msg; - /* 执行应用程序初始化: */ if (!init_instance(pg->instance)) { return 0xFFFFFFFF; @@ -963,25 +967,50 @@ DWORD WINAPI messageloopthread(LPVOID lpParameter) pg->mouse_show = 0; pg->exit_flag = 0; - pg->use_force_exit = (g_initoption & INIT_NOFORCEEXIT ? false : true); + pg->use_force_exit = (pg->init_option & INIT_NOFORCEEXIT ? false : true); - if (g_initoption & INIT_NOFORCEEXIT) { + if (pg->init_option & INIT_NOFORCEEXIT) { SetCloseHandler(DefCloseHandler); } pg->close_manually = true; - pg->skip_timer_mark = false; - SetTimer(pg->hwnd, RENDER_TIMER_ID, 50, NULL); + + /* 仅在 INIT_EVENTLOOP 模式下设置定时器(INIT_EVENTLOOP 模式下事件在主线程中处理,固定为手动渲染模式,无需设置定时器。 */ + if (pg->init_option & INIT_EVENTLOOP) { + pg->lock_window = true; + pg->skip_timer_mark = true; + } else { + pg->skip_timer_mark = false; + SetTimer(pg->hwnd, RENDER_TIMER_ID, 50, NULL); + } pg->has_init = true; +} - while (!pg->exit_window) { - if (GetMessageW(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } else { - Sleep(1); +int messageHandle() +{ + MSG msg; + int handleCount = 0; + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + return -1; } + + TranslateMessage(&msg); + DispatchMessageW(&msg); + handleCount++; + } + + return handleCount; +} + +/*private function*/ +DWORD WINAPI messageLoopThread(LPVOID lpParameter) +{ + _graph_setting* pg = (_graph_setting*)lpParameter; + initWindow(pg); + while (messageHandle() != -1) { + Sleep(1); } return 0; @@ -1054,7 +1083,7 @@ BOOL init_instance(HINSTANCE hInstance) //DeleteObject(hfont); } //*/ - if (!(g_initoption & INIT_HIDE)) { + if (!(pg->init_option & INIT_HIDE)) { SetActiveWindow(pg->hwnd); } diff --git a/src/time.cpp b/src/time.cpp index eebf0187..86c12da7 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -72,6 +72,10 @@ void delay_ms(long ms) const double targetTime = get_highfeq_time_ls(pg) * 1000.0 + ms; + if (pg->init_option & INIT_EVENTLOOP) { + messageHandle(); + } + /* 处理 UI 事件,更新 UI 控件数据 */ guiupdate(pg, root); @@ -129,6 +133,10 @@ void delay_fps(double fps) dw = pg->delay_fps_dwLast; } + if (pg->init_option & INIT_EVENTLOOP) { + messageHandle(); + } + root->draw(NULL); for (; nloop >= 0; --nloop) { @@ -182,6 +190,11 @@ void delay_jfps(double fps) dw = pg->delay_fps_dwLast; } + + if (pg->init_option & INIT_EVENTLOOP) { + messageHandle(); + } + root->draw(NULL); for (; nloop >= 0; --nloop) {