CPL command

This commit is contained in:
2026-05-26 15:07:42 -04:00
parent 933c1ac6c3
commit 8dab0d16b7
9 changed files with 64 additions and 47 deletions

Binary file not shown.

View File

@@ -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;
}

View File

@@ -63,6 +63,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")
ElxBreakToDebuggerThreshold BreakToDebuggerLogVerbosity;
@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {
@@ -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,24 +1163,22 @@ 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_id >= 0) {
Tangible *actor = tangible_get(actor_id);
if (actor != nullptr) {
actor->print_buffer_.add_string(output, is_authoritative());
}
}
}
void World::lthread_prints_to_dprint()
{
const eng::string &output = lthread_prints_.str();
if (output.size() > 0) {
} else {
util::dprintview(output);
}
}
lthread_prints_.str("");
lthread_prints_.clear();
}
}
void World::set_global(const eng::string &gvar, std::string_view value) {

View File

@@ -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";
}
}

View File

@@ -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 &lthread_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.
//

View File

@@ -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"}}