diff --git a/Source/DTFluxCore/Private/Assets/DTFluxModelAsset.cpp b/Source/DTFluxCore/Private/Assets/DTFluxModelAsset.cpp
index 683c765..7d9a3a0 100644
--- a/Source/DTFluxCore/Private/Assets/DTFluxModelAsset.cpp
+++ b/Source/DTFluxCore/Private/Assets/DTFluxModelAsset.cpp
@@ -13,6 +13,11 @@ UDTFluxModelAsset::UDTFluxModelAsset(const FObjectInitializer& ObjectInitializer
void UDTFluxModelAsset::AddContest(const FDTFluxContest& Contest)
{
Contests.Add(Contest.Name, Contest);
+ // initialisation
+ for (const auto& Stage : Contest.Stages)
+ {
+ FinishedStagesCache.Add(FDTFluxStageKey(Contest.ContestId, Stage.StageId), Stage.IsFinished());
+ }
}
bool UDTFluxModelAsset::GetContestById(const int InContestId, FDTFluxContest& OutContest)
@@ -132,6 +137,32 @@ bool UDTFluxModelAsset::GetParticipantByBib(int Bib, FDTFluxParticipant& OutPart
return false;
}
+bool UDTFluxModelAsset::IsStageFinished(FDTFluxStageKey StageKey)
+{
+ if (!FinishedStagesCache.Contains(StageKey))
+ {
+ if (FinishedStagesCache[StageKey])
+ {
+ return true;
+ }
+ //maybe stage is finished because we have not be able to set it ?
+ return CheckStageIsFinished(StageKey);
+ }
+ return false;
+}
+
+
+bool UDTFluxModelAsset::CheckStageIsFinished(FDTFluxStageKey StageKey)
+{
+ FDTFluxStage Stage;
+ if (GetStage(StageKey, Stage))
+ {
+ FinishedStagesCache.Add(StageKey, Stage.IsFinished());
+ return FinishedStagesCache[StageKey];
+ }
+ return false;
+}
+
void UDTFluxModelAsset::UpdateOrCreateStageRanking(const FDTFluxStageRankings& InStageRankings)
{
diff --git a/Source/DTFluxCore/Private/Types/Struct/DTFluxRaceDataStucts.cpp b/Source/DTFluxCore/Private/Types/Struct/DTFluxRaceDataStucts.cpp
index 70cff33..f799c4d 100644
--- a/Source/DTFluxCore/Private/Types/Struct/DTFluxRaceDataStucts.cpp
+++ b/Source/DTFluxCore/Private/Types/Struct/DTFluxRaceDataStucts.cpp
@@ -2,6 +2,11 @@
#include "Types/Struct/DTFluxRaceDataStructs.h"
+bool FDTFluxStage::IsFinished() const
+{
+ return EndTime <= FDateTime::Now();
+}
+
bool FDTFluxContest::IsFinished() const
{
return EndTime <= FDateTime::Now();
@@ -62,6 +67,3 @@ bool FDTFluxContest::GetStage(const int StageID, FDTFluxStage& OutStage) const
}
return false;
}
-
-
-
diff --git a/Source/DTFluxCore/Private/Types/Struct/DTFluxRankingStructs.cpp b/Source/DTFluxCore/Private/Types/Struct/DTFluxRankingStructs.cpp
index bfe1d5d..e9102cc 100644
--- a/Source/DTFluxCore/Private/Types/Struct/DTFluxRankingStructs.cpp
+++ b/Source/DTFluxCore/Private/Types/Struct/DTFluxRankingStructs.cpp
@@ -3,6 +3,12 @@
#include "Types/Struct/DTFluxRankingStructs.h"
#include "DTFluxCoreModule.h"
+bool FDTFluxBaseRankings::IsSealed(const FDateTime EndTime) const
+
+{
+ return ReceivedAt >= EndTime;
+}
+
void FDTFluxContestRanking::Dump() const
{
UE_LOG(logDTFluxCore, Log,
diff --git a/Source/DTFluxCore/Public/Assets/DTFluxModelAsset.h b/Source/DTFluxCore/Public/Assets/DTFluxModelAsset.h
index 8cac78d..5647017 100644
--- a/Source/DTFluxCore/Public/Assets/DTFluxModelAsset.h
+++ b/Source/DTFluxCore/Public/Assets/DTFluxModelAsset.h
@@ -89,4 +89,13 @@ public:
UFUNCTION(BlueprintCallable, CallInEditor, Category="DTFlux|Participant")
bool GetParticipantByBib(int Bib, FDTFluxParticipant& OutParticipant);
+
+ UFUNCTION()
+ bool IsStageFinished(FDTFluxStageKey StageKey);
+
+private:
+ UPROPERTY()
+ TMap FinishedStagesCache;
+ UFUNCTION()
+ bool CheckStageIsFinished(FDTFluxStageKey StageKey);
};
diff --git a/Source/DTFluxCore/Public/Types/Struct/DTFluxRaceDataStructs.h b/Source/DTFluxCore/Public/Types/Struct/DTFluxRaceDataStructs.h
index c7fd5f4..f3934c4 100644
--- a/Source/DTFluxCore/Public/Types/Struct/DTFluxRaceDataStructs.h
+++ b/Source/DTFluxCore/Public/Types/Struct/DTFluxRaceDataStructs.h
@@ -51,6 +51,7 @@ public:
FDateTime EndTime;
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
FDateTime CutOff;
+ bool IsFinished() const;
};
/**
@@ -98,4 +99,4 @@ public:
UPROPERTY()
// ReSharper disable once IdentifierTypo
TArray Datas;
-};
\ No newline at end of file
+};
diff --git a/Source/DTFluxCore/Public/Types/Struct/DTFluxRankingStructs.h b/Source/DTFluxCore/Public/Types/Struct/DTFluxRankingStructs.h
index 3232676..1d62b34 100644
--- a/Source/DTFluxCore/Public/Types/Struct/DTFluxRankingStructs.h
+++ b/Source/DTFluxCore/Public/Types/Struct/DTFluxRankingStructs.h
@@ -8,6 +8,18 @@
#include "DTFluxRankingStructs.generated.h"
+USTRUCT(BlueprintType)
+struct DTFLUXCORE_API FDTFluxBaseRankings
+{
+ GENERATED_BODY()
+
+public:
+ UPROPERTY(BlueprintReadOnly, Category="DTFlux|Model", VisibleAnywhere)
+ FDateTime ReceivedAt = FDateTime::Now();
+
+ bool IsSealed(const FDateTime EndTime) const;
+};
+
/**
* @struct FDTFluxContestRanking
* Representing a contest ranking for a participant
@@ -37,7 +49,7 @@ public:
USTRUCT(BlueprintType)
-struct FDTFluxContestRankings
+struct FDTFluxContestRankings : public FDTFluxBaseRankings
{
GENERATED_BODY()
@@ -94,7 +106,7 @@ public:
};
USTRUCT(BlueprintType)
-struct FDTFluxDetailedRankings
+struct FDTFluxDetailedRankings : public FDTFluxBaseRankings
{
GENERATED_BODY()
diff --git a/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp b/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp
index 6557b65..8499282 100644
--- a/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp
+++ b/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp
@@ -185,6 +185,46 @@ void UDTFluxCoreSubsystem::RegisterDelegates()
}
}
+bool UDTFluxCoreSubsystem::IsStageRankingSealed(FDTFluxStageKey StageKey)
+{
+ FDTFluxStageRankings StageRankings;
+ if (GetStageRankingsWithKey(StageKey, StageRankings))
+ {
+ FDTFluxStage Stage;
+ if (GetStageDefinition(StageKey, Stage))
+ {
+ return StageRankings.IsSealed(Stage.EndTime);
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find Stage %i"), StageKey.StageId);
+ return false;
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find StageRankings for StageKey %i"), StageKey.StageId);
+ return false;
+}
+
+bool UDTFluxCoreSubsystem::IsContestRankingSealed(int ContestId)
+{
+ if (DataStorage)
+ {
+ FDTFluxContestRankings ContestRankings;
+ if (GetContestRankings(ContestId, ContestRankings))
+ {
+ FDTFluxContest Contest;
+ if (GetContestForId(ContestId, Contest))
+ {
+ return ContestRankings.IsSealed(Contest.EndTime);
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find Contest %i"), ContestId);
+ return false;
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find ContestRankings for ContestId %i"), ContestId);
+ return false;
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
+ return false;
+}
+
+
void UDTFluxCoreSubsystem::ProcessRaceData(const FDTFluxRaceData& RaceDataDefinition)
{
if (RaceDataDefinition.Datas.Num() > 0)
@@ -288,6 +328,138 @@ void UDTFluxCoreSubsystem::SendRequest(const FString& Message)
}
}
+FGuid UDTFluxCoreSubsystem::InitContestRankingsDisplay(const int ContestId)
+{
+ if (NetworkSubsystem)
+ {
+ if (DataStorage)
+ {
+ // no need to request StageRankings;
+ if (IsContestRankingSealed(ContestId))
+ {
+ const FGuid DisplayRequestId = FGuid::NewGuid();
+ OnContestRankingDisplayReady.Broadcast(DisplayRequestId, true);
+ return DisplayRequestId;
+ }
+ else
+ {
+ FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
+ [this](const FDTFluxTrackedRequest& Request)
+ {
+ FDTFluxContestRankings Rankings = FDTFluxContestRankings();
+ if (Request.ParsedResponse.IsSet())
+ {
+ TSharedPtr ResponsePtr = Request.ParsedResponse.GetValue();
+ ResponsePtr->ParseContestRanking(Rankings);
+ this->DataStorage->AddContestRanking(Rankings);
+ this->OnContestRankingDisplayReady.Broadcast(Request.RequestId, true);
+ return;
+ }
+ this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, false);
+ });
+ FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
+ [this](const FDTFluxTrackedRequest& InReq, const FString& InError)
+ {
+ this->OnStageRankingDisplayReady.Broadcast(InReq.RequestId, false);
+ });
+ FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
+ EDTFluxApiDataType::ContestRanking, ContestId, -1, -1, OnSuccess, OnError, true);
+ return DisplayRequestId;
+ }
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxDatastorage unavailable ..."));
+ OnContestRankingDisplayReady.Broadcast(FGuid(), false);
+ return FGuid();
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
+ OnContestRankingDisplayReady.Broadcast(FGuid(), false);
+ return FGuid();
+}
+
+FGuid UDTFluxCoreSubsystem::InitStageRankingsDisplay(const int ContestId, const int StageId)
+{
+ if (NetworkSubsystem)
+ {
+ if (DataStorage)
+ {
+ // no need to request StageRankings;
+ if (IsStageRankingSealed(FDTFluxStageKey(ContestId, StageId)))
+ {
+ const FGuid DisplayRequestId = FGuid::NewGuid();
+ OnStageRankingDisplayReady.Broadcast(DisplayRequestId, true);
+ return DisplayRequestId;
+ }
+ else
+ {
+ FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
+ [this](const FDTFluxTrackedRequest& Request)
+ {
+ FDTFluxStageRankings Rankings = FDTFluxStageRankings();
+ if (Request.ParsedResponse.IsSet())
+ {
+ TSharedPtr ResponsePtr = Request.ParsedResponse.GetValue();
+ ResponsePtr->ParseStageRanking(Rankings);
+ this->DataStorage->AddStageRanking(Rankings);
+ this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, true);
+ return;
+ }
+ this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, false);
+ });
+ FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
+ [this](const FDTFluxTrackedRequest& InReq, const FString& InError)
+ {
+ this->OnStageRankingDisplayReady.Broadcast(InReq.RequestId, false);
+ });
+ FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
+ EDTFluxApiDataType::StageRanking, ContestId, StageId, -1, OnSuccess, OnError, true);
+ return DisplayRequestId;
+ }
+ }
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
+ const FGuid RequestId = FGuid::NewGuid();
+ OnStageRankingDisplayReady.Broadcast(RequestId, false);
+ return RequestId;
+}
+
+FGuid UDTFluxCoreSubsystem::InitSplitRankingsDisplay(const int ContestId, const int StageId, const int SplitId)
+{
+ if (NetworkSubsystem)
+ {
+ if (DataStorage)
+ {
+ FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
+ [this](const FDTFluxTrackedRequest& Request)
+ {
+ FDTFluxSplitRankings Rankings = FDTFluxSplitRankings();
+ if (Request.ParsedResponse.IsSet())
+ {
+ TSharedPtr ResponsePtr = Request.ParsedResponse.GetValue();
+ ResponsePtr->ParseSplitRanking(Rankings);
+ this->DataStorage->AddSplitRanking(Rankings);
+ this->OnSplitRankingDisplayReady.Broadcast(Request.RequestId, true);
+ return;
+ }
+ this->OnSplitRankingDisplayReady.Broadcast(Request.RequestId, false);
+ });
+ FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
+ [this](const FDTFluxTrackedRequest& InReq, const FString& InError)
+ {
+ this->OnSplitRankingDisplayReady.Broadcast(InReq.RequestId, false);
+ });
+ FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
+ EDTFluxApiDataType::ContestRanking, ContestId, StageId, SplitId, OnSuccess, OnError, true);
+ return DisplayRequestId;
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxDatastorage unavailable ..."));
+ OnSplitRankingDisplayReady.Broadcast(FGuid(), false);
+ return FGuid();
+ }
+ UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
+ OnSplitRankingDisplayReady.Broadcast(FGuid(), false);
+ return FGuid();
+}
+
bool UDTFluxCoreSubsystem::GetStageRankingForBib(const int ContestId, const int StageId, const int Bib,
FDTFluxStageRanking& OutStageRanking)
{
@@ -491,7 +663,6 @@ TArray UDTFluxCoreSubsystem::TrackedRequestStageRankings(const TArraySendTrackedRequestWithCallbacks(EDTFluxApiDataType::StageRanking,
diff --git a/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h b/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h
index 8029005..180fd98 100644
--- a/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h
+++ b/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h
@@ -41,6 +41,25 @@ public:
UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem")
FOnStageRankings OnStageRankings;
+
+ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnContestRankingDisplayReady, const FGuid, RequestId, const bool,
+ bSuccesRequest);
+
+ UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem")
+ FOnContestRankingDisplayReady OnContestRankingDisplayReady;
+
+ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStageRankingDisplayReady, const FGuid, RequestId, const bool,
+ bSuccesRequest);
+
+ UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem")
+ FOnStageRankingDisplayReady OnStageRankingDisplayReady;
+
+ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSplitRankingDisplayReady, const FGuid, RequestId, const bool,
+ bSuccesRequest);
+
+ UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem")
+ FOnSplitRankingDisplayReady OnSplitRankingDisplayReady;
+
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnContestRankings, const int, ContestId, FDTFluxContestRankings,
ContestRankings);
@@ -78,6 +97,18 @@ public:
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Core Subsystem")
bool bShouldKeepRankings = true;
+
+ UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
+ FGuid InitContestRankingsDisplay(const int ContestIds);
+
+
+ UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
+ FGuid InitStageRankingsDisplay(const int ContestId, const int StageId);
+
+ UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
+ FGuid InitSplitRankingsDisplay(const int ContestId, const int StageId, const int SplitId);
+
+
UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
bool GetStageRankingForBib(const int ContestId, const int StageId, const int Bib,
FDTFluxStageRanking& OutStageRankings);
@@ -165,4 +196,9 @@ private:
void SendRequest(const FString& Message);
UFUNCTION()
void RegisterDelegates();
+
+ UFUNCTION()
+ bool IsStageRankingSealed(FDTFluxStageKey StageKey);
+ UFUNCTION()
+ bool IsContestRankingSealed(int ContestId);
};