Expose dashboard deck preview and handoff recommendation surfaces
This commit is contained in:
parent
8467b00225
commit
5ab380abfe
5 changed files with 828 additions and 2 deletions
|
|
@ -9895,6 +9895,496 @@ UHyperTwistCoachDashboardWidget::GetDisplayedGuidancePreferenceInspectSurface()
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedRecommendedGuidanceDeckPreviewInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Recommended guidance");
|
||||
Surface.GuidanceLaneLabel = TEXT("recommended");
|
||||
|
||||
const auto BuildDeckPreviewLine = [](const FHyperTwistTrainingDeck& Deck, const FHyperTwistCoachBrief& Brief, const TCHAR* EmptyPrefix)
|
||||
{
|
||||
if (Deck.IsStructurallyValid())
|
||||
{
|
||||
TArray<FString> PreviewCaseParts;
|
||||
const int32 PreviewCaseCount = FMath::Min(Deck.Cases.Num(), 3);
|
||||
for (int32 CaseIndex = 0; CaseIndex < PreviewCaseCount; ++CaseIndex)
|
||||
{
|
||||
const FHyperTwistTrainingCase& PreviewCase = Deck.Cases[CaseIndex];
|
||||
PreviewCaseParts.Add(
|
||||
PreviewCase.PromptLabel.IsEmpty() ? PreviewCase.CaseId : PreviewCase.PromptLabel
|
||||
);
|
||||
}
|
||||
const FString PreviewCases = PreviewCaseParts.Num() > 0
|
||||
? FString::Join(PreviewCaseParts, TEXT(" | "))
|
||||
: TEXT("none");
|
||||
return FString::Printf(
|
||||
TEXT("Deck preview: %s | Deck: %s | Cases: %d | Selection: %s | Difficulty: %s | Subset: %s | Preview: %s"),
|
||||
Deck.Title.IsEmpty() ? TEXT("n/a") : *Deck.Title,
|
||||
Deck.DeckId.IsEmpty() ? TEXT("n/a") : *Deck.DeckId,
|
||||
Deck.Cases.Num(),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(Deck.SelectionPolicy),
|
||||
Deck.DifficultyBand.IsEmpty() ? TEXT("n/a") : *Deck.DifficultyBand,
|
||||
Deck.SubsetId.IsEmpty() ? TEXT("n/a") : *Deck.SubsetId,
|
||||
*PreviewCases);
|
||||
}
|
||||
|
||||
if (!Brief.UserId.IsEmpty() && !Brief.Headline.IsEmpty())
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("%s: %s | Deck: %s | Method: %s | Focus cases: %d | Action: %s"),
|
||||
EmptyPrefix,
|
||||
*Brief.Headline,
|
||||
Brief.FocusDeckId.IsEmpty() ? TEXT("n/a") : *Brief.FocusDeckId,
|
||||
Brief.FocusMethodSegmentId.IsEmpty() ? TEXT("n/a") : *Brief.FocusMethodSegmentId,
|
||||
Brief.FocusCaseIds.Num(),
|
||||
Brief.PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *Brief.PrimaryActionLabel);
|
||||
}
|
||||
|
||||
return FString::Printf(TEXT("%s: no guidance available"), EmptyPrefix);
|
||||
};
|
||||
|
||||
const bool bGuidanceReadyToLaunch = CachedCoachPanelState.bCanStartCoachRecommendedRun;
|
||||
const FHyperTwistTrainingDeck DisplayedDeck =
|
||||
bGuidanceReadyToLaunch ? CachedCoachRecommendedDeck : FHyperTwistTrainingDeck();
|
||||
const FHyperTwistCoachBrief DisplayedBrief =
|
||||
bGuidanceReadyToLaunch ? CachedCoachBrief : FHyperTwistCoachBrief();
|
||||
|
||||
Surface.bGuidanceReadyToLaunch = bGuidanceReadyToLaunch;
|
||||
Surface.bHasDeck = DisplayedDeck.IsStructurallyValid();
|
||||
Surface.bHasBrief = !DisplayedBrief.UserId.IsEmpty() && !DisplayedBrief.Headline.IsEmpty();
|
||||
Surface.bUsesBriefFallback = !Surface.bHasDeck && Surface.bHasBrief;
|
||||
Surface.bActivePreviewLane =
|
||||
ActiveGuidancePreviewLane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended;
|
||||
Surface.DeckId = DisplayedDeck.DeckId.IsEmpty() ? TEXT("n/a") : DisplayedDeck.DeckId;
|
||||
Surface.DeckTitle = DisplayedDeck.Title.IsEmpty() ? TEXT("n/a") : DisplayedDeck.Title;
|
||||
Surface.DeckLabel =
|
||||
DisplayedDeck.IsStructurallyValid()
|
||||
? (DisplayedDeck.Title.IsEmpty() ? Surface.DeckId : DisplayedDeck.Title)
|
||||
: TEXT("n/a");
|
||||
Surface.BriefHeadline =
|
||||
DisplayedBrief.Headline.IsEmpty() ? TEXT("n/a") : DisplayedBrief.Headline;
|
||||
Surface.PrimaryActionLabel =
|
||||
DisplayedBrief.PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : DisplayedBrief.PrimaryActionLabel;
|
||||
Surface.FocusDeckId =
|
||||
DisplayedBrief.FocusDeckId.IsEmpty() ? TEXT("n/a") : DisplayedBrief.FocusDeckId;
|
||||
Surface.FocusMethodSegmentId =
|
||||
DisplayedBrief.FocusMethodSegmentId.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: DisplayedBrief.FocusMethodSegmentId;
|
||||
Surface.SelectionPolicyLabel =
|
||||
DisplayedDeck.IsStructurallyValid()
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
DisplayedDeck.SelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedModeLabel =
|
||||
Surface.bHasBrief
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedBrief.SuggestedMode)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedSelectionLabel =
|
||||
Surface.bHasBrief
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
DisplayedBrief.SuggestedSelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.DifficultyBand =
|
||||
DisplayedDeck.DifficultyBand.IsEmpty() ? TEXT("n/a") : DisplayedDeck.DifficultyBand;
|
||||
Surface.SubsetId = DisplayedDeck.SubsetId.IsEmpty() ? TEXT("n/a") : DisplayedDeck.SubsetId;
|
||||
Surface.CaseCount = DisplayedDeck.Cases.Num();
|
||||
Surface.FocusCaseCount = DisplayedBrief.FocusCaseIds.Num();
|
||||
|
||||
TArray<FString> PreviewCaseParts;
|
||||
const int32 PreviewCaseCount = FMath::Min(DisplayedDeck.Cases.Num(), 3);
|
||||
for (int32 CaseIndex = 0; CaseIndex < PreviewCaseCount; ++CaseIndex)
|
||||
{
|
||||
const FHyperTwistTrainingCase& PreviewCase = DisplayedDeck.Cases[CaseIndex];
|
||||
PreviewCaseParts.Add(PreviewCase.PromptLabel.IsEmpty() ? PreviewCase.CaseId : PreviewCase.PromptLabel);
|
||||
}
|
||||
Surface.PreviewCaseSummaryLine =
|
||||
PreviewCaseParts.Num() > 0 ? FString::Join(PreviewCaseParts, TEXT(" | ")) : TEXT("none");
|
||||
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
Surface.bClosedLoopIdleDashboard =
|
||||
IsCoachLoopActionabilityClosed()
|
||||
&& (
|
||||
bQueueRecoveryMemorySource
|
||||
|| !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
|| DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None);
|
||||
|
||||
Surface.StatusLine = !DisplayedRecommendedDeckPreviewLine.IsEmpty()
|
||||
? DisplayedRecommendedDeckPreviewLine
|
||||
: BuildDeckPreviewLine(DisplayedDeck, DisplayedBrief, TEXT("Recommended guidance"));
|
||||
Surface.DetailLine = Surface.bHasDeck
|
||||
? FString::Printf(
|
||||
TEXT("Recommended preview detail: deck %s | selection %s | mode %s | difficulty %s | subset %s | focus deck %s | method %s | focus cases %d | preview %s"),
|
||||
*Surface.DeckLabel,
|
||||
*Surface.SelectionPolicyLabel,
|
||||
*Surface.SuggestedModeLabel,
|
||||
*Surface.DifficultyBand,
|
||||
*Surface.SubsetId,
|
||||
*Surface.FocusDeckId,
|
||||
*Surface.FocusMethodSegmentId,
|
||||
Surface.FocusCaseCount,
|
||||
*Surface.PreviewCaseSummaryLine)
|
||||
: (Surface.bHasBrief
|
||||
? FString::Printf(
|
||||
TEXT("Recommended preview detail: %s | action %s | focus deck %s | method %s | focus cases %d"),
|
||||
*Surface.BriefHeadline,
|
||||
*Surface.PrimaryActionLabel,
|
||||
*Surface.FocusDeckId,
|
||||
*Surface.FocusMethodSegmentId,
|
||||
Surface.FocusCaseCount)
|
||||
: TEXT("Recommended preview detail: no recommended guidance is currently available."));
|
||||
if (Surface.bClosedLoopIdleDashboard)
|
||||
{
|
||||
Surface.StatusLine =
|
||||
TEXT("Recommended guidance: no active recommended guidance; the coach-to-review loop is closed and idle.");
|
||||
Surface.DetailLine =
|
||||
TEXT("Recommended preview detail: retained coach memory remains inspectable, but no live recommended preview deck remains active.");
|
||||
}
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedFollowUpGuidanceDeckPreviewInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Follow-up guidance");
|
||||
Surface.GuidanceLaneLabel = TEXT("follow-up");
|
||||
|
||||
const auto BuildDeckPreviewLine = [](const FHyperTwistTrainingDeck& Deck, const FHyperTwistCoachBrief& Brief, const TCHAR* EmptyPrefix)
|
||||
{
|
||||
if (Deck.IsStructurallyValid())
|
||||
{
|
||||
TArray<FString> PreviewCaseParts;
|
||||
const int32 PreviewCaseCount = FMath::Min(Deck.Cases.Num(), 3);
|
||||
for (int32 CaseIndex = 0; CaseIndex < PreviewCaseCount; ++CaseIndex)
|
||||
{
|
||||
const FHyperTwistTrainingCase& PreviewCase = Deck.Cases[CaseIndex];
|
||||
PreviewCaseParts.Add(
|
||||
PreviewCase.PromptLabel.IsEmpty() ? PreviewCase.CaseId : PreviewCase.PromptLabel
|
||||
);
|
||||
}
|
||||
const FString PreviewCases = PreviewCaseParts.Num() > 0
|
||||
? FString::Join(PreviewCaseParts, TEXT(" | "))
|
||||
: TEXT("none");
|
||||
return FString::Printf(
|
||||
TEXT("Deck preview: %s | Deck: %s | Cases: %d | Selection: %s | Difficulty: %s | Subset: %s | Preview: %s"),
|
||||
Deck.Title.IsEmpty() ? TEXT("n/a") : *Deck.Title,
|
||||
Deck.DeckId.IsEmpty() ? TEXT("n/a") : *Deck.DeckId,
|
||||
Deck.Cases.Num(),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(Deck.SelectionPolicy),
|
||||
Deck.DifficultyBand.IsEmpty() ? TEXT("n/a") : *Deck.DifficultyBand,
|
||||
Deck.SubsetId.IsEmpty() ? TEXT("n/a") : *Deck.SubsetId,
|
||||
*PreviewCases);
|
||||
}
|
||||
|
||||
if (!Brief.UserId.IsEmpty() && !Brief.Headline.IsEmpty())
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("%s: %s | Deck: %s | Method: %s | Focus cases: %d | Action: %s"),
|
||||
EmptyPrefix,
|
||||
*Brief.Headline,
|
||||
Brief.FocusDeckId.IsEmpty() ? TEXT("n/a") : *Brief.FocusDeckId,
|
||||
Brief.FocusMethodSegmentId.IsEmpty() ? TEXT("n/a") : *Brief.FocusMethodSegmentId,
|
||||
Brief.FocusCaseIds.Num(),
|
||||
Brief.PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *Brief.PrimaryActionLabel);
|
||||
}
|
||||
|
||||
return FString::Printf(TEXT("%s: no guidance available"), EmptyPrefix);
|
||||
};
|
||||
|
||||
const bool bGuidanceReadyToLaunch =
|
||||
CachedCoachPanelState.bCanStartCoachFollowUpRun
|
||||
&& CachedCoachPanelState.bHasFollowUpGuidance;
|
||||
const FHyperTwistTrainingDeck DisplayedDeck =
|
||||
bGuidanceReadyToLaunch ? CachedCoachFollowUpDeck : FHyperTwistTrainingDeck();
|
||||
const FHyperTwistCoachBrief DisplayedBrief =
|
||||
bGuidanceReadyToLaunch ? CachedCoachFollowUpBrief : FHyperTwistCoachBrief();
|
||||
|
||||
Surface.bGuidanceReadyToLaunch = bGuidanceReadyToLaunch;
|
||||
Surface.bHasDeck = DisplayedDeck.IsStructurallyValid();
|
||||
Surface.bHasBrief = !DisplayedBrief.UserId.IsEmpty() && !DisplayedBrief.Headline.IsEmpty();
|
||||
Surface.bUsesBriefFallback = !Surface.bHasDeck && Surface.bHasBrief;
|
||||
Surface.bActivePreviewLane =
|
||||
ActiveGuidancePreviewLane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp;
|
||||
Surface.DeckId = DisplayedDeck.DeckId.IsEmpty() ? TEXT("n/a") : DisplayedDeck.DeckId;
|
||||
Surface.DeckTitle = DisplayedDeck.Title.IsEmpty() ? TEXT("n/a") : DisplayedDeck.Title;
|
||||
Surface.DeckLabel =
|
||||
DisplayedDeck.IsStructurallyValid()
|
||||
? (DisplayedDeck.Title.IsEmpty() ? Surface.DeckId : DisplayedDeck.Title)
|
||||
: TEXT("n/a");
|
||||
Surface.BriefHeadline =
|
||||
DisplayedBrief.Headline.IsEmpty() ? TEXT("n/a") : DisplayedBrief.Headline;
|
||||
Surface.PrimaryActionLabel =
|
||||
DisplayedBrief.PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : DisplayedBrief.PrimaryActionLabel;
|
||||
Surface.FocusDeckId =
|
||||
DisplayedBrief.FocusDeckId.IsEmpty() ? TEXT("n/a") : DisplayedBrief.FocusDeckId;
|
||||
Surface.FocusMethodSegmentId =
|
||||
DisplayedBrief.FocusMethodSegmentId.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: DisplayedBrief.FocusMethodSegmentId;
|
||||
Surface.SelectionPolicyLabel =
|
||||
DisplayedDeck.IsStructurallyValid()
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
DisplayedDeck.SelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedModeLabel =
|
||||
Surface.bHasBrief
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedBrief.SuggestedMode)
|
||||
: TEXT("n/a");
|
||||
Surface.SuggestedSelectionLabel =
|
||||
Surface.bHasBrief
|
||||
? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
DisplayedBrief.SuggestedSelectionPolicy)
|
||||
: TEXT("n/a");
|
||||
Surface.DifficultyBand =
|
||||
DisplayedDeck.DifficultyBand.IsEmpty() ? TEXT("n/a") : DisplayedDeck.DifficultyBand;
|
||||
Surface.SubsetId = DisplayedDeck.SubsetId.IsEmpty() ? TEXT("n/a") : DisplayedDeck.SubsetId;
|
||||
Surface.CaseCount = DisplayedDeck.Cases.Num();
|
||||
Surface.FocusCaseCount = DisplayedBrief.FocusCaseIds.Num();
|
||||
|
||||
TArray<FString> PreviewCaseParts;
|
||||
const int32 PreviewCaseCount = FMath::Min(DisplayedDeck.Cases.Num(), 3);
|
||||
for (int32 CaseIndex = 0; CaseIndex < PreviewCaseCount; ++CaseIndex)
|
||||
{
|
||||
const FHyperTwistTrainingCase& PreviewCase = DisplayedDeck.Cases[CaseIndex];
|
||||
PreviewCaseParts.Add(PreviewCase.PromptLabel.IsEmpty() ? PreviewCase.CaseId : PreviewCase.PromptLabel);
|
||||
}
|
||||
Surface.PreviewCaseSummaryLine =
|
||||
PreviewCaseParts.Num() > 0 ? FString::Join(PreviewCaseParts, TEXT(" | ")) : TEXT("none");
|
||||
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
Surface.bClosedLoopIdleDashboard =
|
||||
IsCoachLoopActionabilityClosed()
|
||||
&& (
|
||||
bQueueRecoveryMemorySource
|
||||
|| !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
|| DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None);
|
||||
|
||||
Surface.StatusLine = !DisplayedFollowUpDeckPreviewLine.IsEmpty()
|
||||
? DisplayedFollowUpDeckPreviewLine
|
||||
: BuildDeckPreviewLine(DisplayedDeck, DisplayedBrief, TEXT("Follow-up guidance"));
|
||||
Surface.DetailLine = Surface.bHasDeck
|
||||
? FString::Printf(
|
||||
TEXT("Follow-up preview detail: deck %s | selection %s | mode %s | difficulty %s | subset %s | focus deck %s | method %s | focus cases %d | preview %s"),
|
||||
*Surface.DeckLabel,
|
||||
*Surface.SelectionPolicyLabel,
|
||||
*Surface.SuggestedModeLabel,
|
||||
*Surface.DifficultyBand,
|
||||
*Surface.SubsetId,
|
||||
*Surface.FocusDeckId,
|
||||
*Surface.FocusMethodSegmentId,
|
||||
Surface.FocusCaseCount,
|
||||
*Surface.PreviewCaseSummaryLine)
|
||||
: (Surface.bHasBrief
|
||||
? FString::Printf(
|
||||
TEXT("Follow-up preview detail: %s | action %s | focus deck %s | method %s | focus cases %d"),
|
||||
*Surface.BriefHeadline,
|
||||
*Surface.PrimaryActionLabel,
|
||||
*Surface.FocusDeckId,
|
||||
*Surface.FocusMethodSegmentId,
|
||||
Surface.FocusCaseCount)
|
||||
: TEXT("Follow-up preview detail: no follow-up guidance is currently available."));
|
||||
if (Surface.bClosedLoopIdleDashboard)
|
||||
{
|
||||
Surface.StatusLine =
|
||||
TEXT("Follow-up guidance: no active follow-up guidance; the coach-to-review loop is closed and idle.");
|
||||
Surface.DetailLine =
|
||||
TEXT("Follow-up preview detail: retained coach memory remains inspectable, but no live follow-up preview deck remains active.");
|
||||
}
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedCoachHandoffRecommendationInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Handoff recommendation");
|
||||
|
||||
const HyperTwistCoachDashboardWidgetInternal::FHandoffHistoryDashboardBias HandoffHistoryBias =
|
||||
HyperTwistCoachDashboardWidgetInternal::DeriveHandoffHistoryDashboardBias(
|
||||
HandoffHistoryEntries);
|
||||
const HyperTwistCoachDashboardWidgetInternal::FMethodDrillRecoveryPacketDashboardBias
|
||||
MethodDrillRecoveryPacketHandoffBias =
|
||||
HyperTwistCoachDashboardWidgetInternal::DeriveMethodDrillRecoveryPacketDashboardBias(
|
||||
MethodDrillRecoveryMemoryHistoryEntries);
|
||||
const HyperTwistCoachDashboardWidgetInternal::FMethodDrillRecoveryPlanComparisonSummary
|
||||
MethodDrillRecoveryPlanComparisonSummary =
|
||||
HyperTwistCoachDashboardWidgetInternal::DeriveMethodDrillRecoveryPlanComparisonSummary(
|
||||
MethodDrillRecoveryMemoryHistoryEntries);
|
||||
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
|
||||
RetainedMethodDrillRecoveryMemoryHandoffBias =
|
||||
HyperTwistCoachDashboardWidgetInternal::DeriveRetainedMethodDrillRecoveryMemoryBias(
|
||||
MethodDrillRecoveryMemoryHistoryEntries,
|
||||
false);
|
||||
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
|
||||
CurrentMethodDrillRecoveryMemoryBias =
|
||||
HyperTwistCoachDashboardWidgetInternal::ResolveMethodDrillRecoveryMemoryBias(
|
||||
CachedCoachPanelState.MethodDrillRecoveryHistoryCount,
|
||||
CachedCoachPanelState.StrongMethodDrillRecoveryHistoryCount,
|
||||
CachedCoachPanelState.WeakMethodDrillRecoveryHistoryCount,
|
||||
CachedCoachPanelState.MethodDrillRecoveryAverageOutcomeScore);
|
||||
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
|
||||
EffectiveMethodDrillRecoveryMemoryHandoffBias =
|
||||
RetainedMethodDrillRecoveryMemoryHandoffBias
|
||||
!= HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::None
|
||||
? RetainedMethodDrillRecoveryMemoryHandoffBias
|
||||
: CurrentMethodDrillRecoveryMemoryBias;
|
||||
const bool bHasActiveRun = CachedRunState.Session.IsStructurallyValid()
|
||||
&& CachedRunState.ActiveDeck.IsStructurallyValid();
|
||||
const auto DescribeDisplayedHandoffKind = [](const EHyperTwistTrainingCoachHandoffKind Kind) -> FString
|
||||
{
|
||||
switch (Kind)
|
||||
{
|
||||
case EHyperTwistTrainingCoachHandoffKind::Queue:
|
||||
return TEXT("queue");
|
||||
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
|
||||
return TEXT("follow-up");
|
||||
case EHyperTwistTrainingCoachHandoffKind::Recommended:
|
||||
return TEXT("recommended");
|
||||
default:
|
||||
return TEXT("none");
|
||||
}
|
||||
};
|
||||
|
||||
Surface.bQueueReady = CachedCoachPanelState.bCanStartQueuedRun;
|
||||
Surface.bFollowUpReady =
|
||||
CachedCoachPanelState.bCanStartCoachFollowUpRun
|
||||
&& CachedCoachPanelState.bHasFollowUpGuidance;
|
||||
Surface.bRecommendedReady = CachedCoachPanelState.bCanStartCoachRecommendedRun;
|
||||
Surface.bCanUseCoachHandoff = !bHasLiveAttemptTimer && !bHasActiveRun;
|
||||
Surface.bHasDeferredFirstSuppressionSignal =
|
||||
HyperTwistCoachDashboardWidgetInternal::FindCoachSignalById(
|
||||
CachedCoachSignals,
|
||||
TEXT("queue_suppression_deferred_first_continuation"))
|
||||
!= nullptr;
|
||||
Surface.RecommendationKindLabel =
|
||||
DescribeDisplayedHandoffKind(DisplayedCoachHandoffRecommendationKind);
|
||||
Surface.PreferredHandoffHistoryKindLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeHandoffRecommendationKind(
|
||||
HandoffHistoryBias.PreferredKind);
|
||||
Surface.QueueSourceLabel =
|
||||
CachedCoachPanelState.NextQueueSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachPanelState.NextQueueSourceLabel;
|
||||
Surface.PreferredGuidanceLaneLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeGuidanceLane(
|
||||
CachedCoachPanelState.PreferredGuidanceLane);
|
||||
Surface.PreferredGuidanceSourceLabel =
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachPanelState.PreferredGuidanceSourceLabel;
|
||||
Surface.PreferredGuidanceSourceDescription =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
Surface.LaunchBiasLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetBias);
|
||||
Surface.LaunchBiasSourceLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetSourceLabel);
|
||||
Surface.MethodDrillRecoveryPostureLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeMethodDrillRecoveryMemoryBias(
|
||||
EffectiveMethodDrillRecoveryMemoryHandoffBias);
|
||||
Surface.MethodDrillRecoveryPacketPreferredKindLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeHandoffRecommendationKind(
|
||||
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind);
|
||||
Surface.MethodDrillRecoveryPlanPreferenceLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeMethodDrillRecoveryPlanComparisonPreference(
|
||||
MethodDrillRecoveryPlanComparisonSummary);
|
||||
Surface.StartActionSourceLabel =
|
||||
DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None
|
||||
? ResolveDashboardHandoffStartActionSourceLabel(
|
||||
DisplayedCoachHandoffRecommendationKind)
|
||||
: TEXT("n/a");
|
||||
Surface.AcceptedQueuedHandoffCount = HandoffHistoryBias.QueueAcceptedDeltaCount;
|
||||
Surface.AcceptedFollowUpHandoffCount = HandoffHistoryBias.FollowUpAcceptedDeltaCount;
|
||||
Surface.AcceptedRecommendedHandoffCount = HandoffHistoryBias.RecommendedAcceptedDeltaCount;
|
||||
Surface.QueueRecommendationCount = HandoffHistoryBias.QueueRecommendationCount;
|
||||
Surface.FollowUpRecommendationCount = HandoffHistoryBias.FollowUpRecommendationCount;
|
||||
Surface.RecommendedRecommendationCount = HandoffHistoryBias.RecommendedRecommendationCount;
|
||||
Surface.StrongMethodDrillRecoveryHistoryCount =
|
||||
CachedCoachPanelState.StrongMethodDrillRecoveryHistoryCount;
|
||||
Surface.WeakMethodDrillRecoveryHistoryCount =
|
||||
CachedCoachPanelState.WeakMethodDrillRecoveryHistoryCount;
|
||||
Surface.MethodDrillRecoveryHistoryCount =
|
||||
CachedCoachPanelState.MethodDrillRecoveryHistoryCount;
|
||||
Surface.PacketQueueHistoryCount = MethodDrillRecoveryPacketHandoffBias.QueueEntryHistoryCount;
|
||||
Surface.PacketFollowUpHistoryCount =
|
||||
MethodDrillRecoveryPacketHandoffBias.FollowUpPacketHistoryCount;
|
||||
Surface.PacketRecommendedHistoryCount =
|
||||
MethodDrillRecoveryPacketHandoffBias.RecommendedBriefHistoryCount;
|
||||
Surface.bHasRecommendation =
|
||||
DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None;
|
||||
Surface.bUsedDeferredFirstSuppressionSignal =
|
||||
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal;
|
||||
Surface.bUsedMethodDrillWeighting =
|
||||
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting;
|
||||
Surface.bUsedAlignedTightPacketAcceptedHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedAlignedTightPacketAcceptedHistory;
|
||||
Surface.bUsedAlignedBroadPacketAcceptedHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedAlignedBroadPacketAcceptedHistory;
|
||||
Surface.bUsedAcceptedAlignedTightPacketOutcomeTrust =
|
||||
bDisplayedCoachHandoffRecommendationUsedAcceptedAlignedTightPacketOutcomeTrust;
|
||||
Surface.bUsedAcceptedAlignedBroadPacketOutcomeTrust =
|
||||
bDisplayedCoachHandoffRecommendationUsedAcceptedAlignedBroadPacketOutcomeTrust;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketOutcomeTrust =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketOutcomeTrust;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketOutcomeTrust =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketOutcomeTrust;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketOutcomeHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketOutcomeHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketOutcomeHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketOutcomeHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketExactHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketExactHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketExactHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketExactHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketExactOutcomeHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketExactOutcomeHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketExactOutcomeHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketExactOutcomeHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketExactOutcomeAcceptedHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketExactOutcomeAcceptedHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketExactOutcomeAcceptedHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketExactOutcomeAcceptedHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedTightPacketExactOutcomeReliableHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketExactOutcomeReliableHistory;
|
||||
Surface.bUsedReliableAcceptedAlignedBroadPacketExactOutcomeReliableHistory =
|
||||
bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketExactOutcomeReliableHistory;
|
||||
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
Surface.bClosedLoopIdleDashboard =
|
||||
IsCoachLoopActionabilityClosed()
|
||||
&& (
|
||||
bQueueRecoveryMemorySource
|
||||
|| !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
|| DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None);
|
||||
|
||||
Surface.StatusLine = !DisplayedCoachHandoffRecommendationStatusLine.IsEmpty()
|
||||
? DisplayedCoachHandoffRecommendationStatusLine
|
||||
: TEXT("Recommendation: no coach-directed handoff is currently ready.");
|
||||
Surface.DetailLine = !DisplayedCoachHandoffRecommendationDetailLine.IsEmpty()
|
||||
? DisplayedCoachHandoffRecommendationDetailLine
|
||||
: TEXT("Handoff recommendation detail: closure-history pressure is retained, but no displayed handoff recommendation is currently active.");
|
||||
if (Surface.bClosedLoopIdleDashboard)
|
||||
{
|
||||
Surface.StatusLine = !DisplayedCoachHandoffRecommendationStatusLine.IsEmpty()
|
||||
? DisplayedCoachHandoffRecommendationStatusLine
|
||||
: TEXT("Handoff recommendation: none; the coach-to-review loop is idle.");
|
||||
Surface.DetailLine = !DisplayedCoachHandoffRecommendationDetailLine.IsEmpty()
|
||||
? DisplayedCoachHandoffRecommendationDetailLine
|
||||
: TEXT("Handoff detail: retained closure history remains inspectable, but no queued, follow-up, or recommended continuation is active.");
|
||||
}
|
||||
return Surface;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::SelectPreviousMethodDrillFollowUpHistoryEntry()
|
||||
{
|
||||
if (MethodDrillFollowUpHistoryEntries.Num() <= 0)
|
||||
|
|
@ -20239,6 +20729,10 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
CoachHandoffRecommendationDetailLine =
|
||||
TEXT("Handoff detail: retained closure history remains inspectable, but no queued, follow-up, or recommended continuation is active.");
|
||||
}
|
||||
DisplayedRecommendedDeckPreviewLine = RecommendedDeckPreviewLine;
|
||||
DisplayedFollowUpDeckPreviewLine = FollowUpDeckPreviewLine;
|
||||
DisplayedCoachHandoffRecommendationStatusLine = CoachHandoffRecommendationStatusLine;
|
||||
DisplayedCoachHandoffRecommendationDetailLine = CoachHandoffRecommendationDetailLine;
|
||||
RecordCoachHandoffHistorySnapshot(
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeHandoffRecommendationKind(
|
||||
HandoffRecommendationKind),
|
||||
|
|
|
|||
|
|
@ -791,6 +791,18 @@ public:
|
|||
FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface
|
||||
GetDisplayedGuidancePreferenceInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface
|
||||
GetDisplayedRecommendedGuidanceDeckPreviewInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface
|
||||
GetDisplayedFollowUpGuidanceDeckPreviewInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface
|
||||
GetDisplayedCoachHandoffRecommendationInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool SelectPreviousMethodDrillFollowUpHistoryEntry();
|
||||
|
||||
|
|
@ -1828,6 +1840,10 @@ private:
|
|||
bool bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedTightPacketExactOutcomeReliableHistory = false;
|
||||
bool bDisplayedCoachHandoffRecommendationUsedReliableAcceptedAlignedBroadPacketExactOutcomeReliableHistory = false;
|
||||
FString DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel;
|
||||
FString DisplayedCoachHandoffRecommendationStatusLine;
|
||||
FString DisplayedCoachHandoffRecommendationDetailLine;
|
||||
FString DisplayedRecommendedDeckPreviewLine;
|
||||
FString DisplayedFollowUpDeckPreviewLine;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE;
|
||||
|
|
|
|||
|
|
@ -10559,6 +10559,268 @@ struct FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString GuidanceLaneLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeckTitle;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DeckLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString BriefHeadline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PrimaryActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusDeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusMethodSegmentId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectionPolicyLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedModeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedSelectionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DifficultyBand;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SubsetId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreviewCaseSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 CaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FocusCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bGuidanceReadyToLaunch = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDeck = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasBrief = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsesBriefFallback = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bActivePreviewLane = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bClosedLoopIdleDashboard = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasDeck
|
||||
|| bHasBrief
|
||||
|| bGuidanceReadyToLaunch;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RecommendationKindLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredHandoffHistoryKindLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString QueueSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredGuidanceLaneLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredGuidanceSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredGuidanceSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LaunchBiasLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LaunchBiasSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString MethodDrillRecoveryPostureLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString MethodDrillRecoveryPacketPreferredKindLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString MethodDrillRecoveryPlanPreferenceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StartActionSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 AcceptedQueuedHandoffCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 AcceptedFollowUpHandoffCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 AcceptedRecommendedHandoffCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 QueueRecommendationCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FollowUpRecommendationCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 RecommendedRecommendationCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 StrongMethodDrillRecoveryHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 WeakMethodDrillRecoveryHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 MethodDrillRecoveryHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PacketQueueHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PacketFollowUpHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PacketRecommendedHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasRecommendation = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bCanUseCoachHandoff = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bQueueReady = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bFollowUpReady = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRecommendedReady = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasDeferredFirstSuppressionSignal = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bClosedLoopIdleDashboard = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedDeferredFirstSuppressionSignal = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedMethodDrillWeighting = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedAlignedTightPacketAcceptedHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedAlignedBroadPacketAcceptedHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedAcceptedAlignedTightPacketOutcomeTrust = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedAcceptedAlignedBroadPacketOutcomeTrust = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketOutcomeTrust = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketOutcomeTrust = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketOutcomeHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketOutcomeHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketExactHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketExactHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketExactOutcomeHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketExactOutcomeHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketExactOutcomeAcceptedHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketExactOutcomeAcceptedHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedTightPacketExactOutcomeReliableHistory = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bUsedReliableAcceptedAlignedBroadPacketExactOutcomeReliableHistory = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasRecommendation
|
||||
|| bQueueReady
|
||||
|| bFollowUpReady
|
||||
|| bRecommendedReady;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachGeneratedModeLaunchExecutionContextSurface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ Current correction call from the source-exposed audit and current execution refr
|
|||
- 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 now-complete deliberate `UHyperTwistTrainingRuntimeLibrary` world-context consumer lane reaches through active generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup, normalized-order lookup, and evaluation-order lookup inspect surfaces, so gameplay/Blueprint callers can inspect one retained merged-roster row directly by phase id, normalized order, or evaluation order without scanning the merged roster array or re-running inspect derivation details directly
|
||||
- the latest landed bounded `Phase 4` packet stays on that same live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds displayed guidance preview selection, displayed preview-case detail, displayed guidance rationale, and displayed guidance-preference inspect surfaces over already-derived preview brief/deck state and cached coach preference state, so gameplay/Blueprint callers can inspect the surfaced preview target, case detail, rationale signal posture, and lane-preference bias without scraping dashboard text blocks or reopening preview/preference derivation
|
||||
- the next clean move is to stay on that same live dashboard guidance-consumer lane and land the displayed recommended guidance deck preview, displayed follow-up guidance deck preview, and live coach handoff recommendation inspect surface group rather than drifting back into backend continuity or reopening the already-complete retained-history seam
|
||||
- the latest landed bounded `Phase 4` packet stays on that same live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds displayed recommended guidance deck preview, displayed follow-up guidance deck preview, and displayed coach handoff recommendation inspect surfaces over already-cached deck/brief state and the live retained handoff recommendation posture, so gameplay/Blueprint callers can inspect the surfaced deck previews and current handoff recommendation without scraping dashboard text blocks or reopening preview/handoff derivation
|
||||
- the next clean move is to stay on that same live dashboard guidance-consumer lane and land the displayed coach handoff status, displayed transition status, and displayed continuation / queued / follow-up / recommended run action-label inspect surface group rather than drifting back into backend continuity or reopening the already-complete retained-history seam
|
||||
- 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,54 @@
|
|||
# HyperTwist Phase 4 dashboard live guidance deck preview and handoff recommendation inspect surface packet
|
||||
|
||||
- bounded Phase `4` dashboard-consumer slice
|
||||
- date: `2026-05-09`
|
||||
|
||||
## Intent
|
||||
|
||||
Stay on the deliberate live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and expose the remaining surfaced recommended/follow-up deck preview state and live coach handoff recommendation state directly to gameplay and Blueprint callers.
|
||||
|
||||
## Why this packet exists
|
||||
|
||||
The dashboard already derived:
|
||||
|
||||
- the displayed recommended guidance deck preview line
|
||||
- the displayed follow-up guidance deck preview line
|
||||
- the current coach handoff recommendation line and retained recommendation detail posture
|
||||
|
||||
But that live state still only surfaced through dashboard text blocks. Callers still had to scrape widget presentation or reopen deck-preview / handoff derivation to inspect what the dashboard was currently showing.
|
||||
|
||||
## What changed
|
||||
|
||||
- added `FHyperTwistTrainingCoachDashboardGuidanceDeckPreviewInspectSurface`
|
||||
- added `FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface`
|
||||
- added `GetDisplayedRecommendedGuidanceDeckPreviewInspectSurface()`
|
||||
- added `GetDisplayedFollowUpGuidanceDeckPreviewInspectSurface()`
|
||||
- added `GetDisplayedCoachHandoffRecommendationInspectSurface()`
|
||||
- retained the exact displayed preview / recommendation lines inside the widget so the new inspect surfaces report the same live strings the dashboard is already presenting
|
||||
- kept the packet bounded to `UHyperTwistCoachDashboardWidget` plus shared surface types, with no dashboard redesign and no backend continuity changes
|
||||
|
||||
## Files
|
||||
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistTrainingTypes.h`
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistCoachDashboardWidget.h`
|
||||
- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Private\HyperTwistTraining\HyperTwistCoachDashboardWidget.cpp`
|
||||
- `C:\HyperTwist\docs\HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md`
|
||||
|
||||
## Outcome
|
||||
|
||||
Gameplay and Blueprint callers can now inspect:
|
||||
|
||||
- the displayed recommended guidance deck preview, including deck identity, selection posture, brief fallback, and preview-case summary
|
||||
- the displayed follow-up guidance deck preview, including deck identity, selection posture, brief fallback, and preview-case summary
|
||||
- the live coach handoff recommendation, including readiness posture, retained recommendation source posture, and current accepted-packet / method-drill / exact-branch reinforcement flags
|
||||
|
||||
without scraping dashboard text blocks or reopening deck-preview / handoff derivation.
|
||||
|
||||
## Validation
|
||||
|
||||
- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln`
|
||||
- passed with `0 Warning(s), 0 Error(s)`
|
||||
|
||||
## Next clean slice
|
||||
|
||||
Stay on the same live dashboard guidance-consumer lane and land the displayed coach handoff status, displayed transition status, and displayed continuation / queued / follow-up / recommended run action-label inspect surface group.
|
||||
Loading…
Add table
Reference in a new issue