Download

What is the most efficient way to periodically (T = 30ms) send info from another process to UE4?

Dear UE gurus,
we are in the need of creating an efficient bridge to allow the transfer of small amount of data (say three to six float numbers) gathered from separate process into an UE4 environment, around 30 per second.
The system is a pediatric rehabilitation set of games, which need to be coupled with several different input devices that in turn provide the motion information requested by the games.

At the moment (thaks to Rama) we are using a TCP implementation, but I feel like it is not very efficient both for the TCP handling burden and for the need to have a timer that continuously asks if there are data available. My desire would be to fire from the outside an event inside UE4, whose arguments are the variables required by the game. I guess if the UDP solutions that are around or other different implementation (i.e. MessageBus based - I haven’t been able to find out any of this kind with one side “non-UE4” coded) could be much more efficient and reduce the little lag (something I feel like around 100-200 ms) we’re currently experiencing with the TCPListener solution inside UE4.

Thanks in advance for your suggestions

Paolo

If your processes are on the same machine, you can use FInteractiveProcess. This won’t help if you have to send data over the network (well, maybe someone better at this knows a way).

I’m working on a project that generates complex data structures in a separate process upon request, using FInteractiveProcess. Using a callback, when the process is finished, the OnOutput handler fires a method to parse the message:



// FInteractive process
FInteractiveProcess* defProcess = nullptr;

std::atomic<bool> messages = false;

void StartProcess()
	{
		if(defProcess == nullptr)
		{

			defProcess = new FInteractiveProcess(
				TEXT(PATH_TO_PROCESS_EXE),
				TEXT(""),
				true,
				true
			);

			defProcess->OnOutput().BindLambda(&] (const FString& message)
			{
				messages = true;
                                HandleMessage(message);
			});

			if(!defProcess->Launch())
			{
				UE_LOG(LogTemp, Error, TEXT("Unable to start generator process!"));
			}
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("'StartProcess' called - but process already created."));
		}
	}

	void StopProcess()
	{
		if(defProcess != nullptr)
		{
			if(defProcess->IsRunning())
			{
				UE_LOG(LogTemp, Display, TEXT("Stopping process..."));
				defProcess->Stop();
			}
			
			delete defProcess;
			defProcess = nullptr;
		}
	}

void HandleMessage(const FString& msg)
{
// parsing goes here
//
//

//all done this cycle
messages = false;

}



You could have your external process send text to stdout, and buffer the results in a std::queue. Then have an object check this per tick or add a delegate. My process sends at variable intervals so I use thread safe atomic variables, which if you have a set interval you may not need it. Note: if your process is windows based, you may have to use ReadFile and WriteFile instead of std::cout and std::cin.

Hope this helps.