Compare commits

...

5 Commits

8 changed files with 130 additions and 58 deletions

View File

@ -31,6 +31,7 @@ public class DTFluxAPIStatus : ModuleRules
"DTFluxCoreSubsystem", "DTFluxCoreSubsystem",
"InputCore", "InputCore",
"OutputLog", "OutputLog",
"ToolMenus",
} }
); );
} }

View File

@ -14,9 +14,9 @@ FText DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StatusTabDisplayName = FText::
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StartupModule() void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StartupModule()
{ {
FDTFluxStatusStyle::RegisterStyle();
InitMenuExtension(); InitMenuExtension();
RegisterStatusTab(); RegisterStatusTab();
FDTFluxStatusStyle::RegisterStyle();
} }
@ -25,45 +25,109 @@ void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StartupModule()
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::InitMenuExtension() void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::InitMenuExtension()
{ {
FLevelEditorModule& LevelEditorModule = // FLevelEditorModule& LevelEditorModule =
FModuleManager::LoadModuleChecked<FLevelEditorModule>(TEXT("LevelEditor")); // FModuleManager::LoadModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
// FDTFluxAPIModule& DTFluxApi = // // FDTFluxAPIModule& DTFluxApi =
// FModuleManager::LoadModuleChecked<FDTFluxAPIModule>(TEXT("DTFluxAPI")); // // FModuleManager::LoadModuleChecked<FDTFluxAPIModule>(TEXT("DTFluxAPI"));
const TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender()); // const TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
//
// MenuExtender->AddMenuBarExtension(
// "Help",
// EExtensionHook::Before,
// nullptr,
// FMenuBarExtensionDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::AddMenu)
// );
// LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
MenuExtender->AddMenuBarExtension( UToolMenus::RegisterStartupCallback(
"Help", FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::RegisterMenus)
EExtensionHook::Before,
nullptr,
FMenuBarExtensionDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::AddMenu)
); );
LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
} }
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::AddMenu(FMenuBarBuilder& MenuBarBuilder) void FDTFluxAPIStatusModule::RegisterMenus()
{ {
MenuBarBuilder.AddPullDownMenu( UE_LOG(logDTFluxStatus, Warning, TEXT("Creating DTFlux menu"));
// 1. Enregistrer le menu DTFlux
UToolMenu* DTFluxMenu = UToolMenus::Get()->RegisterMenu("DTFlux.MainMenu");
if (DTFluxMenu)
{
CreateSubmenu(DTFluxMenu);
}
// 2. Ajouter ce menu à la barre principale
if (UToolMenu* MainMenu = UToolMenus::Get()->ExtendMenu("MainFrame.MainMenu"))
{
FToolMenuSection& DTFluxMenuSection = MainMenu->FindOrAddSection("DTFlux");
DTFluxMenuSection.Label = FText::FromString("DTFlux");
DTFluxMenuSection.AddSubMenu(
"DTFluxSubmenu",
FText::FromString("DTFlux"), FText::FromString("DTFlux"),
FText::FromString("DTFlux API Tools"), FText::FromString("DTFlux API Tools"),
FNewMenuDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::FillMenu) FNewToolMenuDelegate::CreateLambda([](UToolMenu* Menu)
{
// Référencer le menu enregistré
if (UToolMenu* RegisteredMenu = UToolMenus::Get()->FindMenu("DTFlux.MainMenu"))
{
// Copier la structure du menu enregistré
for (const FToolMenuSection& Section : RegisteredMenu->Sections)
{
Menu->Sections.Add(Section);
}
}
}),
false,
FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tab.Icon")
); );
}
} }
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::FillMenu(FMenuBuilder& MenuBuilder) void FDTFluxAPIStatusModule::CreateSubmenu(UToolMenu* Menu)
{ {
MenuBuilder.BeginSection(NAME_None, FText::FromString("DTFlux API")); FToolMenuSection& DTFluxAPISection = Menu->FindOrAddSection("DTFluxAPI");
MenuBuilder.AddMenuEntry( DTFluxAPISection.Label = FText::FromString("DTFlux API");
FText::FromString("Status"), // Cette section est vide pour le moment, prête pour de futurs boutons
FText::FromString("Launch DTFlux Status"),
FSlateIcon(FDTFluxStatusStyle::GetStyleSetName(), "LevelEditor.Tab.Icon"),
FExecuteAction::CreateRaw(this, &FDTFluxAPIStatusModule::OnButtonClicked)
);
MenuBuilder.EndSection();
// Section 2 : Tools
FToolMenuSection& ToolsSection = Menu->FindOrAddSection("Tools");
ToolsSection.Label = FText::FromString("Tools");
// Ajouter le bouton Status dans la section Tools
DTFluxAPISection.AddMenuEntry(
"DTFluxStatus",
FText::FromString("DTFlux Status"),
FText::FromString("Launch DTFlux Status Control Panel"),
FSlateIcon(FDTFluxStatusStyle::GetStyleSetName(), "LevelEditor.Tab.Icon"),
FUIAction(FExecuteAction::CreateRaw(this, &FDTFluxAPIStatusModule::OnButtonClicked))
);
} }
// void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::AddMenu(FMenuBarBuilder& MenuBarBuilder)
// {
// MenuBarBuilder.AddPullDownMenu(
// FText::FromString("DTFlux"),
// FText::FromString("DTFlux API Tools"),
// FNewMenuDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::FillMenu)
// );
// }
// void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::FillMenu(FMenuBuilder& MenuBuilder)
// {
// MenuBuilder.BeginSection(NAME_None, FText::FromString("DTFlux API"));
// MenuBuilder.AddMenuEntry(
// FText::FromString("Status"),
// FText::FromString("Launch DTFlux Status"),
// FSlateIcon(FDTFluxStatusStyle::GetStyleSetName(), "LevelEditor.Tab.Icon"),
// FExecuteAction::CreateRaw(this, &FDTFluxAPIStatusModule::OnButtonClicked)
// );
// MenuBuilder.EndSection();
// }
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::OnButtonClicked() void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::OnButtonClicked()
{ {
FGlobalTabmanager::Get()->TryInvokeTab(StatusTabId); FGlobalTabmanager::Get()->TryInvokeTab(StatusTabId);

View File

@ -13,10 +13,11 @@ public:
#pragma region MenuExtention #pragma region MenuExtention
void InitMenuExtension(); void InitMenuExtension();
void AddMenu(FMenuBarBuilder& MenuBarBuilder); void RegisterMenus();
void FillMenu(FMenuBuilder& MenuBuilder); void CreateSubmenu(UToolMenu* Menu);
// void AddMenu(FMenuBarBuilder& MenuBarBuilder);
// void FillMenu(FMenuBuilder& MenuBuilder);
void OnButtonClicked(); void OnButtonClicked();
// void OnWsEvent(TEnumAsByte<EDTFluxWsStatus> WsResponseEvent) const;
#pragma endregion #pragma endregion
#pragma region EditorTab #pragma region EditorTab
@ -25,7 +26,6 @@ public:
private: private:
static FName StatusTabId; static FName StatusTabId;
static FText StatusTabDisplayName; static FText StatusTabDisplayName;
TSharedPtr<class SDTFluxStatusWidget> StatusWidget; TSharedPtr<class SDTFluxStatusWidget> StatusWidget;
#pragma endregion #pragma endregion
}; };

View File

@ -366,3 +366,12 @@ void UDTFluxCoreSubsystem::LaunchPursuitSequenceFor(const TArray<int> ContestIds
} }
} }
} }
FOnPursuitSequenceReady& UDTFluxCoreSubsystem::InitPursuit(const TArray<FDTFluxContest> Contests)
{
if (PursuitManager)
{
PursuitManager->LaunchPursuitSequenceFor(Contests);
}
return PursuitManager->OnPursuitSequenceReady;
}

View File

@ -18,7 +18,7 @@ class UDTFluxPursuitManager;
/** /**
* *
*/ */
UCLASS() UCLASS(Blueprintable, BlueprintType)
class DTFLUXCORESUBSYSTEM_API UDTFluxCoreSubsystem : public UEngineSubsystem class DTFLUXCORESUBSYSTEM_API UDTFluxCoreSubsystem : public UEngineSubsystem
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@ -102,7 +102,7 @@ public:
UPROPERTY() UPROPERTY()
int CurrentIndex = -1; int CurrentIndex = -1;
UPROPERTY(BlueprintCallable, Category="DTFlux|Pursuit") UPROPERTY(BlueprintAssignable, Category="DTFlux|Pursuit")
FOnPursuitSequenceReady OnPursuitSequenceReady; FOnPursuitSequenceReady OnPursuitSequenceReady;

View File

@ -104,7 +104,6 @@ FGuid UDTFluxNetworkSubsystem::SendTrackedRequestWithCallback(
PendingErrorCallbacks.Add(RequestId, OnError.GetValue()); PendingErrorCallbacks.Add(RequestId, OnError.GetValue());
} }
} }
return RequestId; return RequestId;
} }
@ -592,8 +591,6 @@ void UDTFluxNetworkSubsystem::Parse(FDTFluxServerResponse& Response)
void UDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString& MessageString) void UDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString& MessageString)
{ {
// UE_LOG(logDTFluxNetwork, Warning, TEXT("Client %s :\nMessage Received : %s"), *WsClient->GetAddress(), *MessageString);
//Do Something With the message
EDTFluxResponseStatus ResponseStatus; EDTFluxResponseStatus ResponseStatus;
FDTFluxServerResponse Response(MessageString, ResponseStatus); FDTFluxServerResponse Response(MessageString, ResponseStatus);
if (!TryMatchResponseToQueuedRequest(Response)) if (!TryMatchResponseToQueuedRequest(Response))
@ -680,6 +677,7 @@ bool UDTFluxNetworkSubsystem::TryMatchResponseToQueuedRequest(FDTFluxServerRespo
TEXT("Matched response to queued request: Type=%s, Contest=%d, Stage=%d, Split=%d"), TEXT("Matched response to queued request: Type=%s, Contest=%d, Stage=%d, Split=%d"),
*UEnum::GetValueAsString(Response.GetResponseType()), Response.ContestID, Response.StageID, *UEnum::GetValueAsString(Response.GetResponseType()), Response.ContestID, Response.StageID,
Response.SplitID); Response.SplitID);
if (PendingCallbacks.Contains(FoundRequestId)) if (PendingCallbacks.Contains(FoundRequestId))
{ {
FOnDTFluxTrackedRequestResponse* SuccessCallback = PendingCallbacks.Find(FoundRequestId); FOnDTFluxTrackedRequestResponse* SuccessCallback = PendingCallbacks.Find(FoundRequestId);
@ -689,7 +687,6 @@ bool UDTFluxNetworkSubsystem::TryMatchResponseToQueuedRequest(FDTFluxServerRespo
} }
return QueueManager->MarkRequestAsResponded(FoundRequestId); return QueueManager->MarkRequestAsResponded(FoundRequestId);
} }
return false; return false;
} }

View File

@ -128,14 +128,14 @@ public:
// === REQUÊTES AVEC QUEUE ET TRACKING === // === REQUÊTES AVEC QUEUE ET TRACKING ===
UFUNCTION(BlueprintCallable, Category="DTFlux|Tracked Requests") UFUNCTION(BlueprintCallable, Category="DTFlux|Tracked Requests")
FGuid SendTrackedRequest(EDTFluxApiDataType RequestType, int32 ContestId = -1, int32 StageId = -1, FGuid SendTrackedRequest(EDTFluxApiDataType RequestType, int32 ContestId = -1, int32 StageId = -1,
int32 SplitId = -1, float TimeoutSeconds = 30.0f); int32 SplitId = -1, float TimeoutSeconds = 5.0f);
FGuid SendTrackedRequestWithCallback(EDTFluxApiDataType RequestType, int32 ContestId, int32 StageId, int32 SplitId, FGuid SendTrackedRequestWithCallback(EDTFluxApiDataType RequestType, int32 ContestId, int32 StageId, int32 SplitId,
FOnDTFluxTrackedRequestResponse OnCompleted, FOnDTFluxTrackedRequestResponse OnCompleted,
FOnDTFluxTrackedRequestTimeout OnTimeout, FOnDTFluxTrackedRequestTimeout OnTimeout,
TOptional<FOnDTFluxRequestResponseError> OnError = TOptional< TOptional<FOnDTFluxRequestResponseError> OnError = TOptional<
FOnDTFluxRequestResponseError>(), FOnDTFluxRequestResponseError>(),
float TimeoutSeconds = 30.0f); float TimeoutSeconds = 5.0f);
UFUNCTION(BlueprintCallable, Category="DTFlux|Tracked Requests") UFUNCTION(BlueprintCallable, Category="DTFlux|Tracked Requests")
bool GetTrackedRequest(const FGuid& RequestId, FDTFluxQueuedRequest& OutRequest) const; bool GetTrackedRequest(const FGuid& RequestId, FDTFluxQueuedRequest& OutRequest) const;
@ -192,28 +192,30 @@ private:
// === MÉTHODES DE CONFIGURATION === // === MÉTHODES DE CONFIGURATION ===
UFUNCTION() UFUNCTION()
void WsSettingsChanged(const FDTFluxWsSettings& NewWsSettings); void WsSettingsChanged(const FDTFluxWsSettings& NewWsSettings);
void ReconnectWs(const FName WsClientId);
UFUNCTION() UFUNCTION()
void HttpSettingsChanged(const FDTFluxHttpSettings& NewHttpSettings); void HttpSettingsChanged(const FDTFluxHttpSettings& NewHttpSettings);
void ReconnectWs(const FName WsClientId);
void ReconnectHttp(const FName WsClientId); void ReconnectHttp(const FName WsClientId);
// === GESTION DES ÉVÉNEMENTS HTTP ===
void RegisterHttpEvents();
void UnregisterHttpEvents();
// === GESTION DES ÉVÉNEMENTS WEBSOCKET === // === GESTION DES ÉVÉNEMENTS WEBSOCKET ===
void RegisterWebSocketEvents(); void RegisterWebSocketEvents();
void UnregisterWebSocketEvents(); void UnregisterWebSocketEvents();
void OnWebSocketConnected_Subsystem(); void OnWebSocketConnected_Subsystem();
void OnWebSocketConnectionError_Subsystem(const FString& Error); void OnWebSocketConnectionError_Subsystem(const FString& Error);
void OnWebSocketClosedEvent_Subsystem(int32 StatusCode, const FString& Reason, bool bWasClean); void OnWebSocketClosedEvent_Subsystem(int32 StatusCode, const FString& Reason, bool bWasClean);
void OnWebSocketMessageEvent_Subsystem(const FString& MessageString);
void OnWebSocketMessageSentEvent_Subsystem(const FString& MessageSent);
FDelegateHandle OnWsConnectedEventDelegateHandle; FDelegateHandle OnWsConnectedEventDelegateHandle;
FDelegateHandle OnWsConnectionErrorEventDelegateHandle; FDelegateHandle OnWsConnectionErrorEventDelegateHandle;
FDelegateHandle OnWsClosedEventDelegateHandle; FDelegateHandle OnWsClosedEventDelegateHandle;
FDelegateHandle OnWsMessageEventDelegateHandle; FDelegateHandle OnWsMessageEventDelegateHandle;
FDelegateHandle OnWsMessageSentEventDelegateHandle; FDelegateHandle OnWsMessageSentEventDelegateHandle;
// === GESTION DES ÉVÉNEMENTS HTTP ===
void RegisterHttpEvents();
void UnregisterHttpEvents();
// === PARSING DES RÉPONSES === // === PARSING DES RÉPONSES ===
void ParseTeamListResponse(FDTFluxServerResponse& ServerResponse); void ParseTeamListResponse(FDTFluxServerResponse& ServerResponse);
@ -224,10 +226,9 @@ private:
void ParseStatusUpdateResponse(FDTFluxServerResponse& Response); void ParseStatusUpdateResponse(FDTFluxServerResponse& Response);
void ParseSplitSensorResponse(FDTFluxServerResponse& Response); void ParseSplitSensorResponse(FDTFluxServerResponse& Response);
EDTFluxResponseStatus ProcessPushMessage(FDTFluxServerResponse& Response); EDTFluxResponseStatus ProcessPushMessage(FDTFluxServerResponse& Response);
void Parse(FDTFluxServerResponse& Response); void Parse(FDTFluxServerResponse& Response);
void OnWebSocketMessageEvent_Subsystem(const FString& MessageString);
void OnWebSocketMessageSentEvent_Subsystem(const FString& MessageSent);
bool CleanRequestCallbacks(const FGuid& RequestId); bool CleanRequestCallbacks(const FGuid& RequestId);
// === GESTION DES REQUÊTES TRACKÉES === // === GESTION DES REQUÊTES TRACKÉES ===