Refactor code for invoke_lua_source and world.init. Also, add compile_commands.json to luprex
This commit is contained in:
@@ -436,9 +436,6 @@ 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) {
|
||||
event_init(std::string_view(srcpk, srcpklen), argc, argv);
|
||||
}
|
||||
|
||||
void DrivenEngine::drv_clear_new_outgoing() {
|
||||
new_outgoing_.clear();
|
||||
@@ -569,7 +566,7 @@ static void drv_get_animation_queues(EngineWrapper *w, uint32_t count, const int
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static void play_initialize(EngineWrapper *w, uint32_t argc, char **argv, uint32_t srcpklen, const char *srcpk, const char *logfn) {
|
||||
static void play_initialize(EngineWrapper *w, const char *engtype, const char *logfn) {
|
||||
if (w->engine != nullptr) {
|
||||
return reset_wrapper(w, "Cannot initialize wrapper, it's already initialized.");
|
||||
}
|
||||
@@ -590,63 +587,31 @@ static void play_initialize(EngineWrapper *w, uint32_t argc, char **argv, uint32
|
||||
// If we have a logfile, then log this initialization.
|
||||
if (w->wlog != nullptr) {
|
||||
w->wlog->write_cmd_hash(PLAY_INITIALIZE, eng::memhash());
|
||||
w->wlog->write_uint32(argc);
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
w->wlog->write_string(argv[i]);
|
||||
}
|
||||
w->wlog->write_string(std::string_view(srcpk, srcpklen));
|
||||
w->wlog->write_string(engtype);
|
||||
w->wlog->flush();
|
||||
}
|
||||
|
||||
// Create the engine of the appropriate type.
|
||||
if (argc < 1) {
|
||||
std::ostringstream oss;
|
||||
oss << "Must pass an engine type on the command line. Known types:\n";
|
||||
for (auto reg = DrivenEngineReg::All; reg != nullptr; reg=reg->next) {
|
||||
oss << " " << reg->name << std::endl;
|
||||
}
|
||||
std::string err = oss.str();
|
||||
return reset_wrapper(w, err.c_str());
|
||||
}
|
||||
w->engine = make_engine(argv[0]);
|
||||
w->engine = make_engine(engtype);
|
||||
if (w->engine == nullptr) {
|
||||
return reset_wrapper(w, "No such driven engine type: %s", argv[0]);
|
||||
return reset_wrapper(w, "No such driven engine type: %s", engtype);
|
||||
}
|
||||
|
||||
// Call the engine initialization sequence.
|
||||
w->engine->drv_initialize(srcpklen, srcpk, argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
|
||||
static void replay_initialize(EngineWrapper *w) {
|
||||
assert(w->rlog != nullptr);
|
||||
std::vector<std::string> argvstr;
|
||||
uint32_t argc = w->rlog->read_uint32();
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
argvstr.push_back(w->rlog->read_string());
|
||||
}
|
||||
std::string srcpk = w->rlog->read_string();
|
||||
std::string engtype = w->rlog->read_string();
|
||||
|
||||
if (!w->rlog->good()) {
|
||||
return reset_wrapper(w, "replay log corrupt in replay_initialize");
|
||||
}
|
||||
|
||||
// We need to convert the argument vector from an array
|
||||
// of C++ strings into the canonical argc, argv format.
|
||||
std::vector<char *> argvec;
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
argvec.push_back(&argvstr[i][0]);
|
||||
}
|
||||
char **argv = &argvec[0];
|
||||
|
||||
// Create the engine.
|
||||
w->engine = make_engine(argv[0]);
|
||||
w->engine = make_engine(engtype.c_str());
|
||||
if (w->engine == nullptr) {
|
||||
return reset_wrapper(w, "No such driven engine type: %s", argvstr[0]);
|
||||
return reset_wrapper(w, "No such driven engine type: %s", engtype.c_str());
|
||||
}
|
||||
|
||||
|
||||
w->engine->drv_initialize(srcpk.size(), srcpk.c_str(), argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,11 +142,6 @@ public:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// The init callback. You may override this in a subclass.
|
||||
// This will be called once at program initialization.
|
||||
//
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) = 0;
|
||||
|
||||
// The call-function callback. This is invoked whenever drv_access
|
||||
// is called. This is the main entry point for "general" access into the
|
||||
// DrivenEngine. The datapk parameter can contain any arbitrary data needed
|
||||
@@ -289,7 +284,6 @@ public:
|
||||
void drv_get_tangibles_near(int64_t tanid, double rx, double ry, double rz, uint32_t *count, int64_t **ids);
|
||||
void drv_get_animation_queues(uint32_t count, const int64_t *ids, uint32_t *lengths, const char **strings);
|
||||
|
||||
void drv_initialize(uint32_t srcpklen, const char *srcpk, int argc, char **argv);
|
||||
void drv_clear_new_outgoing();
|
||||
void drv_sent_outgoing(uint32_t chid, uint32_t nbytes);
|
||||
void drv_recv_incoming(uint32_t chid, uint32_t nbytes, const char *bytes);
|
||||
|
||||
@@ -22,21 +22,12 @@ static void dump_lines(StreamBuffer *in, StreamBuffer *out, int chid) {
|
||||
}
|
||||
}
|
||||
|
||||
// This test is the minimal possible DrivenEngine.
|
||||
class DriverStubTest : public DrivenEngine {
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
|
||||
stop_driver();
|
||||
}
|
||||
virtual void event_update() override {
|
||||
}
|
||||
};
|
||||
|
||||
// This test connects to a public webserver and prints
|
||||
// the output from the server.
|
||||
class DriverWebServerTest : public DrivenEngine {
|
||||
public:
|
||||
eng::vector<SharedChannel> channels_;
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
|
||||
DriverWebServerTest() {
|
||||
SharedChannel ch = new_outgoing_channel("cert:stanford.edu:443");
|
||||
ch->out()->write_bytes("GET https://stanford.edu/xbanankjdsh.html HTTP/1.1\n\n");
|
||||
channels_.emplace_back(std::move(ch));
|
||||
@@ -62,7 +53,7 @@ public:
|
||||
class DriverDNSFailTest : public DrivenEngine {
|
||||
public:
|
||||
eng::vector<SharedChannel> channels_;
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
|
||||
DriverDNSFailTest() {
|
||||
SharedChannel ch = new_outgoing_channel("akjsdkajshdakjshd.alk:80");
|
||||
ch->out()->write_bytes("GET http://stanford.edu/index.html HTTP/1.1\n\n");
|
||||
channels_.emplace_back(std::move(ch));
|
||||
@@ -89,7 +80,7 @@ class DriverPrintClockTest : public DrivenEngine {
|
||||
public:
|
||||
int count_;
|
||||
double last_clock_;
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
|
||||
DriverPrintClockTest() {
|
||||
count_ = 0;
|
||||
last_clock_ = 0.0;
|
||||
}
|
||||
@@ -111,21 +102,29 @@ public:
|
||||
|
||||
|
||||
class RunUnitTests : public DrivenEngine {
|
||||
private:
|
||||
public:
|
||||
UniqueWorld world_;
|
||||
|
||||
void event_init(std::string_view srcpk, int argc, char *argv[]) override
|
||||
{
|
||||
RunUnitTests() {
|
||||
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||
world_->update_source(srcpk);
|
||||
world_->run_unittests();
|
||||
stop_driver();
|
||||
rescan_lua_source();
|
||||
}
|
||||
|
||||
virtual void event_access(AccessKind kind, int64_t place_id, std::string_view datapk, StreamBuffer *retpk) override {
|
||||
switch (kind) {
|
||||
case AccessKind::INVOKE_LUA_SOURCE: {
|
||||
world_->update_source(datapk);
|
||||
world_->run_unittests();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void event_update() override {}
|
||||
};
|
||||
|
||||
DrivenEngineDefine("driverstubtest", DriverStubTest);
|
||||
DrivenEngineDefine("driverwebservertest", DriverWebServerTest);
|
||||
DrivenEngineDefine("driverdnsfailtest", DriverDNSFailTest);
|
||||
DrivenEngineDefine("driverprintclocktest", DriverPrintClockTest);
|
||||
|
||||
@@ -28,6 +28,7 @@ enum class AccessKind {
|
||||
INVOKE_TICK,
|
||||
INVOKE_LUA_SOURCE,
|
||||
PROBE_LUA_CALL,
|
||||
CONNECT_TO_SERVER,
|
||||
};
|
||||
|
||||
class DrivenEngine;
|
||||
@@ -154,15 +155,11 @@ struct EngineWrapper {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Create the driven engine. argc and argv allow you to specify what
|
||||
// kind of engine you want. You must pass in the initial state of the lua
|
||||
// source, if you have any. You may optionally also specify a replay log.
|
||||
// If you don't want to create a replay log, pass a null pointer.
|
||||
// Create the driven engine. You must specify the type of engine you
|
||||
// want (typically 'lpxserver' or 'lpxclient'), and a filename for the
|
||||
// logfile.
|
||||
//
|
||||
// Check to see if the error buffer contains a message after calling
|
||||
// this function.
|
||||
//
|
||||
void (*play_initialize)(EngineWrapper *w, uint32_t argc, char **argv, uint32_t srcpklen, const char *srcpk, const char *logfn);
|
||||
void (*play_initialize)(EngineWrapper *w, const char *engtype, const char *logfn);
|
||||
|
||||
// Clear the list of recently-opened channels. You are meant to fetch
|
||||
// new outgoing channels using get_new_outgoing, then you call
|
||||
|
||||
@@ -22,6 +22,12 @@ public:
|
||||
eng::vector<Invocation> delayed_invocations_;
|
||||
|
||||
public:
|
||||
LpxClient() {
|
||||
set_console_prompt(console_.get_prompt());
|
||||
|
||||
set_initial_state_standalone();
|
||||
}
|
||||
|
||||
void set_initial_state_connect(const eng::string &hostspec) {
|
||||
// Create the world model.
|
||||
world_.reset(new World(WORLD_TYPE_PREDICTIVE));
|
||||
@@ -46,21 +52,16 @@ public:
|
||||
print_channeler_.reset();
|
||||
}
|
||||
|
||||
void set_initial_state_standalone(std::string_view srcpk) {
|
||||
void set_initial_state_standalone() {
|
||||
// Create the world model.
|
||||
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||
|
||||
// Update the source code of the master model.
|
||||
world_->update_source(srcpk);
|
||||
|
||||
// Make sure the channel is empty.
|
||||
channel_.reset();
|
||||
|
||||
// Create the standalone actor.
|
||||
actor_id_ = world_->create_login_actor();
|
||||
|
||||
// TODO: initialize the standalone actor.
|
||||
|
||||
// Clear the unack command queue.
|
||||
unack_.clear();
|
||||
|
||||
@@ -69,8 +70,10 @@ public:
|
||||
|
||||
// Reset the print channeler
|
||||
print_channeler_.reset();
|
||||
}
|
||||
|
||||
// Trigger lua source loading.
|
||||
rescan_lua_source();
|
||||
}
|
||||
|
||||
// When the world is in synchronous mode, there's no
|
||||
// snapshot, and the commands in the unack queue are not
|
||||
@@ -96,37 +99,15 @@ public:
|
||||
}
|
||||
|
||||
void abandon_server() {
|
||||
// When we abandon the server, we leave the world model
|
||||
// hanging around to preserve the invariant that there
|
||||
// is always a world model. Then, we trigger a rescan
|
||||
// of the lua source. When the lua source shows up, then
|
||||
// we will create a standalone model to replace the client
|
||||
// model.
|
||||
|
||||
channel_.reset();
|
||||
rescan_lua_source();
|
||||
}
|
||||
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) {
|
||||
// Put the world into the starting state.
|
||||
set_initial_state_standalone(srcpk);
|
||||
|
||||
// Set the console prompt
|
||||
set_console_prompt(console_.get_prompt());
|
||||
if (channel_)
|
||||
{
|
||||
set_initial_state_standalone();
|
||||
}
|
||||
}
|
||||
|
||||
void send_invocation(const Invocation &inv) {
|
||||
if (channel_ == nullptr) {
|
||||
if ((!world_->is_authoritative()) && (inv.kind() == AccessKind::INVOKE_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
|
||||
// the lua source, we're supposed to throw out the client model and
|
||||
// create a standalone model.
|
||||
set_initial_state_standalone(inv.datapack());
|
||||
} else {
|
||||
world_->invoke(inv);
|
||||
}
|
||||
world_->invoke(inv);
|
||||
} else {
|
||||
world_to_asynchronous();
|
||||
world_->invoke(inv);
|
||||
@@ -247,14 +228,27 @@ public:
|
||||
}
|
||||
|
||||
virtual void event_access(AccessKind kind, int64_t place_id, std::string_view datapk, StreamBuffer *retpk) override {
|
||||
if (place_id == 0) place_id = actor_id_;
|
||||
switch (kind) {
|
||||
case AccessKind::INVOKE_LUA_CALL:
|
||||
case AccessKind::INVOKE_LUA_EXPR:
|
||||
case AccessKind::INVOKE_FLUSH_PRINTS:
|
||||
case AccessKind::INVOKE_TICK:
|
||||
case AccessKind::INVOKE_LUA_SOURCE: {
|
||||
delayed_invocations_.emplace_back(kind, actor_id_, place_id, datapk);
|
||||
break;
|
||||
}
|
||||
case AccessKind::PROBE_LUA_CALL: {
|
||||
world_to_asynchronous();
|
||||
world_->probe_lua_call(actor_id_, place_id, datapk, retpk);
|
||||
break;
|
||||
}
|
||||
case AccessKind::CONNECT_TO_SERVER: {
|
||||
set_initial_state_connect(util::ss("nocert:", datapk, ":8085"));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
delayed_invocations_.emplace_back(kind, actor_id_, place_id, datapk);
|
||||
stdostream() << "Invalid event_access: " << int(kind) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,24 +29,19 @@ public:
|
||||
PrintChanneler print_channeler_;
|
||||
HttpChannelMap http_client_channels_;
|
||||
HttpChannelVec http_server_channels_;
|
||||
int64_t admin_id_;
|
||||
int next_diff_chan_;
|
||||
double next_tick_;
|
||||
eng::vector<Invocation> delayed_invocations_;
|
||||
int64_t admin_id_ = 0;
|
||||
double next_tick_ = 0;
|
||||
|
||||
public:
|
||||
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
|
||||
LpxServer()
|
||||
{
|
||||
// Create the master world model.
|
||||
master_.reset(new World(WORLD_TYPE_MASTER));
|
||||
|
||||
// Update the source code of the master model.
|
||||
master_->update_source(srcpk);
|
||||
|
||||
// Create an actor for administrative commands.
|
||||
// Create the admin actor. Note: there isn't any 'init' function yet.
|
||||
admin_id_ = master_->create_login_actor();
|
||||
|
||||
// TODO: initialize the admin actor.
|
||||
|
||||
// Print out admin ID for debugging purposes.
|
||||
stdostream() << "Admin actor id = " << admin_id_ << std::endl;
|
||||
|
||||
@@ -61,9 +56,9 @@ public:
|
||||
|
||||
// Export stuff to the graphics engine.
|
||||
set_visible_world_and_actor(master_.get(), admin_id_);
|
||||
|
||||
// for ticking.
|
||||
next_tick_ = 0.0;
|
||||
|
||||
// Trigger the loading of the lua source.
|
||||
rescan_lua_source();
|
||||
}
|
||||
|
||||
virtual void do_syntax_error(std::string_view error) override {
|
||||
@@ -91,35 +86,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void do_work_command() override {
|
||||
master_->snapshot();
|
||||
StreamBuffer datapack;
|
||||
StreamBuffer retvals;
|
||||
datapack.write_string("engio");
|
||||
datapack.write_string("myfunction");
|
||||
datapack.write_simple_dynamic_tag(SimpleDynamicTag::NUMBER);
|
||||
datapack.write_double(3.7);
|
||||
datapack.write_simple_dynamic_tag(SimpleDynamicTag::STRING);
|
||||
datapack.write_string("banana");
|
||||
datapack.write_simple_dynamic_tag(SimpleDynamicTag::BOOLEAN);
|
||||
datapack.write_bool(true);
|
||||
master_->probe_lua_call(admin_id_, admin_id_, datapack.view(), &retvals);
|
||||
while (!retvals.empty()) {
|
||||
SimpleDynamicValue value;
|
||||
retvals.read_simple_dynamic(&value);
|
||||
if (value.type == SimpleDynamicTag::NUMBER) {
|
||||
util::dprint("retval: ", value.x);
|
||||
} else if (value.type == SimpleDynamicTag::STRING) {
|
||||
util::dprint("retval: ", value.s);
|
||||
} else if (value.type == SimpleDynamicTag::BOOLEAN) {
|
||||
util::dprint(value.x ? "retval: true" : "retval: false");
|
||||
} else if (value.type == SimpleDynamicTag::VECTOR) {
|
||||
util::dprint("retval: ", value.x, " ", value.y, " ", value.z);
|
||||
} else {
|
||||
util::dprint("retval: invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
master_->rollback();
|
||||
do_unknown_command("work");
|
||||
}
|
||||
|
||||
virtual void do_display_command() override {
|
||||
@@ -194,7 +161,16 @@ public:
|
||||
}
|
||||
|
||||
virtual void event_access(AccessKind kind, int64_t place_id, std::string_view datapk, StreamBuffer *retpk) override {
|
||||
if (place_id == 0) place_id = admin_id_;
|
||||
switch (kind) {
|
||||
case AccessKind::INVOKE_LUA_CALL:
|
||||
case AccessKind::INVOKE_LUA_EXPR:
|
||||
case AccessKind::INVOKE_FLUSH_PRINTS:
|
||||
case AccessKind::INVOKE_TICK:
|
||||
case AccessKind::INVOKE_LUA_SOURCE: {
|
||||
delayed_invocations_.emplace_back(kind, admin_id_, place_id, datapk);
|
||||
break;
|
||||
}
|
||||
case AccessKind::PROBE_LUA_CALL: {
|
||||
master_->snapshot();
|
||||
master_->probe_lua_call(admin_id_, place_id, datapk, retpk);
|
||||
@@ -202,7 +178,7 @@ public:
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
delayed_invocations_.emplace_back(kind, admin_id_, place_id, datapk);
|
||||
stdostream() << "Invalid event_access: " << int(kind) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,44 +546,49 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view
|
||||
// some lua source file tries to modify, say, tangible state
|
||||
// in top-level code.
|
||||
//
|
||||
void World::rebuild_sourcedb() {
|
||||
bool World::rebuild_sourcedb() {
|
||||
bool ok = true;
|
||||
for (const eng::string &mod: source_db_.modules()) {
|
||||
open_lthread_state(0, 0, 0, false, true);
|
||||
eng::string err = source_db_.rebuild_module(mod);
|
||||
eng::string prints = lthread_prints_->str();
|
||||
lthread_prints_.reset();
|
||||
close_lthread_state();
|
||||
if (!err.empty()) ok = false;
|
||||
if (!err.empty() || !prints.empty()) {
|
||||
util::dprint("Loading Module ", mod);
|
||||
if (!err.empty()) util::dprint(err);
|
||||
if (!prints.empty()) util::dprint(prints);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void World::update_source(const util::LuaSourceVec &source) {
|
||||
bool World::update_source(const util::LuaSourceVec &source) {
|
||||
assert(stack_is_clear());
|
||||
source_db_.update(source);
|
||||
rebuild_sourcedb();
|
||||
return rebuild_sourcedb();
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
void World::update_source(const util::LuaSourcePtr &source) {
|
||||
if (source != nullptr) {
|
||||
update_source(*source);
|
||||
bool World::update_source(const util::LuaSourcePtr &source) {
|
||||
if (source == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return 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;
|
||||
}
|
||||
bool World::update_source(std::string_view sourcepack) {
|
||||
if (sourcepack.empty()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
StreamBuffer sb(sourcepack);
|
||||
util::LuaSourceVec sv;
|
||||
SourceDB::deserialize_source(&sv, &sb);
|
||||
return update_source(sv);
|
||||
} catch (const StreamException &ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,11 +965,40 @@ void World::invoke_tick(int64_t actor_id, int64_t place_id, std::string_view dat
|
||||
}
|
||||
|
||||
void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
if (!is_authoritative()) {
|
||||
return;
|
||||
// Sanity check arguments.
|
||||
// We also need some kind of authentication here.
|
||||
if (!is_authoritative()) return;
|
||||
if (actor_id != place_id) return;
|
||||
|
||||
// Check if this is the first time we're loading the source.
|
||||
bool brand_new = (source_db_.modules().size() == 1);
|
||||
|
||||
// Compile and load the source.
|
||||
bool success = update_source(datapack);
|
||||
|
||||
// Call world.init
|
||||
if (brand_new) {
|
||||
if (success) {
|
||||
{
|
||||
lua_State *L = state();
|
||||
LuaVar lclass, lfunc;
|
||||
LuaExtStack LS(L, lclass, lfunc);
|
||||
|
||||
LS.getclass(lclass, "world");
|
||||
if (LS.classname(lclass) != "") {
|
||||
LS.rawget(lfunc, lclass, "init");
|
||||
spawn(LS, actor_id, place_id, lfunc, 0, false);
|
||||
}
|
||||
}
|
||||
run_scheduled_threads();
|
||||
} else {
|
||||
util::dprint("Did not run world.init because of lua errors.");
|
||||
util::dprint("You will need to fix the errors then run it manually.");
|
||||
}
|
||||
}
|
||||
// We need some kind of authentication here.
|
||||
update_source(datapack);
|
||||
|
||||
// Run the new thread and return.
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
void World::guard_blockable(lua_State *L, const char *fn) {
|
||||
|
||||
@@ -216,11 +216,11 @@ public:
|
||||
// This is used to create a temporary actor which is used during
|
||||
// the login process.
|
||||
//
|
||||
// If this is a master model, The function 'login.initialize'
|
||||
// If this is a master model, The function 'login.init'
|
||||
// called. Then, the following login flags are set:
|
||||
// can_be_controlled, is_controlled, and delete_on_disconnect.
|
||||
//
|
||||
// In a client model, 'login.initialize' is not called,
|
||||
// In a client model, 'login.init' is not called,
|
||||
// and the login flags are not used in client models.
|
||||
//
|
||||
int64_t create_login_actor();
|
||||
@@ -265,19 +265,21 @@ public:
|
||||
//
|
||||
const PrintBuffer *get_printbuffer(int64_t actor_id);
|
||||
|
||||
// Update the source database from disk.
|
||||
// Rebuild the global environment from the source database.
|
||||
//
|
||||
// Returns true if the rebuild goes without errors.
|
||||
//
|
||||
bool rebuild_sourcedb();
|
||||
|
||||
// Update the source database from disk, then rebuild the global environment.
|
||||
//
|
||||
// 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::LuaSourceVec &source);
|
||||
void update_source(const util::LuaSourcePtr &source);
|
||||
void update_source(std::string_view sourcepk);
|
||||
|
||||
// Rebuild the source database.
|
||||
// Returns true if the update goes without errors.
|
||||
//
|
||||
void rebuild_sourcedb();
|
||||
bool update_source(const util::LuaSourceVec &source);
|
||||
bool update_source(const util::LuaSourcePtr &source);
|
||||
bool update_source(std::string_view sourcepk);
|
||||
|
||||
// Supply an HTTP response to an outstanding HTTP request.
|
||||
//
|
||||
|
||||
@@ -646,14 +646,8 @@ class Driver {
|
||||
ssl_load_certificate_authorities(ssl_client_secure_ctx_.get());
|
||||
sslutil::ctx_load_dummy_cert(ssl_server_ctx_.get());
|
||||
|
||||
// Read the initial lua source code.
|
||||
drvutil::ostringstream srcpak;
|
||||
std::string srcpakerr = drvutil::package_lua_source(luprexroot, &srcpak);
|
||||
if_error_print_and_exit(srcpakerr);
|
||||
|
||||
// Initialize the engine.
|
||||
std::string_view srcpakv = srcpak.view();
|
||||
engw.play_initialize(&engw, argc, argv, srcpakv.size(), srcpakv.data(), replaylogfn.c_str());
|
||||
engw.play_initialize(&engw, argv[0], replaylogfn.c_str());
|
||||
if_error_print_and_exit(engw.error);
|
||||
|
||||
// Set up listening ports.
|
||||
|
||||
Reference in New Issue
Block a user