Expose imported runtime surface selectors at runtime

This commit is contained in:
axiomlogicnexus 2026-05-01 22:54:00 +02:00
parent afaffa903a
commit 20d5b113e9
6 changed files with 226 additions and 0 deletions

View file

@ -256,6 +256,28 @@ namespace HyperTwistTrainingCatalogLibraryInternal
return ToTitleLabel(MethodKey);
}
bool DoesSelectorOptionMatchCase(
const FHyperTwistTrainingImportedRuntimeSelectorOption& Option,
const FHyperTwistTrainingCase& TrainingCase
)
{
if (!Option.IsStructurallyValid() || !TrainingCase.IsStructurallyValid())
{
return false;
}
if (TrainingCase.SourceAttribution.SourceCaseId.Equals(Option.OptionValue, ESearchCase::IgnoreCase)
|| TrainingCase.SourceAttribution.SourceCaseId.Equals(Option.OptionId, ESearchCase::IgnoreCase))
{
return true;
}
const FString ExpectedCaseSuffixA = FString::Printf(TEXT("/%s"), *Option.OptionValue);
const FString ExpectedCaseSuffixB = FString::Printf(TEXT("/%s"), *Option.OptionId);
return TrainingCase.CaseId.EndsWith(ExpectedCaseSuffixA, ESearchCase::IgnoreCase)
|| TrainingCase.CaseId.EndsWith(ExpectedCaseSuffixB, ESearchCase::IgnoreCase);
}
FString TemplateKindToTag(EHyperTwistTrainingSessionTemplateKind TemplateKind)
{
switch (TemplateKind)
@ -2667,6 +2689,77 @@ bool UHyperTwistTrainingCatalogLibrary::TryGetDefaultDeckFromContentPack(
return OutDeck.IsStructurallyValid();
}
bool UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSurfaceFromDeck(
const FHyperTwistTrainingDeck& Deck,
FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
)
{
OutRuntimeSurface = FHyperTwistTrainingImportedRuntimeSurface();
if (!Deck.IsStructurallyValid() || !Deck.ImportedRuntimeSurface.IsStructurallyValid())
{
return false;
}
OutRuntimeSurface = Deck.ImportedRuntimeSurface;
return OutRuntimeSurface.IsStructurallyValid();
}
bool UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSelectorFromDeck(
const FHyperTwistTrainingDeck& Deck,
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
)
{
OutSelector = FHyperTwistTrainingImportedRuntimeSelector();
FHyperTwistTrainingImportedRuntimeSurface RuntimeSurface;
if (!TryGetImportedRuntimeSurfaceFromDeck(Deck, RuntimeSurface) || SelectorId.IsEmpty())
{
return false;
}
for (const FHyperTwistTrainingImportedRuntimeSelector& Selector : RuntimeSurface.Selectors)
{
if (Selector.SelectorId == SelectorId)
{
OutSelector = Selector;
return OutSelector.IsStructurallyValid();
}
}
return false;
}
bool UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSelectorOptionCasesFromDeck(
const FHyperTwistTrainingDeck& Deck,
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
)
{
OutCases.Reset();
FHyperTwistTrainingImportedRuntimeSelector Selector;
if (!TryGetImportedRuntimeSelectorFromDeck(Deck, SelectorId, Selector) || Selector.Options.Num() == 0)
{
return false;
}
for (const FHyperTwistTrainingImportedRuntimeSelectorOption& Option : Selector.Options)
{
const FHyperTwistTrainingCase* MatchingCase = Deck.Cases.FindByPredicate(
[&Option](const FHyperTwistTrainingCase& Candidate)
{
return HyperTwistTrainingCatalogLibraryInternal::DoesSelectorOptionMatchCase(Option, Candidate);
}
);
if (MatchingCase != nullptr)
{
OutCases.Add(*MatchingCase);
}
}
return OutCases.Num() > 0;
}
FHyperTwistTrainingMethodDescriptor UHyperTwistTrainingCatalogLibrary::DescribeTrainingDeckMethod(
const FHyperTwistTrainingDeck& Deck
)

View file

@ -58,6 +58,50 @@ FHyperTwistTrainingRunState UHyperTwistTrainingRuntimeLibrary::GetActiveTraining
return FHyperTwistTrainingRunState();
}
bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveImportedRuntimeSurface(
UObject* WorldContextObject,
FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
)
{
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
{
return TrainingSubsystem->TryGetActiveImportedRuntimeSurface(OutRuntimeSurface);
}
OutRuntimeSurface = FHyperTwistTrainingImportedRuntimeSurface();
return false;
}
bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveImportedRuntimeSelector(
UObject* WorldContextObject,
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
)
{
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
{
return TrainingSubsystem->TryGetActiveImportedRuntimeSelector(SelectorId, OutSelector);
}
OutSelector = FHyperTwistTrainingImportedRuntimeSelector();
return false;
}
bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveImportedRuntimeSelectorOptionCases(
UObject* WorldContextObject,
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
)
{
if (UHyperTwistTrainingSubsystem* TrainingSubsystem = GetTrainingSubsystem(WorldContextObject))
{
return TrainingSubsystem->TryGetActiveImportedRuntimeSelectorOptionCases(SelectorId, OutCases);
}
OutCases.Reset();
return false;
}
FHyperTwistTrainingMethodDrillRunState UHyperTwistTrainingRuntimeLibrary::GetActiveMethodDrillRunState(
UObject* WorldContextObject
)

View file

@ -711,6 +711,40 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::GetActiveRunState() co
return ActiveRunState;
}
bool UHyperTwistTrainingSubsystem::TryGetActiveImportedRuntimeSurface(
FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
) const
{
return UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSurfaceFromDeck(
ActiveRunState.ActiveDeck,
OutRuntimeSurface
);
}
bool UHyperTwistTrainingSubsystem::TryGetActiveImportedRuntimeSelector(
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
) const
{
return UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSelectorFromDeck(
ActiveRunState.ActiveDeck,
SelectorId,
OutSelector
);
}
bool UHyperTwistTrainingSubsystem::TryGetActiveImportedRuntimeSelectorOptionCases(
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
) const
{
return UHyperTwistTrainingCatalogLibrary::TryGetImportedRuntimeSelectorOptionCasesFromDeck(
ActiveRunState.ActiveDeck,
SelectorId,
OutCases
);
}
FHyperTwistTrainingMethodDrillRunState UHyperTwistTrainingSubsystem::GetActiveMethodDrillRunState() const
{
return ActiveMethodDrillRunState;

View file

@ -134,6 +134,26 @@ public:
FHyperTwistTrainingDeck& OutDeck
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
static bool TryGetImportedRuntimeSurfaceFromDeck(
const FHyperTwistTrainingDeck& Deck,
FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
static bool TryGetImportedRuntimeSelectorFromDeck(
const FHyperTwistTrainingDeck& Deck,
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
static bool TryGetImportedRuntimeSelectorOptionCasesFromDeck(
const FHyperTwistTrainingDeck& Deck,
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
static FHyperTwistTrainingMethodDescriptor DescribeTrainingDeckMethod(
const FHyperTwistTrainingDeck& Deck

View file

@ -28,6 +28,26 @@ public:
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static FHyperTwistTrainingRunState GetActiveTrainingRunState(UObject* WorldContextObject);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static bool TryGetActiveImportedRuntimeSurface(
UObject* WorldContextObject,
FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static bool TryGetActiveImportedRuntimeSelector(
UObject* WorldContextObject,
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training", meta = (WorldContext = "WorldContextObject"))
static bool TryGetActiveImportedRuntimeSelectorOptionCases(
UObject* WorldContextObject,
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill", meta = (WorldContext = "WorldContextObject"))
static FHyperTwistTrainingMethodDrillRunState GetActiveMethodDrillRunState(UObject* WorldContextObject);

View file

@ -23,6 +23,21 @@ public:
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training")
FHyperTwistTrainingRunState GetActiveRunState() const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
bool TryGetActiveImportedRuntimeSurface(FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
bool TryGetActiveImportedRuntimeSelector(
const FString& SelectorId,
FHyperTwistTrainingImportedRuntimeSelector& OutSelector
) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
bool TryGetActiveImportedRuntimeSelectorOptionCases(
const FString& SelectorId,
TArray<FHyperTwistTrainingCase>& OutCases
) const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Drill")
FHyperTwistTrainingMethodDrillRunState GetActiveMethodDrillRunState() const;