Add invoke_choose and invoke_player to DrivenEngine. invoke_player is not fully implemented in World
This commit is contained in:
@@ -566,8 +566,11 @@ void World::run_unittests() {
|
||||
|
||||
void World::invoke(const Invocation &inv) {
|
||||
switch (inv.kind()) {
|
||||
case Invocation::KIND_PLAN:
|
||||
invoke_plan(inv.actor(), inv.place(), inv.datapack());
|
||||
case Invocation::KIND_CHOOSE:
|
||||
invoke_choose(inv.actor(), inv.place(), inv.datapack());
|
||||
break;
|
||||
case Invocation::KIND_PLAYER:
|
||||
invoke_player(inv.actor(), inv.place(), inv.datapack());
|
||||
break;
|
||||
case Invocation::KIND_LUA:
|
||||
invoke_lua(inv.actor(), inv.place(), inv.datapack());
|
||||
@@ -609,8 +612,6 @@ void World::invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
assert(stack_is_clear());
|
||||
|
||||
@@ -679,7 +680,7 @@ void World::invoke_lua(int64_t actor_id, int64_t place_id, std::string_view data
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
void World::invoke_plan(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
void World::invoke_choose(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
assert(stack_is_clear());
|
||||
|
||||
// Validate that the action is legal.
|
||||
@@ -768,6 +769,98 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, std::string_view dat
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
void World::invoke_player(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
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.
|
||||
StreamBuffer datasb(datapack);
|
||||
|
||||
// Extract the function name from the datapack.
|
||||
eng::string funcname;
|
||||
try {
|
||||
funcname = datasb.read_string_limit(100);
|
||||
} catch (const StreamException &ex) {
|
||||
return;
|
||||
}
|
||||
if (sv::is_lua_id(funcname)) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
// Set up for Lua manipulation.
|
||||
lua_State *L = state();
|
||||
LuaVar actor, place, func, mt, tangibles, playercb, thread, threads, thinfo, message;
|
||||
LuaExtStack LS(L, actor, place, func, mt, tangibles, playercb, thread, threads, thinfo, message);
|
||||
|
||||
// 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 closure (playerinvoke.funcname).
|
||||
eng::string err = LS.getclass(playercb, "playerinvoke");
|
||||
if ((!err.empty()) || (!LS.istable(playercb))) {
|
||||
return;
|
||||
}
|
||||
LS.rawget(func, playercb, funcname);
|
||||
if (!LS.isfunction(func)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new thread, push func, actor, place.
|
||||
int nargs = 3;
|
||||
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.
|
||||
// TODO: IMPLEMENT ME.
|
||||
|
||||
// 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();
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
void World::invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||
if (!is_authoritative()) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user