Adding Status and Last server response handled but not tested

This commit is contained in:
2025-07-03 17:28:51 +02:00
parent 2855fa1e98
commit fa5493adcf
43 changed files with 2035 additions and 379 deletions

View File

@ -9,7 +9,7 @@ public class DTFluxCore : ModuleRules
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core","JsonUtilities"
"Core",
}
);
@ -21,6 +21,7 @@ public class DTFluxCore : ModuleRules
"Slate",
"SlateCore",
"JsonUtilities",
"OutputLog",
"Json",
}

View File

@ -36,18 +36,20 @@ void UDTFluxModelAsset::AddPerson(const FDTFluxPerson& InPerson)
void UDTFluxModelAsset::AddParticipant(const FDTFluxParticipant& InParticipant, const int ContestId)
{
UE_LOG(logDTFluxCore, Error, TEXT("%i Person in Participant %i"), InParticipant.GetTeammateNum(), InParticipant.Bib);
FDTFluxContest TargetContest;
if(GetContestById(ContestId, TargetContest))
{
if(!PersonExists(InParticipant.Person1))
TArray<FDTFluxPerson> Teammate = InParticipant.Teammate;
for(auto& Person : InParticipant.Teammate)
{
AddPerson(InParticipant.Person1);
}
if(InParticipant.Person2 != 0)
{
if(!PersonExists(InParticipant.Person2))
UE_LOG(logDTFluxCore, Error, TEXT("AddParticipant() DTFlux Person %s %s %s"),
*Person.FirstName, *Person.LastName, *Person.Gender);
if(!PersonExists(Person))
{
AddPerson(InParticipant.Person2);
UE_LOG(logDTFluxCore, Error, TEXT("AddParticipant() DTFlux Person %s %s %s doesnot exists, adding..."),
*Person.FirstName, *Person.LastName, *Person.Gender);
AddPerson(Person);
}
}
Participants.Add(InParticipant.Bib, InParticipant);
@ -79,30 +81,24 @@ void UDTFluxModelAsset::AddContestRanking(const FDTFluxContestRankings& NewConte
ContestRankings.Add(NewContestRankings.ContestId, NewContestRankings);
}
bool UDTFluxModelAsset::UpdateStageRanking(const FDTFluxStageRankings& InStageRankings)
void UDTFluxModelAsset::UpdateOrCreateStageRanking(const FDTFluxStageRankings& InStageRankings)
{
const int ContestId = InStageRankings.ContestId;
const int StageId = InStageRankings.StageId;
int Index = 0;
int StageRankingArraySize = StageRankings.Num()-1;
for(auto Ranking : StageRankings)
{
if(Ranking.ContestId == ContestId && Ranking.StageId == StageId)
{
Index++;
break;
}
Index++;
}
if(Index != StageRankingArraySize )
{
StageRankings[Index] = InStageRankings;
return true;
}
return false;
FDTFluxStageKey StageKey = InStageRankings.GetCompositeKey();
StageRankings.FindOrAdd(StageKey) = InStageRankings;
}
bool UDTFluxModelAsset::UpdateSplitRanking(const FDTFluxStageRankings& InStageRankings)
void UDTFluxModelAsset::AddStageRanking(const FDTFluxStageRankings& InStageRankings)
{
return true;
StageRankings.Add(InStageRankings.GetCompositeKey(), InStageRankings);
}
void UDTFluxModelAsset::AddSplitRanking(const FDTFluxSplitRankings& InSplitRanking)
{
SplitRankings.Add(InSplitRanking.GetCompositeKey(), InSplitRanking);
}
void UDTFluxModelAsset::UpdateOrCreateSplitRanking(const FDTFluxSplitRankings& InSplitRankings)
{
FDTFluxSplitKey SplitKey = InSplitRankings.GetCompositeKey();
SplitRankings.FindOrAdd(SplitKey) = InSplitRankings;
}

View File

@ -0,0 +1,43 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Types/Objects/DTFluxPursuitManager.h"
void UDTFluxPursuitManager::InitForStage(const FDTFluxStageRankings& StageRankings)
{
}
TArray<FDTFluxPursuit> UDTFluxPursuitManager::GetNextPursuits(int MaxPursuit)
{
//TODO : Implement me !!!
return PursuitParticipants;
}
TArray<FDTFluxPursuit> UDTFluxPursuitManager::GetPursuits(int FromIndex, int MaxPursuit)
{
//TODO : Implement me !!!
return PursuitParticipants;
}
FDateTime UDTFluxPursuitManager::GetMassStart()
{
//TODO : Implement me !!!
return MassStart;
}
FText UDTFluxPursuitManager::GetFormattedName(FDTFluxPursuit& InPursuit, const int MaxChar,
const FString OverflowChar)
{
return InPursuit.GetFormattedName(MaxChar, OverflowChar);
}
FText UDTFluxPursuitManager::DisplayPursuit(FDTFluxPursuit& InPursuit, const int MaxWidth,
const FString NameOverflowChar)
{
return InPursuit.DisplayPursuit(MaxWidth, NameOverflowChar);
}
bool UDTFluxPursuitManager::IsUnique(const FDTFluxPursuit& InPursuit)
{
return InPursuit.IsUnique();
}

View File

@ -0,0 +1,25 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Types/Objects/UDTFluxParticipantFactory.h"
bool UDTFluxParticipantFactory::CreateParticipantFomJson(const FString& JsonString, FDTFluxParticipant& OutParticipant)
{
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
{
return UDTFluxParticipantFactory::CreateFromJsonCpp(JsonObject, OutParticipant);
}
else
{
OutParticipant = FDTFluxParticipant();
return false;
}
}
bool UDTFluxParticipantFactory::CreateFromJsonCpp(const TSharedPtr<FJsonObject> JsonObject, FDTFluxParticipant& OutParticipant)
{
OutParticipant = FDTFluxParticipant::CreateFromJson(JsonObject);
return OutParticipant == 0;
}

View File

@ -0,0 +1,4 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Types/Struct/DTFluxCompositeKey.h"

View File

@ -0,0 +1,30 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Types/Struct/DTFluxPursuitStructs.h"
FDTFluxPursuit::FDTFluxPursuit()
{
}
FDTFluxPursuit::~FDTFluxPursuit()
{
}
FText FDTFluxPursuit::GetFormattedName(const int MaxChar, const FString OverflowChar)
{
//TODO: Implement Me !!!
return Participants[0].GetConcatFormattedName(MaxChar, OverflowChar);
}
FText FDTFluxPursuit::DisplayPursuit(const int MaxWidth, const FString NameOverflowChar)
{
//TODO: Implement Me !!!
return Participants[0].GetConcatFormattedName(MaxWidth, NameOverflowChar);
}
bool FDTFluxPursuit::IsUnique() const
{
return Participants.Num() == 1;
}

View File

@ -10,13 +10,13 @@ void FDTFluxContestRanking::Dump() const
Rank, Bib, *Gap, *Time );
};
void FDTFluxStageRanking::Dump() const
{
UE_LOG(logDTFluxCore, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
Rank, Bib, *Gap, *TimeSwim,
*TimeTransition, *TimeRun, *StartTime.ToString());
}
// void FDTFluxStageRanking::Dump() const
// {
// UE_LOG(logDTFluxCore, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
// Rank, Bib, *Gap, *TimeSwim,
// *TimeTransition, *TimeRun, *StartTime.ToString());
// }
//

View File

@ -0,0 +1,4 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Types/Struct/DTFluxSplitSensor.h"

View File

@ -4,104 +4,150 @@
#include "Types/Struct/DTFluxTeamListStruct.h"
bool FDTFluxParticipant::IsTeam() const
void FDTFluxParticipant::AddTeammate(const FDTFluxPerson& Person)
{
return Person2.FirstName.IsEmpty() && Person2.LastName.IsEmpty();
Teammate.Add(Person);
}
void FDTFluxParticipant::Dump() const
void FDTFluxParticipant::AddTeammate(const FString LastName, const FString FirstName, const FString Gender)
{
FString EliteStr = "NO";
if(Elite)
}
FText FDTFluxParticipant::GetFormattedName(const int MaxChar, const FString OverflowChars)
{
// Vérifie les cas limites
if (MaxChar <= 0)
{
EliteStr = "YES";
return FText::GetEmpty();
}
UE_LOG(logDTFluxCore, Log, TEXT("PARTICIPANT with bib: %03d"), Bib);
UE_LOG(logDTFluxCore, Log, TEXT("Fullname : %s %s"), *Person1.FirstName, *Person1.LastName);
FString FirstName;
FString LastName;
if(IsTeam())
{
UE_LOG(logDTFluxCore, Log, TEXT("Teamate : %s %s"), *Person2.FirstName, *Person2.LastName);
UE_LOG(logDTFluxCore, Log, TEXT("Team name : %s"), *Team);
LastName = Team;
}
UE_LOG(logDTFluxCore, Log, TEXT("Club : %s, Category : %s, IsElite : %s, Status : %s"),
*Club, *Category, *EliteStr, *UEnum::GetValueAsString(Status));
// Récupère la première lettre du prénom en majuscule
FString Initial;
if (!FirstName.IsEmpty())
{
Initial = FirstName.Left(1).ToUpper() + " ";
}
// Nom complet en majuscules
FString FormattedLastName = LastName.ToUpper();
// Construction du nom final
FString FullName = Initial + FormattedLastName;
// Tronque si nécessaire
if (FullName.Len() > MaxChar)
{
// On essaie de garder autant de caractères que possible
const int32 AvailableLength = MaxChar - Initial.Len();
if (AvailableLength <= 0)
{
// Pas assez de place pour le nom → juste l'initiale ?
return FText::FromString(Initial);
}
// Coupe le nom pour quil rentre dans la limite
const int32 TruncateLength = FMath::Min(AvailableLength, FormattedLastName.Len());
FullName = Initial + FormattedLastName.Left(TruncateLength);
// Si on a coupé trop court, on ajoute le suffixe
if (FormattedLastName.Len() > TruncateLength)
{
// On vérifie qu'il reste de la place pour le suffixe
const int32 CurrentLength = FullName.Len();
const int32 OverflowLength = OverflowChars.Len();
if (CurrentLength + OverflowLength <= MaxChar)
{
FullName += OverflowChars;
}
else
{
// Il faut tronquer davantage pour faire de la place au suffixe
const int32 RemainingSpace = MaxChar - CurrentLength;
if (RemainingSpace > 0)
{
FullName = FullName.Left(MaxChar - OverflowLength) + OverflowChars;
}
else
{
FullName = FullName.Left(MaxChar);
}
}
}
}
return FText::FromString(FullName);
}
FString FDTFluxParticipant::GetParticipantFormatedName(bool Truncate, int MaxSize) const
FText FDTFluxParticipant::GetConcatFormattedName(const int MaxChar, const FString OverflowChar)
{
FString ParticipantName;
if(Truncate)
{
if(IsTeam())
{
//Concatenate the team name;
if(Team.Len() > MaxSize - 3)
{
return Team.Left(MaxSize - 3).Append(TEXT("..."));
}
return Team;
}
if(Person1.FirstName.Contains("-") )
{
FString Formated = "";
//Compound Firstname
TArray<FString> Out;
Person1.FirstName.ParseIntoArray(Out,TEXT("-"),true);
for(const auto& Str : Out)
{
Formated.Append(Str.Left(1).ToUpper()).Append(".");
}
// TODO : Camel Case handling for LastName
Formated.Append(" ").Append(*Person1.LastName);
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is with space compound. Formated Name %s length %02d MAX Size : %02d"),
*Formated, Formated.Len(), MaxSize);
if(Formated.Len() >= MaxSize)
{
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
FString BibText = FString::FromInt(Bib) + " ";
FText FormattedName = GetFormattedName(MaxChar - BibText.Len(), OverflowChar );
return FText::FromString(BibText + FormattedName.ToString());
}
return Formated.Left(MaxSize - 3).Append("...");
}
return Formated;
}
if(Person1.FirstName.Contains(" "))
{
FString Formated = "";
//Compound Firstname
TArray<FString> Out;
Person1.FirstName.ParseIntoArray(Out,TEXT(" "),true);
for(const auto& Str : Out)
{
Formated.Append(Str.Left(1).ToUpper()).Append(".");
}
// TODO : Camel Case handling for LastName
Formated.Append(" ").Append(*Person1.LastName);
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is with space compound. Formated Name %s length %02d MAX Size : %02d"),
*Formated, Formated.Len(), MaxSize);
if(Formated.Len() >= MaxSize)
{
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
return Formated.Left(MaxSize - 3).Append("...");
}
return Formated;
}
FString Formated = Person1.FirstName.Left(1).Append(". ");
Formated.Append(Person1.LastName);
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is not compound. Formated Name %s length %02d MAX Size : %02d"),
*Formated, Formated.Len(), MaxSize);
if(Formated.Len() >= MaxSize)
{
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
return Formated.Left(MaxSize - 3).Append("...");
}
return Formated;
}
else
// Constructeur privé depuis JSON
FDTFluxParticipant::FDTFluxParticipant(const TSharedPtr<FJsonObject>& JsonObject)
: Bib(JsonObject->GetIntegerField(TEXT("bib")))
, ContestId(JsonObject->GetIntegerField(TEXT("contestId")))
, Category(JsonObject->GetStringField(TEXT("category")))
, Club(JsonObject->GetStringField(TEXT("club")))
, Elite(JsonObject->GetBoolField(TEXT("elite")))
, Status(static_cast<EDTFluxParticipantStatusType>(JsonObject->GetIntegerField(TEXT("status"))))
, Team(JsonObject->GetStringField(TEXT("team")))
, bIsMassStartParticipant(false)
, LastSplitId(-1)
{
UE_LOG(logDTFluxCore, Error, TEXT("Ctor with JSON Object"))
for(uint8 Index = 1; ; Index++)
{
FString FirstNameKey = Index == 1 ? "firstName" : FString::Printf(TEXT("firstName%i"), Index);
FString LastNameKey = Index == 1 ? "lastName" : FString::Printf(TEXT("lastName%i"), Index);
FString GenderKey = Index == 1 ? "gender" : FString::Printf(TEXT("gender%i"), Index);
// max 10 Persons
if(Index >= 10)
{
if(!IsTeam())
{
return FString::Printf(TEXT("%s %s"), *Person1.FirstName, *Person2.LastName);
}
return Team;
break;
}
if (!JsonObject->HasField(FirstNameKey) && !JsonObject->HasField(LastNameKey)
&& !JsonObject->HasField(GenderKey))
{
UE_LOG(logDTFluxCore, Error, TEXT("No Corresponding Field!!!"))
break;
}
const FString FirstName = JsonObject->GetStringField(FirstNameKey);
const FString LastName = JsonObject->GetStringField(LastNameKey);
const FString Gender = JsonObject->GetStringField(GenderKey);
if (FirstName.IsEmpty() && LastName.IsEmpty())
continue;
FDTFluxPerson Person;
Person.FirstName = FirstName;
Person.LastName = LastName;
Person.Gender = Gender;
Teammate.Add(Person);
}
UE_LOG(logDTFluxCore, Error, TEXT("Ctor with JSON Object Teammate is now %i long"), Teammate.Num());
}
FDTFluxParticipant FDTFluxParticipant::CreateFromJson(const TSharedPtr<FJsonObject>& JsonObject)
{
return FDTFluxParticipant(JsonObject);
}
int FDTFluxParticipant::GetTeammateNum() const
{
return Teammate.Num();
}
bool FDTFluxParticipant::IsTeam()
{
return Teammate.Num() < 1;
}

View File

@ -5,6 +5,7 @@
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Dom/JsonObject.h"
#include "Types/Struct/DTFluxCompositeKey.h"
#include "Types/Struct/DTFluxRaceDataStructs.h"
#include "DTFluxModelAsset.generated.h"
@ -37,10 +38,10 @@ public:
TMap<int /*ContestId*/, FDTFluxContestRankings> ContestRankings;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
TArray<FDTFluxStageRankings> StageRankings;
TMap<FDTFluxStageKey, FDTFluxStageRankings> StageRankings;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
TArray<FDTFluxStageRankings> SplitRankings;
TMap<FDTFluxSplitKey, FDTFluxSplitRankings> SplitRankings;
UFUNCTION(BlueprintCallable, CallInEditor, Category="DTFlux|ModelAsset")
void AddContest(const FDTFluxContest &Contest);
@ -60,11 +61,17 @@ public:
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
FString GetContestNameForId(const int InContestID);
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
bool UpdateStageRanking(const FDTFluxStageRankings& InStageRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Stage")
void UpdateOrCreateStageRanking(const FDTFluxStageRankings& InStageRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
bool UpdateSplitRanking(const FDTFluxStageRankings& InStageRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Stage")
void AddStageRanking(const FDTFluxStageRankings& InStageRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Split")
void UpdateOrCreateSplitRanking(const FDTFluxSplitRankings& InSplitRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Split")
void AddSplitRanking(const FDTFluxSplitRankings& InSplitRanking);
UFUNCTION()
void AddContestRanking(const FDTFluxContestRankings& NewContestRankings);

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "DTFluxCoreEnum.generated.h"
UENUM(BlueprintType)
@ -22,5 +23,7 @@ enum class EDTFluxConnectionStatus : uint8
{
Unset = 0 UMETA(DisplayName="Unset"),
Connected = 1 << 0 UMETA(DisplayName="Connected"),
Error = 2 << 1 UMETA(DisplayName="Error")
Error = 1 << 1 UMETA(DisplayName="Error"),
Closed = 1 << 2 UMETA(DisplayName="Closed"),
NotConnected= 1 << 3 UMETA(DisplayName="NotConnected")
};

View File

@ -11,12 +11,13 @@
UENUM(BlueprintType, Category="DTFlux|Model")
enum class EDTFluxParticipantStatusType : uint8
{
Normal = 0 UMETA(DisplayName="Normal"),
OutOfRace = 1 UMETA(DisplayName="HorsCourse"),
DSQ = 2 UMETA(DisplayName="Disqualifié"),
DNF = 3 UMETA(DisplayName="Abandon"),
DNS = 4 UMETA(DisplayName="NonPartant"),
NotLinedUp = 5 UMETA(DisplayName="NonPresentAuDépart"),
Normal = 0 UMETA(DisplayName="Normal"),
OutOfRace = 1 UMETA(DisplayName="HorsCourse"),
DSQ = 2 UMETA(DisplayName="Disqualifié"),
DNF = 3 UMETA(DisplayName="Abandon"),
DNS = 4 UMETA(DisplayName="NonPartant"),
NotLinedUp = 5 UMETA(DisplayName="NonPresentAuDépart"),
Unknown = 1 << 4 UMETA(DisplayName="Unknown")
};

View File

@ -0,0 +1,63 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Types/Struct/DTFluxPursuitStructs.h"
#include "Types/Struct/DTFluxRankingStructs.h"
#include "UObject/Object.h"
#include "DTFluxPursuitManager.generated.h"
/**
*
*/
UCLASS(BlueprintType)
class DTFLUXCORE_API UDTFluxPursuitManager : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"), Transient)
TArray<FDTFluxPursuit> PursuitParticipants;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
FDateTime MassStart;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
int ContestId;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
int StageId;
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
void InitForStage(const FDTFluxStageRankings& StageRankings);
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
TArray<FDTFluxPursuit> GetNextPursuits(int MaxPursuit);
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
TArray<FDTFluxPursuit> GetPursuits(int FromIndex = 0, int MaxPursuit=10);
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
FDateTime GetMassStart();
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
static FText GetFormattedName(FDTFluxPursuit& InPursuit, const int MaxChar = 10, const FString OverflowChar = FString(TEXT("...")));
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
static FText DisplayPursuit(FDTFluxPursuit& InPursuit, const int MaxWidth = 14, const FString NameOverflowChar = FString(TEXT("...")));
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
static bool IsUnique(const FDTFluxPursuit& InPursuit);
protected:
private:
UPROPERTY(VisibleAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
int CurrentIndex;
};

View File

@ -0,0 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Types/Struct/DTFluxTeamListStruct.h"
#include "UDTFluxParticipantFactory.generated.h"
/**
*
*/
UCLASS()
class DTFLUXCORE_API UDTFluxParticipantFactory : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="DTFlux|Factory")
static bool CreateParticipantFomJson(const FString& JsonString, FDTFluxParticipant& OutParticipant );
static bool CreateFromJsonCpp(const TSharedPtr<FJsonObject> JsonObject, FDTFluxParticipant& OutParticipant);
};

View File

@ -0,0 +1,100 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "DTFluxCompositeKey.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct DTFLUXCORE_API FDTFluxStageKey
{
GENERATED_BODY()
FDTFluxStageKey() = default;
FDTFluxStageKey(const int InContestId, const int InStageId )
:ContestId(InContestId)
, StageId(InStageId){};
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
int ContestId = -1;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
int StageId = -1;
friend uint32 GetTypeHash(const FDTFluxStageKey& Key)
{
return HashCombine(
GetTypeHash(Key.ContestId),
GetTypeHash(Key.StageId)
);
}
bool operator==(const FDTFluxStageKey& Other) const
{
return ContestId == Other.ContestId && StageId == Other.StageId;
}
FString GetDisplayName() const
{
return FString::Printf(TEXT("Contest%i -| Stage%i"), ContestId, StageId);
}
FText GetTooltipText() const
{
return FText::Format(INVTEXT("Contest{0}|Stage{1}"),
FText::AsNumber(ContestId),
FText::AsNumber(StageId));
}
};
/**
*
*/
USTRUCT(BlueprintType)
struct DTFLUXCORE_API FDTFluxSplitKey
{
GENERATED_BODY()
FDTFluxSplitKey() = default;
FDTFluxSplitKey(const int InContestId, const int InStageId, const int InSplitId )
:ContestId(InContestId)
, StageId(InStageId)
, SplitId(InSplitId){};
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
int ContestId = -1;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
int StageId = -1;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
int SplitId = -1;
friend uint32 GetTypeHash(const FDTFluxSplitKey& Key)
{
return HashCombine(
GetTypeHash(Key.ContestId),
GetTypeHash(Key.StageId),
GetTypeHash(Key.SplitId)
);
}
bool operator==(const FDTFluxSplitKey& Other) const
{
return ContestId == Other.ContestId && StageId == Other.StageId && SplitId == Other.SplitId;
}
FString GetDisplayName() const
{
return FString::Printf(TEXT("Contest%i | Stage%i | Split%i"), ContestId, StageId, SplitId);
}
FText GetTooltipText() const
{
return FText::Format(INVTEXT("Contest{0}|Stage{1}|Split{2}"),
FText::AsNumber(ContestId),
FText::AsNumber(StageId),
FText::AsNumber(SplitId)
);
}
};

View File

@ -0,0 +1,38 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "DTFluxTeamListStruct.h"
#include "DTFluxPursuitStructs.generated.h"
/**
*
*/
USTRUCT(BlueprintType, Blueprintable)
struct DTFLUXCORE_API FDTFluxPursuit
{
GENERATED_BODY()
public:
FDTFluxPursuit();
FDTFluxPursuit(const TArray<FDTFluxParticipant>& InParticipants) : Participants(InParticipants){};
~FDTFluxPursuit();
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
TArray<FDTFluxParticipant> Participants;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
FDateTime StartTime;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
int IndexMultiple = 0;
FText GetFormattedName(const int MaxChar = 15, const FString OverflowChar = FString(TEXT("...")));
FText DisplayPursuit(const int MaxWidth = 20, const FString NameOverflowChar = FString(TEXT("...")));
bool IsUnique() const;
};

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "DTFluxCompositeKey.h"
#include "UObject/Object.h"
#include "DTFluxRankingStructs.generated.h"
@ -58,7 +59,7 @@ public:
* Representing a stage ranking for a participant
*/
USTRUCT(BlueprintType, Category="DTFlux|Model")
struct DTFLUXCORE_API FDTFluxStageRanking
struct DTFLUXCORE_API FDTFluxDetailedRankingItem
{
GENERATED_BODY()
public:
@ -91,19 +92,76 @@ public:
};
USTRUCT(BlueprintType)
struct FDTFluxStageRankings
struct FDTFluxDetailedRankings
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
TArray<FDTFluxStageRanking> Rankings;
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
int ContestId;
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
int StageId;
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
int SplitId;
TArray<FDTFluxDetailedRankingItem> Rankings;
};
/**
* @struct FDTFluxStageRanking
* Representing a stage ranking for a participant
* This struct is only a cosmetic Struct
*/
USTRUCT(BlueprintType)
struct FDTFluxStageRanking : public FDTFluxDetailedRankingItem
{
GENERATED_BODY()
};
/**
* @struct FDTFluxSplitRanking
* Representing a split ranking for a participant
* This struct is only a cosmetic Struct
*/
USTRUCT(BlueprintType, Category="DTFlux|Model")
struct DTFLUXCORE_API FDTFluxSplitRanking : public FDTFluxStageRanking
{
GENERATED_BODY()
};
/**
* @struct FDTFluxStageRankings
* StageRanking Container Struct
*/
USTRUCT(BlueprintType)
struct FDTFluxStageRankings : public FDTFluxDetailedRankings
{
GENERATED_BODY()
inline FDTFluxStageKey GetKeyFrom(const FDTFluxStageRankings& InRankings)
{
return FDTFluxStageKey(InRankings.ContestId, InRankings.StageId);
}
inline FDTFluxStageKey GetCompositeKey() const
{
return FDTFluxStageKey(ContestId, StageId);
}
};
USTRUCT(BlueprintType)
struct FDTFluxSplitRankings : public FDTFluxDetailedRankings
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
int SplitId;
inline static FDTFluxSplitKey GetKeyFrom(const FDTFluxSplitRankings& InRankings)
{
return FDTFluxSplitKey(InRankings.ContestId, InRankings.StageId, InRankings.SplitId);
}
inline FDTFluxSplitKey GetCompositeKey() const
{
return FDTFluxSplitKey(ContestId, StageId, SplitId);
}
};

View File

@ -0,0 +1,37 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "DTFluxTeamListStruct.h"
#include "UObject/Object.h"
#include "DTFluxSplitSensor.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct FDTFluxSplitSensorInfo
{
GENERATED_BODY()
public:
FDTFluxSplitSensorInfo() = default;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int Bib = -1;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int ContestId = -1;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int StageId = -1;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int SplitId = -1;
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
FString Time = "";
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
FString Gap = "-";
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int Rank;
};

View File

@ -43,20 +43,7 @@ public:
FString Club;
};
/**
* @struct FDTFluxTeamListDefinition
* Struct representing the Participant List definition
* Used to exchange data between Objects in the system
*/
USTRUCT(BlueprintType)
struct DTFLUXCORE_API FDTFluxTeamListDefinition
{
GENERATED_BODY()
public:
UPROPERTY()
// ReSharper disable once IdentifierTypo
TArray<FDTFluxTeamListItemDefinition> Datas;
};
@ -101,14 +88,36 @@ USTRUCT(BlueprintType, Category="DTFlux|Model")
struct DTFLUXCORE_API FDTFluxParticipant
{
GENERATED_BODY()
friend class UDTFluxModelAsset;
friend class UDTFluxParticipantFactory;
public:
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
int Bib = -1;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
FDTFluxPerson Person1;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
FDTFluxPerson Person2;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
// Constructeur public par défaut requis par Unreal
FDTFluxParticipant()
: Bib(-1)
,ContestId(-1)
, Elite(false)
, Status(static_cast<EDTFluxParticipantStatusType>(0))
, bIsMassStartParticipant(false)
, LastSplitId(0)
{
Teammate.Reset();
}
bool operator == ( int Rhs) const
{
return Rhs == 0 && Bib == -1 && Team.IsEmpty() && Club.IsEmpty() && ContestId == -1
&& Teammate.IsEmpty();
}
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
int Bib = -1;
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
int ContestId = -1;
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
FString Category;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
FString Club;
@ -121,9 +130,58 @@ public:
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
bool bIsMassStartParticipant = false;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
int LastSplitId = 0;
bool IsTeam() const;
void Dump() const;
FString GetParticipantFormatedName(bool Truncate = false, int MaxSize = 20) const;
int LastSplitId = -1;
// void Dump() const;
void AddTeammate(const FDTFluxPerson& Person);
void AddTeammate(const FString LastName, const FString FirstName, const FString Gender);
FText GetFormattedName(const int MaxChar = 15, const FString OverflowChar = FString("..."));
FText GetConcatFormattedName(const int MaxChar = 20, const FString OverflowChar = FString("..."));
private:
// --- Constructeur privé ---
explicit FDTFluxParticipant(const TSharedPtr<FJsonObject>& JsonObject);
};
protected:
UPROPERTY(Category="DTFlux|model", VisibleAnywhere)
TArray<FDTFluxPerson> Teammate;
// Méthode publique pour construire à partir d'un JSON (utilisée par la factory)
static FDTFluxParticipant CreateFromJson(const TSharedPtr<FJsonObject>& JsonObject);
int GetTeammateNum() const;
bool IsTeam();
};
/**
* @struct FDTFluxTeamListDefinition
* Struct representing the Participant List definition
* Used to exchange data between Objects in the system
*/
USTRUCT(BlueprintType)
struct DTFLUXCORE_API FDTFluxTeamListDefinition
{
GENERATED_BODY()
public:
UPROPERTY()
// ReSharper disable once IdentifierTypo
TArray<FDTFluxParticipant> Participants;
};
USTRUCT(BlueprintType)
struct FDTFluxTeamStatusUpdate
{
GENERATED_BODY()
public:
FDTFluxTeamStatusUpdate() = default;
FDTFluxTeamStatusUpdate(const int InBib, const int InStatus)
:Bib(InBib)
, Status(static_cast<EDTFluxParticipantStatusType>(InStatus)){};
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Participant")
int Bib = -1;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Participant")
EDTFluxParticipantStatusType Status = EDTFluxParticipantStatusType::Unknown;
};