#include "MessageDispatcher.h" #include "EntityManager.h" MessageDispatcher* MessageDispatcher::Instance() { static MessageDispatcher instance; return &instance; } //----------------------------- Dispatch --------------------------------- // // see description in header //------------------------------------------------------------------------ void MessageDispatcher::Discharge(BasicEntity* receiver, const Telegram& telegram) { if (!receiver->HandleMessage(telegram)) { // telegram could not be handled #ifdef SHOW_MESSAGING_INFO debug_con << "Message not handled" << ""; #endif } } //---------------------------- DispatchMsg --------------------------- // // given a message, a receiver, a sender and any time delay, this function // routes the message to the correct agent (if no delay) or stores // in the message queue to be dispatched at the correct time //------------------------------------------------------------------------ void MessageDispatcher::DispatchMsg(Uint32 delay, int sender, int receiverID, int msg, void* additionalInfo = nullptr) { // get a pointer to the receiver BasicEntity* receiver = EntityMgr->getEntityFromID(receiverID); // make sure the receiver is valid if (receiver == nullptr) { #ifdef SHOW_MESSAGING_INFO debug_con << "\nWarning! No Receiver with ID of " << receiver << " found" << ""; #endif return; } // create the telegram Telegram telegram(0, sender, receiverID, msg, additionalInfo); // if there is no delay, route telegram immediately if (delay <= 0.0) { #ifdef SHOW_MESSAGING_INFO debug_con << "\nTelegram dispatched at time: " << TickCounter->GetCurrentFrame() << " by " << sender << " for " << receiver << ". Msg is " << msg << ""; #endif // send the telegram to the recipient Discharge(receiver, telegram); } // else calculate the time when the telegram should be dispatched else { Uint32 currentTime = SDL_GetTicks(); // double CurrentTime = TickCounter->GetCurrentFrame(); telegram.DispatchTime = currentTime + delay; // and put it in the queue PriorityQ.insert(telegram); #ifdef SHOW_MESSAGING_INFO debug_con << "\nDelayed telegram from " << sender << " recorded at time " << TickCounter->GetCurrentFrame() << " for " << receiver << ". Msg is " << msg << ""; #endif } } //---------------------- DispatchDelayedMessages ------------------------- // // This function dispatches any telegrams with a timestamp that has // expired. Any dispatched telegrams are removed from the queue //------------------------------------------------------------------------ void MessageDispatcher::DispatchDelayedMessages() { // first get current time Uint32 currentTime = SDL_GetTicks(); // double CurrentTime = TickCounter->GetCurrentFrame(); // now peek at the queue to see if any telegrams need dispatching. // remove all telegrams from the front of the queue that have gone // past their sell by date while (!PriorityQ.empty() && (PriorityQ.begin()->DispatchTime < currentTime) && (PriorityQ.begin()->DispatchTime > 0)) { // read the telegram from the front of the queue const Telegram& telegram = *PriorityQ.begin(); // find the recipient BasicEntity* receiver = EntityMgr->getEntityFromID(telegram.Receiver); #ifdef SHOW_MESSAGING_INFO debug_con << "\nQueued telegram ready for dispatch: Sent to " << pReceiver->ID() << ". Msg is " << telegram.Msg << ""; #endif // send the telegram to the recipient Discharge(receiver, telegram); // remove it from the queue PriorityQ.erase(PriorityQ.begin()); } }