|
@@ -114,8 +114,9 @@ namespace BansheeEngine
|
|
|
for(auto& widget : widgetCopy)
|
|
for(auto& widget : widgetCopy)
|
|
|
widget.widget->destroy();
|
|
widget.widget->destroy();
|
|
|
|
|
|
|
|
- // Ensure everything queued get destroyed
|
|
|
|
|
- processDestroyQueue();
|
|
|
|
|
|
|
+ // Ensure everything queued get destroyed, loop until queue empties
|
|
|
|
|
+ while (processDestroyQueue())
|
|
|
|
|
+ { }
|
|
|
|
|
|
|
|
mOnPointerPressedConn.disconnect();
|
|
mOnPointerPressedConn.disconnect();
|
|
|
mOnPointerReleasedConn.disconnect();
|
|
mOnPointerReleasedConn.disconnect();
|
|
@@ -218,76 +219,79 @@ namespace BansheeEngine
|
|
|
|
|
|
|
|
PROFILE_CALL(updateMeshes(), "UpdateMeshes");
|
|
PROFILE_CALL(updateMeshes(), "UpdateMeshes");
|
|
|
|
|
|
|
|
- mNewElementsUnderPointer.clear();
|
|
|
|
|
- for(auto& elementInfo : mElementsUnderPointer)
|
|
|
|
|
|
|
+ // Destroy all queued elements (and loop in case any new ones get queued during destruction)
|
|
|
|
|
+ do
|
|
|
{
|
|
{
|
|
|
- if(!elementInfo.element->_isDestroyed())
|
|
|
|
|
- mNewElementsUnderPointer.push_back(elementInfo);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ mNewElementsUnderPointer.clear();
|
|
|
|
|
+ for (auto& elementInfo : mElementsUnderPointer)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!elementInfo.element->_isDestroyed())
|
|
|
|
|
+ mNewElementsUnderPointer.push_back(elementInfo);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- mElementsUnderPointer.swap(mNewElementsUnderPointer);
|
|
|
|
|
|
|
+ mElementsUnderPointer.swap(mNewElementsUnderPointer);
|
|
|
|
|
|
|
|
- mNewActiveElements.clear();
|
|
|
|
|
- for(auto& elementInfo : mActiveElements)
|
|
|
|
|
- {
|
|
|
|
|
- if(!elementInfo.element->_isDestroyed())
|
|
|
|
|
- mNewActiveElements.push_back(elementInfo);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ mNewActiveElements.clear();
|
|
|
|
|
+ for (auto& elementInfo : mActiveElements)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!elementInfo.element->_isDestroyed())
|
|
|
|
|
+ mNewActiveElements.push_back(elementInfo);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- mActiveElements.swap(mNewActiveElements);
|
|
|
|
|
|
|
+ mActiveElements.swap(mNewActiveElements);
|
|
|
|
|
|
|
|
- mNewElementsInFocus.clear();
|
|
|
|
|
- for(auto& elementInfo : mElementsInFocus)
|
|
|
|
|
- {
|
|
|
|
|
- if(!elementInfo.element->_isDestroyed())
|
|
|
|
|
- mNewElementsInFocus.push_back(elementInfo);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ mNewElementsInFocus.clear();
|
|
|
|
|
+ for (auto& elementInfo : mElementsInFocus)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!elementInfo.element->_isDestroyed())
|
|
|
|
|
+ mNewElementsInFocus.push_back(elementInfo);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- mElementsInFocus.swap(mNewElementsInFocus);
|
|
|
|
|
|
|
+ mElementsInFocus.swap(mNewElementsInFocus);
|
|
|
|
|
|
|
|
- for(auto& focusElementInfo : mForcedFocusElements)
|
|
|
|
|
- {
|
|
|
|
|
- if(focusElementInfo.element->_isDestroyed())
|
|
|
|
|
- continue;
|
|
|
|
|
-
|
|
|
|
|
- if(focusElementInfo.focus)
|
|
|
|
|
|
|
+ for (auto& focusElementInfo : mForcedFocusElements)
|
|
|
{
|
|
{
|
|
|
- auto iterFind = std::find_if(mElementsInFocus.begin(), mElementsInFocus.end(),
|
|
|
|
|
- [&](const ElementInfo& x) { return x.element == focusElementInfo.element; });
|
|
|
|
|
|
|
+ if (focusElementInfo.element->_isDestroyed())
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- if(iterFind == mElementsInFocus.end())
|
|
|
|
|
|
|
+ if (focusElementInfo.focus)
|
|
|
{
|
|
{
|
|
|
- mElementsInFocus.push_back(ElementInfo(focusElementInfo.element, focusElementInfo.element->_getParentWidget()));
|
|
|
|
|
|
|
+ auto iterFind = std::find_if(mElementsInFocus.begin(), mElementsInFocus.end(),
|
|
|
|
|
+ [&](const ElementInfo& x) { return x.element == focusElementInfo.element; });
|
|
|
|
|
+
|
|
|
|
|
+ if (iterFind == mElementsInFocus.end())
|
|
|
|
|
+ {
|
|
|
|
|
+ mElementsInFocus.push_back(ElementInfo(focusElementInfo.element, focusElementInfo.element->_getParentWidget()));
|
|
|
|
|
|
|
|
- mCommandEvent = GUICommandEvent();
|
|
|
|
|
- mCommandEvent.setType(GUICommandEventType::FocusGained);
|
|
|
|
|
|
|
+ mCommandEvent = GUICommandEvent();
|
|
|
|
|
+ mCommandEvent.setType(GUICommandEventType::FocusGained);
|
|
|
|
|
|
|
|
- sendCommandEvent(focusElementInfo.element->_getParentWidget(), focusElementInfo.element, mCommandEvent);
|
|
|
|
|
|
|
+ sendCommandEvent(focusElementInfo.element->_getParentWidget(), focusElementInfo.element, mCommandEvent);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- mNewElementsInFocus.clear();
|
|
|
|
|
- for(auto& elementInfo : mElementsInFocus)
|
|
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
- if(elementInfo.element == focusElementInfo.element)
|
|
|
|
|
|
|
+ mNewElementsInFocus.clear();
|
|
|
|
|
+ for (auto& elementInfo : mElementsInFocus)
|
|
|
{
|
|
{
|
|
|
- mCommandEvent = GUICommandEvent();
|
|
|
|
|
- mCommandEvent.setType(GUICommandEventType::FocusLost);
|
|
|
|
|
|
|
+ if (elementInfo.element == focusElementInfo.element)
|
|
|
|
|
+ {
|
|
|
|
|
+ mCommandEvent = GUICommandEvent();
|
|
|
|
|
+ mCommandEvent.setType(GUICommandEventType::FocusLost);
|
|
|
|
|
|
|
|
- sendCommandEvent(elementInfo.widget, elementInfo.element, mCommandEvent);
|
|
|
|
|
|
|
+ sendCommandEvent(elementInfo.widget, elementInfo.element, mCommandEvent);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ mNewElementsInFocus.push_back(elementInfo);
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- mNewElementsInFocus.push_back(elementInfo);
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- mElementsInFocus.swap(mNewElementsInFocus);
|
|
|
|
|
|
|
+ mElementsInFocus.swap(mNewElementsInFocus);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- mForcedFocusElements.clear();
|
|
|
|
|
|
|
+ mForcedFocusElements.clear();
|
|
|
|
|
|
|
|
- processDestroyQueue();
|
|
|
|
|
|
|
+ } while (processDestroyQueue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void GUIManager::render(ViewportPtr& target, DrawList& drawList) const
|
|
void GUIManager::render(ViewportPtr& target, DrawList& drawList) const
|
|
@@ -1355,21 +1359,18 @@ namespace BansheeEngine
|
|
|
mForcedFocusElements.push_back(efi);
|
|
mForcedFocusElements.push_back(efi);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- void GUIManager::processDestroyQueue()
|
|
|
|
|
|
|
+ bool GUIManager::processDestroyQueue()
|
|
|
{
|
|
{
|
|
|
- // Need two loops and a temporary since element destructors may themselves
|
|
|
|
|
- // queue other elements for destruction
|
|
|
|
|
- while(!mScheduledForDestruction.empty())
|
|
|
|
|
- {
|
|
|
|
|
- Stack<GUIElement*> toDestroy = mScheduledForDestruction;
|
|
|
|
|
- mScheduledForDestruction = Stack<GUIElement*>();
|
|
|
|
|
|
|
+ Stack<GUIElement*> toDestroy = mScheduledForDestruction;
|
|
|
|
|
+ mScheduledForDestruction = Stack<GUIElement*>();
|
|
|
|
|
|
|
|
- while(!toDestroy.empty())
|
|
|
|
|
- {
|
|
|
|
|
- bs_delete<PoolAlloc>(toDestroy.top());
|
|
|
|
|
- toDestroy.pop();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ while (!toDestroy.empty())
|
|
|
|
|
+ {
|
|
|
|
|
+ bs_delete<PoolAlloc>(toDestroy.top());
|
|
|
|
|
+ toDestroy.pop();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return !mScheduledForDestruction.empty();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void GUIManager::setInputBridge(const RenderTexture* renderTex, const GUIElement* element)
|
|
void GUIManager::setInputBridge(const RenderTexture* renderTex, const GUIElement* element)
|