Theme::~Theme()
{
+ theme_menu.reset();
lua_close(L);
}
assert(lua_gettop(L) == 0);
}
-int Theme::set_theme_menu(lua_State *L)
+template <class T>
+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<unique_ptr<Theme::MenuEntry>> create_recursive_theme_menu(lua_State *L);
+
+unique_ptr<Theme::MenuEntry> create_theme_menu_entry(lua_State *L, int index)
+{
+ unique_ptr<Theme::MenuEntry> 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<unique_ptr<Theme::MenuEntry>> 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<unique_ptr<Theme::MenuEntry>> create_recursive_theme_menu(lua_State *L)
+{
+ vector<unique_ptr<Theme::MenuEntry>> 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<unique_ptr<MenuEntry>> 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);