tangible.start version 2: multistart
This commit is contained in:
@@ -297,7 +297,9 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
|
|||||||
"|"
|
"|"
|
||||||
"|Every thread is owned by a tangible. The first argument"
|
"|Every thread is owned by a tangible. The first argument"
|
||||||
"|to 'tangible.start' indicates the tangible that owns"
|
"|to 'tangible.start' indicates the tangible that owns"
|
||||||
"|the new thread."
|
"|the new thread. Instead of passing a single tangible,"
|
||||||
|
"|you can pass a list of tangibles, in which case a thread"
|
||||||
|
"|is started on each tangible."
|
||||||
"|"
|
"|"
|
||||||
"|The function can be a lua closure, or it can be a string."
|
"|The function can be a lua closure, or it can be a string."
|
||||||
"|If it's a string, then the tangible's class will be"
|
"|If it's a string, then the tangible's class will be"
|
||||||
@@ -341,54 +343,58 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
|
|||||||
int varlen = top - 2;
|
int varlen = top - 2;
|
||||||
|
|
||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
w->guard_nopredict(L, "tangible.start");
|
w->guard_blockable(L, "tangible.start");
|
||||||
|
|
||||||
LuaVar mt, classtab, plthreads, thread, thinfo;
|
LuaVar mt, classtab, plthreads, thread, thinfo, func, tanlist;
|
||||||
LuaStack LS(L, mt, classtab, plthreads, thread, thinfo);
|
LuaStack LS(L, mt, classtab, plthreads, thread, thinfo, func, tanlist);
|
||||||
LuaSpecial place(1);
|
LuaSpecial place(1);
|
||||||
LuaSpecial func(2);
|
LuaSpecial fname(2);
|
||||||
|
|
||||||
|
// If they passed in a single tangible, convert it to a tangible list.
|
||||||
|
int64_t place_id = LS.tanid(place);
|
||||||
|
if (place_id != 0) {
|
||||||
|
LS.newtable(tanlist);
|
||||||
|
LS.rawset(tanlist, 1, place);
|
||||||
|
} else {
|
||||||
|
LS.set(tanlist, place);
|
||||||
|
if (!LS.istable(tanlist)) {
|
||||||
|
luaL_error(L, "tangible.start expects a tangible or list of tangibles");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; ; i++) {
|
||||||
|
LS.rawget(place, tanlist, i);
|
||||||
|
if (LS.isnil(place)) break;
|
||||||
|
|
||||||
// Confirm that the place is a valid tangible,
|
// Confirm that the place is a valid tangible,
|
||||||
// and get the tangible ID.
|
// and get the tangible ID.
|
||||||
w->tangible_get(LS, place);
|
w->tangible_get(LS, place);
|
||||||
int64_t place_id = LS.tanid(place);
|
place_id = LS.tanid(place);
|
||||||
|
|
||||||
// Get place's metatable.
|
// Get place's metatable and threads table.
|
||||||
LS.getmetatable(mt, place);
|
LS.getmetatable(mt, place);
|
||||||
if (!LS.istable(mt)) {
|
assert(LS.istable(mt));
|
||||||
luaL_error(L, "invalid tangible passed to tangible.start");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get place's threads table.
|
|
||||||
LS.rawget(plthreads, mt, "threads");
|
LS.rawget(plthreads, mt, "threads");
|
||||||
if (!LS.istable(plthreads)) {
|
assert(LS.istable(plthreads));
|
||||||
luaL_error(L, "invalid tangible passed to tangible.start");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the function is actually a function-name,
|
// Get the function closure.
|
||||||
// then convert it to a closure.
|
if (LS.isfunction(fname)) {
|
||||||
if (!LS.isfunction(func)) {
|
LS.set(func, fname);
|
||||||
if (!LS.isstring(func)) {
|
} else if (LS.isstring(fname)) {
|
||||||
luaL_error(L, "invalid function passed to tangible.start");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LS.rawget(classtab, mt, "__index");
|
LS.rawget(classtab, mt, "__index");
|
||||||
if (!LS.istable(classtab)) {
|
assert(LS.istable(classtab));
|
||||||
luaL_error(L, "tangible doesn't have a class table in tangible.start");
|
LS.rawget(func, classtab, fname);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LS.rawget(func, classtab, func);
|
|
||||||
if (!LS.isfunction(func)) {
|
if (!LS.isfunction(func)) {
|
||||||
luaL_error(L, "tangible doesn't have specified method in tangible.start");
|
eng::string cfname = LS.ckstring(fname);
|
||||||
|
luaL_error(L, "tangible doesn't have method: %s", cfname.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
luaL_error(L, "invalid function, expected closure or string");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a thread ID for the new thread
|
|
||||||
int64_t tid = w->alloc_id_predictable();
|
|
||||||
|
|
||||||
// Create a new thread, set up function and arguments.
|
// Create a new thread, set up function and arguments.
|
||||||
lua_State *CO = LS.newthread(thread);
|
lua_State *CO = LS.newthread(thread);
|
||||||
lua_pushvalue(L, func.index());
|
lua_pushvalue(L, func.index());
|
||||||
@@ -405,11 +411,14 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
|
|||||||
LS.rawset(thinfo, "useppool", false);
|
LS.rawset(thinfo, "useppool", false);
|
||||||
LS.rawset(thinfo, "print", false);
|
LS.rawset(thinfo, "print", false);
|
||||||
|
|
||||||
|
// Get a thread ID for the new thread, store it in
|
||||||
|
// the thread table.
|
||||||
|
int64_t tid = w->alloc_id_predictable();
|
||||||
LS.rawset(plthreads, tid, thinfo);
|
LS.rawset(plthreads, tid, thinfo);
|
||||||
LS.result();
|
|
||||||
|
|
||||||
// Push the thread's ID into the runnable thread queue.
|
// Push the thread's ID into the runnable thread queue.
|
||||||
w->schedule(0, tid, place_id);
|
w->schedule(0, tid, place_id);
|
||||||
|
}
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -299,9 +299,6 @@ private:
|
|||||||
//
|
//
|
||||||
static void store_global_pointer(lua_State *L, World *w);
|
static void store_global_pointer(lua_State *L, World *w);
|
||||||
|
|
||||||
// Start a thread on the specified tangible.
|
|
||||||
void tangible_start(Tangible *actor, Tangible *place, LuaStack &LS, LuaSlot func, int argpos, int nargs);
|
|
||||||
|
|
||||||
// Invoke a plan.
|
// Invoke a plan.
|
||||||
//
|
//
|
||||||
void invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data);
|
void invoke_plan(int64_t actor_id, int64_t place_id, const eng::string &action, const InvocationData &data);
|
||||||
|
|||||||
Reference in New Issue
Block a user