First attempt at error-resistant /cpl directive

This commit is contained in:
2026-06-08 17:47:10 -04:00
parent 53a06281fd
commit 6a230e3ab2
9 changed files with 169 additions and 203 deletions

View File

@@ -572,71 +572,6 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view
clear_lthread_state();
}
// 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
// up error handling.
//
// We also need to figure out a solution for what happens if
// some lua source file tries to modify, say, tangible state
// in top-level code.
//
bool World::rebuild_sourcedb(int64_t actor_id) {
int successes = 0;
int failures = 0;
for (const eng::string &mod: source_db_.modules()) {
open_lthread_state(0, 0, 0, false);
eng::string err = source_db_.rebuild_module(mod);
eng::string prints = lthread_prints_.str();
clear_lthread_state();
if (err.empty()) successes ++;
else failures ++;
if ((!err.empty()) || (!prints.empty())) {
lthread_prints_ << "Compiling " << mod << ":" << std::endl;
if (!err.empty()) lthread_prints_ << err << std::endl;
if (!prints.empty()) lthread_prints_ << prints;
util::dprintview(lthread_prints_.view());
if (actor_id != 0) lthread_prints_to_actor(actor_id);
}
}
source_db_.rebuild_funcnames();
lthread_prints_ << "Compiled " << successes << " modules successfully." << std::endl;
if (failures > 0) {
lthread_prints_ << "Compiled " << failures << " modules with errors." << std::endl;
}
util::dprintview(lthread_prints_.view());
if (actor_id > 0) lthread_prints_to_actor(actor_id);
return (failures == 0);
}
bool World::update_source(const util::LuaSourceVec &source, int64_t actor_id) {
assert(stack_is_clear());
source_db_.update(source);
return rebuild_sourcedb(actor_id);
assert(stack_is_clear());
}
bool World::update_source(std::string_view sourcepack, int64_t actor_id) {
if (sourcepack.empty()) {
return false;
}
try {
StreamBuffer sb(sourcepack);
util::LuaSourceVec sv;
SourceDB::deserialize_source(&sv, &sb);
return update_source(sv, actor_id);
} catch (const StreamException &ex) {
return false;
}
}
void World::http_response(const HttpParser &response) {
// Find the request.
auto iter = http_requests_.find(response.request_id());
@@ -1019,14 +954,27 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_vi
if (actor_id != place_id) return;
// Check if this is the first time we're loading the source.
bool brand_new = (source_db_.modules().size() == 1);
bool brand_new = (source_db_.modules().size() == 0);
// Compile and load the source.
bool success = update_source(datapack, actor_id);
// Deserialize the datapack.
util::LuaSourceVec sv = SourceDB::deserialize_source(datapack);
if (sv.empty()) return;
// Try to compile the code.
open_lthread_state(actor_id, actor_id, 0, false);
eng::string errors = source_db_.update(sv);
if (errors.empty()) {
lthread_prints_ << "Compiled source successfully.\n";
} else {
lthread_prints_ << "Compiling source: \n" << errors;
}
util::dprint(lthread_prints_.view());
lthread_prints_to_actor(actor_id);
// Call world.init
if (brand_new) {
if (success) {
if (errors.empty()) {
{
lua_State *L = state();
LuaVar lclass, lfunc;