diff --git a/Source/DisplayClusterExtensions/Private/ClusterSyncedMethodCaller.cpp b/Source/DisplayClusterExtensions/Private/ClusterSyncedMethodCaller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88a5c920782ba29fc5340ec016dba9661bb07d8a --- /dev/null +++ b/Source/DisplayClusterExtensions/Private/ClusterSyncedMethodCaller.cpp @@ -0,0 +1,63 @@ +#include "ClusterSyncedMethodCaller.h" + +#include "IDisplayCluster.h" + +void UClusterSyncedMethodCaller::RegisterListener() +{ + IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr(); + if (ClusterManager && !ClusterEventListenerDelegate.IsBound()) + { + ClusterEventListenerDelegate = FOnClusterEventListener::CreateUObject(this, &UClusterSyncedMethodCaller::HandleClusterEvent); + ClusterManager->AddClusterEventListener(ClusterEventListenerDelegate); + } + +} + +void UClusterSyncedMethodCaller::DeregisterListener() { + IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr(); + if (ClusterManager && ClusterEventListenerDelegate.IsBound()) + { + ClusterManager->RemoveClusterEventListener(ClusterEventListenerDelegate); + } +} + +void UClusterSyncedMethodCaller::CallMethodSynced(FString UniqueIdentifier, TMap<FString, FString> Parameters) +{ + + check(SyncedFunctions.Contains(UniqueIdentifier)) + + IDisplayClusterClusterManager* const Manager = IDisplayCluster::Get().GetClusterMgr(); + if (Manager) + { + if (Manager->IsStandalone()) { + //in standalone (e.g., desktop editor play) cluster events are not executed.... + if (SyncedFunctions.Contains(UniqueIdentifier)) { + SyncedFunctions.FindChecked(UniqueIdentifier).Execute(Parameters); + } + } + else { + // else create a cluster event to react to + FDisplayClusterClusterEvent cluster_event; + cluster_event.Category = "ClusterSyncedMethodCaller"; + cluster_event.Type = "ClusterSyncedMethodCaller"; + cluster_event.Name = UniqueIdentifier; + cluster_event.Parameters = Parameters; + + Manager->EmitClusterEvent(cluster_event, true); + } + } +} + +void UClusterSyncedMethodCaller::RegisterSyncedMethod(FString UniqueIdentifier, FSyncMethod MethodToCall) +{ + SyncedFunctions.Add(UniqueIdentifier, MethodToCall); +} + +void UClusterSyncedMethodCaller::HandleClusterEvent(const FDisplayClusterClusterEvent & Event) +{ + if (Event.Category.Equals("ClusterSyncedMethodCaller") && Event.Type.Equals("ClusterSyncedMethodCaller")) { + if (SyncedFunctions.Contains(Event.Name)) { + SyncedFunctions.FindChecked(Event.Name).Execute(Event.Parameters); + } + } +} diff --git a/Source/DisplayClusterExtensions/Public/ClusterSyncedMethodCaller.h b/Source/DisplayClusterExtensions/Public/ClusterSyncedMethodCaller.h new file mode 100644 index 0000000000000000000000000000000000000000..52d990b2c8a7e31ab543a063b6f59a2611254315 --- /dev/null +++ b/Source/DisplayClusterExtensions/Public/ClusterSyncedMethodCaller.h @@ -0,0 +1,41 @@ +#pragma once + +#include "CoreMinimal.h" +#include "UObject/NoExportTypes.h" +#include "Cluster/IDisplayClusterClusterManager.h" +#include "Cluster/DisplayClusterClusterEvent.h" +#include "Delegates/Delegate.h" + +#include "ClusterSyncedMethodCaller.generated.h" + +typedef TMap<FString, FString> FStringMap; +DECLARE_DELEGATE_OneParam(FSyncMethod, FStringMap) +//typedef FSyncMethod::FDelegate FSyncMethodDelegate; + +UCLASS() +class DISPLAYCLUSTEREXTENSIONS_API UClusterSyncedMethodCaller : public UObject +{ + GENERATED_BODY() + +public: + //RegisterListener should be called in BeginPlay() + void RegisterListener(); + + //DeregisterListener() should be called in EndPlay() + void DeregisterListener(); + + //This will call a with UniqueIdentifier registered method in a synced manner with given parameters, also works in non-cluster mode. + //Notice that in the cluster case this call is synced between all nodes, but async to the call of this method! + void CallMethodSynced(FString UniqueIdentifier, TMap<FString, FString> Parameters); + + //Register a method to be called in a synced manner, UniqueIdentifier should be unique to any call of this method of any object! + void RegisterSyncedMethod(FString UniqueIdentifier, FSyncMethod MethodToCall); + +private: + FOnClusterEventListener ClusterEventListenerDelegate; + virtual void HandleClusterEvent(const FDisplayClusterClusterEvent& Event); + + TMap<FString, FSyncMethod> SyncedFunctions; + +}; +