bool EventManager::QueueEvent(const IEventPtr& pEvent) { CB_ASSERT(m_ActiveQueue >= 0); CB_ASSERT(m_ActiveQueue < EVENTMANAGER_NUM_QUEUES); if (!pEvent) { CB_ERROR("Invalid Event"); return false; } CB_LOG("Events", "Attempting to queue event: " + std::string(pEvent->GetName())); // make sure there are listeners for this event auto findIt = m_EventListeners.find(pEvent->GetEventType()); if (findIt != m_EventListeners.end()) { m_Queues[m_ActiveQueue].push_back(pEvent); CB_LOG("Events", "Successfully queued event: " + std::string(pEvent->GetName())); return true; } else { CB_LOG("Events", "No listeners for event: " + std::string(pEvent->GetName())); return false; } }
bool EventManager::TriggerEvent(const IEventPtr& pEvent) const { CB_LOG("Events", "Attempting to trigger event " + std::string(pEvent->GetName())); bool processed = false; // iterate the map looking for this event type auto findIt = m_EventListeners.find(pEvent->GetEventType()); if (findIt != m_EventListeners.end()) { // iterate the listener list and send the event to each listener const EventListenerList& listeners = findIt->second; for (EventListenerList::const_iterator it = listeners.begin(); it != listeners.end(); ++it) { EventListenerDelegate listener = (*it); CB_LOG("Events", "Sending event " + std::string(pEvent->GetName()) + " to delegate listener."); listener(pEvent); processed = true; } } return processed; }
bool EventManager::VUpdate( unsigned long maxMs ) { unsigned long currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); unsigned long targetMs = ( maxMs == kINFINITE )? kINFINITE: currMs + maxMs; // swap active queues and clear the new queue after the swap int queueToProcess = m_ActiveQueue; m_ActiveQueue = (m_ActiveQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_EventQueues[m_ActiveQueue].clear(); std::string s( ( "EventLoop", "Processing Event Queue " + ToStr( queueToProcess ) + "; " + ToStr( ( unsigned long ) m_EventQueues[ queueToProcess ].size() ) + " events to process" ) ); \ Logger::Log( "EventLoop", s, NULL, NULL, 0 ); \ /*ENG_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_EventQueues[queueToProcess].size()) + " events to process");*/ // Process the queue while ( !m_EventQueues[queueToProcess].empty() ) { // pop the front of the queue IEventPtr pEvent = m_EventQueues[queueToProcess].front(); m_EventQueues[queueToProcess].pop_front(); ENG_LOG( "EventLoop", "\t\tProcessing Event " + std::string( pEvent->GetName() ) ); const EventType& eventType = pEvent->VGetEventType(); // find all the delegate functions registered for this event auto findIt = m_EventListeners.find(eventType); if (findIt != m_EventListeners.end()) { const EventListenerList& eventListeners = findIt->second; ENG_LOG("EventLoop", "\t\tFound " + ToStr((unsigned long)eventListeners.size()) + " delegates"); // call each listener for (auto it = eventListeners.begin(); it != eventListeners.end(); ++it) { EventListenerDelegate listener = (*it); ENG_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to delegate"); listener(pEvent); } } // check to see if time ran out currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); if ( targetMs != IEventManager::kINFINITE && currMs >= targetMs ) { ENG_LOG("EventLoop", "Aborting event processing; time ran out"); break; } } // If we couldn't process all of the events, push the remaining events to the new active queue. // Note: To preserve sequencing, go back-to-front, inserting them at the head of the active queue bool queueFlushed = ( m_EventQueues[queueToProcess].empty() ); if ( !queueFlushed ) { while (!m_EventQueues[queueToProcess].empty()) { IEventPtr pEvent = m_EventQueues[queueToProcess].back(); m_EventQueues[queueToProcess].pop_back(); m_EventQueues[m_ActiveQueue].push_front(pEvent); } } return queueFlushed; }
bool EventManager::Update(unsigned long maxMillis) { unsigned long currMS = GetTickCount(); // set the max milliseconds to process events unsigned long maxMS = (maxMillis == IEventManager::kINFINITE) ? IEventManager::kINFINITE : currMS + maxMillis; // handle events from other threads IEventPtr pRealtimeEvent; while (m_RealTimeEventQueue.try_pop(pRealtimeEvent)) { QueueEvent(pRealtimeEvent); currMS = GetTickCount(); if (maxMillis != IEventManager::kINFINITE) { if (currMS >= maxMS) { CB_ERROR("Too many real time processes hitting the event manager"); } } } // swap active queues and clear the new active after the swap int queueToProcess = m_ActiveQueue; m_ActiveQueue = (m_ActiveQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_Queues[m_ActiveQueue].clear(); CB_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_Queues[queueToProcess].size()) + " events to process"); // process the queue of events while (!m_Queues[queueToProcess].empty()) { // process the first event and pop it IEventPtr pEvent = m_Queues[queueToProcess].front(); m_Queues[queueToProcess].pop_front(); CB_LOG("EventLoop", "\t\tProcessing Event " + std::string(pEvent->GetName())); const EventType& eventType = pEvent->GetEventType(); // find all the listeners registered for this event in the map auto findIt = m_EventListeners.find(eventType); if (findIt != m_EventListeners.end()) { // get the list of listeners const EventListenerList& listeners = findIt->second; CB_LOG("Event Loop", "\t\tFound " + ToStr((unsigned long)listeners.size()) + " listeners"); // call each listener for this event type for (auto it = listeners.begin(); it != listeners.end(); ++it) { EventListenerDelegate listener = *it; CB_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to listener"); listener(pEvent); } } // check to see if time ran out currMS = GetTickCount(); if (maxMillis != IEventManager::kINFINITE && currMS >= maxMS) { CB_LOG("EventLoop", "Aborting event processing, time ran out"); break; } } bool queueFlushed = m_Queues[queueToProcess].empty(); // if we couldn't process all events, push remaining events on the new active queue if (!queueFlushed) { while (!m_Queues[queueToProcess].empty()) { IEventPtr pEvent = m_Queues[queueToProcess].back(); m_Queues[queueToProcess].pop_back(); m_Queues[m_ActiveQueue].push_front(pEvent); } } return queueFlushed; }