--- nono/cli/cuimessage.cpp 2026/04/29 17:04:56 1.1 +++ nono/cli/cuimessage.cpp 2026/04/29 17:05:49 1.1.1.4 @@ -4,31 +4,69 @@ // Licensed under nono-license.txt // +// +// UI スレッドへのメッセージ機構 (CLI 側) +// + +#include "nono.h" #include "cuimessage.h" +#include "kevent.h" -std::array CUIMessage::func_table; +/*static*/ autofd CUIMessage::wpipe; +/*static*/ autofd CUIMessage::rpipe; -// UIMessage を func に接続する -/*static*/ void -CUIMessage::Connect(UIMessage::ID id, CUIMessage::Func func) +// CUIMessage の初期化。パイプを用意して kqueue ディスクリプタを返す。 +int +CUIMessage::Init() { - func_table[id] = func; + int kq; + int fds[2]; + + kq = kqueue(); + if (kq < 0) { + warn("CUIMessage::Init: kqueue"); + return -1; + } + + if (pipe(fds) < 0) { + warn("CUIMessage::Init: pipe"); + close(kq); + return -1; + } + + rpipe = fds[0]; + wpipe = fds[1]; + + if (kevent_add(kq, rpipe, EVFILT_READ, EV_ADD, 0) < 0) { + warn("CUIMessage::Init: kevent_add"); + close(kq); + return -1; + } + + return kq; } -// UIMessage を処理する +// UIMessage::Post() で呼ばれるコールバック関数。 /*static*/ void -CUIMessage::Process(UIMessage::Queue& queue) +CUIMessage::Process(uint id, int arg) { - UIMessage m; + if (id >= UIMessage::ID_MAX) { + PANIC("Invalid UIMessage %u", (uint)id); + } + + union64 m; + m.h = id; + m.l = arg; - while (queue.Dequeue(&m)) { - UIMessage::ID id = m.GetID(); - if (id < 0 || id >= UIMessage::ID_MAX) { - PANIC("Invalid UIMessage %d", id); - } - auto func = func_table[id]; - if (func) { - func(m); - } + // パイプで通知。 + int r; + r = write(wpipe, &m, sizeof(m)); + if (r < 0) { + warn("CUIMessage::Process: write"); + return; + } + if (r < sizeof(m)) { + warnx("CUIMessage::Process: write: too short"); + return; } }