Add login.initialize function
This commit is contained in:
@@ -34,7 +34,7 @@ public:
|
|||||||
// the invariant that there's always an actor. When the first difference
|
// the invariant that there's always an actor. When the first difference
|
||||||
// transmission arrives, this actor may be deleted, or it may just be
|
// transmission arrives, this actor may be deleted, or it may just be
|
||||||
// ignored, at the server's discretion.
|
// ignored, at the server's discretion.
|
||||||
actor_id_ = world_->create_login_actor();
|
actor_id_ = world_->create_login_actor(false);
|
||||||
|
|
||||||
// Clear the unack command queue.
|
// Clear the unack command queue.
|
||||||
unack_.clear();
|
unack_.clear();
|
||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
channel_.reset();
|
channel_.reset();
|
||||||
|
|
||||||
// Create the standalone actor.
|
// Create the standalone actor.
|
||||||
actor_id_ = world_->create_login_actor();
|
actor_id_ = world_->create_login_actor(true);
|
||||||
|
|
||||||
// TODO: initialize the standalone actor.
|
// TODO: initialize the standalone actor.
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
master_->update_source(srcpk);
|
master_->update_source(srcpk);
|
||||||
|
|
||||||
// Create an actor for administrative commands.
|
// Create an actor for administrative commands.
|
||||||
admin_id_ = master_->create_login_actor();
|
admin_id_ = master_->create_login_actor(true);
|
||||||
|
|
||||||
// TODO: initialize the admin actor.
|
// TODO: initialize the admin actor.
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ public:
|
|||||||
if (chan == nullptr) break;
|
if (chan == nullptr) break;
|
||||||
if (chan->port() == 8085) {
|
if (chan->port() == 8085) {
|
||||||
Client *client = new Client;
|
Client *client = new Client;
|
||||||
client->actor_id_ = master_->create_login_actor();
|
client->actor_id_ = master_->create_login_actor(true);
|
||||||
// TODO: initialize the login actor on the master.
|
// TODO: initialize the login actor on the master.
|
||||||
client->channel_ = std::move(chan);
|
client->channel_ = std::move(chan);
|
||||||
client->async_diff_ = true;
|
client->async_diff_ = true;
|
||||||
@@ -216,7 +216,7 @@ public:
|
|||||||
client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE));
|
client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE));
|
||||||
// This login actor is never used, it is just to preserve the invariant that
|
// This login actor is never used, it is just to preserve the invariant that
|
||||||
// the client model and the server synchronous model are identical.
|
// the client model and the server synchronous model are identical.
|
||||||
client->sync_->create_login_actor();
|
client->sync_->create_login_actor(false);
|
||||||
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;
|
||||||
} else if (chan->port() == 8080) {
|
} else if (chan->port() == 8080) {
|
||||||
|
|||||||
@@ -246,18 +246,26 @@ World::Redirects World::fetch_redirects() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t World::create_login_actor() {
|
int64_t World::create_login_actor(bool initialize) {
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
int64_t id = id_global_pool_.get_one();
|
int64_t id = id_global_pool_.get_one();
|
||||||
LuaVar database, classtab, mt;
|
{
|
||||||
LuaExtStack LS(state(), database, classtab, mt);
|
LuaVar database, classtab, mt, func;
|
||||||
Tangible *tan = tangible_make(LS, database, id);
|
LuaExtStack LS(state(), database, classtab, mt, func);
|
||||||
LS.makeclass(classtab, "login");
|
Tangible *tan = tangible_make(LS, database, id);
|
||||||
LS.getmetatable(mt, database);
|
LS.makeclass(classtab, "login");
|
||||||
LS.rawset(mt, "__index", classtab);
|
LS.getmetatable(mt, database);
|
||||||
tan->configure_id_pool_for_actor();
|
LS.rawset(mt, "__index", classtab);
|
||||||
tan->print_buffer_.clear();
|
tan->configure_id_pool_for_actor();
|
||||||
return tan->id();
|
tan->print_buffer_.clear();
|
||||||
|
|
||||||
|
if (initialize) {
|
||||||
|
LS.rawget(func, classtab, "initialize");
|
||||||
|
spawn(LS, id, id, func, true, 0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run_scheduled_threads();
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
eng::string World::probe_lua(int64_t actor_id, const eng::string &lua) {
|
eng::string World::probe_lua(int64_t actor_id, const eng::string &lua) {
|
||||||
@@ -794,17 +802,6 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) {
|
|||||||
void World::invoke_engio(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
void World::invoke_engio(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
|
|
||||||
// Get the actor and place. Make sure both exist.
|
|
||||||
Tangible *tactor = tangible_get(actor_id);
|
|
||||||
Tangible *tplace = tangible_get(place_id);
|
|
||||||
if ((tactor == nullptr) || (tplace == nullptr)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get an ID for the thread. We always use the player
|
|
||||||
// pool in this case.
|
|
||||||
int64_t tid = tactor->id_player_pool_.get_one();
|
|
||||||
|
|
||||||
// Use a streambuffer to parse the datapack.
|
// Use a streambuffer to parse the datapack.
|
||||||
StreamBuffer datasb(datapack);
|
StreamBuffer datasb(datapack);
|
||||||
|
|
||||||
@@ -820,37 +817,19 @@ void World::invoke_engio(int64_t actor_id, int64_t place_id, std::string_view da
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Set up for Lua manipulation.
|
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar actor, place, func, mt, tangibles, playercb, thread, threads, thinfo, message;
|
LuaVar engio, func;
|
||||||
LuaExtStack LS(L, actor, place, func, mt, tangibles, playercb, thread, threads, thinfo, message);
|
LuaExtStack LS(L, engio, func);
|
||||||
|
|
||||||
// Get the actor and place.
|
// Get the closure (engio.funcname).
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
eng::string err = LS.getclass(engio, "engio");
|
||||||
LS.rawget(actor, tangibles, actor_id);
|
if ((!err.empty()) || (!LS.istable(engio))) {
|
||||||
LS.rawget(place, tangibles, place_id);
|
|
||||||
if (!LS.istable(actor) || !LS.istable(place)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the closure (playerinvoke.funcname).
|
|
||||||
eng::string err = LS.getclass(playercb, "engio");
|
|
||||||
if ((!err.empty()) || (!LS.istable(playercb))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawget(func, playercb, funcname);
|
|
||||||
if (!LS.isfunction(func)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
LS.rawget(func, engio, funcname);
|
||||||
|
|
||||||
// Create a new thread, push func, actor, place.
|
// Spawn a thread, pushing extra arguments from the datapack.
|
||||||
int nargs = 3;
|
int nargs = 0;
|
||||||
lua_State *CO = LS.newthread(thread);
|
|
||||||
lua_pushvalue(L, func.index());
|
|
||||||
lua_pushvalue(L, actor.index());
|
|
||||||
lua_pushvalue(L, place.index());
|
|
||||||
|
|
||||||
// Push any additional args from the datapack.
|
|
||||||
try {
|
try {
|
||||||
while (!datasb.empty()) {
|
while (!datasb.empty()) {
|
||||||
push_simple_dynamic(L, &datasb);
|
push_simple_dynamic(L, &datasb);
|
||||||
@@ -859,33 +838,8 @@ void World::invoke_engio(int64_t actor_id, int64_t place_id, std::string_view da
|
|||||||
} catch (const StreamException &exc) {
|
} catch (const StreamException &exc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
spawn(LS, actor_id, place_id, func, true, nargs, false);
|
||||||
// Transfer all arguments to the new thread.
|
|
||||||
lua_xmove(L, CO, nargs);
|
|
||||||
|
|
||||||
// Create the thread info table.
|
|
||||||
LS.newtable(thinfo);
|
|
||||||
LS.rawset(thinfo, "thread", thread);
|
|
||||||
LS.rawset(thinfo, "actorid", actor_id);
|
|
||||||
LS.rawset(thinfo, "isnew", true);
|
|
||||||
LS.rawset(thinfo, "useppool", true);
|
|
||||||
LS.rawset(thinfo, "print", false);
|
|
||||||
|
|
||||||
// Store the thread into place's thread table.
|
|
||||||
LS.getmetatable(mt, place);
|
|
||||||
if (!LS.istable(mt)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawget(threads, mt, "threads");
|
|
||||||
if (!LS.istable(threads)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawset(threads, tid, thinfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the thread's ID into the runnable thread queue,
|
|
||||||
// then run the thread queue.
|
|
||||||
schedule(0, tid, place_id);
|
|
||||||
run_scheduled_threads();
|
run_scheduled_threads();
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,10 @@ public:
|
|||||||
// This is used to create a temporary actor which is used during
|
// This is used to create a temporary actor which is used during
|
||||||
// the login process.
|
// the login process.
|
||||||
//
|
//
|
||||||
int64_t create_login_actor();
|
// If initialize is true, then the function 'login.initialize'
|
||||||
|
// will be executed.
|
||||||
|
//
|
||||||
|
int64_t create_login_actor(bool initialize);
|
||||||
|
|
||||||
// Fetch all redirects and clear the redirects table.
|
// Fetch all redirects and clear the redirects table.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
makeclass('login')
|
makeclass('login')
|
||||||
|
|
||||||
|
function login.initialize(actor, place)
|
||||||
|
dprint("login.initialize:", actor)
|
||||||
|
end
|
||||||
|
|
||||||
function login.interface(actor, place)
|
function login.interface(actor, place)
|
||||||
gui.menu_item("cb_becomeplayer", "Become a Player")
|
gui.menu_item("cb_becomeplayer", "Become a Player")
|
||||||
gui.menu_item("cb_p123", "Print 1, 2, 3")
|
gui.menu_item("cb_p123", "Print 1, 2, 3")
|
||||||
|
|||||||
Reference in New Issue
Block a user