// Fill out your copyright notice in the Description page of Project Settings. #include "DTFluxPursuitManager.h" #include #include "DTFluxCoreSubsystem.h" #include "DTFluxCoreSubsystemModule.h" UDTFluxPursuitManager::UDTFluxPursuitManager(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer) { } void UDTFluxPursuitManager::InitPursuit(const TArray InContestIds, const int MaxSimultaneousPursuit) { CoreSubsystem = Cast(GetOuter()); if (!CoreSubsystem) { UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("CoreSubsystem is not Available !!!")); return; } AllRankings.Reset(); for (const auto& ContestId : InContestIds) { FDTFluxContest Contest; if (CoreSubsystem->GetContestForId(ContestId, Contest)) { BindRankings(); FDTFluxStageKey StageKey = FDTFluxStageKey(ContestId, Contest.GetLastStageId()); FDTFluxStageRankings TempStageRankings; //Obtenir les ranking Frais. CoreSubsystem->GetStageRankingsWithKey(StageKey, TempStageRankings, false); PendingStageRanking.Add(StageKey, false); } } } 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; } } } } bool UDTFluxPursuitManager::InitSubSystems() { if (NetworkSubsystem) { return true; } NetworkSubsystem = GEngine->GetEngineSubsystem(); return NetworkSubsystem != nullptr; } bool UDTFluxPursuitManager::BindRankings() { if (CoreSubsystem) { if (!bIsRankingBounded) { CoreSubsystem->OnRequestedStageRankings.AddDynamic(this, &UDTFluxPursuitManager::OnRankingsReceived); bIsRankingBounded = true; } return bIsRankingBounded; } UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("CoreSubsystem is not Available !!!")); return bIsRankingBounded = false; } void UDTFluxPursuitManager::UnbindRankings() { if (CoreSubsystem) { if (bIsRankingBounded) { CoreSubsystem->OnRequestedStageRankings.RemoveDynamic(this, &UDTFluxPursuitManager::OnRankingsReceived); bIsRankingBounded = false; return; } } bIsRankingBounded = false; UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("CoreSubsystem is not Available !!!")); } void UDTFluxPursuitManager::OnRankingsReceived(const FDTFluxStageKey NewStageKey, const FDTFluxStageRankings NewStageRankings) { if (PendingStageRanking.Contains(NewStageKey)) { PendingStageRanking.Remove(NewStageKey); AllRankings.Add(NewStageRankings); if (PendingStageRanking.IsEmpty()) { //everything is ready to go compute and start UnbindRankings(); LaunchPursuitSequence(); } } } bool UDTFluxPursuitManager::LaunchPursuitSequence() { GroupedPursuit.Empty(); TArray AllPursuits; TMap TempGroups; bIsSequenceDone = false; // Full the Array Of Rankings for (auto& Ranking : AllRankings) { for (auto StageRanking : Ranking.Rankings) { int ContestId = Ranking.ContestId; FDTFluxPursuitInfo PursuitInfo; PursuitInfo.StartTime = StageRanking.StartTime; PursuitInfo.Bib = StageRanking.Bib; PursuitInfo.ContestId = ContestId; AllPursuits.Add(PursuitInfo); } } for (auto& Pursuit : AllPursuits) { if (TempGroups.Contains(Pursuit.StartTime)) { TempGroups[Pursuit.StartTime].PursuitGroup.Add(Pursuit); } else { FDTFluxPursuitGroup Group; Group.StartTimeGlobal = Pursuit.StartTime; Group.PursuitGroup.Add(Pursuit); TempGroups.Add(Pursuit.StartTime, Group); } } TempGroups.KeySort([](const FDateTime& A, const FDateTime& B) { return A < B; }); TMap StartTimeFrequency; int32 MaxFrequency = 0; GroupedPursuit.Reserve(TempGroups.Num()); for (const auto& Pair : TempGroups) { 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); } GroupedPursuit.Sort([](const FDTFluxPursuitGroup& A, const FDTFluxPursuitGroup& B) { return A.StartTimeGlobal < B.StartTimeGlobal; }); TArray FocusPursuits; TArray NextPursuits; bool bIsFocusTruncate = false; GetPursuit(FocusPursuits, NextPursuits, bIsFocusTruncate); FPursuitStarterData PursuitData = FPursuitStarterData(FocusPursuits, NextPursuits, MassStartTime, bIsFocusTruncate); OnPursuitSequenceReady.Broadcast(PursuitData); return true; }