Expose gameplay selector split-phase provenance preview surface
This commit is contained in:
parent
6ca05d0c47
commit
1cf96f4f77
9 changed files with 896 additions and 2 deletions
|
|
@ -9041,6 +9041,498 @@ UHyperTwistTrainingCoachLibrary::
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FHyperTwistTrainingRunState& RunState,
|
||||
const FString& SelectorId,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
)
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDetailRetentionPreviewSurface
|
||||
SplitPhaseDetailPreviewSurface =
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDetailRetentionPreviewSurface(
|
||||
RunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
Surface;
|
||||
Surface.SelectorId = SelectorId;
|
||||
Surface.SelectorLabel = OptionMenuSurface.SelectorLabel;
|
||||
Surface.BindingLabel = OptionMenuSurface.BindingLabel;
|
||||
Surface.Headline =
|
||||
TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Phase-Id/Label-Fallback Provenance Preview");
|
||||
Surface.bHasSelector = OptionMenuSurface.bHasSelector;
|
||||
|
||||
if (!SelectorId.IsEmpty())
|
||||
{
|
||||
Surface.Headline = OptionMenuSurface.SelectorLabel.IsEmpty()
|
||||
? FString::Printf(
|
||||
TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Phase-Id/Label-Fallback Provenance Preview: %s"),
|
||||
*SelectorId
|
||||
)
|
||||
: FString::Printf(
|
||||
TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Phase-Id/Label-Fallback Provenance Preview: %s"),
|
||||
*OptionMenuSurface.SelectorLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (SelectorId.IsEmpty())
|
||||
{
|
||||
Surface.StatusLine =
|
||||
TEXT("Generated-mode selector option owned-execution split-phase phase-id/label-fallback provenance preview requires a selector id from the active selector roster.");
|
||||
Surface.SplitPhaseCountSummaryLine = TEXT("Split-phase label provenance: n/a");
|
||||
Surface.LabelProvenanceSummaryLine = TEXT("Label-fallback detail: n/a");
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine = TEXT("Current selection: n/a");
|
||||
Surface.DetailLine = SplitPhaseDetailPreviewSurface.DetailLine.IsEmpty()
|
||||
? TEXT("Launch-request preview: n/a")
|
||||
: SplitPhaseDetailPreviewSurface.DetailLine;
|
||||
return Surface;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingImportedRuntimeSurface& RuntimeSurface =
|
||||
RunState.ActiveDeck.ImportedRuntimeSurface;
|
||||
const bool bHasGeneratedModeSurface = RuntimeSurface.IsStructurallyValid()
|
||||
&& RuntimeSurface.SurfaceKind.Equals(TEXT("generated-mode"), ESearchCase::IgnoreCase);
|
||||
|
||||
if (!RunState.IsStructurallyValid() || !bHasGeneratedModeSurface)
|
||||
{
|
||||
Surface.StatusLine = SplitPhaseDetailPreviewSurface.StatusLine;
|
||||
Surface.SplitPhaseCountSummaryLine = TEXT("Split-phase label provenance: n/a");
|
||||
Surface.LabelProvenanceSummaryLine = TEXT("Label-fallback detail: n/a");
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine =
|
||||
OptionMenuSurface.bHasUnresolvedSelectionDetail
|
||||
? OptionMenuSurface.UnresolvedSelectionLine
|
||||
: (OptionMenuSurface.bHasSelection
|
||||
? TEXT("Current selection remains cached, but no active owned-execution split-phase label provenance preview is available.")
|
||||
: TEXT("Current selection: unresolved"));
|
||||
Surface.DetailLine = SplitPhaseDetailPreviewSurface.DetailLine;
|
||||
return Surface;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingTimingPolicy RawTimingPolicy = RunState.ActiveDeck.TimingPolicy;
|
||||
const FHyperTwistTrainingTimingPolicy PreviewTimingPolicy =
|
||||
UHyperTwistTrainingLibrary::NormalizeTimingPolicy(RawTimingPolicy);
|
||||
|
||||
const auto BuildPhaseProvenanceEntries = [](
|
||||
const FHyperTwistTrainingTimingPolicy& SourceTimingPolicy,
|
||||
const FHyperTwistTrainingTimingPolicy& NormalizedTimingPolicy,
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface>&
|
||||
OutEntries,
|
||||
int32& OutExplicitLabelPhaseCount,
|
||||
int32& OutFallbackLabelPhaseCount
|
||||
)
|
||||
{
|
||||
OutEntries.Reset();
|
||||
OutExplicitLabelPhaseCount = 0;
|
||||
OutFallbackLabelPhaseCount = 0;
|
||||
|
||||
TArray<FHyperTwistTrainingSplitPhaseDefinition> SortedPhases =
|
||||
SourceTimingPolicy.SplitPhases;
|
||||
SortedPhases.Sort([](
|
||||
const FHyperTwistTrainingSplitPhaseDefinition& Left,
|
||||
const FHyperTwistTrainingSplitPhaseDefinition& Right
|
||||
)
|
||||
{
|
||||
if (Left.Order != Right.Order)
|
||||
{
|
||||
return Left.Order < Right.Order;
|
||||
}
|
||||
|
||||
return Left.PhaseId < Right.PhaseId;
|
||||
});
|
||||
|
||||
TSet<FString> SeenPhaseIds;
|
||||
int32 NextOrder = 0;
|
||||
for (const FHyperTwistTrainingSplitPhaseDefinition& PhaseDefinition : SortedPhases)
|
||||
{
|
||||
if (!PhaseDefinition.IsStructurallyValid()
|
||||
|| SeenPhaseIds.Contains(PhaseDefinition.PhaseId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SeenPhaseIds.Add(PhaseDefinition.PhaseId);
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface
|
||||
PhaseEntry;
|
||||
PhaseEntry.PhaseId = PhaseDefinition.PhaseId;
|
||||
PhaseEntry.Order = NextOrder++;
|
||||
PhaseEntry.SourceLabel = PhaseDefinition.Label;
|
||||
PhaseEntry.bSourceLabelWasExplicit = !PhaseDefinition.Label.IsEmpty();
|
||||
PhaseEntry.bLabelFallsBackToPhaseId = !PhaseEntry.bSourceLabelWasExplicit;
|
||||
|
||||
const int32 EntryIndex = OutEntries.Num();
|
||||
const FString NormalizedLabel =
|
||||
NormalizedTimingPolicy.SplitPhases.IsValidIndex(EntryIndex)
|
||||
&& NormalizedTimingPolicy.SplitPhases[EntryIndex].PhaseId
|
||||
== PhaseDefinition.PhaseId
|
||||
? NormalizedTimingPolicy.SplitPhases[EntryIndex].Label
|
||||
: (PhaseDefinition.Label.IsEmpty()
|
||||
? PhaseDefinition.PhaseId
|
||||
: PhaseDefinition.Label);
|
||||
PhaseEntry.NormalizedLabel = NormalizedLabel;
|
||||
PhaseEntry.OrderLine = FString::Printf(
|
||||
TEXT("Normalized phase order on execute: #%d"),
|
||||
PhaseEntry.Order
|
||||
);
|
||||
PhaseEntry.NormalizedLabelLine = FString::Printf(
|
||||
TEXT("Normalized phase label on execute: %s (%s)"),
|
||||
*PhaseEntry.NormalizedLabel,
|
||||
*PhaseEntry.PhaseId
|
||||
);
|
||||
PhaseEntry.LabelProvenanceLine = PhaseEntry.bSourceLabelWasExplicit
|
||||
? FString::Printf(
|
||||
TEXT("Label provenance on execute: explicit source label retained (%s)"),
|
||||
*PhaseDefinition.Label
|
||||
)
|
||||
: FString::Printf(
|
||||
TEXT("Label provenance on execute: phase-id fallback retained because the source label is empty (%s)"),
|
||||
*PhaseEntry.PhaseId
|
||||
);
|
||||
PhaseEntry.DetailLine = FString::Printf(
|
||||
TEXT("%s | %s | %s"),
|
||||
*PhaseEntry.OrderLine,
|
||||
*PhaseEntry.NormalizedLabelLine,
|
||||
*PhaseEntry.LabelProvenanceLine
|
||||
);
|
||||
PhaseEntry.bCanPreview = true;
|
||||
|
||||
if (PhaseEntry.bSourceLabelWasExplicit)
|
||||
{
|
||||
++OutExplicitLabelPhaseCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++OutFallbackLabelPhaseCount;
|
||||
}
|
||||
|
||||
OutEntries.Add(MoveTemp(PhaseEntry));
|
||||
}
|
||||
};
|
||||
|
||||
const auto BuildSplitPhaseCountLine = [](
|
||||
const int32 SplitPhaseCount
|
||||
) -> FString
|
||||
{
|
||||
return SplitPhaseCount > 0
|
||||
? FString::Printf(
|
||||
TEXT("Split-phase label provenance on execute: %d retained phase%s"),
|
||||
SplitPhaseCount,
|
||||
SplitPhaseCount == 1 ? TEXT("") : TEXT("s")
|
||||
)
|
||||
: FString(TEXT("Split-phase label provenance on execute: none"));
|
||||
};
|
||||
|
||||
const auto BuildLabelProvenanceLine = [](
|
||||
const int32 ExplicitLabelPhaseCount,
|
||||
const int32 FallbackLabelPhaseCount
|
||||
) -> FString
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("Label provenance on execute: %d explicit | %d phase-id fallback"),
|
||||
ExplicitLabelPhaseCount,
|
||||
FallbackLabelPhaseCount
|
||||
);
|
||||
};
|
||||
|
||||
const auto BuildFallbackPhaseIdLine = [](
|
||||
const TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface>&
|
||||
PhaseEntries
|
||||
) -> FString
|
||||
{
|
||||
TArray<FString> FallbackPhaseIds;
|
||||
for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface&
|
||||
PhaseEntry : PhaseEntries)
|
||||
{
|
||||
if (PhaseEntry.bLabelFallsBackToPhaseId)
|
||||
{
|
||||
FallbackPhaseIds.Add(PhaseEntry.PhaseId);
|
||||
}
|
||||
}
|
||||
|
||||
return FallbackPhaseIds.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Phase-id fallback labels on execute: %s"),
|
||||
*FString::Join(FallbackPhaseIds, TEXT(", "))
|
||||
)
|
||||
: FString(TEXT("Phase-id fallback labels on execute: none"));
|
||||
};
|
||||
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface>
|
||||
TemplatePhaseEntries;
|
||||
int32 TemplateExplicitLabelPhaseCount = 0;
|
||||
int32 TemplateFallbackLabelPhaseCount = 0;
|
||||
BuildPhaseProvenanceEntries(
|
||||
RawTimingPolicy,
|
||||
PreviewTimingPolicy,
|
||||
TemplatePhaseEntries,
|
||||
TemplateExplicitLabelPhaseCount,
|
||||
TemplateFallbackLabelPhaseCount
|
||||
);
|
||||
const int32 TemplateSplitPhaseCount = TemplatePhaseEntries.Num();
|
||||
const bool bTemplateHasSplitPhases = TemplateSplitPhaseCount > 0;
|
||||
const bool bTemplateHasFallbackLabels = TemplateFallbackLabelPhaseCount > 0;
|
||||
const FString TemplateSplitPhaseCountLine = BuildSplitPhaseCountLine(
|
||||
TemplateSplitPhaseCount
|
||||
);
|
||||
const FString TemplateLabelProvenanceLine = BuildLabelProvenanceLine(
|
||||
TemplateExplicitLabelPhaseCount,
|
||||
TemplateFallbackLabelPhaseCount
|
||||
);
|
||||
const FString TemplateFallbackPhaseIdLine = BuildFallbackPhaseIdLine(
|
||||
TemplatePhaseEntries
|
||||
);
|
||||
|
||||
for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDetailRetentionPreviewEntrySurface&
|
||||
SplitPhaseEntry : SplitPhaseDetailPreviewSurface.OptionEntries)
|
||||
{
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewEntrySurface
|
||||
Entry;
|
||||
Entry.OptionId = SplitPhaseEntry.OptionId;
|
||||
Entry.Label = SplitPhaseEntry.Label;
|
||||
Entry.OptionValue = SplitPhaseEntry.OptionValue;
|
||||
Entry.LaunchRequestPreviewKind = SplitPhaseEntry.LaunchRequestPreviewKind;
|
||||
Entry.bMatchesCurrentSelection = SplitPhaseEntry.bMatchesCurrentSelection;
|
||||
Entry.bStartsOwnedCaseImmediately = SplitPhaseEntry.bStartsOwnedCaseImmediately;
|
||||
|
||||
switch (SplitPhaseEntry.LaunchRequestPreviewKind)
|
||||
{
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
DirectOwnedCaseStart:
|
||||
Entry.PhaseEntries = TemplatePhaseEntries;
|
||||
Entry.SplitPhaseCount = TemplateSplitPhaseCount;
|
||||
Entry.ExplicitLabelPhaseCount = TemplateExplicitLabelPhaseCount;
|
||||
Entry.FallbackLabelPhaseCount = TemplateFallbackLabelPhaseCount;
|
||||
Entry.bHasSplitPhases = bTemplateHasSplitPhases;
|
||||
Entry.bHasFallbackLabels = bTemplateHasFallbackLabels;
|
||||
Entry.SplitPhaseCountLine = TemplateSplitPhaseCountLine;
|
||||
Entry.LabelProvenanceLine = TemplateLabelProvenanceLine;
|
||||
Entry.FallbackPhaseIdLine = TemplateFallbackPhaseIdLine;
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase provenance source: exact normalized active-deck split-phase labels retained on direct covered-case start.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bHasExactSplitPhaseLabelProvenancePreview = true;
|
||||
Entry.bRetainsActiveDeckSplitPhaseLabelProvenance = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.DirectExactOptionCount;
|
||||
if (Entry.bHasSplitPhases)
|
||||
{
|
||||
++Surface.NonEmptySplitPhaseOptionCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++Surface.EmptySplitPhaseOptionCount;
|
||||
}
|
||||
if (Entry.bHasFallbackLabels)
|
||||
{
|
||||
++Surface.OptionsWithFallbackLabelCount;
|
||||
}
|
||||
Surface.TotalPreviewedSplitPhaseCount += Entry.SplitPhaseCount;
|
||||
Surface.ExplicitLabelPhaseCount += Entry.ExplicitLabelPhaseCount;
|
||||
Surface.FallbackLabelPhaseCount += Entry.FallbackLabelPhaseCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
StoredRequestReusable:
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
RefreshRequired:
|
||||
Entry.PhaseEntries = TemplatePhaseEntries;
|
||||
Entry.SplitPhaseCount = TemplateSplitPhaseCount;
|
||||
Entry.ExplicitLabelPhaseCount = TemplateExplicitLabelPhaseCount;
|
||||
Entry.FallbackLabelPhaseCount = TemplateFallbackLabelPhaseCount;
|
||||
Entry.bHasSplitPhases = bTemplateHasSplitPhases;
|
||||
Entry.bHasFallbackLabels = bTemplateHasFallbackLabels;
|
||||
Entry.SplitPhaseCountLine = TemplateSplitPhaseCountLine;
|
||||
Entry.LabelProvenanceLine = TemplateLabelProvenanceLine;
|
||||
Entry.FallbackPhaseIdLine = TemplateFallbackPhaseIdLine;
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase provenance source: exact normalized source-deck split-phase labels retained on generated owned execution.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bHasExactSplitPhaseLabelProvenancePreview = true;
|
||||
Entry.bRetainsActiveDeckSplitPhaseLabelProvenance = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.GeneratedExactOptionCount;
|
||||
if (Entry.bHasSplitPhases)
|
||||
{
|
||||
++Surface.NonEmptySplitPhaseOptionCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++Surface.EmptySplitPhaseOptionCount;
|
||||
}
|
||||
if (Entry.bHasFallbackLabels)
|
||||
{
|
||||
++Surface.OptionsWithFallbackLabelCount;
|
||||
}
|
||||
Surface.TotalPreviewedSplitPhaseCount += Entry.SplitPhaseCount;
|
||||
Surface.ExplicitLabelPhaseCount += Entry.ExplicitLabelPhaseCount;
|
||||
Surface.FallbackLabelPhaseCount += Entry.FallbackLabelPhaseCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
UnresolvedAfterChoice:
|
||||
Entry.SplitPhaseCountLine =
|
||||
TEXT("Split-phase label provenance on execute: blocked until every required selector is resolved.");
|
||||
Entry.LabelProvenanceLine =
|
||||
TEXT("Label provenance on execute: blocked until every required selector is resolved.");
|
||||
Entry.FallbackPhaseIdLine =
|
||||
TEXT("Phase-id fallback labels on execute: blocked until every required selector is resolved.");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase provenance source: blocked while selector coverage remains incomplete.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bPreviewBlocked = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.BlockedOptionCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
PayloadUnavailable:
|
||||
Entry.SplitPhaseCountLine =
|
||||
TEXT("Split-phase label provenance on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.LabelProvenanceLine =
|
||||
TEXT("Label provenance on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.FallbackPhaseIdLine =
|
||||
TEXT("Phase-id fallback labels on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase provenance source: blocked while the hypothetical generated-mode payload remains structurally invalid.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bPreviewBlocked = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.BlockedOptionCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::Unavailable:
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None:
|
||||
default:
|
||||
Entry.SplitPhaseCountLine =
|
||||
TEXT("Split-phase label provenance on execute: unavailable");
|
||||
Entry.LabelProvenanceLine =
|
||||
TEXT("Label provenance on execute: unavailable");
|
||||
Entry.FallbackPhaseIdLine =
|
||||
TEXT("Phase-id fallback labels on execute: unavailable");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase provenance source: unavailable");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bCanPreview = false;
|
||||
++Surface.UnavailableOptionCount;
|
||||
break;
|
||||
}
|
||||
|
||||
const FString EntryDetail = Entry.SplitPhaseSourceLine.IsEmpty()
|
||||
? Entry.PreviewStabilityLine
|
||||
: FString::Printf(
|
||||
TEXT("%s | %s"),
|
||||
*Entry.PreviewStabilityLine,
|
||||
*Entry.SplitPhaseSourceLine
|
||||
);
|
||||
Entry.DetailLine = EntryDetail;
|
||||
|
||||
if (Entry.bMatchesCurrentSelection)
|
||||
{
|
||||
Surface.bCurrentSelectionHasExactSplitPhaseLabelProvenancePreview =
|
||||
Entry.bHasExactSplitPhaseLabelProvenancePreview;
|
||||
Surface.bCurrentSelectionRetainsActiveDeckSplitPhaseLabelProvenance =
|
||||
Entry.bRetainsActiveDeckSplitPhaseLabelProvenance;
|
||||
Surface.bCurrentSelectionHasSplitPhases = Entry.bHasSplitPhases;
|
||||
Surface.bCurrentSelectionHasFallbackLabels = Entry.bHasFallbackLabels;
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine = FString::Printf(
|
||||
TEXT("%s | %s | %s"),
|
||||
*Entry.SplitPhaseCountLine,
|
||||
*Entry.LabelProvenanceLine,
|
||||
*Entry.FallbackPhaseIdLine
|
||||
);
|
||||
}
|
||||
|
||||
Surface.OptionEntries.Add(MoveTemp(Entry));
|
||||
}
|
||||
|
||||
Surface.bHasOwnedExecutionSplitPhaseLabelProvenancePreviewOptions =
|
||||
Surface.OptionEntries.Num() > 0;
|
||||
Surface.bHasDirectSplitPhaseLabelProvenancePreviewOptions =
|
||||
Surface.DirectExactOptionCount > 0;
|
||||
Surface.bHasGeneratedSplitPhaseLabelProvenancePreviewOptions =
|
||||
Surface.GeneratedExactOptionCount > 0;
|
||||
Surface.bHasBlockedSplitPhaseLabelProvenancePreviewOptions =
|
||||
Surface.BlockedOptionCount > 0;
|
||||
|
||||
Surface.SplitPhaseCountSummaryLine = Surface.OptionEntries.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Split-phase label provenance: %d options with retained phases | %d options with none | %d total phases | %d blocked | %d unavailable"),
|
||||
Surface.NonEmptySplitPhaseOptionCount,
|
||||
Surface.EmptySplitPhaseOptionCount,
|
||||
Surface.TotalPreviewedSplitPhaseCount,
|
||||
Surface.BlockedOptionCount,
|
||||
Surface.UnavailableOptionCount
|
||||
)
|
||||
: TEXT("Split-phase label provenance: no imported options");
|
||||
Surface.LabelProvenanceSummaryLine = Surface.OptionEntries.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Label-fallback detail: %d explicit labels | %d phase-id fallbacks | %d options with at least one fallback"),
|
||||
Surface.ExplicitLabelPhaseCount,
|
||||
Surface.FallbackLabelPhaseCount,
|
||||
Surface.OptionsWithFallbackLabelCount
|
||||
)
|
||||
: TEXT("Label-fallback detail: no imported options");
|
||||
|
||||
if (Surface.CurrentSelectionSplitPhaseProvenanceLine.IsEmpty())
|
||||
{
|
||||
if (OptionMenuSurface.bHasUnresolvedSelectionDetail)
|
||||
{
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine =
|
||||
OptionMenuSurface.UnresolvedSelectionLine;
|
||||
}
|
||||
else if (OptionMenuSurface.bHasSelection)
|
||||
{
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine =
|
||||
TEXT("Current selection has no additional owned-execution split-phase label provenance preview.");
|
||||
}
|
||||
else if (OptionMenuSurface.bHasSelector)
|
||||
{
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine =
|
||||
TEXT("Current selection: unresolved");
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface.CurrentSelectionSplitPhaseProvenanceLine =
|
||||
TEXT("Current selection: n/a");
|
||||
}
|
||||
}
|
||||
|
||||
if (OptionMenuSurface.bHasSelector && Surface.OptionEntries.Num() > 0)
|
||||
{
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Generated-mode selector option owned-execution split-phase phase-id/label-fallback provenance preview exposes %d direct exact option%s, %d generated exact option%s, %d blocked option%s, and %d unavailable option%s."),
|
||||
Surface.DirectExactOptionCount,
|
||||
Surface.DirectExactOptionCount == 1 ? TEXT("") : TEXT("s"),
|
||||
Surface.GeneratedExactOptionCount,
|
||||
Surface.GeneratedExactOptionCount == 1 ? TEXT("") : TEXT("s"),
|
||||
Surface.BlockedOptionCount,
|
||||
Surface.BlockedOptionCount == 1 ? TEXT("") : TEXT("s"),
|
||||
Surface.UnavailableOptionCount,
|
||||
Surface.UnavailableOptionCount == 1 ? TEXT("") : TEXT("s")
|
||||
);
|
||||
}
|
||||
else if (OptionMenuSurface.bHasSelector)
|
||||
{
|
||||
Surface.StatusLine =
|
||||
TEXT("Generated-mode selector option owned-execution split-phase phase-id/label-fallback provenance preview is active, but this selector does not expose imported options.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface.StatusLine = SplitPhaseDetailPreviewSurface.StatusLine;
|
||||
}
|
||||
|
||||
Surface.DetailLine = SplitPhaseDetailPreviewSurface.DetailLine;
|
||||
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachQueueControlSurface
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface(
|
||||
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
|
||||
OptionLaunchRequestPreviewSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
|
||||
return UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
CachedRunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
|
||||
const int32 MaxCases,
|
||||
const FString& StartActionSourceLabel
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,25 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
|
||||
OptionLaunchRequestPreviewSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
|
||||
return UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
CachedRunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
|
|
|
|||
|
|
@ -887,4 +887,14 @@ public:
|
|||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FHyperTwistTrainingRunState& RunState,
|
||||
const FString& SelectorId,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -362,6 +362,12 @@ public:
|
|||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedRun(
|
||||
int32 MaxCases,
|
||||
|
|
|
|||
|
|
@ -343,6 +343,12 @@ public:
|
|||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
|
|
|
|||
|
|
@ -12328,3 +12328,240 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPha
|
|||
|| bHasOwnedExecutionSplitPhaseDetailRetentionPreviewOptions;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PhaseId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NormalizedLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 Order = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString OrderLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NormalizedLabelLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LabelProvenanceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSourceLabelWasExplicit = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bLabelFallsBackToPhaseId = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCanPreview = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !PhaseId.IsEmpty()
|
||||
|| !NormalizedLabel.IsEmpty()
|
||||
|| !OrderLine.IsEmpty()
|
||||
|| !LabelProvenanceLine.IsEmpty()
|
||||
|| bCanPreview;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewEntrySurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString OptionId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Label;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString OptionValue;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind LaunchRequestPreviewKind =
|
||||
EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SplitPhaseCountLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LabelProvenanceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FallbackPhaseIdLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SplitPhaseSourceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreviewStabilityLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface>
|
||||
PhaseEntries;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SplitPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ExplicitLabelPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FallbackLabelPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bMatchesCurrentSelection = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bStartsOwnedCaseImmediately = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasExactSplitPhaseLabelProvenancePreview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRetainsActiveDeckSplitPhaseLabelProvenance = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSplitPhases = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasFallbackLabels = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreviewBlocked = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCanPreview = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !OptionId.IsEmpty()
|
||||
|| !Label.IsEmpty()
|
||||
|| !SplitPhaseCountLine.IsEmpty()
|
||||
|| !LabelProvenanceLine.IsEmpty()
|
||||
|| !FallbackPhaseIdLine.IsEmpty()
|
||||
|| LaunchRequestPreviewKind
|
||||
!= EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None
|
||||
|| bCanPreview;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
{
|
||||
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 SplitPhaseCountSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LabelProvenanceSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CurrentSelectionSplitPhaseProvenanceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewEntrySurface>
|
||||
OptionEntries;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DirectExactOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 GeneratedExactOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 BlockedOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 UnavailableOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 NonEmptySplitPhaseOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 EmptySplitPhaseOptionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 TotalPreviewedSplitPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ExplicitLabelPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FallbackLabelPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 OptionsWithFallbackLabelCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelector = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasOwnedExecutionSplitPhaseLabelProvenancePreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDirectSplitPhaseLabelProvenancePreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasGeneratedSplitPhaseLabelProvenancePreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasBlockedSplitPhaseLabelProvenancePreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasExactSplitPhaseLabelProvenancePreview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionRetainsActiveDeckSplitPhaseLabelProvenance = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasSplitPhases = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasFallbackLabels = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !SelectorId.IsEmpty()
|
||||
|| OptionEntries.Num() > 0
|
||||
|| bHasSelector
|
||||
|| bHasOwnedExecutionSplitPhaseLabelProvenancePreviewOptions;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 detail retention preview surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect normalized phase order and labels for a chosen option without rebuilding timing-policy normalization rules directly
|
||||
- the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase phase-id / label-fallback provenance preview surface on those same two consumer surfaces so gameplay/Blueprint callers can distinguish explicit labels from phase-id fallback without rebuilding timing-policy normalization rules directly
|
||||
- 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 phase-id / label-fallback provenance preview surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can distinguish explicit labels from phase-id fallback without rebuilding timing-policy normalization rules directly
|
||||
- the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase duplicate-pruning / survivor provenance preview surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect which raw split-phase definitions actually survive normalization and duplicate rejection without rebuilding timing-policy normalization rules directly
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
# HyperTwist Phase 4 gameplay generated-mode selector option owned execution split-phase phase-id / label-fallback provenance preview surface packet
|
||||
|
||||
Created on `2026-05-08`
|
||||
|
||||
Status:
|
||||
|
||||
- first-party HyperTwist packet
|
||||
- bounded Phase `4` gameplay-facing consumer slice
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet closes the next thin gameplay-facing consumer seam above the panel-widget and session-actor generated-mode selector option owned execution split-phase detail retention preview surface by exposing one parameterized owned execution split-phase phase-id / label-fallback provenance preview surface for a chosen selector id.
|
||||
|
||||
The open tasks were:
|
||||
|
||||
- stop forcing gameplay / Blueprint callers to rebuild timing-policy normalization rules just to distinguish explicit split-phase labels from normalization fallback to `PhaseId`
|
||||
- expose direct covered-case split-phase label provenance and generated owned-execution split-phase label provenance on the same thin consumer lane
|
||||
- expose per-phase label provenance without widening into backend execution behavior
|
||||
|
||||
It is not:
|
||||
|
||||
- a selector-dispatch behavior change
|
||||
- a generated-mode launch-request persistence behavior change
|
||||
- a generated-mode execution deck synthesis change
|
||||
- a broader gameplay UI composition pass
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- add first-party owned execution split-phase phase-id / label-fallback provenance preview surfaces in shared training types
|
||||
- add a coach-library helper that reconstructs the retained normalized split-phase set from the raw timing policy using the same sort / dedupe / fallback rule as timing normalization
|
||||
- expose that parameterized split-phase provenance preview surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
|
||||
- keep the derivation presentation-only and rooted in the already-owned selector/runtime/request surfaces
|
||||
|
||||
Out of scope:
|
||||
|
||||
- changing selector-choice apply behavior
|
||||
- changing stored launch-request creation, refresh, or execute behavior
|
||||
- changing generated-mode execution deck synthesis
|
||||
- widening into dashboard-only or broader gameplay composition work
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- gameplay-facing panel/session consumers already exposed truthful owned case identity, prompt presentation, execution modality, execution scope, provenance posture, deck container posture, retained runtime-surface identity, retained delivery-mode posture, retained deck capability posture, retained timing-policy posture, and retained normalized split-phase detail for imported selector options
|
||||
- callers could already inspect retained normalized phase order and labels for a chosen option
|
||||
|
||||
But one thin consumer seam was still open:
|
||||
|
||||
- callers still had to reconstruct whether each retained normalized phase label came from an explicit source label or from the normalization fallback that substitutes `PhaseId` when the source label is empty
|
||||
|
||||
That meant:
|
||||
|
||||
- split-phase detail preview was already thin and reusable
|
||||
- but phase-id / label-fallback provenance still leaked timing-policy normalization rules into callers
|
||||
|
||||
So the next bounded move was:
|
||||
|
||||
- keep the already-landed owned execution split-phase detail retention preview surface unchanged in behavior
|
||||
- reuse that split-phase detail preview as the exact/blocked/unavailable option-state baseline and expose one narrow label-provenance surface above it
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewPhaseEntrySurface`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewEntrySurface`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
|
||||
- added `DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(...)`
|
||||
- split-phase label provenance preview is derived from cached run state plus the already-landed split-phase detail retention preview surface and reconstructs the retained normalized split-phase set from the raw timing policy
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
|
||||
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(const FString& SelectorId)`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
|
||||
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(const FString& SelectorId)`
|
||||
|
||||
Surface behavior:
|
||||
|
||||
- reports exact normalized retained split-phase label provenance for direct covered-case starts
|
||||
- reports exact normalized retained split-phase label provenance for generated owned-execution paths
|
||||
- distinguishes explicit source labels from phase-id fallback per retained phase entry
|
||||
- exposes option-level counts for explicit labels, phase-id fallbacks, and options that contain at least one fallback label
|
||||
- keeps reusable stored-request cases and refresh-required generated cases exact because execute still retains the same normalized split-phase label provenance even when request refresh is required
|
||||
- keeps unresolved or payload-invalid choices inspectable as blocked split-phase label-provenance preview states instead of collapsing them into a generic unavailable branch
|
||||
- keeps the surface presentation-only and compatible with the already-landed launch / execution, request-alignment, stored-request delta, launch-request payload / refresh-preview, launch-request metadata / origin-notes preview, launch-request envelope / request-source preview, owned execution case / canonical-state preview, owned execution prompt preview, owned execution delivery preview, owned execution scope preview, owned execution provenance preview, owned execution deck-title / selection-policy preview, owned execution deck-id / runtime-surface retention preview, owned execution delivery-mode roster / allowed-mode retention preview, owned execution deck capability retention preview, owned execution timing-policy retention preview, and owned execution split-phase detail retention preview surfaces
|
||||
|
||||
## Validation
|
||||
|
||||
Validation target:
|
||||
|
||||
- full `Development Editor|Win64` build of `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln`
|
||||
|
||||
Result:
|
||||
|
||||
- passed with `0` warnings and `0` errors
|
||||
|
||||
## Follow-on
|
||||
|
||||
The next bounded packet on this same gameplay-facing consumer lane should stay thin and expose one generated-mode selector option owned execution split-phase duplicate-pruning / survivor provenance preview surface so callers can inspect which raw split-phase definitions actually survive normalization and duplicate rejection without rebuilding timing-policy normalization rules directly.
|
||||
Loading…
Add table
Reference in a new issue