From 8dab0d16b7e445b2ad7fe3ca253eca90b265ce28 Mon Sep 17 00:00:00 2001 From: jyelon Date: Tue, 26 May 2026 15:07:42 -0400 Subject: [PATCH] CPL command --- Content/Widgets/WB_Console.uasset | 4 +- Source/Integration/LuprexGameModeBase.cpp | 9 +++- Source/Integration/LuprexGameModeBase.h | 8 +++ luprex/cpp/core/source.cpp | 1 - luprex/cpp/core/unit-testing.cpp | 2 +- luprex/cpp/core/world-core.cpp | 63 +++++++++++------------ luprex/cpp/core/world-diffxmit.cpp | 2 +- luprex/cpp/core/world.hpp | 20 ++++--- luprex/lua/login.lua | 2 +- 9 files changed, 64 insertions(+), 47 deletions(-) diff --git a/Content/Widgets/WB_Console.uasset b/Content/Widgets/WB_Console.uasset index d6921d85..52746273 100644 --- a/Content/Widgets/WB_Console.uasset +++ b/Content/Widgets/WB_Console.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61efa6e7d2b14e2e7f44dfcb1e50d57030f097e374bf5aed00848724b1fe9a63 -size 232134 +oid sha256:76e9c59b6e9a30ec9a4572e57bf336350f14ad8fde444ba9e285fa063628a7b9 +size 239430 diff --git a/Source/Integration/LuprexGameModeBase.cpp b/Source/Integration/LuprexGameModeBase.cpp index c8dd486b..b13ae807 100644 --- a/Source/Integration/LuprexGameModeBase.cpp +++ b/Source/Integration/LuprexGameModeBase.cpp @@ -73,7 +73,6 @@ void ALuprexGameModeBase::UpdateConsoleOutput() { } } -#pragma optimize("", off) void ALuprexGameModeBase::UpdateTangibles() { double radius = 1000.0; // Hardwired for now. using TanArray = UlxTangibleManager::TanArray; @@ -132,8 +131,9 @@ void ALuprexGameModeBase::UpdatePossessedTangible() { void ALuprexGameModeBase::UpdateLuaSourceCode() { FlxLockedWrapper lockedwrap; - if (lockedwrap->get_rescan_lua_source(lockedwrap.Get())) + if (lockedwrap->get_rescan_lua_source(lockedwrap.Get()) || ReloadSource) { + ReloadSource = false; drvutil::ostringstream srcpak; FString LuprexRoot = FPaths::Combine(FPaths::ProjectDir(), TEXT("luprex")); std::string srcpakerr = drvutil::package_lua_source(TCHAR_TO_UTF8(*LuprexRoot), &srcpak); @@ -259,4 +259,9 @@ ALuprexGameModeBase *ALuprexGameModeBase::FromContext(const UObject *context) { return result; } +void ALuprexGameModeBase::TriggerReloadSource(const UObject *WorldContextObject) { + ALuprexGameModeBase *GameMode = FromContext(WorldContextObject); + GameMode->ReloadSource = true; +} + diff --git a/Source/Integration/LuprexGameModeBase.h b/Source/Integration/LuprexGameModeBase.h index 850bc5cf..b395cf84 100644 --- a/Source/Integration/LuprexGameModeBase.h +++ b/Source/Integration/LuprexGameModeBase.h @@ -62,6 +62,11 @@ public: // Get the current Luprex Game Mode Base, given a Context object. static ALuprexGameModeBase *FromContext(const UObject *Context); + + // Set the ReloadSource flag on the current Luprex game mode, causing + // the Lua source to be reloaded on the next tick. + UFUNCTION(BlueprintCallable, Category = "Luprex|Miscellaneous", meta = (WorldContext = "WorldContextObject")) + static void TriggerReloadSource(const UObject *WorldContextObject); // The sensitivity level at which a log message triggers a debugger breakpoint. UPROPERTY(EditAnywhere, Category="Debugging Tools") @@ -76,6 +81,9 @@ public: // This is always true unless you use the debugger to set it to false. bool TickEnabled = true; + // True to trigger a source reload. + bool ReloadSource = false; + // Current Player ID int64 PlayerId = 0; diff --git a/luprex/cpp/core/source.cpp b/luprex/cpp/core/source.cpp index cbff7559..91e17715 100644 --- a/luprex/cpp/core/source.cpp +++ b/luprex/cpp/core/source.cpp @@ -278,7 +278,6 @@ void SourceDB::update(const util::LuaSourceVec &source) { for (int i = 0; i < int(source.size()); i++) { const eng::string &file = source[i].first; const eng::string &code = source[i].second; - util::dprint("Compiling ", file); LS.newtable(info); LS.rawset(info, "name", file); LS.rawset(info, "code", code); diff --git a/luprex/cpp/core/unit-testing.cpp b/luprex/cpp/core/unit-testing.cpp index 6c8014cf..dff24ae5 100644 --- a/luprex/cpp/core/unit-testing.cpp +++ b/luprex/cpp/core/unit-testing.cpp @@ -55,7 +55,7 @@ public: virtual void event_access(AccessKind kind, int64_t place_id, std::string_view datapk, StreamBuffer *retpk) override { switch (kind) { case AccessKind::INVOKE_LUA_SOURCE: { - world_->update_source(datapk); + world_->update_source(datapk, 0); run_unittests(world_->state()); stop_driver(); break; diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index bbc66a86..7d000713 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -523,6 +523,9 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view // This is called from World::update_source, and also // from World::patch_source in the difference transmitter. // +// When called from the difference transmitter, we suppress +// error messages. +// // For the moment, errors are channeled to util::dprint, // and 'print' statements just go to std::cerr. Neither // of these is ideal. We need to get serious about setting @@ -532,7 +535,7 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view // some lua source file tries to modify, say, tangible state // in top-level code. // -bool World::rebuild_sourcedb() { +bool World::rebuild_sourcedb(int64_t actor_id) { bool ok = true; for (const eng::string &mod: source_db_.modules()) { open_lthread_state(0, 0, 0, false); @@ -540,30 +543,28 @@ bool World::rebuild_sourcedb() { eng::string prints = lthread_prints_.str(); clear_lthread_state(); if (!err.empty()) ok = false; - if (!err.empty() || !prints.empty()) { - util::dprint("Loading Module ", mod); - if (!err.empty()) util::dprint(err); - if (!prints.empty()) util::dprint(prints); + if (actor_id >= 0) { + lthread_prints_ << "Compiling " << mod << std::endl; + if (!err.empty()) lthread_prints_ << err << std::endl; + if (!prints.empty()) lthread_prints_ << prints; + lthread_prints_to_actor(actor_id); } } + if (actor_id > 0) { + lthread_prints_ << (ok ? "Compilation Successful." : "Compilation Failed.") << std::endl; + lthread_prints_to_actor(actor_id); + } return ok; } -bool World::update_source(const util::LuaSourceVec &source) { +bool World::update_source(const util::LuaSourceVec &source, int64_t actor_id) { assert(stack_is_clear()); source_db_.update(source); - return rebuild_sourcedb(); + return rebuild_sourcedb(actor_id); assert(stack_is_clear()); } -bool World::update_source(const util::LuaSourcePtr &source) { - if (source == nullptr) { - return false; - } - return update_source(*source); -} - -bool World::update_source(std::string_view sourcepack) { +bool World::update_source(std::string_view sourcepack, int64_t actor_id) { if (sourcepack.empty()) { return false; } @@ -571,7 +572,7 @@ bool World::update_source(std::string_view sourcepack) { StreamBuffer sb(sourcepack); util::LuaSourceVec sv; SourceDB::deserialize_source(&sv, &sb); - return update_source(sv); + return update_source(sv, actor_id); } catch (const StreamException &ex) { return false; } @@ -697,7 +698,7 @@ HttpServerResponse World::http_serve(const HttpParser &request) { open_lthread_state(0, 0, 0, false); eng::string msg = traceback_pcall(L, 1, LUA_MULTRET); if (!msg.empty()) lthread_prints_ << msg << std::endl; - lthread_prints_to_dprint(); + lthread_prints_to_actor(0); clear_lthread_state(); // If the call threw an error, return @@ -954,7 +955,7 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_vi bool brand_new = (source_db_.modules().size() == 1); // Compile and load the source. - bool success = update_source(datapack); + bool success = update_source(datapack, actor_id); // Call world.init if (brand_new) { @@ -976,7 +977,7 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_vi util::dprint("You will need to fix the errors then run it manually."); } } - + // Run the new thread and return. assert(stack_is_clear()); } @@ -1096,7 +1097,7 @@ void World::run_scheduled_threads() { } LS.rawset(threads, sched.thread_id(), LuaNil); } - lthread_prints_to_printbuffer(); + lthread_prints_to_actor(lthread_actor_id_); clear_lthread_state(); } } @@ -1162,22 +1163,20 @@ void World::open_lthread_state(int64_t actor, int64_t place, int64_t thread, boo lthread_prints_.clear(); } -void World::lthread_prints_to_printbuffer() +void World::lthread_prints_to_actor(int64_t actor_id) { const eng::string &output = lthread_prints_.str(); if (output.size() > 0) { - Tangible *actor = tangible_get(lthread_actor_id_); - if (actor != nullptr) { - actor->print_buffer_.add_string(output, is_authoritative()); + if (actor_id >= 0) { + Tangible *actor = tangible_get(actor_id); + if (actor != nullptr) { + actor->print_buffer_.add_string(output, is_authoritative()); + } else { + util::dprintview(output); + } } - } -} - -void World::lthread_prints_to_dprint() -{ - const eng::string &output = lthread_prints_.str(); - if (output.size() > 0) { - util::dprintview(output); + lthread_prints_.str(""); + lthread_prints_.clear(); } } diff --git a/luprex/cpp/core/world-diffxmit.cpp b/luprex/cpp/core/world-diffxmit.cpp index b8ef1ae6..d3b05d21 100644 --- a/luprex/cpp/core/world-diffxmit.cpp +++ b/luprex/cpp/core/world-diffxmit.cpp @@ -292,7 +292,7 @@ void World::patch_source(StreamBuffer *sb, DebugCollector *dbc) { DebugBlock dbb(dbc, "patch_source"); bool modified = source_db_.patch(sb, dbc); if (modified) { - rebuild_sourcedb(); + rebuild_sourcedb(-1); DebugLine(dbc) << "Source DB rebuilt"; } } diff --git a/luprex/cpp/core/world.hpp b/luprex/cpp/core/world.hpp index a64c24ef..8a0110a3 100644 --- a/luprex/cpp/core/world.hpp +++ b/luprex/cpp/core/world.hpp @@ -284,19 +284,20 @@ public: // Rebuild the global environment from the source database. // + // Error messages go to the specified actor. + // // Returns true if the rebuild goes without errors. // - bool rebuild_sourcedb(); + bool rebuild_sourcedb(int64_t actor_id); // Update the source database from disk, then rebuild the global environment. // - // Special case: if the source pointer is nullptr, does not update. + // Error messages go to the specified actor. // // Returns true if the update goes without errors. // - bool update_source(const util::LuaSourceVec &source); - bool update_source(const util::LuaSourcePtr &source); - bool update_source(std::string_view sourcepk); + bool update_source(const util::LuaSourceVec &source, int64_t actor_id); + bool update_source(std::string_view sourcepk, int64_t actor_id); // Supply an HTTP response to an outstanding HTTP request. // @@ -375,8 +376,13 @@ public: std::ostream *lthread_print_stream() { return <hread_prints_; } - void lthread_prints_to_printbuffer(); - void lthread_prints_to_dprint(); + // Send the lthread_prints output to the specified actor. + // + // If actor_id == (-1) prints are discarded. + // If actor_id == (0) prints go to dprint. + // Anything else, and the prints go to a specific actor. + // + void lthread_prints_to_actor(int64_t actor_id); // Set a lua global variable. // diff --git a/luprex/lua/login.lua b/luprex/lua/login.lua index 379a1b8d..ce63b5b9 100644 --- a/luprex/lua/login.lua +++ b/luprex/lua/login.lua @@ -79,7 +79,7 @@ function engio.getlookat() return "" end - +print("Hello from login.lua") function jp3() tangible.animate{tan=actor, anim={action="play", seq="jump"}}