// Fill out your copyright notice in the Description page of Project Settings. #include "DTFluxPursuitManager.h" #include "DTFluxCoreSubsystemModule.h" UDTFluxPursuitManager::UDTFluxPursuitManager(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer) { } // TODO : Add way to pass MaxSimultaneousPursuit and MassStartDelay // For now it's done in UPROPERTIES void UDTFluxPursuitManager::LaunchPursuitSequenceFor(const TArray InContests) { if (InitSubSystems()) { for (const auto Contest : InContests) { FRequestData RequestData; RequestData.ContestId = Contest.ContestId; uint8 StageId = Contest.Stages.Last().StageId; FGuid Guid = NetworkSubsystem->SendTrackedRequestWithCallback(EDTFluxApiDataType::StageRanking, Contest.ContestId, StageId, -1, FOnDTFluxTrackedRequestResponse::CreateUObject( this, &UDTFluxPursuitManager::OnRequestResponse), FOnDTFluxTrackedRequestTimeout::CreateUObject( this, &UDTFluxPursuitManager::OnRequestTimeoutResponse), FOnDTFluxRequestResponseError::CreateUObject( this, &UDTFluxPursuitManager::OnRequestError)); RequestData.RequestIds.Add(Guid); PendingRequestData.Add(RequestData); } } } void UDTFluxPursuitManager::OnRequestResponse(const FGuid& RequestId, FDTFluxServerResponse& Response) { UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("UDTFluxPursuitManager::OnRequestResponse() Received Ranking For Stage %i"), Response.StageID) UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("Response is %s"), *UEnum::GetValueAsString(Response.GetResponseType())) //check if request if (Response.GetResponseType() == EDTFluxApiDataType::StageRanking) { FDTFluxStageRankings Rankings; FRequestData FoundData; if (Response.ParseStageRankingResponse(Rankings)) { for (auto& PendingReq : PendingRequestData) { // Check for a matching PendingReq if (PendingReq.IsWaitingFor(RequestId, Rankings)) { FoundData = PendingReq; // A request Is Terminated UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("UDTFluxPursuitManager::OnRequestResponse() Ranking for Stage %i is complete"), Response.StageID) break; } } if (InitPursuit(FoundData)) { OnPursuitSequenceReady_Internal.Broadcast(NextFocusPursuits, NextFocusPursuits, bFocusIsTruncate); } } } } void UDTFluxPursuitManager::OnRequestTimeoutResponse(const FGuid& RequestId, const FString& TimeoutMessage) { UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Request Timeout [%s]"), *TimeoutMessage); } void UDTFluxPursuitManager::OnRequestError(const FGuid& RequestId, const FString& ErrorMessage) { UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Request Error [%s]"), *ErrorMessage); } bool UDTFluxPursuitManager::InitSubSystems() { if (NetworkSubsystem) { return true; } NetworkSubsystem = GEngine->GetEngineSubsystem(); return NetworkSubsystem != nullptr; } bool UDTFluxPursuitManager::InitPursuit(FRequestData Data) { //Clean Data NextFocusPursuits.Empty(); NextPursuits.Empty(); PursuitGrouped.Empty(); TArray AllRankings; TArray AllPursuits; TMap TempGroups; // Full the Array Of Rankings for (auto& KeyPair : Data.StageRankings) { for (auto StageRanking : KeyPair.Value.Rankings) { int ContestId = KeyPair.Value.ContestId; FDTFluxPursuitInfo PursuitInfo; PursuitInfo.StartTime = StageRanking.StartTime; PursuitInfo.Bib = StageRanking.Bib; PursuitInfo.ContestId = ContestId; AllPursuits.Add(PursuitInfo); } } // Sort Rankings // AllPursuits.Sort([](const FDTFluxPursuitInfo& A, const FDTFluxPursuitInfo& B) { // return A.StartTime < B.StartTime; // }); 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; }); PursuitGrouped.Reserve(TempGroups.Num()); for (const auto& Pair : TempGroups) { PursuitGrouped.Add(Pair.Value); } PursuitGrouped.Sort([](const FDTFluxPursuitGroup& A, const FDTFluxPursuitGroup& B) { return A.StartTimeGlobal < B.StartTimeGlobal; }); return true; }