First attempt at error-resistant /cpl directive
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user