Refactor code to make it easier to do 'nopredict' inside of any function without having a dependency on world model.
This commit is contained in:
@@ -323,8 +323,8 @@ bool AnimStep::from_string(const eng::string &config) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimQueue::AnimQueue(util::WorldType wt) {
|
AnimQueue::AnimQueue(WorldType wt) {
|
||||||
version_autoinc_ = (wt == util::WORLD_TYPE_MASTER);
|
version_autoinc_ = (wt == WORLD_TYPE_MASTER);
|
||||||
size_limit_ = 10; // Default size limit.
|
size_limit_ = 10; // Default size limit.
|
||||||
steps_.emplace_back();
|
steps_.emplace_back();
|
||||||
steps_.front().keep_state_only();
|
steps_.front().keep_state_only();
|
||||||
@@ -576,8 +576,8 @@ static bool diff_works(const AnimQueue &master, AnimQueue &sync) {
|
|||||||
LuaDefine(unittests_animqueue, "", "some unit tests") {
|
LuaDefine(unittests_animqueue, "", "some unit tests") {
|
||||||
// Useful objects.
|
// Useful objects.
|
||||||
AnimStep stp;
|
AnimStep stp;
|
||||||
AnimQueue aq(util::WORLD_TYPE_MASTER);
|
AnimQueue aq(WORLD_TYPE_MASTER);
|
||||||
AnimQueue aqds(util::WORLD_TYPE_S_SYNC);
|
AnimQueue aqds(WORLD_TYPE_PREDICTIVE);
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
|
|
||||||
// Debug string of a newly initialized queue
|
// Debug string of a newly initialized queue
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ private:
|
|||||||
class AnimQueue : public eng::nevernew {
|
class AnimQueue : public eng::nevernew {
|
||||||
public:
|
public:
|
||||||
// World type determines whether versions increment or autozero
|
// World type determines whether versions increment or autozero
|
||||||
AnimQueue(util::WorldType wt);
|
AnimQueue(WorldType wt);
|
||||||
|
|
||||||
// Simple getters.
|
// Simple getters.
|
||||||
const AnimStep &nth(int n) const { return steps_[n]; }
|
const AnimStep &nth(int n) const { return steps_[n]; }
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ private:
|
|||||||
|
|
||||||
void event_init(int argc, char *argv[])
|
void event_init(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
world_.reset(new World(util::WORLD_TYPE_STANDALONE));
|
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||||
world_->update_source(get_lua_source());
|
world_->update_source(get_lua_source());
|
||||||
world_->run_unittests();
|
world_->run_unittests();
|
||||||
stop_driver();
|
stop_driver();
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ LuaDefine(global_once, "name", "for a given string, returns true exactly once")
|
|||||||
LuaVar oncedb, val;
|
LuaVar oncedb, val;
|
||||||
LuaStack LS(L, name, flag, oncedb, val);
|
LuaStack LS(L, name, flag, oncedb, val);
|
||||||
|
|
||||||
|
LS.guard_nopredict("global.once");
|
||||||
|
|
||||||
// Get a pointer to the oncedb.
|
// Get a pointer to the oncedb.
|
||||||
LS.rawget(oncedb, LuaRegistry, "oncedb");
|
LS.rawget(oncedb, LuaRegistry, "oncedb");
|
||||||
if (!LS.istable(oncedb)) {
|
if (!LS.istable(oncedb)) {
|
||||||
@@ -25,11 +27,14 @@ LuaDefine(global_once, "name", "for a given string, returns true exactly once")
|
|||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaDefine(global_clearonce, "name", "reset the specified once-flag") {
|
LuaDefine(global_clearonce, "name", "reset the specified once-flag") {
|
||||||
LuaArg name;
|
LuaArg name;
|
||||||
LuaVar oncedb;
|
LuaVar oncedb;
|
||||||
LuaStack LS(L, name, oncedb);
|
LuaStack LS(L, name, oncedb);
|
||||||
|
|
||||||
|
LS.guard_nopredict("global.clearonce");
|
||||||
|
|
||||||
// Get a pointer to the oncedb.
|
// Get a pointer to the oncedb.
|
||||||
LS.rawget(oncedb, LuaRegistry, "oncedb");
|
LS.rawget(oncedb, LuaRegistry, "oncedb");
|
||||||
if (!LS.istable(oncedb)) {
|
if (!LS.istable(oncedb)) {
|
||||||
@@ -50,11 +55,6 @@ LuaDefine(global_table, "globalname", "get a table where global data can be stor
|
|||||||
// Get a pointer to the globaldb.
|
// Get a pointer to the globaldb.
|
||||||
LS.rawget(globaldb, LuaRegistry, "globaldb");
|
LS.rawget(globaldb, LuaRegistry, "globaldb");
|
||||||
|
|
||||||
// nopredict
|
|
||||||
if (lua_isyieldable(L) && (!LS.istable(globaldb))) {
|
|
||||||
return lua_yield(L, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the globaltab from the globaldb, sanity check it.
|
// Get the globaltab from the globaldb, sanity check it.
|
||||||
LS.rawget(globaltab, globaldb, globalname);
|
LS.rawget(globaltab, globaldb, globalname);
|
||||||
if (LS.istable(globaltab)) {
|
if (LS.istable(globaltab)) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
void set_initial_state() {
|
void set_initial_state() {
|
||||||
// Create the world model.
|
// Create the world model.
|
||||||
world_.reset(new World(util::WORLD_TYPE_C_SYNC));
|
world_.reset(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
|
|
||||||
// This is a temporary actor that will be used only until the server sends
|
// This is a temporary actor that will be used only until the server sends
|
||||||
// us the first difference transmission. We do this only to establish
|
// us the first difference transmission. We do this only to establish
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual void event_init(int argc, char *argv[]) {
|
virtual void event_init(int argc, char *argv[]) {
|
||||||
// Create the master world model.
|
// Create the master world model.
|
||||||
master_.reset(new World(util::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());
|
||||||
@@ -189,7 +189,7 @@ public:
|
|||||||
Client *client = new Client;
|
Client *client = new Client;
|
||||||
client->actor_id_ = master_->create_login_actor();
|
client->actor_id_ = master_->create_login_actor();
|
||||||
client->channel_ = std::move(chan);
|
client->channel_ = std::move(chan);
|
||||||
client->sync_.reset(new World(util::WORLD_TYPE_S_SYNC));
|
client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
client->sync_->create_login_actor();
|
client->sync_->create_login_actor();
|
||||||
clients_.emplace_back(client);
|
clients_.emplace_back(client);
|
||||||
stdostream() << "New client: actor id=" << client->actor_id_ << std::endl;
|
stdostream() << "New client: actor id=" << client->actor_id_ << std::endl;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ void LuaSnap::deserialize(StreamBuffer *sb) {
|
|||||||
void *ud = sb->lua_reader_ud(len);
|
void *ud = sb->lua_reader_ud(len);
|
||||||
|
|
||||||
// Call eris with the permanents table and passing the snapshot as a lua_Reader.
|
// Call eris with the permanents table and passing the snapshot as a lua_Reader.
|
||||||
lua_getfield(state_, LUA_REGISTRYINDEX, "unpersist");
|
lua_pushstring(state_, "unpersist");
|
||||||
|
lua_rawget(state_, LUA_REGISTRYINDEX);
|
||||||
eris_undump(state_, sb->lua_reader, ud);
|
eris_undump(state_, sb->lua_reader, ud);
|
||||||
assert(lua_gettop(state_) == 2);
|
assert(lua_gettop(state_) == 2);
|
||||||
|
|
||||||
|
|||||||
@@ -466,6 +466,24 @@ void LuaStack::setvisited(LuaSlot tab, bool visited) const {
|
|||||||
lua_modflagbits(L_, tab.index(), 0x0010, visited ? 0x0010 : 0);
|
lua_modflagbits(L_, tab.index(), 0x0010, visited ? 0x0010 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldType LuaStack::world_type() const {
|
||||||
|
lua_pushstring(L_, "worldtype");
|
||||||
|
lua_rawget(L_, LUA_REGISTRYINDEX);
|
||||||
|
lua_Integer n = lua_tointeger(L_, -1);
|
||||||
|
lua_pop(L_, 1);
|
||||||
|
assert(n != 0);
|
||||||
|
return (WorldType)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaStack::guard_nopredict(const char *fn) {
|
||||||
|
if (lua_isyieldable(L_)) {
|
||||||
|
if (!is_authoritative()) {
|
||||||
|
lua_yield(L_, 0);
|
||||||
|
luaL_error(L_, "unexplained nopredict failure in %s", fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LuaKeywordParser::LuaKeywordParser(lua_State *L, int slot) {
|
LuaKeywordParser::LuaKeywordParser(lua_State *L, int slot) {
|
||||||
L_ = L;
|
L_ = L;
|
||||||
slot_ = slot;
|
slot_ = slot;
|
||||||
|
|||||||
@@ -226,6 +226,13 @@ int LuaTypeTagValue(lua_State *L) { return 0; }
|
|||||||
#define LUA_TT_GLOBALDB 22
|
#define LUA_TT_GLOBALDB 22
|
||||||
#define LUA_TT_CLASS 23
|
#define LUA_TT_CLASS 23
|
||||||
|
|
||||||
|
// World types enum.
|
||||||
|
|
||||||
|
enum WorldType {
|
||||||
|
WORLD_TYPE_MASTER = 1,
|
||||||
|
WORLD_TYPE_PREDICTIVE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
// We use lightuserdata to store 'tokens': short
|
// We use lightuserdata to store 'tokens': short
|
||||||
// strings of 8 characters or less. These tokens
|
// strings of 8 characters or less. These tokens
|
||||||
// are useful as unique markers. The 8 characters
|
// are useful as unique markers. The 8 characters
|
||||||
@@ -517,6 +524,17 @@ public:
|
|||||||
bool getvisited(LuaSlot tab) const;
|
bool getvisited(LuaSlot tab) const;
|
||||||
void setvisited(LuaSlot tab, bool visited) const;
|
void setvisited(LuaSlot tab, bool visited) const;
|
||||||
|
|
||||||
|
// Return the world type (from the registry).
|
||||||
|
WorldType world_type() const;
|
||||||
|
|
||||||
|
// World types that are authoritative.
|
||||||
|
static bool is_authoritative(WorldType t) { return (t == WORLD_TYPE_MASTER); }
|
||||||
|
bool is_authoritative() { return is_authoritative(world_type()); }
|
||||||
|
|
||||||
|
// Stop execution of this thread if in a nonauth model,
|
||||||
|
// and if the thread is not a probe.
|
||||||
|
void guard_nopredict(const char *fn);
|
||||||
|
|
||||||
// Return true if the int64 value can be stored as a lua number.
|
// Return true if the int64 value can be stored as a lua number.
|
||||||
static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); }
|
static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ private:
|
|||||||
|
|
||||||
void event_init(int argc, char *argv[])
|
void event_init(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
world_.reset(new World(util::WORLD_TYPE_STANDALONE));
|
world_.reset(new World(WORLD_TYPE_MASTER));
|
||||||
world_->update_source(get_lua_source());
|
world_->update_source(get_lua_source());
|
||||||
world_->run_unittests();
|
world_->run_unittests();
|
||||||
actor_id_ = world_->create_login_actor();
|
actor_id_ = world_->create_login_actor();
|
||||||
|
|||||||
@@ -198,13 +198,6 @@ bool valid_number(string_view v, bool plus, bool minus, bool dec, bool exp);
|
|||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
enum WorldType {
|
|
||||||
WORLD_TYPE_STANDALONE,
|
|
||||||
WORLD_TYPE_C_SYNC,
|
|
||||||
WORLD_TYPE_S_SYNC,
|
|
||||||
WORLD_TYPE_MASTER,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MessageType {
|
enum MessageType {
|
||||||
MSG_NULL,
|
MSG_NULL,
|
||||||
MSG_DIFF,
|
MSG_DIFF,
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ World *World::fetch_global_pointer(lua_State *L) {
|
|||||||
World::~World() {
|
World::~World() {
|
||||||
}
|
}
|
||||||
|
|
||||||
World::World(util::WorldType wt) {
|
World::World(WorldType wt) {
|
||||||
// Master world model by default.
|
// Master world model by default.
|
||||||
world_type_ = wt;
|
world_type_ = wt;
|
||||||
|
|
||||||
// Initialize the ID allocator in master mode.
|
// Initialize the ID allocator in master mode.
|
||||||
if (wt == util::WORLD_TYPE_MASTER || wt == util::WORLD_TYPE_STANDALONE) {
|
if (is_authoritative()) {
|
||||||
id_global_pool_.init_master();
|
id_global_pool_.init_master();
|
||||||
} else {
|
} else {
|
||||||
id_global_pool_.init_synch();
|
id_global_pool_.init_synch();
|
||||||
@@ -63,11 +63,12 @@ World::World(util::WorldType wt) {
|
|||||||
// Create the tangibles table in the registry.
|
// Create the tangibles table in the registry.
|
||||||
LS.rawset(LuaRegistry, "tangibles", LuaNewTable);
|
LS.rawset(LuaRegistry, "tangibles", LuaNewTable);
|
||||||
|
|
||||||
|
// Store the world type in the registry.
|
||||||
|
LS.rawset(LuaRegistry, "worldtype", wt);
|
||||||
|
|
||||||
// Create the globaldb and oncedb in the registry.
|
// Create the globaldb and oncedb in the registry.
|
||||||
if ((wt == util::WORLD_TYPE_MASTER) || (wt == util::WORLD_TYPE_STANDALONE)) {
|
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
|
||||||
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
|
LS.rawset(LuaRegistry, "oncedb", LuaNewTable);
|
||||||
LS.rawset(LuaRegistry, "oncedb", LuaNewTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the SourceDB. At this stage, the sourcedb is
|
// Initialize the SourceDB. At this stage, the sourcedb is
|
||||||
// empty, so it's just populating the lua builtins.
|
// empty, so it's just populating the lua builtins.
|
||||||
@@ -788,12 +789,12 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, const eng::str
|
|||||||
|
|
||||||
void World::guard_blockable(lua_State *L, const char *fn) {
|
void World::guard_blockable(lua_State *L, const char *fn) {
|
||||||
if (lthread_thread_id_ == 0) {
|
if (lthread_thread_id_ == 0) {
|
||||||
// in a probe, http.get throws an error.
|
// in a probe, blocking functions like http.get throw an error.
|
||||||
luaL_error(L, "cannot %s in a probe", fn);
|
luaL_error(L, "cannot %s in a probe", fn);
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
if (!is_authoritative()) {
|
if (!is_authoritative()) {
|
||||||
// in a nonauth model, http.get is converted to nopredict.
|
// in a nonauth model, blocking functions like http.get are converted to nopredict.
|
||||||
lua_yield(L, 0);
|
lua_yield(L, 0);
|
||||||
luaL_error(L, "unexplained nopredict failure in %s", fn);
|
luaL_error(L, "unexplained nopredict failure in %s", fn);
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -801,6 +802,8 @@ void World::guard_blockable(lua_State *L, const char *fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void World::guard_nopredict(lua_State *L, const char *fn) {
|
void World::guard_nopredict(lua_State *L, const char *fn) {
|
||||||
|
// Caution: this code must be equivalent to the
|
||||||
|
// code in LuaStack::guard_nopredict.
|
||||||
if (lthread_thread_id_ == 0) {
|
if (lthread_thread_id_ == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -883,7 +886,10 @@ void World::run_scheduled_threads() {
|
|||||||
LS.rawset(thinfo, "isnew", false);
|
LS.rawset(thinfo, "isnew", false);
|
||||||
LS.rawset(thinfo, "useppool", false);
|
LS.rawset(thinfo, "useppool", false);
|
||||||
} else {
|
} else {
|
||||||
// In a nonauth model, a yield is converted to a 'nopredict'.
|
// When a nonauthoritative model yields, for any reason,
|
||||||
|
// the thread is discarded. This is also used as a way to implement
|
||||||
|
// nopredict: the thread that wants to 'nopredict' just yields,
|
||||||
|
// knowing that this will cause it to be killed.
|
||||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -136,8 +136,6 @@ void World::pair_lua_tables(const IdVector &basis, lua_State *master) {
|
|||||||
// If the master table is already paired, skip.
|
// If the master table is already paired, skip.
|
||||||
MLS.rawget(midx, mtnmap, mtab);
|
MLS.rawget(midx, mtnmap, mtab);
|
||||||
if (MLS.isnumber(midx)) continue;
|
if (MLS.isnumber(midx)) continue;
|
||||||
// If the synch table is not a table, skip.
|
|
||||||
if (!SLS.istable(stab)) continue;
|
|
||||||
// If the synch table doesn't have a number, skip.
|
// If the synch table doesn't have a number, skip.
|
||||||
SLS.rawget(sidx, stnmap, stab);
|
SLS.rawget(sidx, stnmap, stab);
|
||||||
if (!SLS.isnumber(sidx)) continue;
|
if (!SLS.isnumber(sidx)) continue;
|
||||||
|
|||||||
@@ -241,9 +241,9 @@ static bool worlds_identical(const UniqueWorld &w1, const UniqueWorld &w2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(unittests_world1animdiff, "", "some unit tests") {
|
LuaDefine(unittests_world1animdiff, "", "some unit tests") {
|
||||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
UniqueWorld m(new World(WORLD_TYPE_MASTER));
|
||||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
UniqueWorld ss(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
UniqueWorld cs(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
util::IdVector ids = util::id_vector_create(123, 345);
|
util::IdVector ids = util::id_vector_create(123, 345);
|
||||||
|
|
||||||
@@ -311,8 +311,8 @@ LuaDefine(unittests_world1animdiff, "", "some unit tests") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(unittests_world2pairtab, "", "some unit tests") {
|
LuaDefine(unittests_world2pairtab, "", "some unit tests") {
|
||||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
UniqueWorld m(new World(WORLD_TYPE_MASTER));
|
||||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
UniqueWorld ss(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
int ncreate;
|
int ncreate;
|
||||||
|
|
||||||
@@ -359,9 +359,9 @@ LuaDefine(unittests_world2pairtab, "", "some unit tests") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
|
LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
|
||||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
UniqueWorld m(new World(WORLD_TYPE_MASTER));
|
||||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
UniqueWorld ss(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
UniqueWorld cs(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
|
|
||||||
// Initialize all three models so that a tangible exists.
|
// Initialize all three models so that a tangible exists.
|
||||||
@@ -413,9 +413,9 @@ LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(unittests_world4difftanclass, "", "some unit tests") {
|
LuaDefine(unittests_world4difftanclass, "", "some unit tests") {
|
||||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
UniqueWorld m(new World(WORLD_TYPE_MASTER));
|
||||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
UniqueWorld ss(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
UniqueWorld cs(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
|
|
||||||
// Initialize all three models so that a tangible exists.
|
// Initialize all three models so that a tangible exists.
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public:
|
|||||||
// The constructor also calls 'lua_open' to create a new
|
// The constructor also calls 'lua_open' to create a new
|
||||||
// lua interpreter for this world model.
|
// lua interpreter for this world model.
|
||||||
//
|
//
|
||||||
World(util::WorldType wt);
|
World(WorldType wt);
|
||||||
|
|
||||||
// Destructor.
|
// Destructor.
|
||||||
//
|
//
|
||||||
@@ -236,8 +236,8 @@ public:
|
|||||||
|
|
||||||
// Check if the world is authoritative.
|
// Check if the world is authoritative.
|
||||||
//
|
//
|
||||||
bool is_authoritative() const { return (world_type_ == util::WORLD_TYPE_MASTER) || (world_type_ == util::WORLD_TYPE_STANDALONE); }
|
bool is_authoritative() const { return LuaStack::is_authoritative(world_type_); }
|
||||||
|
|
||||||
// Get a table showing all outstanding HTTP requests.
|
// Get a table showing all outstanding HTTP requests.
|
||||||
//
|
//
|
||||||
const HttpClientRequestMap &http_requests() const { return http_requests_; }
|
const HttpClientRequestMap &http_requests() const { return http_requests_; }
|
||||||
@@ -249,6 +249,9 @@ public:
|
|||||||
|
|
||||||
// Snapshot and rollback.
|
// Snapshot and rollback.
|
||||||
//
|
//
|
||||||
|
// These are used by the client to convert the synchronous model
|
||||||
|
// to an asynchronous model and back.
|
||||||
|
//
|
||||||
void snapshot();
|
void snapshot();
|
||||||
void rollback();
|
void rollback();
|
||||||
bool snapshot_empty() { return snapshot_.empty(); }
|
bool snapshot_empty() { return snapshot_.empty(); }
|
||||||
@@ -494,7 +497,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Type of model
|
// Type of model
|
||||||
util::WorldType world_type_;
|
WorldType world_type_;
|
||||||
|
|
||||||
// A lua intepreter with snapshot function.
|
// A lua intepreter with snapshot function.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user