#define SOL_ALL_SAFETIES_ON 1 #include // Something that can't be collided with static const auto& script_key = "GlobalResource.MySpecialIdentifier123"; struct GlobalResource { int value = 2; }; template bool sol_lua_check(sol::types, lua_State* L, int /*index*/, Handler&& handler, sol::stack::record& tracking) { // not actually taking anything off the stack tracking.use(0); // get the field from global storage sol::stack::get_field(L, script_key); // verify type sol::type t = static_cast(lua_type(L, -1)); lua_pop(L, 1); if (t != sol::type::lightuserdata) { handler(L, 0, sol::type::lightuserdata, t, "global resource is not present as a light " "userdata"); return false; } return true; } GlobalResource* sol_lua_get(sol::types, lua_State* L, int /*index*/, sol::stack::record& tracking) { // retrieve the (light) userdata for this type // not actually pulling anything off the stack tracking.use(0); sol::stack::get_field(L, script_key); GlobalResource* ls = static_cast(lua_touserdata(L, -1)); // clean up stack value returned by `get_field` lua_pop(L, 1); return ls; } int sol_lua_push(sol::types, lua_State* L, GlobalResource* ls) { // push light userdata return sol::stack::push(L, static_cast(ls)); } int main() { sol::state lua; lua.open_libraries(sol::lib::base); GlobalResource instance; // get GlobalResource lua.set_function("f", [](GlobalResource* l, int value) { return l->value + value; }); lua.set(script_key, &instance); // note only 1 argument, // despite f having 2 arguments to recieve lua.script("assert(f(1) == 3)"); return 0; }