diff --git a/changes.txt b/changes.txt index 02bdce47..8a507bb9 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,6 @@ -------------------------- Changes in 1.9 (not yet released) +- Add IGUIEnvironment::addToDeletionQueue to allow save removal of gui elements while iterating over them (like the same named function in ISceneManager). - IGUIEnvironment::drawAll has now a parameter to allow disabling automatic resize to screensize. Makes it easier to use partial screens with full alignment support. - No longer try to set WM_QUIT when using an external Window on Win32. Thx @Marko Mahnic for the patch (https://sourceforge.net/p/irrlicht/bugs/449) diff --git a/include/IGUIEnvironment.h b/include/IGUIEnvironment.h index b670d969..4bd3db87 100644 --- a/include/IGUIEnvironment.h +++ b/include/IGUIEnvironment.h @@ -623,10 +623,10 @@ public: virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)=0; //! writes an element - virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) =0; + virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* element) =0; //! reads an element - virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node) =0; + virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* element) =0; //! Find the next element which would be selected when pressing the tab-key /** If you set the focus for the result you can manually force focus-changes like they @@ -646,6 +646,17 @@ public: //! Get the way the gui does handle focus changes /** \returns A bitmask which is a combination of ::EFOCUS_FLAG flags.*/ virtual u32 getFocusBehavior() const = 0; + + //! Adds a IGUIElement to deletion queue. + /** Queued elements will be removed at the end of each drawAll call. + Or latest in the destructor of the GUIEnvironment. + This can be used to allow an element removing itself safely in a function + iterating over gui elements, like an overloaded IGUIElement::draw or + IGUIElement::OnPostRender function. + Note that in general just calling IGUIElement::remove() is enough. + Unless you create your own GUI elements removing themselves you won't need it. + \param element: Element to remove */ + virtual void addToDeletionQueue(IGUIElement* element) = 0; }; diff --git a/source/Irrlicht/CGUIEnvironment.cpp b/source/Irrlicht/CGUIEnvironment.cpp index 0f0dc18b..e970d640 100644 --- a/source/Irrlicht/CGUIEnvironment.cpp +++ b/source/Irrlicht/CGUIEnvironment.cpp @@ -101,6 +101,8 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive //! destructor CGUIEnvironment::~CGUIEnvironment() { + clearDeletionQueue(); + if ( HoveredNoSubelement && HoveredNoSubelement != this ) { HoveredNoSubelement->drop(); @@ -212,6 +214,8 @@ void CGUIEnvironment::drawAll(bool useScreenSize) draw(); OnPostRender ( os::Timer::getTime () ); + + clearDeletionQueue(); } @@ -470,6 +474,28 @@ void CGUIEnvironment::OnPostRender( u32 time ) IGUIElement::OnPostRender ( time ); } +void CGUIEnvironment::addToDeletionQueue(IGUIElement* element) +{ + if (!element) + return; + + element->grab(); + DeletionQueue.push_back(element); +} + +void CGUIEnvironment::clearDeletionQueue() +{ + if (DeletionQueue.empty()) + return; + + for (u32 i=0; iremove(); + DeletionQueue[i]->drop(); + } + + DeletionQueue.clear(); +} // void CGUIEnvironment::updateHoveredElement(core::position2d mousePos) diff --git a/source/Irrlicht/CGUIEnvironment.h b/source/Irrlicht/CGUIEnvironment.h index f8b03230..e87e236f 100644 --- a/source/Irrlicht/CGUIEnvironment.h +++ b/source/Irrlicht/CGUIEnvironment.h @@ -269,8 +269,14 @@ public: //! Get the way the gui does handle focus changes virtual u32 getFocusBehavior() const _IRR_OVERRIDE_; + //! Adds a IGUIElement to deletion queue. + virtual void addToDeletionQueue(IGUIElement* element) _IRR_OVERRIDE_; + private: + //! clears the deletion queue + void clearDeletionQueue(); + void updateHoveredElement(core::position2d mousePos); void loadBuiltInFont(); @@ -322,6 +328,8 @@ private: IEventReceiver* UserReceiver; IOSOperator* Operator; u32 FocusFlags; + core::array DeletionQueue; + static const io::path DefaultFontName; };