//--------------------------------------------------------------------------------------------------------------------- // EventManager::VQueueEvent //--------------------------------------------------------------------------------------------------------------------- bool EventManager::VQueueEvent(const IEventDataPtr& pEvent) { GCC_ASSERT(m_activeQueue >= 0); GCC_ASSERT(m_activeQueue < EVENTMANAGER_NUM_QUEUES); // make sure the event is valid if (!pEvent) { GCC_ERROR("Invalid event in VQueueEvent()"); return false; } GCC_LOG("Events", "Attempting to queue event: " + std::string(pEvent->GetName())); auto findIt = m_eventListeners.find(pEvent->VGetEventType()); if (findIt != m_eventListeners.end()) { m_queues[m_activeQueue].push_back(pEvent); GCC_LOG("Events", "Successfully queued event: " + std::string(pEvent->GetName())); return true; } else { GCC_LOG("Events", "Skipping event since there are no delegates registered to receive it: " + std::string(pEvent->GetName())); return false; } }
void RemoteNetworkView::ForwardEvent(IEventDataPtr pEventData) { std::string httpinmsg; if (!pEventData) { GCC_ERROR("Event Invalid"); return; } int socketId = pEventData->VGetSocketId(); std::ostrstream out; pEventData->VSerialize(out); out << std::ends; IPacket *packetBack = NULL; if (!strncmp("HTTP", &out.rdbuf()->str()[0], 4)) { packetBack = GCC_NEW HTTPPacket(out.rdbuf()->str()); } else { //TODO create binary packet } std::shared_ptr<IPacket> ipBack(packetBack); printf("RemoteNetworkView Forward Event socket:%d %s\n", socketId, pEventData->GetName()); g_pSocketManager->Send(socketId, ipBack); if (!strncmp("HTTP", &out.rdbuf()->str()[0], 4)) { IEventDataPtr pCloseSocketHttpEvent(CREATE_EVENT(EventData_CloseSocketHTTP::sk_EventType)); char* id = new char[100]; sprintf_s(id, 100, "%d", socketId); httpinmsg.append(id); std::istrstream in(httpinmsg.c_str(), httpinmsg.size()); pCloseSocketHttpEvent->VDeserialize(in); IEventManager::Get()->VQueueEvent(pCloseSocketHttpEvent); } }
//--------------------------------------------------------------------------------------------------------------------- // EventManager::VTrigger //--------------------------------------------------------------------------------------------------------------------- bool EventManager::VTriggerEvent(const IEventDataPtr& pEvent) const { GCC_LOG("Events", "Attempting to trigger event " + std::string(pEvent->GetName())); bool processed = false; auto findIt = m_eventListeners.find(pEvent->VGetEventType()); if (findIt != m_eventListeners.end()) { const EventListenerList& eventListenerList = findIt->second; for (EventListenerList::const_iterator it = eventListenerList.begin(); it != eventListenerList.end(); ++it) { EventListenerDelegate listener = (*it); GCC_LOG("Events", "Sending Event " + std::string(pEvent->GetName()) + " to delegate."); listener(pEvent); // call the delegate processed = true; } } return processed; }
//--------------------------------------------------------------------------------------------------------------------- // EventManager::VTick //--------------------------------------------------------------------------------------------------------------------- bool EventManager::VUpdate(unsigned long maxMillis) { unsigned long currMs = GetTickCount(); unsigned long maxMs = ((maxMillis == IEventManager::kINFINITE) ? (IEventManager::kINFINITE) : (currMs + maxMillis)); // This section added to handle events from other threads. Check out Chapter 20. IEventDataPtr pRealtimeEvent; while (m_realtimeEventQueue.try_pop(pRealtimeEvent)) { VQueueEvent(pRealtimeEvent); currMs = GetTickCount(); if (maxMillis != IEventManager::kINFINITE) { if (currMs >= maxMs) { GCC_ERROR("A realtime process is spamming the event manager!"); } } } // swap active queues and clear the new queue after the swap int queueToProcess = m_activeQueue; m_activeQueue = (m_activeQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_queues[m_activeQueue].clear(); GCC_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_queues[queueToProcess].size()) + " events to process"); // Process the queue while (!m_queues[queueToProcess].empty()) { // pop the front of the queue IEventDataPtr pEvent = m_queues[queueToProcess].front(); m_queues[queueToProcess].pop_front(); GCC_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; GCC_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); GCC_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to delegate"); listener(pEvent); } } // check to see if time ran out currMs = GetTickCount(); if (maxMillis != IEventManager::kINFINITE && currMs >= maxMs) { GCC_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_queues[queueToProcess].empty()); if (!queueFlushed) { while (!m_queues[queueToProcess].empty()) { IEventDataPtr pEvent = m_queues[queueToProcess].back(); m_queues[queueToProcess].pop_back(); m_queues[m_activeQueue].push_front(pEvent); } } return queueFlushed; }