Index: ps/trunk/source/gui/CGUI.h =================================================================== --- ps/trunk/source/gui/CGUI.h +++ ps/trunk/source/gui/CGUI.h @@ -650,6 +650,12 @@ // Icons std::map m_Icons; + +public: + /** + * Stores all the IGUIObject which listen to a given event. + */ + std::map> m_EventIGUIObjects; }; #endif // INCLUDED_CGUI Index: ps/trunk/source/gui/CGUI.cpp =================================================================== --- ps/trunk/source/gui/CGUI.cpp +++ ps/trunk/source/gui/CGUI.cpp @@ -278,12 +278,24 @@ void CGUI::SendEventToAll(const CStr& eventName) { - m_BaseObject.RecurseObject(nullptr, &IGUIObject::ScriptEvent, eventName); + auto it = m_EventIGUIObjects.find(eventName); + if (it == m_EventIGUIObjects.end()) + return; + + std::set copy = it->second; + for (IGUIObject* pIGUIObject : copy) + pIGUIObject->ScriptEvent(eventName); } void CGUI::SendEventToAll(const CStr& eventName, const JS::HandleValueArray& paramData) { - m_BaseObject.RecurseObject(nullptr, &IGUIObject::ScriptEvent, eventName, paramData); + auto it = m_EventIGUIObjects.find(eventName); + if (it == m_EventIGUIObjects.end()) + return; + + std::set copy = it->second; + for (IGUIObject* pIGUIObject : copy) + pIGUIObject->ScriptEvent(eventName, paramData); } void CGUI::Draw() Index: ps/trunk/source/gui/ObjectBases/IGUIObject.cpp =================================================================== --- ps/trunk/source/gui/ObjectBases/IGUIObject.cpp +++ ps/trunk/source/gui/ObjectBases/IGUIObject.cpp @@ -334,6 +334,12 @@ JS_AddExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetJSRuntime(), Trace, this); m_ScriptHandlers[eventName] = JS::Heap(Function); + + auto it = m_pGUI.m_EventIGUIObjects.find(eventName); + if (it == m_pGUI.m_EventIGUIObjects.end()) + m_pGUI.m_EventIGUIObjects.emplace(eventName, std::set{this}); + else + it->second.insert(this); } void IGUIObject::UnsetScriptHandler(const CStr& eventName) @@ -347,6 +353,15 @@ if (m_ScriptHandlers.empty()) JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetJSRuntime(), Trace, this); + { + auto it = m_pGUI.m_EventIGUIObjects.find(eventName); + if (it != m_pGUI.m_EventIGUIObjects.end()) + { + it->second.erase(this); + if (!it->second.size()) + m_pGUI.m_EventIGUIObjects.erase(eventName); + } + } } InReaction IGUIObject::SendEvent(EGUIMessageType type, const CStr& eventName)