// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// bool EventManager::VQueueEvent ( IEventDataPtr const & inEvent ) { assert ( m_activeQueue >= 0 ); assert ( m_activeQueue < kNumQueues ); if ( ! VValidateType( inEvent->VGetEventType() ) ) return false; EventListenerMap::const_iterator it = m_registry.find( inEvent->VGetEventType().getHashValue() ); if ( it == m_registry.end() ) { // if global listener is not active, then abort queue add EventListenerMap::const_iterator itWC = m_registry.find( 0 ); if ( itWC == m_registry.end() ) { // no listeners for this event, skipit return false; } } m_queues[m_activeQueue].push_back( inEvent ); return true; }
// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// EventListenerList EventManager::GetListenerList(EventType const &eventType) const { // invalid event type, so sad if ( ! VValidateType( eventType ) ) return EventListenerList(); EventListenerMap::const_iterator itListeners = m_registry.find( eventType.getHashValue() ); // no listerners currently for this event type, so sad if ( itListeners == m_registry.end() ) return EventListenerList(); EventListenerTable const & table = itListeners->second; // there was, but is not now, any listerners currently for // this event type, so sad if ( table.size() == 0 ) return EventListenerList(); EventListenerList result; result.reserve( table.size() ); for ( EventListenerTable::const_iterator it = table.begin(), end = table.end(); it != end ; it++ ) { result.push_back( *it ); } return result; }
// Remove a listener/type pairing from the internal tables // // Returns false if the pairing was not found. // bool cEventManager::VDelListener (EventListenerPtr const & inListener, cEventType const & inType ){ if ( ! VValidateType( inType ) ) return false; bool rc = false; // brute force method, iterate through all existing mapping // entries looking for the matching listener and remove it. for ( EventListenerMap::iterator it = m_registry.begin(), itEnd = m_registry.end(); it != itEnd; it++ ){ unsigned int const kEventId = it->first; EventListenerTable & table = it->second; for ( EventListenerTable::iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ){ if ( *it2 == inListener ){ // found match, remove from table, table.erase( it2 ); // update return code rc = true; // and early-quit the inner loop as addListener() // code ensures that each listener can only // appear in one event's processing list once. break; } } } return rc; }
// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// bool EventManager::VAddListener(EventListenerPtr const &inListener, EventType const & inType) { if ( ! VValidateType( inType ) ) return false; // check / update type list EventTypeSet::iterator evIt = m_typeList.find( inType ); // find listener map entry, create one if no table already // exists for this entry ... EventListenerMap::iterator elmIt = m_registry.find( inType.getHashValue() ); if ( elmIt == m_registry.end() ) { EventListenerMapIRes elmIRes = m_registry.insert( EventListenerMapEnt( inType.getHashValue(), EventListenerTable() ) ); // whoops, could not insert into map!?!? if ( elmIRes.second == false ) return false; // should not be possible, how did we insert and create // an empty table!?!?! if ( elmIRes.first == m_registry.end() ) return false; // store it so we can update the mapped list next ... elmIt = elmIRes.first; } // update the mapped list of listeners, walk the existing // list (if any entries) to prevent duplicate addition of // listeners. This is a bit more costly at registration time // but will prevent the hard-to-notice duplicate event // propogation sequences that would happen if double-entries // were allowed. // note: use reference to make following code more simple EventListenerTable & evlTable = (*elmIt).second; for ( EventListenerTable::iterator it = evlTable.begin(), itEnd = evlTable.end(); it != itEnd ; it++ ) { bool bListenerMatch = ( *it == inListener ); if ( bListenerMatch ) return false; } // okay, event type validated, event listener validated, // event listener not already in map, add it evlTable.push_back( inListener ); return true; }
bool Manager::VDelListener ( ListenerPtr const & inListener, TypeId const & inType ) { if ( ! VValidateType( inType ) ) return false; bool rc = false; for ( EventListenerMap::iterator it = m_registry.begin(), itEnd = m_registry.end(); it != itEnd; it++ ) { unsigned int const kEventId = it->first; EventListenerTable & table = it->second; for ( EventListenerTable::iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ) { if ( *it2 == inListener ) { table.erase( it2 ); rc = true; break; } } } return rc; }
bool Manager::VAddListener ( ListenerPtr const & inListener, TypeId const & inType ) { if ( ! VValidateType( inType ) ) return false; TypeIdSet::iterator evIt = m_typeList.find( inType ); EventListenerMap::iterator elmIt = m_registry.find( inType.Value() ); if ( elmIt == m_registry.end() ) { EventListenerMapIRes elmIRes = m_registry.insert( EventListenerMapEnt( inType.Value(), EventListenerTable() ) ); if ( elmIRes.second == false ) return false; if ( elmIRes.first == m_registry.end() ) return false; elmIt = elmIRes.first; } EventListenerTable & evlTable = (*elmIt).second; for ( EventListenerTable::iterator it = evlTable.begin(), itEnd = evlTable.end(); it != itEnd; it++ ) { bool bListenerMatch = ( *it == inListener ); if ( bListenerMatch ) return false; } evlTable.push_back( inListener ); return true; }
// // EventManager::VTrigger - Chapter 10, page 293 // // Fire off event - synchronous - do it NOW kind of thing - // analogous to Win32 SendMessage() API. // // returns true if the event was consumed, false if not. Note // that it is acceptable for all event listeners to act on an // event and not consume it, this return signature exists to // allow complete propogation of that shred of information from // the internals of this system to outside uesrs. // bool EventManager::VTrigger ( IEventData const & inEvent ) const { if ( ! VValidateType( inEvent.VGetEventType() ) ) return false; EventListenerMap::const_iterator itWC = m_registry.find( 0 ); if ( itWC != m_registry.end() ) { EventListenerTable const & table = itWC->second; bool processed = false; for ( EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ) { (*it2)->HandleEvent( inEvent ); } } EventListenerMap::const_iterator it = m_registry.find( inEvent.VGetEventType().getHashValue() ); if ( it == m_registry.end() ) return false; EventListenerTable const & table = it->second; bool processed = false; for ( EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ) { EventListenerPtr listener = *it2; if ( listener->HandleEvent( inEvent ) ) { // only set to true, if processing eats the messages processed = true; } } return processed; }
bool Manager::VTrigger ( IData const & inEvent ) const { if ( ! VValidateType( inEvent.GetTypeId() ) ) return false; EventListenerMap::const_iterator itWC = m_registry.find( 0 ); if ( itWC != m_registry.end() ) { EventListenerTable const & table = itWC->second; bool processed = false; for ( EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ) { (*it2)->HandleEvent( inEvent ); } } EventListenerMap::const_iterator it = m_registry.find( inEvent.GetTypeId().Value() ); if ( it == m_registry.end() ) return false; EventListenerTable const & table = it->second; bool processed = false; for ( EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++ ) { ListenerPtr listener = *it2; if ( listener->HandleEvent( inEvent ) ) { processed = true; } } return processed; }
// // EventManager::VAbortEvent - Chapter 10, page 295 // // Find the next-available instance of the named event type and // remove it from the processing queue. // // This may be done up to the point that it is actively being // processed ... e.g.: is safe to happen during event processing // itself. // // returns true if the event was found and removed, false // otherwise // bool EventManager::VAbortEvent ( EventType const & inType, bool allOfType ) { assert ( m_activeQueue >= 0 ); assert ( m_activeQueue < kNumQueues ); if ( ! VValidateType( inType ) ) return false; EventListenerMap::iterator it = m_registry.find( inType.getHashValue() ); if ( it == m_registry.end() ) return false; // no listeners for this event, skipit bool rc = false; // See a good discussion on this code here: // http://www.mcshaffry.com/GameCode/thread.php?threadid=517&sid= EventQueue &evtQueue = m_queues[m_activeQueue]; for ( EventQueue::iterator it = evtQueue.begin(), itEnd = evtQueue.end(); it != itEnd; it++ ) { if ( (*it)->VGetEventType() == inType ) { it = evtQueue.erase(it); rc = true; if ( !allOfType ) break; } else { ++it; } } return rc; }
bool Manager::VQueueEvent ( IDataPtr const & inEvent ) { assert ( m_activeQueue >= 0 ); assert ( m_activeQueue < kNumQueues ); if ( ! VValidateType( inEvent->GetTypeId() ) ) return false; EventListenerMap::const_iterator it = m_registry.find( inEvent->GetTypeId().Value() ); if ( it == m_registry.end() ) { EventListenerMap::const_iterator itWC = m_registry.find( 0 ); if ( itWC == m_registry.end() ) { return false; } } m_queues[m_activeQueue].push_back( inEvent ); return true; }
bool Manager::VAbortEvent ( TypeId const & inType, bool allOfType ) { assert ( m_activeQueue >= 0 ); assert ( m_activeQueue < kNumQueues ); if ( ! VValidateType( inType ) ) return false; EventListenerMap::iterator it = m_registry.find( inType.Value() ); if ( it == m_registry.end() ) return false; // no listeners for this event, skipit bool rc = false; EventQueue &evtQueue = m_queues[m_activeQueue]; for ( EventQueue::iterator it = evtQueue.begin(), itEnd = evtQueue.end(); it != itEnd; it++ ) { if ( (*it)->GetTypeId() == inType ) { it = evtQueue.erase(it); rc = true; if ( !allOfType ) break; } else { ++it; } } return rc; }