diff --git a/Aeon/Core/Events.cpp b/Aeon/Core/Events.cpp index 479cd82..4a79c25 100644 --- a/Aeon/Core/Events.cpp +++ b/Aeon/Core/Events.cpp @@ -17,12 +17,34 @@ EventListener::~EventListener() } -void EventListener::RegisterAsSink( std::string system, int layer ) +void EventListener::PushThisAsSink( std::string system ) { - mListenerID = EventManager::GetInstance().RegisterSink( this, system ); + mListenerID = EventManager::GetInstance().RegisterSinkPush( this, system ); AEON_ASSERT( mListenerID != -1, "Cannot register event sink" ); } +void EventListener::PushAndStickThisAsSink( std::string system ) +{ + mListenerID = EventManager::GetInstance().RegisterSinkPushStick( this, system ); + AEON_ASSERT( mListenerID != -1, "Cannot register event sink" ); +} + +void EventListener::UnshiftThisAsSink( std::string system ) +{ + mListenerID = EventManager::GetInstance().RegisterSinkUnshift( this, system ); + AEON_ASSERT( mListenerID != -1, "Cannot register event sink" ); +} + +void EventListener::ShiftSinkLeft( std::string forSystem ) +{ + EventManager::GetInstance().MoveSinkLeft( this, forSystem ); +} + +void EventListener::ShiftSinkRight( std::string forSystem ) +{ + EventManager::GetInstance().MoveSinkRight( this, forSystem ); +} + void EventListener::DeRegisterAsSink( std::string system ) { @@ -90,7 +112,7 @@ int EventManager::RegisterSource( EventDispatcher* source, std::string system ) return id; } -int EventManager::RegisterSink( EventListener* sink, std::string system ) +int EventManager::RegisterSinkPush( EventListener* sink, std::string system ) { int id = mNextHeighest; mListeners[id] = sink; @@ -100,6 +122,7 @@ int EventManager::RegisterSink( EventListener* sink, std::string system ) { std::vector> v; mSinks.insert( { system, v } ); + return; } auto& sinkVector = mSinks[system]; @@ -109,6 +132,53 @@ int EventManager::RegisterSink( EventListener* sink, std::string system ) return id; } +int EventManager::RegisterSinkPushStick( EventListener* sink, std::string system ) +{ + int id = mNextHeighest; + mListeners[id] = sink; + + if ( !mStickySinks.count( system ) ) + { + std::vector> v; + mStickySinks.insert( { system, v } ); + return; + } + + auto& sinkVector = mStickySinks[system]; + sinkVector.push_back( { sink, id } ); + + mNextHeighest++; + return id; +} + +int EventManager::RegisterSinkUnshift( EventListener* sink, std::string system ) +{ + int id = mNextHeighest; + mListeners[id] = sink; + + if ( !mSinks.count( system ) ) + { + RegisterSinkPush( sink, system ); + return; + } + + auto& sinkVector = mSinks[system]; + sinkVector.insert( sinkVector.begin(), { sink, id } ); + + mNextHeighest++; + return id; +} + +void EventManager::MoveSinkLeft( EventListener* sink, std::string system ) +{ + +} + +void EventManager::MoveSinkRight( EventListener* sink, std::string system ) +{ + +} + void EventManager::RemoveSource( int dispatcherID, std::string system ) { @@ -122,8 +192,25 @@ void EventManager::RemoveSink( int listenerID, std::string system ) void EventManager::Dispatch( int dispatcherID, GenericEvent e ) { std::string targetSink = mSources[dispatcherID]; + auto stickySinks = mStickySinks[targetSink]; auto sinks = mSinks[targetSink]; + if ( !stickySinks.empty() ) + { + for ( auto& listenerPair : stickySinks ) + { + EventListener* listener = std::get<0>( listenerPair ); + bool handled = listener->EventRecieved( e ); + if ( handled ) e.Handled = handled; + + if ( e.Handled ) + { + // destroy event + return; + } + } + } + if ( sinks.empty() ) { return; @@ -138,7 +225,7 @@ void EventManager::Dispatch( int dispatcherID, GenericEvent e ) if ( e.Handled ) { // destroy event - break; + return; } } } diff --git a/Aeon/Core/Events.hpp b/Aeon/Core/Events.hpp index 1109722..1ea147a 100644 --- a/Aeon/Core/Events.hpp +++ b/Aeon/Core/Events.hpp @@ -82,13 +82,22 @@ public: EventListener(); virtual ~EventListener(); - void PushRegisterAsSink( std::string system ); - void PushStickyRegisterAsSink( std::string system ); - void EmplaceRegisterAsSink( std::string system ); + // Pushes sink to the top of the listener stack + // underneath the stuck listeners + void PushThisAsSink( std::string system ); + // Pushes sink to the top of the listener stack + // with all of the other "stuck" listeners + void PushAndStickThisAsSink( std::string system ); + // Pushes sink to the bottom of the listener stack + void UnshiftThisAsSink( std::string system ); + + void ShiftSinkLeft( std::string forSystem ); + void ShiftSinkRight( std::string forSystem ); void DeRegisterAsSink( std::string system ); - // return true = event handled + // return true = event handled and will not be further + // propogated virtual bool EventRecieved( GenericEvent& e ) = 0; private: @@ -108,7 +117,7 @@ public: void DeRegisterAsSource( std::string system ); void Dispatch( GenericEvent e ); - // no data needed + // no data needed, listeners act on the event happening void Dispatch( std::string type ); private: @@ -125,20 +134,28 @@ public: ~EventManager(); int RegisterSource( EventDispatcher* source, std::string system ); - int RegisterSink( EventListener* sink, std::string system ); + + int RegisterSinkPush( EventListener* sink, std::string system ); + int RegisterSinkPushStick( EventListener* sink, std::string system ); + int RegisterSinkUnshift( EventListener* sink, std::string system ); + + void MoveSinkLeft( EventListener* sink, std::string system ); + void MoveSinkRight( EventListener* sink, std::string system ); void RemoveSource( int dispatcherID, std::string system ); + void RemoveSink( int listenerID, std::string system ); void Dispatch( int dispatcherID, GenericEvent e ); private: - // indexed by listener ID + // indexed by listener ID for quick lookup std::map mListeners; - // indexed by dispatcher ID + // indexed by dispatcher ID for itteration std::map mSources; - // indexed by (sink) system ID + // indexed by (sink) system ID (string) // their position in the vector is their layer + std::map>> mStickySinks; std::map>> mSinks; int mNextHeighest = 0;