void xd::lua::scheduler::start(luabind::object func) { // create a new thread lua_State *thread = lua_newthread(m_vm.lua_state()); // push the function in the new thread, because the function // the thread calls must be called in its local environment func.push(thread); // construct a callable object from it, the value is copied from stack luabind::object thread_func(luabind::from_stack(thread, -1)); // remove the original value from the stack lua_pop(thread, 1); // set the current thread m_thread_stack->threads.push(thread); m_current_thread = thread; // start the thread luabind::object result = luabind::resume_function<luabind::object>(thread_func); // if the thread was yielded from lua side, and the return value is a callable function int type = luabind::type(result); if (type == LUA_TFUNCTION || type == LUA_TTABLE || type == LUA_TUSERDATA) { yield(xd::create<detail::callback_task_lua>(result)); } // reset current thread m_thread_stack->threads.pop(); if (m_thread_stack->threads.empty()) m_current_thread = nullptr; else m_current_thread = m_thread_stack->threads.top(); }
// TODO Move arguments from constructor to here? void timer::start(luabind::object& f) { thread = player->create_lua_thread(); #ifndef NDEBUG int old_top = lua_gettop(thread); #endif //function.push(thread); f.push(f.interpreter()); lua_xmove(f.interpreter(), thread, 1); assert(old_top + 1 == lua_gettop(thread)); timer_thread = boost::thread(&timer::count_down, this); }