Less serialization and deserialization of Lua Source, also, Invocation is now simpler
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<std::ostream> stdostream_;
|
||||
eng::vector<SharedChannel> accepted_channels_;
|
||||
eng::vector<uint32_t> new_outgoing_;
|
||||
util::LuaSourcePtr lua_source_;
|
||||
eng::vector<uint32_t> listen_ports_;
|
||||
World *visible_world_;
|
||||
int64_t visible_actor_id_;
|
||||
util::IdVector scan_result_;
|
||||
std::vector<util::SharedStdString> anim_queues_;
|
||||
eng::string lua_source_pack_;
|
||||
bool rescan_lua_source_;
|
||||
double clock_;
|
||||
bool stop_driver_;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<eng::string, eng::string> {
|
||||
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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user