tangible.start is functional
This commit is contained in:
@@ -292,6 +292,128 @@ LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere",
|
|||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
|
||||||
|
"|Start a thread."
|
||||||
|
"|"
|
||||||
|
"|Every thread is owned by a tangible. The first argument"
|
||||||
|
"|to 'tangible.start' indicates the tangible that owns"
|
||||||
|
"|the new thread."
|
||||||
|
"|"
|
||||||
|
"|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"
|
||||||
|
"|used to look up the relevant closure."
|
||||||
|
"|"
|
||||||
|
"|The arguments arg1,arg2... will be passed to the"
|
||||||
|
"|function."
|
||||||
|
"|"
|
||||||
|
"|Actor and place aren't passed to the function unless"
|
||||||
|
"|you manually include them in the list arg1, arg2, etc."
|
||||||
|
"|The new thread can, however, use the builtin "
|
||||||
|
"|functions 'tangible.actor' and 'tangible.place' to obtain "
|
||||||
|
"|actor and place. Actor will be the same actor who "
|
||||||
|
"|called 'tangible.start'. Place will be the tangible that"
|
||||||
|
"|owns the thread, ie, the tangible passed to 'tangible.start'."
|
||||||
|
"|"
|
||||||
|
"|The new thread doesn't start running instantly:"
|
||||||
|
"|it waits until the current thread is finished. The"
|
||||||
|
"|current thread must either block (eg, 'wait') or terminate"
|
||||||
|
"|before the new thread can actually begin execution."
|
||||||
|
"|"
|
||||||
|
"|If you start a thread, then start another, then both of"
|
||||||
|
"|the newly-started threads wait until the current thread"
|
||||||
|
"|is finished. At that point, it is undefined which of the"
|
||||||
|
"|two new threads runs first."
|
||||||
|
"|"
|
||||||
|
"|Threads are owned by tangibles. If a tangible is"
|
||||||
|
"|deleted, then none of its threads will ever be resumed,"
|
||||||
|
"|for any reason."
|
||||||
|
"|"
|
||||||
|
"|However, if a thread deletes its own place (ie, the tangible"
|
||||||
|
"|that owns the thread), then the thread will be allowed"
|
||||||
|
"|to continue running until it blocks. But from that point"
|
||||||
|
"|forward, the thread will never be resumed for any reason.") {
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top < 2) {
|
||||||
|
luaL_error(L, "Not enough arguments to tangible.start");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int varlen = top - 2;
|
||||||
|
|
||||||
|
World *w = World::fetch_global_pointer(L);
|
||||||
|
w->guard_nopredict(L, "tangible.start");
|
||||||
|
|
||||||
|
LuaVar mt, classtab, plthreads, thread, thinfo;
|
||||||
|
LuaStack LS(L, mt, classtab, plthreads, thread, thinfo);
|
||||||
|
LuaSpecial place(1);
|
||||||
|
LuaSpecial func(2);
|
||||||
|
|
||||||
|
// Confirm that the place is a valid tangible,
|
||||||
|
// and get the tangible ID.
|
||||||
|
w->tangible_get(LS, place);
|
||||||
|
int64_t place_id = LS.tanid(place);
|
||||||
|
|
||||||
|
// Get place's metatable.
|
||||||
|
LS.getmetatable(mt, place);
|
||||||
|
if (!LS.istable(mt)) {
|
||||||
|
luaL_error(L, "invalid tangible passed to tangible.start");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get place's threads table.
|
||||||
|
LS.rawget(plthreads, mt, "threads");
|
||||||
|
if (!LS.istable(plthreads)) {
|
||||||
|
luaL_error(L, "invalid tangible passed to tangible.start");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the function is actually a function-name,
|
||||||
|
// then convert it to a closure.
|
||||||
|
if (!LS.isfunction(func)) {
|
||||||
|
if (!LS.isstring(func)) {
|
||||||
|
luaL_error(L, "invalid function passed to tangible.start");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LS.rawget(classtab, mt, "__index");
|
||||||
|
if (!LS.istable(classtab)) {
|
||||||
|
luaL_error(L, "tangible doesn't have a class table in tangible.start");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LS.rawget(func, classtab, func);
|
||||||
|
if (!LS.isfunction(func)) {
|
||||||
|
luaL_error(L, "tangible doesn't have specified method in tangible.start");
|
||||||
|
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.
|
||||||
|
lua_State *CO = LS.newthread(thread);
|
||||||
|
lua_pushvalue(L, func.index());
|
||||||
|
for (int i = 0; i < varlen; i++) {
|
||||||
|
lua_pushvalue(L, i + 3);
|
||||||
|
}
|
||||||
|
lua_xmove(L, CO, varlen + 1);
|
||||||
|
|
||||||
|
// Create the thread info table.
|
||||||
|
LS.newtable(thinfo);
|
||||||
|
LS.rawset(thinfo, "thread", thread);
|
||||||
|
LS.rawset(thinfo, "actorid", w->lthread_actor_id_);
|
||||||
|
LS.rawset(thinfo, "isnew", true);
|
||||||
|
LS.rawset(thinfo, "useppool", false);
|
||||||
|
LS.rawset(thinfo, "print", false);
|
||||||
|
|
||||||
|
LS.rawset(plthreads, tid, thinfo);
|
||||||
|
LS.result();
|
||||||
|
|
||||||
|
// Push the thread's ID into the runnable thread queue.
|
||||||
|
w->schedule(0, tid, place_id);
|
||||||
|
return LS.result();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaDefine(wait, "nticks",
|
LuaDefine(wait, "nticks",
|
||||||
"|Wait the specified number of ticks.") {
|
"|Wait the specified number of ticks.") {
|
||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
|
|||||||
@@ -299,6 +299,9 @@ 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);
|
||||||
@@ -543,6 +546,7 @@ private:
|
|||||||
friend int lfn_tangible_nopredict(lua_State *L);
|
friend int lfn_tangible_nopredict(lua_State *L);
|
||||||
friend int lfn_tangible_near(lua_State *L);
|
friend int lfn_tangible_near(lua_State *L);
|
||||||
friend int lfn_tangible_scan(lua_State *L);
|
friend int lfn_tangible_scan(lua_State *L);
|
||||||
|
friend int lfn_tangible_start(lua_State *L);
|
||||||
friend int lfn_math_random(lua_State *L);
|
friend int lfn_math_random(lua_State *L);
|
||||||
friend int lfn_math_randomstate(lua_State *L);
|
friend int lfn_math_randomstate(lua_State *L);
|
||||||
friend int lfn_wait(lua_State *L);
|
friend int lfn_wait(lua_State *L);
|
||||||
|
|||||||
Reference in New Issue
Block a user