--- nono/wx/wxuimessage.cpp 2026/04/29 17:05:00 1.1 +++ nono/wx/wxuimessage.cpp 2026/04/29 17:05:27 1.1.1.4 @@ -4,13 +4,18 @@ // Licensed under nono-license.txt // +// +// UI スレッドへのメッセージ機構 (GUI 側) +// + #include "wxuimessage.h" // イベントタイプの定義 wxDEFINE_EVENT(NONO_EVT_UIMESSAGE, wxCommandEvent); /*static*/ -std::array WXUIMessage::dest_table; +std::array, UIMessage::ID_MAX> + WXUIMessage::dest_table; // UIMessage を wxWidgets のイベントハンドラに接続する /*static*/ void @@ -18,17 +23,20 @@ WXUIMessage::Connect(UIMessage::ID id, w wxObjectEventFunction function) { dest->Connect(id, NONO_EVT_UIMESSAGE, function); - dest_table[id] = dest; + dest_table[id].push_back(dest); } // イベントハンドラの接続を解除する /*static*/ void -WXUIMessage::Disconnect(UIMessage::ID id, wxObjectEventFunction function) +WXUIMessage::Disconnect(UIMessage::ID id, wxEvtHandler *dest, + wxObjectEventFunction function) { - wxEvtHandler *dest = dest_table[id]; - if (dest) { - dest->Disconnect(NONO_EVT_UIMESSAGE, function); - dest_table[id] = NULL; + dest->Disconnect(NONO_EVT_UIMESSAGE, function); + for (auto it = dest_table[id].begin(); it != dest_table[id].end(); ++it) { + if (*it == dest) { + dest_table[id].erase(it); + break; + } } } @@ -40,14 +48,24 @@ WXUIMessage::Process(UIMessage::Queue& q while (queue.Dequeue(&m)) { UIMessage::ID id = m.GetID(); - if (id < 0 || id >= UIMessage::ID_MAX) { - PANIC("Invalid UIMessage %d", id); + if (id >= UIMessage::ID_MAX) { + PANIC("Invalid UIMessage %u", id); } - auto dest = dest_table[id]; - if (dest) { + for (auto dest : dest_table[id]) { wxCommandEvent ev(NONO_EVT_UIMESSAGE, id); ev.SetInt(m.GetArg()); wxPostEvent(dest, ev); } } } + +// すべてのハンドラが解除されているかチェックする (開発用) +/*static*/ void +WXUIMessage::AssertAllDisconnected() +{ + for (int i = 0; i < dest_table.size(); i++) { + if (dest_table[i].empty() == false) { + warnx("UIMessage ID=%d not disconnected", i); + } + } +}