Update Cluster Events in Cpp authored by Jonathan Ehret's avatar Jonathan Ehret
Here is a little example on how to use cluster events in C++, e.g., reacting to UMG user input, or keyboard input which is otherwise not synced yet in the CAVE.
You can now find it in the [Snippets section of the Unreal Template](https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/unrealprojecttemplate/-/snippets).
## Code Example
Here is the code you would need to use, if you don't want to use the helper class `DisplayClusterEventWrapper`.
`UserInputSync.h`
```c++
#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`
```c++
#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();
}
}
Here is a little example on how to use cluster events in C++, e.g., reacting to UMG user input, or keyboard input which is otherwise not synced yet in the CAVE.
You can now find it in the [Snippets section of the Unreal Template](https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/unrealprojecttemplate/-/snippets).
## Code Example
Here is the code you would need to use, if you don't want to use the helper class `DisplayClusterEventWrapper`.
`UserInputSync.h`
```c++
#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:
FOnClusterEventJsonListener ClusterEventListenerDelegate;
void HandleClusterEvent(const FDisplayClusterClusterEventJson& Event);
};
```
`UserInputSync.cpp`
```c++
#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();
}
}
```
\ No newline at end of file