Refactor code in world-core that spawns threads
This commit is contained in:
@@ -87,6 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_choose_command(const StringVec &cmd) {
|
void do_choose_command(const StringVec &cmd) {
|
||||||
|
stdostream() << "Chose menu item: " << cmd[1] << std::endl;
|
||||||
eng::string action = gui_.get_action(sv::to_int64(cmd[1]));
|
eng::string action = gui_.get_action(sv::to_int64(cmd[1]));
|
||||||
if (action == "") {
|
if (action == "") {
|
||||||
stdostream() << "Invalid menu item #" << std::endl;
|
stdostream() << "Invalid menu item #" << std::endl;
|
||||||
|
|||||||
@@ -54,9 +54,10 @@ void LuaConsole::simplify(const StringVec &words) {
|
|||||||
return;
|
return;
|
||||||
} else if (sv::valid_int64(words[0])) {
|
} else if (sv::valid_int64(words[0])) {
|
||||||
if (words.size() == 1) {
|
if (words.size() == 1) {
|
||||||
|
eng::string num = words[0];
|
||||||
words_.clear();
|
words_.clear();
|
||||||
words_.push_back("choose");
|
words_.push_back("choose");
|
||||||
words_.push_back(words[0]);
|
words_.push_back(num);
|
||||||
} else {
|
} else {
|
||||||
synerr("/choose command takes no arguments");
|
synerr("/choose command takes no arguments");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -664,6 +664,8 @@ public:
|
|||||||
template<class... SS>
|
template<class... SS>
|
||||||
LuaExtStack(const LuaCoreStack &LS0, SS & ... stackslots) : LuaCoreStack(LS0.state(), stackslots...) {}
|
LuaExtStack(const LuaCoreStack &LS0, SS & ... stackslots) : LuaCoreStack(LS0.state(), stackslots...) {}
|
||||||
|
|
||||||
|
int oldtop() const { return oldtop_; }
|
||||||
|
|
||||||
~LuaExtStack() {
|
~LuaExtStack() {
|
||||||
if (!lua_isthrowing(L_)) {
|
if (!lua_isthrowing(L_)) {
|
||||||
lua_settop(L_, oldtop_);
|
lua_settop(L_, oldtop_);
|
||||||
|
|||||||
@@ -594,6 +594,90 @@ void World::invoke(const Invocation &inv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool World::spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func,
|
||||||
|
bool passactorplace, int nargs, bool print) {
|
||||||
|
lua_State *L = LS0.state();
|
||||||
|
LuaVar actor, place, mt, index, tangibles, thread, threads, thinfo;
|
||||||
|
LuaExtStack LS(L, actor, place, mt, index, tangibles, thread, threads, thinfo);
|
||||||
|
|
||||||
|
// Get the actor and place, C++ version. Make sure both exist.
|
||||||
|
Tangible *tactor = tangible_get(actor_id);
|
||||||
|
Tangible *tplace = tangible_get(place_id);
|
||||||
|
if ((tactor == nullptr) || (tplace == nullptr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the actor and place, lua version. Make sure both exist.
|
||||||
|
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||||
|
LS.rawget(actor, tangibles, actor_id);
|
||||||
|
LS.rawget(place, tangibles, place_id);
|
||||||
|
if (!LS.istable(actor) || !LS.istable(place)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an ID for the thread.
|
||||||
|
// We currently always use the actor pool. We may extend
|
||||||
|
// this to allow the use of the place pool.
|
||||||
|
int64_t tid = tactor->id_player_pool_.get_one();
|
||||||
|
|
||||||
|
// Get the place's metatable.
|
||||||
|
LS.getmetatable(mt, place);
|
||||||
|
if (!LS.istable(mt)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the function is a string, look it up in the place's class.
|
||||||
|
if (LS.isstring(func)) {
|
||||||
|
LS.rawget(index, mt, "__index");
|
||||||
|
if (!LS.istable(index)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LS.rawget(func, index, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the function is a function.
|
||||||
|
if (!LS.isfunction(func)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new thread. Push function, and maybe actor and place.
|
||||||
|
lua_State *CO = LS.newthread(thread);
|
||||||
|
lua_pushvalue(L, func.index());
|
||||||
|
if (passactorplace) {
|
||||||
|
lua_pushvalue(L, actor.index());
|
||||||
|
lua_pushvalue(L, place.index());
|
||||||
|
}
|
||||||
|
lua_xmove(L, CO, passactorplace ? 3:1);
|
||||||
|
|
||||||
|
// Push any extra arguments. Extra arguments were pushed onto
|
||||||
|
// the lua stack before calling spawn, so they are located at oldtop.
|
||||||
|
if (nargs > 0) {
|
||||||
|
int base = LS.oldtop() - nargs + 1;
|
||||||
|
for (int i = 0; i < nargs; i++) {
|
||||||
|
lua_pushvalue(L, base + i);
|
||||||
|
}
|
||||||
|
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", print);
|
||||||
|
|
||||||
|
// Store the thread into place's thread table.
|
||||||
|
LS.rawget(threads, mt, "threads");
|
||||||
|
if (!LS.istable(threads)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LS.rawset(threads, tid, thinfo);
|
||||||
|
|
||||||
|
schedule(0, tid, place_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
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.
|
||||||
@@ -614,22 +698,10 @@ void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_
|
|||||||
|
|
||||||
void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
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.
|
|
||||||
Tangible *tactor = tangible_get(actor_id);
|
|
||||||
Tangible *tplace = tangible_get(place_id);
|
|
||||||
if ((tactor == nullptr) || (tplace == nullptr)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a thread ID for the new thread.
|
|
||||||
int64_t tid = tplace->id_player_pool_.get_one();
|
|
||||||
|
|
||||||
// Set up for lua manipulation.
|
|
||||||
{
|
{
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar func, tangibles, place, mt, thread, thinfo, threads;
|
LuaVar func;
|
||||||
LuaExtStack LS(L, func, tangibles, place, mt, thread, thinfo, threads);
|
LuaExtStack LS(L, func);
|
||||||
|
|
||||||
// create the compiled closure.
|
// create the compiled closure.
|
||||||
int status = luaL_loadbuffer(L, datapack.data(), datapack.size(), "=invoke");
|
int status = luaL_loadbuffer(L, datapack.data(), datapack.size(), "=invoke");
|
||||||
@@ -641,41 +713,10 @@ void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view data
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the place.
|
// Spawn the thread and run it.
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
int nargs = 0;
|
||||||
LS.rawget(place, tangibles, place_id);
|
spawn(LS, actor_id, place_id, func, false, nargs, true);
|
||||||
if (!LS.istable(place)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the place's metatable.
|
|
||||||
LS.getmetatable(mt, place);
|
|
||||||
if (!LS.istable(mt)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new thread, set up function and parameters.
|
|
||||||
lua_State *CO = LS.newthread(thread);
|
|
||||||
lua_pushvalue(L, func.index());
|
|
||||||
lua_xmove(L, CO, 1);
|
|
||||||
|
|
||||||
// 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", true);
|
|
||||||
|
|
||||||
// Store the thread into place's thread table.
|
|
||||||
LS.rawget(threads, mt, "threads");
|
|
||||||
if (!LS.istable(threads)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawset(threads, tid, thinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule(0, tid, place_id);
|
|
||||||
run_scheduled_threads();
|
run_scheduled_threads();
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
@@ -694,77 +735,23 @@ void World::invoke_choose(int64_t actor_id, int64_t place_id, std::string_view d
|
|||||||
if (!sv::has_prefix(datapack, "cb_")) {
|
if (!sv::has_prefix(datapack, "cb_")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Set up for Lua manipulation.
|
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar actor, place, func, tangibles, mt, index, thread, threads, thinfo, message, invdata;
|
LuaVar func, invdata;
|
||||||
LuaExtStack LS(L, actor, place, func, tangibles, mt, index, thread, threads, thinfo, message, invdata);
|
LuaExtStack LS(L, func, invdata);
|
||||||
|
|
||||||
// Get the actor and place.
|
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
|
||||||
LS.rawget(actor, tangibles, actor_id);
|
|
||||||
LS.rawget(place, tangibles, place_id);
|
|
||||||
if (!LS.istable(actor) || !LS.istable(place)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the action closure.
|
LS.set(func, datapack);
|
||||||
LS.getmetatable(mt, place);
|
|
||||||
if (!LS.istable(mt)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawget(index, mt, "__index");
|
|
||||||
if (!LS.istable(index)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LS.rawget(func, index, datapack);
|
|
||||||
if (!LS.isfunction(func)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: maybe add the ability to pass data in as a table?
|
// We're planning to add the ability to pass data in as a table.
|
||||||
// For now the table is always empty.
|
// For now the table is always empty.
|
||||||
LS.newtable(invdata);
|
LS.newtable(invdata);
|
||||||
|
|
||||||
// Create a new thread, set up function and parameters.
|
// Spawn the thread and run it.
|
||||||
lua_State *CO = LS.newthread(thread);
|
int nargs = 1;
|
||||||
lua_pushvalue(L, func.index());
|
|
||||||
lua_pushvalue(L, actor.index());
|
|
||||||
lua_pushvalue(L, place.index());
|
|
||||||
lua_pushvalue(L, invdata.index());
|
lua_pushvalue(L, invdata.index());
|
||||||
lua_xmove(L, CO, 4);
|
spawn(LS, actor_id, place_id, func, true, nargs, false);
|
||||||
|
|
||||||
// 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.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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,6 +373,10 @@ private:
|
|||||||
//
|
//
|
||||||
void invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
void invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
||||||
|
|
||||||
|
// Low level spawn thread function.
|
||||||
|
//
|
||||||
|
bool spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func, bool passactorplace, int nargs, bool print);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ function login.cb_becomeplayer(actor, place, dialog)
|
|||||||
tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0})
|
tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function login.cb_p123(actor, place, dialog)
|
||||||
|
print("CB_P123 actor=", actor, " place=", place, " dialog=", dialog);
|
||||||
|
print(1);
|
||||||
|
print(2);
|
||||||
|
print(3);
|
||||||
|
end
|
||||||
|
|
||||||
function bechar()
|
function bechar()
|
||||||
local a = tangible.actor()
|
local a = tangible.actor()
|
||||||
|
|||||||
Reference in New Issue
Block a user