Less serialization and deserialization of Lua Source, also, Invocation is now simpler

This commit is contained in:
2023-10-19 19:42:33 -04:00
parent 049b0b893a
commit 7104a523b5
16 changed files with 134 additions and 150 deletions

View File

@@ -357,12 +357,6 @@ void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
}
}
void World::update_source(const util::LuaSourcePtr &source) {
if (source != nullptr) {
update_source(*source);
}
}
// This is called from World::update_source, and also
// from World::patch_source in the difference transmitter.
//
@@ -397,6 +391,25 @@ void World::update_source(const util::LuaSourceVec &source) {
assert(stack_is_clear());
}
void World::update_source(const util::LuaSourcePtr &source) {
if (source != nullptr) {
update_source(*source);
}
}
void World::update_source(std::string_view sourcepack) {
if (!sourcepack.empty()) {
try {
StreamBuffer sb(sourcepack);
util::LuaSourceVec sv;
SourceDB::deserialize_source(&sv, &sb);
update_source(sv);
} catch (const StreamException &ex) {
return;
}
}
}
void World::http_response(const HttpParser &response) {
// Find the request.
auto iter = http_requests_.find(response.request_id());
@@ -554,19 +567,19 @@ void World::run_unittests() {
void World::invoke(const Invocation &inv) {
switch (inv.kind()) {
case Invocation::KIND_PLAN:
invoke_plan(inv.actor(), inv.place(), inv.action(), inv.data());
invoke_plan(inv.actor(), inv.place(), inv.datapack());
break;
case Invocation::KIND_LUA:
invoke_lua(inv.actor(), inv.place(), inv.action(), inv.data());
invoke_lua(inv.actor(), inv.place(), inv.datapack());
break;
case Invocation::KIND_FLUSH_PRINTS:
invoke_flush_prints(inv.actor(), inv.place(), inv.action(), inv.data());
invoke_flush_prints(inv.actor(), inv.place(), inv.datapack());
break;
case Invocation::KIND_TICK:
invoke_tick(inv.actor(), inv.place(), inv.action(), inv.data());
invoke_tick(inv.actor(), inv.place(), inv.datapack());
break;
case Invocation::KIND_LUA_SOURCE:
invoke_lua_source(inv.actor(), inv.place(), inv.action(), inv.data());
invoke_lua_source(inv.actor(), inv.place(), inv.datapack());
break;
default:
// Do nothing. Standard behavior for any invalid command is to
@@ -578,13 +591,13 @@ void World::invoke(const Invocation &inv) {
}
}
void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data) {
void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_view datapack) {
assert(stack_is_clear());
// Check argument sanity.
if (actor_id != place_id) {
return;
}
int64_t line = sv::to_int64(action, -1);
int64_t line = sv::to_int64(datapack, -1);
if ((line < 0)||(line > INT_MAX)) {
return;
}
@@ -598,7 +611,7 @@ void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, const eng::s
void World::invoke_lua(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data) {
void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack) {
assert(stack_is_clear());
// Make sure that actor and place exist and are not stubs.
@@ -618,7 +631,7 @@ void World::invoke_lua(int64_t actor_id, int64_t place_id, const eng::string &ac
LuaExtStack LS(L, func, tangibles, place, mt, thread, thinfo, threads);
// create the compiled closure.
int status = luaL_loadbuffer(L, action.c_str(), action.size(), "=invoke");
int status = luaL_loadbuffer(L, datapack.data(), datapack.size(), "=invoke");
lua_replace(L, func.index());
if (status != LUA_OK) {
// The closure is actually an error message. Do nothing.
@@ -666,18 +679,18 @@ void World::invoke_lua(int64_t actor_id, int64_t place_id, const eng::string &ac
assert(stack_is_clear());
}
void World::invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data) {
void World::invoke_plan(int64_t actor_id, int64_t place_id, std::string_view datapack) {
assert(stack_is_clear());
// Validate that the action is legal.
Gui validation_gui;
update_gui(actor_id, place_id, &validation_gui);
if (!validation_gui.has_action(action)) {
if (!validation_gui.has_action(datapack)) {
return;
}
// Make sure the action starts with "cb_"
if (!sv::has_prefix(action, "cb_")) {
if (!sv::has_prefix(datapack, "cb_")) {
return;
}
@@ -715,16 +728,14 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &a
if (!LS.istable(index)) {
return;
}
LS.rawget(func, index, action);
LS.rawget(func, index, datapack);
if (!LS.isfunction(func)) {
return;
}
// Convert the InvocationData into a lua table.
// TODO: maybe add the ability to pass data in as a table?
// For now the table is always empty.
LS.newtable(invdata);
for (const auto &p : data) {
LS.rawset(invdata, p.first, p.second);
}
// Create a new thread, set up function and parameters.
lua_State *CO = LS.newthread(thread);
@@ -757,7 +768,7 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &a
assert(stack_is_clear());
}
void World::invoke_tick(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data) {
void World::invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack) {
if (!is_authoritative()) {
return;
}
@@ -765,19 +776,12 @@ void World::invoke_tick(int64_t actor_id, int64_t place_id, const eng::string &a
run_scheduled_threads();
}
void World::invoke_lua_source(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data) {
void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack) {
if (!is_authoritative()) {
return;
}
// We need some kind of authentication here.
try {
StreamBuffer sb(action);
util::LuaSourceVec sv;
SourceDB::deserialize_source(&sv, &sb);
update_source(sv);
} catch (const StreamException &ex) {
return;
}
update_source(datapack);
}
void World::guard_blockable(lua_State *L, const char *fn) {