diff --git a/binding/binding.h b/binding/binding.h index c4c81ef1..c9864ac5 100644 --- a/binding/binding.h +++ b/binding/binding.h @@ -232,6 +232,25 @@ namespace bee::lua { return *o; } + template + T& newudata(lua_State* L, const char* name, void (*init_metatable)(lua_State*), Args&&... args) { + int nupvalue = 0; + if constexpr (udata_has_nupvalue::value) { + nupvalue = udata::nupvalue; + } + T* o = static_cast(lua_newuserdatauv(L, sizeof(T), nupvalue)); + new (o) T(std::forward(args)...); + if (luaL_newmetatable(L, name)) { + if constexpr (!std::is_trivially_destructible::value) { + lua_pushcfunction(L, destroyudata); + lua_setfield(L, -2, "__gc"); + } + init_metatable(L); + } + lua_setmetatable(L, -2); + return *o; + } + template T& checkudata(lua_State* L, int arg) { if constexpr (udata_has_name::value) { diff --git a/binding/lua_socket.cpp b/binding/lua_socket.cpp index b32f544d..cd90f1ca 100644 --- a/binding/lua_socket.cpp +++ b/binding/lua_socket.cpp @@ -12,13 +12,6 @@ #include #include -namespace bee::lua { - template <> - struct udata { - static inline auto name = "bee::net::fd"; - }; -} - namespace bee::lua_socket { static int push_neterror(lua_State* L, std::string_view msg) { auto error = make_neterror(msg); @@ -369,10 +362,10 @@ namespace bee::lua_socket { luaL_setfuncs(L, mt, 0); } static void pushfd(lua_State* L, net::fd_t fd) { - lua::newudata(L, metatable, fd); + lua::newudata(L, "bee::net::fd", metatable, fd); } static void pushfd_no_ownership(lua_State* L, net::fd_t fd) { - lua::newudata(L, metatable_no_ownership, fd); + lua::newudata(L, "bee::net::fd (no ownership)", metatable_no_ownership, fd); } static int pair(lua_State* L) { net::fd_t sv[2];