Index: source/gui/CGUI.h =================================================================== --- source/gui/CGUI.h +++ source/gui/CGUI.h @@ -649,6 +649,11 @@ // Icons std::map m_Icons; + +public: + + // Stores all the IGUIObject that have a given event + std::map> m_EventIGUIObjects; }; #endif // INCLUDED_CGUI Index: source/gui/CGUI.cpp =================================================================== --- source/gui/CGUI.cpp +++ source/gui/CGUI.cpp @@ -274,12 +274,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: source/gui/ObjectBases/IGUIObject.cpp =================================================================== --- source/gui/ObjectBases/IGUIObject.cpp +++ source/gui/ObjectBases/IGUIObject.cpp @@ -336,6 +336,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) @@ -344,11 +350,20 @@ if (it == m_ScriptHandlers.end()) return; - m_ScriptHandlers.erase(it); 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)