Added Subsystem Timer
This commit is contained in:
@ -4,6 +4,7 @@
|
|||||||
#include "DTFluxCountDown/DTFluxCountDownComponent.h"
|
#include "DTFluxCountDown/DTFluxCountDownComponent.h"
|
||||||
|
|
||||||
#include "DTFluxAPILog.h"
|
#include "DTFluxAPILog.h"
|
||||||
|
#include "DTFluxSubsystem/DTFluxSubsystem.h"
|
||||||
|
|
||||||
|
|
||||||
// Sets default values for this component's properties
|
// Sets default values for this component's properties
|
||||||
@ -12,7 +13,14 @@ UDTFluxCountDownComponent::UDTFluxCountDownComponent()
|
|||||||
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
||||||
// off to improve performance if you don't need them.
|
// off to improve performance if you don't need them.
|
||||||
PrimaryComponentTick.bCanEverTick = true;
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
|
if(FModuleManager::Get().IsModuleLoaded("DTFluxApi"))
|
||||||
|
{
|
||||||
|
DataStorage = GEngine->GetEngineSubsystem<UDTFluxSubsystem>()->GetDataStorage();
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("DTFluxApi loaded"))
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("DTFluxApi Not Loaded"))
|
||||||
|
}
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "DTFluxDataStorage/DTFluxDataStorage.h"
|
#include "DTFluxDataStorage/DTFluxDataStorage.h"
|
||||||
|
|
||||||
// #include "AsyncTreeDifferences.h"
|
|
||||||
#include "DTFluxAPILog.h"
|
#include "DTFluxAPILog.h"
|
||||||
#include "DTFluxModel/DTFluxModel.h"
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
|
|
||||||
@ -138,73 +137,110 @@ FDTFluxFinisher UDTFluxDataStorage::GetFinisherStatus(const FDTFluxSplitSensorRe
|
|||||||
return Finisher;
|
return Finisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDTFluxDataStorage::GetContest(FDTFluxContest& OutContest, const int& ContestId)
|
bool UDTFluxDataStorage::GetContest(const int ContestId, FDTFluxContest& OutContest )
|
||||||
{
|
|
||||||
// Current contest requested
|
|
||||||
if(ContestId == -1)
|
|
||||||
{
|
|
||||||
FDateTime Now = FDateTime::Now();
|
|
||||||
for(auto& Contest : Contests)
|
|
||||||
{
|
|
||||||
for( auto& Stage : Contest.Stages)
|
|
||||||
{
|
|
||||||
if(Stage.StartTime >= Now && Stage.EndTime <= Now)
|
|
||||||
{
|
|
||||||
//We have a winner
|
|
||||||
OutContest = Contest;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("RequestedContest %d"),
|
||||||
|
// ContestId);
|
||||||
for(auto& Contest : Contests)
|
for(auto& Contest : Contests)
|
||||||
{
|
{
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Checking Contest %d"),
|
||||||
|
// Contest.Id);
|
||||||
if(Contest.Id == ContestId)
|
if(Contest.Id == ContestId)
|
||||||
{
|
{
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Found Contest %d"),
|
||||||
|
// Contest.Id);
|
||||||
OutContest = Contest;
|
OutContest = Contest;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// UE_LOG(LogDTFluxAPI, Error, TEXT("Contest %d not Found "),
|
||||||
|
// ContestId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDTFluxDataStorage::GetStage(FDTFluxStage& CurrentStage, const int& StageId)
|
bool UDTFluxDataStorage::GetStage(const int ContestId, const int StageId, FDTFluxStage& OutStage)
|
||||||
{
|
{
|
||||||
// Current contest requested
|
FDTFluxContest Contest;
|
||||||
if(StageId == -1)
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("RequestedStage %d in Contest%02d ****"),
|
||||||
{
|
// ContestId, StageId);
|
||||||
FDateTime Now = FDateTime::Now();
|
if(GetContest(ContestId, Contest))
|
||||||
for(auto& Contest : Contests)
|
|
||||||
{
|
{
|
||||||
for(auto & Stage: Contest.Stages)
|
for(auto & Stage: Contest.Stages)
|
||||||
{
|
{
|
||||||
if(StageId <= -1)
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Checking Stage %d "),
|
||||||
{
|
// Stage.Id);
|
||||||
if(Stage.StartTime >= Now && Stage.EndTime <= Now)
|
|
||||||
{
|
|
||||||
//We have a winner for current stage
|
|
||||||
CurrentStage = Stage;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
if(Stage.Id == StageId)
|
if(Stage.Id == StageId)
|
||||||
{
|
{
|
||||||
//We have a winner for the search stage
|
|
||||||
CurrentStage = Stage;
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Found %s in Stage ***"),
|
||||||
|
// *Stage.Name);
|
||||||
|
OutStage = Stage;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// UE_LOG(LogDTFluxAPI, Error, TEXT("Stage %d Not Found in Contest %d ****"),
|
||||||
|
// StageId, ContestId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDTFluxDataStorage::GetSplit(const int ContestId, const int StageId, const int SplitId, FDTFluxSplit& OutSplit)
|
||||||
|
{
|
||||||
|
// DumpContest();
|
||||||
|
FDTFluxStage Stage;
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("RequestedSplit %d in Stage%02d of Contest%02d"),
|
||||||
|
// ContestId, StageId, SplitId);
|
||||||
|
if(GetStage(ContestId, StageId, Stage))
|
||||||
|
{
|
||||||
|
for(auto& Split: Stage.Splits)
|
||||||
|
{
|
||||||
|
if(Split.Id == SplitId)
|
||||||
|
{
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Get Split %s in Stage%02d of Contest%02d"),
|
||||||
|
// *Split.Name, StageId, SplitId);
|
||||||
|
OutSplit = Split;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FDTFluxSplitRanking UDTFluxDataStorage::AddSplitRanking(const FDTFluxSplitSensorItemResponse& SplitSensorItem)
|
||||||
|
{
|
||||||
|
FDTFluxSplitRanking NewSplitRanking;
|
||||||
|
NewSplitRanking.Bib = SplitSensorItem.Bib;
|
||||||
|
NewSplitRanking.Gap = SplitSensorItem.Gap;
|
||||||
|
NewSplitRanking.Rank = SplitSensorItem.Rank;
|
||||||
|
NewSplitRanking.Time = SplitSensorItem.Time;
|
||||||
|
FDTFluxSplit Split;
|
||||||
|
if(GetSplit(SplitSensorItem.ContestID, SplitSensorItem.StageID,
|
||||||
|
SplitSensorItem.SplitID, Split))
|
||||||
|
{
|
||||||
|
Split.SplitRankings.Add(NewSplitRanking);
|
||||||
|
return NewSplitRanking;
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Error,
|
||||||
|
TEXT("Error, Cannot process split sensor."))
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("Split %d from stage %d of Contest %d does not exist"),
|
||||||
|
SplitSensorItem.SplitID, SplitSensorItem.StageID, SplitSensorItem.ContestID);
|
||||||
|
return NewSplitRanking;
|
||||||
|
}
|
||||||
|
|
||||||
|
EDTFluxSplitType UDTFluxDataStorage::GetSplitStatus(int ContestID, int StageID, int SplitID)
|
||||||
|
{
|
||||||
|
FDTFluxStage Stage;
|
||||||
|
if(GetStage(ContestID, StageID, Stage))
|
||||||
|
{
|
||||||
|
int SplitCount = Stage.Splits.Num();
|
||||||
|
FDTFluxSplit S;
|
||||||
|
return Stage.GetSplitType(SplitID);
|
||||||
|
}
|
||||||
|
return EDTFluxSplitType::UnknownSplitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TArray<FDTFluxParticipant> UDTFluxDataStorage::GetParticipants(const int ContestId)
|
TArray<FDTFluxParticipant> UDTFluxDataStorage::GetParticipants(const int ContestId)
|
||||||
{
|
{
|
||||||
TArray<FDTFluxParticipant> Participants;
|
TArray<FDTFluxParticipant> Participants;
|
||||||
@ -254,6 +290,7 @@ void UDTFluxDataStorage::AddOrUpdateContest(const FDTFluxContestResponse& Contes
|
|||||||
FDTFluxContest Contest;
|
FDTFluxContest Contest;
|
||||||
bool NewContest = false;
|
bool NewContest = false;
|
||||||
int ContestIdx = 0;
|
int ContestIdx = 0;
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("DateTime Json Contest \"%s\""), *ContestResponse.Date.ToString() );
|
||||||
if(!Contests.IsEmpty() )
|
if(!Contests.IsEmpty() )
|
||||||
{
|
{
|
||||||
for(auto& OldContest: Contests)
|
for(auto& OldContest: Contests)
|
||||||
@ -277,6 +314,7 @@ void UDTFluxDataStorage::AddOrUpdateContest(const FDTFluxContestResponse& Contes
|
|||||||
// Updating values
|
// Updating values
|
||||||
Contest.Id = ContestResponse.Id;
|
Contest.Id = ContestResponse.Id;
|
||||||
Contest.Name = ContestResponse.Name;
|
Contest.Name = ContestResponse.Name;
|
||||||
|
Contest.Date = ContestResponse.Date;
|
||||||
TArray<FDTFluxSplit> Splits;
|
TArray<FDTFluxSplit> Splits;
|
||||||
for(auto Split: ContestResponse.Splits)
|
for(auto Split: ContestResponse.Splits)
|
||||||
{
|
{
|
||||||
@ -290,18 +328,32 @@ void UDTFluxDataStorage::AddOrUpdateContest(const FDTFluxContestResponse& Contes
|
|||||||
FDTFluxStage Stage;
|
FDTFluxStage Stage;
|
||||||
Stage.Id = StageResp.Id;
|
Stage.Id = StageResp.Id;
|
||||||
Stage.Name = StageResp.Name;
|
Stage.Name = StageResp.Name;
|
||||||
FDateTime::Parse(StageResp.StartTime, Stage.StartTime);
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("ContestResponse.Stage StartTime = %s"), *StageResp.StartTime);
|
||||||
FDateTime::Parse(StageResp.EndTime, Stage.EndTime);
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("ContestResponse.Stage EndTime = %s"), *StageResp.EndTime);
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("ContestResponse.Stage CutOff = %s"), *StageResp.CutOff);
|
||||||
|
FTimespan StartTimeSpan;
|
||||||
|
FTimespan::Parse(StageResp.StartTime, StartTimeSpan);
|
||||||
|
FTimespan EndTimeSpan;
|
||||||
|
FTimespan::Parse(StageResp.EndTime, EndTimeSpan);
|
||||||
|
FTimespan CutOffTimeSpan;
|
||||||
|
FTimespan::Parse(StageResp.CutOff, CutOffTimeSpan);
|
||||||
|
Stage.StartTime = Contest.Date + StartTimeSpan;
|
||||||
|
Stage.EndTime = Contest.Date + EndTimeSpan;
|
||||||
|
Stage.CutOff = Stage.StartTime + CutOffTimeSpan;
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("STAGE StartTime = %s"), *Stage.StartTime.ToString());
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("STAGE EndTime = %s"), *Stage.EndTime.ToString());
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("STAGE CutOff = %s"), *Stage.CutOff.ToString());
|
||||||
|
|
||||||
Stage.Splits = Splits;
|
Stage.Splits = Splits;
|
||||||
Contest.Stages.Add(Stage);
|
Contest.Stages.Add(Stage);
|
||||||
}
|
}
|
||||||
if(NewContest)
|
if(NewContest)
|
||||||
{
|
{
|
||||||
Contest.Dump();
|
// Contest.Dump();
|
||||||
Contests.Add(Contest);
|
Contests.Add(Contest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Contest.Dump();
|
// Contest.Dump();
|
||||||
Contests.RemoveAt(ContestIdx);
|
Contests.RemoveAt(ContestIdx);
|
||||||
Contests.Insert(Contest, ContestIdx);
|
Contests.Insert(Contest, ContestIdx);
|
||||||
// handle updating contest
|
// handle updating contest
|
||||||
@ -309,10 +361,10 @@ void UDTFluxDataStorage::AddOrUpdateContest(const FDTFluxContestResponse& Contes
|
|||||||
|
|
||||||
void UDTFluxDataStorage::AddOrUpdateParticipant(const FDTFluxTeamListItemResponse& TeamListItemResponse)
|
void UDTFluxDataStorage::AddOrUpdateParticipant(const FDTFluxTeamListItemResponse& TeamListItemResponse)
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("In DataStorage::AddOrUpdateParticipant"));
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("In DataStorage::AddOrUpdateParticipant"));
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("AboutToUpdateOrAdd Participant %d %s %s in Contest%02d "),
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("AboutToUpdateOrAdd Participant %d %s %s in Contest%02d "),
|
||||||
TeamListItemResponse.Bib, *TeamListItemResponse.FirstName, *TeamListItemResponse.LastName,
|
// TeamListItemResponse.Bib, *TeamListItemResponse.FirstName, *TeamListItemResponse.LastName,
|
||||||
TeamListItemResponse.ContestId);
|
// TeamListItemResponse.ContestId);
|
||||||
FDTFluxParticipant Participant;
|
FDTFluxParticipant Participant;
|
||||||
Participant.Bib = TeamListItemResponse.Bib;
|
Participant.Bib = TeamListItemResponse.Bib;
|
||||||
Participant.Category = TeamListItemResponse.Category;
|
Participant.Category = TeamListItemResponse.Category;
|
||||||
@ -330,15 +382,15 @@ void UDTFluxDataStorage::AddOrUpdateParticipant(const FDTFluxTeamListItemRespons
|
|||||||
{
|
{
|
||||||
if(Contest.Id == TeamListItemResponse.ContestId)
|
if(Contest.Id == TeamListItemResponse.ContestId)
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("AboutToUpdateOrAdd Participant %d %s %s in Contest%02d "),
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("AboutToUpdateOrAdd Participant %d %s %s in Contest%02d "),
|
||||||
Participant.Bib, *Participant.Person1.FirstName, *Participant.Person1.LastName,
|
// Participant.Bib, *Participant.Person1.FirstName, *Participant.Person1.LastName,
|
||||||
Contest.Id);
|
// Contest.Id);
|
||||||
|
|
||||||
Contest.AddParticipant(Participant);
|
Contest.AddParticipant(Participant);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("Contest%02d has now %04d Participants"), Contest.Id,
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("Contest%02d has now %04d Participants"), Contest.Id,
|
||||||
Contest.Participants.Num());
|
// Contest.Participants.Num());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,16 +441,21 @@ void UDTFluxDataStorage::UpdateStageRanking(const FDTFluxStageRankingResponse& S
|
|||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Found Stage::%02d "),Stage.Id);
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("Found Stage::%02d "),Stage.Id);
|
||||||
// Cleaning StageRanking
|
// Cleaning StageRanking
|
||||||
Stage.StageRanking.Empty();
|
Stage.StageRanking.Empty();
|
||||||
for(auto& StageRanking: StageRankingResponse.Datas )
|
for(auto& StageRankingResp: StageRankingResponse.Datas )
|
||||||
{
|
{
|
||||||
FDTFluxStageRanking NewStageRanking;
|
FDTFluxStageRanking NewStageRanking;
|
||||||
NewStageRanking.TimeRun = StageRanking.TimeRun;
|
NewStageRanking.TimeRun = StageRankingResp.TimeRun;
|
||||||
NewStageRanking.TimeStart = StageRanking.TimeStart;
|
FTimespan StartTimeSpan;
|
||||||
NewStageRanking.TimeTransition = StageRanking.TimeTransition;
|
FTimespan::Parse(StageRankingResp.TimeStart, StartTimeSpan);
|
||||||
NewStageRanking.TimeSwim = StageRanking.TimeSwim;
|
NewStageRanking.TimeStart = Contest.Date + StartTimeSpan;
|
||||||
NewStageRanking.Bib = StageRanking.Bib;
|
NewStageRanking.TimeTransition = StageRankingResp.TimeTransition;
|
||||||
NewStageRanking.Gap = StageRanking.Gap;
|
NewStageRanking.TimeSwim = StageRankingResp.TimeSwim;
|
||||||
NewStageRanking.Rank = StageRanking.Rank;
|
NewStageRanking.Bib = StageRankingResp.Bib;
|
||||||
|
NewStageRanking.Gap = StageRankingResp.Gap;
|
||||||
|
NewStageRanking.Rank = StageRankingResp.Rank;
|
||||||
|
NewStageRanking.SpeedRunning = StageRankingResp.SpeedRunning;
|
||||||
|
NewStageRanking.SpeedSwim = StageRankingResp.SpeedSwim;
|
||||||
|
NewStageRanking.SpeedTotal = StageRankingResp.SpeedTotal;
|
||||||
Stage.StageRanking.Add(NewStageRanking);
|
Stage.StageRanking.Add(NewStageRanking);
|
||||||
Stage.SortStageRanking();
|
Stage.SortStageRanking();
|
||||||
// UE_LOG(LogDTFluxAPI, Log,
|
// UE_LOG(LogDTFluxAPI, Log,
|
||||||
@ -414,15 +471,8 @@ void UDTFluxDataStorage::UpdateStageRanking(const FDTFluxStageRankingResponse& S
|
|||||||
void UDTFluxDataStorage::AddSplitSensorResult(FDTFluxSplitSensorItemResponse Response)
|
void UDTFluxDataStorage::AddSplitSensorResult(FDTFluxSplitSensorItemResponse Response)
|
||||||
{
|
{
|
||||||
// Send SplitSensor Result to BP
|
// Send SplitSensor Result to BP
|
||||||
FDTFluxStage CurrentStage;
|
|
||||||
if(GetStage(CurrentStage, Response.StageID))
|
|
||||||
{
|
|
||||||
// this is an empty stage
|
|
||||||
if(CurrentStage.Id == -1 )
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,3 +520,56 @@ const FString UDTFluxDataStorage::GetConcurrentFormatedName(int Bib, bool Trunca
|
|||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UDTFluxDataStorage::GetFirstStageOfContest(const int ContestId, FDTFluxStage& Stage)
|
||||||
|
{
|
||||||
|
if(Contests.IsEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
if(Contest.Id == ContestId)
|
||||||
|
{
|
||||||
|
Contest.Stages.Sort([](const FDTFluxStage& A, const FDTFluxStage& B)
|
||||||
|
{
|
||||||
|
return A.Id < B.Id;
|
||||||
|
});
|
||||||
|
if(Contest.Stages.IsValidIndex(0))
|
||||||
|
{
|
||||||
|
Stage = Contest.Stages[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxDataStorage::DumpContest()
|
||||||
|
{
|
||||||
|
for(const auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("Contest%02d with name %s : Date %s\n"),
|
||||||
|
Contest.Id, *Contest.Name, *Contest.Date.ToString());
|
||||||
|
// UE_LOG(LogDTFluxAPI, Warning, TEXT("Participants :\n"));
|
||||||
|
// for(const auto& Participant : Contest.Participants)
|
||||||
|
// {
|
||||||
|
// Participant.Dump();
|
||||||
|
// }
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("Stages :\n"));
|
||||||
|
for(const auto& Stage : Contest.Stages)
|
||||||
|
{
|
||||||
|
Stage.Dump();
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("ContestRanking :\n"));
|
||||||
|
for(const auto& ContestRankingItem : Contest.ContestRanking)
|
||||||
|
{
|
||||||
|
ContestRankingItem.Dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -34,63 +34,7 @@ void UDTFluxSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|||||||
FDateTime Now = FDateTime::Now();
|
FDateTime Now = FDateTime::Now();
|
||||||
FDateTime Send1Min = Now + FTimespan::FromMinutes(1);
|
FDateTime Send1Min = Now + FTimespan::FromMinutes(1);
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("TEST timer timeSpan Duration : %s"), *Send1Min.ToString());
|
UE_LOG(LogDTFluxAPI, Log, TEXT("TEST timer timeSpan Duration : %s"), *Send1Min.ToString());
|
||||||
// SetTimerEvent( Send1Min );
|
|
||||||
// UWorld* World = nullptr;
|
|
||||||
// TIndirectArray<FWorldContext> WorldCtx = GEngine->GetWorldContexts();
|
|
||||||
// for(const auto& Ctx : WorldCtx)
|
|
||||||
// {
|
|
||||||
// EWorldType::Type Type = Ctx.WorldType.GetValue();
|
|
||||||
// switch(Type)
|
|
||||||
// {
|
|
||||||
// case EWorldType::None:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is None "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::Editor:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is EDITOR "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::Game:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is GAME "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::GamePreview :
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is GamePreview "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::EditorPreview:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is EditorPreview "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::Inactive:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is Inactive "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::PIE:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is PIE "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// case EWorldType::GameRPC:
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("Ctx world is GameRPC "));
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if(World)
|
|
||||||
// {
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("World IS NOT NULL"));
|
|
||||||
//
|
|
||||||
// World->GetTimerManager().SetTimer(
|
|
||||||
// TestTimerHandle, this, &UDTFluxSubsystem::TestTimers, 1.0f, true);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("World IS NULL:-D"));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// WsServer Event binding
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDTFluxSubsystem::Deinitialize()
|
void UDTFluxSubsystem::Deinitialize()
|
||||||
@ -185,8 +129,6 @@ void UDTFluxSubsystem::Tick(float DeltaTime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UDTFluxSubsystem::RequestRaceDatas()
|
void UDTFluxSubsystem::RequestRaceDatas()
|
||||||
{
|
{
|
||||||
WsClient->SendMessage(TEXT("{\"path\": \"race-datas\"}"));
|
WsClient->SendMessage(TEXT("{\"path\": \"race-datas\"}"));
|
||||||
@ -260,7 +202,6 @@ void UDTFluxSubsystem::BroadcastTimerEvent()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UDTFluxSubsystem::SetTimerEvent(const FDateTime& When)
|
void UDTFluxSubsystem::SetTimerEvent(const FDateTime& When)
|
||||||
{
|
{
|
||||||
FTimespan TimeSpan = FDateTime::Now() - When;
|
FTimespan TimeSpan = FDateTime::Now() - When;
|
||||||
@ -270,14 +211,12 @@ void UDTFluxSubsystem::SetTimerEvent(const FDateTime& When)
|
|||||||
// AddTimer(When, )
|
// AddTimer(When, )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UDTFluxSubsystem::AddTimer(FDateTime Time, FOnTimer NewTimer)
|
bool UDTFluxSubsystem::AddTimer(FDateTime Time, FOnTimer NewTimer)
|
||||||
{
|
{
|
||||||
Timer.Add(Time, NewTimer);
|
Timer.Add(Time, NewTimer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* END TIMER HANDLING
|
* END TIMER HANDLING
|
||||||
***/
|
***/
|
||||||
@ -403,6 +342,7 @@ void UDTFluxSubsystem::WsReceivedMessage( const FString& MessageReceived)
|
|||||||
UE_LOG(LogDTFluxAPI, Error, TEXT("Message %s is not a valid split-sensor data"), *MessageReceived)
|
UE_LOG(LogDTFluxAPI, Error, TEXT("Message %s is not a valid split-sensor data"), *MessageReceived)
|
||||||
}
|
}
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("Received split-sensor data"));
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Received split-sensor data"));
|
||||||
|
ProcessSplitSensor(SplitSensorResponse);
|
||||||
Event.WsResponseType = SplitSensor;
|
Event.WsResponseType = SplitSensor;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -479,6 +419,7 @@ void UDTFluxSubsystem::ProcessRaceDataResponse(const FDTFluxRaceDataResponse& Da
|
|||||||
Event.WsResponseType = RaceData;
|
Event.WsResponseType = RaceData;
|
||||||
Event.RawData = "race-data";
|
Event.RawData = "race-data";
|
||||||
OnWsEvent.Broadcast(Event);
|
OnWsEvent.Broadcast(Event);
|
||||||
|
OnRaceDataReceived.Broadcast();
|
||||||
// UE_LOG(LogDTFluxAPI, Log, TEXT("New Contest Size %d"), DataStorage->Contests.Num())
|
// UE_LOG(LogDTFluxAPI, Log, TEXT("New Contest Size %d"), DataStorage->Contests.Num())
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -537,15 +478,40 @@ void UDTFluxSubsystem::ProcessSplitSensor(const FDTFluxSplitSensorResponse& Spli
|
|||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
||||||
|
for(auto& SplitSensorItem : SplitSensorResponse.Datas)
|
||||||
|
{
|
||||||
|
FDTFluxSplitRanking NewRanking = DataStorage->AddSplitRanking(SplitSensorItem);
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Checking SplitStatus ..."))
|
||||||
|
EDTFluxSplitType SplitType = DataStorage->GetSplitStatus(SplitSensorItem.ContestID,
|
||||||
|
SplitSensorItem.StageID, SplitSensorItem.SplitID);
|
||||||
|
switch(SplitType)
|
||||||
|
{
|
||||||
|
case PreFinnishSplit:
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("SplitSensor %d for Stage%02d in Contest%02d is a Prefinish Sensor"),
|
||||||
|
SplitSensorItem.SplitID, SplitSensorItem.StageID, SplitSensorItem.ContestID);
|
||||||
|
OnSpotter.Broadcast(NewRanking);
|
||||||
|
break;
|
||||||
|
case FinishSplit:
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("SplitSensor %d for Stage%02d in Contest%02d is a Finish Sensor"),
|
||||||
|
SplitSensorItem.SplitID, SplitSensorItem.StageID, SplitSensorItem.ContestID);
|
||||||
|
OnFinisher.Broadcast(NewRanking);
|
||||||
|
break;
|
||||||
|
case NormalSplit:
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("SplitSensor %d for Stage%02d in Contest%02d is a Normal Split"),
|
||||||
|
SplitSensorItem.SplitID, SplitSensorItem.StageID, SplitSensorItem.ContestID);
|
||||||
|
OnSplitSensor.Broadcast(NewRanking);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("SplitSensor %d for Stage%02d in Contest%02d %s"),
|
||||||
|
SplitSensorItem.SplitID, SplitSensorItem.StageID, SplitSensorItem.ContestID,
|
||||||
|
*UEnum::GetValueAsString(SplitType));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
FDTFluxWsResponseEvent Event;
|
FDTFluxWsResponseEvent Event;
|
||||||
Event.WsResponseType = SplitSensor;
|
Event.WsResponseType = SplitSensor;
|
||||||
Event.RawData = "split-sensor";
|
Event.RawData = "split-sensor";
|
||||||
OnWsEvent.Broadcast(Event);
|
OnWsEvent.Broadcast(Event);
|
||||||
// determine if SplitSensorResponse come from a finisher spot
|
|
||||||
if(DataStorage->IsFinisherSplit(SplitSensorResponse))
|
|
||||||
{
|
|
||||||
FDTFluxFinisher Finisher = DataStorage->GetFinisherStatus(SplitSensorResponse);
|
|
||||||
OnFinisher.Broadcast(Finisher);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,189 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DTFluxSubsystem/DTFluxSubsystemTimer.h"
|
||||||
|
|
||||||
|
#include "DTFluxAPILog.h"
|
||||||
|
#include "DTFluxSubsystem/DTFluxSubsystem.h"
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
|
{
|
||||||
|
Super::Initialize(Collection);
|
||||||
|
|
||||||
|
UDTFluxSubsystem* Subsystem = GetDTFluxSubSystem();
|
||||||
|
Subsystem->OnRaceDataReceived.AddDynamic(this, &UDTFluxSubsystemTimer::OnDataStorageInit);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::Deinitialize()
|
||||||
|
{
|
||||||
|
Super::Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::Tick(float DeltaTime)
|
||||||
|
{
|
||||||
|
Super::Tick(DeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::OnDataStorageInit()
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("DataStorage Has been Set Or Updated"));
|
||||||
|
UDTFluxDataStorage* DataStorage = GetDTFluxDataStorage();
|
||||||
|
|
||||||
|
for(const auto&Contest : DataStorage->Contests)
|
||||||
|
{
|
||||||
|
for (const auto& Stage: Contest.Stages)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
|
||||||
|
FDTFluxContestTimerHandle StartContestTimerHandle;
|
||||||
|
StartContestTimerHandle.Type = EDTFluxTimerEventType::StageStart;
|
||||||
|
StartContestTimerHandle.ContestId = Contest.Id;
|
||||||
|
StartContestTimerHandle.StageId = Stage.Id;
|
||||||
|
|
||||||
|
FDTFluxContestTimerHandle CutOffContestTimerHandle;
|
||||||
|
CutOffContestTimerHandle.Type = EDTFluxTimerEventType::StageCutOff;
|
||||||
|
CutOffContestTimerHandle.ContestId = Contest.Id;
|
||||||
|
CutOffContestTimerHandle.StageId = Stage.Id;
|
||||||
|
|
||||||
|
float StartTimeTriggerSeconds = GetSecondsFrom(Stage.StartTime);
|
||||||
|
float CutOffTimeTriggerSeconds = GetSecondsFrom(Stage.CutOff);
|
||||||
|
if( StartTimeTriggerSeconds > 0)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Can Set Time to %04f Seconds"), StartTimeTriggerSeconds );
|
||||||
|
World->GetTimerManager().SetTimer(StartContestTimerHandle.Handle, this, &UDTFluxSubsystemTimer::OnStartTimer, StartTimeTriggerSeconds);
|
||||||
|
World->GetTimerManager().SetTimer(CutOffContestTimerHandle.Handle, this, &UDTFluxSubsystemTimer::OnCutOffTimer, CutOffTimeTriggerSeconds);
|
||||||
|
Timers.Add(StartContestTimerHandle);
|
||||||
|
Timers.Add(CutOffContestTimerHandle);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("Unable to Set Time to %04f Seconds"), StartTimeTriggerSeconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::AddCutoffTimer(const int ContestID, const int StageID)
|
||||||
|
{
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
FTimerHandle Timer;
|
||||||
|
World->GetTimerManager().SetTimer(Timer, this, &UDTFluxSubsystemTimer::OnStartTimer, 1.0, true);
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("AddCutoffTimer Added"));
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Error,
|
||||||
|
TEXT("UDTFluxSubsystemTimer::AddCutoffTimer Cannot have the World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::AddStageStartedTimer(const int ContestID, const int StageID)
|
||||||
|
{
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
FTimerHandle Timer;
|
||||||
|
World->GetTimerManager().SetTimer(Timer, this, &UDTFluxSubsystemTimer::OnStartTimer, 1.0, true);
|
||||||
|
UE_LOG(LogDTFluxAPI, Warning, TEXT("AddStageStartedTimer Added"));
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Error,
|
||||||
|
TEXT("UDTFluxSubsystemTimer::AddStageStartedTimer Cannot have the World"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::OnStartTimer()
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
int Idx = 0 ;
|
||||||
|
for(auto& Timer : Timers)
|
||||||
|
{
|
||||||
|
if(Timer.Type == EDTFluxTimerEventType::StageStart)
|
||||||
|
{
|
||||||
|
if(World->GetTimerManager().GetTimerRemaining(Timer.Handle) == 0)
|
||||||
|
{
|
||||||
|
OnStageStarted.Broadcast(Timer.ContestId, Timer.StageId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Idx++;
|
||||||
|
}
|
||||||
|
if(Timers.IsValidIndex(Idx))
|
||||||
|
{
|
||||||
|
Timers.RemoveAt(Idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void UDTFluxSubsystemTimer::OnCutOffTimer()
|
||||||
|
{
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
int Idx = 0 ;
|
||||||
|
for(auto& Timer : Timers)
|
||||||
|
{
|
||||||
|
if(Timer.Type == EDTFluxTimerEventType::StageCutOff)
|
||||||
|
{
|
||||||
|
if(World->GetTimerManager().GetTimerRemaining(Timer.Handle) == 0)
|
||||||
|
{
|
||||||
|
OnCutoff.Broadcast(Timer.ContestId, Timer.StageId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Idx++;
|
||||||
|
}
|
||||||
|
if(Timers.IsValidIndex(Idx))
|
||||||
|
{
|
||||||
|
Timers.RemoveAt(Idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::ClearTimer(FDTFluxContestTimerHandle TimerHandle)
|
||||||
|
{
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if(World)
|
||||||
|
{
|
||||||
|
World->GetTimerManager().ClearTimer(TimerHandle.Handle);
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("Cannot Clear Timer %s of type %s for Stage%02d of Contest%02d"),
|
||||||
|
*TimerHandle.Handle.ToString(), *UEnum::GetValueAsString(TimerHandle.Type),
|
||||||
|
TimerHandle.StageId, TimerHandle.ContestId)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystemTimer::ClearTimer(const int HandleIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UDTFluxSubsystem* UDTFluxSubsystemTimer::GetDTFluxSubSystem()
|
||||||
|
{
|
||||||
|
return GEngine->GetEngineSubsystem<UDTFluxSubsystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
UDTFluxDataStorage* UDTFluxSubsystemTimer::GetDTFluxDataStorage()
|
||||||
|
{
|
||||||
|
return GetDTFluxSubSystem()->GetDataStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
float UDTFluxSubsystemTimer::GetSecondsFrom(const FDateTime When)
|
||||||
|
{
|
||||||
|
FTimespan Delta = When - FDateTime::Now();
|
||||||
|
return static_cast<float>(Delta.GetTotalSeconds()) ;
|
||||||
|
}
|
||||||
|
|
||||||
@ -5,3 +5,24 @@
|
|||||||
|
|
||||||
#include "DTFluxModel/DTFluxModel.h"
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
|
|
||||||
|
EDTFluxStageStatusType UDTFluxModelHelper::GetStatusType(const int ContestID, const int StageID,
|
||||||
|
UDTFluxDataStorage* DataStorage)
|
||||||
|
{
|
||||||
|
EDTFluxStageStatusType StageStatus = UnknownStatus;
|
||||||
|
|
||||||
|
FDTFluxStage SelectedStage;
|
||||||
|
if( DataStorage->GetStage(ContestID, StageID, SelectedStage))
|
||||||
|
{
|
||||||
|
StageStatus = StageWaiting;
|
||||||
|
FDateTime Now = FDateTime::Now();
|
||||||
|
if(SelectedStage.StartTime <= Now)
|
||||||
|
{
|
||||||
|
StageStatus = StageStarted;
|
||||||
|
}
|
||||||
|
if(SelectedStage.CutOff <= Now)
|
||||||
|
{
|
||||||
|
StageStatus = StageEnded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StageStatus;
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "AvaText3DComponent.h"
|
#include "AvaText3DComponent.h"
|
||||||
#include "Components/ActorComponent.h"
|
#include "Components/ActorComponent.h"
|
||||||
|
#include "DTFluxDataStorage/DTFluxDataStorage.h"
|
||||||
#include "DTFluxCountDownComponent.generated.h"
|
#include "DTFluxCountDownComponent.generated.h"
|
||||||
|
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ protected:
|
|||||||
int64 InternalDuration;
|
int64 InternalDuration;
|
||||||
bool IsWaiting;
|
bool IsWaiting;
|
||||||
bool IsCounting;
|
bool IsCounting;
|
||||||
|
UDTFluxDataStorage* DataStorage;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -51,11 +53,21 @@ public:
|
|||||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
||||||
FActorComponentTickFunction* ThisTickFunction) override;
|
FActorComponentTickFunction* ThisTickFunction) override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
||||||
void SetGoTime(FDateTime NewGoTime);
|
void SetGoTime(FDateTime NewGoTime);
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
||||||
void SetDuration(int32 NewDuration);
|
void SetDuration(int32 NewDuration);
|
||||||
|
|
||||||
|
// set the current stage
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
||||||
|
void SetStage(const int ContestId, const int StageId){};
|
||||||
|
|
||||||
|
// set the current contest
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
||||||
|
void SetContest(const int ContestId){};
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Counter")
|
||||||
void SetTarget(UAvaText3DComponent* TextComponent);
|
void SetTarget(UAvaText3DComponent* TextComponent);
|
||||||
|
|
||||||
|
|||||||
@ -16,26 +16,9 @@ struct FDTFluxParticipant;
|
|||||||
struct FDTFluxStage;
|
struct FDTFluxStage;
|
||||||
struct FDTFluxContest;
|
struct FDTFluxContest;
|
||||||
|
|
||||||
UENUM(BlueprintType, Category="DTFlux|DataStorage")
|
|
||||||
// ReSharper disable once IdentifierTypo
|
|
||||||
enum EDTFluxDataStorageEventType : uint8
|
|
||||||
{
|
|
||||||
UnknownEvent = 0 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
ParticipantCreateEvent = 1 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
ParticipantUpdateEvent = 2 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
ParticipantDeleteEvent = 3 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
ParticipantStatusUpdateEvent = 4 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
RaceDataCreateEvent = 5 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
RaceDataUpdateEvent = 6 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
RaceDataDeleteEvent = 7 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
ContestRankingUpdate = 8 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
StageRankingUpdate = 9 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
SplitRankingUpdate = 10 UMETA(DisplayName="ParticipantUpdateEvent"),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDataStorageUpdated, FString, What);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDataStorageUpdated, FString, What);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDataStorageInit);
|
||||||
|
|
||||||
UCLASS(BlueprintType, Category="DTFlux|Datastorage")
|
UCLASS(BlueprintType, Category="DTFlux|Datastorage")
|
||||||
class DTFLUXAPI_API UDTFluxDataStorage : public UObject
|
class DTFLUXAPI_API UDTFluxDataStorage : public UObject
|
||||||
@ -46,6 +29,11 @@ class DTFLUXAPI_API UDTFluxDataStorage : public UObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|DataStorage|Event")
|
||||||
|
FOnDataStorageInit OnDataStorageInit;
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|DataStorage|Event")
|
||||||
|
FOnDataStorageUpdated OnDataStorageUpdated;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|DataStorage")
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|DataStorage")
|
||||||
TArray<FDTFluxContest> Contests;
|
TArray<FDTFluxContest> Contests;
|
||||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|DataStorage")
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|DataStorage")
|
||||||
@ -70,11 +58,12 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
||||||
bool GetContest(FDTFluxContest& OutContest, const int& ContestId);
|
bool GetContest(const int ContestId, FDTFluxContest& OutContest);
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
||||||
TArray<FDTFluxStage> GetStages(const int ContestId);
|
TArray<FDTFluxStage> GetStages(const int ContestId);
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
||||||
bool GetStage( FDTFluxStage& Stage,const int& StageId = -1);
|
bool GetStage( const int ContestId, const int StageId, FDTFluxStage& OutStage);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
||||||
TArray<FDTFluxParticipant> GetParticipants(const int ContestId = -1);
|
TArray<FDTFluxParticipant> GetParticipants(const int ContestId = -1);
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
@ -123,6 +112,13 @@ public:
|
|||||||
void ChangeCurrentContest();
|
void ChangeCurrentContest();
|
||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|DataStorage")
|
||||||
const FString GetConcurrentFormatedName( int Bib, bool Truncate = true, int MaxSize = 20);
|
const FString GetConcurrentFormatedName( int Bib, bool Truncate = true, int MaxSize = 20);
|
||||||
|
UFUNCTION()
|
||||||
|
bool GetFirstStageOfContest(const int ContestId, FDTFluxStage& Stage);
|
||||||
|
void DumpContest();
|
||||||
|
UFUNCTION()
|
||||||
|
bool GetSplit(const int ContestID, const int StageID, const int SplitID, FDTFluxSplit& OutSplit);
|
||||||
|
UFUNCTION()
|
||||||
|
FDTFluxSplitRanking AddSplitRanking(const FDTFluxSplitSensorItemResponse& SplitSensorItem);
|
||||||
|
UFUNCTION()
|
||||||
|
EDTFluxSplitType GetSplitStatus(int ContestID, int StageID, int SplitID);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -144,7 +144,7 @@ public:
|
|||||||
FString Gap;
|
FString Gap;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
FString Time;
|
FString Time;
|
||||||
void Dump()
|
void Dump () const
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log,
|
UE_LOG(LogDTFluxAPI, Log,
|
||||||
TEXT("FDTFluxContestRanking ->> \n \"rank\" : %d, Participant with Bib %d \"Gap\" : %s, \"Time\" : %s "),
|
TEXT("FDTFluxContestRanking ->> \n \"rank\" : %d, Participant with Bib %d \"Gap\" : %s, \"Time\" : %s "),
|
||||||
@ -170,13 +170,21 @@ public:
|
|||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
FString TimeRun;
|
FString TimeRun;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
FString TimeStart;
|
FDateTime TimeStart;
|
||||||
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
|
float SpeedRunning;
|
||||||
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
|
float SpeedTotal;
|
||||||
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
|
float SpeedSwim;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Dump() const
|
void Dump() const
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
|
UE_LOG(LogDTFluxAPI, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
|
||||||
Rank, Bib, *Gap, *TimeSwim,
|
Rank, Bib, *Gap, *TimeSwim,
|
||||||
*TimeTransition, *TimeRun, *TimeStart);
|
*TimeTransition, *TimeRun, *TimeStart.ToString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,12 +200,14 @@ public:
|
|||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
FString Time;
|
FString Time;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
int Rank;
|
int Rank = 0;
|
||||||
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
|
bool Display = false;
|
||||||
void Dump() const
|
void Dump() const
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("SplitGapItem"))
|
UE_LOG(LogDTFluxAPI, Log, TEXT("SplitGapItem"))
|
||||||
// Participant.Dump();
|
// Participant.Dump();
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("Bib %02d Gap %s"), Bib, *Gap);
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Bib %02d Rank %02d Gap %s Time %s"), Bib, Rank, *Gap, *Time);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,12 +221,12 @@ public:
|
|||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Model")
|
||||||
FString Name;
|
FString Name;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||||
TArray<FDTFluxSplitRanking> SplitGaps;
|
TArray<FDTFluxSplitRanking> SplitRankings;
|
||||||
|
|
||||||
void Dump() const
|
void Dump() const
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("Split %02d::%s *****\n"), Id, *Name);
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Split %02d::%s *****\n"), Id, *Name);
|
||||||
for(const auto& SplitGapItem : SplitGaps)
|
for(const auto& SplitGapItem : SplitRankings)
|
||||||
{
|
{
|
||||||
SplitGapItem.Dump();
|
SplitGapItem.Dump();
|
||||||
}
|
}
|
||||||
@ -227,14 +237,16 @@ public:
|
|||||||
FDTFluxSplitRanking NewSplitGapItem;
|
FDTFluxSplitRanking NewSplitGapItem;
|
||||||
NewSplitGapItem.Bib = SplitRankingItemResp.Bib;
|
NewSplitGapItem.Bib = SplitRankingItemResp.Bib;
|
||||||
NewSplitGapItem.Gap = SplitRankingItemResp.Gap;
|
NewSplitGapItem.Gap = SplitRankingItemResp.Gap;
|
||||||
if(SplitGaps.IsEmpty())
|
NewSplitGapItem.Rank = SplitRankingItemResp.Rank;
|
||||||
|
NewSplitGapItem.Time = SplitRankingItemResp.Time;
|
||||||
|
if(SplitRankings.IsEmpty())
|
||||||
{
|
{
|
||||||
SplitGaps.Add(NewSplitGapItem);
|
SplitRankings.Add(NewSplitGapItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool Update = true;
|
bool Update = true;
|
||||||
int Idx = 0;
|
int Idx = 0;
|
||||||
for(auto& SplitGapItem : SplitGaps)
|
for(auto& SplitGapItem : SplitRankings)
|
||||||
{
|
{
|
||||||
if(SplitGapItem.Bib == SplitRankingItemResp.Bib)
|
if(SplitGapItem.Bib == SplitRankingItemResp.Bib)
|
||||||
{
|
{
|
||||||
@ -244,13 +256,46 @@ public:
|
|||||||
}
|
}
|
||||||
if(Update)
|
if(Update)
|
||||||
{
|
{
|
||||||
if(SplitGaps.IsValidIndex(Idx))
|
if(SplitRankings.IsValidIndex(Idx))
|
||||||
{
|
{
|
||||||
SplitGaps.RemoveAt(Idx);
|
SplitRankings.RemoveAt(Idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SplitGaps.Add(NewSplitGapItem);
|
SplitRankings.Add(NewSplitGapItem);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SortByRank()
|
||||||
|
{
|
||||||
|
SplitRankings.Sort([](const FDTFluxSplitRanking& A, const FDTFluxSplitRanking& B)
|
||||||
|
{
|
||||||
|
if(A.Rank == 0 && B.Rank == 0)
|
||||||
|
return true;
|
||||||
|
return A.Rank < B.Rank;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FDTFluxSplitRanking> GetSplitRanking(const int From = 0, const int DisplayNumber = 0)
|
||||||
|
{
|
||||||
|
TArray<FDTFluxSplitRanking> NewSplitRankings;
|
||||||
|
SortByRank();
|
||||||
|
NewSplitRankings.Append(SplitRankings);
|
||||||
|
|
||||||
|
if(From == 0 && DisplayNumber == 0)
|
||||||
|
return NewSplitRankings;
|
||||||
|
for(auto& SRank : SplitRankings)
|
||||||
|
{
|
||||||
|
if(SRank.Rank >= From)
|
||||||
|
{
|
||||||
|
NewSplitRankings.Add(SRank);
|
||||||
|
if(NewSplitRankings.Num() >= DisplayNumber)
|
||||||
|
{
|
||||||
|
return NewSplitRankings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NewSplitRankings;
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
@ -267,6 +312,8 @@ public:
|
|||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||||
FDateTime EndTime;
|
FDateTime EndTime;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||||
|
FDateTime CutOff;
|
||||||
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||||
TArray<FDTFluxSplit> Splits;
|
TArray<FDTFluxSplit> Splits;
|
||||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||||
TArray<FDTFluxStageRanking> StageRanking;
|
TArray<FDTFluxStageRanking> StageRanking;
|
||||||
@ -288,6 +335,31 @@ public:
|
|||||||
Split.Dump();
|
Split.Dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EDTFluxSplitType GetSplitType(int SplitID)
|
||||||
|
{
|
||||||
|
int SplitCount = Splits.Num();
|
||||||
|
//sort by ID
|
||||||
|
Splits.Sort([](const FDTFluxSplit& A, const FDTFluxSplit& B)
|
||||||
|
{
|
||||||
|
return A.Id < B.Id;
|
||||||
|
});
|
||||||
|
int SplitIndex = Splits.IndexOfByPredicate([SplitID](const FDTFluxSplit& Split)
|
||||||
|
{
|
||||||
|
return Split.Id == SplitID;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(SplitCount -2 == SplitIndex )
|
||||||
|
{
|
||||||
|
return EDTFluxSplitType::PreFinnishSplit;
|
||||||
|
}
|
||||||
|
if(SplitCount -1 == SplitIndex)
|
||||||
|
{
|
||||||
|
return EDTFluxSplitType::FinishSplit;
|
||||||
|
}
|
||||||
|
return EDTFluxSplitType::NormalSplit;
|
||||||
|
|
||||||
};
|
};
|
||||||
void SortStageRanking()
|
void SortStageRanking()
|
||||||
{
|
{
|
||||||
@ -410,13 +482,10 @@ public:
|
|||||||
NewRanking.Bib, NewRanking.Rank, Id );
|
NewRanking.Bib, NewRanking.Rank, Id );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ContestRanking.Add(NewRanking);
|
ContestRanking.Add(NewRanking);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void Dump()
|
void Dump()
|
||||||
{
|
{
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("CONTEST DUMP BEGIN *****%s::%02d *****\n"), *Name, Id);
|
UE_LOG(LogDTFluxAPI, Log, TEXT("CONTEST DUMP BEGIN *****%s::%02d *****\n"), *Name, Id);
|
||||||
@ -445,7 +514,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType, Category="FDTFlux|Model")
|
USTRUCT(BlueprintType, Category="FDTFlux|Model")
|
||||||
struct FDTFluxFinisher
|
struct DTFLUXAPI_API FDTFluxFinisher
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@ -457,9 +526,8 @@ struct FDTFluxFinisher
|
|||||||
FDTFluxStageRanking CurrentRanking;
|
FDTFluxStageRanking CurrentRanking;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType, Category="DTFlux|Subsystem|Events")
|
USTRUCT(BlueprintType, Category="DTFlux|Subsystem|Events")
|
||||||
struct FDTFluxWsResponseEvent
|
struct DTFLUXAPI_API FDTFluxWsResponseEvent
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@ -468,3 +536,27 @@ struct FDTFluxWsResponseEvent
|
|||||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
FString RawData;
|
FString RawData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Subsystem|Events")
|
||||||
|
struct DTFLUXAPI_API FDTFluxStageFinished
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
|
int ContestId = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
|
int StageId = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
|
TArray<FDTFluxStageRanking> Rankings;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Subsystem|Events")
|
||||||
|
struct DTFLUXAPI_API FDTFluxContestFinished
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
|
int ContestId = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category="DTFlux|Subsystem|Events")
|
||||||
|
TArray<FDTFluxStageRanking> Rankings;
|
||||||
|
};
|
||||||
|
|||||||
@ -39,6 +39,8 @@ public:
|
|||||||
FString StartTime;
|
FString StartTime;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString EndTime;
|
FString EndTime;
|
||||||
|
UPROPERTY()
|
||||||
|
FString CutOff;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ public:
|
|||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString Name;
|
FString Name;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString Date;
|
FDateTime Date;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
TArray<FStageResponse> Stages;
|
TArray<FStageResponse> Stages;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
@ -124,11 +126,11 @@ public:
|
|||||||
UPROPERTY();
|
UPROPERTY();
|
||||||
FString TimeStart;
|
FString TimeStart;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString SpeedSwim;
|
float SpeedSwim;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString SpeedRunning;
|
float SpeedRunning;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString SpeedTotal;
|
float SpeedTotal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -26,9 +26,12 @@ class UDTFluxProjectSettings;
|
|||||||
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTimerTriggered);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTimerTriggered);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnRaceDataReceived);
|
||||||
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnTimer, FString, TimerName);
|
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnTimer, FString, TimerName);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnWsEvent, FDTFluxWsResponseEvent, WsResponseEvent);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnWsEvent, FDTFluxWsResponseEvent, WsResponseEvent);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFinisher, FDTFluxFinisher, Finisher);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFinisher, FDTFluxSplitRanking, FinisherData);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSpotter, FDTFluxSplitRanking, SpotterData);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSplitSensor, FDTFluxSplitRanking, ParticipantSplitData);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnContestBegin, int, ContestId);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnContestBegin, int, ContestId);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStageBegin, int, ContestId, int, StageId);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStageBegin, int, ContestId, int, StageId);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnTimesUp, int, ContestId, int, StageId);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnTimesUp, int, ContestId, int, StageId);
|
||||||
@ -104,6 +107,10 @@ public:
|
|||||||
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
FOnWsEvent OnWsEvent;
|
FOnWsEvent OnWsEvent;
|
||||||
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
|
FOnSplitSensor OnSplitSensor;
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
|
FOnSpotter OnSpotter;
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
FOnFinisher OnFinisher;
|
FOnFinisher OnFinisher;
|
||||||
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
FOnContestBegin OnContestBegin;
|
FOnContestBegin OnContestBegin;
|
||||||
@ -113,6 +120,8 @@ public:
|
|||||||
FOnTimesUp OnTimesUp;
|
FOnTimesUp OnTimesUp;
|
||||||
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
FOnRestTimeBegin FOnRestTimeBegin;
|
FOnRestTimeBegin FOnRestTimeBegin;
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Events")
|
||||||
|
FOnRaceDataReceived OnRaceDataReceived;
|
||||||
|
|
||||||
// UPROPERTY(BlueprintReadWrite, Category="DTFlux|Subsystem|Websocket")
|
// UPROPERTY(BlueprintReadWrite, Category="DTFlux|Subsystem|Websocket")
|
||||||
// int ReconnectTimeout = 60; //seconds
|
// int ReconnectTimeout = 60; //seconds
|
||||||
@ -172,14 +181,5 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category="DTFlux|subsystem")
|
UFUNCTION(BlueprintCallable, Category="DTFlux|subsystem")
|
||||||
bool IsConnected() const;
|
bool IsConnected() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FTimerHandle TestTimerHandle;
|
|
||||||
|
|
||||||
|
|
||||||
void TestTimers()
|
|
||||||
{
|
|
||||||
UE_LOG(LogDTFluxAPI, Log, TEXT("IT WORKS !!!!"));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,84 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DTFluxUtils/DTFluxEnums.h"
|
||||||
|
#include "Subsystems/WorldSubsystem.h"
|
||||||
|
#include "DTFluxSubsystemTimer.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class UDTFluxDataStorage;
|
||||||
|
class UDTFluxSubsystem;
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct FDTFluxContestTimerHandle
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
int ContestId;
|
||||||
|
UPROPERTY()
|
||||||
|
int StageId;
|
||||||
|
UPROPERTY();
|
||||||
|
TEnumAsByte<EDTFluxTimerEventType> Type;
|
||||||
|
UPROPERTY();
|
||||||
|
FTimerHandle Handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnCutoff, int, ContestId, int, StageId);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStageStarted, int, ContestId, int, StageId);
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS(BlueprintType, Category="DTFlux|Timer")
|
||||||
|
class DTFLUXAPI_API UDTFluxSubsystemTimer : public UTickableWorldSubsystem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
/** Implement this for initialization of instances of the system */
|
||||||
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||||
|
|
||||||
|
/** Implement this for deinitialization of instances of the system */
|
||||||
|
virtual void Deinitialize() override;
|
||||||
|
|
||||||
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
|
virtual TStatId GetStatId() const override
|
||||||
|
{
|
||||||
|
RETURN_QUICK_DECLARE_CYCLE_STAT(UDTFluxSubsystemTimer, STATGROUP_Tickables);
|
||||||
|
}
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
TArray<FDTFluxContestTimerHandle> Timers;
|
||||||
|
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Timer")
|
||||||
|
FOnCutoff OnCutoff;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Timer")
|
||||||
|
FOnStageStarted OnStageStarted;
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnDataStorageInit();
|
||||||
|
|
||||||
|
void AddCutoffTimer(const int ContestID, const int StageID);
|
||||||
|
void AddStageStartedTimer(const int ContestID, const int StageID);
|
||||||
|
|
||||||
|
void OnStartTimer();
|
||||||
|
void OnCutOffTimer();
|
||||||
|
|
||||||
|
void ClearTimer(FDTFluxContestTimerHandle TimerHandle);
|
||||||
|
void ClearTimer(const int HandleIndex);
|
||||||
|
|
||||||
|
static UDTFluxSubsystem* GetDTFluxSubSystem();
|
||||||
|
static UDTFluxDataStorage* GetDTFluxDataStorage();
|
||||||
|
|
||||||
|
static float GetSecondsFrom(const FDateTime When);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -53,3 +53,50 @@ enum EDTFluxResponseType: uint8
|
|||||||
WsClosed = 10 UMETA(DisplayName="WsClosed"),
|
WsClosed = 10 UMETA(DisplayName="WsClosed"),
|
||||||
WsError = 11 UMETA(DisplayName="WsError"),
|
WsError = 11 UMETA(DisplayName="WsError"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType, Category="DTFlux|Subsystem")
|
||||||
|
enum EDTFluxSplitType : uint8
|
||||||
|
{
|
||||||
|
UnknownSplitType = 0 UMETA(DisplayName="UnknownSplitType"),
|
||||||
|
NormalSplit = 1 UMETA(DisplayName="NormalSplit"),
|
||||||
|
PreFinnishSplit = 2 UMETA(DisplayName="PreFinnishSplit"),
|
||||||
|
FinishSplit = 3 UMETA(DisplayName="FinishSplit"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UENUM(BlueprintType, Category="DTFlux|DataStorage")
|
||||||
|
// ReSharper disable once IdentifierTypo
|
||||||
|
enum EDTFluxDataStorageEventType : uint8
|
||||||
|
{
|
||||||
|
UnknownEvent = 0 UMETA(DisplayName="ParticipantUpdateEvent"),
|
||||||
|
ParticipantCreateEvent = 1 UMETA(DisplayName="ParticipantUpdateEvent"),
|
||||||
|
ParticipantUpdateEvent = 2 UMETA(DisplayName="ParticipantUpdateEvent"),
|
||||||
|
ParticipantDeleteEvent = 3 UMETA(DisplayName="ParticipantDeleteEvent"),
|
||||||
|
ParticipantStatusUpdateEvent = 4 UMETA(DisplayName="ParticipantUpdateEvent"),
|
||||||
|
RaceDataCreateEvent = 5 UMETA(DisplayName="RaceDataCreateEvent"),
|
||||||
|
RaceDataUpdateEvent = 6 UMETA(DisplayName="RaceDataUpdateEvent"),
|
||||||
|
RaceDataDeleteEvent = 7 UMETA(DisplayName="RaceDataDeleteEvent"),
|
||||||
|
ContestRankingUpdate = 8 UMETA(DisplayName="ContestRankingUpdate"),
|
||||||
|
StageRankingUpdate = 9 UMETA(DisplayName="StageRankingUpdate"),
|
||||||
|
SplitRankingUpdate = 10 UMETA(DisplayName="SplitRankingUpdate"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum EDTFluxTimerEventType : uint8
|
||||||
|
{
|
||||||
|
StageStart = 0 UMETA(DisplayName="StageStart"),
|
||||||
|
StageCutOff = 1 UMETA(DisplayName="StageCutOff"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum EDTFluxStageStatusType : uint8
|
||||||
|
{
|
||||||
|
UnknownStatus = 0 UMETA(DisplayName="UnknownStatus"),
|
||||||
|
StageWaiting = 1 UMETA(DisplayName="StageWaiting"),
|
||||||
|
StageStarted = 2 UMETA(DisplayName="StageStarted"),
|
||||||
|
StageEnded = 3 UMETA(DisplayName="StageCutOff")
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "DTFluxModel/DTFluxModel.h"
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
|
#include "DTFluxSubsystem/DTFluxSubsystem.h"
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
#include "DTFluxUtils.generated.h"
|
#include "DTFluxUtils.generated.h"
|
||||||
|
|
||||||
@ -21,4 +22,101 @@ public:
|
|||||||
{
|
{
|
||||||
return Participant.Person2.FirstName != "";
|
return Participant.Person2.FirstName != "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static TArray<FDTFluxSplitRanking> GetSplitRanking(const int ContestId, const int StageId,
|
||||||
|
const int SplitId, const int From = 0, const int DisplayNumber = 0)
|
||||||
|
{
|
||||||
|
TArray<FDTFluxSplitRanking> SplitRankings;
|
||||||
|
UDTFluxSubsystem* Subsystem = GEngine->GetEngineSubsystem<UDTFluxSubsystem>();
|
||||||
|
TArray<FDTFluxContest> Contests = Subsystem->GetDataStorage()->Contests;
|
||||||
|
for( auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
if(Contest.Id == ContestId)
|
||||||
|
{
|
||||||
|
for( auto& Stage : Contest.Stages)
|
||||||
|
{
|
||||||
|
if(Stage.Id == StageId)
|
||||||
|
{
|
||||||
|
for( auto& Split : Stage.Splits)
|
||||||
|
{
|
||||||
|
if(Split.Id == SplitId)
|
||||||
|
{
|
||||||
|
Split.SortByRank();
|
||||||
|
return Split.GetSplitRanking(From, DisplayNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SplitRankings;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static TArray<FDTFluxStageRanking> GetStageRanking(const int ContestId, const int StageId, const int From = 0, const int DisplayNumber = 0)
|
||||||
|
{
|
||||||
|
TArray<FDTFluxStageRanking> StageRankings;
|
||||||
|
UDTFluxSubsystem* Subsystem = GEngine->GetEngineSubsystem<UDTFluxSubsystem>();
|
||||||
|
TArray<FDTFluxContest> Contests = Subsystem->GetDataStorage()->Contests;
|
||||||
|
for( auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
if(Contest.Id == ContestId)
|
||||||
|
{
|
||||||
|
for( auto& Stage : Contest.Stages)
|
||||||
|
{
|
||||||
|
if(Stage.Id == StageId)
|
||||||
|
{
|
||||||
|
StageRankings = Stage.StageRanking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//CAREFUL Can Be Empty
|
||||||
|
return StageRankings;
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static TArray<FDTFluxContestRanking> GetContestRanking(const int ContestId, const int StageId, const int From = 0, const int DisplayNumber = 0)
|
||||||
|
{
|
||||||
|
TArray<FDTFluxContestRanking> ContestRankings;
|
||||||
|
UDTFluxSubsystem* Subsystem = GEngine->GetEngineSubsystem<UDTFluxSubsystem>();
|
||||||
|
TArray<FDTFluxContest> Contests = Subsystem->GetDataStorage()->Contests;
|
||||||
|
for( auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
if(Contest.Id == ContestId)
|
||||||
|
{
|
||||||
|
ContestRankings = Contest.ContestRanking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//CAREFUL Can Be Empty
|
||||||
|
return ContestRankings;
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static bool GetParticipant(const int Bib, FDTFluxParticipant& Participant)
|
||||||
|
{
|
||||||
|
UDTFluxSubsystem* Subsystem= GEngine->GetEngineSubsystem<UDTFluxSubsystem>();
|
||||||
|
UDTFluxDataStorage* DataStorage = Subsystem->GetDataStorage();
|
||||||
|
|
||||||
|
return DataStorage->GetParticipantByBib(Bib, Participant);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static FString GetParticipantString(const int Bib, bool Truncate = true, int MaxSize = 20)
|
||||||
|
{
|
||||||
|
FString ParticipantStr = "";
|
||||||
|
FDTFluxParticipant Participant;
|
||||||
|
if(UDTFluxModelHelper::GetParticipant(Bib, Participant))
|
||||||
|
{
|
||||||
|
ParticipantStr = Participant.GetParticipantFormatedName(Truncate, MaxSize);
|
||||||
|
}
|
||||||
|
return ParticipantStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Model|Helpers")
|
||||||
|
static EDTFluxStageStatusType GetStatusType(const int ContestID, const int StageID, UDTFluxDataStorage* DataStorage);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user