Implement the core of the login system
This commit is contained in:
@@ -81,7 +81,7 @@ void TextGame::do_view_command(const StringVec &cmd) {
|
|||||||
std::cerr << "v command (view) takes no arguments" << std::endl;
|
std::cerr << "v command (view) takes no arguments" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int64_t id : world_->get_near(1, 100, true)) {
|
for (int64_t id : world_->get_near(actor_id_, 100, true)) {
|
||||||
const Tangible *tan = world_->tangible_get(id);
|
const Tangible *tan = world_->tangible_get(id);
|
||||||
const AnimStep &aqback = tan->anim_queue_.back();
|
const AnimStep &aqback = tan->anim_queue_.back();
|
||||||
std::cerr << id << ": " << aqback.graphic() << " " << aqback.plane() << " " << aqback.xyz() << std::endl;
|
std::cerr << id << ": " << aqback.graphic() << " " << aqback.plane() << " " << aqback.xyz() << std::endl;
|
||||||
@@ -91,15 +91,15 @@ void TextGame::do_view_command(const StringVec &cmd) {
|
|||||||
void TextGame::do_menu_command(const StringVec &cmd) {
|
void TextGame::do_menu_command(const StringVec &cmd) {
|
||||||
int64_t id;
|
int64_t id;
|
||||||
if (cmd.size() == 1) {
|
if (cmd.size() == 1) {
|
||||||
id = 1;
|
id = actor_id_;
|
||||||
} else if (cmd.size() == 2) {
|
} else if (cmd.size() == 2) {
|
||||||
id = util::strtoint(cmd[1], -1);
|
id = util::strtoint(cmd[1], -1);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "m command (menu) expects a tangible ID or defaults to 1" << std::endl;
|
std::cerr << "m command (menu) expects a tangible ID or defaults to actor_id" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gui_place_ = id;
|
gui_place_ = id;
|
||||||
world_->update_gui(1, id, &gui_);
|
world_->update_gui(actor_id_, id, &gui_);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (const GuiElt &elt : gui_.elts()) {
|
for (const GuiElt &elt : gui_.elts()) {
|
||||||
std::cerr << index << " " << elt.label() << std::endl;
|
std::cerr << index << " " << elt.label() << std::endl;
|
||||||
@@ -125,7 +125,7 @@ void TextGame::do_choose_command(const StringVec &cmd) {
|
|||||||
GuiResult dummyresult;
|
GuiResult dummyresult;
|
||||||
dummyresult["flavor"] = "chocolate";
|
dummyresult["flavor"] = "chocolate";
|
||||||
dummyresult["color"] = "blue";
|
dummyresult["color"] = "blue";
|
||||||
world_->invoke_plan(1, gui_place_, action, dummyresult);
|
world_->invoke_plan(actor_id_, gui_place_, action, dummyresult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextGame::do_snapshot_command(const StringVec &cmd) {
|
void TextGame::do_snapshot_command(const StringVec &cmd) {
|
||||||
@@ -164,12 +164,26 @@ void TextGame::do_command(const StringVec &words) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextGame::check_redirects() {
|
||||||
|
World::Redirects redir = world_->fetch_redirects();
|
||||||
|
for (const auto &p : redir) {
|
||||||
|
if (p.first == actor_id_) {
|
||||||
|
actor_id_ = p.second;
|
||||||
|
std::cerr << "Login actor ID: " << actor_id_ << std::endl;
|
||||||
|
gui_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextGame::run()
|
void TextGame::run()
|
||||||
{
|
{
|
||||||
world_.reset(new World);
|
world_.reset(new World);
|
||||||
world_->init_standalone();
|
world_->init_standalone();
|
||||||
|
actor_id_ = world_->create_login_actor();
|
||||||
|
std::cerr << "Login actor ID: " << actor_id_ << std::endl;
|
||||||
console_.clear();
|
console_.clear();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
check_redirects();
|
||||||
console_.add_stdin();
|
console_.add_stdin();
|
||||||
int action = console_.action();
|
int action = console_.action();
|
||||||
if (action == LuaConsole::DO_LUA) {
|
if (action == LuaConsole::DO_LUA) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ private:
|
|||||||
LuaConsole console_;
|
LuaConsole console_;
|
||||||
Gui gui_;
|
Gui gui_;
|
||||||
int64_t gui_place_;
|
int64_t gui_place_;
|
||||||
|
int64_t actor_id_;
|
||||||
|
|
||||||
void do_view_command(const StringVec &cmd);
|
void do_view_command(const StringVec &cmd);
|
||||||
void do_menu_command(const StringVec &cmd);
|
void do_menu_command(const StringVec &cmd);
|
||||||
@@ -23,6 +24,8 @@ private:
|
|||||||
|
|
||||||
void do_lua(const std::string &exp);
|
void do_lua(const std::string &exp);
|
||||||
void do_command(const StringVec &exp);
|
void do_command(const StringVec &exp);
|
||||||
|
|
||||||
|
void check_redirects();
|
||||||
public:
|
public:
|
||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,29 +72,9 @@ void Tangible::deserialize(StreamBuffer *sb) {
|
|||||||
update_plane_item();
|
update_plane_item();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tangible::be_a_player() {
|
|
||||||
if (!id_player_pool_.fifo_enabled()) {
|
|
||||||
id_player_pool_.enable_fifo();
|
|
||||||
|
|
||||||
AnimStep asinit;
|
|
||||||
asinit.set_graphic("player");
|
|
||||||
anim_queue_.add(world_->id_global_pool_.get_one(), asinit);
|
|
||||||
anim_queue_.keep_only(1);
|
|
||||||
update_plane_item();
|
|
||||||
|
|
||||||
LuaVar classtab, mt, place, tangibles;
|
|
||||||
LuaStack LS(world_->state(), classtab, mt, place, tangibles);
|
|
||||||
|
|
||||||
LS.makeclass(classtab, "player");
|
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
|
||||||
LS.rawget(place, tangibles, id());
|
|
||||||
LS.getmetatable(mt, place);
|
|
||||||
LS.rawset(mt, "__index", classtab);
|
|
||||||
LS.result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void World::init_standalone() {
|
void World::init_standalone() {
|
||||||
|
assert(stack_is_clear());
|
||||||
|
|
||||||
// Load the lua source from disk then rebuild the environment.
|
// Load the lua source from disk then rebuild the environment.
|
||||||
source_db_.update();
|
source_db_.update();
|
||||||
source_db_.rebuild();
|
source_db_.rebuild();
|
||||||
@@ -102,9 +82,7 @@ void World::init_standalone() {
|
|||||||
// Run unit tests.
|
// Run unit tests.
|
||||||
source_db_.run_unittests();
|
source_db_.run_unittests();
|
||||||
|
|
||||||
// Create the player tangible.
|
assert(stack_is_clear());
|
||||||
Tangible *player = tangible_make(state(), 1, false);
|
|
||||||
player->be_a_player();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tangible *World::tangible_get(int64_t id) {
|
Tangible *World::tangible_get(int64_t id) {
|
||||||
@@ -207,7 +185,50 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
|||||||
return t.get();
|
return t.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
World::Redirects World::fetch_redirects() {
|
||||||
|
World::Redirects result = std::move(redirects_);
|
||||||
|
redirects_.clear();
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void Tangible::be_a_player() {
|
||||||
|
// if (!id_player_pool_.fifo_enabled()) {
|
||||||
|
// id_player_pool_.enable_fifo();
|
||||||
|
|
||||||
|
// AnimStep asinit;
|
||||||
|
// asinit.set_graphic("player");
|
||||||
|
// anim_queue_.add(world_->id_global_pool_.get_one(), asinit);
|
||||||
|
// anim_queue_.keep_only(1);
|
||||||
|
// update_plane_item();
|
||||||
|
|
||||||
|
// LuaVar classtab, mt, place, tangibles;
|
||||||
|
// LuaStack LS(world_->state(), classtab, mt, place, tangibles);
|
||||||
|
|
||||||
|
// LS.makeclass(classtab, "player");
|
||||||
|
// LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||||
|
// LS.rawget(place, tangibles, id());
|
||||||
|
// LS.getmetatable(mt, place);
|
||||||
|
// LS.rawset(mt, "__index", classtab);
|
||||||
|
// LS.result();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
int64_t World::create_login_actor() {
|
||||||
|
Tangible *tan = tangible_make(state(), 0, true);
|
||||||
|
LuaArg database;
|
||||||
|
LuaVar classtab, mt;
|
||||||
|
LuaStack LS(state(), database, classtab, mt);
|
||||||
|
LS.makeclass(classtab, "login");
|
||||||
|
LS.getmetatable(mt, database);
|
||||||
|
LS.rawset(mt, "__index", classtab);
|
||||||
|
LS.result();
|
||||||
|
tan->id_player_pool_.enable_fifo();
|
||||||
|
assert(stack_is_clear());
|
||||||
|
return tan->id();
|
||||||
|
}
|
||||||
|
|
||||||
void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
|
void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
|
||||||
|
assert(stack_is_clear());
|
||||||
gui->clear();
|
gui->clear();
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
|
|
||||||
@@ -256,9 +277,12 @@ void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
|
|||||||
|
|
||||||
// And we're done.
|
// And we're done.
|
||||||
LS.result();
|
LS.result();
|
||||||
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &action, const GuiResult &gres) {
|
void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &action, const GuiResult &gres) {
|
||||||
|
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);
|
||||||
@@ -334,9 +358,11 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
|||||||
// then run the thread queue.
|
// then run the thread queue.
|
||||||
thread_sched_.add(0, tid, place_id);
|
thread_sched_.add(0, tid, place_id);
|
||||||
run_scheduled_threads(0);
|
run_scheduled_threads(0);
|
||||||
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::run_scheduled_threads(int64_t clk) {
|
void World::run_scheduled_threads(int64_t clk) {
|
||||||
|
assert(stack_is_clear());
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar tangibles, place, mt, threads, thread;
|
LuaVar tangibles, place, mt, threads, thread;
|
||||||
LuaStack LS(L, tangibles, place, mt, threads, thread);
|
LuaStack LS(L, tangibles, place, mt, threads, thread);
|
||||||
@@ -391,9 +417,12 @@ void World::run_scheduled_threads(int64_t clk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LS.result();
|
LS.result();
|
||||||
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::serialize(StreamBuffer *sb) {
|
void World::serialize(StreamBuffer *sb) {
|
||||||
|
assert(stack_is_clear());
|
||||||
|
assert(redirects_.empty());
|
||||||
int64_t wc0 = sb->write_count();
|
int64_t wc0 = sb->write_count();
|
||||||
lua_snap_.serialize(sb);
|
lua_snap_.serialize(sb);
|
||||||
id_global_pool_.serialize(sb);
|
id_global_pool_.serialize(sb);
|
||||||
@@ -405,9 +434,12 @@ void World::serialize(StreamBuffer *sb) {
|
|||||||
}
|
}
|
||||||
int64_t wc1 = sb->write_count();
|
int64_t wc1 = sb->write_count();
|
||||||
std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl;
|
std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl;
|
||||||
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::deserialize(StreamBuffer *sb) {
|
void World::deserialize(StreamBuffer *sb) {
|
||||||
|
assert(stack_is_clear());
|
||||||
|
redirects_.clear();
|
||||||
lua_snap_.deserialize(sb);
|
lua_snap_.deserialize(sb);
|
||||||
id_global_pool_.deserialize(sb);
|
id_global_pool_.deserialize(sb);
|
||||||
thread_sched_.deserialize(sb);
|
thread_sched_.deserialize(sb);
|
||||||
@@ -435,6 +467,7 @@ void World::deserialize(StreamBuffer *sb) {
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::snapshot() {
|
void World::snapshot() {
|
||||||
@@ -561,6 +594,16 @@ LuaDefine(tangible_get, "c") {
|
|||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LuaDefine(tangible_redirect, "c") {
|
||||||
|
LuaArg actor1, actor2;
|
||||||
|
LuaStack LS(L, actor1, actor2);
|
||||||
|
World *w = World::fetch_global_pointer(L);
|
||||||
|
Tangible *tan1 = w->tangible_get(L, actor1.index());
|
||||||
|
Tangible *tan2 = w->tangible_get(L, actor2.index());
|
||||||
|
w->redirects_[tan1->id()] = tan2->id();
|
||||||
|
return LS.result();
|
||||||
|
}
|
||||||
|
|
||||||
LuaDefine(world_wait, "f") {
|
LuaDefine(world_wait, "f") {
|
||||||
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
|
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
|
||||||
luaL_error(L, "Argument to wait must be a number.");
|
luaL_error(L, "Argument to wait must be a number.");
|
||||||
|
|||||||
@@ -68,12 +68,13 @@ public:
|
|||||||
//
|
//
|
||||||
int64_t id() { return plane_item_.id(); }
|
int64_t id() { return plane_item_.id(); }
|
||||||
|
|
||||||
void be_a_player();
|
// void be_a_player();
|
||||||
void update_plane_item();
|
void update_plane_item();
|
||||||
};
|
};
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// A lua intepreter with snapshot function.
|
// A lua intepreter with snapshot function.
|
||||||
//
|
//
|
||||||
LuaSnap lua_snap_;
|
LuaSnap lua_snap_;
|
||||||
@@ -99,8 +100,16 @@ public:
|
|||||||
// Serialized snapshot of world model.
|
// Serialized snapshot of world model.
|
||||||
StreamBuffer snapshot_;
|
StreamBuffer snapshot_;
|
||||||
|
|
||||||
|
// Redirects.
|
||||||
|
//
|
||||||
|
using Redirects = std::map<int64_t, int64_t>;
|
||||||
|
Redirects redirects_;
|
||||||
|
|
||||||
void run_scheduled_threads(int64_t clk);
|
void run_scheduled_threads(int64_t clk);
|
||||||
static void store_global_pointer(lua_State *L, World *w);
|
static void store_global_pointer(lua_State *L, World *w);
|
||||||
|
|
||||||
|
// Check if main thread has nothing on the stack
|
||||||
|
bool stack_is_clear() const { return lua_gettop(state()) == 0; }
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
//
|
//
|
||||||
@@ -125,7 +134,7 @@ public:
|
|||||||
//
|
//
|
||||||
// Get the lua interpreter associated with this world model.
|
// Get the lua interpreter associated with this world model.
|
||||||
//
|
//
|
||||||
lua_State *state() { return lua_snap_.state(); }
|
lua_State *state() const { return lua_snap_.state(); }
|
||||||
|
|
||||||
// get_near
|
// get_near
|
||||||
//
|
//
|
||||||
@@ -157,6 +166,18 @@ public:
|
|||||||
//
|
//
|
||||||
void tangible_delete(lua_State *L, int64_t id);
|
void tangible_delete(lua_State *L, int64_t id);
|
||||||
|
|
||||||
|
// Create a login actor.
|
||||||
|
//
|
||||||
|
// Creates a tangible of class 'login' and returns its ID.
|
||||||
|
// This is used to create a temporary actor which is used during
|
||||||
|
// the login process.
|
||||||
|
//
|
||||||
|
int64_t create_login_actor();
|
||||||
|
|
||||||
|
// Fetch all redirects and clear the redirects table.
|
||||||
|
//
|
||||||
|
Redirects fetch_redirects();
|
||||||
|
|
||||||
// Probe the 'interface' function of the specified sprite.
|
// Probe the 'interface' function of the specified sprite.
|
||||||
//
|
//
|
||||||
void update_gui(int64_t actor_id, int64_t place_id, Gui *gui);
|
void update_gui(int64_t actor_id, int64_t place_id, Gui *gui);
|
||||||
|
|||||||
Reference in New Issue
Block a user