Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism
authorKahrl <kahrl@gmx.net>
Fri, 24 Oct 2014 14:22:05 +0000 (16:22 +0200)
committerKahrl <kahrl@gmx.net>
Fri, 24 Oct 2014 19:14:48 +0000 (21:14 +0200)
src/game.cpp
src/guiEngine.cpp
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h
src/modalMenu.h

index 2f228b0eda64e65d81f65da5a21e655f4fa33349..2e4485e36cd8416fdc1a9720699373d0c24d726e 100644 (file)
@@ -944,9 +944,16 @@ static inline void create_formspec_menu(GUIFormSpecMenu** cur_formspec,
 
        if (*cur_formspec == 0) {
                *cur_formspec = new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr,
-                               invmgr, gamedef, tsrc, fs_src, txt_dest, cur_formspec, client);
+                               invmgr, gamedef, tsrc, fs_src, txt_dest, client);
                (*cur_formspec)->doPause = false;
-               (*cur_formspec)->drop();
+
+               /*
+                       Caution: do not call (*cur_formspec)->drop() here --
+                       the reference might outlive the menu, so we will
+                       periodically check if *cur_formspec is the only
+                       remaining reference (i.e. the menu was removed)
+                       and delete it in that case.
+               */
        }
        else {
                (*cur_formspec)->setFormSource(fs_src);
@@ -3417,10 +3424,16 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                }
 
                /*
-                       make sure menu is on top
+                       1. Delete formspec menu reference if menu was removed
+                       2. Else, make sure formspec menu is on top
                */
-               if ((!noMenuActive()) && (current_formspec)) {
+               if (current_formspec) {
+                       if (current_formspec->getReferenceCount() == 1) {
+                               current_formspec->drop();
+                               current_formspec = NULL;
+                       } else if (!noMenuActive()) {
                                guiroot->bringToFront(current_formspec);
+                       }
                }
 
                /*
@@ -3509,6 +3522,11 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                g_menumgr.m_stack.front()->setVisible(false);
                g_menumgr.deletingMenu(g_menumgr.m_stack.front());
        }
+       if (current_formspec) {
+               current_formspec->drop();
+               current_formspec = NULL;
+       }
+
        /*
                Draw a "shutting down" screen, which will be shown while the map
                generator and other stuff quits
index 41a522cafffa780526777c12ca48f0561886d1aa..e53b52b01ab9dd57cc72636a814a1c4fffd2584f 100644 (file)
@@ -190,7 +190,7 @@ GUIEngine::GUIEngine(       irr::IrrlichtDevice* dev,
                        m_texture_source,
                        m_formspecgui,
                        m_buttonhandler,
-                       NULL, NULL);
+                       NULL);
 
        m_menu->allowClose(false);
        m_menu->lockSize(true,v2u32(800,600));
@@ -220,8 +220,7 @@ GUIEngine::GUIEngine(       irr::IrrlichtDevice* dev,
        }
 
        m_menu->quitMenu();
-       m_menu->remove();
-       delete m_menu;
+       m_menu->drop();
        m_menu = NULL;
 }
 
index a502c9682790e2847bb0826d47da5bd09ff5e471..e82ea829c34f8ca3c53a76bc2a44f0adf5841aba 100644 (file)
@@ -68,12 +68,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /*
        GUIFormSpecMenu
 */
-
 GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
                gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
                InventoryManager *invmgr, IGameDef *gamedef,
                ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst,
-               GUIFormSpecMenu** ext_ptr, Client* client) :
+               Client* client) :
        GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr),
        m_device(dev),
        m_invmgr(invmgr),
@@ -89,7 +88,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
        m_lock(false),
        m_form_src(fsrc),
        m_text_dst(tdst),
-       m_ext_ptr(ext_ptr),
        m_font(dev->getGUIEnvironment()->getSkin()->getFont()),
        m_formspec_version(0)
 #ifdef __ANDROID__
@@ -130,11 +128,6 @@ GUIFormSpecMenu::~GUIFormSpecMenu()
        if (m_text_dst != NULL) {
                delete m_text_dst;
        }
-
-       if (m_ext_ptr != NULL) {
-               assert(*m_ext_ptr == this);
-               *m_ext_ptr = NULL;
-       }
 }
 
 void GUIFormSpecMenu::removeChildren()
index 40be59b4660419532155fdcda50fc451358fe792..d38e9ec468e5973a9d57c1f521efd7ce0318e49e 100644 (file)
@@ -210,7 +210,6 @@ public:
                        ISimpleTextureSource *tsrc,
                        IFormSource* fs_src,
                        TextDest* txt_dst,
-                       GUIFormSpecMenu** ext_ptr,
                        Client* client
                        );
 
@@ -346,7 +345,6 @@ protected:
 private:
        IFormSource      *m_form_src;
        TextDest         *m_text_dst;
-       GUIFormSpecMenu **m_ext_ptr;
        gui::IGUIFont    *m_font;
        unsigned int      m_formspec_version;
 
index 2c512d3ca08eb4fc921272a46f65ca5e00f97800..72ecedcb9ca7e32e286548457b2cfff6734cc872 100644 (file)
@@ -96,6 +96,8 @@ public:
 
                WARNING: THIS DEALLOCATES THE MENU FROM MEMORY. Return
                immediately if you call this from the menu itself.
+
+               (More precisely, this decrements the reference count.)
        */
        void quitMenu()
        {