Compare commits
7 Commits
da89e35eb2
...
0bc765cd29
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bc765cd29 | |||
| dbe904e388 | |||
| 1f35fcbcf5 | |||
| 65c32d9240 | |||
| 609f623737 | |||
| e02ed8538f | |||
| 9b85bfc94a |
@ -23,7 +23,7 @@ public class DTFluxProjectSettings : ModuleRules
|
|||||||
"DeveloperSettings",
|
"DeveloperSettings",
|
||||||
"DTFluxCore",
|
"DTFluxCore",
|
||||||
"Settings",
|
"Settings",
|
||||||
"DeveloperSettings"
|
"DeveloperSettings","AvalancheMedia"
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "DTFluxGeneralSettings.h"
|
#include "DTFluxGeneralSettings.h"
|
||||||
|
#include "Assets/DTFluxModelAsset.h"
|
||||||
|
|
||||||
#include "DTFluxProjectSettingsModule.h"
|
#include "DTFluxProjectSettingsModule.h"
|
||||||
|
|
||||||
@ -14,3 +15,17 @@ UDTFluxGeneralSettings::UDTFluxGeneralSettings()
|
|||||||
UE_LOG(logDTFluxProjectSettings, Log, TEXT("Category Name -> %s"), *GetCategoryName().ToString());
|
UE_LOG(logDTFluxProjectSettings, Log, TEXT("Category Name -> %s"), *GetCategoryName().ToString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDTFluxGeneralSettings::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||||
|
{
|
||||||
|
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||||
|
if (PropertyChangedEvent.Property &&
|
||||||
|
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UDTFluxGeneralSettings, RemoteTargetRundown))
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Log, TEXT("RemoteTargetRundown property changed to: %s"),
|
||||||
|
RemoteTargetRundown.IsNull() ? TEXT("None") : *RemoteTargetRundown.ToString());
|
||||||
|
|
||||||
|
OnRemoteRundownChanged.Broadcast(RemoteTargetRundown);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -3,10 +3,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Assets/DTFluxModelAsset.h"
|
|
||||||
#include "Engine/DeveloperSettings.h"
|
#include "Engine/DeveloperSettings.h"
|
||||||
#include "DTFluxGeneralSettings.generated.h"
|
#include "DTFluxGeneralSettings.generated.h"
|
||||||
|
|
||||||
|
class UAvaRundown;
|
||||||
|
class UDTFluxModelAsset;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -20,5 +21,14 @@ public:
|
|||||||
UDTFluxGeneralSettings();
|
UDTFluxGeneralSettings();
|
||||||
UPROPERTY(Category="General", Config, EditAnywhere, BlueprintReadOnly, DisplayName="Datastorage File")
|
UPROPERTY(Category="General", Config, EditAnywhere, BlueprintReadOnly, DisplayName="Datastorage File")
|
||||||
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset;
|
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset;
|
||||||
|
UPROPERTY(Category="General|Remote HTTP", Config, EditAnywhere, BlueprintReadOnly, DisplayName="Rundown Remote Target")
|
||||||
|
TSoftObjectPtr<UAvaRundown> RemoteTargetRundown;
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||||
|
|
||||||
|
DECLARE_MULTICAST_DELEGATE_OneParam(FOnRemoteRundownChanged, const TSoftObjectPtr<UAvaRundown>& );
|
||||||
|
FOnRemoteRundownChanged OnRemoteRundownChanged;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -23,6 +23,8 @@ public class DTFluxRemote : ModuleRules
|
|||||||
"HttpServer",
|
"HttpServer",
|
||||||
"JsonUtilities",
|
"JsonUtilities",
|
||||||
"Json",
|
"Json",
|
||||||
|
"DTFluxProjectSettings",
|
||||||
|
"AvalancheMedia"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,13 @@
|
|||||||
|
|
||||||
#include "DTFluxRemoteSubsystem.h"
|
#include "DTFluxRemoteSubsystem.h"
|
||||||
#include "DTFluxRemoteSubsystem.h"
|
#include "DTFluxRemoteSubsystem.h"
|
||||||
|
|
||||||
|
#include "DTFluxGeneralSettings.h"
|
||||||
#include "DTFluxRemoteModule.h"
|
#include "DTFluxRemoteModule.h"
|
||||||
#include "DTFluxRemoteModule.h"
|
#include "DTFluxRemoteModule.h"
|
||||||
#include "HttpServerModule.h"
|
#include "HttpServerModule.h"
|
||||||
#include "IHttpRouter.h"
|
#include "IHttpRouter.h"
|
||||||
|
#include "Rundown/AvaRundown.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "Engine/Engine.h"
|
#include "Engine/Engine.h"
|
||||||
#include "Misc/DateTime.h"
|
#include "Misc/DateTime.h"
|
||||||
@ -18,6 +21,16 @@ void UDTFluxRemoteSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|||||||
|
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux API Subsystem Initialized"));
|
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux API Subsystem Initialized"));
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
// S'abonner aux changements de settings
|
||||||
|
if (UDTFluxGeneralSettings* Settings = GetMutableDefault<UDTFluxGeneralSettings>())
|
||||||
|
{
|
||||||
|
SettingsRundownChangedHandle = Settings->OnRemoteRundownChanged.AddUObject(
|
||||||
|
this, &UDTFluxRemoteSubsystem::OnSettingsRundownChanged
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
LoadRundownFromSettings();
|
||||||
// Auto-start server (optionnel)
|
// Auto-start server (optionnel)
|
||||||
StartHTTPServer(63350);
|
StartHTTPServer(63350);
|
||||||
}
|
}
|
||||||
@ -25,7 +38,22 @@ void UDTFluxRemoteSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|||||||
void UDTFluxRemoteSubsystem::Deinitialize()
|
void UDTFluxRemoteSubsystem::Deinitialize()
|
||||||
{
|
{
|
||||||
StopHTTPServer();
|
StopHTTPServer();
|
||||||
|
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
// Se désabonner du delegate
|
||||||
|
if (UDTFluxGeneralSettings* Settings = GetMutableDefault<UDTFluxGeneralSettings>())
|
||||||
|
{
|
||||||
|
if (SettingsRundownChangedHandle.IsValid())
|
||||||
|
{
|
||||||
|
Settings->OnRemoteRundownChanged.Remove(SettingsRundownChangedHandle);
|
||||||
|
SettingsRundownChangedHandle.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Décharger proprement le rundown
|
||||||
|
UnloadCurrentRundown();
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux API Subsystem Deinitialized"));
|
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux API Subsystem Deinitialized"));
|
||||||
|
|
||||||
Super::Deinitialize();
|
Super::Deinitialize();
|
||||||
@ -64,9 +92,9 @@ bool UDTFluxRemoteSubsystem::StartHTTPServer(int32 Port)
|
|||||||
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux HTTP API Server started on port %d"), ServerPort);
|
UE_LOG(logDTFluxRemote, Log, TEXT("DTFlux HTTP API Server started on port %d"), ServerPort);
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT("Base URL: http://localhost:%d/dtflux/api/v1"), ServerPort);
|
UE_LOG(logDTFluxRemote, Log, TEXT("Base URL: http://localhost:%d/dtflux/api/v1"), ServerPort);
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT("Available routes:"));
|
UE_LOG(logDTFluxRemote, Log, TEXT("Available routes:"));
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT(" POST /dtflux/api/v1/title"));
|
UE_LOG(logDTFluxRemote, Log, TEXT(" PUT /dtflux/api/v1/title"));
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT(" POST /dtflux/api/v1/title-bib"));
|
UE_LOG(logDTFluxRemote, Log, TEXT(" PUT /dtflux/api/v1/title-bib"));
|
||||||
UE_LOG(logDTFluxRemote, Log, TEXT(" POST /dtflux/api/v1/commands"));
|
UE_LOG(logDTFluxRemote, Log, TEXT(" PUT /dtflux/api/v1/commands"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -111,21 +139,21 @@ void UDTFluxRemoteSubsystem::SetupRoutes()
|
|||||||
// Route: POST /dtflux/api/v1/title
|
// Route: POST /dtflux/api/v1/title
|
||||||
TitleRouteHandle = HttpRouter->BindRoute(
|
TitleRouteHandle = HttpRouter->BindRoute(
|
||||||
FHttpPath(TEXT("/dtflux/api/v1/title")),
|
FHttpPath(TEXT("/dtflux/api/v1/title")),
|
||||||
EHttpServerRequestVerbs::VERB_GET,
|
EHttpServerRequestVerbs::VERB_PUT,
|
||||||
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleTitleRequest)
|
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleTitleRequest)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Route: POST /dtflux/api/v1/title-bib
|
// Route: POST /dtflux/api/v1/title-bib
|
||||||
TitleBibRouteHandle = HttpRouter->BindRoute(
|
TitleBibRouteHandle = HttpRouter->BindRoute(
|
||||||
FHttpPath(TEXT("/dtflux/api/v1/title-bib")),
|
FHttpPath(TEXT("/dtflux/api/v1/title-bib")),
|
||||||
EHttpServerRequestVerbs::VERB_GET,
|
EHttpServerRequestVerbs::VERB_PUT,
|
||||||
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleTitleBibRequest)
|
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleTitleBibRequest)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Route: POST /dtflux/api/v1/commands
|
// Route: POST /dtflux/api/v1/commands
|
||||||
CommandsRouteHandle = HttpRouter->BindRoute(
|
CommandsRouteHandle = HttpRouter->BindRoute(
|
||||||
FHttpPath(TEXT("/dtflux/api/v1/commands")),
|
FHttpPath(TEXT("/dtflux/api/v1/commands")),
|
||||||
EHttpServerRequestVerbs::VERB_GET,
|
EHttpServerRequestVerbs::VERB_PUT,
|
||||||
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleCommandsRequest)
|
FHttpRequestHandler::CreateUObject(this, &UDTFluxRemoteSubsystem::HandleCommandsRequest)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -316,6 +344,56 @@ bool UDTFluxRemoteSubsystem::ParseCommandData(const TSharedPtr<FJsonObject>& Jso
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDTFluxRemoteSubsystem::UnloadCurrentRundown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxRemoteSubsystem::LoadRundownFromSettings()
|
||||||
|
{
|
||||||
|
const UDTFluxGeneralSettings* Settings = GetDefault<UDTFluxGeneralSettings>();
|
||||||
|
if (!Settings)
|
||||||
|
{
|
||||||
|
UE_LOG(logDTFluxRemote, Warning, TEXT("Cannot access DTFlux settings"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSoftObjectPtr<UAvaRundown> RundownAsset = Settings->RemoteTargetRundown;
|
||||||
|
|
||||||
|
if (RundownAsset.IsNull())
|
||||||
|
{
|
||||||
|
UE_LOG(logDTFluxRemote, Log, TEXT("No rundown specified in settings"));
|
||||||
|
UnloadCurrentRundown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si c'est le même rundown, pas besoin de recharger
|
||||||
|
if (RemotedRundown && RemotedRundown == RundownAsset.LoadSynchronous())
|
||||||
|
{
|
||||||
|
UE_LOG(logDTFluxRemote, Log, TEXT("Rundown already loaded: %s"), *RundownAsset.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Décharger l'ancien rundown d'abord
|
||||||
|
UnloadCurrentRundown();
|
||||||
|
RundownAsset = RundownAsset.LoadSynchronous();
|
||||||
|
// Charger le nouveau rundown
|
||||||
|
if ( RundownAsset.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(logDTFluxRemote, Log, TEXT("Successfully loaded rundown from settings: %s"), *RundownAsset.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(logDTFluxRemote, Error, TEXT("Failed to load rundown from settings: %s"), *RundownAsset.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
void UDTFluxRemoteSubsystem::OnSettingsRundownChanged(const TSoftObjectPtr<UAvaRundown>& NewRundown)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Manual processing functions for testing
|
// Manual processing functions for testing
|
||||||
bool UDTFluxRemoteSubsystem::ProcessTitleData(const FString& JsonString)
|
bool UDTFluxRemoteSubsystem::ProcessTitleData(const FString& JsonString)
|
||||||
{
|
{
|
||||||
@ -373,4 +451,7 @@ bool UDTFluxRemoteSubsystem::ProcessCommandData(const FString& JsonString)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "IHttpRouter.h"
|
#include "IHttpRouter.h"
|
||||||
#include "DTFluxRemoteSubsystem.generated.h"
|
#include "DTFluxRemoteSubsystem.generated.h"
|
||||||
|
|
||||||
|
class UAvaRundown;
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTitleReceived, const FDTFluxRemoteTitleData&, TitleData);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTitleReceived, const FDTFluxRemoteTitleData&, TitleData);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTitleBibReceived, const FDTFluxRemoteBibData&, TitleBibData);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTitleBibReceived, const FDTFluxRemoteBibData&, TitleBibData);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCommandReceived, const FDTFluxRemoteCommandData&, CommandData);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCommandReceived, const FDTFluxRemoteCommandData&, CommandData);
|
||||||
@ -73,10 +74,25 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
TSharedPtr<IHttpRouter> HttpRouter;
|
TSharedPtr<IHttpRouter> HttpRouter;
|
||||||
|
TSoftObjectPtr<UAvaRundown> RemotedRundown;
|
||||||
int32 ServerPort = 63350;
|
int32 ServerPort = 63350;
|
||||||
bool bServerRunning = false;
|
bool bServerRunning = false;
|
||||||
|
|
||||||
FHttpRouteHandle TitleRouteHandle;
|
FHttpRouteHandle TitleRouteHandle;
|
||||||
FHttpRouteHandle TitleBibRouteHandle;
|
FHttpRouteHandle TitleBibRouteHandle;
|
||||||
FHttpRouteHandle CommandsRouteHandle;
|
FHttpRouteHandle CommandsRouteHandle;
|
||||||
|
|
||||||
|
void UnloadCurrentRundown();
|
||||||
|
void LoadRundownFromSettings();
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
FDelegateHandle SettingsRundownChangedHandle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if WITH_EDITOR
|
||||||
|
// Callback pour les changements de settings
|
||||||
|
UFUNCTION()
|
||||||
|
void OnSettingsRundownChanged(const TSoftObjectPtr<UAvaRundown>& NewRundown);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "FTDFluxUtils.h"
|
#include "DTFluxUtils.h"
|
||||||
|
|
||||||
#include "DTFluxCoreSubsystem.h"
|
#include "DTFluxCoreSubsystem.h"
|
||||||
#include "DTFluxUtilitiesModule.h"
|
#include "DTFluxUtilitiesModule.h"
|
||||||
@ -55,3 +55,13 @@ void UFTDFluxUtils::GetFullName(const int Bib, FText& OutFullName)
|
|||||||
}
|
}
|
||||||
UE_LOG(logDTFluxUtilities, Error, TEXT("DTFluxCoreSubsystem not available"));
|
UE_LOG(logDTFluxUtilities, Error, TEXT("DTFluxCoreSubsystem not available"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<FDTFluxSplitSensorInfo> UFTDFluxUtils::SortSplitRankingsByRank(const TArray<FDTFluxSplitSensorInfo>& Rankings)
|
||||||
|
{
|
||||||
|
TArray<FDTFluxSplitSensorInfo> CopyRankings = Rankings;
|
||||||
|
CopyRankings.Sort([](const FDTFluxSplitSensorInfo& A, const FDTFluxSplitSensorInfo& B)
|
||||||
|
{
|
||||||
|
return A.Rank < B.Rank;
|
||||||
|
});
|
||||||
|
return CopyRankings;
|
||||||
|
}
|
||||||
@ -5,8 +5,8 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "DTFluxCore/Public/Types/Struct/DTFluxTeamListStruct.h"
|
#include "DTFluxCore/Public/Types/Struct/DTFluxTeamListStruct.h"
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
#include "Types/Struct/DTFluxRankingStructs.h"
|
#include "Types/Struct/DTFluxSplitSensor.h"
|
||||||
#include "FTDFluxUtils.generated.h"
|
#include "DTFluxUtils.generated.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -70,4 +70,8 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Utils")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Utils")
|
||||||
static void GetFullName(const int Bib, FText& OutFullName);
|
static void GetFullName(const int Bib, FText& OutFullName);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Utils")
|
||||||
|
static TArray<FDTFluxSplitSensorInfo> SortSplitRankingsByRank(const TArray<FDTFluxSplitSensorInfo>& OutRankings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user