--- nono/cli/cli_app.cpp 2026/04/29 17:04:33 1.1.1.3 +++ nono/cli/cli_app.cpp 2026/04/29 17:05:09 1.1.1.9 @@ -4,25 +4,33 @@ // Licensed under nono-license.txt // +// +// CLI アプリケーションのエントリポイント +// + #include "header.h" +#include "cuimessage.h" +#include "kevent.h" #include "mainapp.h" #include "mpu680x0.h" #include "pluto.h" -#include "rtc.h" #include "vm.h" -void cli_halt_callback(void *); - // wxApp と相似にするためのクラス class CLIApp { public: - bool OnInit(); + int OnInit(); bool Parse(); - [[noreturn]] void OnCreate(); + int OnCreate(); + void OnHalt(); + void OnAppExit(); + + int ac {}; + char **av {}; - int ac; - char **av; + autofd kq {}; + bool exit_request {}; }; int @@ -33,55 +41,93 @@ main(int ac, char *av[]) // wxApp とよく似せるため app->ac = ac; app->av = av; - if (!app->OnInit()) { - return 1; - } - return 0; + return app->OnInit(); } // ここがエントリポイント(のつもり) -bool +int CLIApp::OnInit() { - if (!gMainApp.Init(true, ac, av)) { - return false; + int rv; + + // CLI 側では関係ないが wx 側で必要なので初期化は2ステージに分かれている + rv = gMainApp.Init1(true, ac, av); + if (rv != MainApp::PASS) { + return rv; } - if (!gMainApp.Start()) { - return false; + // UIMessage の初期化はなんとなくスレッド開始前のほうがよかろう + kq = CUIMessage::Init(); + if (kq < 0) { + return EXIT_FAILURE; + } + if (!gMainApp.Init2()) { + return EXIT_FAILURE; } // メインウィンドウに相当するところ OnCreate(); - return true; + return EXIT_SUCCESS; } // メインウィンドウ作成後のイベントに相当するところ -void +int CLIApp::OnCreate() { - // VM にコールバックを登録 + CUIMessage::Connect(UIMessage::APPEXIT, + [&](const UIMessage&) { OnAppExit(); }); if (gMPU680x0) { - gMPU680x0->SetHaltCallback(cli_halt_callback, NULL); + CUIMessage::Connect(UIMessage::HALT, + [&](const UIMessage&) { OnHalt(); }); } + // UIMessage の処理を開始する。 + UIMessage::Attach(&CUIMessage::Process); - // 時刻開始? - // なるべく VM が開始する直前にしたい。 - gRTC->InitRTC(); - - // VM 実行開始 + // 電源投入 gVM->PowerButton(); - // ? - for (;;) { - sleep(1); + // メッセージを待つ + while (exit_request == false) { + struct kevent kev; + + if (kevent_poll(kq, &kev, 1, NULL) < 0) { + if (errno == EINTR) { + continue; + } + warn("CLIApp::OnCreate: kevent_poll"); + // XXX どうする? + continue; + } + + // パイプから1メッセージ分読み出す + UIMessage m; + if (read((int)kev.ident, &m, sizeof(m)) < 0) { + warn("CLIApp::OnCreate: read"); + // XXX どうする? + continue; + } + + // ディスパッチ + CUIMessage::Dispatch(m); } + + // VM を解放 + gVM->Dispose(); + + return 0; } // m680x0 ダブルバスフォールト時に呼ばれるコールバック。 void -cli_halt_callback(void *dummy) +CLIApp::OnHalt() { // どうする? warnx("Double bus fault has occurred in VM"); } + +// アプリケーションの終了要求で呼ばれるコールバック。 +void +CLIApp::OnAppExit() +{ + exit_request = true; +}