From 1b7f917cdf506a01aba6c0f1249630d4fe38b2b5 Mon Sep 17 00:00:00 2001 From: jyelon Date: Mon, 15 Dec 2025 23:35:47 -0500 Subject: [PATCH] Using CHANNEL_PRINTS to transfer printbuffers to stdout is now working. --- luprex/cpp/core/drivenengine.cpp | 14 ++++++++++---- luprex/cpp/core/drivenengine.hpp | 9 ++++++++- luprex/cpp/core/enginewrapper.hpp | 5 +++++ luprex/cpp/core/lpxclient.cpp | 3 +++ luprex/cpp/core/lpxserver.cpp | 4 ++++ luprex/cpp/core/printbuffer.cpp | 7 +++++++ luprex/cpp/core/printbuffer.hpp | 3 +++ luprex/cpp/drv/driver.cpp | 24 ++++++++++++------------ 8 files changed, 52 insertions(+), 17 deletions(-) diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index d209db81..27e5c21d 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -168,10 +168,6 @@ void DrivenEngine::set_console_prompt(const eng::string &prompt) { console_prompt_ = prompt; } -void DrivenEngine::rescan_lua_source(bool b) { - rescan_lua_source_ = b; -} - void DrivenEngine::set_visible_world_and_actor(World *w, int64_t id) { visible_world_ = w; visible_actor_id_ = id; @@ -192,6 +188,7 @@ DrivenEngine::DrivenEngine() { channels_[0] = stdio_channel_; rescan_lua_source_ = false; clock_ = 0.0; + have_prints_ = false; stop_driver_ = false; } @@ -381,6 +378,10 @@ double DrivenEngine::drv_get_clock() const { return clock_; } +bool DrivenEngine::drv_get_have_prints() const { + return have_prints_; +} + bool DrivenEngine::drv_get_rescan_lua_source() const { return rescan_lua_source_; } @@ -536,6 +537,10 @@ static double drv_get_clock(EngineWrapper *w) { return w->engine->drv_get_clock(); } +static bool drv_get_have_prints(EngineWrapper *w) { + return w->engine->drv_get_have_prints(); +} + static bool drv_get_rescan_lua_source(EngineWrapper *w) { return w->engine->drv_get_rescan_lua_source(); } @@ -913,6 +918,7 @@ static void init_engine_wrapper_helper(EngineWrapper *w) { w->get_outgoing_empty = drv_get_outgoing_empty; w->get_console_prompt = drv_get_console_prompt; w->get_clock = drv_get_clock; + w->get_have_prints = drv_get_have_prints; w->get_rescan_lua_source = drv_get_rescan_lua_source; w->get_stop_driver = drv_get_stop_driver; w->get_actor_id = drv_get_actor_id; diff --git a/luprex/cpp/core/drivenengine.hpp b/luprex/cpp/core/drivenengine.hpp index 591bd91c..7a7abbc5 100644 --- a/luprex/cpp/core/drivenengine.hpp +++ b/luprex/cpp/core/drivenengine.hpp @@ -218,7 +218,12 @@ public: // DRIVER: this merely sets a flag, which the driver will notice later, // causing the driver to update the lua source. // - void rescan_lua_source(bool b); + void rescan_lua_source(bool b) { rescan_lua_source_ = b; } + + // Set the flag to indicate that you have something you want to + // print. This will trigger the driver to access CHANNEL_PRINTS. + // + void set_have_prints(bool b) { have_prints_ = b; } // Set the world pointer and the actor ID. // @@ -274,6 +279,7 @@ public: bool drv_get_outgoing_empty(uint32_t chid) const; void drv_get_console_prompt(uint32_t *len, const char **data) const; double drv_get_clock() const; + bool drv_get_have_prints() const; bool drv_get_rescan_lua_source() const; bool drv_get_stop_driver() const; int64_t drv_get_actor_id() const; @@ -310,6 +316,7 @@ private: StreamBuffer call_function_retpk_; bool rescan_lua_source_; double clock_; + bool have_prints_; bool stop_driver_; eng::string console_prompt_; friend class Channel; diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index 688ab496..dbe8a9da 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -115,6 +115,11 @@ struct EngineWrapper { // double (*get_clock)(EngineWrapper *w); + // Check the 'have prints' flag. If true, then the engine + // wants the driver to use CHANNEL_PRINTS to obtain prints. + // + bool (*get_have_prints)(EngineWrapper *w); + // Check the 'rescan_lua_source' flag. If this flag is set, it means // that the engine wants the driver to rescan the lua source code. // When the driver sees this flag, it should rescan the source and call diff --git a/luprex/cpp/core/lpxclient.cpp b/luprex/cpp/core/lpxclient.cpp index c8f7633e..689e3a23 100644 --- a/luprex/cpp/core/lpxclient.cpp +++ b/luprex/cpp/core/lpxclient.cpp @@ -276,6 +276,7 @@ public: if (print_channeler_.channel(world_->get_printbuffer(actor_id_), retpk)) { send_invocation(print_channeler_.invocation(actor_id_)); } + set_have_prints(false); break; } default: { @@ -313,6 +314,8 @@ public: world_to_asynchronous(); } } + + set_have_prints(print_channeler_.have_prints(world_->get_printbuffer(actor_id_))); } }; diff --git a/luprex/cpp/core/lpxserver.cpp b/luprex/cpp/core/lpxserver.cpp index ccc5e870..3796977b 100644 --- a/luprex/cpp/core/lpxserver.cpp +++ b/luprex/cpp/core/lpxserver.cpp @@ -202,6 +202,7 @@ public: if (print_channeler_.channel(master_->get_printbuffer(admin_id_), retpk)) { master_->invoke(print_channeler_.invocation(admin_id_)); } + set_have_prints(false); break; } default: { @@ -354,6 +355,9 @@ public: } } util::remove_marked_items(http_server_channels_); + + // Notify the driver if there are any prints. + set_have_prints(print_channeler_.have_prints(master_->get_printbuffer(admin_id_))); } }; diff --git a/luprex/cpp/core/printbuffer.cpp b/luprex/cpp/core/printbuffer.cpp index 6c75c1a7..68b4d491 100644 --- a/luprex/cpp/core/printbuffer.cpp +++ b/luprex/cpp/core/printbuffer.cpp @@ -179,6 +179,13 @@ void PrintBuffer::patch(StreamBuffer *sb, DebugCollector *dbc) { } } +bool PrintChanneler::have_prints(const PrintBuffer *printbuffer) const +{ + return ((printbuffer != nullptr) && + (printbuffer->first_line() < printbuffer->first_unchecked()) && + (line_ < printbuffer->first_unchecked())); +} + bool PrintChanneler::channel(const PrintBuffer *printbuffer, StreamBuffer *sb) { if (printbuffer == nullptr) return false; if (printbuffer->first_line() > line_) { diff --git a/luprex/cpp/core/printbuffer.hpp b/luprex/cpp/core/printbuffer.hpp index a13d68fd..a927cd7b 100644 --- a/luprex/cpp/core/printbuffer.hpp +++ b/luprex/cpp/core/printbuffer.hpp @@ -149,6 +149,9 @@ public: // Reset the print channeler. void reset() { line_ = 0; } + // Check if there's anything to channel. + bool have_prints(const PrintBuffer *pb) const; + // Copy any new lines from the printbuffer to the stream buffer. // Update the current line number. Return true if the printbuffer // contains any lines that have already been channeled. diff --git a/luprex/cpp/drv/driver.cpp b/luprex/cpp/drv/driver.cpp index 752d5e0a..abd1018e 100644 --- a/luprex/cpp/drv/driver.cpp +++ b/luprex/cpp/drv/driver.cpp @@ -197,18 +197,18 @@ class Driver { } } - void handle_console_output() { - while (true) { - uint32_t ndata; const char *data; - engw.get_outgoing(&engw, 0, &ndata, &data); - if (ndata == 0) break; - if (ndata > DRV_SHORTSTRING_SIZE) ndata = DRV_SHORTSTRING_SIZE; - std::string_view src(data, ndata); - int consumed; - std::u32string cps = drvutil::utf8_to_utf32(src, &consumed); - readline_device_.print(cps); - engw.play_sent_outgoing(&engw, 0, consumed); + if (engw.get_have_prints(&engw)) { + uint32_t ndata; + const char *data; + engw.play_access(&engw, AccessKind::CHANNEL_PRINTS, 0, 0, "", &ndata, &data); + if (ndata > 0) { + if (ndata > DRV_SHORTSTRING_SIZE) ndata = DRV_SHORTSTRING_SIZE; + std::string_view src(data, ndata); + int consumed; + std::u32string cps = drvutil::utf8_to_utf32(src, &consumed); + readline_device_.print(cps); + } } } @@ -660,8 +660,8 @@ class Driver { handle_new_outgoing_sockets(); handle_socket_input_output(); handle_console_input(); - handle_console_output(); engw.play_update(&engw, drvutil::get_monotonic_clock()); + handle_console_output(); } // Cleanup