Close Roux Bound2 drill recovery packet
This commit is contained in:
parent
5ac8ff9169
commit
7a715358a0
11 changed files with 684 additions and 1 deletions
|
|
@ -496,6 +496,48 @@ FHyperTwistTrainingMethodDrillBatch UHyperTwistContractLibrary::MakeSampleMethod
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillDefinition UHyperTwistContractLibrary::MakeSampleFavoriteFirstMethodDrillDefinition()
|
||||
{
|
||||
const FHyperTwistTrainingMethodDrillDefinition BaseDefinition = MakeSampleMethodDrillDefinition();
|
||||
if (!BaseDefinition.IsStructurallyValid())
|
||||
{
|
||||
return FHyperTwistTrainingMethodDrillDefinition();
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingMethodDrillFavoriteEntry> Favorites;
|
||||
FHyperTwistTrainingMethodDrillFavoriteEntry FavoriteEntry = MakeSampleMethodDrillFavoriteEntry();
|
||||
FavoriteEntry.CaseId = TEXT("roux-block-case-02");
|
||||
Favorites.Add(FavoriteEntry);
|
||||
return UHyperTwistTrainingRepositoryLibrary::BuildDrillDefinitionFavoriteFirst(
|
||||
BaseDefinition,
|
||||
Favorites,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness UHyperTwistContractLibrary::MakeSampleMethodDrillBatchReadiness()
|
||||
{
|
||||
return UHyperTwistTrainingRepositoryLibrary::DeriveDrillBatchReadiness(
|
||||
MakeSampleMethodDrillBatch(),
|
||||
MakeSampleMethodDrillDefinition()
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDrillCaseModeCompatibility UHyperTwistContractLibrary::MakeSampleMethodDrillCaseModeCompatibility()
|
||||
{
|
||||
const FHyperTwistTrainingMethodDrillDefinition DrillDefinition = MakeSampleMethodDrillDefinition();
|
||||
if (!DrillDefinition.IsStructurallyValid() || DrillDefinition.SourceDeck.Cases.Num() == 0)
|
||||
{
|
||||
return FHyperTwistTrainingDrillCaseModeCompatibility();
|
||||
}
|
||||
|
||||
return UHyperTwistTrainingLibrary::DeriveDrillCaseModeCompatibility(
|
||||
DrillDefinition.SourceDeck.Cases[0],
|
||||
DrillDefinition.DrillMode,
|
||||
DrillDefinition.VisibilityPolicy
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunStepResult UHyperTwistContractLibrary::MakeSampleTrainingRunStepResult()
|
||||
{
|
||||
const FHyperTwistTrainingRunState RunState = MakeSampleTrainingRunState();
|
||||
|
|
|
|||
|
|
@ -1638,6 +1638,15 @@ FHyperTwistTrainingMethodDrillDefinition UHyperTwistTrainingLibrary::BuildMethod
|
|||
|
||||
DrillDefinition.SourceDeckId = Deck.DeckId;
|
||||
DrillDefinition.SourceDeck = Deck;
|
||||
DrillDefinition.SourceDeck.Cases = FilterDrillCasesByModeCompatibility(
|
||||
Deck.Cases,
|
||||
DrillMode,
|
||||
VisibilityPolicy
|
||||
);
|
||||
if (DrillDefinition.SourceDeck.Cases.Num() == 0)
|
||||
{
|
||||
return FHyperTwistTrainingMethodDrillDefinition();
|
||||
}
|
||||
DrillDefinition.FocusCaseIds = HyperTwistTrainingLibraryInternal::BuildDrillCaseIds(DrillDefinition);
|
||||
DrillDefinition.DrillMode = DrillMode;
|
||||
DrillDefinition.VisibilityPolicy = VisibilityPolicy;
|
||||
|
|
@ -1963,3 +1972,105 @@ FHyperTwistTrainingMethodDrillBatch UHyperTwistTrainingLibrary::BuildMethodDrill
|
|||
DrillBatch.bPinnedFavoritesOnly = bPinnedFavoritesOnly;
|
||||
return DrillBatch;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDrillCaseModeCompatibility UHyperTwistTrainingLibrary::DeriveDrillCaseModeCompatibility(
|
||||
const FHyperTwistTrainingCase& TrainingCase,
|
||||
EHyperTwistTrainingDrillModeKind DrillMode,
|
||||
EHyperTwistTrainingDrillVisibilityPolicy VisibilityPolicy
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingDrillCaseModeCompatibility Result;
|
||||
Result.CaseId = TrainingCase.CaseId;
|
||||
Result.DrillMode = DrillMode;
|
||||
Result.VisibilityPolicy = VisibilityPolicy;
|
||||
|
||||
if (!TrainingCase.IsStructurallyValid())
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
const bool bHasNotation = !TrainingCase.CanonicalNotation.IsEmpty();
|
||||
const bool bHasStateRef = !TrainingCase.CanonicalStateRef.IsEmpty();
|
||||
const bool bHasScramble = !TrainingCase.ScrambleNotation.IsEmpty();
|
||||
const bool bHasPromptLabel = !TrainingCase.PromptLabel.IsEmpty();
|
||||
|
||||
const EHyperTwistTrainingPromptKind PromptKind = TrainingCase.PromptKind;
|
||||
|
||||
switch (DrillMode)
|
||||
{
|
||||
case EHyperTwistTrainingDrillModeKind::Recognition:
|
||||
Result.bCompatibleWithMode =
|
||||
bHasStateRef
|
||||
|| bHasScramble
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Recognition
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::State;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingDrillModeKind::Recall:
|
||||
Result.bCompatibleWithMode =
|
||||
bHasNotation
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Algorithm
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Sequence
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Memo;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingDrillModeKind::Execution:
|
||||
Result.bCompatibleWithMode =
|
||||
bHasNotation
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Algorithm
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Sequence;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingDrillModeKind::Reconstruction:
|
||||
Result.bCompatibleWithMode =
|
||||
bHasStateRef
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::State
|
||||
|| PromptKind == EHyperTwistTrainingPromptKind::Recognition;
|
||||
break;
|
||||
|
||||
default:
|
||||
Result.bCompatibleWithMode = false;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (VisibilityPolicy)
|
||||
{
|
||||
case EHyperTwistTrainingDrillVisibilityPolicy::FullInformation:
|
||||
Result.bCompatibleWithVisibility = true;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingDrillVisibilityPolicy::PromptOnly:
|
||||
Result.bCompatibleWithVisibility = bHasPromptLabel || bHasNotation;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingDrillVisibilityPolicy::MaskedState:
|
||||
case EHyperTwistTrainingDrillVisibilityPolicy::PartialState:
|
||||
Result.bCompatibleWithVisibility = bHasStateRef;
|
||||
break;
|
||||
|
||||
default:
|
||||
Result.bCompatibleWithVisibility = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingCase> UHyperTwistTrainingLibrary::FilterDrillCasesByModeCompatibility(
|
||||
const TArray<FHyperTwistTrainingCase>& Cases,
|
||||
EHyperTwistTrainingDrillModeKind DrillMode,
|
||||
EHyperTwistTrainingDrillVisibilityPolicy VisibilityPolicy
|
||||
)
|
||||
{
|
||||
TArray<FHyperTwistTrainingCase> Filtered;
|
||||
for (const FHyperTwistTrainingCase& TrainingCase : Cases)
|
||||
{
|
||||
const FHyperTwistTrainingDrillCaseModeCompatibility Compat =
|
||||
DeriveDrillCaseModeCompatibility(TrainingCase, DrillMode, VisibilityPolicy);
|
||||
if (Compat.bCompatibleWithMode && Compat.bCompatibleWithVisibility)
|
||||
{
|
||||
Filtered.Add(TrainingCase);
|
||||
}
|
||||
}
|
||||
return Filtered;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2953,6 +2953,211 @@ FHyperTwistTrainingRepositoryState UHyperTwistTrainingRepositoryLibrary::RemoveM
|
|||
return UpdatedRepositoryState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness UHyperTwistTrainingRepositoryLibrary::DeriveDrillBatchReadiness(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& CurrentDefinition
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness Readiness;
|
||||
Readiness.BatchId = DrillBatch.BatchId;
|
||||
Readiness.LastUpdatedAtUtc = DrillBatch.LastUpdatedAtUtc;
|
||||
|
||||
if (!DrillBatch.IsStructurallyValid())
|
||||
{
|
||||
return Readiness;
|
||||
}
|
||||
|
||||
TSet<FString> AllowedCaseIds;
|
||||
for (const FHyperTwistTrainingCase& TrainingCase : CurrentDefinition.SourceDeck.Cases)
|
||||
{
|
||||
if (!TrainingCase.CaseId.IsEmpty())
|
||||
{
|
||||
AllowedCaseIds.Add(TrainingCase.CaseId);
|
||||
}
|
||||
}
|
||||
if (CurrentDefinition.FocusCaseIds.Num() > 0)
|
||||
{
|
||||
for (const FString& FocusId : CurrentDefinition.FocusCaseIds)
|
||||
{
|
||||
AllowedCaseIds.Add(FocusId);
|
||||
}
|
||||
}
|
||||
|
||||
bool bFoundStaleCase = false;
|
||||
|
||||
for (const FString& PendingId : DrillBatch.PendingCaseIds)
|
||||
{
|
||||
if (!AllowedCaseIds.Contains(PendingId))
|
||||
{
|
||||
bFoundStaleCase = true;
|
||||
}
|
||||
}
|
||||
if (!DrillBatch.CurrentCaseId.IsEmpty() && !AllowedCaseIds.Contains(DrillBatch.CurrentCaseId))
|
||||
{
|
||||
bFoundStaleCase = true;
|
||||
}
|
||||
for (const FString& CompletedId : DrillBatch.CompletedCaseIds)
|
||||
{
|
||||
if (!AllowedCaseIds.Contains(CompletedId))
|
||||
{
|
||||
bFoundStaleCase = true;
|
||||
}
|
||||
}
|
||||
|
||||
Readiness.bIsStale = bFoundStaleCase;
|
||||
|
||||
const int32 PendingCount = DrillBatch.PendingCaseIds.Num();
|
||||
const bool bHasActiveCurrent = !DrillBatch.CurrentCaseId.IsEmpty()
|
||||
&& !DrillBatch.CompletedCaseIds.Contains(DrillBatch.CurrentCaseId);
|
||||
Readiness.RemainingCaseCount = PendingCount + (bHasActiveCurrent ? 1 : 0);
|
||||
Readiness.CompletedCaseCount = DrillBatch.CompletedCaseIds.Num();
|
||||
Readiness.bIsResumable = Readiness.RemainingCaseCount > 0;
|
||||
|
||||
const int32 Total = Readiness.RemainingCaseCount + Readiness.CompletedCaseCount;
|
||||
Readiness.CompletionFraction = Total > 0
|
||||
? static_cast<float>(Readiness.CompletedCaseCount) / static_cast<float>(Total)
|
||||
: 0.0f;
|
||||
|
||||
return Readiness;
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> UHyperTwistTrainingRepositoryLibrary::ListResumableDrillBatches(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
)
|
||||
{
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> AllBatches =
|
||||
ListMethodDrillBatches(RepositoryState, UserId, MethodSegmentId);
|
||||
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> Resumable;
|
||||
for (const FHyperTwistTrainingMethodDrillBatch& Batch : AllBatches)
|
||||
{
|
||||
const bool bHasPending = Batch.PendingCaseIds.Num() > 0;
|
||||
const bool bHasActiveCurrent = !Batch.CurrentCaseId.IsEmpty()
|
||||
&& !Batch.CompletedCaseIds.Contains(Batch.CurrentCaseId);
|
||||
if (bHasPending || bHasActiveCurrent)
|
||||
{
|
||||
Resumable.Add(Batch);
|
||||
}
|
||||
}
|
||||
return Resumable;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatch UHyperTwistTrainingRepositoryLibrary::RebuildDrillBatchForResume(
|
||||
const FHyperTwistTrainingMethodDrillBatch& SavedBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& CurrentDefinition
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingMethodDrillBatch Rebuilt = SavedBatch;
|
||||
|
||||
if (!SavedBatch.IsStructurallyValid())
|
||||
{
|
||||
return Rebuilt;
|
||||
}
|
||||
|
||||
TSet<FString> AllowedCaseIds;
|
||||
for (const FHyperTwistTrainingCase& TrainingCase : CurrentDefinition.SourceDeck.Cases)
|
||||
{
|
||||
if (!TrainingCase.CaseId.IsEmpty())
|
||||
{
|
||||
AllowedCaseIds.Add(TrainingCase.CaseId);
|
||||
}
|
||||
}
|
||||
if (CurrentDefinition.FocusCaseIds.Num() > 0)
|
||||
{
|
||||
for (const FString& FocusId : CurrentDefinition.FocusCaseIds)
|
||||
{
|
||||
AllowedCaseIds.Add(FocusId);
|
||||
}
|
||||
}
|
||||
|
||||
Rebuilt.PendingCaseIds.RemoveAll([&AllowedCaseIds](const FString& CaseId)
|
||||
{
|
||||
return !AllowedCaseIds.Contains(CaseId);
|
||||
});
|
||||
|
||||
Rebuilt.CompletedCaseIds.RemoveAll([&AllowedCaseIds](const FString& CaseId)
|
||||
{
|
||||
return !AllowedCaseIds.Contains(CaseId);
|
||||
});
|
||||
|
||||
Rebuilt.Responses.RemoveAll([&AllowedCaseIds](const FHyperTwistTrainingMethodDrillResponseRecord& Record)
|
||||
{
|
||||
return !AllowedCaseIds.Contains(Record.CaseId);
|
||||
});
|
||||
|
||||
const bool bCurrentStillValid = !Rebuilt.CurrentCaseId.IsEmpty()
|
||||
&& AllowedCaseIds.Contains(Rebuilt.CurrentCaseId);
|
||||
if (!bCurrentStillValid)
|
||||
{
|
||||
if (Rebuilt.PendingCaseIds.Num() > 0)
|
||||
{
|
||||
Rebuilt.CurrentCaseId = Rebuilt.PendingCaseIds[0];
|
||||
Rebuilt.PendingCaseIds.RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rebuilt.CurrentCaseId = FString();
|
||||
}
|
||||
}
|
||||
|
||||
Rebuilt.LastUpdatedAtUtc = FDateTime::UtcNow().ToIso8601();
|
||||
return Rebuilt;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillDefinition UHyperTwistTrainingRepositoryLibrary::BuildDrillDefinitionFavoriteFirst(
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const TArray<FHyperTwistTrainingMethodDrillFavoriteEntry>& Favorites,
|
||||
int32 MaxFavoriteCases
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingMethodDrillDefinition Result = BaseDefinition;
|
||||
|
||||
if (!BaseDefinition.IsStructurallyValid())
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
TSet<FString> DeckCaseIds;
|
||||
for (const FHyperTwistTrainingCase& TrainingCase : BaseDefinition.SourceDeck.Cases)
|
||||
{
|
||||
if (!TrainingCase.CaseId.IsEmpty())
|
||||
{
|
||||
DeckCaseIds.Add(TrainingCase.CaseId);
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FString> FavoriteCaseIds;
|
||||
for (const FHyperTwistTrainingMethodDrillFavoriteEntry& FavoriteEntry : Favorites)
|
||||
{
|
||||
if (!FavoriteEntry.CaseId.IsEmpty() && DeckCaseIds.Contains(FavoriteEntry.CaseId))
|
||||
{
|
||||
FavoriteCaseIds.AddUnique(FavoriteEntry.CaseId);
|
||||
if (MaxFavoriteCases > 0 && FavoriteCaseIds.Num() >= MaxFavoriteCases)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FString> OrderedCaseIds = FavoriteCaseIds;
|
||||
for (const FHyperTwistTrainingCase& TrainingCase : BaseDefinition.SourceDeck.Cases)
|
||||
{
|
||||
if (!TrainingCase.CaseId.IsEmpty() && !OrderedCaseIds.Contains(TrainingCase.CaseId))
|
||||
{
|
||||
OrderedCaseIds.Add(TrainingCase.CaseId);
|
||||
}
|
||||
}
|
||||
|
||||
Result.FocusCaseIds = OrderedCaseIds;
|
||||
if (FavoriteCaseIds.Num() > 0)
|
||||
{
|
||||
Result.EntrySource = EHyperTwistTrainingDrillEntrySource::Favorites;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRepositoryState UHyperTwistTrainingRepositoryLibrary::UpsertRunRecord(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FHyperTwistTrainingRunRecord& RunRecord
|
||||
|
|
|
|||
|
|
@ -514,6 +514,67 @@ TArray<FHyperTwistTrainingMethodDrillBatch> UHyperTwistTrainingRuntimeLibrary::G
|
|||
return TArray<FHyperTwistTrainingMethodDrillBatch>();
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> UHyperTwistTrainingRuntimeLibrary::GetResumableMethodDrillBatchesForUser(
|
||||
UObject* WorldContextObject,
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
)
|
||||
{
|
||||
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
|
||||
{
|
||||
return TrainingSubsystem->GetResumableMethodDrillBatchesForUser(UserId, MethodSegmentId);
|
||||
}
|
||||
|
||||
return TArray<FHyperTwistTrainingMethodDrillBatch>();
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness UHyperTwistTrainingRuntimeLibrary::DeriveMethodDrillBatchReadiness(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
)
|
||||
{
|
||||
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
|
||||
{
|
||||
return TrainingSubsystem->DeriveMethodDrillBatchReadiness(DrillBatch, DrillDefinition);
|
||||
}
|
||||
|
||||
return FHyperTwistTrainingMethodDrillBatchReadiness();
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatch UHyperTwistTrainingRuntimeLibrary::RebuildMethodDrillBatchForResume(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
)
|
||||
{
|
||||
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
|
||||
{
|
||||
return TrainingSubsystem->RebuildMethodDrillBatchForResume(DrillBatch, DrillDefinition);
|
||||
}
|
||||
|
||||
return FHyperTwistTrainingMethodDrillBatch();
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillDefinition UHyperTwistTrainingRuntimeLibrary::BuildFavoriteFirstMethodDrillDefinition(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const FString& UserId,
|
||||
int32 MaxFavoriteCases
|
||||
)
|
||||
{
|
||||
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
|
||||
{
|
||||
return TrainingSubsystem->BuildFavoriteFirstMethodDrillDefinition(
|
||||
BaseDefinition,
|
||||
UserId,
|
||||
MaxFavoriteCases
|
||||
);
|
||||
}
|
||||
|
||||
return FHyperTwistTrainingMethodDrillDefinition();
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingCaseRecommendation> UHyperTwistTrainingRuntimeLibrary::GetActiveTrainingCaseRecommendations(UObject* WorldContextObject)
|
||||
{
|
||||
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
|
||||
|
|
|
|||
|
|
@ -863,6 +863,70 @@ TArray<FHyperTwistTrainingMethodDrillBatch> UHyperTwistTrainingSubsystem::GetMet
|
|||
);
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> UHyperTwistTrainingSubsystem::GetResumableMethodDrillBatchesForUser(
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
) const
|
||||
{
|
||||
return UHyperTwistTrainingRepositoryLibrary::ListResumableDrillBatches(
|
||||
TrainingRepositoryState,
|
||||
UserId,
|
||||
MethodSegmentId
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness UHyperTwistTrainingSubsystem::DeriveMethodDrillBatchReadiness(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
) const
|
||||
{
|
||||
return UHyperTwistTrainingRepositoryLibrary::DeriveDrillBatchReadiness(
|
||||
DrillBatch,
|
||||
DrillDefinition
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillBatch UHyperTwistTrainingSubsystem::RebuildMethodDrillBatchForResume(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
) const
|
||||
{
|
||||
return UHyperTwistTrainingRepositoryLibrary::RebuildDrillBatchForResume(
|
||||
DrillBatch,
|
||||
DrillDefinition
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingMethodDrillDefinition UHyperTwistTrainingSubsystem::BuildFavoriteFirstMethodDrillDefinition(
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const FString& UserId,
|
||||
int32 MaxFavoriteCases
|
||||
) const
|
||||
{
|
||||
if (!BaseDefinition.IsStructurallyValid())
|
||||
{
|
||||
return BaseDefinition;
|
||||
}
|
||||
|
||||
const FString EffectiveUserId = !UserId.IsEmpty() ? UserId : ActiveMethodDrillRunState.UserId;
|
||||
if (EffectiveUserId.IsEmpty())
|
||||
{
|
||||
return BaseDefinition;
|
||||
}
|
||||
|
||||
const TArray<FHyperTwistTrainingMethodDrillFavoriteEntry> Favorites =
|
||||
UHyperTwistTrainingRepositoryLibrary::ListMethodDrillFavorites(
|
||||
TrainingRepositoryState,
|
||||
EffectiveUserId,
|
||||
BaseDefinition.MethodDescriptor.SegmentId
|
||||
);
|
||||
return UHyperTwistTrainingRepositoryLibrary::BuildDrillDefinitionFavoriteFirst(
|
||||
BaseDefinition,
|
||||
Favorites,
|
||||
MaxFavoriteCases
|
||||
);
|
||||
}
|
||||
|
||||
TArray<FHyperTwistTrainingCaseRecommendation> UHyperTwistTrainingSubsystem::GetActiveCaseRecommendations() const
|
||||
{
|
||||
return ActiveCaseRecommendations;
|
||||
|
|
@ -2062,11 +2126,49 @@ FHyperTwistTrainingMethodDrillRunState UHyperTwistTrainingSubsystem::ResumeMetho
|
|||
const FString& RunId
|
||||
)
|
||||
{
|
||||
const FHyperTwistTrainingMethodDrillBatch RebuiltBatch =
|
||||
UHyperTwistTrainingRepositoryLibrary::RebuildDrillBatchForResume(DrillBatch, DrillDefinition);
|
||||
if (!RebuiltBatch.IsStructurallyValid())
|
||||
{
|
||||
ActiveMethodDrillRunState = FHyperTwistTrainingMethodDrillRunState();
|
||||
bHasActiveMethodDrillRun = false;
|
||||
RefreshMethodDrillSummary();
|
||||
return ActiveMethodDrillRunState;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingMethodDrillBatchReadiness Readiness =
|
||||
UHyperTwistTrainingRepositoryLibrary::DeriveDrillBatchReadiness(RebuiltBatch, DrillDefinition);
|
||||
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillBatch(
|
||||
TrainingRepositoryState,
|
||||
RebuiltBatch
|
||||
);
|
||||
RefreshRepositoryViews();
|
||||
|
||||
ActiveMethodDrillRunState = UHyperTwistTrainingLibrary::ResumeMethodDrillRunFromBatch(
|
||||
DrillDefinition,
|
||||
DrillBatch,
|
||||
RebuiltBatch,
|
||||
RunId
|
||||
);
|
||||
if (ActiveMethodDrillRunState.IsStructurallyValid()
|
||||
&& !Readiness.bIsResumable
|
||||
&& ActiveMethodDrillRunState.LifecycleState != EHyperTwistTrainingDrillLifecycleState::Completed
|
||||
&& ActiveMethodDrillRunState.LifecycleState != EHyperTwistTrainingDrillLifecycleState::Aborted)
|
||||
{
|
||||
ActiveMethodDrillRunState = UHyperTwistTrainingLibrary::FinishMethodDrillRun(
|
||||
ActiveMethodDrillRunState,
|
||||
false
|
||||
);
|
||||
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillBatch(
|
||||
TrainingRepositoryState,
|
||||
UHyperTwistTrainingLibrary::BuildMethodDrillBatch(
|
||||
ActiveMethodDrillRunState,
|
||||
RebuiltBatch.BatchId,
|
||||
RebuiltBatch.Title,
|
||||
RebuiltBatch.bPinnedFavoritesOnly
|
||||
)
|
||||
);
|
||||
RefreshRepositoryViews();
|
||||
}
|
||||
bHasActiveMethodDrillRun = ActiveMethodDrillRunState.IsStructurallyValid();
|
||||
RefreshMethodDrillSummary();
|
||||
return ActiveMethodDrillRunState;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,15 @@ public:
|
|||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static FHyperTwistTrainingMethodDrillBatch MakeSampleMethodDrillBatch();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static FHyperTwistTrainingMethodDrillDefinition MakeSampleFavoriteFirstMethodDrillDefinition();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static FHyperTwistTrainingMethodDrillBatchReadiness MakeSampleMethodDrillBatchReadiness();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static FHyperTwistTrainingDrillCaseModeCompatibility MakeSampleMethodDrillCaseModeCompatibility();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training")
|
||||
static FHyperTwistTrainingRunStepResult MakeSampleTrainingRunStepResult();
|
||||
|
||||
|
|
|
|||
|
|
@ -208,4 +208,18 @@ public:
|
|||
const FString& Title,
|
||||
bool bPinnedFavoritesOnly
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static FHyperTwistTrainingDrillCaseModeCompatibility DeriveDrillCaseModeCompatibility(
|
||||
const FHyperTwistTrainingCase& TrainingCase,
|
||||
EHyperTwistTrainingDrillModeKind DrillMode,
|
||||
EHyperTwistTrainingDrillVisibilityPolicy VisibilityPolicy
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
static TArray<FHyperTwistTrainingCase> FilterDrillCasesByModeCompatibility(
|
||||
const TArray<FHyperTwistTrainingCase>& Cases,
|
||||
EHyperTwistTrainingDrillModeKind DrillMode,
|
||||
EHyperTwistTrainingDrillVisibilityPolicy VisibilityPolicy
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,6 +98,32 @@ public:
|
|||
const FString& BatchId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Drill")
|
||||
static FHyperTwistTrainingMethodDrillBatchReadiness DeriveDrillBatchReadiness(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& CurrentDefinition
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Drill")
|
||||
static TArray<FHyperTwistTrainingMethodDrillBatch> ListResumableDrillBatches(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Drill")
|
||||
static FHyperTwistTrainingMethodDrillBatch RebuildDrillBatchForResume(
|
||||
const FHyperTwistTrainingMethodDrillBatch& SavedBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& CurrentDefinition
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Drill")
|
||||
static FHyperTwistTrainingMethodDrillDefinition BuildDrillDefinitionFavoriteFirst(
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const TArray<FHyperTwistTrainingMethodDrillFavoriteEntry>& Favorites,
|
||||
int32 MaxFavoriteCases
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository")
|
||||
static FHyperTwistTrainingRepositoryState UpsertRunRecord(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
|
|
|
|||
|
|
@ -178,6 +178,35 @@ public:
|
|||
const FString& MethodSegmentId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
|
||||
static TArray<FHyperTwistTrainingMethodDrillBatch> GetResumableMethodDrillBatchesForUser(
|
||||
UObject* WorldContextObject,
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
|
||||
static FHyperTwistTrainingMethodDrillBatchReadiness DeriveMethodDrillBatchReadiness(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
|
||||
static FHyperTwistTrainingMethodDrillBatch RebuildMethodDrillBatchForResume(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
|
||||
static FHyperTwistTrainingMethodDrillDefinition BuildFavoriteFirstMethodDrillDefinition(
|
||||
UObject* WorldContextObject,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const FString& UserId,
|
||||
int32 MaxFavoriteCases
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
|
||||
static TArray<FHyperTwistTrainingCaseRecommendation> GetActiveTrainingCaseRecommendations(UObject* WorldContextObject);
|
||||
|
||||
|
|
|
|||
|
|
@ -152,6 +152,31 @@ public:
|
|||
const FString& MethodSegmentId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
TArray<FHyperTwistTrainingMethodDrillBatch> GetResumableMethodDrillBatchesForUser(
|
||||
const FString& UserId,
|
||||
const FString& MethodSegmentId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
FHyperTwistTrainingMethodDrillBatchReadiness DeriveMethodDrillBatchReadiness(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
FHyperTwistTrainingMethodDrillBatch RebuildMethodDrillBatchForResume(
|
||||
const FHyperTwistTrainingMethodDrillBatch& DrillBatch,
|
||||
const FHyperTwistTrainingMethodDrillDefinition& DrillDefinition
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
|
||||
FHyperTwistTrainingMethodDrillDefinition BuildFavoriteFirstMethodDrillDefinition(
|
||||
const FHyperTwistTrainingMethodDrillDefinition& BaseDefinition,
|
||||
const FString& UserId,
|
||||
int32 MaxFavoriteCases
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training")
|
||||
TArray<FHyperTwistTrainingCaseRecommendation> GetActiveCaseRecommendations() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -2401,6 +2401,65 @@ struct FHyperTwistTrainingMethodDrillBatch
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingMethodDrillBatchReadiness
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString BatchId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bIsResumable = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bIsStale = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 RemainingCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 CompletedCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
float CompletionFraction = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LastUpdatedAtUtc;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !BatchId.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingDrillCaseModeCompatibility
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CaseId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCompatibleWithMode = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCompatibleWithVisibility = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingDrillModeKind DrillMode = EHyperTwistTrainingDrillModeKind::Recognition;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingDrillVisibilityPolicy VisibilityPolicy =
|
||||
EHyperTwistTrainingDrillVisibilityPolicy::FullInformation;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !CaseId.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingLearnerPreset
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue