242 lines
7.0 KiB
C++
242 lines
7.0 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Async/Future.h"
|
|
#include "Containers/Array.h"
|
|
#include "Containers/Map.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "DirectLinkCommon.h"
|
|
#include "HAL/Platform.h"
|
|
#include "HAL/PlatformCrt.h"
|
|
#include "IMessageContext.h"
|
|
#include "Misc/EngineVersion.h"
|
|
#include "Misc/EnumClassFlags.h"
|
|
#include "Misc/Guid.h"
|
|
#include "Templates/SharedPointer.h"
|
|
#include "Templates/UniquePtr.h"
|
|
#include "Templates/UnrealTemplate.h"
|
|
|
|
#include <atomic>
|
|
|
|
#define UE_API DIRECTLINK_API
|
|
|
|
class FMessageEndpoint;
|
|
|
|
namespace DirectLink
|
|
{
|
|
class ISceneGraphNode;
|
|
|
|
|
|
enum class ECommunicationStatus{
|
|
NoIssue = 0,
|
|
ModuleNotLoaded_Messaging = 1<<0,
|
|
ModuleNotLoaded_UdpMessaging = 1<<1,
|
|
ModuleNotLoaded_Networking = 1<<2,
|
|
};
|
|
ENUM_CLASS_FLAGS(ECommunicationStatus)
|
|
DIRECTLINK_API ECommunicationStatus ValidateCommunicationStatus();
|
|
|
|
struct FRawInfo
|
|
{
|
|
struct FDataPointId
|
|
{
|
|
FString Name;
|
|
FGuid Id;
|
|
bool bIsPublic = false;
|
|
};
|
|
|
|
struct FEndpointInfo
|
|
{
|
|
FEndpointInfo() = default;
|
|
FString Name;
|
|
FEngineVersion Version; // Unreal version. This field is empty when the client predates 4.27.0
|
|
TArray<FDataPointId> Destinations;
|
|
TArray<FDataPointId> Sources;
|
|
FString UserName;
|
|
FString ExecutableName;
|
|
FString ComputerName;
|
|
bool bIsLocal = false;
|
|
uint32 ProcessId = 0;
|
|
};
|
|
|
|
struct FDataPointInfo
|
|
{
|
|
FMessageAddress EndpointAddress;
|
|
FString Name;
|
|
bool bIsSource = false; // as opposed to a destination
|
|
bool bIsOnThisEndpoint = false;
|
|
bool bIsPublic = false; // if public, can be displayed as candidate for connection
|
|
};
|
|
|
|
struct FStreamInfo
|
|
{
|
|
FStreamPort StreamId = InvalidStreamPort;
|
|
FGuid Source;
|
|
FGuid Destination;
|
|
EStreamConnectionState ConnectionState;
|
|
FCommunicationStatus CommunicationStatus;
|
|
};
|
|
FMessageAddress ThisEndpointAddress;
|
|
TMap<FMessageAddress, FEndpointInfo> EndpointsInfo;
|
|
TMap<FGuid, FDataPointInfo> DataPointsInfo;
|
|
TArray<FStreamInfo> StreamsInfo;
|
|
};
|
|
|
|
|
|
class IEndpointObserver
|
|
{
|
|
public:
|
|
virtual ~IEndpointObserver() = default;
|
|
|
|
virtual void OnStateChanged(const FRawInfo& RawInfo) {}
|
|
};
|
|
|
|
|
|
using FSourceHandle = FGuid;
|
|
using FDestinationHandle = FGuid;
|
|
|
|
|
|
|
|
/**
|
|
* FEndpoint class is the main interface for sending and receiving data with
|
|
* the DirectLink system.
|
|
*
|
|
* Instances of this class discover themselves (through MessageBus) and can see
|
|
* Sources and Destinations available on each others. This is automatic and
|
|
* works for multiple applications. With that system, one can expose data from
|
|
* an application and consume it from another.
|
|
*
|
|
* An endpoint can exposes N sources and N Destinations. That being said, a
|
|
* more classic setup is to have an 'exporter' process that only exposes
|
|
* sources, and some 'consumer' process that only have Destinations.
|
|
*
|
|
* As a convention, 'consumers' have the responsibility to handle the
|
|
* connections management. Exporters have the sole responsibility to exposes
|
|
* their data.
|
|
*
|
|
* Setup example:
|
|
* - Exporter process
|
|
* - Source "My First Source"
|
|
* - Source "My Second Source"
|
|
*
|
|
* - Consumer process
|
|
* - Destination "Viewport"
|
|
*
|
|
* The consumer process can handle the connections between Sources and
|
|
* Destinations with the OpenStream and CloseStream methods.
|
|
*/
|
|
class FEndpoint
|
|
: public FNoncopyable
|
|
{
|
|
public:
|
|
enum class EOpenStreamResult
|
|
{
|
|
Opened,
|
|
AlreadyOpened,
|
|
SourceAndDestinationNotFound,
|
|
RemoteEndpointNotFound,
|
|
Unsuppported,
|
|
CannotConnectToPrivate,
|
|
};
|
|
|
|
public:
|
|
UE_API FEndpoint(const FString& InName);
|
|
UE_API ~FEndpoint();
|
|
|
|
UE_API void SetVerbose(bool bVerbose=true);
|
|
|
|
/**
|
|
* Add a Source to that endpoint. A source can hold content (a scene snapshot)
|
|
* and is able to stream that content to remote destinations.
|
|
* @param Name User facing name for this source.
|
|
* @param Visibility Whether that Source is visible to remote endpoints
|
|
* @return A Handle required by other Source related methods
|
|
*/
|
|
UE_API FSourceHandle AddSource(const FString& Name, EVisibility Visibility=EVisibility::Public);
|
|
|
|
/**
|
|
* Closes all streams related to this Source and remove it from the endpoint.
|
|
* @param Source Handle of the source to remove
|
|
*/
|
|
UE_API void RemoveSource(const FSourceHandle& Source);
|
|
|
|
/**
|
|
* Set the root of the content that should be exposed from that source.
|
|
* @param Source Handle of the source to setup
|
|
* @param InRoot Root of the graph that should be exposed
|
|
* @param bSnapshot Whether the graph should be snapshotted right away
|
|
*/
|
|
UE_API void SetSourceRoot(const FSourceHandle& Source, ISceneGraphNode* InRoot, bool bSnapshot);
|
|
|
|
/**
|
|
* Use the Source root to discover the graph and snapshot the content in its current state.
|
|
* @param Source Handle of the source to snapshot
|
|
*/
|
|
UE_API void SnapshotSource(const FSourceHandle& Source);
|
|
|
|
|
|
/**
|
|
* Add a Destination on that endpoint
|
|
*
|
|
* @param Name Name of that destination
|
|
* @param Visibility Whether this destination should be visible to remote endpoints
|
|
* @param ConnectionRequestHandler Object that will handle connections requests from Sources
|
|
* @return A handle to the new destination
|
|
*/
|
|
UE_API FDestinationHandle AddDestination(const FString& Name, EVisibility Visibility, const TSharedPtr<class IConnectionRequestHandler>& ConnectionRequestHandler);
|
|
|
|
/**
|
|
* Disconnect all streams related to that destination and removes the
|
|
* Destination itself from that endpoint
|
|
* @param Destination Handle of the destination to remove
|
|
*/
|
|
UE_API void RemoveDestination(const FDestinationHandle& Destination);
|
|
|
|
/**
|
|
* Get a snapshot of the current state of the DirectLink swarm. It includes
|
|
* discovered Endpoints, their sources and destinations, and the streams
|
|
* descriptions.
|
|
* @return Description of the last state of swarm
|
|
*/
|
|
UE_API FRawInfo GetRawInfoCopy() const;
|
|
|
|
/**
|
|
* Register an IEndpointObserver that will be notified periodically with the last state of the swarm.
|
|
* @param Observer Object that should be notified
|
|
*/
|
|
UE_API void AddEndpointObserver(IEndpointObserver* Observer);
|
|
|
|
/**
|
|
* Removes a previously added observer
|
|
* @param Observer Observer to remove
|
|
*/
|
|
UE_API void RemoveEndpointObserver(IEndpointObserver* Observer);
|
|
|
|
/**
|
|
* Open a Stream between a Source and a Destination
|
|
* @param SourceId Handle to the Source
|
|
* @param DestinationId Handle to the Destination
|
|
* @return Whether the stream is correctly opened
|
|
*/
|
|
UE_API EOpenStreamResult OpenStream(const FSourceHandle& SourceId, const FDestinationHandle& DestinationId);
|
|
|
|
/**
|
|
* Close a previously opened stream
|
|
* @param SourceId Handle to the Source
|
|
* @param DestinationId Handle to the Destination
|
|
*/
|
|
UE_API void CloseStream(const FSourceHandle& SourceId, const FDestinationHandle& DestinationId);
|
|
|
|
private:
|
|
TUniquePtr<class FSharedState> SharedStatePtr;
|
|
class FSharedState& SharedState;
|
|
|
|
TUniquePtr<class FInternalThreadState> InternalPtr;
|
|
class FInternalThreadState& Internal;
|
|
};
|
|
|
|
} // namespace DirectLink
|
|
|
|
#undef UE_API
|