Skip to content

Commit

Permalink
Allow event listener to be ordered (YBmnRay76B) & updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Neko-Box-Coder committed May 21, 2023
1 parent 4836057 commit 1e5f580
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 21 deletions.
50 changes: 36 additions & 14 deletions Include/ssGUI/EventCallback.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ namespace ssGUI
private:
//Events
std::unordered_map<std::string, std::function<void(EventInfo)>> EventListeners; //See <AddEventListener>
std::vector<std::string> EventListenersOrder; //See <GetEventListenerOrder>
ssGUI::GUIObject* Container; //See <BindToObject>
ssGUI::ObjectsReferences CurrentObjectsReferences; //See <GetObjectReference> and <Internal_GetObjectsReferences>
ssGUI::Enums::EventType CurrentEventType; //See <GetEventType>
=================================================================
============================== C++ ==============================
BaseEventCallback::BaseEventCallback() : EventListeners(),
EventListenersOrder(),
Container(nullptr),
CurrentObjectsReferences(),
CurrentEventType(ssGUI::Enums::EventType::NONE)
Expand All @@ -57,6 +59,7 @@ namespace ssGUI
private:
//Events
std::unordered_map<std::string, std::function<void(EventInfo)>> EventListeners; //See <AddEventListener>
std::vector<std::string> EventListenersOrder; //See <GetEventListenerOrder>
ssGUI::GUIObject* Container; //See <BindToObject>
ssGUI::ObjectsReferences CurrentObjectsReferences; //See <GetObjectReference> and <Internal_GetObjectsReferences>
ssGUI::Enums::EventType CurrentEventType; //See <GetEventType>
Expand All @@ -73,55 +76,73 @@ namespace ssGUI

public:
//function: AddEventListener
//See <EventCallback::AddEventListener>
//Adds a callback listener function with key and adder for unique identification which triggers when <Notify> is called
virtual void AddEventListener(std::string key, ssGUI::GUIObject* adder, std::function<void(EventInfo)> callback);

//function: AddEventListener
//See <EventCallback::AddEventListener>
//See <AddEventListener> where adder is nullptr
virtual void AddEventListener(std::string key, std::function<void(EventInfo)> callback);

//function: IsEventListenerExist
//See <EventCallback::IsEventListenerExist>
//Checks if the callback listener function with unique identification key and adder exists
virtual bool IsEventListenerExist(std::string key, ssGUI::GUIObject* adder);

//function: IsEventListenerExist
//See <EventCallback::IsEventListenerExist>
//See <IsEventListenerExist> where adder is nullptr
virtual bool IsEventListenerExist(std::string key);

//function: RemoveEventListener
//See <EventCallback::RemoveEventListener>
//Removes the callback listener function with unique identification key and adder
virtual void RemoveEventListener(std::string key, ssGUI::GUIObject* adder);

//function: RemoveEventListener
//See <EventCallback::RemoveEventListener>
//See <RemoveEventListener> where adder is nullptr
virtual void RemoveEventListener(std::string key);

//function: SetEventListenerOrder
//Sets the order for the callback listener function with unique identification key and adder being called from <Notify>
virtual void SetEventListenerOrder(std::string key, ssGUI::GUIObject* adder, int order);

//function: SetEventListenerOrder
//See <SetEventListenerOrder> where adder is nullptr
virtual void SetEventListenerOrder(std::string key, int order);

//function: GetEventListenerOrder
//Gets the order for the callback listener function with unique identification key and adder being called from <Notify>.
//Returns -1 if such event callback function with unique identification key and adder is not found.
virtual int GetEventListenerOrder(std::string key, ssGUI::GUIObject* adder) const;

//function: GetEventListenerOrder
//See <GetEventListenerOrder> where adder is nullptr
virtual int GetEventListenerOrder(std::string key) const;

//function: ClearEventListeners
//See <EventCallback::ClearEventListeners>
//Removes all callback listener functions.
virtual void ClearEventListeners();

//function: GetEventListenerCount
//See <EventCallback::GetEventListenerCount>
//Gets the number of callback listener functions
virtual int GetEventListenerCount() const;

//function: Notify
//See <EventCallback::Notify>
//Calls all the callback listener functions added from <AddEventListener>
virtual void Notify(ssGUI::GUIObject* source, void* customInfo = nullptr);

//function: BindToObject
//See <EventCallback::BindToObject>
//Binds this event callback to a GUI Object
virtual void BindToObject(ssGUI::GUIObject* bindObj);

//function: AddObjectReference
//See <EventCallback::AddObjectReference>
//Adds a reference to a GUI Object that can be retrieved using the returned ssGUIObjectIndex
//inside the callback listener functions
virtual ssGUI::ssGUIObjectIndex AddObjectReference(ssGUI::GUIObject* obj);

//function: GetObjectReference
//See <EventCallback::GetObjectReference>
//Gets the GUI Object using the ssGUIObjectIndex obtained when calling <AddObjectReference>
virtual ssGUI::GUIObject* GetObjectReference(ssGUI::ssGUIObjectIndex index) const;

//function: RemoveObjectReference
//See <EventCallback::RemoveObjectReference>
//Removes the reference to the GUI Object using the ssGUIObjectIndex obtained when calling <AddObjectReference>
virtual void RemoveObjectReference(ssGUI::ssGUIObjectIndex index);

//function: Internal_GetObjectsReferences
Expand All @@ -137,7 +158,8 @@ namespace ssGUI
virtual ssGUI::Enums::EventType GetEventType() const;

//function: Clone
//See <EventCallback::Clone>
//This creates a copy of this event callback with the option of also copying
//the callback listener functions
virtual EventCallback* Clone(bool copyListeners);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,26 @@ int main()
!Callback->IsEventListenerExist("key", TestObj));
}

ssTEST("ClearEventListenersTest")
ssTEST("SetEventListenerOrderTest")
{
Callback->AddEventListener("key", [](ssGUI::EventInfo info){});
Callback->AddEventListener("key1", [](ssGUI::EventInfo info){});
Callback->AddEventListener("key2", [](ssGUI::EventInfo info){});
Callback->AddEventListener("key3", TestObj, [](ssGUI::EventInfo info){});

ssTEST_OUTPUT_ASSERT("Without adder", Callback->GetEventListenerOrder("key") == 0 &&
Callback->GetEventListenerOrder("key2") == 1);

Callback->AddEventListener("key", TestObj, [](ssGUI::EventInfo info){});
Callback->AddEventListener("key2", TestObj, [](ssGUI::EventInfo info){});

ssTEST_OUTPUT_ASSERT("With adder", Callback->GetEventListenerOrder("key", TestObj) == 2 &&
Callback->GetEventListenerOrder("key2", TestObj) == 3);
}

ssTEST_SKIP("GetEventListenerOrder (Tested in SetEventListenerOrderTest)"){}

ssTEST("ClearEventListenersTest")
{
ssTEST_OUTPUT_ASSERT(Callback->GetEventListenerCount() == 4);

Callback->ClearEventListeners();

Expand Down
107 changes: 103 additions & 4 deletions Src/ssGUI/EventCallback.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "ssGUI/EventCallback.hpp"

#include "ssGUI/HelperClasses/LogWithTagsAndLevel.hpp"
#include <cassert>

namespace ssGUI
{

EventCallback::EventCallback() : EventListeners(),
EventListenersOrder(),
Container(nullptr),
CurrentObjectsReferences(),
CurrentEventType(ssGUI::Enums::EventType::NONE)
Expand All @@ -21,10 +23,21 @@ namespace ssGUI
if(adder != nullptr)
{
int adderIndex = CurrentObjectsReferences.AddObjectReference(adder);
EventListeners[key+"-adder-"+std::to_string(adderIndex)] = callback;
std::string listenerKey = key+"-adder-"+std::to_string(adderIndex);
if(EventListeners.find(listenerKey) == EventListeners.end())
EventListenersOrder.push_back(listenerKey);

EventListeners[listenerKey] = callback;
}
else
{
if(EventListeners.find(key) == EventListeners.end())
EventListenersOrder.push_back(key);

EventListeners[key] = callback;
}

assert(EventListeners.size() == EventListenersOrder.size());
}

void EventCallback::AddEventListener(std::string key, std::function<void(EventInfo)> callback)
Expand Down Expand Up @@ -60,20 +73,104 @@ namespace ssGUI
if(adder != nullptr)
{
int adderIndex = CurrentObjectsReferences.GetObjectIndex(adder);
EventListeners.erase(key+"-adder-"+std::to_string(adderIndex));
std::string listenerKey = key+"-adder-"+std::to_string(adderIndex);
EventListeners.erase(listenerKey);

for(int i = 0; i < EventListenersOrder.size(); i++)
{
if(EventListenersOrder[i] == listenerKey)
{
EventListenersOrder.erase(EventListenersOrder.begin() + i);
break;
}
}
}
else
{
EventListeners.erase(key);

for(int i = 0; i < EventListenersOrder.size(); i++)
{
if(EventListenersOrder[i] == key)
{
EventListenersOrder.erase(EventListenersOrder.begin() + i);
break;
}
}
}
}

void EventCallback::RemoveEventListener(std::string key)
{
RemoveEventListener(key, nullptr);
}

void EventCallback::SetEventListenerOrder(std::string key, ssGUI::GUIObject* adder, int order)
{
if(order < 0 || order >= EventListenersOrder.size())
{
ssGUI_WARNING(0, "Invalid order index: "<<order);
return;
}

std::string listenerKey = key;

if(adder != nullptr)
{
int adderIndex = CurrentObjectsReferences.GetObjectIndex(adder);
listenerKey += "-adder-"+std::to_string(adderIndex);
}

for(int i = 0; i < EventListenersOrder.size(); i++)
{
if(EventListenersOrder[i] == listenerKey)
{
std::string temp = EventListenersOrder[i];
EventListenersOrder[i] = EventListenersOrder[order];
EventListenersOrder[order] = temp;
return;
}
}

ssGUI_WARNING(0, "Failed to find event listener with key: "<<key);
}

void EventCallback::SetEventListenerOrder(std::string key, int order)
{
SetEventListenerOrder(key, nullptr, order);
}

int EventCallback::GetEventListenerOrder(std::string key, ssGUI::GUIObject* adder) const
{
std::string listenerKey = key;

if(adder != nullptr)
{
int adderIndex = CurrentObjectsReferences.GetObjectIndex(adder);
listenerKey += "-adder-"+std::to_string(adderIndex);
}

for(int i = 0; i < EventListenersOrder.size(); i++)
{
if(EventListenersOrder[i] == listenerKey)
{
return i;
}
}

ssGUI_WARNING(0, "Failed to find event listener with key: "<<key);
return -1;
}

int EventCallback::GetEventListenerOrder(std::string key) const
{
return GetEventListenerOrder(key, nullptr);
}

void EventCallback::ClearEventListeners()
{
EventListeners.clear();
EventListenersOrder.clear();
}

int EventCallback::GetEventListenerCount() const
Expand All @@ -84,14 +181,16 @@ namespace ssGUI
void EventCallback::Notify(ssGUI::GUIObject* source, void* customInfo)
{
ssLOG_FUNC_ENTRY();
for(auto it = EventListeners.begin(); it != EventListeners.end(); it++)
assert(EventListeners.size() == EventListenersOrder.size());

for(int i = 0; i < EventListenersOrder.size(); i++)
{
ssGUI::EventInfo info;
info.EventSource = source;
info.Container = Container;
info.References = &CurrentObjectsReferences;
info.CustomInfo = customInfo;
it->second(info);
EventListeners.at(EventListenersOrder[i])(info);
}
ssLOG_FUNC_EXIT();
}
Expand Down

0 comments on commit 1e5f580

Please sign in to comment.