Less serialization and deserialization of Lua Source, also, Invocation is now simpler
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user