diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index 6198d431..6148ab6f 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -221,8 +221,7 @@ enum DrvAction { PLAY_NOTIFY_CLOSE, PLAY_NOTIFY_ACCEPT, PLAY_CALL_EVENT_UPDATE, - PLAY_INVOKE_LUA_CALL, - PLAY_INVOKE_LUA_SOURCE, + PLAY_INVOKE, PLAY_RELEASE, }; @@ -235,8 +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_CALL_EVENT_UPDATE: return "PLAY_CALL_EVENT_UPDATE"; - case PLAY_INVOKE_LUA_CALL: return "PLAY_INVOKE_LUA_CALL"; - case PLAY_INVOKE_LUA_SOURCE: return "PLAY_INVOKE_LUA_SOURCE"; + case PLAY_INVOKE: return "PLAY_INVOKE_LUA_CALL"; case PLAY_RELEASE: return "PLAY_RELEASE"; default: return "unknown"; } @@ -483,15 +481,10 @@ void DrivenEngine::drv_call_event_update(double clock) { event_update(); } -void DrivenEngine::drv_invoke_lua_call(int64_t place, uint32_t datapklen, const char *datapk) { - Invocation *inv = new Invocation(Invocation::KIND_LUA_CALL, visible_actor_id_, place, std::string_view(datapk, datapklen)); +void DrivenEngine::drv_invoke(InvocationKind kind, int64_t place, uint32_t datapklen, const char *datapk) { + Invocation *inv = new Invocation(kind, visible_actor_id_, place, std::string_view(datapk, datapklen)); queued_invocations_.emplace_back(inv); -} - -void DrivenEngine::drv_invoke_lua_source(uint32_t srcpklen, const char *srcpk) { - Invocation *inv = new Invocation(Invocation::KIND_LUA_SOURCE, visible_actor_id_, visible_actor_id_, std::string_view(srcpk, srcpklen)); - queued_invocations_.emplace_back(inv); - rescan_lua_source_ = false; + if (kind == InvocationKind::LUA_SOURCE) rescan_lua_source_ = false; } ////////////////////////////////////////////////////////////////////////////// @@ -818,49 +811,28 @@ static void replay_invoke_event_update(EngineWrapper *w) { //////////////////////// -void play_invoke_lua_call(EngineWrapper *w, int64_t place, uint32_t datapklen, const char *datapk) { +void play_invoke(EngineWrapper *w, InvocationKind kind, int64_t place, uint32_t datapklen, const char *datapk) { assert(w->rlog == nullptr); if (w->wlog != nullptr) { - w->wlog->write_cmd_hash(PLAY_INVOKE_LUA_CALL, eng::memhash()); + w->wlog->write_cmd_hash(PLAY_INVOKE, eng::memhash()); + w->wlog->write_uint8(int64_t(kind)); w->wlog->write_int64(place); w->wlog->write_string(std::string_view(datapk, datapklen)); w->wlog->flush(); } - w->engine->drv_invoke_lua_call(place, datapklen, datapk); + w->engine->drv_invoke(kind, place, datapklen, datapk); } -void replay_invoke_lua_call(EngineWrapper *w) { +void replay_invoke(EngineWrapper *w) { + InvocationKind kind = InvocationKind(w->rlog->read_uint8()); int64_t place = w->rlog->read_int64(); std::string srcpack = w->rlog->read_string(); if (!w->rlog->good()) { return reset_wrapper(w, "replay log corrupt in replay_invoke_lua_call"); } - w->engine->drv_invoke_lua_call(place, srcpack.size(), srcpack.c_str()); -} - -//////////////////////// - - -void play_invoke_lua_source(EngineWrapper *w, uint32_t srcpklen, const char *srcpk) { - assert(w->rlog == nullptr); - if (w->wlog != nullptr) { - w->wlog->write_cmd_hash(PLAY_INVOKE_LUA_SOURCE, eng::memhash()); - w->wlog->write_string(std::string_view(srcpk, srcpklen)); - w->wlog->flush(); - } - - w->engine->drv_invoke_lua_source(srcpklen, srcpk); -} - -void replay_invoke_lua_source(EngineWrapper *w) { - std::string srcpack = w->rlog->read_string(); - if (!w->rlog->good()) { - return reset_wrapper(w, "replay log corrupt in replay_invoke_lua_source"); - } - - w->engine->drv_invoke_lua_source(srcpack.size(), srcpack.c_str()); + w->engine->drv_invoke(kind, place, srcpack.size(), srcpack.c_str()); } @@ -931,8 +903,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_CALL_EVENT_UPDATE: replay_invoke_event_update(w); return; - case PLAY_INVOKE_LUA_CALL: replay_invoke_lua_call(w); return; - case PLAY_INVOKE_LUA_SOURCE: replay_invoke_lua_source(w); return; + case PLAY_INVOKE: replay_invoke(w); return; case PLAY_RELEASE: release(w); return; default: return reset_wrapper(w, "Replay log corrupt in command dispatcher"); } @@ -993,8 +964,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_invoke_lua_call = play_invoke_lua_call; - w->play_invoke_lua_source = play_invoke_lua_source; + w->play_invoke = play_invoke; 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 4521153f..880ea53c 100644 --- a/luprex/cpp/core/drivenengine.hpp +++ b/luprex/cpp/core/drivenengine.hpp @@ -152,6 +152,11 @@ public: // virtual void event_update() = 0; + // // The probe callback. You may override this in a subclass. + // // This will be called whenever the driver wants to probe the state of the world. + // // + // virtual void event_probe(InvocationKind kind, int64_t place, std::string_view datapack, StreamBuffer *retvals) = 0; + // Specify the set of listening ports. // This can only be used during the init routine. // @@ -293,8 +298,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_call_event_update(double clock); - void drv_invoke_lua_call(int64_t place, uint32_t datapklen, const char *datapk); - void drv_invoke_lua_source(uint32_t srcpklen, const char *srcpk); + void drv_invoke(InvocationKind kind, int64_t place, uint32_t datapklen, const char *datapk); private: // Find a currently-unused channel ID. Channel IDs diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index e461d27c..900030e4 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -20,6 +20,15 @@ #define DRV_ERRMSG_SIZE 8192 #define DRV_SHORTSTRING_SIZE 65536 +enum class InvocationKind { + INVALID, + LUA_CALL, + LUA_EXPR, + LUA_SOURCE, + FLUSH_PRINTS, + TICK, +}; + class DrivenEngine; class PlayLogfile; class ReplayLogfile; @@ -197,21 +206,12 @@ struct EngineWrapper { // void (*play_invoke_event_update)(EngineWrapper *w, double clock); - // Send an invoke/KIND_LUA_CALL + // Send an invoke. // // This is the main pathway for blueprints, or the unreal C++ code, - // to reach into lua. The datapack mus contain a classname, a function - // name, and then arguments for the function. + // to change the state of the world. // - void (*play_invoke_lua_call)(EngineWrapper *w, int64_t place, uint32_t datapklen, const char *datapk); - - // Send an invoke/KIND_LUA_SOURCE - // - // This is used to update the lua source at runtime, without stopping - // the game. In addition to sending the invoke/KIND_LUA_SOURCE, it also - // clears the rescan_lua_source flag. - // - void (*play_invoke_lua_source)(EngineWrapper *w, uint32_t srcpklen, const char *srcpk); + void (*play_invoke)(EngineWrapper *w, InvocationKind kind, int64_t place, uint32_t datapklen, const char *datapk); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff --git a/luprex/cpp/core/invocation.cpp b/luprex/cpp/core/invocation.cpp index 4e2d1839..155f6f91 100644 --- a/luprex/cpp/core/invocation.cpp +++ b/luprex/cpp/core/invocation.cpp @@ -6,21 +6,21 @@ #include "invocation.hpp" -Invocation::Invocation() : kind_(KIND_INVALID), actor_(0), place_(0) {} +Invocation::Invocation() : kind_(InvocationKind::INVALID), actor_(0), place_(0) {} -Invocation::Invocation(Kind kind, int64_t actor, int64_t place, std::string_view datapack) +Invocation::Invocation(InvocationKind 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_uint8(int64_t(kind_)); sb->write_int64(actor_); sb->write_int64(place_); sb->write_string(datapack_); } void Invocation::deserialize(StreamBuffer *sb) { - kind_ = Kind(sb->read_uint8()); + kind_ = InvocationKind(sb->read_uint8()); actor_ = sb->read_int64(); place_ = sb->read_int64(); datapack_ = sb->read_string(); @@ -30,12 +30,12 @@ eng::string Invocation::debug_string() const { eng::ostringstream oss; oss << "inv["; switch (kind_) { - case KIND_INVALID: oss << "invalid"; break; - case KIND_LUA_CALL: oss << "lua_call"; break; - case KIND_LUA: oss << "lua"; break; - case KIND_FLUSH_PRINTS: oss << "flush_prints"; break; - case KIND_TICK: oss << "tick"; break; - case KIND_LUA_SOURCE: oss << "lua_source"; break; + case InvocationKind::INVALID: oss << "invalid"; break; + case InvocationKind::LUA_CALL: oss << "lua_call"; break; + case InvocationKind::LUA_EXPR: oss << "lua"; break; + case InvocationKind::FLUSH_PRINTS: oss << "flush_prints"; break; + case InvocationKind::TICK: oss << "tick"; break; + case InvocationKind::LUA_SOURCE: oss << "lua_source"; break; default: oss << "UNKNOWN"; break; } oss << " a=" << actor_; diff --git a/luprex/cpp/core/invocation.hpp b/luprex/cpp/core/invocation.hpp index 5af94798..3ade9986 100644 --- a/luprex/cpp/core/invocation.hpp +++ b/luprex/cpp/core/invocation.hpp @@ -8,28 +8,28 @@ // // The actual contents of the datapack depends on the type of invocation: // -// KIND_INVALID: +// InvocationKind::INVALID: // // Nothing. // -// KIND_LUA_CALL: +// InvocationKind::LUA_CALL: // // A lua function call. The class name, the function name, and then // the function arguments. // -// KIND_LUA: +// InvocationKind::LUA_EXPR: // // A block of lua source code, in plaintext. // -// KIND_FLUSH_PRINTS: +// InvocationKind::FLUSH_PRINTS: // // Line number in ascii. // -// KIND_TICK: +// InvocationKind::TICK: // // Nothing. // -// KIND_LUA_SOURCE: +// InvocationKind::LUA_SOURCE: // // Packaged lua sourcecode. See drvutil::package_lua_source. // @@ -42,30 +42,22 @@ #include "wrap-map.hpp" #include "wrap-deque.hpp" #include "streambuffer.hpp" +#include "enginewrapper.hpp" class Invocation : public eng::opnew { public: - enum Kind { - KIND_INVALID, - KIND_LUA_CALL, - KIND_LUA, - KIND_FLUSH_PRINTS, - KIND_TICK, - KIND_LUA_SOURCE, - }; - private: - Kind kind_; + InvocationKind kind_; int64_t actor_; int64_t place_; eng::string datapack_; public: Invocation(); - Invocation(Kind kind, int64_t actor, int64_t place, std::string_view datapack); + Invocation(InvocationKind kind, int64_t actor, int64_t place, std::string_view datapack); - bool valid() const { return kind_ != KIND_INVALID; } - Kind kind() const { return kind_; } + bool valid() const { return kind_ != InvocationKind::INVALID; } + InvocationKind kind() const { return kind_; } int64_t actor() const { return actor_; } int64_t place() const { return place_; } const eng::string &datapack() const { return datapack_; } diff --git a/luprex/cpp/core/lpxclient.cpp b/luprex/cpp/core/lpxclient.cpp index 68b451a7..6b9dcf0d 100644 --- a/luprex/cpp/core/lpxclient.cpp +++ b/luprex/cpp/core/lpxclient.cpp @@ -116,7 +116,7 @@ public: void send_invocation(const Invocation &inv) { if (channel_ == nullptr) { - if ((!world_->is_authoritative()) && (inv.kind() == Invocation::KIND_LUA_SOURCE)) { + if ((!world_->is_authoritative()) && (inv.kind() == InvocationKind::LUA_SOURCE)) { // We have a client model, but no client connection. That means we're // in the process of shutting down a client model. The client model // is supposed to linger until the lua source is reread. Once we have @@ -178,7 +178,7 @@ public: } virtual void do_luainvoke_command(std::string_view cmd) override { - send_invocation(Invocation(Invocation::KIND_LUA, actor_id_, actor_id_, cmd)); + send_invocation(Invocation(InvocationKind::LUA_EXPR, actor_id_, actor_id_, cmd)); } virtual void do_luaprobe_command(std::string_view cmd) override { diff --git a/luprex/cpp/core/lpxserver.cpp b/luprex/cpp/core/lpxserver.cpp index 47267c21..26ee9b98 100644 --- a/luprex/cpp/core/lpxserver.cpp +++ b/luprex/cpp/core/lpxserver.cpp @@ -134,7 +134,7 @@ public: } virtual void do_luainvoke_command(std::string_view cmd) override { - master_->invoke(Invocation(Invocation::KIND_LUA, admin_id_, admin_id_, cmd)); + master_->invoke(Invocation(InvocationKind::LUA_EXPR, admin_id_, admin_id_, cmd)); } virtual void do_luaprobe_command(std::string_view cmd) override { @@ -243,7 +243,7 @@ public: // If the clock has advanced far enough, tick the master model. if (clock >= next_tick_) { - master_->invoke(Invocation(Invocation::KIND_TICK, 0, 0, "")); + master_->invoke(Invocation(InvocationKind::TICK, 0, 0, "")); for (UniqueClient &client : clients_) { client->async_diff_ = true; } diff --git a/luprex/cpp/core/printbuffer.cpp b/luprex/cpp/core/printbuffer.cpp index c1daff88..90f05b25 100644 --- a/luprex/cpp/core/printbuffer.cpp +++ b/luprex/cpp/core/printbuffer.cpp @@ -195,7 +195,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); + return Invocation(InvocationKind::FLUSH_PRINTS, actor_id, actor_id, buf); } LuaDefine(unittests_printbuffer, "", "some unit tests") { diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index e4c5ed0b..cd771eb5 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -700,19 +700,19 @@ void World::run_unittests() { void World::invoke(const Invocation &inv) { switch (inv.kind()) { - case Invocation::KIND_LUA_CALL: + case InvocationKind::LUA_CALL: invoke_lua_call(inv.actor(), inv.place(), inv.datapack()); break; - case Invocation::KIND_LUA: - invoke_lua(inv.actor(), inv.place(), inv.datapack()); + case InvocationKind::LUA_EXPR: + invoke_lua_expr(inv.actor(), inv.place(), inv.datapack()); break; - case Invocation::KIND_FLUSH_PRINTS: + case InvocationKind::FLUSH_PRINTS: invoke_flush_prints(inv.actor(), inv.place(), inv.datapack()); break; - case Invocation::KIND_TICK: + case InvocationKind::TICK: invoke_tick(inv.actor(), inv.place(), inv.datapack()); break; - case Invocation::KIND_LUA_SOURCE: + case InvocationKind::LUA_SOURCE: invoke_lua_source(inv.actor(), inv.place(), inv.datapack()); break; default: @@ -827,7 +827,7 @@ void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_ assert(stack_is_clear()); } -void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack) { +void World::invoke_lua_expr(int64_t actor_id, int64_t place_id, std::string_view datapack) { assert(stack_is_clear()); { lua_State *L = state(); diff --git a/luprex/cpp/core/world.hpp b/luprex/cpp/core/world.hpp index 731e92f3..fe6e8a0a 100644 --- a/luprex/cpp/core/world.hpp +++ b/luprex/cpp/core/world.hpp @@ -403,7 +403,7 @@ private: // Invoke a lua string. // - void invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack); + void invoke_lua_expr(int64_t actor_id, int64_t place_id, std::string_view datapack); // Invoke the flush-prints operation. // diff --git a/luprex/cpp/drv/driver.cpp b/luprex/cpp/drv/driver.cpp index 16778a2c..95eed416 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_invoke_lua_source(&engw, ossv.size(), ossv.data()); + engw.play_invoke(&engw, InvocationKind::LUA_SOURCE, 0, ossv.size(), ossv.data()); } }