From 021fa9fa5ce103ae5843647fee3d5d1d7038d32f Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Tue, 11 Jun 2019 22:31:30 +0200 Subject: [PATCH] Move some Lua utility functions into a separate header file. --- nageru/lua_utils.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++ nageru/theme.cpp | 54 +------------------------------- 2 files changed, 78 insertions(+), 53 deletions(-) create mode 100644 nageru/lua_utils.h diff --git a/nageru/lua_utils.h b/nageru/lua_utils.h new file mode 100644 index 0000000..102d7c5 --- /dev/null +++ b/nageru/lua_utils.h @@ -0,0 +1,77 @@ +#ifndef _LUA_UTILS_H +#define _LUA_UTILS_H 1 + +#include +#include + +#include +#include + +class LuaRefWithDeleter { +public: + LuaRefWithDeleter(std::mutex *m, lua_State *L, int ref) : m(m), L(L), ref(ref) {} + ~LuaRefWithDeleter() { + std::lock_guard lock(*m); + luaL_unref(L, LUA_REGISTRYINDEX, ref); + } + int get() const { return ref; } + +private: + LuaRefWithDeleter(const LuaRefWithDeleter &) = delete; + + std::mutex *m; + lua_State *L; + int ref; +}; + +template +int wrap_lua_object(lua_State* L, const char *class_name, Args&&... args) +{ + // Construct the C++ object and put it on the stack. + void *mem = lua_newuserdata(L, sizeof(T)); + new(mem) T(std::forward(args)...); + + // Look up the metatable named , and set it on the new object. + luaL_getmetatable(L, class_name); + lua_setmetatable(L, -2); + + return 1; +} + +// Like wrap_lua_object, but the object is not owned by Lua; ie. it's not freed +// by Lua GC. This is typically the case for Effects, which are owned by EffectChain +// and expected to be destructed by it. The object will be of type T** instead of T* +// when exposed to Lua. +// +// Note that we currently leak if you allocate an Effect in this way and never call +// add_effect. We should see if there's a way to e.g. set __gc on it at construction time +// and then release that once add_effect() takes ownership. +template +int wrap_lua_object_nonowned(lua_State* L, const char *class_name, Args&&... args) +{ + // Construct the pointer ot the C++ object and put it on the stack. + T **obj = (T **)lua_newuserdata(L, sizeof(T *)); + *obj = new T(std::forward(args)...); + + // Look up the metatable named , and set it on the new object. + luaL_getmetatable(L, class_name); + lua_setmetatable(L, -2); + + return 1; +} + +template +int wrap_lua_existing_object_nonowned(lua_State* L, const char *class_name, T *ptr) +{ + // Construct the pointer ot the C++ object and put it on the stack. + T **obj = (T **)lua_newuserdata(L, sizeof(T *)); + *obj = ptr; + + // Look up the metatable named , and set it on the new object. + luaL_getmetatable(L, class_name); + lua_setmetatable(L, -2); + + return 1; +} + +#endif // !defined(_LUA_UTILS_H) diff --git a/nageru/theme.cpp b/nageru/theme.cpp index 780c7ce..71a59a2 100644 --- a/nageru/theme.cpp +++ b/nageru/theme.cpp @@ -37,6 +37,7 @@ #include "flags.h" #include "image_input.h" #include "input_state.h" +#include "lua_utils.h" #include "pbo_frame_allocator.h" class Mixer; @@ -115,59 +116,6 @@ InputStateInfo::InputStateInfo(const InputState &input_state) } } -class LuaRefWithDeleter { -public: - LuaRefWithDeleter(mutex *m, lua_State *L, int ref) : m(m), L(L), ref(ref) {} - ~LuaRefWithDeleter() { - lock_guard lock(*m); - luaL_unref(L, LUA_REGISTRYINDEX, ref); - } - int get() const { return ref; } - -private: - LuaRefWithDeleter(const LuaRefWithDeleter &) = delete; - - mutex *m; - lua_State *L; - int ref; -}; - -template -int wrap_lua_object(lua_State* L, const char *class_name, Args&&... args) -{ - // Construct the C++ object and put it on the stack. - void *mem = lua_newuserdata(L, sizeof(T)); - new(mem) T(forward(args)...); - - // Look up the metatable named , and set it on the new object. - luaL_getmetatable(L, class_name); - lua_setmetatable(L, -2); - - return 1; -} - -// Like wrap_lua_object, but the object is not owned by Lua; ie. it's not freed -// by Lua GC. This is typically the case for Effects, which are owned by EffectChain -// and expected to be destructed by it. The object will be of type T** instead of T* -// when exposed to Lua. -// -// Note that we currently leak if you allocate an Effect in this way and never call -// add_effect. We should see if there's a way to e.g. set __gc on it at construction time -// and then release that once add_effect() takes ownership. -template -int wrap_lua_object_nonowned(lua_State* L, const char *class_name, Args&&... args) -{ - // Construct the pointer ot the C++ object and put it on the stack. - T **obj = (T **)lua_newuserdata(L, sizeof(T *)); - *obj = new T(forward(args)...); - - // Look up the metatable named , and set it on the new object. - luaL_getmetatable(L, class_name); - lua_setmetatable(L, -2); - - return 1; -} - enum EffectType { WHITE_BALANCE_EFFECT, RESAMPLE_EFFECT, -- 2.39.2