void FMessageTracer::TraceSentMessage(const IMessageContextRef& Context) { if (!Running) { return; } double Timestamp = FPlatformTime::Seconds(); Traces.Enqueue([=]() { // look up endpoint info FMessageTracerEndpointInfoPtr EndpointInfo = AddressesToEndpointInfos.FindRef(Context->GetSender()); if (!EndpointInfo.IsValid()) { return; } // create message info FMessageTracerMessageInfoRef MessageInfo = MakeShareable(new FMessageTracerMessageInfo()); { MessageInfo->Context = Context; MessageInfo->Intercepted = false; MessageInfo->SenderInfo = EndpointInfo; MessageInfo->TimeRouted = 0.0; MessageInfo->TimeSent = Timestamp; MessageInfos.Add(Context, MessageInfo); } // add message type FMessageTracerTypeInfoPtr& TypeInfo = MessageTypes.FindOrAdd(Context->GetMessageType()); if (!TypeInfo.IsValid()) { TypeInfo = MakeShareable(new FMessageTracerTypeInfo()); TypeInfo->TypeName = Context->GetMessageType(); TypeAddedDelegate.Broadcast(TypeInfo.ToSharedRef()); } TypeInfo->Messages.Add(MessageInfo); // update database EndpointInfo->SentMessages.Add(MessageInfo); MessageInfo->TypeInfo = TypeInfo; MessagesAddedDelegate.Broadcast(MessageInfo); }); }
void FMessageRouter::HandleRouteMessage( IMessageContextRef Context ) { // intercept routing TArray<IMessageInterceptorPtr>& Interceptors = ActiveInterceptors.FindOrAdd(Context->GetMessageType()); for (TArray<IMessageInterceptorPtr>::TIterator It(Interceptors); It; ++It) { if ((*It)->InterceptMessage(Context)) { Tracer->TraceInterceptedMessage(Context, It->ToSharedRef()); return; } } // dispatch the message // @todo gmp: implement time synchronization between networked message endpoints if (false) //(Context->GetTimeSent() > CurrentTime) { DelayedMessages.HeapPush(FDelayedMessage(Context, ++DelayedMessagesSequence)); } else { DispatchMessage(Context); } Tracer->TraceRoutedMessage(Context); }
void FMessageRouter::DispatchMessage( const IMessageContextRef& Context ) { if (Context->IsValid()) { TArray<IReceiveMessagesPtr> Recipients; // get recipients, either from the context... const TArray<FMessageAddress>& RecipientList = Context->GetRecipients(); if (RecipientList.Num() > 0) { for (int32 Index = 0; Index < RecipientList.Num(); Index++) { IReceiveMessagesPtr Recipient = ActiveRecipients.FindRef(RecipientList[Index]).Pin(); if (Recipient.IsValid()) { Recipients.AddUnique(Recipient); } else { ActiveRecipients.Remove(RecipientList[Index]); } } } // ... or from subscriptions else { FilterSubscriptions(ActiveSubscriptions.FindOrAdd(Context->GetMessageType()), Context, Recipients); FilterSubscriptions(ActiveSubscriptions.FindOrAdd(NAME_All), Context, Recipients); } // dispatch the message for (int32 RecipientIndex = 0; RecipientIndex < Recipients.Num(); RecipientIndex++) { IReceiveMessagesPtr Recipient = Recipients[RecipientIndex]; ENamedThreads::Type RecipientThread = Recipient->GetRecipientThread(); if (RecipientThread == ENamedThreads::AnyThread) { Tracer->TraceDispatchedMessage(Context, Recipient.ToSharedRef(), false); Recipient->ReceiveMessage(Context); Tracer->TraceHandledMessage(Context, Recipient.ToSharedRef()); } else { TGraphTask<FMessageDispatchTask>::CreateTask().ConstructAndDispatchWhenReady(RecipientThread, Context, Recipient, Tracer); } } } }
void FMessageTracer::ProcessSentMessage( IMessageContextRef Context, double TimeSeconds ) { FMessageTracerEndpointInfoPtr EndpointInfo = AddressesToEndpointInfos.FindRef(Context->GetSender()); if (!EndpointInfo.IsValid()) { return; } // create message info FMessageTracerMessageInfoRef MessageInfo = MakeShareable(new FMessageTracerMessageInfo()); MessageInfo->Context = Context; MessageInfo->SenderInfo = EndpointInfo; MessageInfo->TimeRouted = 0.0; MessageInfo->TimeSent = TimeSeconds; MessageInfos.Add(Context, MessageInfo); // add message type FMessageTracerTypeInfoPtr& TypeInfo = MessageTypes.FindOrAdd(Context->GetMessageType()); if (!TypeInfo.IsValid()) { TypeInfo = MakeShareable(new FMessageTracerTypeInfo()); TypeInfo->TypeName = Context->GetMessageType(); TypeAddedDelegate.Broadcast(TypeInfo.ToSharedRef()); } TypeInfo->Messages.Add(MessageInfo); // update database EndpointInfo->SentMessages.Add(MessageInfo); MessageInfo->TypeInfo = TypeInfo; MessagesAddedDelegate.Broadcast(MessageInfo); }