From 7104a523b537192e7e07240d0e4d397a3cdf6d6f Mon Sep 17 00:00:00 2001 From: jyelon Date: Thu, 19 Oct 2023 19:42:33 -0400 Subject: [PATCH] Less serialization and deserialization of Lua Source, also, Invocation is now simpler --- luprex/cpp/core/drivenengine.cpp | 42 ++++++++----------- luprex/cpp/core/drivenengine.hpp | 13 +++--- luprex/cpp/core/eng-tests.cpp | 2 +- luprex/cpp/core/enginewrapper.hpp | 4 +- luprex/cpp/core/gui.cpp | 2 +- luprex/cpp/core/gui.hpp | 2 +- luprex/cpp/core/invocation.cpp | 50 +++------------------- luprex/cpp/core/invocation.hpp | 53 ++++++++++++++++------- luprex/cpp/core/lpxclient.cpp | 17 ++++---- luprex/cpp/core/lpxserver.cpp | 4 +- luprex/cpp/core/printbuffer.cpp | 2 +- luprex/cpp/core/textgame.cpp | 4 +- luprex/cpp/core/world-core.cpp | 70 ++++++++++++++++--------------- luprex/cpp/core/world.hpp | 15 ++++--- luprex/cpp/drv/driver.cpp | 2 +- luprex/cpp/drv/drvutil.cpp | 2 - 16 files changed, 134 insertions(+), 150 deletions(-) diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index 840cd58c..1c64e525 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -165,8 +165,10 @@ void DrivenEngine::set_console_prompt(const eng::string &prompt) { console_prompt_ = prompt; } -util::LuaSourcePtr DrivenEngine::get_lua_source() { - return std::move(lua_source_); +eng::string DrivenEngine::get_lua_source_pack() { + eng::string result = std::move(lua_source_pack_); + lua_source_pack_.clear(); + return result; } void DrivenEngine::rescan_lua_source() { @@ -219,7 +221,7 @@ enum DrvAction { PLAY_NOTIFY_CLOSE, PLAY_NOTIFY_ACCEPT, PLAY_INVOKE_EVENT_UPDATE, - PLAY_SET_LUA_SOURCE, + PLAY_SET_LUA_SOURCE_PACK, PLAY_RELEASE, }; @@ -232,7 +234,7 @@ inline static const char *action_string(DrvAction act) { case PLAY_NOTIFY_CLOSE: return "PLAY_NOTIFY_CLOSE"; case PLAY_NOTIFY_ACCEPT: return "PLAY_NOTIFY_ACCEPT"; case PLAY_INVOKE_EVENT_UPDATE: return "PLAY_INVOKE_EVENT_UPDATE"; - case PLAY_SET_LUA_SOURCE: return "PLAY_SET_LUA_SOURCE"; + case PLAY_SET_LUA_SOURCE_PACK: return "PLAY_SET_LUA_SOURCE_PACK"; case PLAY_RELEASE: return "PLAY_RELEASE"; default: return "unknown"; } @@ -442,7 +444,7 @@ void DrivenEngine::drv_get_animation_queues(uint32_t count, const int64_t *ids, ////////////////////////////////////////////////////////////////////////////// void DrivenEngine::drv_initialize(uint32_t srcpklen, const char *srcpk, int argc, char **argv) { - drv_set_lua_source(srcpklen, srcpk); + drv_set_lua_source_pack(srcpklen, srcpk); event_init(argc, argv); } @@ -481,22 +483,12 @@ void DrivenEngine::drv_invoke_event_update(double clock) { event_update(); } -void DrivenEngine::drv_set_lua_source(uint32_t srcpklen, const char *srcpk) { - StreamBuffer sb(std::string_view(srcpk, srcpklen)); - uint32_t nfiles = sb.read_uint32(); - lua_source_.reset(new util::LuaSourceVec); - lua_source_->resize(nfiles); - for (uint32_t i = 0; i < nfiles; i++) { - (*lua_source_)[i].first = sb.read_string(); - } - for (uint32_t i = 0; i < nfiles; i++) { - (*lua_source_)[i].second = sb.read_string(); - } +void DrivenEngine::drv_set_lua_source_pack(uint32_t srcpklen, const char *srcpk) { + lua_source_pack_ = std::string_view(srcpk, srcpklen); rescan_lua_source_ = false; } - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // @@ -821,25 +813,25 @@ static void replay_invoke_event_update(EngineWrapper *w) { //////////////////////// -void play_set_lua_source(EngineWrapper *w, uint32_t srcpklen, const char *srcpk) { +void play_set_lua_source_pack(EngineWrapper *w, uint32_t srcpklen, const char *srcpk) { assert(w->rlog == nullptr); if (w->wlog != nullptr) { - w->wlog->write_cmd_hash(PLAY_SET_LUA_SOURCE, eng::memhash()); + w->wlog->write_cmd_hash(PLAY_SET_LUA_SOURCE_PACK, eng::memhash()); w->wlog->write_string(std::string_view(srcpk, srcpklen)); w->wlog->flush(); } - w->engine->drv_set_lua_source(srcpklen, srcpk); + w->engine->drv_set_lua_source_pack(srcpklen, srcpk); } -void replay_set_lua_source(EngineWrapper *w) { +void replay_set_lua_source_pack(EngineWrapper *w) { std::string srcpack = w->rlog->read_string(); if (!w->rlog->good()) { - return reset_wrapper(w, "replay log corrupt in replay_set_lua_source"); + return reset_wrapper(w, "replay log corrupt in replay_set_lua_source_pack"); } - w->engine->drv_set_lua_source(srcpack.size(), srcpack.c_str()); + w->engine->drv_set_lua_source_pack(srcpack.size(), srcpack.c_str()); } @@ -910,7 +902,7 @@ static void replaycore_step(EngineWrapper *w) { case PLAY_NOTIFY_CLOSE: replay_notify_close(w); return; case PLAY_NOTIFY_ACCEPT: replay_notify_accept(w); return; case PLAY_INVOKE_EVENT_UPDATE: replay_invoke_event_update(w); return; - case PLAY_SET_LUA_SOURCE: replay_set_lua_source(w); return; + case PLAY_SET_LUA_SOURCE_PACK: replay_set_lua_source_pack(w); return; case PLAY_RELEASE: release(w); return; default: return reset_wrapper(w, "Replay log corrupt in command dispatcher"); } @@ -971,7 +963,7 @@ static void init_engine_wrapper_helper(EngineWrapper *w) { w->play_notify_close = play_notify_close; w->play_notify_accept = play_notify_accept; w->play_invoke_event_update = play_invoke_event_update; - w->play_set_lua_source = play_set_lua_source; + w->play_set_lua_source_pack = play_set_lua_source_pack; w->replay_initialize = replaycore_initialize; w->replay_step = replaycore_step; diff --git a/luprex/cpp/core/drivenengine.hpp b/luprex/cpp/core/drivenengine.hpp index 0a29ef40..2591b459 100644 --- a/luprex/cpp/core/drivenengine.hpp +++ b/luprex/cpp/core/drivenengine.hpp @@ -210,10 +210,13 @@ public: // void set_console_prompt(const eng::string &prompt); - // Fetches the lua source, and takes ownership of it. The DrivenEngine - // no longer contains the source after calling this. + // Fetches the lua 'sourcepack'. The sourcepack is a packaged collection + // of all the lua sourcefiles, see drvutil::package_lua_source for + // documentation of the format. This also clears the sourcepack stored + // in the DrivenEngine. Returns empty string if there is no sourcepack + // in the DrivenEngine. // - util::LuaSourcePtr get_lua_source(); + eng::string get_lua_source_pack(); // Rescan the lua source directory. The lua source directory is read once, // automatically, at engine creation time. If you want to read it again, @@ -291,7 +294,7 @@ public: void drv_notify_close(uint32_t chid, uint32_t len, const char *data); uint32_t drv_notify_accept(uint32_t port); void drv_invoke_event_update(double clock); - void drv_set_lua_source(uint32_t srcpklen, const char *srcpk); + void drv_set_lua_source_pack(uint32_t srcpklen, const char *srcpk); private: // Find a currently-unused channel ID. Channel IDs @@ -308,12 +311,12 @@ private: std::unique_ptr stdostream_; eng::vector accepted_channels_; eng::vector new_outgoing_; - util::LuaSourcePtr lua_source_; eng::vector listen_ports_; World *visible_world_; int64_t visible_actor_id_; util::IdVector scan_result_; std::vector anim_queues_; + eng::string lua_source_pack_; bool rescan_lua_source_; double clock_; bool stop_driver_; diff --git a/luprex/cpp/core/eng-tests.cpp b/luprex/cpp/core/eng-tests.cpp index e4f17ba5..61037b76 100644 --- a/luprex/cpp/core/eng-tests.cpp +++ b/luprex/cpp/core/eng-tests.cpp @@ -115,7 +115,7 @@ private: void event_init(int argc, char *argv[]) { world_.reset(new World(WORLD_TYPE_MASTER)); - world_->update_source(get_lua_source()); + world_->update_source(get_lua_source_pack()); world_->run_unittests(); stop_driver(); } diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index d2946753..438b7476 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -102,7 +102,7 @@ struct EngineWrapper { // Check the 'rescan_lua_source' flag. If this flag is set, it means // that the engine wants the driver to rescan the lua source code. // When the driver sees this flag, it should rescan the source and call - // set_lua_source. + // set_lua_source_pack. // bool (*get_rescan_lua_source)(EngineWrapper *w); @@ -199,7 +199,7 @@ struct EngineWrapper { // Store the lua source code. // - void (*play_set_lua_source)(EngineWrapper *w, uint32_t srcpklen, const char *srcpk); + void (*play_set_lua_source_pack)(EngineWrapper *w, uint32_t srcpklen, const char *srcpk); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff --git a/luprex/cpp/core/gui.cpp b/luprex/cpp/core/gui.cpp index 475c7c82..d04a1a08 100644 --- a/luprex/cpp/core/gui.cpp +++ b/luprex/cpp/core/gui.cpp @@ -30,7 +30,7 @@ void Gui::menu_item(const eng::string &action, const eng::string &label) { elts_.push_back(elt); } -bool Gui::has_action(const eng::string &action) const { +bool Gui::has_action(std::string_view action) const { for (const GuiElt &elt : elts_) { if (elt.action_ == action) { return true; diff --git a/luprex/cpp/core/gui.hpp b/luprex/cpp/core/gui.hpp index a9ef03e0..6ff5c787 100644 --- a/luprex/cpp/core/gui.hpp +++ b/luprex/cpp/core/gui.hpp @@ -38,7 +38,7 @@ public: int64_t place() { return place_; } const EltVec &elts() const { return elts_; } void clear(int64_t p) { place_ = p; elts_.clear(); } - bool has_action(const eng::string &action) const; + bool has_action(std::string_view action) const; void menu_item(const eng::string &action, const eng::string &label); eng::string get_action(int64_t index); eng::string menu_debug_string() const; diff --git a/luprex/cpp/core/invocation.cpp b/luprex/cpp/core/invocation.cpp index d22ddec3..1a9eedf7 100644 --- a/luprex/cpp/core/invocation.cpp +++ b/luprex/cpp/core/invocation.cpp @@ -6,57 +6,24 @@ #include "invocation.hpp" -const eng::string &InvocationData::get(const eng::string &key) const { - static eng::string blank_; - auto iter = find(key); - if (iter == end()) { - return blank_; - } else { - return iter->second; - } -} - -void InvocationData::serialize(StreamBuffer *sb) const { - assert(int(size()) < 65536); - sb->write_uint16(size()); - for (const auto &pair : *this) { - sb->write_string(pair.first); - sb->write_string(pair.second); - } -} - -void InvocationData::deserialize(StreamBuffer *sb) { - clear(); - int size = sb->read_uint16(); - for (int i = 0; i < size; i++) { - eng::string key = sb->read_string(); - eng::string val = sb->read_string(); - (*this)[key] = val; - } -} - Invocation::Invocation() : kind_(KIND_INVALID), actor_(0), place_(0) {} -Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action, const InvocationData &data) - : kind_(kind), actor_(actor), place_(place), action_(action), data_(data) {} - -Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action) - : kind_(kind), actor_(actor), place_(place), action_(action) {} +Invocation::Invocation(Kind kind, int64_t actor, int64_t place, std::string_view datapack) + : kind_(kind), actor_(actor), place_(place), datapack_(datapack) {} + void Invocation::serialize(StreamBuffer *sb) const { sb->write_uint8(kind_); sb->write_int64(actor_); sb->write_int64(place_); - sb->write_string(action_); - data_.serialize(sb); + sb->write_string(datapack_); } void Invocation::deserialize(StreamBuffer *sb) { kind_ = Kind(sb->read_uint8()); actor_ = sb->read_int64(); place_ = sb->read_int64(); - action_ = sb->read_string(); - data_.deserialize(sb); + datapack_ = sb->read_string(); } eng::string Invocation::debug_string() const { @@ -73,12 +40,7 @@ eng::string Invocation::debug_string() const { } oss << " a=" << actor_; oss << " p=" << place_; - if (kind_ != KIND_LUA_SOURCE) { - oss << " " << action_; - } - for (const auto &pair : data_) { - oss << " " << pair.first << "=" << pair.second; - } + oss << " dp=" << datapack_.size() << " bytes"; oss << "]"; return oss.str(); } diff --git a/luprex/cpp/core/invocation.hpp b/luprex/cpp/core/invocation.hpp index e8c59af5..4a2a6fc9 100644 --- a/luprex/cpp/core/invocation.hpp +++ b/luprex/cpp/core/invocation.hpp @@ -1,3 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// DATAPACK +// +// Invocations contain a field 'datapack' which contains additional +// data for the invocation, packed up in a serialized format. Executing +// the invocation involves unpacking the datapack. +// +// The actual contents of the datapack depends on the type of invocation: +// +// KIND_INVALID: +// +// Nothing. +// +// KIND_PLAN: +// +// Name of a callback function, in plaintext. +// +// KIND_LUA: +// +// A block of lua source code, in plaintext. +// +// KIND_FLUSH_PRINTS: +// +// Line number in ascii. +// +// KIND_TICK: +// +// Nothing. +// +// KIND_LUA_SOURCE: +// +// Packaged lua sourcecode. See drvutil::package_lua_source. +// +////////////////////////////////////////////////////////////////////////// + #ifndef INVOCATION_HPP #define INVOCATION_HPP @@ -8,14 +44,6 @@ #include "streambuffer.hpp" -class InvocationData : public eng::map { -public: - const eng::string &get(const eng::string &key) const; - - void serialize(StreamBuffer *sb) const; - void deserialize(StreamBuffer *sb); -}; - class Invocation : public eng::nevernew { public: enum Kind { @@ -31,19 +59,16 @@ private: Kind kind_; int64_t actor_; int64_t place_; - eng::string action_; - InvocationData data_; + eng::string datapack_; public: Invocation(); - Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action, const InvocationData &data); - Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action); + Invocation(Kind kind, int64_t actor, int64_t place, std::string_view datapack); bool valid() const { return kind_ != KIND_INVALID; } Kind kind() const { return kind_; } int64_t actor() const { return actor_; } int64_t place() const { return place_; } - const eng::string &action() const { return action_; } - const InvocationData &data() const { return data_; } + const eng::string &datapack() const { return datapack_; } void serialize(StreamBuffer *sb) const; void deserialize(StreamBuffer *sb); diff --git a/luprex/cpp/core/lpxclient.cpp b/luprex/cpp/core/lpxclient.cpp index 1f54908c..872d4a25 100644 --- a/luprex/cpp/core/lpxclient.cpp +++ b/luprex/cpp/core/lpxclient.cpp @@ -81,7 +81,7 @@ public: // The driver loads the lua source automatically. // However, we don't need it. Throw it out. - get_lua_source(); + get_lua_source_pack(); } void send_invocation(const Invocation &inv) { @@ -97,11 +97,8 @@ public: inv.serialize(sb); } - void send_lua_source(const util::LuaSourceVec &sv) { - StreamBuffer serial; - SourceDB::serialize_source(sv, &serial); - eng::string sstr(serial.view()); - Invocation inv(Invocation::KIND_LUA_SOURCE, actor_id_, actor_id_, sstr); + void send_lua_source(std::string_view sourcepack) { + Invocation inv(Invocation::KIND_LUA_SOURCE, actor_id_, actor_id_, sourcepack); send_invocation(inv); } @@ -239,10 +236,10 @@ public: virtual void event_update() { // Check for lua source code. If this returns non-null, // it is because somebody typed CPL. - util::LuaSourcePtr lua_source = get_lua_source(); - if (lua_source != nullptr) { - send_lua_source(*lua_source); - lua_source.reset(); + eng::string lua_source_pack = get_lua_source_pack(); + if (!lua_source_pack.empty()) { + send_lua_source(lua_source_pack); + lua_source_pack.clear(); } // Check for keyboard input on stdin. diff --git a/luprex/cpp/core/lpxserver.cpp b/luprex/cpp/core/lpxserver.cpp index f476ba95..0134d562 100644 --- a/luprex/cpp/core/lpxserver.cpp +++ b/luprex/cpp/core/lpxserver.cpp @@ -36,7 +36,7 @@ public: master_.reset(new World(WORLD_TYPE_MASTER)); // Update the source code of the master model. - master_->update_source(get_lua_source()); + master_->update_source(get_lua_source_pack()); // Create an actor for administrative commands. admin_id_ = master_->create_login_actor(); @@ -168,7 +168,7 @@ public: virtual void event_update() { // If the driver has reloaded the source, put it into master model. - master_->update_source(get_lua_source()); + master_->update_source(get_lua_source_pack()); // Check for keyboard input on stdin. while (true) { diff --git a/luprex/cpp/core/printbuffer.cpp b/luprex/cpp/core/printbuffer.cpp index 55d029fb..70a77070 100644 --- a/luprex/cpp/core/printbuffer.cpp +++ b/luprex/cpp/core/printbuffer.cpp @@ -192,7 +192,7 @@ bool PrintChanneler::channel(const PrintBuffer *printbuffer, std::ostream &ostre Invocation PrintChanneler::invocation(int64_t actor_id) { char buf[80]; sprintf(buf, "%" PRId64, line_); - return Invocation(Invocation::KIND_FLUSH_PRINTS, actor_id, actor_id, buf, InvocationData()); + return Invocation(Invocation::KIND_FLUSH_PRINTS, actor_id, actor_id, buf); } LuaDefine(unittests_printbuffer, "", "some unit tests") { diff --git a/luprex/cpp/core/textgame.cpp b/luprex/cpp/core/textgame.cpp index 3a7b86f5..e004a98f 100644 --- a/luprex/cpp/core/textgame.cpp +++ b/luprex/cpp/core/textgame.cpp @@ -99,7 +99,7 @@ private: void event_init(int argc, char *argv[]) { world_.reset(new World(WORLD_TYPE_MASTER)); - world_->update_source(get_lua_source()); + world_->update_source(get_lua_source_pack()); world_->run_unittests(); actor_id_ = world_->create_login_actor(); stdostream() << "Login actor ID: " << actor_id_ << std::endl; @@ -108,7 +108,7 @@ private: void event_update() { - world_->update_source(get_lua_source()); + world_->update_source(get_lua_source_pack()); while (true) { eng::string line = get_stdio_channel()->in()->readline(); if (line == "") break; diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index 1b3aaf7d..ea91edd3 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -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) { diff --git a/luprex/cpp/core/world.hpp b/luprex/cpp/core/world.hpp index 84bba880..02ded864 100644 --- a/luprex/cpp/core/world.hpp +++ b/luprex/cpp/core/world.hpp @@ -220,9 +220,12 @@ public: // Update the source database from disk. // // Special case: if the source pointer is nullptr, does not update. + // The final form takes a sourcepk, a serialized representation + // of a LuaSourceVec. // - void update_source(const util::LuaSourcePtr &source); void update_source(const util::LuaSourceVec &source); + void update_source(const util::LuaSourcePtr &source); + void update_source(std::string_view sourcepk); // Rebuild the source database. // @@ -348,23 +351,23 @@ private: // Invoke a plan. // - void invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data); + void invoke_plan(int64_t actor_id, int64_t place_id, std::string_view datapack); // Invoke a lua string. // - void invoke_lua(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data); + void invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack); // Invoke the flush-prints operation. // - void invoke_flush_prints(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data); + void invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_view datapack); // Invoke the tick operation. // - void invoke_tick(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data); + void invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack); // Invoke the lua_source operation. // - void invoke_lua_source(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data); + void invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack); public: //////////////////////////////////////////////////////////////////////////// diff --git a/luprex/cpp/drv/driver.cpp b/luprex/cpp/drv/driver.cpp index 6a9705b4..1c0f4707 100644 --- a/luprex/cpp/drv/driver.cpp +++ b/luprex/cpp/drv/driver.cpp @@ -193,7 +193,7 @@ class Driver { std::string err = drvutil::package_lua_source(".", &oss); if_error_print_and_exit(err); std::string_view ossv = oss.view(); - engw.play_set_lua_source(&engw, ossv.size(), ossv.data()); + engw.play_set_lua_source_pack(&engw, ossv.size(), ossv.data()); } } diff --git a/luprex/cpp/drv/drvutil.cpp b/luprex/cpp/drv/drvutil.cpp index 50c8fee2..310ff26f 100644 --- a/luprex/cpp/drv/drvutil.cpp +++ b/luprex/cpp/drv/drvutil.cpp @@ -345,8 +345,6 @@ std::string package_lua_source(const std::filesystem::path &base, std::ostream * sbwrite_uint32(s, names.size()); for (int i = 0; i < int(names.size()); i++) { sbwrite_string(s, names[i]); - } - for (int i = 0; i < int(names.size()); i++) { std::filesystem::path lfn = base / "lua" / names[i]; if (!sbwrite_file(s, lfn)) { return std::string("Cannot read source file: ") + lfn.u8string();