Adds Custom DataAsset UI + Added Request buttons for RaceDatas/TeamList/Rankings request to ApiStatus Tab + Addes Tracked Requests For Rankings + Added Utils Module For Blueprint Utilities Functions

This commit is contained in:
2025-07-08 16:50:31 +02:00
parent 7e1ce2cdfa
commit b63f2dd7b5
40 changed files with 4027 additions and 1199 deletions

View File

@ -0,0 +1,166 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Containers/Queue.h"
#include "Tickable.h"
#include "Struct/DTFluxRequestStructs.h"
#include "Struct/DTFluxServerResponseStruct.h"
#include "Types/Enum/DTFluxCoreEnum.h"
#include "DTFluxQueuedManager.generated.h"
/**
* @brief Structure représentant une requête en file d'attente avec ses métadonnées
*/
USTRUCT(BlueprintType)
struct FDTFluxQueuedRequest : public FDTFluxRequestBase
{
GENERATED_BODY()
/** L'identifiant unique de la requête */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
FGuid RequestId;
/** L'heure à laquelle la requête a été envoyée */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
FDateTime CreatedAt;
/** Le type de requête */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
EDTFluxApiDataType RequestType = EDTFluxRequestType::None;
/** Identifiant de la compétition (ContestId) */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
int32 ContestId = -1;
/** Identifiant de l'étape (StageId) */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
int32 StageId = -1;
/** Identifiant du split (SplitId) */
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
int32 SplitId = -1;
UPROPERTY(BlueprintReadOnly, Category = "DTFlux|Request")
FString RawResponse = "";
/** Délai maximum avant que la requête soit considérée comme expirée (en secondes) */
UPROPERTY(BlueprintReadWrite, Category = "DTFlux|Request")
float TimeoutSeconds = 2.0f;
/** Determine si la requête peut être mise en cache */
UPROPERTY(BlueprintReadWrite, Category = "DTFlux|Request")
bool bIsCacheable = false;
/** Validité du cache si bIsCacheable est mis à true après reception de la réponse (en secondes) */
UPROPERTY(BlueprintReadWrite, Category = "DTFlux|Request")
float CachedValidity = 50.0f;
/** Indicateur si la requête a reçu une réponse */
UPROPERTY(BlueprintReadWrite, Category = "DTFlux|Request")
bool bHasReceivedResponse = false;
/** Constructeur par défaut */
FDTFluxQueuedRequest()
{
RequestId = FGuid::NewGuid();
CreatedAt = FDateTime::Now();
}
/** Constructeur avec paramètres */
FDTFluxQueuedRequest(EDTFluxRequestType InRequestType, int32 InContestId = -1, int32 InStageId = -1,
int32 InSplitId = -1)
: RequestType(InRequestType)
, ContestId(InContestId)
, StageId(InStageId)
, SplitId(InSplitId)
{
RequestId = FGuid::NewGuid();
CreatedAt = FDateTime::Now();
}
bool operator==(const FDTFluxQueuedRequest& Left) const
{
return RequestId == Left.RequestId;
}
bool operator!=(const FDTFluxQueuedRequest& Left) const
{
return RequestId != Left.RequestId;
}
const FString Serialize() const;
/** Vérifie si la requête a expiré */
bool HasTimedOut() const
{
return (FDateTime::Now() - CreatedAt).GetTotalSeconds() > TimeoutSeconds;
}
/** Vérifie si cette requête correspond aux paramètres spécifiés */
bool Matches(EDTFluxRequestType InRequestType, int32 InContestId = -1, int32 InStageId = -1,
int32 InSplitId = -1) const
{
return RequestType == InRequestType &&
(InContestId == -1 || ContestId == InContestId) &&
(InStageId == -1 || StageId == InStageId) &&
(InSplitId == -1 || SplitId == InSplitId);
}
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestTimedOut, const FDTFluxQueuedRequest&, TimedOutRequest);
/**
* @brief Classe Tickable gérant les requêtes WebSockets qui ne sont pas traçables nativement par l'API.
* Cette classe utilise TQueue pour gérer efficacement les requêtes en attente et vérifie leur état dans le tick.
*/
UCLASS()
class DTFLUXNETWORK_API UDTFluxQueuedManager : public UObject, public FTickableGameObject
{
GENERATED_BODY()
public:
/** Constructeur par défaut */
UDTFluxQueuedManager();
virtual ~UDTFluxQueuedManager() override;
void Initialize();
FGuid QueueRequest(EDTFluxRequestType RequestType, int32 ContestId = -1, int32 StageId = -1, int32 SplitId = -1,
const FString& RawMessage = "");
bool MarkRequestAsResponded(const FGuid& TargetRequestGuid);
bool MarkRequestAsResponded(const FDTFluxQueuedRequest& TargetRequest);
bool IsRequestPending(EDTFluxRequestType RequestType, int32 ContestId = -1, int32 StageId = -1, int32 SplitId = -1);
FDTFluxQueuedRequest* GetRequestPending(EDTFluxRequestType RequestType, int32 ContestId = -1, int32 StageId = -1,
int32 SplitId = -1);
const FDTFluxQueuedRequest* GetRequest(const FGuid& SearchedGuid);
int32 GetPendingRequestCount();
int32 CleanupTimedOutRequests();
int32 CleanCashedRequests();
void ClearAllRequests();
// bool TryProcessResponse(const FDTFluxServerResponse& Response);
// Interface FTickableGameObject
virtual void Tick(float DeltaTime) override;
virtual bool IsTickable() const override;
virtual TStatId GetStatId() const override;
virtual bool IsTickableWhenPaused() const override { return true; }
virtual bool IsTickableInEditor() const override { return true; }
// Interface ~FTickableGameObject
UPROPERTY(BlueprintAssignable, Category = "DTFlux|Network")
FOnRequestTimedOut OnRequestTimedOut;
private:
TQueue<FDTFluxQueuedRequest, EQueueMode::Mpsc> PendingRequestsQueue;
TQueue<FDTFluxQueuedRequest, EQueueMode::Mpsc> CompletedRequestsQueue;
TQueue<FDTFluxQueuedRequest, EQueueMode::Mpsc> TimedOutRequestsQueue;
bool bIsInitialized;
float CheckInterval;
float TimeSinceLastCheck;
};