Events function and propogate properly now

This commit is contained in:
Ben
2021-11-12 21:01:30 +00:00
parent 17a1913747
commit b1f79f4aa3
5 changed files with 199 additions and 35 deletions

View File

@@ -117,14 +117,6 @@ int EventManager::RegisterSinkPush( EventListener* sink, std::string system )
int id = mNextHeighest; int id = mNextHeighest;
mListeners[id] = sink; mListeners[id] = sink;
// if there is no sinks for the system, make sure there is one
if ( !mSinks.count( system ) )
{
std::vector<std::tuple<EventListener*, int>> v;
mSinks.insert( { system, v } );
return -1;
}
auto& sinkVector = mSinks[system]; auto& sinkVector = mSinks[system];
sinkVector.push_back( { sink, id } ); sinkVector.push_back( { sink, id } );
@@ -137,13 +129,6 @@ int EventManager::RegisterSinkPushStick( EventListener* sink, std::string system
int id = mNextHeighest; int id = mNextHeighest;
mListeners[id] = sink; mListeners[id] = sink;
if ( !mStickySinks.count( system ) )
{
std::vector<std::tuple<EventListener*, int>> v;
mStickySinks.insert( { system, v } );
return -1;
}
auto& sinkVector = mStickySinks[system]; auto& sinkVector = mStickySinks[system];
sinkVector.push_back( { sink, id } ); sinkVector.push_back( { sink, id } );
@@ -188,6 +173,35 @@ void EventManager::RemoveSink( int listenerID, std::string system )
} }
// it is important to reverse the lists so that the dispatching is done correctly
// this is more efficiently done at insert... lol
template <typename C>
struct reverse_wrapper {
C& c_;
reverse_wrapper(C& c) : c_(c) {}
typename C::reverse_iterator begin() { return c_.rbegin(); }
typename C::reverse_iterator end() { return c_.rend(); }
};
template <typename C, size_t N>
struct reverse_wrapper< C[N] > {
C(&c_)[N];
reverse_wrapper(C(&c)[N]) : c_(c) {}
typename std::reverse_iterator<const C*> begin() { return std::rbegin(c_); }
typename std::reverse_iterator<const C*> end() { return std::rend(c_); }
};
template <typename C>
reverse_wrapper<C> r_wrap(C& c) {
return reverse_wrapper<C>(c);
}
void EventManager::Dispatch( int dispatcherID, GenericEvent e ) void EventManager::Dispatch( int dispatcherID, GenericEvent e )
{ {
std::string targetSink = mSources[dispatcherID]; std::string targetSink = mSources[dispatcherID];
@@ -196,7 +210,7 @@ void EventManager::Dispatch( int dispatcherID, GenericEvent e )
if ( !stickySinks.empty() ) if ( !stickySinks.empty() )
{ {
for ( auto& listenerPair : stickySinks ) for ( auto& listenerPair : r_wrap(stickySinks))
{ {
EventListener* listener = std::get<0>( listenerPair ); EventListener* listener = std::get<0>( listenerPair );
bool handled = listener->EventRecieved( e ); bool handled = listener->EventRecieved( e );
@@ -210,21 +224,37 @@ void EventManager::Dispatch( int dispatcherID, GenericEvent e )
} }
} }
if ( sinks.empty() ) if (!sinks.empty())
{ {
return; for (auto& listenerPair : r_wrap(sinks))
}
for ( auto& listenerPair : sinks )
{
EventListener* listener = std::get<0>( listenerPair );
bool handled = listener->EventRecieved(e);
if ( handled ) e.Handled = handled;
if ( e.Handled )
{ {
// destroy event EventListener* listener = std::get<0>(listenerPair);
return; bool handled = listener->EventRecieved(e);
if (handled) e.Handled = handled;
if (e.Handled)
{
// destroy event
return;
}
} }
} }
}
void EventManager::DebugPrint()
{
std::cout << "----- BEGIN EVENTS DEBUG -----" << std::endl;
for (auto const& [dispatcher, targetSink] : mSources)
{
auto stickySinks = mStickySinks[targetSink];
auto sinks = mSinks[targetSink];
int sourceCount = 0;
for (auto const& [id, source] : mSources)
if (source == targetSink) sourceCount++;
std::cout << targetSink << " has " << stickySinks.size() << " sticky and " << sinks.size() << " sink(s) and is being dispatched from " << sourceCount << " different source(s)" << std::endl;
}
std::cout << "----- END EVENTS DEBUG -----" << std::endl;
} }

View File

@@ -147,6 +147,9 @@ public:
void RemoveSink( int listenerID, std::string system ); void RemoveSink( int listenerID, std::string system );
void Dispatch( int dispatcherID, GenericEvent e ); void Dispatch( int dispatcherID, GenericEvent e );
void DebugPrint();
private: private:
// indexed by listener ID for quick lookup // indexed by listener ID for quick lookup

View File

@@ -10,7 +10,7 @@ For milestones see the project notion page [here](https://www.notion.so/Aeon-e34
## Status ## Status
### 2021-11-12 - Benjamin Kyd ### 2021-11-12 - Ben
* Development restarts * Development restarts
* Issue with SDL2 Resolved as well as the broken shit in d69b6a is fixed * Issue with SDL2 Resolved as well as the broken shit in d69b6a is fixed

View File

@@ -6,10 +6,14 @@
#include <Aeon/Aeon.hpp> #include <Aeon/Aeon.hpp>
#include <Aeon/Core/Events.hpp> #include <Aeon/Core/Events.hpp>
class Level : public Aeon::Core::GameLayer class BottomestLevel : public Aeon::Core::GameLayer
{ {
public: public:
Level() { } BottomestLevel()
{
UnshiftThisAsSink("GAME_LOL");
Aeon::Core::EventManager::GetInstance().DebugPrint();
}
void Attach() override void Attach() override
{ {
@@ -26,9 +30,9 @@ public:
} }
bool EventRecieved( Aeon::Core::GenericEvent& e ) override bool EventRecieved(Aeon::Core::GenericEvent& e) override
{ {
std::cout << "FROM BOTTOMESTLEVEL " << e.System << " " << e.Type << " " << e.Data << std::endl;
return false; return false;
} }
@@ -38,10 +42,92 @@ public:
} }
}; };
class BottomLevel : public Aeon::Core::GameLayer
{
public:
BottomLevel()
{
PushThisAsSink("GAME_LOL");
Aeon::Core::EventManager::GetInstance().DebugPrint();
}
void Attach() override
{
}
void FrameTick() override
{
}
void TimeTick() override
{
}
bool EventRecieved(Aeon::Core::GenericEvent& e) override
{
std::cout << "FROM BOTTOMLEVEL " << e.System << " " << e.Type << " " << e.Data << std::endl;
return false;
}
void Detach() override
{
}
};
class Level : public Aeon::Core::GameLayer
{
public:
Level()
{
mEventDispatcher.RegisterAsSource("GAME_LOL");
PushThisAsSink("GAME_LOL");
Aeon::Core::EventManager::GetInstance().DebugPrint();
}
void Attach() override
{
}
void FrameTick() override
{
mEventDispatcher.Dispatch("Lmao gottem");
}
void TimeTick() override
{
}
bool EventRecieved( Aeon::Core::GenericEvent& e ) override
{
std::cout << "FROM LEVEL " << e.System << " " << e.Type << " " << e.Data << std::endl;
return false;
}
void Detach() override
{
}
Aeon::Core::EventDispatcher mEventDispatcher;
};
class TopLevel : public Aeon::Core::GameLayer class TopLevel : public Aeon::Core::GameLayer
{ {
public: public:
TopLevel() { } TopLevel()
{
PushAndStickThisAsSink("GAME_LOL");
Aeon::Core::EventManager::GetInstance().DebugPrint();
}
void Attach() override void Attach() override
{ {
@@ -60,7 +146,43 @@ public:
bool EventRecieved( Aeon::Core::GenericEvent& e ) override bool EventRecieved( Aeon::Core::GenericEvent& e ) override
{ {
std::cout << "FROM TOPLEVEL " << e.System << " " << e.Type << " " << e.Data << std::endl;
return false;
}
void Detach() override
{
}
};
class ToperLevel : public Aeon::Core::GameLayer
{
public:
ToperLevel()
{
PushAndStickThisAsSink("GAME_LOL");
Aeon::Core::EventManager::GetInstance().DebugPrint();
}
void Attach() override
{
}
void FrameTick() override
{
}
void TimeTick() override
{
}
bool EventRecieved(Aeon::Core::GenericEvent& e) override
{
std::cout << "FROM TOPERLEVEL " << e.System << " " << e.Type << " " << e.Data << std::endl;
return false; return false;
} }
@@ -78,10 +200,16 @@ public:
ExampleGame() ExampleGame()
: App( { "Example" }, { "Game with AEON!" } ) : App( { "Example" }, { "Game with AEON!" } )
{ {
BottomestLevel* bottomestLevel = new BottomestLevel;
BottomLevel* bottomLevel = new BottomLevel;
Level* level = new Level; Level* level = new Level;
TopLevel* topLevel = new TopLevel; TopLevel* topLevel = new TopLevel;
ToperLevel* toperLevel = new ToperLevel;
PushLayer( (Aeon::Core::GameLayer*)bottomestLevel );
PushLayer( (Aeon::Core::GameLayer*)bottomLevel );
PushLayer( (Aeon::Core::GameLayer*)level ); PushLayer( (Aeon::Core::GameLayer*)level );
PushLayer( (Aeon::Core::GameLayer*)topLevel ); PushLayer( (Aeon::Core::GameLayer*)topLevel );
PushLayer( (Aeon::Core::GameLayer*)toperLevel);
Run(); Run();
delete level; delete level;
} }

View File

@@ -0,0 +1,3 @@
# Events
The event system of Aeon is a simple source/sink model similar to the subscriber/publisher model. Anything can register as a source and