Compare recap against coach guidance
This commit is contained in:
parent
f3339e8ff4
commit
2b01fdd8c4
2 changed files with 203 additions and 2 deletions
|
|
@ -382,12 +382,21 @@ FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::StartActiveGuidance
|
|||
: (ActiveGuidancePreviewLane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp
|
||||
? TEXT("_preview_follow_up")
|
||||
: TEXT("_preview"));
|
||||
const FString SessionId = DefaultSessionId + SessionSuffix;
|
||||
const FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
|
||||
*Deck,
|
||||
DefaultUserId,
|
||||
DefaultSessionId + SessionSuffix,
|
||||
SessionId,
|
||||
DefaultMode
|
||||
);
|
||||
CaptureActiveGuidanceLaunchContext(
|
||||
RunState.Session.IsStructurallyValid() ? RunState.Session.TrainingSessionId : SessionId,
|
||||
*Deck,
|
||||
false,
|
||||
SelectedGuidancePreviewCaseIndex >= 0 && SelectedGuidancePreviewCaseIndex < Deck->Cases.Num()
|
||||
? Deck->Cases[SelectedGuidancePreviewCaseIndex].CaseId
|
||||
: FString()
|
||||
);
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
|
|
@ -410,12 +419,19 @@ FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::StartSelectedGuidan
|
|||
: (ActiveGuidancePreviewLane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp
|
||||
? TEXT("_preview_case_follow_up")
|
||||
: TEXT("_preview_case"));
|
||||
const FString SessionId = DefaultSessionId + SessionSuffix;
|
||||
const FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
|
||||
Deck,
|
||||
DefaultUserId,
|
||||
DefaultSessionId + SessionSuffix,
|
||||
SessionId,
|
||||
DefaultMode
|
||||
);
|
||||
CaptureActiveGuidanceLaunchContext(
|
||||
RunState.Session.IsStructurallyValid() ? RunState.Session.TrainingSessionId : SessionId,
|
||||
Deck,
|
||||
true,
|
||||
Deck.Cases.Num() > 0 ? Deck.Cases[0].CaseId : FString()
|
||||
);
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
|
|
@ -464,6 +480,13 @@ void UHyperTwistCoachDashboardWidget::ClearRetainedRunRecap()
|
|||
RetainedRunRecapUserId.Reset();
|
||||
RetainedRunRecapSessionId.Reset();
|
||||
RetainedRunRecapMode = EHyperTwistTrainingDeliveryMode::Timer;
|
||||
bHasRetainedGuidanceComparison = false;
|
||||
RetainedGuidanceComparisonSessionId.Reset();
|
||||
RetainedGuidanceComparisonLane = EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
bRetainedGuidanceComparisonSingleCase = false;
|
||||
RetainedGuidanceComparisonBrief = FHyperTwistCoachBrief();
|
||||
RetainedGuidanceComparisonDeck = FHyperTwistTrainingDeck();
|
||||
RetainedGuidanceComparisonSelectedCaseId.Reset();
|
||||
UpdateDashboardPresentation();
|
||||
}
|
||||
|
||||
|
|
@ -1011,6 +1034,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
TEXT("CoachRunRecapDetail"),
|
||||
2
|
||||
);
|
||||
GuidanceComparisonHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceComparisonHeader"),
|
||||
2
|
||||
);
|
||||
GuidanceComparisonStatusTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceComparisonStatus"),
|
||||
2
|
||||
);
|
||||
GuidanceComparisonDetailTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceComparisonDetail"),
|
||||
8
|
||||
);
|
||||
CoachHandoffHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
|
|
@ -1943,6 +1984,18 @@ void UHyperTwistCoachDashboardWidget::SyncRetainedRunRecap()
|
|||
RetainedRunRecapUserId = CachedRunState.Session.UserId;
|
||||
RetainedRunRecapSessionId = CachedRunState.Session.TrainingSessionId;
|
||||
RetainedRunRecapMode = CachedRunState.Session.Mode;
|
||||
if (!ActiveGuidanceLaunchSessionId.IsEmpty()
|
||||
&& ActiveGuidanceLaunchSessionId == RetainedRunRecapSessionId
|
||||
&& ActiveGuidanceLaunchLane != EHyperTwistCoachDashboardGuidancePreviewLane::None)
|
||||
{
|
||||
bHasRetainedGuidanceComparison = true;
|
||||
RetainedGuidanceComparisonSessionId = ActiveGuidanceLaunchSessionId;
|
||||
RetainedGuidanceComparisonLane = ActiveGuidanceLaunchLane;
|
||||
bRetainedGuidanceComparisonSingleCase = bActiveGuidanceLaunchSingleCase;
|
||||
RetainedGuidanceComparisonBrief = ActiveGuidanceLaunchBrief;
|
||||
RetainedGuidanceComparisonDeck = ActiveGuidanceLaunchDeck;
|
||||
RetainedGuidanceComparisonSelectedCaseId = ActiveGuidanceLaunchSelectedCaseId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1992,6 +2045,25 @@ const FHyperTwistCoachBrief* UHyperTwistCoachDashboardWidget::GetActiveGuidanceP
|
|||
}
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::CaptureActiveGuidanceLaunchContext(
|
||||
const FString& SessionId,
|
||||
const FHyperTwistTrainingDeck& Deck,
|
||||
const bool bSingleCaseLaunch,
|
||||
const FString& SelectedCaseId
|
||||
)
|
||||
{
|
||||
ActiveGuidanceLaunchSessionId = SessionId;
|
||||
ActiveGuidanceLaunchLane = ActiveGuidancePreviewLane;
|
||||
bActiveGuidanceLaunchSingleCase = bSingleCaseLaunch;
|
||||
ActiveGuidanceLaunchDeck = Deck;
|
||||
ActiveGuidanceLaunchSelectedCaseId = SelectedCaseId;
|
||||
ActiveGuidanceLaunchBrief = FHyperTwistCoachBrief();
|
||||
if (const FHyperTwistCoachBrief* ActiveBrief = GetActiveGuidancePreviewBrief())
|
||||
{
|
||||
ActiveGuidanceLaunchBrief = *ActiveBrief;
|
||||
}
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::BuildSelectedGuidancePreviewCaseDeck() const
|
||||
{
|
||||
const FHyperTwistTrainingDeck* Deck = GetActiveGuidancePreviewDeck();
|
||||
|
|
@ -2225,6 +2297,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FHyperTwistTrainingSessionSummary* DisplayedRunRecap = bHasCurrentRunRecap
|
||||
? &CachedRunSummary
|
||||
: (bHasRetainedRunRecap ? &RetainedRunRecapSummary : nullptr);
|
||||
const FHyperTwistTrainingDeck* DisplayedRunRecapDeck = bHasCurrentRunRecap
|
||||
? &CachedRunState.ActiveDeck
|
||||
: (bHasRetainedRunRecap ? &RetainedRunRecapDeck : nullptr);
|
||||
const EHyperTwistTrainingDeliveryMode DisplayedRunRecapMode = bHasCurrentRunRecap
|
||||
? CachedRunState.Session.Mode
|
||||
: RetainedRunRecapMode;
|
||||
const bool bHasDisplayedRunRecap = DisplayedRunRecap != nullptr
|
||||
&& !DisplayedRunRecap->TrainingSessionId.IsEmpty();
|
||||
const FString RunRecapSourceLabel = bHasCurrentRunRecap
|
||||
|
|
@ -2236,6 +2314,36 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Completed
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Aborted);
|
||||
const bool bCanDismissStoredRecap = !bHasCurrentRunRecap && bHasRetainedRunRecap;
|
||||
const bool bHasActiveGuidanceComparison =
|
||||
bHasCurrentRunRecap
|
||||
&& DisplayedRunRecap != nullptr
|
||||
&& !ActiveGuidanceLaunchSessionId.IsEmpty()
|
||||
&& DisplayedRunRecap->TrainingSessionId == ActiveGuidanceLaunchSessionId
|
||||
&& ActiveGuidanceLaunchLane != EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
const bool bHasDisplayedRetainedGuidanceComparison =
|
||||
!bHasCurrentRunRecap
|
||||
&& bHasRetainedGuidanceComparison
|
||||
&& DisplayedRunRecap != nullptr
|
||||
&& !RetainedGuidanceComparisonSessionId.IsEmpty()
|
||||
&& DisplayedRunRecap->TrainingSessionId == RetainedGuidanceComparisonSessionId
|
||||
&& RetainedGuidanceComparisonLane != EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
const FHyperTwistCoachBrief* DisplayedGuidanceComparisonBrief = bHasActiveGuidanceComparison
|
||||
? &ActiveGuidanceLaunchBrief
|
||||
: (bHasDisplayedRetainedGuidanceComparison ? &RetainedGuidanceComparisonBrief : nullptr);
|
||||
const FHyperTwistTrainingDeck* DisplayedGuidanceComparisonDeck = bHasActiveGuidanceComparison
|
||||
? &ActiveGuidanceLaunchDeck
|
||||
: (bHasDisplayedRetainedGuidanceComparison ? &RetainedGuidanceComparisonDeck : nullptr);
|
||||
const FString DisplayedGuidanceComparisonSelectedCaseId = bHasActiveGuidanceComparison
|
||||
? ActiveGuidanceLaunchSelectedCaseId
|
||||
: (bHasDisplayedRetainedGuidanceComparison ? RetainedGuidanceComparisonSelectedCaseId : FString());
|
||||
const EHyperTwistCoachDashboardGuidancePreviewLane DisplayedGuidanceComparisonLane = bHasActiveGuidanceComparison
|
||||
? ActiveGuidanceLaunchLane
|
||||
: (bHasDisplayedRetainedGuidanceComparison
|
||||
? RetainedGuidanceComparisonLane
|
||||
: EHyperTwistCoachDashboardGuidancePreviewLane::None);
|
||||
const bool bDisplayedGuidanceComparisonSingleCase = bHasActiveGuidanceComparison
|
||||
? bActiveGuidanceLaunchSingleCase
|
||||
: (bHasDisplayedRetainedGuidanceComparison ? bRetainedGuidanceComparisonSingleCase : false);
|
||||
const bool bCanUseCoachHandoff = !bHasLiveAttemptTimer && !bHasActiveRun;
|
||||
FString CoachHandoffStatusLine;
|
||||
if (bHasLiveAttemptTimer)
|
||||
|
|
@ -2456,6 +2564,57 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
*SignalSummaryLine
|
||||
)
|
||||
: TEXT("Rationale detail: unavailable until a guidance preview lane is active.");
|
||||
const FString GuidanceComparisonLaneLabel =
|
||||
DisplayedGuidanceComparisonLane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: (DisplayedGuidanceComparisonLane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: TEXT("none"));
|
||||
const bool bDisplayedComparisonSelectedCaseMatchesLastCase =
|
||||
DisplayedRunRecap != nullptr
|
||||
&& !DisplayedGuidanceComparisonSelectedCaseId.IsEmpty()
|
||||
&& DisplayedRunRecap->LastCaseId == DisplayedGuidanceComparisonSelectedCaseId;
|
||||
const int32 GuidanceComparisonExpectedCaseCount =
|
||||
DisplayedGuidanceComparisonDeck != nullptr ? DisplayedGuidanceComparisonDeck->Cases.Num() : 0;
|
||||
const FString GuidanceComparisonStatusLine =
|
||||
DisplayedRunRecap != nullptr
|
||||
&& DisplayedGuidanceComparisonBrief != nullptr
|
||||
&& DisplayedGuidanceComparisonDeck != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Comparison: %s recap vs %s preview | Scope: %s | Focus lane: %s | Expected cases: %d | Completed attempts: %d | Success rate: %.2f"),
|
||||
*RunRecapSourceLabel,
|
||||
*GuidanceComparisonLaneLabel,
|
||||
bDisplayedGuidanceComparisonSingleCase ? TEXT("selected case") : TEXT("full preview deck"),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedGuidanceComparisonBrief->FocusLane),
|
||||
GuidanceComparisonExpectedCaseCount,
|
||||
DisplayedRunRecap->CompletedAttemptCount,
|
||||
DisplayedRunRecap->SuccessRate
|
||||
)
|
||||
: TEXT("Comparison: complete a run launched from previewed guidance to compare the recap against the original coach intent.");
|
||||
const FString GuidanceComparisonDetailLine =
|
||||
DisplayedRunRecap != nullptr
|
||||
&& DisplayedGuidanceComparisonBrief != nullptr
|
||||
&& DisplayedGuidanceComparisonDeck != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Launch brief: %s | Action: %s | Preview deck: %s | Actual deck: %s | Mode expected/actual: %s / %s | Selection expected/actual: %s / %s | Selected case: %s | Last case matched: %s | Focus cases: %d | Last case: %s"),
|
||||
DisplayedGuidanceComparisonBrief->Headline.IsEmpty() ? TEXT("n/a") : *DisplayedGuidanceComparisonBrief->Headline,
|
||||
DisplayedGuidanceComparisonBrief->PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *DisplayedGuidanceComparisonBrief->PrimaryActionLabel,
|
||||
DisplayedGuidanceComparisonDeck->Title.IsEmpty() ? *DisplayedGuidanceComparisonDeck->DeckId : *DisplayedGuidanceComparisonDeck->Title,
|
||||
DisplayedRunRecapDeck != nullptr
|
||||
? (DisplayedRunRecapDeck->Title.IsEmpty() ? *DisplayedRunRecapDeck->DeckId : *DisplayedRunRecapDeck->Title)
|
||||
: TEXT("n/a"),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedGuidanceComparisonBrief->SuggestedMode),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedRunRecapMode),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedGuidanceComparisonBrief->SuggestedSelectionPolicy),
|
||||
DisplayedRunRecapDeck != nullptr
|
||||
? *HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(DisplayedRunRecapDeck->SelectionPolicy)
|
||||
: TEXT("n/a"),
|
||||
DisplayedGuidanceComparisonSelectedCaseId.IsEmpty() ? TEXT("n/a") : *DisplayedGuidanceComparisonSelectedCaseId,
|
||||
bDisplayedComparisonSelectedCaseMatchesLastCase ? TEXT("yes") : TEXT("no"),
|
||||
DisplayedGuidanceComparisonBrief->FocusCaseIds.Num(),
|
||||
DisplayedRunRecap->LastCaseId.IsEmpty() ? TEXT("n/a") : *DisplayedRunRecap->LastCaseId
|
||||
)
|
||||
: TEXT("Comparison detail: no preview-launched recap is currently selected.");
|
||||
const bool bCanStartPreviewDeck =
|
||||
!bHasLiveAttemptTimer && !bHasActiveRun && ActivePreviewDeck != nullptr && ActivePreviewDeck->IsStructurallyValid();
|
||||
const bool bCanStartPreviewCase = bCanStartPreviewDeck && SelectedGuidancePreviewCase != nullptr;
|
||||
|
|
@ -2572,6 +2731,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
));
|
||||
}
|
||||
}
|
||||
if (GuidanceComparisonHeaderTextBlock != nullptr)
|
||||
{
|
||||
GuidanceComparisonHeaderTextBlock->SetText(FText::FromString(TEXT("[Guidance Comparison]")));
|
||||
}
|
||||
if (GuidanceComparisonStatusTextBlock != nullptr)
|
||||
{
|
||||
GuidanceComparisonStatusTextBlock->SetText(FText::FromString(GuidanceComparisonStatusLine));
|
||||
}
|
||||
if (GuidanceComparisonDetailTextBlock != nullptr)
|
||||
{
|
||||
GuidanceComparisonDetailTextBlock->SetText(FText::FromString(GuidanceComparisonDetailLine));
|
||||
}
|
||||
if (RepeatRunButtonLabel != nullptr)
|
||||
{
|
||||
RepeatRunButtonLabel->SetText(FText::FromString(TEXT("Repeat Run")));
|
||||
|
|
|
|||
|
|
@ -188,6 +188,15 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> RunRecapDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceComparisonHeaderTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceComparisonStatusTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceComparisonDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> CoachHandoffHeaderTextBlock = nullptr;
|
||||
|
||||
|
|
@ -614,6 +623,12 @@ private:
|
|||
const FHyperTwistTrainingDeck* GetActiveGuidancePreviewDeck() const;
|
||||
const FHyperTwistCoachBrief* GetActiveGuidancePreviewBrief() const;
|
||||
FHyperTwistTrainingDeck BuildSelectedGuidancePreviewCaseDeck() const;
|
||||
void CaptureActiveGuidanceLaunchContext(
|
||||
const FString& SessionId,
|
||||
const FHyperTwistTrainingDeck& Deck,
|
||||
bool bSingleCaseLaunch,
|
||||
const FString& SelectedCaseId
|
||||
);
|
||||
bool IsLiveAttemptInspectionPhase() const;
|
||||
int32 GetMaxManualSplitCaptureCount() const;
|
||||
const FHyperTwistTrainingSplitPhaseDefinition* FindNextSplitPhaseToCapture() const;
|
||||
|
|
@ -629,6 +644,21 @@ private:
|
|||
FString RetainedRunRecapUserId;
|
||||
FString RetainedRunRecapSessionId;
|
||||
EHyperTwistTrainingDeliveryMode RetainedRunRecapMode = EHyperTwistTrainingDeliveryMode::Timer;
|
||||
FString ActiveGuidanceLaunchSessionId;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidanceLaunchLane =
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
bool bActiveGuidanceLaunchSingleCase = false;
|
||||
FHyperTwistCoachBrief ActiveGuidanceLaunchBrief;
|
||||
FHyperTwistTrainingDeck ActiveGuidanceLaunchDeck;
|
||||
FString ActiveGuidanceLaunchSelectedCaseId;
|
||||
bool bHasRetainedGuidanceComparison = false;
|
||||
FString RetainedGuidanceComparisonSessionId;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane RetainedGuidanceComparisonLane =
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
bool bRetainedGuidanceComparisonSingleCase = false;
|
||||
FHyperTwistCoachBrief RetainedGuidanceComparisonBrief;
|
||||
FHyperTwistTrainingDeck RetainedGuidanceComparisonDeck;
|
||||
FString RetainedGuidanceComparisonSelectedCaseId;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue