Improve invoke_lua_call and probe_lua_call, don't pass actor/place, better support for classname/funcname
This commit is contained in:
Binary file not shown.
@@ -345,7 +345,7 @@ int64_t World::create_login_actor() {
|
|||||||
|
|
||||||
if (is_authoritative()) {
|
if (is_authoritative()) {
|
||||||
LS.rawget(func, classtab, "init");
|
LS.rawget(func, classtab, "init");
|
||||||
spawn(LS, id, id, func, true, 0, false);
|
spawn(LS, id, id, func, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_authoritative()) {
|
if (is_authoritative()) {
|
||||||
@@ -440,12 +440,9 @@ void World::probe_lua_call(int64_t place_id, int64_t actor_id, std::string_view
|
|||||||
} catch (const StreamException &ex) {
|
} catch (const StreamException &ex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((!sv::is_lua_id(classname)) || (!sv::is_lua_id(funcname))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LuaVar lclass, lfunc, actor, place, tangibles, retvec, retval;
|
LuaVar lclass, lfunc, actor, place, mt, tangibles, retvec, retval;
|
||||||
LuaExtStack LS(L, lclass, lfunc, actor, place, tangibles, retvec, retval);
|
LuaExtStack LS(L, lclass, lfunc, actor, place, mt, tangibles, retvec, retval);
|
||||||
|
|
||||||
// Get the actor and place, lua version. Make sure both exist.
|
// Get the actor and place, lua version. Make sure both exist.
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||||
@@ -455,21 +452,26 @@ void World::probe_lua_call(int64_t place_id, int64_t actor_id, std::string_view
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the class table and closure
|
// Get the class. If the classname is *, then use the class of the place.
|
||||||
eng::string err = LS.getclass(lclass, classname);
|
if (classname == "*") {
|
||||||
if ((!err.empty()) || (!LS.istable(lclass))) {
|
LS.getmetatable(mt, place);
|
||||||
return;
|
if (!LS.istable(mt)) return;
|
||||||
|
LS.rawget(lclass, mt, "__index");
|
||||||
|
} else {
|
||||||
|
LS.getclass(lclass, classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the true classname. This also checks validity of the class.
|
||||||
|
classname = LS.classname(lclass);
|
||||||
|
if (classname.empty()) return;
|
||||||
|
|
||||||
|
// Get the function from the class.
|
||||||
LS.rawget(lfunc, lclass, funcname);
|
LS.rawget(lfunc, lclass, funcname);
|
||||||
if (!LS.isfunction(lfunc)) {
|
if (!LS.isfunction(lfunc)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the closure.
|
// Call the closure.
|
||||||
lua_pushvalue(L, lfunc.index());
|
lua_pushvalue(L, lfunc.index());
|
||||||
lua_pushvalue(L, actor.index());
|
int nargs = 0;
|
||||||
lua_pushvalue(L, place.index());
|
|
||||||
int nargs = 2;
|
|
||||||
try {
|
try {
|
||||||
while (!datasb.empty()) {
|
while (!datasb.empty()) {
|
||||||
push_simple_dynamic(L, &datasb);
|
push_simple_dynamic(L, &datasb);
|
||||||
@@ -738,7 +740,7 @@ void World::invoke(const Invocation &inv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool World::spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func,
|
bool World::spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func,
|
||||||
bool passactorplace, int nargs, bool print) {
|
int nargs, bool print) {
|
||||||
lua_State *L = LS0.state();
|
lua_State *L = LS0.state();
|
||||||
LuaVar actor, place, mt, index, tangibles, thread, threads, thinfo;
|
LuaVar actor, place, mt, index, tangibles, thread, threads, thinfo;
|
||||||
LuaExtStack LS(L, actor, place, mt, index, tangibles, thread, threads, thinfo);
|
LuaExtStack LS(L, actor, place, mt, index, tangibles, thread, threads, thinfo);
|
||||||
@@ -783,14 +785,10 @@ bool World::spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new thread. Push function, and maybe actor and place.
|
// Create a new thread. Push function.
|
||||||
lua_State *CO = LS.newthread(thread);
|
lua_State *CO = LS.newthread(thread);
|
||||||
lua_pushvalue(L, func.index());
|
lua_pushvalue(L, func.index());
|
||||||
if (passactorplace) {
|
lua_xmove(L, CO, 1);
|
||||||
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
|
// Push any extra arguments. Extra arguments were pushed onto
|
||||||
// the lua stack before calling spawn, so they are located at oldtop.
|
// the lua stack before calling spawn, so they are located at oldtop.
|
||||||
@@ -858,21 +856,19 @@ void World::invoke_lua_expr(int64_t actor_id, int64_t place_id, std::string_view
|
|||||||
|
|
||||||
// Spawn the thread and run it.
|
// Spawn the thread and run it.
|
||||||
int nargs = 0;
|
int nargs = 0;
|
||||||
spawn(LS, actor_id, place_id, func, false, nargs, true);
|
spawn(LS, actor_id, place_id, func, nargs, true);
|
||||||
}
|
}
|
||||||
run_scheduled_threads();
|
run_scheduled_threads();
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile int vx;
|
|
||||||
|
|
||||||
void World::invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
void World::invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack) {
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
|
|
||||||
// Use a streambuffer to parse the datapack.
|
// Use a streambuffer to parse the datapack.
|
||||||
StreamBuffer datasb(datapack);
|
StreamBuffer datasb(datapack);
|
||||||
|
|
||||||
// Extract the class and function name from the datapack.
|
// Extract the class name and function name from the datapack.
|
||||||
eng::string classname;
|
eng::string classname;
|
||||||
eng::string funcname;
|
eng::string funcname;
|
||||||
try {
|
try {
|
||||||
@@ -881,29 +877,33 @@ void World::invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view
|
|||||||
} catch (const StreamException &ex) {
|
} catch (const StreamException &ex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((!sv::is_lua_id(classname)) || (!sv::is_lua_id(funcname))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO: Add support for the wildcard classname.
|
|
||||||
// TODO: Add check for permit_invoke(classname, funcname)
|
|
||||||
|
|
||||||
if (funcname == "printhi") {
|
|
||||||
vx = 0;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar lclass, lfunc;
|
LuaVar tangibles, place, mt, lclass, lfunc;
|
||||||
LuaExtStack LS(L, lclass, lfunc);
|
LuaExtStack LS(L, tangibles, place, mt, lclass, lfunc);
|
||||||
|
|
||||||
// Get the class table and closure
|
// Get the class. If the classname is *, then use the class of the place.
|
||||||
eng::string err = LS.getclass(lclass, classname);
|
if (classname == "*") {
|
||||||
if ((!err.empty()) || (!LS.istable(lclass))) {
|
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||||
return;
|
LS.rawget(place, tangibles, place_id);
|
||||||
|
if (LS.isnil(place)) return;
|
||||||
|
LS.getmetatable(mt, place);
|
||||||
|
if (!LS.istable(mt)) return;
|
||||||
|
LS.rawget(lclass, mt, "__index");
|
||||||
|
} else {
|
||||||
|
LS.getclass(lclass, classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the true classname. This also checks validity of the class.
|
||||||
|
classname = LS.classname(lclass);
|
||||||
|
if (classname.empty()) return;
|
||||||
|
|
||||||
|
// TODO: CHECK FOR PERMIT_INVOKE.
|
||||||
|
|
||||||
|
// Get the function from the class.
|
||||||
LS.rawget(lfunc, lclass, funcname);
|
LS.rawget(lfunc, lclass, funcname);
|
||||||
if (!LS.isfunction(lfunc)) {
|
if (!LS.isfunction(lfunc)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spawn a thread, pushing extra arguments from the datapack.
|
// Spawn a thread, pushing extra arguments from the datapack.
|
||||||
int nargs = 0;
|
int nargs = 0;
|
||||||
@@ -915,8 +915,10 @@ void World::invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view
|
|||||||
} catch (const StreamException &exc) {
|
} catch (const StreamException &exc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spawn(LS, actor_id, place_id, lfunc, true, nargs, false);
|
spawn(LS, actor_id, place_id, lfunc, nargs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run the new thread and return.
|
||||||
run_scheduled_threads();
|
run_scheduled_threads();
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ private:
|
|||||||
|
|
||||||
// Low level spawn thread function.
|
// 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);
|
bool spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func, int nargs, bool print);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -10,15 +10,17 @@ function tree.init(self, config)
|
|||||||
wait(1)
|
wait(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function login.init(actor, place)
|
function login.init()
|
||||||
|
local actor = tangible.actor()
|
||||||
dprint("login.init:", actor)
|
dprint("login.init:", actor)
|
||||||
local x = math.random(1, 100)
|
local x = math.random(1, 100)
|
||||||
local y = math.random(1, 100)
|
local y = math.random(1, 100)
|
||||||
tangible.animate(actor, nil, {bp="tangiblecharacter", action="warpto", plane="earth", xyz={x, y, 90}})
|
tangible.animate(actor, nil, {bp="tangiblecharacter", action="warpto", plane="earth", xyz={x, y, 90}})
|
||||||
end
|
end
|
||||||
|
|
||||||
function engio.move(actor, place, action, xyz, facing)
|
function engio.move(action, xyz, facing)
|
||||||
-- todo: sanity check the parameters.
|
-- todo: sanity check the parameters.
|
||||||
|
local actor = tangible.actor()
|
||||||
dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
|
dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
|
||||||
tangible.animate(actor, nil, {action=action, xyz=xyz, facing=facing})
|
tangible.animate(actor, nil, {action=action, xyz=xyz, facing=facing})
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user