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;
|
console_prompt_ = prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::LuaSourcePtr DrivenEngine::get_lua_source() {
|
eng::string DrivenEngine::get_lua_source_pack() {
|
||||||
return std::move(lua_source_);
|
eng::string result = std::move(lua_source_pack_);
|
||||||
|
lua_source_pack_.clear();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrivenEngine::rescan_lua_source() {
|
void DrivenEngine::rescan_lua_source() {
|
||||||
@@ -219,7 +221,7 @@ enum DrvAction {
|
|||||||
PLAY_NOTIFY_CLOSE,
|
PLAY_NOTIFY_CLOSE,
|
||||||
PLAY_NOTIFY_ACCEPT,
|
PLAY_NOTIFY_ACCEPT,
|
||||||
PLAY_INVOKE_EVENT_UPDATE,
|
PLAY_INVOKE_EVENT_UPDATE,
|
||||||
PLAY_SET_LUA_SOURCE,
|
PLAY_SET_LUA_SOURCE_PACK,
|
||||||
PLAY_RELEASE,
|
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_CLOSE: return "PLAY_NOTIFY_CLOSE";
|
||||||
case PLAY_NOTIFY_ACCEPT: return "PLAY_NOTIFY_ACCEPT";
|
case PLAY_NOTIFY_ACCEPT: return "PLAY_NOTIFY_ACCEPT";
|
||||||
case PLAY_INVOKE_EVENT_UPDATE: return "PLAY_INVOKE_EVENT_UPDATE";
|
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";
|
case PLAY_RELEASE: return "PLAY_RELEASE";
|
||||||
default: return "unknown";
|
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) {
|
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);
|
event_init(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,22 +483,12 @@ void DrivenEngine::drv_invoke_event_update(double clock) {
|
|||||||
event_update();
|
event_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrivenEngine::drv_set_lua_source(uint32_t srcpklen, const char *srcpk) {
|
void DrivenEngine::drv_set_lua_source_pack(uint32_t srcpklen, const char *srcpk) {
|
||||||
StreamBuffer sb(std::string_view(srcpk, srcpklen));
|
lua_source_pack_ = 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();
|
|
||||||
}
|
|
||||||
rescan_lua_source_ = false;
|
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);
|
assert(w->rlog == nullptr);
|
||||||
if (w->wlog != 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->write_string(std::string_view(srcpk, srcpklen));
|
||||||
w->wlog->flush();
|
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();
|
std::string srcpack = w->rlog->read_string();
|
||||||
|
|
||||||
if (!w->rlog->good()) {
|
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_CLOSE: replay_notify_close(w); return;
|
||||||
case PLAY_NOTIFY_ACCEPT: replay_notify_accept(w); return;
|
case PLAY_NOTIFY_ACCEPT: replay_notify_accept(w); return;
|
||||||
case PLAY_INVOKE_EVENT_UPDATE: replay_invoke_event_update(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;
|
case PLAY_RELEASE: release(w); return;
|
||||||
default: return reset_wrapper(w, "Replay log corrupt in command dispatcher");
|
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_close = play_notify_close;
|
||||||
w->play_notify_accept = play_notify_accept;
|
w->play_notify_accept = play_notify_accept;
|
||||||
w->play_invoke_event_update = play_invoke_event_update;
|
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_initialize = replaycore_initialize;
|
||||||
w->replay_step = replaycore_step;
|
w->replay_step = replaycore_step;
|
||||||
|
|||||||
@@ -210,10 +210,13 @@ public:
|
|||||||
//
|
//
|
||||||
void set_console_prompt(const eng::string &prompt);
|
void set_console_prompt(const eng::string &prompt);
|
||||||
|
|
||||||
// Fetches the lua source, and takes ownership of it. The DrivenEngine
|
// Fetches the lua 'sourcepack'. The sourcepack is a packaged collection
|
||||||
// no longer contains the source after calling this.
|
// 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,
|
// Rescan the lua source directory. The lua source directory is read once,
|
||||||
// automatically, at engine creation time. If you want to read it again,
|
// 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);
|
void drv_notify_close(uint32_t chid, uint32_t len, const char *data);
|
||||||
uint32_t drv_notify_accept(uint32_t port);
|
uint32_t drv_notify_accept(uint32_t port);
|
||||||
void drv_invoke_event_update(double clock);
|
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:
|
private:
|
||||||
// Find a currently-unused channel ID. Channel IDs
|
// Find a currently-unused channel ID. Channel IDs
|
||||||
@@ -308,12 +311,12 @@ private:
|
|||||||
std::unique_ptr<std::ostream> stdostream_;
|
std::unique_ptr<std::ostream> stdostream_;
|
||||||
eng::vector<SharedChannel> accepted_channels_;
|
eng::vector<SharedChannel> accepted_channels_;
|
||||||
eng::vector<uint32_t> new_outgoing_;
|
eng::vector<uint32_t> new_outgoing_;
|
||||||
util::LuaSourcePtr lua_source_;
|
|
||||||
eng::vector<uint32_t> listen_ports_;
|
eng::vector<uint32_t> listen_ports_;
|
||||||
World *visible_world_;
|
World *visible_world_;
|
||||||
int64_t visible_actor_id_;
|
int64_t visible_actor_id_;
|
||||||
util::IdVector scan_result_;
|
util::IdVector scan_result_;
|
||||||
std::vector<util::SharedStdString> anim_queues_;
|
std::vector<util::SharedStdString> anim_queues_;
|
||||||
|
eng::string lua_source_pack_;
|
||||||
bool rescan_lua_source_;
|
bool rescan_lua_source_;
|
||||||
double clock_;
|
double clock_;
|
||||||
bool stop_driver_;
|
bool stop_driver_;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ private:
|
|||||||
void event_init(int argc, char *argv[])
|
void event_init(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
world_.reset(new World(WORLD_TYPE_MASTER));
|
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||||
world_->update_source(get_lua_source());
|
world_->update_source(get_lua_source_pack());
|
||||||
world_->run_unittests();
|
world_->run_unittests();
|
||||||
stop_driver();
|
stop_driver();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ struct EngineWrapper {
|
|||||||
// Check the 'rescan_lua_source' flag. If this flag is set, it means
|
// 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.
|
// 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
|
// 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);
|
bool (*get_rescan_lua_source)(EngineWrapper *w);
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ struct EngineWrapper {
|
|||||||
|
|
||||||
// Store the lua source code.
|
// 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);
|
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_) {
|
for (const GuiElt &elt : elts_) {
|
||||||
if (elt.action_ == action) {
|
if (elt.action_ == action) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public:
|
|||||||
int64_t place() { return place_; }
|
int64_t place() { return place_; }
|
||||||
const EltVec &elts() const { return elts_; }
|
const EltVec &elts() const { return elts_; }
|
||||||
void clear(int64_t p) { place_ = p; elts_.clear(); }
|
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);
|
void menu_item(const eng::string &action, const eng::string &label);
|
||||||
eng::string get_action(int64_t index);
|
eng::string get_action(int64_t index);
|
||||||
eng::string menu_debug_string() const;
|
eng::string menu_debug_string() const;
|
||||||
|
|||||||
@@ -6,57 +6,24 @@
|
|||||||
|
|
||||||
#include "invocation.hpp"
|
#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_INVALID), actor_(0), place_(0) {}
|
||||||
|
|
||||||
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action, const InvocationData &data)
|
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, std::string_view datapack)
|
||||||
: kind_(kind), actor_(actor), place_(place), action_(action), data_(data) {}
|
: kind_(kind), actor_(actor), place_(place), datapack_(datapack) {}
|
||||||
|
|
||||||
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action)
|
|
||||||
: kind_(kind), actor_(actor), place_(place), action_(action) {}
|
|
||||||
|
|
||||||
void Invocation::serialize(StreamBuffer *sb) const {
|
void Invocation::serialize(StreamBuffer *sb) const {
|
||||||
sb->write_uint8(kind_);
|
sb->write_uint8(kind_);
|
||||||
sb->write_int64(actor_);
|
sb->write_int64(actor_);
|
||||||
sb->write_int64(place_);
|
sb->write_int64(place_);
|
||||||
sb->write_string(action_);
|
sb->write_string(datapack_);
|
||||||
data_.serialize(sb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Invocation::deserialize(StreamBuffer *sb) {
|
void Invocation::deserialize(StreamBuffer *sb) {
|
||||||
kind_ = Kind(sb->read_uint8());
|
kind_ = Kind(sb->read_uint8());
|
||||||
actor_ = sb->read_int64();
|
actor_ = sb->read_int64();
|
||||||
place_ = sb->read_int64();
|
place_ = sb->read_int64();
|
||||||
action_ = sb->read_string();
|
datapack_ = sb->read_string();
|
||||||
data_.deserialize(sb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eng::string Invocation::debug_string() const {
|
eng::string Invocation::debug_string() const {
|
||||||
@@ -73,12 +40,7 @@ eng::string Invocation::debug_string() const {
|
|||||||
}
|
}
|
||||||
oss << " a=" << actor_;
|
oss << " a=" << actor_;
|
||||||
oss << " p=" << place_;
|
oss << " p=" << place_;
|
||||||
if (kind_ != KIND_LUA_SOURCE) {
|
oss << " dp=" << datapack_.size() << " bytes";
|
||||||
oss << " " << action_;
|
|
||||||
}
|
|
||||||
for (const auto &pair : data_) {
|
|
||||||
oss << " " << pair.first << "=" << pair.second;
|
|
||||||
}
|
|
||||||
oss << "]";
|
oss << "]";
|
||||||
return oss.str();
|
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
|
#ifndef INVOCATION_HPP
|
||||||
#define INVOCATION_HPP
|
#define INVOCATION_HPP
|
||||||
|
|
||||||
@@ -8,14 +44,6 @@
|
|||||||
#include "streambuffer.hpp"
|
#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 {
|
class Invocation : public eng::nevernew {
|
||||||
public:
|
public:
|
||||||
enum Kind {
|
enum Kind {
|
||||||
@@ -31,19 +59,16 @@ private:
|
|||||||
Kind kind_;
|
Kind kind_;
|
||||||
int64_t actor_;
|
int64_t actor_;
|
||||||
int64_t place_;
|
int64_t place_;
|
||||||
eng::string action_;
|
eng::string datapack_;
|
||||||
InvocationData data_;
|
|
||||||
public:
|
public:
|
||||||
Invocation();
|
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, std::string_view datapack);
|
||||||
Invocation(Kind kind, int64_t actor, int64_t place, const eng::string &action);
|
|
||||||
|
|
||||||
bool valid() const { return kind_ != KIND_INVALID; }
|
bool valid() const { return kind_ != KIND_INVALID; }
|
||||||
Kind kind() const { return kind_; }
|
Kind kind() const { return kind_; }
|
||||||
int64_t actor() const { return actor_; }
|
int64_t actor() const { return actor_; }
|
||||||
int64_t place() const { return place_; }
|
int64_t place() const { return place_; }
|
||||||
const eng::string &action() const { return action_; }
|
const eng::string &datapack() const { return datapack_; }
|
||||||
const InvocationData &data() const { return data_; }
|
|
||||||
|
|
||||||
void serialize(StreamBuffer *sb) const;
|
void serialize(StreamBuffer *sb) const;
|
||||||
void deserialize(StreamBuffer *sb);
|
void deserialize(StreamBuffer *sb);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
|
|
||||||
// The driver loads the lua source automatically.
|
// The driver loads the lua source automatically.
|
||||||
// However, we don't need it. Throw it out.
|
// However, we don't need it. Throw it out.
|
||||||
get_lua_source();
|
get_lua_source_pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_invocation(const Invocation &inv) {
|
void send_invocation(const Invocation &inv) {
|
||||||
@@ -97,11 +97,8 @@ public:
|
|||||||
inv.serialize(sb);
|
inv.serialize(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_lua_source(const util::LuaSourceVec &sv) {
|
void send_lua_source(std::string_view sourcepack) {
|
||||||
StreamBuffer serial;
|
Invocation inv(Invocation::KIND_LUA_SOURCE, actor_id_, actor_id_, sourcepack);
|
||||||
SourceDB::serialize_source(sv, &serial);
|
|
||||||
eng::string sstr(serial.view());
|
|
||||||
Invocation inv(Invocation::KIND_LUA_SOURCE, actor_id_, actor_id_, sstr);
|
|
||||||
send_invocation(inv);
|
send_invocation(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,10 +236,10 @@ public:
|
|||||||
virtual void event_update() {
|
virtual void event_update() {
|
||||||
// Check for lua source code. If this returns non-null,
|
// Check for lua source code. If this returns non-null,
|
||||||
// it is because somebody typed CPL.
|
// it is because somebody typed CPL.
|
||||||
util::LuaSourcePtr lua_source = get_lua_source();
|
eng::string lua_source_pack = get_lua_source_pack();
|
||||||
if (lua_source != nullptr) {
|
if (!lua_source_pack.empty()) {
|
||||||
send_lua_source(*lua_source);
|
send_lua_source(lua_source_pack);
|
||||||
lua_source.reset();
|
lua_source_pack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for keyboard input on stdin.
|
// Check for keyboard input on stdin.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
master_.reset(new World(WORLD_TYPE_MASTER));
|
master_.reset(new World(WORLD_TYPE_MASTER));
|
||||||
|
|
||||||
// Update the source code of the master model.
|
// 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.
|
// Create an actor for administrative commands.
|
||||||
admin_id_ = master_->create_login_actor();
|
admin_id_ = master_->create_login_actor();
|
||||||
@@ -168,7 +168,7 @@ public:
|
|||||||
|
|
||||||
virtual void event_update() {
|
virtual void event_update() {
|
||||||
// If the driver has reloaded the source, put it into master model.
|
// 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.
|
// Check for keyboard input on stdin.
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ bool PrintChanneler::channel(const PrintBuffer *printbuffer, std::ostream &ostre
|
|||||||
Invocation PrintChanneler::invocation(int64_t actor_id) {
|
Invocation PrintChanneler::invocation(int64_t actor_id) {
|
||||||
char buf[80];
|
char buf[80];
|
||||||
sprintf(buf, "%" PRId64, line_);
|
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") {
|
LuaDefine(unittests_printbuffer, "", "some unit tests") {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
void event_init(int argc, char *argv[])
|
void event_init(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
world_.reset(new World(WORLD_TYPE_MASTER));
|
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||||
world_->update_source(get_lua_source());
|
world_->update_source(get_lua_source_pack());
|
||||||
world_->run_unittests();
|
world_->run_unittests();
|
||||||
actor_id_ = world_->create_login_actor();
|
actor_id_ = world_->create_login_actor();
|
||||||
stdostream() << "Login actor ID: " << actor_id_ << std::endl;
|
stdostream() << "Login actor ID: " << actor_id_ << std::endl;
|
||||||
@@ -108,7 +108,7 @@ private:
|
|||||||
|
|
||||||
void event_update()
|
void event_update()
|
||||||
{
|
{
|
||||||
world_->update_source(get_lua_source());
|
world_->update_source(get_lua_source_pack());
|
||||||
while (true) {
|
while (true) {
|
||||||
eng::string line = get_stdio_channel()->in()->readline();
|
eng::string line = get_stdio_channel()->in()->readline();
|
||||||
if (line == "") break;
|
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
|
// This is called from World::update_source, and also
|
||||||
// from World::patch_source in the difference transmitter.
|
// from World::patch_source in the difference transmitter.
|
||||||
//
|
//
|
||||||
@@ -397,6 +391,25 @@ void World::update_source(const util::LuaSourceVec &source) {
|
|||||||
assert(stack_is_clear());
|
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) {
|
void World::http_response(const HttpParser &response) {
|
||||||
// Find the request.
|
// Find the request.
|
||||||
auto iter = http_requests_.find(response.request_id());
|
auto iter = http_requests_.find(response.request_id());
|
||||||
@@ -554,19 +567,19 @@ void World::run_unittests() {
|
|||||||
void World::invoke(const Invocation &inv) {
|
void World::invoke(const Invocation &inv) {
|
||||||
switch (inv.kind()) {
|
switch (inv.kind()) {
|
||||||
case Invocation::KIND_PLAN:
|
case Invocation::KIND_PLAN:
|
||||||
invoke_plan(inv.actor(), inv.place(), inv.action(), inv.data());
|
invoke_plan(inv.actor(), inv.place(), inv.datapack());
|
||||||
break;
|
break;
|
||||||
case Invocation::KIND_LUA:
|
case Invocation::KIND_LUA:
|
||||||
invoke_lua(inv.actor(), inv.place(), inv.action(), inv.data());
|
invoke_lua(inv.actor(), inv.place(), inv.datapack());
|
||||||
break;
|
break;
|
||||||
case Invocation::KIND_FLUSH_PRINTS:
|
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;
|
break;
|
||||||
case Invocation::KIND_TICK:
|
case Invocation::KIND_TICK:
|
||||||
invoke_tick(inv.actor(), inv.place(), inv.action(), inv.data());
|
invoke_tick(inv.actor(), inv.place(), inv.datapack());
|
||||||
break;
|
break;
|
||||||
case Invocation::KIND_LUA_SOURCE:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
// Do nothing. Standard behavior for any invalid command is to
|
// 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());
|
assert(stack_is_clear());
|
||||||
// Check argument sanity.
|
// Check argument sanity.
|
||||||
if (actor_id != place_id) {
|
if (actor_id != place_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int64_t line = sv::to_int64(action, -1);
|
int64_t line = sv::to_int64(datapack, -1);
|
||||||
if ((line < 0)||(line > INT_MAX)) {
|
if ((line < 0)||(line > INT_MAX)) {
|
||||||
return;
|
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());
|
assert(stack_is_clear());
|
||||||
|
|
||||||
// Make sure that actor and place exist and are not stubs.
|
// 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);
|
LuaExtStack LS(L, func, tangibles, place, mt, thread, thinfo, threads);
|
||||||
|
|
||||||
// create the compiled closure.
|
// 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());
|
lua_replace(L, func.index());
|
||||||
if (status != LUA_OK) {
|
if (status != LUA_OK) {
|
||||||
// The closure is actually an error message. Do nothing.
|
// 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());
|
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());
|
assert(stack_is_clear());
|
||||||
|
|
||||||
// Validate that the action is legal.
|
// Validate that the action is legal.
|
||||||
Gui validation_gui;
|
Gui validation_gui;
|
||||||
update_gui(actor_id, place_id, &validation_gui);
|
update_gui(actor_id, place_id, &validation_gui);
|
||||||
if (!validation_gui.has_action(action)) {
|
if (!validation_gui.has_action(datapack)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the action starts with "cb_"
|
// Make sure the action starts with "cb_"
|
||||||
if (!sv::has_prefix(action, "cb_")) {
|
if (!sv::has_prefix(datapack, "cb_")) {
|
||||||
return;
|
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)) {
|
if (!LS.istable(index)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LS.rawget(func, index, action);
|
LS.rawget(func, index, datapack);
|
||||||
if (!LS.isfunction(func)) {
|
if (!LS.isfunction(func)) {
|
||||||
return;
|
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);
|
LS.newtable(invdata);
|
||||||
for (const auto &p : data) {
|
|
||||||
LS.rawset(invdata, p.first, p.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new thread, set up function and parameters.
|
// Create a new thread, set up function and parameters.
|
||||||
lua_State *CO = LS.newthread(thread);
|
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());
|
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()) {
|
if (!is_authoritative()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -765,19 +776,12 @@ void World::invoke_tick(int64_t actor_id, int64_t place_id, const eng::string &a
|
|||||||
run_scheduled_threads();
|
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()) {
|
if (!is_authoritative()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// We need some kind of authentication here.
|
// We need some kind of authentication here.
|
||||||
try {
|
update_source(datapack);
|
||||||
StreamBuffer sb(action);
|
|
||||||
util::LuaSourceVec sv;
|
|
||||||
SourceDB::deserialize_source(&sv, &sb);
|
|
||||||
update_source(sv);
|
|
||||||
} catch (const StreamException &ex) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::guard_blockable(lua_State *L, const char *fn) {
|
void World::guard_blockable(lua_State *L, const char *fn) {
|
||||||
|
|||||||
@@ -220,9 +220,12 @@ public:
|
|||||||
// Update the source database from disk.
|
// Update the source database from disk.
|
||||||
//
|
//
|
||||||
// Special case: if the source pointer is nullptr, does not update.
|
// 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::LuaSourceVec &source);
|
||||||
|
void update_source(const util::LuaSourcePtr &source);
|
||||||
|
void update_source(std::string_view sourcepk);
|
||||||
|
|
||||||
// Rebuild the source database.
|
// Rebuild the source database.
|
||||||
//
|
//
|
||||||
@@ -348,23 +351,23 @@ private:
|
|||||||
|
|
||||||
// Invoke a plan.
|
// 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.
|
// 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.
|
// 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.
|
// 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.
|
// 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:
|
public:
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class Driver {
|
|||||||
std::string err = drvutil::package_lua_source(".", &oss);
|
std::string err = drvutil::package_lua_source(".", &oss);
|
||||||
if_error_print_and_exit(err);
|
if_error_print_and_exit(err);
|
||||||
std::string_view ossv = oss.view();
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -345,8 +345,6 @@ std::string package_lua_source(const std::filesystem::path &base, std::ostream *
|
|||||||
sbwrite_uint32(s, names.size());
|
sbwrite_uint32(s, names.size());
|
||||||
for (int i = 0; i < int(names.size()); i++) {
|
for (int i = 0; i < int(names.size()); i++) {
|
||||||
sbwrite_string(s, names[i]);
|
sbwrite_string(s, names[i]);
|
||||||
}
|
|
||||||
for (int i = 0; i < int(names.size()); i++) {
|
|
||||||
std::filesystem::path lfn = base / "lua" / names[i];
|
std::filesystem::path lfn = base / "lua" / names[i];
|
||||||
if (!sbwrite_file(s, lfn)) {
|
if (!sbwrite_file(s, lfn)) {
|
||||||
return std::string("Cannot read source file: ") + lfn.u8string();
|
return std::string("Cannot read source file: ") + lfn.u8string();
|
||||||
|
|||||||
Reference in New Issue
Block a user