Expose gameplay selector split-phase duplicate-pruning preview surface
This commit is contained in:
parent
1cf96f4f77
commit
9d91cc37af
9 changed files with 1031 additions and 2 deletions
|
|
@ -9533,6 +9533,621 @@ UHyperTwistTrainingCoachLibrary::
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FHyperTwistTrainingRunState& RunState,
|
||||
const FString& SelectorId,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
)
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface
|
||||
SplitPhaseLabelProvenancePreviewSurface =
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewSurface(
|
||||
RunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
Surface;
|
||||
Surface.SelectorId = SelectorId;
|
||||
Surface.SelectorLabel = OptionMenuSurface.SelectorLabel;
|
||||
Surface.BindingLabel = OptionMenuSurface.BindingLabel;
|
||||
Surface.Headline =
|
||||
TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Duplicate-Pruning/Survivor 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 Duplicate-Pruning/Survivor Provenance Preview: %s"),
|
||||
*SelectorId
|
||||
)
|
||||
: FString::Printf(
|
||||
TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Duplicate-Pruning/Survivor Provenance Preview: %s"),
|
||||
*OptionMenuSurface.SelectorLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (SelectorId.IsEmpty())
|
||||
{
|
||||
Surface.StatusLine =
|
||||
TEXT("Generated-mode selector option owned-execution split-phase duplicate-pruning / survivor provenance preview requires a selector id from the active selector roster.");
|
||||
Surface.RawSplitPhaseCountSummaryLine = TEXT("Split-phase duplicate-pruning: n/a");
|
||||
Surface.DuplicatePruningSummaryLine = TEXT("Survivor provenance detail: n/a");
|
||||
Surface.CurrentSelectionDuplicatePruningLine = TEXT("Current selection: n/a");
|
||||
Surface.DetailLine = SplitPhaseLabelProvenancePreviewSurface.DetailLine.IsEmpty()
|
||||
? TEXT("Launch-request preview: n/a")
|
||||
: SplitPhaseLabelProvenancePreviewSurface.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 = SplitPhaseLabelProvenancePreviewSurface.StatusLine;
|
||||
Surface.RawSplitPhaseCountSummaryLine = TEXT("Split-phase duplicate-pruning: n/a");
|
||||
Surface.DuplicatePruningSummaryLine = TEXT("Survivor provenance detail: n/a");
|
||||
Surface.CurrentSelectionDuplicatePruningLine =
|
||||
OptionMenuSurface.bHasUnresolvedSelectionDetail
|
||||
? OptionMenuSurface.UnresolvedSelectionLine
|
||||
: (OptionMenuSurface.bHasSelection
|
||||
? TEXT("Current selection remains cached, but no active owned-execution split-phase duplicate-pruning preview is available.")
|
||||
: TEXT("Current selection: unresolved"));
|
||||
Surface.DetailLine = SplitPhaseLabelProvenancePreviewSurface.DetailLine;
|
||||
return Surface;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingTimingPolicy RawTimingPolicy = RunState.ActiveDeck.TimingPolicy;
|
||||
const FHyperTwistTrainingTimingPolicy PreviewTimingPolicy =
|
||||
UHyperTwistTrainingLibrary::NormalizeTimingPolicy(RawTimingPolicy);
|
||||
|
||||
const auto BuildInvalidReason = [](
|
||||
const FHyperTwistTrainingSplitPhaseDefinition& PhaseDefinition
|
||||
) -> FString
|
||||
{
|
||||
TArray<FString> Reasons;
|
||||
if (PhaseDefinition.PhaseId.IsEmpty())
|
||||
{
|
||||
Reasons.Add(TEXT("phase id is empty"));
|
||||
}
|
||||
if (PhaseDefinition.Order < 0)
|
||||
{
|
||||
Reasons.Add(TEXT("order is negative"));
|
||||
}
|
||||
|
||||
return Reasons.Num() > 0
|
||||
? FString::Join(Reasons, TEXT("; "))
|
||||
: FString(TEXT("definition is structurally invalid"));
|
||||
};
|
||||
|
||||
const auto BuildRawPhaseEntries = [&BuildInvalidReason](
|
||||
const FHyperTwistTrainingTimingPolicy& SourceTimingPolicy,
|
||||
const FHyperTwistTrainingTimingPolicy& NormalizedTimingPolicy,
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface>&
|
||||
OutEntries,
|
||||
int32& OutSurvivorPhaseCount,
|
||||
int32& OutDuplicatePrunedPhaseCount,
|
||||
int32& OutInvalidRawDefinitionCount
|
||||
)
|
||||
{
|
||||
struct FSurvivorMetadata
|
||||
{
|
||||
int32 NormalizedOrder = -1;
|
||||
int32 EvaluationOrder = -1;
|
||||
FString NormalizedLabel;
|
||||
};
|
||||
|
||||
OutEntries.Reset();
|
||||
OutSurvivorPhaseCount = 0;
|
||||
OutDuplicatePrunedPhaseCount = 0;
|
||||
OutInvalidRawDefinitionCount = 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;
|
||||
});
|
||||
|
||||
TMap<FString, FSurvivorMetadata> SurvivorMetadataByPhaseId;
|
||||
int32 NextNormalizedOrder = 0;
|
||||
for (int32 SortedIndex = 0; SortedIndex < SortedPhases.Num(); ++SortedIndex)
|
||||
{
|
||||
const FHyperTwistTrainingSplitPhaseDefinition& PhaseDefinition =
|
||||
SortedPhases[SortedIndex];
|
||||
const FString DisplayPhaseId = PhaseDefinition.PhaseId.IsEmpty()
|
||||
? TEXT("<empty>")
|
||||
: PhaseDefinition.PhaseId;
|
||||
const FString DisplayLabel = PhaseDefinition.Label.IsEmpty()
|
||||
? TEXT("<empty>")
|
||||
: PhaseDefinition.Label;
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface
|
||||
Entry;
|
||||
Entry.PhaseId = PhaseDefinition.PhaseId;
|
||||
Entry.SourceLabel = PhaseDefinition.Label;
|
||||
Entry.RawOrder = PhaseDefinition.Order;
|
||||
Entry.EvaluationOrder = SortedIndex;
|
||||
Entry.bSourceLabelWasExplicit = !PhaseDefinition.Label.IsEmpty();
|
||||
Entry.bStructurallyValid = PhaseDefinition.IsStructurallyValid();
|
||||
Entry.RawDefinitionLine = FString::Printf(
|
||||
TEXT("Raw definition before normalize: order %d | phase id %s | label %s"),
|
||||
PhaseDefinition.Order,
|
||||
*DisplayPhaseId,
|
||||
*DisplayLabel
|
||||
);
|
||||
Entry.EvaluationOrderLine = FString::Printf(
|
||||
TEXT("Normalization evaluation order on execute: #%d"),
|
||||
SortedIndex
|
||||
);
|
||||
|
||||
if (!Entry.bStructurallyValid)
|
||||
{
|
||||
Entry.bDroppedBecauseInvalid = true;
|
||||
Entry.NormalizationOutcomeLine = FString::Printf(
|
||||
TEXT("Normalization outcome on execute: skipped because the raw definition is structurally invalid (%s)"),
|
||||
*BuildInvalidReason(PhaseDefinition)
|
||||
);
|
||||
Entry.DuplicatePruningProvenanceLine =
|
||||
TEXT("Duplicate-pruning provenance on execute: invalid raw definitions never enter duplicate resolution.");
|
||||
Entry.DetailLine = FString::Printf(
|
||||
TEXT("%s | %s | %s"),
|
||||
*Entry.RawDefinitionLine,
|
||||
*Entry.NormalizationOutcomeLine,
|
||||
*Entry.DuplicatePruningProvenanceLine
|
||||
);
|
||||
Entry.bCanPreview = true;
|
||||
++OutInvalidRawDefinitionCount;
|
||||
OutEntries.Add(MoveTemp(Entry));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const FSurvivorMetadata* ExistingSurvivor =
|
||||
SurvivorMetadataByPhaseId.Find(PhaseDefinition.PhaseId))
|
||||
{
|
||||
Entry.bDroppedBecauseDuplicate = true;
|
||||
Entry.NormalizedOrder = ExistingSurvivor->NormalizedOrder;
|
||||
Entry.SurvivorNormalizedLabel = ExistingSurvivor->NormalizedLabel;
|
||||
Entry.NormalizationOutcomeLine = FString::Printf(
|
||||
TEXT("Normalization outcome on execute: dropped as a duplicate raw definition for phase id %s."),
|
||||
*DisplayPhaseId
|
||||
);
|
||||
Entry.DuplicatePruningProvenanceLine = FString::Printf(
|
||||
TEXT("Duplicate-pruning provenance on execute: earlier survivor already retained phase id %s at normalized order #%d with label %s."),
|
||||
*DisplayPhaseId,
|
||||
ExistingSurvivor->NormalizedOrder,
|
||||
*ExistingSurvivor->NormalizedLabel
|
||||
);
|
||||
Entry.DetailLine = FString::Printf(
|
||||
TEXT("%s | %s | %s"),
|
||||
*Entry.RawDefinitionLine,
|
||||
*Entry.NormalizationOutcomeLine,
|
||||
*Entry.DuplicatePruningProvenanceLine
|
||||
);
|
||||
Entry.bCanPreview = true;
|
||||
++OutDuplicatePrunedPhaseCount;
|
||||
OutEntries.Add(MoveTemp(Entry));
|
||||
continue;
|
||||
}
|
||||
|
||||
Entry.bSurvivesNormalization = true;
|
||||
Entry.NormalizedOrder = NextNormalizedOrder;
|
||||
Entry.SurvivorNormalizedLabel =
|
||||
NormalizedTimingPolicy.SplitPhases.IsValidIndex(NextNormalizedOrder)
|
||||
&& NormalizedTimingPolicy.SplitPhases[NextNormalizedOrder].PhaseId
|
||||
== PhaseDefinition.PhaseId
|
||||
? NormalizedTimingPolicy.SplitPhases[NextNormalizedOrder].Label
|
||||
: (PhaseDefinition.Label.IsEmpty()
|
||||
? PhaseDefinition.PhaseId
|
||||
: PhaseDefinition.Label);
|
||||
Entry.NormalizationOutcomeLine = FString::Printf(
|
||||
TEXT("Normalization outcome on execute: retained as survivor #%d with normalized label %s (%s)."),
|
||||
Entry.NormalizedOrder,
|
||||
*Entry.SurvivorNormalizedLabel,
|
||||
*DisplayPhaseId
|
||||
);
|
||||
Entry.DuplicatePruningProvenanceLine = FString::Printf(
|
||||
TEXT("Duplicate-pruning provenance on execute: first valid definition for phase id %s survives duplicate rejection."),
|
||||
*DisplayPhaseId
|
||||
);
|
||||
Entry.DetailLine = FString::Printf(
|
||||
TEXT("%s | %s | %s"),
|
||||
*Entry.RawDefinitionLine,
|
||||
*Entry.NormalizationOutcomeLine,
|
||||
*Entry.DuplicatePruningProvenanceLine
|
||||
);
|
||||
Entry.bCanPreview = true;
|
||||
|
||||
FSurvivorMetadata SurvivorMetadata;
|
||||
SurvivorMetadata.NormalizedOrder = Entry.NormalizedOrder;
|
||||
SurvivorMetadata.EvaluationOrder = Entry.EvaluationOrder;
|
||||
SurvivorMetadata.NormalizedLabel = Entry.SurvivorNormalizedLabel;
|
||||
SurvivorMetadataByPhaseId.Add(PhaseDefinition.PhaseId, MoveTemp(SurvivorMetadata));
|
||||
|
||||
++NextNormalizedOrder;
|
||||
++OutSurvivorPhaseCount;
|
||||
OutEntries.Add(MoveTemp(Entry));
|
||||
}
|
||||
};
|
||||
|
||||
const auto BuildRawSplitPhaseCountLine = [](
|
||||
const int32 RawSplitPhaseCount
|
||||
) -> FString
|
||||
{
|
||||
return RawSplitPhaseCount > 0
|
||||
? FString::Printf(
|
||||
TEXT("Raw split-phase definitions before normalize: %d"),
|
||||
RawSplitPhaseCount
|
||||
)
|
||||
: FString(TEXT("Raw split-phase definitions before normalize: none"));
|
||||
};
|
||||
|
||||
const auto BuildSurvivorCountLine = [](
|
||||
const int32 SurvivorPhaseCount
|
||||
) -> FString
|
||||
{
|
||||
return SurvivorPhaseCount > 0
|
||||
? FString::Printf(
|
||||
TEXT("Surviving normalized split phases on execute: %d"),
|
||||
SurvivorPhaseCount
|
||||
)
|
||||
: FString(TEXT("Surviving normalized split phases on execute: none"));
|
||||
};
|
||||
|
||||
const auto BuildDuplicatePruningLine = [](
|
||||
const int32 DuplicatePrunedPhaseCount
|
||||
) -> FString
|
||||
{
|
||||
return DuplicatePrunedPhaseCount > 0
|
||||
? FString::Printf(
|
||||
TEXT("Duplicate-pruned raw split-phase definitions on execute: %d"),
|
||||
DuplicatePrunedPhaseCount
|
||||
)
|
||||
: FString(TEXT("Duplicate-pruned raw split-phase definitions on execute: none"));
|
||||
};
|
||||
|
||||
const auto BuildInvalidDefinitionLine = [](
|
||||
const int32 InvalidRawDefinitionCount
|
||||
) -> FString
|
||||
{
|
||||
return InvalidRawDefinitionCount > 0
|
||||
? FString::Printf(
|
||||
TEXT("Invalid raw split-phase definitions skipped on execute: %d"),
|
||||
InvalidRawDefinitionCount
|
||||
)
|
||||
: FString(TEXT("Invalid raw split-phase definitions skipped on execute: none"));
|
||||
};
|
||||
|
||||
const auto BuildSurvivorPhaseIdLine = [](
|
||||
const TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface>&
|
||||
RawPhaseEntries
|
||||
) -> FString
|
||||
{
|
||||
TArray<FString> SurvivorPhaseIds;
|
||||
for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface&
|
||||
Entry : RawPhaseEntries)
|
||||
{
|
||||
if (Entry.bSurvivesNormalization)
|
||||
{
|
||||
SurvivorPhaseIds.Add(Entry.PhaseId);
|
||||
}
|
||||
}
|
||||
|
||||
return SurvivorPhaseIds.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Surviving phase ids on execute: %s"),
|
||||
*FString::Join(SurvivorPhaseIds, TEXT(", "))
|
||||
)
|
||||
: FString(TEXT("Surviving phase ids on execute: none"));
|
||||
};
|
||||
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface>
|
||||
TemplateRawPhaseEntries;
|
||||
int32 TemplateSurvivorPhaseCount = 0;
|
||||
int32 TemplateDuplicatePrunedPhaseCount = 0;
|
||||
int32 TemplateInvalidRawDefinitionCount = 0;
|
||||
BuildRawPhaseEntries(
|
||||
RawTimingPolicy,
|
||||
PreviewTimingPolicy,
|
||||
TemplateRawPhaseEntries,
|
||||
TemplateSurvivorPhaseCount,
|
||||
TemplateDuplicatePrunedPhaseCount,
|
||||
TemplateInvalidRawDefinitionCount
|
||||
);
|
||||
const int32 TemplateRawSplitPhaseCount = TemplateRawPhaseEntries.Num();
|
||||
const FString TemplateRawSplitPhaseCountLine = BuildRawSplitPhaseCountLine(
|
||||
TemplateRawSplitPhaseCount
|
||||
);
|
||||
const FString TemplateSurvivorCountLine = BuildSurvivorCountLine(
|
||||
TemplateSurvivorPhaseCount
|
||||
);
|
||||
const FString TemplateDuplicatePruningLine = BuildDuplicatePruningLine(
|
||||
TemplateDuplicatePrunedPhaseCount
|
||||
);
|
||||
const FString TemplateInvalidDefinitionLine = BuildInvalidDefinitionLine(
|
||||
TemplateInvalidRawDefinitionCount
|
||||
);
|
||||
const FString TemplateSurvivorPhaseIdLine = BuildSurvivorPhaseIdLine(
|
||||
TemplateRawPhaseEntries
|
||||
);
|
||||
|
||||
for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhasePhaseIdLabelFallbackProvenancePreviewEntrySurface&
|
||||
SplitPhaseEntry : SplitPhaseLabelProvenancePreviewSurface.OptionEntries)
|
||||
{
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewEntrySurface
|
||||
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.RawPhaseEntries = TemplateRawPhaseEntries;
|
||||
Entry.RawSplitPhaseCount = TemplateRawSplitPhaseCount;
|
||||
Entry.SurvivorPhaseCount = TemplateSurvivorPhaseCount;
|
||||
Entry.DuplicatePrunedPhaseCount = TemplateDuplicatePrunedPhaseCount;
|
||||
Entry.InvalidRawDefinitionCount = TemplateInvalidRawDefinitionCount;
|
||||
Entry.bHasDuplicatePrunedPhases = TemplateDuplicatePrunedPhaseCount > 0;
|
||||
Entry.bHasInvalidRawDefinitions = TemplateInvalidRawDefinitionCount > 0;
|
||||
Entry.RawSplitPhaseCountLine = TemplateRawSplitPhaseCountLine;
|
||||
Entry.SurvivorCountLine = TemplateSurvivorCountLine;
|
||||
Entry.DuplicatePruningLine = TemplateDuplicatePruningLine;
|
||||
Entry.InvalidDefinitionLine = TemplateInvalidDefinitionLine;
|
||||
Entry.SurvivorPhaseIdLine = TemplateSurvivorPhaseIdLine;
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase duplicate-pruning provenance source: exact active-deck raw split-phase set normalized and duplicate-pruned for direct covered-case start.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bHasExactSplitPhaseDuplicatePruningPreview = true;
|
||||
Entry.bRetainsActiveDeckSplitPhaseDuplicatePruningProvenance = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.DirectExactOptionCount;
|
||||
if (Entry.bHasDuplicatePrunedPhases)
|
||||
{
|
||||
++Surface.OptionsWithDuplicatePruningCount;
|
||||
}
|
||||
if (Entry.bHasInvalidRawDefinitions)
|
||||
{
|
||||
++Surface.OptionsWithInvalidRawDefinitionsCount;
|
||||
}
|
||||
Surface.RawSplitPhaseDefinitionCount += Entry.RawSplitPhaseCount;
|
||||
Surface.SurvivorPhaseCount += Entry.SurvivorPhaseCount;
|
||||
Surface.DuplicatePrunedPhaseCount += Entry.DuplicatePrunedPhaseCount;
|
||||
Surface.InvalidRawDefinitionCount += Entry.InvalidRawDefinitionCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
StoredRequestReusable:
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
RefreshRequired:
|
||||
Entry.RawPhaseEntries = TemplateRawPhaseEntries;
|
||||
Entry.RawSplitPhaseCount = TemplateRawSplitPhaseCount;
|
||||
Entry.SurvivorPhaseCount = TemplateSurvivorPhaseCount;
|
||||
Entry.DuplicatePrunedPhaseCount = TemplateDuplicatePrunedPhaseCount;
|
||||
Entry.InvalidRawDefinitionCount = TemplateInvalidRawDefinitionCount;
|
||||
Entry.bHasDuplicatePrunedPhases = TemplateDuplicatePrunedPhaseCount > 0;
|
||||
Entry.bHasInvalidRawDefinitions = TemplateInvalidRawDefinitionCount > 0;
|
||||
Entry.RawSplitPhaseCountLine = TemplateRawSplitPhaseCountLine;
|
||||
Entry.SurvivorCountLine = TemplateSurvivorCountLine;
|
||||
Entry.DuplicatePruningLine = TemplateDuplicatePruningLine;
|
||||
Entry.InvalidDefinitionLine = TemplateInvalidDefinitionLine;
|
||||
Entry.SurvivorPhaseIdLine = TemplateSurvivorPhaseIdLine;
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase duplicate-pruning provenance source: exact source-deck raw split-phase set normalized and duplicate-pruned for generated owned execution.");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bHasExactSplitPhaseDuplicatePruningPreview = true;
|
||||
Entry.bRetainsActiveDeckSplitPhaseDuplicatePruningProvenance = true;
|
||||
Entry.bCanPreview = true;
|
||||
++Surface.GeneratedExactOptionCount;
|
||||
if (Entry.bHasDuplicatePrunedPhases)
|
||||
{
|
||||
++Surface.OptionsWithDuplicatePruningCount;
|
||||
}
|
||||
if (Entry.bHasInvalidRawDefinitions)
|
||||
{
|
||||
++Surface.OptionsWithInvalidRawDefinitionsCount;
|
||||
}
|
||||
Surface.RawSplitPhaseDefinitionCount += Entry.RawSplitPhaseCount;
|
||||
Surface.SurvivorPhaseCount += Entry.SurvivorPhaseCount;
|
||||
Surface.DuplicatePrunedPhaseCount += Entry.DuplicatePrunedPhaseCount;
|
||||
Surface.InvalidRawDefinitionCount += Entry.InvalidRawDefinitionCount;
|
||||
break;
|
||||
|
||||
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
|
||||
UnresolvedAfterChoice:
|
||||
Entry.RawSplitPhaseCountLine =
|
||||
TEXT("Raw split-phase definitions before normalize: blocked until every required selector is resolved.");
|
||||
Entry.SurvivorCountLine =
|
||||
TEXT("Surviving normalized split phases on execute: blocked until every required selector is resolved.");
|
||||
Entry.DuplicatePruningLine =
|
||||
TEXT("Duplicate-pruned raw split-phase definitions on execute: blocked until every required selector is resolved.");
|
||||
Entry.InvalidDefinitionLine =
|
||||
TEXT("Invalid raw split-phase definitions skipped on execute: blocked until every required selector is resolved.");
|
||||
Entry.SurvivorPhaseIdLine =
|
||||
TEXT("Surviving phase ids on execute: blocked until every required selector is resolved.");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase duplicate-pruning 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.RawSplitPhaseCountLine =
|
||||
TEXT("Raw split-phase definitions before normalize: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.SurvivorCountLine =
|
||||
TEXT("Surviving normalized split phases on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.DuplicatePruningLine =
|
||||
TEXT("Duplicate-pruned raw split-phase definitions on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.InvalidDefinitionLine =
|
||||
TEXT("Invalid raw split-phase definitions skipped on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.SurvivorPhaseIdLine =
|
||||
TEXT("Surviving phase ids on execute: blocked until a structurally valid launch payload can be derived.");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase duplicate-pruning 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.RawSplitPhaseCountLine =
|
||||
TEXT("Raw split-phase definitions before normalize: unavailable");
|
||||
Entry.SurvivorCountLine =
|
||||
TEXT("Surviving normalized split phases on execute: unavailable");
|
||||
Entry.DuplicatePruningLine =
|
||||
TEXT("Duplicate-pruned raw split-phase definitions on execute: unavailable");
|
||||
Entry.InvalidDefinitionLine =
|
||||
TEXT("Invalid raw split-phase definitions skipped on execute: unavailable");
|
||||
Entry.SurvivorPhaseIdLine =
|
||||
TEXT("Surviving phase ids on execute: unavailable");
|
||||
Entry.SplitPhaseSourceLine =
|
||||
TEXT("Split-phase duplicate-pruning provenance source: unavailable");
|
||||
Entry.PreviewStabilityLine = SplitPhaseEntry.PreviewStabilityLine;
|
||||
Entry.bCanPreview = false;
|
||||
++Surface.UnavailableOptionCount;
|
||||
break;
|
||||
}
|
||||
|
||||
Entry.DetailLine = Entry.SplitPhaseSourceLine.IsEmpty()
|
||||
? Entry.PreviewStabilityLine
|
||||
: FString::Printf(
|
||||
TEXT("%s | %s"),
|
||||
*Entry.PreviewStabilityLine,
|
||||
*Entry.SplitPhaseSourceLine
|
||||
);
|
||||
|
||||
if (Entry.bMatchesCurrentSelection)
|
||||
{
|
||||
Surface.bCurrentSelectionHasExactSplitPhaseDuplicatePruningPreview =
|
||||
Entry.bHasExactSplitPhaseDuplicatePruningPreview;
|
||||
Surface.bCurrentSelectionRetainsActiveDeckSplitPhaseDuplicatePruningProvenance =
|
||||
Entry.bRetainsActiveDeckSplitPhaseDuplicatePruningProvenance;
|
||||
Surface.bCurrentSelectionHasDuplicatePrunedPhases =
|
||||
Entry.bHasDuplicatePrunedPhases;
|
||||
Surface.bCurrentSelectionHasInvalidRawDefinitions =
|
||||
Entry.bHasInvalidRawDefinitions;
|
||||
Surface.CurrentSelectionDuplicatePruningLine = FString::Printf(
|
||||
TEXT("%s | %s | %s | %s | %s"),
|
||||
*Entry.RawSplitPhaseCountLine,
|
||||
*Entry.SurvivorCountLine,
|
||||
*Entry.DuplicatePruningLine,
|
||||
*Entry.InvalidDefinitionLine,
|
||||
*Entry.SurvivorPhaseIdLine
|
||||
);
|
||||
}
|
||||
|
||||
Surface.OptionEntries.Add(MoveTemp(Entry));
|
||||
}
|
||||
|
||||
Surface.bHasOwnedExecutionSplitPhaseDuplicatePruningPreviewOptions =
|
||||
Surface.OptionEntries.Num() > 0;
|
||||
Surface.bHasDirectSplitPhaseDuplicatePruningPreviewOptions =
|
||||
Surface.DirectExactOptionCount > 0;
|
||||
Surface.bHasGeneratedSplitPhaseDuplicatePruningPreviewOptions =
|
||||
Surface.GeneratedExactOptionCount > 0;
|
||||
Surface.bHasBlockedSplitPhaseDuplicatePruningPreviewOptions =
|
||||
Surface.BlockedOptionCount > 0;
|
||||
|
||||
Surface.RawSplitPhaseCountSummaryLine = Surface.OptionEntries.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Split-phase duplicate-pruning: %d raw definitions | %d survivors | %d duplicate-pruned | %d invalid | %d blocked | %d unavailable"),
|
||||
Surface.RawSplitPhaseDefinitionCount,
|
||||
Surface.SurvivorPhaseCount,
|
||||
Surface.DuplicatePrunedPhaseCount,
|
||||
Surface.InvalidRawDefinitionCount,
|
||||
Surface.BlockedOptionCount,
|
||||
Surface.UnavailableOptionCount
|
||||
)
|
||||
: TEXT("Split-phase duplicate-pruning: no imported options");
|
||||
Surface.DuplicatePruningSummaryLine = Surface.OptionEntries.Num() > 0
|
||||
? FString::Printf(
|
||||
TEXT("Survivor provenance detail: %d options with duplicate-pruned rows | %d options with invalid rows"),
|
||||
Surface.OptionsWithDuplicatePruningCount,
|
||||
Surface.OptionsWithInvalidRawDefinitionsCount
|
||||
)
|
||||
: TEXT("Survivor provenance detail: no imported options");
|
||||
|
||||
if (Surface.CurrentSelectionDuplicatePruningLine.IsEmpty())
|
||||
{
|
||||
if (OptionMenuSurface.bHasUnresolvedSelectionDetail)
|
||||
{
|
||||
Surface.CurrentSelectionDuplicatePruningLine =
|
||||
OptionMenuSurface.UnresolvedSelectionLine;
|
||||
}
|
||||
else if (OptionMenuSurface.bHasSelection)
|
||||
{
|
||||
Surface.CurrentSelectionDuplicatePruningLine =
|
||||
TEXT("Current selection has no additional owned-execution split-phase duplicate-pruning preview.");
|
||||
}
|
||||
else if (OptionMenuSurface.bHasSelector)
|
||||
{
|
||||
Surface.CurrentSelectionDuplicatePruningLine =
|
||||
TEXT("Current selection: unresolved");
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface.CurrentSelectionDuplicatePruningLine =
|
||||
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 duplicate-pruning / survivor 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 duplicate-pruning / survivor provenance preview is active, but this selector does not expose imported options.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface.StatusLine = SplitPhaseLabelProvenancePreviewSurface.StatusLine;
|
||||
}
|
||||
|
||||
Surface.DetailLine = SplitPhaseLabelProvenancePreviewSurface.DetailLine;
|
||||
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachQueueControlSurface
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface(
|
||||
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
|
||||
|
|
|
|||
|
|
@ -1100,6 +1100,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
|
||||
OptionLaunchRequestPreviewSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
|
||||
return UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
CachedRunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
|
||||
const int32 MaxCases,
|
||||
const FString& StartActionSourceLabel
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,25 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const
|
||||
{
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
|
||||
OptionLaunchRequestPreviewSurface =
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
|
||||
return UHyperTwistTrainingCoachLibrary::
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
CachedRunState,
|
||||
SelectorId,
|
||||
OptionMenuSurface,
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
|
|
|
|||
|
|
@ -897,4 +897,14 @@ public:
|
|||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FHyperTwistTrainingRunState& RunState,
|
||||
const FString& SelectorId,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
|
||||
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
|
||||
OptionLaunchRequestPreviewSurface
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -368,6 +368,12 @@ public:
|
|||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedRun(
|
||||
int32 MaxCases,
|
||||
|
|
|
|||
|
|
@ -349,6 +349,12 @@ public:
|
|||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(
|
||||
const FString& SelectorId
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
|
|
|
|||
|
|
@ -12565,3 +12565,267 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPha
|
|||
|| bHasOwnedExecutionSplitPhaseLabelProvenancePreviewOptions;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PhaseId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 RawOrder = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 EvaluationOrder = -1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 NormalizedOrder = -1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SurvivorNormalizedLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RawDefinitionLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString EvaluationOrderLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NormalizationOutcomeLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DuplicatePruningProvenanceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSourceLabelWasExplicit = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bStructurallyValid = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSurvivesNormalization = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bDroppedBecauseDuplicate = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bDroppedBecauseInvalid = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCanPreview = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !PhaseId.IsEmpty()
|
||||
|| !RawDefinitionLine.IsEmpty()
|
||||
|| !NormalizationOutcomeLine.IsEmpty()
|
||||
|| !DuplicatePruningProvenanceLine.IsEmpty()
|
||||
|| bCanPreview;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewEntrySurface
|
||||
{
|
||||
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 RawSplitPhaseCountLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SurvivorCountLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DuplicatePruningLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString InvalidDefinitionLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SurvivorPhaseIdLine;
|
||||
|
||||
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<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface>
|
||||
RawPhaseEntries;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 RawSplitPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SurvivorPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DuplicatePrunedPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 InvalidRawDefinitionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bMatchesCurrentSelection = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bStartsOwnedCaseImmediately = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasExactSplitPhaseDuplicatePruningPreview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRetainsActiveDeckSplitPhaseDuplicatePruningProvenance = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDuplicatePrunedPhases = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasInvalidRawDefinitions = 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()
|
||||
|| !RawSplitPhaseCountLine.IsEmpty()
|
||||
|| !SurvivorCountLine.IsEmpty()
|
||||
|| !DuplicatePruningLine.IsEmpty()
|
||||
|| LaunchRequestPreviewKind
|
||||
!= EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None
|
||||
|| bCanPreview;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface
|
||||
{
|
||||
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 RawSplitPhaseCountSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DuplicatePruningSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CurrentSelectionDuplicatePruningLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewEntrySurface>
|
||||
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 RawSplitPhaseDefinitionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SurvivorPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DuplicatePrunedPhaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 InvalidRawDefinitionCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 OptionsWithDuplicatePruningCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 OptionsWithInvalidRawDefinitionsCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelector = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasOwnedExecutionSplitPhaseDuplicatePruningPreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDirectSplitPhaseDuplicatePruningPreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasGeneratedSplitPhaseDuplicatePruningPreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasBlockedSplitPhaseDuplicatePruningPreviewOptions = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasExactSplitPhaseDuplicatePruningPreview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionRetainsActiveDeckSplitPhaseDuplicatePruningProvenance = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasDuplicatePrunedPhases = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCurrentSelectionHasInvalidRawDefinitions = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !SelectorId.IsEmpty()
|
||||
|| OptionEntries.Num() > 0
|
||||
|| bHasSelector
|
||||
|| bHasOwnedExecutionSplitPhaseDuplicatePruningPreviewOptions;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 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 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 duplicate-pruning / survivor provenance preview surface over the already-cached selector/runtime/request state, 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 next bounded packet is to expose one thin generated-mode selector option owned execution split-phase normalization summary surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect raw definitions, survivors, label fallback, and blocked preview posture from one surface instead of merging the existing split-phase normalization previews 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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# HyperTwist Phase 4 gameplay generated-mode selector option owned execution split-phase duplicate-pruning / survivor 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 phase-id / label-fallback provenance preview surface by exposing one parameterized owned execution split-phase duplicate-pruning / survivor provenance preview surface for a chosen selector id.
|
||||
|
||||
The open tasks were:
|
||||
|
||||
- stop forcing gameplay / Blueprint callers to rebuild timing-policy normalization duplicate-pruning rules just to see which raw split-phase definitions survive normalization
|
||||
- expose direct covered-case duplicate-pruning provenance and generated owned-execution duplicate-pruning provenance on the same thin consumer lane
|
||||
- expose per-raw-definition survivor and duplicate-drop 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 duplicate-pruning / survivor provenance preview surfaces in shared training types
|
||||
- add a coach-library helper that reconstructs raw split-phase evaluation order, survivor retention, duplicate pruning, and invalid-row skipping from the raw timing policy using the same sort / dedupe rule as timing normalization
|
||||
- expose that parameterized split-phase duplicate-pruning 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 execution split-phase detail plus explicit-vs-fallback label provenance 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 which raw split-phase definitions were dropped by duplicate rejection and which first-valid definitions actually survived normalization
|
||||
|
||||
That meant:
|
||||
|
||||
- split-phase detail and label-fallback preview were already thin and reusable
|
||||
- but duplicate-pruning / survivor provenance still leaked timing-policy normalization rules into callers
|
||||
|
||||
So the next bounded move was:
|
||||
|
||||
- keep the already-landed split-phase detail and label-fallback provenance surfaces unchanged in behavior
|
||||
- reuse that exact/blocked/unavailable option-state baseline and expose one narrow duplicate-pruning / survivor provenance surface above it
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewRawPhaseEntrySurface`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewEntrySurface`
|
||||
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
|
||||
- added `DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(...)`
|
||||
- split-phase duplicate-pruning preview is derived from cached run state plus the already-landed split-phase label-provenance preview surface and reconstructs raw evaluation/survivor/drop provenance from the raw timing policy
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
|
||||
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(const FString& SelectorId)`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
|
||||
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseDuplicatePruningSurvivorProvenancePreviewSurface(const FString& SelectorId)`
|
||||
|
||||
Consumer result:
|
||||
|
||||
- gameplay / Blueprint callers can now inspect raw split-phase definitions, survivor counts, duplicate-pruned rows, invalid rows, and per-row survivor/drop provenance for a chosen selector option without rebuilding timing-policy normalization behavior
|
||||
|
||||
## Validation
|
||||
|
||||
- full `Development Editor|Win64` solution build for `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln`
|
||||
- result: `0` warnings, `0` errors
|
||||
Loading…
Add table
Reference in a new issue