type get_type() const { type t = type::none; auto pp = stack::push_pop(tbl); auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state())); if (p) { t = type_of(lua_state(), -1); } lua_pop(lua_state(), p.levels); return t; }
int push(lua_State* Ls) const noexcept { if (lua_state() == nullptr) { lua_pushnil(Ls); return 1; } lua_pushvalue(lua_state(), index); if (Ls != lua_state()) { lua_xmove(lua_state(), Ls, 1); } return 1; }
int main() { if (!lua_init()) { printf("cannot init lua\n"); exit(1); } lua_register(lua_state(), "simpleclient_create", simpleclient_create_lua); lua_register(lua_state(), "simpleclient_destroy", simpleclient_destroy_lua); lua_register(lua_state(), "simpleclient_connect", simpleclient_connect_lua); lua_dofile("./scripts/main.lua"); lua_fini(); }
virtual int on_timeout(int tid) { lua_timer* ltimer = gtimers[tid]; if (!ltimer) { printf("timer %d no callback\n", tid); return -1; } printf("%s\n", ltimer->cbname); lua_getglobal(lua_state(), ltimer->cbname); lua_pushlightuserdata(lua_state(), (void*)ltimer); lua_call(lua_state(), 1, 0); return 0; }
stack_reference(lua_State* L, const stack_reference& r) noexcept : luastate(L) { if (!r.valid()) { index = 0; return; } int i = r.stack_index(); if (detail::xmovable(lua_state(), r.lua_state())) { lua_pushvalue(r.lua_state(), r.index); lua_xmove(r.lua_state(), luastate, 1); i = absolute_index(luastate, -1); } index = i; }
static int lua_import_stream(stream_t* stream, const uuid_t uuid, luaimport_dump_t* dump) { lua_t* env; lua_State* state; int result = 0; lua_readstream_t read_stream = { .stream = stream, }; env = lua_allocate(); state = lua_state(env); if (lua_load(state, lua_read_stream, &read_stream, "import") != 0) { log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua load failed: %s"), lua_tostring(state, -1)); lua_pop(state, 1); result = -1; goto exit; } lua_dump(state, lua_import_dump_writer, dump); if (lua_pcall(state, 0, 0, 0) != 0) { log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua pcall failed: %s"), lua_tostring(state, -1)); lua_pop(state, 1); result = -1; goto exit; } log_debug(HASH_LUA, STRING_CONST("Lua bytecode dump successful")); exit: lua_deallocate(env); return result; }
int push() const noexcept { return push(lua_state()); }
type get_type() const noexcept { int result = lua_type(lua_state(), index); return static_cast<type>(result); }
void pop() const noexcept { pop(lua_state()); }
thread create() { return create(lua_state()); }
lua_State* thread_state() const { auto pp = stack::push_pop(*this); lua_State* lthread = lua_tothread(lua_state(), -1); return lthread; }
auto setup_table(std::true_type) { auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, tbl.stack_index()); lua_pop(lua_state(), p.levels); return p; }
int lua_module_reload(lua_t* lua, const uuid_t uuid) { int ret = -1; lua_State* state = lua_state(lua); lua_modulemap_entry_t* entry = lua_module_registry_lookup(state, uuid); if (entry) { int stacksize = lua_gettop(state); lua_module_t module = lua_module_load_resource(uuid); if (module.size) { string_const_t uuidstr = string_from_uuid_static(uuid); log_debugf(HASH_LUA, STRING_CONST("Reloading module: %.*s"), STRING_FORMAT(uuidstr)); if (lua_module_upload(state, module.bytecode, module.size) == 0) { //Check if module loaded as a table if (lua_istable(state, -1)) { lua_pushlstring(state, STRING_CONST(BUILD_REGISTRY_LOADED_MODULES)); lua_gettable(state, LUA_REGISTRYINDEX); //Get and replace the old loaded module table lua_pushlightuserdata(state, entry); lua_gettable(state, -2); lua_replace(state, -2); //Get rid of loaded-modules registry table from stack if (lua_istable(state, -1)) { lua_pushlstring(state, STRING_CONST("__modulename")); lua_gettable(state, -2); size_t name_length = 0; const char* modulename = lua_isnil(state, -1) ? nullptr : luaL_checklstring(state, -1, &name_length); log_debugf(HASH_LUA, STRING_CONST("Replacing module table: %.*s (%.*s)"), STRING_FORMAT(uuidstr), (int)name_length, modulename); lua_pop(state, 1); //Get rid of name from stack //Clear previous loaded-modules table lua_pushnil(state); while (lua_next(state, -2) != 0) { lua_pop(state, 1); //Old value lua_pushnil(state); //Replace with nil lua_settable(state, -3); //Erase in previous loaded-modules table lua_pushnil(state); //Restart lua_next } //Copy new module table to previous loaded-modules table lua_pushnil(state); while (lua_next(state, -3) != 0) { //Lookup in new module table lua_pushvalue(state, -2); //Copy key lua_pushvalue(state, -2); //Copy value lua_settable(state, -5); //Set in previous loaded-modules table lua_pop(state, 1); //Pop value, leaving key for lua_next iteration } lua_pushlstring(state, STRING_CONST("__modulename")); lua_pushlstring(state, modulename, name_length); lua_settable(state, -3); } } ret = 0; } else { uuidstr = string_from_uuid_static(uuid); log_warnf(HASH_LUA, WARNING_RESOURCE, STRING_CONST("Unable to reload module '%.*s'"), STRING_FORMAT(uuidstr)); } } else { string_const_t uuidstr = string_from_uuid_static(uuid); log_warnf(HASH_LUA, WARNING_RESOURCE, STRING_CONST("Unable to load module '%.*s'"), STRING_FORMAT(uuidstr)); } lua_settop(state, stacksize); } else { string_const_t uuidstr = string_from_uuid_static(uuid); log_debugf(HASH_LUA, STRING_CONST("Reloading module ignored, not loaded: %.*s"), STRING_FORMAT(uuidstr)); } return ret; }
bool lua_module_is_loaded(lua_t* lua, const uuid_t uuid) { return lua_module_registry_lookup(lua_state(lua), uuid) != nullptr; }
void register_lua_timer() { lua_register(lua_state(), "create_timer", create_timer_lua); lua_register(lua_state(), "destroy_timer", destroy_timer_lua); lua_register(lua_state(), "start_timer", start_timer_lua); lua_register(lua_state(), "stop_timer", stop_timer_lua); }
void register_lua_skeleton() { lua_register(lua_state(), "skeleton_eventloop", skeleton_eventloop_lua); lua_register(lua_state(), "skeleton_init", skeleton_init_lua); lua_register(lua_state(), "skeleton_run", skeleton_run_lua); }
bool is_valid(std::false_type) { auto pp = stack::push_pop(tbl); auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state())); lua_pop(lua_state(), p.levels); return p; }