Files
DTFluxAPI/Source/DTFluxCoreSubsystem/Private/DTFluxPursuitManager.cpp

233 lines
6.5 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "DTFluxPursuitManager.h"
#include <ImportExport.h>
#include "DTFluxCoreSubsystem.h"
#include "DTFluxCoreSubsystemModule.h"
UDTFluxPursuitManager::UDTFluxPursuitManager(const FObjectInitializer& ObjectInitializer):
Super(ObjectInitializer)
{
}
void UDTFluxPursuitManager::InitPursuit(const TArray<int> InContestIds, const int MaxSimultaneousPursuit)
{
CoreSubsystem = Cast<UDTFluxCoreSubsystem>(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<FDTFluxPursuitInfo>& OutPursuitFocusNext,
TArray<FDTFluxPursuitInfo>& OutPursuitNext, bool& BIsFocusTruncate,
const int MaxSimultaneousPursuit)
{
if (MaxSimultaneousPursuit <= 0)
{
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("MaxSimultaneousPursuit must be > 0"));
OutPursuitFocusNext = TArray<FDTFluxPursuitInfo>();
OutPursuitNext = TArray<FDTFluxPursuitInfo>();
BIsFocusTruncate = false;
return;
}
if (bIsSequenceDone && MaxSimultaneousPursuit <= 0)
{
OutPursuitFocusNext = TArray<FDTFluxPursuitInfo>();
OutPursuitNext = TArray<FDTFluxPursuitInfo>();
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<UDTFluxNetworkSubsystem>();
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<FDTFluxPursuitInfo> AllPursuits;
TMap<FDateTime, FDTFluxPursuitGroup> 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<FDateTime, int> 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<FDTFluxPursuitInfo> FocusPursuits;
TArray<FDTFluxPursuitInfo> NextPursuits;
bool bIsFocusTruncate = false;
GetPursuit(FocusPursuits, NextPursuits, bIsFocusTruncate);
FPursuitStaterData PursuitData = FPursuitStaterData(FocusPursuits, NextPursuits, MassStartTime, bIsFocusTruncate);
CoreSubsystem->OnPursuitSequenceReady.Broadcast(PursuitData);
return true;
}