diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index d263710..8d8e3c3 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -11757,6 +11757,249 @@ UHyperTwistTrainingCoachLibrary:: return Surface; } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface +UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ) +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionSurvivorPhaseRosterInspectSurface + SurvivorRosterSurface = + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionSurvivorPhaseRosterInspectSurface( + RunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); + + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface + Surface; + Surface.SelectorId = SurvivorRosterSurface.SelectorId; + Surface.SelectorLabel = SurvivorRosterSurface.SelectorLabel; + Surface.BindingLabel = SurvivorRosterSurface.BindingLabel; + Surface.Headline = + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Explicit-Label Roster Inspect"); + Surface.bHasSelector = SurvivorRosterSurface.bHasSelector; + Surface.bHasSelection = SurvivorRosterSurface.bHasSelection; + Surface.bSelectionMatchesAvailableOption = + SurvivorRosterSurface.bSelectionMatchesAvailableOption; + Surface.CurrentSelectionSelectionLine = + SurvivorRosterSurface.CurrentSelectionSelectionLine; + Surface.CurrentSelectionOptionId = + SurvivorRosterSurface.CurrentSelectionOptionId; + Surface.CurrentSelectionOptionLabel = + SurvivorRosterSurface.CurrentSelectionOptionLabel; + Surface.CurrentSelectionOptionValue = + SurvivorRosterSurface.CurrentSelectionOptionValue; + Surface.LaunchRequestPreviewKind = + SurvivorRosterSurface.LaunchRequestPreviewKind; + Surface.bStartsOwnedCaseImmediately = + SurvivorRosterSurface.bStartsOwnedCaseImmediately; + Surface.bHasExactCurrentSelectionExplicitLabelRoster = + SurvivorRosterSurface.bHasExactCurrentSelectionSurvivorPhaseRoster; + Surface.bRetainsActiveDeckSplitPhaseFusion = + SurvivorRosterSurface.bRetainsActiveDeckSplitPhaseFusion; + Surface.bPreviewBlocked = SurvivorRosterSurface.bPreviewBlocked; + Surface.bCanPreview = SurvivorRosterSurface.bCanPreview; + + if (!SelectorId.IsEmpty()) + { + Surface.Headline = OptionMenuSurface.SelectorLabel.IsEmpty() + ? FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Explicit-Label Roster Inspect: %s"), + *SelectorId + ) + : FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Explicit-Label Roster Inspect: %s"), + *OptionMenuSurface.SelectorLabel + ); + } + + for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionSurvivorPhaseRosterInspectPhaseSurface& + SurvivorPhase : SurvivorRosterSurface.SurvivorPhases) + { + if (SurvivorPhase.bLabelFallsBackToPhaseId) + { + continue; + } + + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectPhaseSurface + PhaseSurface; + PhaseSurface.PhaseId = SurvivorPhase.PhaseId; + PhaseSurface.SourceLabel = SurvivorPhase.SourceLabel; + PhaseSurface.NormalizedLabel = SurvivorPhase.NormalizedLabel; + PhaseSurface.EvaluationOrder = SurvivorPhase.EvaluationOrder; + PhaseSurface.NormalizedOrder = SurvivorPhase.NormalizedOrder; + PhaseSurface.OrderLine = SurvivorPhase.OrderLine; + PhaseSurface.LabelLine = SurvivorPhase.LabelLine; + PhaseSurface.LabelProvenanceLine = SurvivorPhase.LabelProvenanceLine; + PhaseSurface.ExplicitLabelRosterLine = FString::Printf( + TEXT("Current-selection explicit-label roster on execute: evaluation #%d survives as normalized phase #%d with explicit label %s (%s)."), + SurvivorPhase.EvaluationOrder, + SurvivorPhase.NormalizedOrder, + *SurvivorPhase.NormalizedLabel, + *SurvivorPhase.PhaseId + ); + PhaseSurface.DetailLine = FString::Printf( + TEXT("%s | %s | %s"), + *PhaseSurface.OrderLine, + *PhaseSurface.LabelProvenanceLine, + *PhaseSurface.ExplicitLabelRosterLine + ); + PhaseSurface.bCanPreview = SurvivorPhase.bCanPreview; + Surface.ExplicitLabelPhases.Add(MoveTemp(PhaseSurface)); + } + + Surface.ExplicitLabelPhaseCount = Surface.ExplicitLabelPhases.Num(); + Surface.bHasCurrentSelectionExplicitLabelRoster = + Surface.ExplicitLabelPhaseCount > 0; + + Surface.ExplicitLabelPhaseCountLine = Surface.bHasCurrentSelectionExplicitLabelRoster + ? FString::Printf( + TEXT("Current-selection explicit-label phases on execute: %d retained phase%s"), + Surface.ExplicitLabelPhaseCount, + Surface.ExplicitLabelPhaseCount == 1 ? TEXT("") : TEXT("s") + ) + : (SurvivorRosterSurface.bHasCurrentSelectionSurvivorPhaseRoster + && !SurvivorRosterSurface.bPreviewBlocked + ? TEXT("Current-selection explicit-label phases on execute: none") + : TEXT("Current-selection explicit-label phases on execute: unavailable")); + + if (Surface.ExplicitLabelPhases.Num() > 0) + { + TArray OrderedPhaseLabels; + OrderedPhaseLabels.Reserve(Surface.ExplicitLabelPhases.Num()); + TArray NormalizedLabels; + NormalizedLabels.Reserve(Surface.ExplicitLabelPhases.Num()); + for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectPhaseSurface& + PhaseSurface : Surface.ExplicitLabelPhases) + { + OrderedPhaseLabels.Add( + FString::Printf(TEXT("#%d %s"), PhaseSurface.NormalizedOrder, *PhaseSurface.NormalizedLabel) + ); + NormalizedLabels.Add( + FString::Printf(TEXT("%s (%s)"), *PhaseSurface.NormalizedLabel, *PhaseSurface.PhaseId) + ); + } + + Surface.OrderSummaryLine = FString::Printf( + TEXT("Current-selection explicit-label order on execute: %s"), + *FString::Join(OrderedPhaseLabels, TEXT(" | ")) + ); + Surface.LabelSummaryLine = FString::Printf( + TEXT("Current-selection explicit labels on execute: %s"), + *FString::Join(NormalizedLabels, TEXT(", ")) + ); + Surface.CurrentSelectionExplicitLabelRosterLine = + Surface.ExplicitLabelPhaseCountLine; + } + else if (OptionMenuSurface.bHasUnresolvedSelectionDetail) + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: unavailable until the cached selection resolves to an imported option."); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: unavailable until the cached selection resolves to an imported option."); + Surface.CurrentSelectionExplicitLabelRosterLine = + OptionMenuSurface.UnresolvedSelectionLine; + } + else if (SurvivorRosterSurface.bPreviewBlocked) + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: blocked until execute-time survivor-phase inspection is available."); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: blocked until execute-time survivor-phase inspection is available."); + Surface.CurrentSelectionExplicitLabelRosterLine = + SurvivorRosterSurface.CurrentSelectionSurvivorRosterLine; + } + else if (SurvivorRosterSurface.bHasCurrentSelectionSurvivorPhaseRoster) + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: none"); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: none"); + Surface.CurrentSelectionExplicitLabelRosterLine = + TEXT("Current-selection explicit-label roster on execute: none"); + } + else if (OptionMenuSurface.bHasSelection) + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: unavailable"); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: unavailable"); + Surface.CurrentSelectionExplicitLabelRosterLine = + TEXT("Current selection has no additional owned-execution split-phase explicit-label roster preview."); + } + else if (OptionMenuSurface.bHasSelector) + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: unresolved"); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: unresolved"); + Surface.CurrentSelectionExplicitLabelRosterLine = + TEXT("Current selection: unresolved"); + } + else + { + Surface.OrderSummaryLine = + TEXT("Current-selection explicit-label order on execute: n/a"); + Surface.LabelSummaryLine = + TEXT("Current-selection explicit labels on execute: n/a"); + Surface.CurrentSelectionExplicitLabelRosterLine = + TEXT("Current selection: n/a"); + } + + if (Surface.bHasCurrentSelectionExplicitLabelRoster) + { + Surface.StatusLine = FString::Printf( + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect exposes %d explicit-label phase%s for the active selection."), + Surface.ExplicitLabelPhaseCount, + Surface.ExplicitLabelPhaseCount == 1 ? TEXT("") : TEXT("s") + ); + } + else if (OptionMenuSurface.bHasSelector && OptionMenuSurface.bHasUnresolvedSelectionDetail) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect is active, but the cached selection no longer matches an imported option."); + } + else if (SurvivorRosterSurface.bPreviewBlocked) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect resolves the active selection, but execute-time explicit-label inspection remains blocked."); + } + else if (SurvivorRosterSurface.bHasCurrentSelectionSurvivorPhaseRoster) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect resolves the active selection, and no explicit-label phases are currently retained."); + } + else if (OptionMenuSurface.bHasSelector && OptionMenuSurface.bHasSelection) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect is active, but the current selection does not expose explicit-label detail."); + } + else if (OptionMenuSurface.bHasSelector) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection explicit-label roster inspect is active, but this selector is currently unresolved."); + } + else + { + Surface.StatusLine = SurvivorRosterSurface.StatusLine; + } + + Surface.DetailLine = FString::Printf( + TEXT("%s | %s | %s"), + *Surface.CurrentSelectionSelectionLine, + *Surface.CurrentSelectionExplicitLabelRosterLine, + *Surface.OrderSummaryLine + ); + + return Surface; +} + FHyperTwistTrainingCoachQueueControlSurface UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface( const FHyperTwistTrainingCoachSessionQueueState& QueueState, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp index 7120315..f67b9d1 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp @@ -1233,6 +1233,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface +UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FString& SelectorId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + CachedRunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun( const int32 MaxCases, const FString& StartActionSourceLabel diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp index f03d903..624fc08 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp @@ -1214,6 +1214,25 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface +AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FString& SelectorId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + CachedRunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun( const int32 MaxCases ) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h index 958e7ef..a19f974 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h @@ -967,4 +967,14 @@ public: const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& OptionLaunchRequestPreviewSurface ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h index a0f47e1..7fe9900 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h @@ -410,6 +410,12 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FString& SelectorId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedRun( int32 MaxCases, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h index c229803..9bb5119 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h @@ -391,6 +391,12 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface( + const FString& SelectorId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index bdecb10..8d96239 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -13953,3 +13953,148 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPha || bHasCurrentSelectionPhaseIdFallbackRoster; } }; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectPhaseSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PhaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NormalizedLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 EvaluationOrder = -1; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 NormalizedOrder = -1; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OrderLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LabelLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LabelProvenanceLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ExplicitLabelRosterLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanPreview = false; + + bool IsStructurallyValid() const + { + return !PhaseId.IsEmpty() + || !NormalizedLabel.IsEmpty() + || !OrderLine.IsEmpty() + || !LabelProvenanceLine.IsEmpty() + || bCanPreview; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionExplicitLabelRosterInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString BindingLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionSelectionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionExplicitLabelRosterLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ExplicitLabelPhaseCountLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OrderSummaryLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LabelSummaryLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray + ExplicitLabelPhases; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionValue; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind LaunchRequestPreviewKind = + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ExplicitLabelPhaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelector = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelection = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSelectionMatchesAvailableOption = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasCurrentSelectionExplicitLabelRoster = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bStartsOwnedCaseImmediately = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasExactCurrentSelectionExplicitLabelRoster = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bRetainsActiveDeckSplitPhaseFusion = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreviewBlocked = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanPreview = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !SelectorId.IsEmpty() + || !CurrentSelectionExplicitLabelRosterLine.IsEmpty() + || ExplicitLabelPhases.Num() > 0 + || bHasSelector + || bHasSelection + || bHasCurrentSelectionExplicitLabelRoster; + } +}; diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index a58f8da..1997940 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -68,8 +68,8 @@ Current correction call from the source-exposed audit and current execution refr - the imported generated-mode gap is closed; request/config/selection plumbing and the bounded clean-room executor are already landed in first-party code - the latest landed bounded `Phase 4` packet closes the retained-idle comparison/outcome actionability gap at the end of the recognition-assisted coach-to-review continuity lane, and the final retained-surface confirmation pass now leaves that closure lane functionally complete - the retained idle widget surface now keeps retained comparison and decision history inspectable without continuing to advertise live launch or guidance-outcome actions once the coach-to-review loop has already collapsed to truthful closed-loop idle - - the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection phase-id fallback roster inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect only surviving phases whose visible labels fall back to phase id without filtering the broader survivor-phase roster themselves - - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection explicit-label roster inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect only surviving phases whose visible labels come from explicit source labels without filtering the broader survivor-phase roster themselves + - the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection explicit-label roster inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect only surviving phases whose visible labels come from explicit source labels without filtering the broader survivor-phase roster themselves + - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition summary inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect the active selection's explicit-label vs phase-id-fallback split from one summary surface without comparing the two filtered rosters themselves - the current execution-discipline rule that broad refactor / monolith-splitting work should not interrupt the active bounded roadmap packet unless structure is actually blocking it ## Current execution-reality references diff --git a/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_EXPLICIT_LABEL_ROSTER_INSPECT_SURFACE_PACKET_2026-05-08.md b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_EXPLICIT_LABEL_ROSTER_INSPECT_SURFACE_PACKET_2026-05-08.md new file mode 100644 index 0000000..b8aced2 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_EXPLICIT_LABEL_ROSTER_INSPECT_SURFACE_PACKET_2026-05-08.md @@ -0,0 +1,33 @@ +# HyperTwist Phase 4 gameplay generated-mode selector option owned execution split-phase current-selection explicit-label roster inspect surface packet + +## Goal + +Close the next thin gameplay-facing consumer seam above the current-selection survivor-phase roster surface by exposing one current-selection explicit-label roster inspect surface for a chosen selector id. + +## Why this packet exists + +The current-selection survivor-phase roster surface already exposed the active selection's normalized surviving phases, including both explicit-label survivors and phase-id fallback survivors. Gameplay and Blueprint callers that only need the explicit-label subset still had to filter the broader survivor-phase roster themselves. + +This packet removes that caller-side filtering step. It exposes one thin current-selection explicit-label roster inspect surface that projects only surviving phases whose visible labels come from explicit source labels, while preserving unresolved-selection and blocked-preview posture from the already-landed survivor-phase roster surface. + +## What changed + +- add a first-party owned execution split-phase current-selection explicit-label roster inspect surface in shared training types +- derive that surface in the coach library by projecting the already-landed current-selection survivor-phase roster inspect surface instead of reimplementing split-phase normalization logic +- expose the current-selection explicit-label roster inspect surface on both gameplay-facing consumers: + - `UHyperTwistTrainingPanelWidget` + - `AHyperTwistTrainingSessionActor` +- preserve exact explicit-label phase order, normalized labels, and label-provenance lines for the active selection +- preserve unresolved cached-selection and blocked-preview posture when the active selection cannot yet expose an explicit-label roster + +## Validation + +- full `Development Editor|Win64` solution build for `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln` + +## Result + +Gameplay and Blueprint callers can now inspect only the active selection's surviving phases whose visible labels come from explicit source labels from one dedicated explicit-label roster surface without filtering the broader survivor-phase roster first. + +## Next bounded slice + +Stay on the same gameplay-facing consumer lane and expose one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition summary inspect surface so callers can inspect the active selection's explicit-label vs phase-id-fallback split from one summary surface without comparing the two filtered rosters themselves.