X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Ftheme.cpp;h=c881dc6891be2b1a32e90fb1b3fb8ec3b043f515;hb=f8da8feaff269b75480625e1384951c20c3a529d;hp=d31a4b948f42384c3d554d6a8069ab54b0e5b5d6;hpb=7a845519ce53c4efd5c5db9eb8fc815fdd69fe2f;p=nageru diff --git a/nageru/theme.cpp b/nageru/theme.cpp index d31a4b9..c881dc6 100644 --- a/nageru/theme.cpp +++ b/nageru/theme.cpp @@ -1266,6 +1266,7 @@ Theme::Theme(const string &filename, const vector &search_dirs, Resource Theme::~Theme() { + theme_menu.reset(); lua_close(L); } @@ -1597,25 +1598,73 @@ void Theme::channel_clicked(int preview_num) assert(lua_gettop(L) == 0); } -int Theme::set_theme_menu(lua_State *L) +template +void destroy(T &ref) +{ + ref.~T(); +} + +Theme::MenuEntry::~MenuEntry() { - for (const Theme::MenuEntry &entry : theme_menu) { - luaL_unref(L, LUA_REGISTRYINDEX, entry.lua_ref); + if (is_submenu) { + luaL_unref(entry.L, LUA_REGISTRYINDEX, entry.lua_ref); + } else { + destroy(submenu); } - theme_menu.clear(); +} - int num_elements = lua_gettop(L); - for (int i = 1; i <= num_elements; ++i) { - lua_rawgeti(L, i, 1); - const string text = checkstdstring(L, -1); - lua_pop(L, 1); +namespace { + +vector> create_recursive_theme_menu(lua_State *L); + +unique_ptr create_theme_menu_entry(lua_State *L, int index) +{ + unique_ptr entry; + + lua_rawgeti(L, index, 1); + const string text = checkstdstring(L, -1); + lua_pop(L, 1); - lua_rawgeti(L, i, 2); + lua_rawgeti(L, index, 2); + if (lua_istable(L, -1)) { + vector> submenu = create_recursive_theme_menu(L); + entry.reset(new Theme::MenuEntry{ text, move(submenu) }); + lua_pop(L, 1); + } else { luaL_checktype(L, -1, LUA_TFUNCTION); int ref = luaL_ref(L, LUA_REGISTRYINDEX); + entry.reset(new Theme::MenuEntry{ text, L, ref }); + } + return entry; +} + +vector> create_recursive_theme_menu(lua_State *L) +{ + vector> menu; + size_t num_elements = lua_objlen(L, -1); + for (size_t i = 1; i <= num_elements; ++i) { + lua_rawgeti(L, -1, i); + menu.emplace_back(create_theme_menu_entry(L, -1)); + lua_pop(L, 1); + } + return menu; +} - theme_menu.push_back(MenuEntry{ text, ref }); +} // namespace + +int Theme::set_theme_menu(lua_State *L) +{ + theme_menu.reset(); + + vector> root_menu; + int num_elements = lua_gettop(L); + for (int i = 1; i <= num_elements; ++i) { + root_menu.emplace_back(create_theme_menu_entry(L, i)); } + fprintf(stderr, "now creating a new one\n"); + theme_menu.reset(new MenuEntry("", move(root_menu))); + fprintf(stderr, "DONE reset\n"); + lua_pop(L, num_elements); assert(lua_gettop(L) == 0);