Track imported generated selector choices in runs

This commit is contained in:
axiomlogicnexus 2026-05-01 23:10:04 +02:00
parent bec22af2a0
commit 0ba5cd033a
6 changed files with 194 additions and 0 deletions

View file

@ -1083,6 +1083,11 @@ FHyperTwistTrainingRunState UHyperTwistTrainingLibrary::StartTrainingRun(
{
return RunState;
}
if (Deck.ImportedRuntimeSurface.IsStructurallyValid())
{
RunState.ImportedRuntimeSelectionState.SurfaceId = Deck.ImportedRuntimeSurface.SurfaceId;
RunState.ImportedRuntimeSelectionState.SurfaceKind = Deck.ImportedRuntimeSurface.SurfaceKind;
}
for (const FHyperTwistTrainingCase& TrainingCase : Deck.Cases)
{

View file

@ -102,6 +102,20 @@ bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveImportedRuntimeSelectorOptio
return false;
}
bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveImportedRuntimeSelectionState(
UObject* WorldContextObject,
FHyperTwistTrainingImportedRuntimeSelectionState& OutSelectionState
)
{
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
{
return TrainingSubsystem->TryGetActiveImportedRuntimeSelectionState(OutSelectionState);
}
OutSelectionState = FHyperTwistTrainingImportedRuntimeSelectionState();
return false;
}
FHyperTwistTrainingRunState UHyperTwistTrainingRuntimeLibrary::ApplyActiveImportedRuntimeSelectorOption(
UObject* WorldContextObject,
const FString& SelectorId,
@ -116,6 +130,25 @@ FHyperTwistTrainingRunState UHyperTwistTrainingRuntimeLibrary::ApplyActiveImport
return FHyperTwistTrainingRunState();
}
FHyperTwistTrainingRunState UHyperTwistTrainingRuntimeLibrary::ApplyActiveImportedGeneratedModeSelectorChoice(
UObject* WorldContextObject,
const FString& SelectorId,
const FString& SelectedValue,
const FString& DisplayValue
)
{
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
{
return TrainingSubsystem->ApplyActiveImportedGeneratedModeSelectorChoice(
SelectorId,
SelectedValue,
DisplayValue
);
}
return FHyperTwistTrainingRunState();
}
FHyperTwistTrainingMethodDrillRunState UHyperTwistTrainingRuntimeLibrary::GetActiveMethodDrillRunState(
UObject* WorldContextObject
)

View file

@ -745,6 +745,20 @@ bool UHyperTwistTrainingSubsystem::TryGetActiveImportedRuntimeSelectorOptionCase
);
}
bool UHyperTwistTrainingSubsystem::TryGetActiveImportedRuntimeSelectionState(
FHyperTwistTrainingImportedRuntimeSelectionState& OutSelectionState
) const
{
OutSelectionState = FHyperTwistTrainingImportedRuntimeSelectionState();
if (!HasActiveRun() || !ActiveRunState.ImportedRuntimeSelectionState.IsStructurallyValid())
{
return false;
}
OutSelectionState = ActiveRunState.ImportedRuntimeSelectionState;
return OutSelectionState.IsStructurallyValid();
}
FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::ApplyActiveImportedRuntimeSelectorOption(
const FString& SelectorId,
const FString& OptionId
@ -781,6 +795,76 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::ApplyActiveImportedRun
);
}
FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::ApplyActiveImportedGeneratedModeSelectorChoice(
const FString& SelectorId,
const FString& SelectedValue,
const FString& DisplayValue
)
{
if (!HasActiveRun() || SelectedValue.IsEmpty())
{
return FHyperTwistTrainingRunState();
}
FHyperTwistTrainingImportedRuntimeSurface RuntimeSurface;
if (!UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSurfaceFromDeck(
ActiveRunState.ActiveDeck,
RuntimeSurface)
|| !RuntimeSurface.SurfaceKind.Equals(TEXT("generated-mode"), ESearchCase::IgnoreCase))
{
return FHyperTwistTrainingRunState();
}
FHyperTwistTrainingImportedRuntimeSelector Selector;
if (!UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSelectorFromDeck(
ActiveRunState.ActiveDeck,
SelectorId,
Selector))
{
return FHyperTwistTrainingRunState();
}
if (!ActiveRunState.ImportedRuntimeSelectionState.IsStructurallyValid())
{
ActiveRunState.ImportedRuntimeSelectionState.SurfaceId = RuntimeSurface.SurfaceId;
ActiveRunState.ImportedRuntimeSelectionState.SurfaceKind = RuntimeSurface.SurfaceKind;
}
FHyperTwistTrainingImportedRuntimeSelectorChoice* ExistingChoice =
ActiveRunState.ImportedRuntimeSelectionState.SelectorChoices.FindByPredicate(
[&SelectorId](const FHyperTwistTrainingImportedRuntimeSelectorChoice& Candidate)
{
return Candidate.SelectorId == SelectorId;
}
);
if (ExistingChoice != nullptr)
{
ExistingChoice->SelectorBinding = Selector.SelectorBinding;
ExistingChoice->SelectedValue = SelectedValue;
ExistingChoice->DisplayValue = DisplayValue.IsEmpty() ? SelectedValue : DisplayValue;
}
else
{
FHyperTwistTrainingImportedRuntimeSelectorChoice Choice;
Choice.SelectorId = SelectorId;
Choice.SelectorBinding = Selector.SelectorBinding;
Choice.SelectedValue = SelectedValue;
Choice.DisplayValue = DisplayValue.IsEmpty() ? SelectedValue : DisplayValue;
ActiveRunState.ImportedRuntimeSelectionState.SelectorChoices.Add(MoveTemp(Choice));
}
ActiveRunState.ActiveDeck.Tags.AddUnique(TEXT("runtime-surface:generated-choice-applied"));
ActiveRunState.ActiveDeck.Tags.AddUnique(FString::Printf(TEXT("selector:%s"), *SelectorId.ToLower()));
ActiveRunState.ActiveDeck.Tags.AddUnique(FString::Printf(TEXT("selector-choice:%s"), *SelectedValue.ToLower()));
RefreshSummary();
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::RecordRunState(
TrainingRepositoryState,
ActiveRunState
);
RefreshRepositoryViews();
return ActiveRunState;
}
FHyperTwistTrainingMethodDrillRunState UHyperTwistTrainingSubsystem::GetActiveMethodDrillRunState() const
{
return ActiveMethodDrillRunState;

View file

@ -48,6 +48,12 @@ public:
TArray<FHyperTwistTrainingCase>& OutCases
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static bool TryGetActiveImportedRuntimeSelectionState(
UObject* WorldContextObject,
FHyperTwistTrainingImportedRuntimeSelectionState& OutSelectionState
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static FHyperTwistTrainingRunState ApplyActiveImportedRuntimeSelectorOption(
UObject* WorldContextObject,
@ -55,6 +61,14 @@ public:
const FString& OptionId
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static FHyperTwistTrainingRunState ApplyActiveImportedGeneratedModeSelectorChoice(
UObject* WorldContextObject,
const FString& SelectorId,
const FString& SelectedValue,
const FString& DisplayValue
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
static FHyperTwistTrainingMethodDrillRunState GetActiveMethodDrillRunState(UObject* WorldContextObject);

View file

@ -38,12 +38,24 @@ public:
TArray<FHyperTwistTrainingCase>& OutCases
) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
bool TryGetActiveImportedRuntimeSelectionState(
FHyperTwistTrainingImportedRuntimeSelectionState& OutSelectionState
) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
FHyperTwistTrainingRunState ApplyActiveImportedRuntimeSelectorOption(
const FString& SelectorId,
const FString& OptionId
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
FHyperTwistTrainingRunState ApplyActiveImportedGeneratedModeSelectorChoice(
const FString& SelectorId,
const FString& SelectedValue,
const FString& DisplayValue
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
FHyperTwistTrainingMethodDrillRunState GetActiveMethodDrillRunState() const;

View file

@ -450,6 +450,49 @@ struct FHyperTwistTrainingImportedRuntimeSurface
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingImportedRuntimeSelectorChoice
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectorId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectorBinding;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectedValue;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DisplayValue;
bool IsStructurallyValid() const
{
return !SelectorId.IsEmpty() && !SelectedValue.IsEmpty();
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingImportedRuntimeSelectionState
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SurfaceId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SurfaceKind;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FHyperTwistTrainingImportedRuntimeSelectorChoice> SelectorChoices;
bool IsStructurallyValid() const
{
return !SurfaceId.IsEmpty() && !SurfaceKind.IsEmpty();
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingDeck
{
@ -925,6 +968,9 @@ struct FHyperTwistTrainingRunState
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistReplayEvent LastReplayEvent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingImportedRuntimeSelectionState ImportedRuntimeSelectionState;
bool IsStructurallyValid() const
{
return ActiveDeck.IsStructurallyValid()