Add code for invoke_lua_call

This commit is contained in:
2024-08-28 19:40:23 -04:00
parent d1efa7f528
commit 811df62bc6
4 changed files with 61 additions and 0 deletions

View File

@@ -31,6 +31,8 @@ eng::string Invocation::debug_string() const {
oss << "inv["; oss << "inv[";
switch (kind_) { switch (kind_) {
case KIND_INVALID: oss << "invalid"; break; case KIND_INVALID: oss << "invalid"; break;
case KIND_ENGIO: oss << "engio"; break;
case KIND_LUA_CALL: oss << "lua_call"; break;
case KIND_LUA: oss << "lua"; break; case KIND_LUA: oss << "lua"; break;
case KIND_FLUSH_PRINTS: oss << "flush_prints"; break; case KIND_FLUSH_PRINTS: oss << "flush_prints"; break;
case KIND_TICK: oss << "tick"; break; case KIND_TICK: oss << "tick"; break;

View File

@@ -51,6 +51,7 @@ public:
enum Kind { enum Kind {
KIND_INVALID, KIND_INVALID,
KIND_ENGIO, KIND_ENGIO,
KIND_LUA_CALL,
KIND_LUA, KIND_LUA,
KIND_FLUSH_PRINTS, KIND_FLUSH_PRINTS,
KIND_TICK, KIND_TICK,

View File

@@ -554,6 +554,9 @@ void World::invoke(const Invocation &inv) {
case Invocation::KIND_ENGIO: case Invocation::KIND_ENGIO:
invoke_engio(inv.actor(), inv.place(), inv.datapack()); invoke_engio(inv.actor(), inv.place(), inv.datapack());
break; break;
case Invocation::KIND_LUA_CALL:
invoke_lua_call(inv.actor(), inv.place(), inv.datapack());
break;
case Invocation::KIND_LUA: case Invocation::KIND_LUA:
invoke_lua(inv.actor(), inv.place(), inv.datapack()); invoke_lua(inv.actor(), inv.place(), inv.datapack());
break; break;
@@ -784,6 +787,57 @@ void World::invoke_engio(int64_t actor_id, int64_t place_id, std::string_view da
assert(stack_is_clear()); assert(stack_is_clear());
} }
void World::invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack) {
assert(stack_is_clear());
// Use a streambuffer to parse the datapack.
StreamBuffer datasb(datapack);
// Extract the class and function name from the datapack.
eng::string classname;
eng::string funcname;
try {
classname = datasb.read_string_limit(100);
funcname = datasb.read_string_limit(100);
} catch (const StreamException &ex) {
return;
}
if ((!sv::is_lua_id(classname)) || (!sv::is_lua_id(funcname))) {
return;
}
// TODO: Add check for permit_invoke(classname, funcname)
{
lua_State *L = state();
LuaVar lclass, lfunc;
LuaExtStack LS(L, lclass, lfunc);
// Get the class table and closure
eng::string err = LS.getclass(lclass, classname);
if ((!err.empty()) || (!LS.istable(lclass))) {
return;
}
LS.rawget(lfunc, lclass, funcname);
if (!LS.isfunction(lfunc)) {
return;
}
// Spawn a thread, pushing extra arguments from the datapack.
int nargs = 0;
try {
while (!datasb.empty()) {
push_simple_dynamic(L, &datasb);
nargs++;
}
} catch (const StreamException &exc) {
return;
}
spawn(LS, actor_id, place_id, lfunc, true, nargs, false);
}
run_scheduled_threads();
assert(stack_is_clear());
}
void World::invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack) { void World::invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack) {
if (!is_authoritative()) { if (!is_authoritative()) {
return; return;

View File

@@ -394,6 +394,10 @@ private:
// //
void invoke_engio(int64_t actor_id, int64_t place_id, std::string_view datapack); void invoke_engio(int64_t actor_id, int64_t place_id, std::string_view datapack);
// Invoke the lua_call operation.
//
void invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack);
// Invoke a lua string. // Invoke a lua string.
// //
void invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack); void invoke_lua(int64_t actor_id, int64_t place_id, std::string_view datapack);