Here is a little example on how to use cluster events in C++
You can now find it in the Snippets section of the Unreal Template.
Code Example
Here is the code you would need to use, if you don't want to use the helper class DisplayClusterEventWrapper
.
UserInputSync.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Cluster/IDisplayClusterClusterManager.h"
#include "Cluster/DisplayClusterClusterEvent.h"
#include "UserInputSync.generated.h"
UCLASS()
class DYNDIRUNREAL_API AUserInputSync : public AActor
{
GENERATED_BODY()
public:
void BeginPlay() override;
void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UFUNCTION(BlueprintCallable)
void OnUserInput();
void ReactOnUserInput();
private:
FOnClusterEventListener ClusterEventListenerDelegate;
void HandleClusterEvent(const FDisplayClusterClusterEvent& Event);
};
UserInputSync.cpp
#include "UserInputSync.h"
#include "IUniversalLogging.h" //just here to give some feedback on the user's action
#include "Engine.h"
#include "IDisplayCluster.h"
void AUserInputSync::BeginPlay() {
Super::BeginPlay();
//register the listener
IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr();
if (ClusterManager && !ClusterEventListenerDelegate.IsBound())
{
ClusterEventListenerDelegate = FOnClusterEventListener::CreateUObject(this, &AUserInputSync::HandleClusterEvent);
ClusterManager->AddClusterEventListener(ClusterEventListenerDelegate);
}
//so the log shows on all slaves on screen
UniLog.GetDefaultLogStream()->SetLogOnScreenOnMaster(true);
UniLog.GetDefaultLogStream()->SetLogOnScreenOnSlaves(true);
}
void AUserInputSync::EndPlay(const EEndPlayReason::Type EndPlayReason) {
//de-register the listener again
IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr();
if (ClusterManager && ClusterEventListenerDelegate.IsBound())
{
ClusterManager->RemoveClusterEventListener(ClusterEventListenerDelegate);
}
Super::EndPlay(EndPlayReason);
}
void AUserInputSync::ReactOnUserInput() {
//some action you want to perform on all nodes, e.g.:
UniLog.Log("Input received!");
}
void AUserInputSync::OnUserInput() {
IDisplayClusterClusterManager* const Manager = IDisplayCluster::Get().GetClusterMgr();
if (Manager)
{
if (Manager->IsStandalone()) {
//in standalone (e.g., desktop editor play) cluster events are not executed....
ReactOnUserInput();
}
else {
// else create a cluster event to react to
FDisplayClusterClusterEvent cluster_event;
cluster_event.Name = "Some Custom Name, e.g., G pressed";
Manager->EmitClusterEvent(cluster_event, true);
}
}
}
void AUserInputSync::HandleClusterEvent(const FDisplayClusterClusterEvent& Event) {
if (Event.Name == "Some Custom Name, e.g., G pressed") {
//now we actually react on all cluster nodes:
ReactOnUserInput();
}
}