Show last attempt timing on coach dashboard

This commit is contained in:
axiomlogicnexus 2026-04-27 14:29:05 +02:00
parent 1251369cb7
commit 7e43c6eb66
2 changed files with 76 additions and 0 deletions

View file

@ -676,6 +676,18 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
TEXT("CoachLastAttempt"),
2
);
LastAttemptTimingTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachLastAttemptTiming"),
2
);
LastAttemptPhaseTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachLastAttemptPhase"),
2
);
CurrentCaseHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
@ -1296,6 +1308,26 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
const FString VerificationNotePreview = CachedRepositoryRoundTripVerification.VerificationNotes.Num() > 0
? CachedRepositoryRoundTripVerification.VerificationNotes[0]
: TEXT("none");
const FHyperTwistTrainingAttempt* LastAttempt = CachedRunState.Attempts.Num() > 0
? &CachedRunState.Attempts.Last()
: nullptr;
FString LastAttemptPhaseSummary = TEXT("none");
if (LastAttempt != nullptr && LastAttempt->TimingBreakdown.DerivedPhaseTimings.Num() > 0)
{
TArray<FString> PhaseParts;
PhaseParts.Reserve(LastAttempt->TimingBreakdown.DerivedPhaseTimings.Num());
for (const FHyperTwistPhaseTiming& PhaseTiming : LastAttempt->TimingBreakdown.DerivedPhaseTimings)
{
PhaseParts.Add(FString::Printf(
TEXT("%s %d-%d (%d ms)"),
PhaseTiming.PhaseKind.IsEmpty() ? TEXT("phase") : *PhaseTiming.PhaseKind,
PhaseTiming.StartedAtMs,
PhaseTiming.EndedAtMs,
PhaseTiming.DurationMs
));
}
LastAttemptPhaseSummary = FString::Join(PhaseParts, TEXT(" | "));
}
if (HeadlineTextBlock != nullptr)
{
@ -1368,6 +1400,44 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
));
}
}
if (LastAttemptTimingTextBlock != nullptr)
{
if (LastAttempt != nullptr)
{
LastAttemptTimingTextBlock->SetText(FText::FromString(FString::Printf(
TEXT("Last timing: result %s | inspection %d ms | raw solve %d ms | final %d ms | penalty %s | split captures %d | did-not-finish: %s"),
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(LastAttempt->Result),
LastAttempt->TimingBreakdown.InspectionElapsedMs,
LastAttempt->TimingBreakdown.RawSolveTimeMs,
LastAttempt->TimingBreakdown.FinalTimeMs,
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(LastAttempt->TimingBreakdown.AppliedPenalty),
LastAttempt->TimingBreakdown.SplitCaptures.Num(),
LastAttempt->TimingBreakdown.bDidNotFinish ? TEXT("yes") : TEXT("no")
)));
}
else
{
LastAttemptTimingTextBlock->SetText(FText::FromString(
TEXT("Last timing: unavailable until the active run records an attempt.")
));
}
}
if (LastAttemptPhaseTextBlock != nullptr)
{
if (LastAttempt != nullptr)
{
LastAttemptPhaseTextBlock->SetText(FText::FromString(FString::Printf(
TEXT("Last derived phases: %s"),
*LastAttemptPhaseSummary
)));
}
else
{
LastAttemptPhaseTextBlock->SetText(FText::FromString(
TEXT("Last derived phases: none yet.")
));
}
}
if (CurrentCaseHeaderTextBlock != nullptr)
{
CurrentCaseHeaderTextBlock->SetText(FText::FromString(TEXT("[Current Case]")));

View file

@ -136,6 +136,12 @@ protected:
UPROPERTY(Transient)
TObjectPtr<UTextBlock> LastAttemptTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> LastAttemptTimingTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> LastAttemptPhaseTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> CurrentCaseHeaderTextBlock = nullptr;