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);
			}
		}
	}
}
Exemple #4
0
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);
}