diff --git a/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp b/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp index 9d9e560..28b101c 100644 --- a/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp +++ b/Source/DTFluxCoreSubsystem/Private/DTFluxCoreSubsystem.cpp @@ -32,7 +32,7 @@ void UDTFluxCoreSubsystem::Initialize(FSubsystemCollectionBase& Collection) { RegisterDelegates(); } - PursuitManager = NewObject(); + PursuitManager = NewObject(this); } void UDTFluxCoreSubsystem::Deinitialize() @@ -347,22 +347,3 @@ TArray UDTFluxCoreSubsystem::GetContests() } return TArray(); } - -void UDTFluxCoreSubsystem::LaunchPursuitSequenceFor(const TArray ContestIds) -{ - TArray Contests = TArray(); - for (const auto& ContestId : ContestIds) - { - FDTFluxContest Contest; - GetContestForId(ContestId, Contest); - Contests.Add(Contest); - if (PursuitManager) - { - PursuitManager->LaunchPursuitSequenceFor(Contests); - } - else - { - UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("PursuitManager is null")); - } - } -} diff --git a/Source/DTFluxCoreSubsystem/Private/DTFluxPursuitManager.cpp b/Source/DTFluxCoreSubsystem/Private/DTFluxPursuitManager.cpp index aa5ff27..00fdd0a 100644 --- a/Source/DTFluxCoreSubsystem/Private/DTFluxPursuitManager.cpp +++ b/Source/DTFluxCoreSubsystem/Private/DTFluxPursuitManager.cpp @@ -3,6 +3,9 @@ #include "DTFluxPursuitManager.h" +#include + +#include "DTFluxCoreSubsystem.h" #include "DTFluxCoreSubsystemModule.h" UDTFluxPursuitManager::UDTFluxPursuitManager(const FObjectInitializer& ObjectInitializer): @@ -12,7 +15,7 @@ UDTFluxPursuitManager::UDTFluxPursuitManager(const FObjectInitializer& ObjectIni // TODO : Add way to pass MaxSimultaneousPursuit and MassStartDelay // For now it's done in UPROPERTIES -void UDTFluxPursuitManager::LaunchPursuitSequenceFor(const TArray InContests) +void UDTFluxPursuitManager::InitPursuitForContests(const TArray InContests) { if (InitSubSystems()) { @@ -39,6 +42,91 @@ void UDTFluxPursuitManager::LaunchPursuitSequenceFor(const TArray InContestIds, const int MaxSimultaneousPursuit) +{ + CoreSubsystem = Cast(GetOuter()); + if (!CoreSubsystem) + { + UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("CoreSubsystem is not Available !!!")); + return; + } + TArray Contests = TArray(); + for (const auto& ContestId : InContestIds) + { + FDTFluxContest Contest; + CoreSubsystem->GetContestForId(ContestId, Contest); + Contests.Add(Contest); + + InitPursuitForContests(Contests); + } +} + +void UDTFluxPursuitManager::SetPursuitInfoIsMassStart(FDTFluxPursuitGroup NextFocusGroup) +{ + for (auto& Pursuit : NextFocusGroup.PursuitGroup) + { + Pursuit.bIsMassStart = Pursuit.StartTime >= MassStartTime; + } +} + +void UDTFluxPursuitManager::GetPursuit(TArray& OutPursuitFocusNext, + TArray& OutPursuitNext, bool& BIsFocusTruncate, + const int MaxSimultaneousPursuit) +{ + if (MaxSimultaneousPursuit <= 0) + { + UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("MaxSimultaneousPursuit must be > 0")); + OutPursuitFocusNext = TArray(); + OutPursuitNext = TArray(); + BIsFocusTruncate = false; + return; + } + if (bIsSequenceDone && MaxSimultaneousPursuit <= 0) + { + OutPursuitFocusNext = TArray(); + OutPursuitNext = TArray(); + BIsFocusTruncate = false; + return; + } + OutPursuitFocusNext.Reset(); + OutPursuitNext.Reset(); + if (!GroupedPursuit.IsEmpty()) + { + FDTFluxPursuitGroup NextFocusGroup = GroupedPursuit[0]; + GroupedPursuit.RemoveAt(0); + SetPursuitInfoIsMassStart(NextFocusGroup); + OutPursuitFocusNext = NextFocusGroup.PursuitGroup; + bFocusIsTruncate = NextFocusGroup.PursuitGroup.Num() > 1; + for (int RemainingPursuitNum = MaxSimultaneousPursuit - 1; RemainingPursuitNum != 0;) + { + if (!GroupedPursuit.IsEmpty()) + { + FDTFluxPursuitGroup NextGroup = GroupedPursuit[0]; + SetPursuitInfoIsMassStart(NextGroup); + if (NextGroup.PursuitGroup.Num() >= RemainingPursuitNum) + { + // extract the number we need + for (int i = 0; i < RemainingPursuitNum; i++) + { + FDTFluxPursuitInfo Pursuit = NextGroup.PursuitGroup[0]; + OutPursuitNext.Add(Pursuit); + } + break; + } + else + { + OutPursuitNext.Append(NextGroup.PursuitGroup); + RemainingPursuitNum -= NextGroup.PursuitGroup.Num(); + } + } + else + { + break; + } + } + } +} + void UDTFluxPursuitManager::OnRequestResponse(const FGuid& RequestId, FDTFluxServerResponse& Response) { UE_LOG(logDTFluxCoreSubsystem, Log, @@ -48,9 +136,9 @@ void UDTFluxPursuitManager::OnRequestResponse(const FGuid& RequestId, FDTFluxSer if (Response.GetResponseType() == EDTFluxApiDataType::StageRanking) { FDTFluxStageRankings Rankings; - FRequestData FoundData; if (Response.ParseStageRankingResponse(Rankings)) { + FRequestData FoundData = FRequestData(); for (auto& PendingReq : PendingRequestData) { // Check for a matching PendingReq @@ -64,9 +152,9 @@ void UDTFluxPursuitManager::OnRequestResponse(const FGuid& RequestId, FDTFluxSer break; } } - if (InitPursuit(FoundData)) + if (InitPursuitForRequest(FoundData)) { - OnPursuitSequenceReady.Broadcast(NextFocusPursuits, NextFocusPursuits, bFocusIsTruncate); + OnPursuitSequenceReady.Broadcast(MassStartTime, NextFocusPursuits, NextFocusPursuits, bFocusIsTruncate); } } } @@ -92,16 +180,17 @@ bool UDTFluxPursuitManager::InitSubSystems() return NetworkSubsystem != nullptr; } -bool UDTFluxPursuitManager::InitPursuit(FRequestData Data) +bool UDTFluxPursuitManager::InitPursuitForRequest(FRequestData Data) { //Clean Data NextFocusPursuits.Empty(); NextPursuits.Empty(); - PursuitGrouped.Empty(); + GroupedPursuit.Empty(); TArray AllRankings; TArray AllPursuits; TMap TempGroups; + // Full the Array Of Rankings for (auto& KeyPair : Data.StageRankings) { @@ -138,13 +227,27 @@ bool UDTFluxPursuitManager::InitPursuit(FRequestData Data) { return A < B; }); - PursuitGrouped.Reserve(TempGroups.Num()); + TMap StartTimeFrequency; + int32 MaxFrequency = 0; + GroupedPursuit.Reserve(TempGroups.Num()); for (const auto& Pair : TempGroups) { - PursuitGrouped.Add(Pair.Value); + if (Pair.Value.StartTimeGlobal != FDateTime::MinValue() && Pair.Value.StartTimeGlobal != FDateTime::MaxValue()) + { + StartTimeFrequency.FindOrAdd(Pair.Value.StartTimeGlobal)++; + const FDateTime& PropertyValue = Pair.Value.StartTimeGlobal; // Votre propriété + int32& Count = StartTimeFrequency.FindOrAdd(PropertyValue, 0); + Count++; + if (Count > MaxFrequency) + { + MaxFrequency = Count; + MassStartTime = PropertyValue; + } + } + GroupedPursuit.Add(Pair.Value); } - PursuitGrouped.Sort([](const FDTFluxPursuitGroup& A, const FDTFluxPursuitGroup& B) + GroupedPursuit.Sort([](const FDTFluxPursuitGroup& A, const FDTFluxPursuitGroup& B) { return A.StartTimeGlobal < B.StartTimeGlobal; }); diff --git a/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h b/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h index dfec220..24179db 100644 --- a/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h +++ b/Source/DTFluxCoreSubsystem/Public/DTFluxCoreSubsystem.h @@ -18,7 +18,7 @@ class UDTFluxPursuitManager; /** * */ -UCLASS() +UCLASS(BlueprintType, meta=(DisplayName="DTFlux Core Subsystem")) class DTFLUXCORESUBSYSTEM_API UDTFluxCoreSubsystem : public UEngineSubsystem { GENERATED_BODY() @@ -28,34 +28,24 @@ public: UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") FOnSplitRankings OnSplitRankings; - DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnStageRankings, FDTFluxStageRankings&, StageRankings); UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") FOnStageRankings OnStageRankings; - DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnContestRankings, FDTFluxContestRankings&, ContestRankings); UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") FOnContestRankings OnContestRankings; - DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTeamList); UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") FOnTeamList OnTeamList; - DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTeamStatusUpdate, FDTFluxParticipant, TeamUpdated); UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") FOnTeamStatusUpdate OnTeamStatusUpdate; - DECLARE_DELEGATE_TwoParams(FOnRequestedStageRankings, const FDTFluxStageKey&, const FDTFluxContestRankings&); FOnRequestedStageRankings OnRequestedStageRankings; - // - // DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnTeamUpdate, FDateTime, ReceivedAt, FDTFluxParticipant, TeamUpdatedList); - // UPROPERTY(BlueprintAssignable, Category="DTFlux|Core Subsystem") - // FOnTeamUpdate OnTeamUpdate; - UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem") void SendTeamListRequest(); @@ -106,24 +96,21 @@ public: UFUNCTION() TArray GetContests(); - - UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem") - void LaunchPursuitSequenceFor(const TArray ContestIds); + UPROPERTY(BlueprintReadOnly, Category="DTFlux|Core Subsystem") + UDTFluxPursuitManager* PursuitManager = nullptr; protected: // ~Subsystem Interface virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; // ~Subsystem Interface - - UPROPERTY() - UDTFluxPursuitManager* PursuitManager = nullptr; - UFUNCTION() void SaveDataStorage(); private: UDTFluxNetworkSubsystem* NetworkSubsystem = nullptr; + UPROPERTY() + UDTFluxModelAsset* DataStorage = nullptr; UFUNCTION() void ProcessRaceData(const FDTFluxRaceData& RaceDataDefinition); @@ -145,8 +132,4 @@ private: void SendRequest(const FString& Message); UFUNCTION() void RegisterDelegates(); - - - UPROPERTY() - UDTFluxModelAsset* DataStorage = nullptr; }; diff --git a/Source/DTFluxCoreSubsystem/Public/DTFluxPursuitManager.h b/Source/DTFluxCoreSubsystem/Public/DTFluxPursuitManager.h index dbc9949..85adf71 100644 --- a/Source/DTFluxCoreSubsystem/Public/DTFluxPursuitManager.h +++ b/Source/DTFluxCoreSubsystem/Public/DTFluxPursuitManager.h @@ -8,6 +8,8 @@ #include "DTFluxPursuitManager.generated.h" +class UDTFluxCoreSubsystem; + USTRUCT() struct FRequestData { @@ -27,7 +29,7 @@ struct FRequestData FRequestData() = default; FRequestData(const TArray& InRequestIds, const TMap& InStageRankings) - : RequestIds(InRequestIds), StageRankings(InStageRankings) + : RequestIds(InRequestIds), StageRankings(InStageRankings), ContestId(-1) { }; @@ -63,9 +65,10 @@ struct FDTFluxPursuitGroup bool bIsFocus = false; }; -DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnPursuitSequenceReady, const TArray, - NextFocusPursuits, - const TArray, NextPursuit, bool, bIsTrtuncate); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnPursuitSequenceReady, const FDateTime, MassStartTime, + const TArray, + NextFocusPursuits, + const TArray, NextPursuit, bool, bIsTrtuncate); /** * @@ -86,28 +89,32 @@ public: UPROPERTY(BlueprintReadOnly, VisibleAnywhere) bool bFocusIsTruncate = false; - // - // UPROPERTY() - // TArray TargetStages; UPROPERTY() - int MaxSimultaneousPursuit = 7; + int PursuitMaxSimultaneousPursuit = 7; + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="DTFlux|Pursuit", meta=(ClampMin="1", ClampMax="60", UIMin="0", UIMax="60")) int MassStartDelay = 10; UPROPERTY() - TArray PursuitGrouped; + FDateTime MassStartTime = FDateTime::MinValue(); + + UPROPERTY() + TArray GroupedPursuit; UPROPERTY() int CurrentIndex = -1; - UPROPERTY(BlueprintCallable, Category="DTFlux|Pursuit") + UPROPERTY(BlueprintAssignable, Category="DTFlux|Pursuit") FOnPursuitSequenceReady OnPursuitSequenceReady; + UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="pursuit, launch, poursuite")) + void InitPursuit(const TArray InContestIds, const int MaxSimultaneousPursuit = 7); UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="pursuit, launch, poursuite")) - void LaunchPursuitSequenceFor(const TArray InContests); + void GetPursuit(TArray& OutPursuitFocusNext, TArray& OutPursuitNext, + bool& BIsFocusTruncate, const int MaxSimultaneousPursuit = 7); UFUNCTION() void OnRequestResponse(const FGuid& RequestId, FDTFluxServerResponse& Response); @@ -123,11 +130,15 @@ public: private: TArray PendingRequestData; - -public: - UFUNCTION() - bool InitPursuit(FRequestData Data); - -private: + UDTFluxCoreSubsystem* CoreSubsystem = nullptr; UDTFluxNetworkSubsystem* NetworkSubsystem = nullptr; + + UPROPERTY() + bool bIsSequenceDone = true; + UFUNCTION() + void SetPursuitInfoIsMassStart(FDTFluxPursuitGroup NextFocusGroup); + UFUNCTION() + void InitPursuitForContests(const TArray InContests); + UFUNCTION() + bool InitPursuitForRequest(FRequestData Data); };