From f5114f15c841f50074e1bfaea6bd39688e2de4ac Mon Sep 17 00:00:00 2001 From: FrankHB Date: Wed, 15 Apr 2020 00:43:25 +0800 Subject: [PATCH] =?UTF-8?q?EGE/:=20=E4=BF=AE=E5=A4=8D=E5=87=BD=E6=95=B0=20?= =?UTF-8?q?getch=20=E9=98=BB=E5=A1=9E=E4=B8=8D=E8=BF=94=E5=9B=9E=EF=BC=88?= =?UTF-8?q?=E8=87=AA=E4=BB=8E=2019.01=20=EF=BC=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参见版本 bb27ec9f3167eed04d23c1fb42c4c426ba9f9239 。 Signed-off-by: FrankHB --- Compatibility.md | 1 + EGE/include/thread_queue.h | 9 ++++++ EGE/src/ege/global.cpp | 66 +++++++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/Compatibility.md b/Compatibility.md index 3a521cef..4bf24352 100644 --- a/Compatibility.md +++ b/Compatibility.md @@ -21,6 +21,7 @@ YEGE 以 [misakamm 的 xege](http://github.com/misakamm/xege) 为基础修改, * 修改后的格式和 `YSLib::Pixel` 在 Win32 上的实现以及 [wysaid/xege pull request 12](https://github.com/wysaid/xege/pull/12) 中的像素格式保持一致,存储格式都为 BGRA8888 。 * 函数 `clearviewport` 使用背景颜色填充。 * 参见 [wysaid/xege pull request 12](https://github.com/wysaid/xege/pull/12) 。 +* 修复函数 `getch` 阻塞不返回(自从 19.01 )。 ### 非外部依赖项代码风格和格式 diff --git a/EGE/include/thread_queue.h b/EGE/include/thread_queue.h index c2a634a5..f51c4bde 100644 --- a/EGE/include/thread_queue.h +++ b/EGE/include/thread_queue.h @@ -78,6 +78,15 @@ class thread_queue for(auto& e : _queue) f(e); } + + template + auto + process_queue(F f) -> decltype(f(_queue)) + { + std::lock_guard lck(mtx); + + return f(_queue); + } }; } diff --git a/EGE/src/ege/global.cpp b/EGE/src/ege/global.cpp index 8a5738e4..80a5cf4a 100644 --- a/EGE/src/ege/global.cpp +++ b/EGE/src/ege/global.cpp @@ -131,6 +131,14 @@ wndproc(::HWND hWnd, unsigned message, ::WPARAM wParam, ::LPARAM lParam) return 0; } +std::uint16_t +filter_getch(int kv, unsigned w) ynothrow +{ + if(((kv & KEYMSG_DOWN) && (w >= 0x70 && w < 0x80)) || (w > ' ' && w < '0')) + kv |= 0x100; + return kv & 0xFFFF; +} + } // unnamed namespace; @@ -275,14 +283,38 @@ EGEApplication::_get_input(get_input_op op) switch(op) { case get_input_op::getch: - do { - int key = _peekkey(); - if(key < 0) - break; - if(key > 0) - key = _getkey_p(); - } while(_is_run() && _waitdealmessage()); + const auto dw(GetTickCount()); + + do + { + int key = _peekkey(); + if(key < 0) + break; + if(key > 0) + { + key = _getkey_p(); + if(key != 0) + { + const auto k(msgkey_queue.process_queue( + [&](std::deque& q) -> std::uint32_t{ + if(!q.empty()) + { + const auto& msg(q.back()); + + if(dw < msg.time + 1000) + return filter_getch(key, msg.wParam); + return 0xFFFFFFFF; + } + return filter_getch(key, key & 0xFFFF); + })); + + if(k != 0xFFFFFFFF) + return k; + } + } + } while(_is_run() && _waitdealmessage()); + } break; case get_input_op::kbhit: return _peekkey(); @@ -576,7 +608,8 @@ EGEApplication::_on_destroy() #endif void -EGEApplication::_on_key(unsigned message, unsigned long keycode, ::LPARAM keyflag) +EGEApplication::_on_key(unsigned message, unsigned long keycode, + ::LPARAM keyflag) { if(message == WM_KEYDOWN && keycode < MAX_KEY_VCODE) keystatemap[keycode] = 1; @@ -587,8 +620,8 @@ EGEApplication::_on_key(unsigned message, unsigned long keycode, ::LPARAM keyfla } void -EGEApplication::_on_mouse_button_up(::HWND h_wnd, unsigned msg, ::WPARAM w_param, - ::LPARAM l_param) +EGEApplication::_on_mouse_button_up(::HWND h_wnd, unsigned msg, + ::WPARAM w_param, ::LPARAM l_param) { auto* l = &mouse_state_l; auto vk = VK_LBUTTON; @@ -640,7 +673,8 @@ EGEApplication::_on_setcursor(::HWND hwnd) ::GetCursorPos(&pt); ::ScreenToClient(hwnd, &pt); ::GetClientRect(hwnd, &rect); - if(pt.x >= rect.left && pt.x < rect.right && pt.y >= rect.top && pt.y <= rect.bottom) + if(pt.x >= rect.left && pt.x < rect.right + && pt.y >= rect.top && pt.y <= rect.bottom) return {}; } return ::LoadCursor({}, IDC_ARROW); @@ -668,8 +702,8 @@ EGEApplication::_peekkey() if(msg.message == WM_KEYDOWN) { if(msg.wParam >= 0x70 && msg.wParam < 0x80) - return (KEYMSG_DOWN | (int(msg.wParam) + 0x100)); - return (KEYMSG_DOWN | (int(msg.wParam) & 0xFFFF)); + return KEYMSG_DOWN | (int(msg.wParam) + 0x100); + return KEYMSG_DOWN | (int(msg.wParam) & 0xFFFF); } else if(msg.message == WM_KEYUP) return KEYMSG_UP | (int(msg.wParam) & 0xFFFF); @@ -692,10 +726,10 @@ EGEApplication::_peekallkey(int flag) (msg.message == WM_KEYDOWN && (flag & KEYMSG_DOWN_FLAG))) { if(msg.message == WM_CHAR) - return (KEYMSG_CHAR | (int(msg.wParam) & 0xFFFF)); + return KEYMSG_CHAR | (int(msg.wParam) & 0xFFFF); else if(msg.message == WM_KEYDOWN) - return (KEYMSG_DOWN | (int(msg.wParam) & 0xFFFF) - | (msg.lParam & 0x40000000 ? 0 : KEYMSG_FIRSTDOWN)); + return KEYMSG_DOWN | (int(msg.wParam) & 0xFFFF) + | (msg.lParam & 0x40000000 ? 0 : KEYMSG_FIRSTDOWN); else if(msg.message == WM_KEYUP) return KEYMSG_UP | (int(msg.wParam) & 0xFFFF); }