Apply guidance outcome from dashboard
This commit is contained in:
parent
5737214c31
commit
d0ccdde06a
2 changed files with 373 additions and 1 deletions
|
|
@ -407,6 +407,7 @@ FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::StartActiveGuidance
|
|||
FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::StartSelectedGuidancePreviewCaseRun()
|
||||
{
|
||||
const FHyperTwistTrainingDeck Deck = BuildSelectedGuidancePreviewCaseDeck();
|
||||
const FHyperTwistTrainingDeck* ActivePreviewDeck = GetActiveGuidancePreviewDeck();
|
||||
if (!Deck.IsStructurallyValid())
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
|
|
@ -428,7 +429,7 @@ FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::StartSelectedGuidan
|
|||
);
|
||||
CaptureActiveGuidanceLaunchContext(
|
||||
RunState.Session.IsStructurallyValid() ? RunState.Session.TrainingSessionId : SessionId,
|
||||
Deck,
|
||||
ActivePreviewDeck != nullptr && ActivePreviewDeck->IsStructurallyValid() ? *ActivePreviewDeck : Deck,
|
||||
true,
|
||||
Deck.Cases.Num() > 0 ? Deck.Cases[0].CaseId : FString()
|
||||
);
|
||||
|
|
@ -552,6 +553,133 @@ bool UHyperTwistCoachDashboardWidget::ContinueCurrentRunFlow()
|
|||
return bSucceeded;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::ApplyGuidanceOutcomeAction()
|
||||
{
|
||||
const EHyperTwistCoachDashboardOutcomeAction Action = DeriveGuidanceOutcomeAction();
|
||||
const bool bCanRestartAboveCompletedRun =
|
||||
!CachedRunState.Session.IsStructurallyValid()
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Completed
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Aborted;
|
||||
if (bHasLiveAttemptTimer || Action == EHyperTwistCoachDashboardOutcomeAction::None || !bCanRestartAboveCompletedRun)
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingSessionSummary* DisplayedRunRecap = nullptr;
|
||||
const FHyperTwistCoachBrief* DisplayedGuidanceComparisonBrief = nullptr;
|
||||
const FHyperTwistTrainingDeck* DisplayedGuidanceComparisonDeck = nullptr;
|
||||
FString DisplayedGuidanceComparisonSelectedCaseId;
|
||||
bool bDisplayedGuidanceComparisonSingleCase = false;
|
||||
if (!ResolveDisplayedGuidanceComparisonContext(
|
||||
DisplayedRunRecap,
|
||||
DisplayedGuidanceComparisonBrief,
|
||||
DisplayedGuidanceComparisonDeck,
|
||||
DisplayedGuidanceComparisonSelectedCaseId,
|
||||
bDisplayedGuidanceComparisonSingleCase))
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
|
||||
const FString ActionSessionIdBase = FString::Printf(
|
||||
TEXT("%s_outcome_%s"),
|
||||
*DefaultSessionId,
|
||||
*FGuid::NewGuid().ToString(EGuidFormats::Digits)
|
||||
);
|
||||
|
||||
switch (Action)
|
||||
{
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RepeatSelectedCase:
|
||||
{
|
||||
const FHyperTwistTrainingDeck SelectedCaseDeck = BuildGuidanceOutcomeSelectedCaseDeck();
|
||||
if (!SelectedCaseDeck.IsStructurallyValid() || DisplayedGuidanceComparisonDeck == nullptr)
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
|
||||
SelectedCaseDeck,
|
||||
DefaultUserId,
|
||||
ActionSessionIdBase + TEXT("_selected_case"),
|
||||
DefaultMode
|
||||
);
|
||||
CaptureActiveGuidanceLaunchContext(
|
||||
RunState.Session.IsStructurallyValid() ? RunState.Session.TrainingSessionId : ActionSessionIdBase,
|
||||
*DisplayedGuidanceComparisonDeck,
|
||||
true,
|
||||
DisplayedGuidanceComparisonSelectedCaseId
|
||||
);
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
UpdateDashboardPresentation();
|
||||
return RunState.Session.IsStructurallyValid() && RunState.ActiveDeck.IsStructurallyValid();
|
||||
}
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RepeatPreviewDeck:
|
||||
case EHyperTwistCoachDashboardOutcomeAction::BroadenPreviewDeck:
|
||||
{
|
||||
if (DisplayedGuidanceComparisonDeck == nullptr || !DisplayedGuidanceComparisonDeck->IsStructurallyValid())
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
|
||||
const FString SessionSuffix = Action == EHyperTwistCoachDashboardOutcomeAction::BroadenPreviewDeck
|
||||
? TEXT("_broaden_preview")
|
||||
: TEXT("_repeat_preview");
|
||||
const FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
|
||||
*DisplayedGuidanceComparisonDeck,
|
||||
DefaultUserId,
|
||||
ActionSessionIdBase + SessionSuffix,
|
||||
DefaultMode
|
||||
);
|
||||
CaptureActiveGuidanceLaunchContext(
|
||||
RunState.Session.IsStructurallyValid() ? RunState.Session.TrainingSessionId : ActionSessionIdBase,
|
||||
*DisplayedGuidanceComparisonDeck,
|
||||
false,
|
||||
DisplayedGuidanceComparisonSelectedCaseId
|
||||
);
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
UpdateDashboardPresentation();
|
||||
return RunState.Session.IsStructurallyValid() && RunState.ActiveDeck.IsStructurallyValid();
|
||||
}
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RedirectCoachGuidance:
|
||||
{
|
||||
FHyperTwistTrainingRunState RunState;
|
||||
if (CachedCoachPanelState.bCanStartCoachFollowUpRun && CachedCoachPanelState.bHasFollowUpGuidance)
|
||||
{
|
||||
RunState = StartCoachFollowUpRun(DefaultCoachMaxCases);
|
||||
}
|
||||
else if (CachedCoachPanelState.bCanStartQueuedRun)
|
||||
{
|
||||
RunState = StartNextQueuedCoachRun(DefaultCoachMaxCases);
|
||||
}
|
||||
else if (CachedCoachPanelState.bCanStartCoachRecommendedRun)
|
||||
{
|
||||
RunState = StartCoachRecommendedRun(DefaultCoachMaxCases);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
UpdateDashboardPresentation();
|
||||
return RunState.Session.IsStructurallyValid() && RunState.ActiveDeck.IsStructurallyValid();
|
||||
}
|
||||
default:
|
||||
UpdateDashboardPresentation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::StartLiveAttemptTimer()
|
||||
{
|
||||
if (!CachedRunState.Session.IsStructurallyValid() || !CachedRunState.CurrentSelection.TrainingCase.IsStructurallyValid())
|
||||
|
|
@ -817,6 +945,11 @@ void UHyperTwistCoachDashboardWidget::HandleContinueRunClicked()
|
|||
ContinueCurrentRunFlow();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandleGuidanceOutcomeActionClicked()
|
||||
{
|
||||
ApplyGuidanceOutcomeAction();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandleClearRunClicked()
|
||||
{
|
||||
ClearActiveTrainingRun();
|
||||
|
|
@ -1152,6 +1285,17 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
);
|
||||
RepeatRunButtonLabel = RepeatRunLabelRaw;
|
||||
|
||||
UTextBlock* GuidanceOutcomeActionLabelRaw = nullptr;
|
||||
GuidanceOutcomeActionButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
RunRecapActionRow,
|
||||
TEXT("GuidanceOutcomeActionButton"),
|
||||
TEXT("GuidanceOutcomeActionButtonLabel"),
|
||||
TEXT("Apply Outcome"),
|
||||
GuidanceOutcomeActionLabelRaw
|
||||
);
|
||||
GuidanceOutcomeActionButtonLabel = GuidanceOutcomeActionLabelRaw;
|
||||
|
||||
UTextBlock* DismissRecapLabelRaw = nullptr;
|
||||
DismissRecapButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
|
|
@ -1797,6 +1941,10 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
{
|
||||
RepeatRunButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleRepeatRunClicked);
|
||||
}
|
||||
if (GuidanceOutcomeActionButton != nullptr)
|
||||
{
|
||||
GuidanceOutcomeActionButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleGuidanceOutcomeActionClicked);
|
||||
}
|
||||
if (DismissRecapButton != nullptr)
|
||||
{
|
||||
DismissRecapButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleDismissRecapClicked);
|
||||
|
|
@ -2108,6 +2256,177 @@ FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::BuildSelectedGuidancePr
|
|||
return SingleCaseDeck;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::ResolveDisplayedGuidanceComparisonContext(
|
||||
const FHyperTwistTrainingSessionSummary*& OutDisplayedRunRecap,
|
||||
const FHyperTwistCoachBrief*& OutDisplayedGuidanceComparisonBrief,
|
||||
const FHyperTwistTrainingDeck*& OutDisplayedGuidanceComparisonDeck,
|
||||
FString& OutDisplayedGuidanceComparisonSelectedCaseId,
|
||||
bool& bOutDisplayedGuidanceComparisonSingleCase
|
||||
) const
|
||||
{
|
||||
OutDisplayedRunRecap = nullptr;
|
||||
OutDisplayedGuidanceComparisonBrief = nullptr;
|
||||
OutDisplayedGuidanceComparisonDeck = nullptr;
|
||||
OutDisplayedGuidanceComparisonSelectedCaseId.Reset();
|
||||
bOutDisplayedGuidanceComparisonSingleCase = false;
|
||||
|
||||
const bool bHasCurrentRunRecap = CachedRunState.Session.IsStructurallyValid()
|
||||
&& (CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Completed
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Aborted);
|
||||
OutDisplayedRunRecap = bHasCurrentRunRecap
|
||||
? &CachedRunSummary
|
||||
: (bHasRetainedRunRecap ? &RetainedRunRecapSummary : nullptr);
|
||||
if (OutDisplayedRunRecap == nullptr || OutDisplayedRunRecap->TrainingSessionId.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool bHasActiveGuidanceComparison =
|
||||
bHasCurrentRunRecap
|
||||
&& !ActiveGuidanceLaunchSessionId.IsEmpty()
|
||||
&& OutDisplayedRunRecap->TrainingSessionId == ActiveGuidanceLaunchSessionId
|
||||
&& ActiveGuidanceLaunchLane != EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
const bool bHasDisplayedRetainedGuidanceComparison =
|
||||
!bHasCurrentRunRecap
|
||||
&& bHasRetainedGuidanceComparison
|
||||
&& !RetainedGuidanceComparisonSessionId.IsEmpty()
|
||||
&& OutDisplayedRunRecap->TrainingSessionId == RetainedGuidanceComparisonSessionId
|
||||
&& RetainedGuidanceComparisonLane != EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
|
||||
if (bHasActiveGuidanceComparison)
|
||||
{
|
||||
OutDisplayedGuidanceComparisonBrief = &ActiveGuidanceLaunchBrief;
|
||||
OutDisplayedGuidanceComparisonDeck = &ActiveGuidanceLaunchDeck;
|
||||
OutDisplayedGuidanceComparisonSelectedCaseId = ActiveGuidanceLaunchSelectedCaseId;
|
||||
bOutDisplayedGuidanceComparisonSingleCase = bActiveGuidanceLaunchSingleCase;
|
||||
}
|
||||
else if (bHasDisplayedRetainedGuidanceComparison)
|
||||
{
|
||||
OutDisplayedGuidanceComparisonBrief = &RetainedGuidanceComparisonBrief;
|
||||
OutDisplayedGuidanceComparisonDeck = &RetainedGuidanceComparisonDeck;
|
||||
OutDisplayedGuidanceComparisonSelectedCaseId = RetainedGuidanceComparisonSelectedCaseId;
|
||||
bOutDisplayedGuidanceComparisonSingleCase = bRetainedGuidanceComparisonSingleCase;
|
||||
}
|
||||
|
||||
return OutDisplayedGuidanceComparisonBrief != nullptr
|
||||
&& OutDisplayedGuidanceComparisonDeck != nullptr
|
||||
&& OutDisplayedGuidanceComparisonDeck->IsStructurallyValid();
|
||||
}
|
||||
|
||||
EHyperTwistCoachDashboardOutcomeAction UHyperTwistCoachDashboardWidget::DeriveGuidanceOutcomeAction() const
|
||||
{
|
||||
const FHyperTwistTrainingSessionSummary* DisplayedRunRecap = nullptr;
|
||||
const FHyperTwistCoachBrief* DisplayedGuidanceComparisonBrief = nullptr;
|
||||
const FHyperTwistTrainingDeck* DisplayedGuidanceComparisonDeck = nullptr;
|
||||
FString DisplayedGuidanceComparisonSelectedCaseId;
|
||||
bool bDisplayedGuidanceComparisonSingleCase = false;
|
||||
if (!ResolveDisplayedGuidanceComparisonContext(
|
||||
DisplayedRunRecap,
|
||||
DisplayedGuidanceComparisonBrief,
|
||||
DisplayedGuidanceComparisonDeck,
|
||||
DisplayedGuidanceComparisonSelectedCaseId,
|
||||
bDisplayedGuidanceComparisonSingleCase)
|
||||
|| DisplayedRunRecap == nullptr
|
||||
|| DisplayedRunRecap->CompletedAttemptCount <= 0)
|
||||
{
|
||||
return EHyperTwistCoachDashboardOutcomeAction::None;
|
||||
}
|
||||
|
||||
const int32 NonSuccessCount =
|
||||
DisplayedRunRecap->FailureCount + DisplayedRunRecap->TimeoutCount + DisplayedRunRecap->DNFCount;
|
||||
if (bDisplayedGuidanceComparisonSingleCase)
|
||||
{
|
||||
if (DisplayedRunRecap->SuccessRate >= 0.85f
|
||||
&& DisplayedRunRecap->TimeoutCount == 0
|
||||
&& DisplayedRunRecap->DNFCount == 0
|
||||
&& DisplayedRunRecap->TotalMistakes <= 1)
|
||||
{
|
||||
return EHyperTwistCoachDashboardOutcomeAction::BroadenPreviewDeck;
|
||||
}
|
||||
|
||||
return DisplayedGuidanceComparisonSelectedCaseId.IsEmpty()
|
||||
? EHyperTwistCoachDashboardOutcomeAction::None
|
||||
: EHyperTwistCoachDashboardOutcomeAction::RepeatSelectedCase;
|
||||
}
|
||||
|
||||
if (DisplayedRunRecap->SuccessRate >= 0.8f
|
||||
&& NonSuccessCount <= FMath::Max(1, DisplayedRunRecap->CompletedAttemptCount / 4)
|
||||
&& DisplayedRunRecap->TotalMistakes <= FMath::Max(1, DisplayedRunRecap->CompletedAttemptCount / 2))
|
||||
{
|
||||
return EHyperTwistCoachDashboardOutcomeAction::RedirectCoachGuidance;
|
||||
}
|
||||
|
||||
if (DisplayedRunRecap->SuccessRate >= 0.55f)
|
||||
{
|
||||
return EHyperTwistCoachDashboardOutcomeAction::RepeatPreviewDeck;
|
||||
}
|
||||
|
||||
return !DisplayedGuidanceComparisonSelectedCaseId.IsEmpty()
|
||||
? EHyperTwistCoachDashboardOutcomeAction::RepeatSelectedCase
|
||||
: EHyperTwistCoachDashboardOutcomeAction::RedirectCoachGuidance;
|
||||
}
|
||||
|
||||
FString UHyperTwistCoachDashboardWidget::BuildGuidanceOutcomeActionLabel(
|
||||
const EHyperTwistCoachDashboardOutcomeAction Action) const
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RepeatSelectedCase:
|
||||
return TEXT("Apply: Repeat Selected Case");
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RepeatPreviewDeck:
|
||||
return TEXT("Apply: Repeat Preview Deck");
|
||||
case EHyperTwistCoachDashboardOutcomeAction::BroadenPreviewDeck:
|
||||
return TEXT("Apply: Broaden to Preview Deck");
|
||||
case EHyperTwistCoachDashboardOutcomeAction::RedirectCoachGuidance:
|
||||
return TEXT("Apply: Next Coach Guidance");
|
||||
default:
|
||||
return TEXT("Apply Outcome");
|
||||
}
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::BuildGuidanceOutcomeSelectedCaseDeck() const
|
||||
{
|
||||
const FHyperTwistTrainingSessionSummary* DisplayedRunRecap = nullptr;
|
||||
const FHyperTwistCoachBrief* DisplayedGuidanceComparisonBrief = nullptr;
|
||||
const FHyperTwistTrainingDeck* DisplayedGuidanceComparisonDeck = nullptr;
|
||||
FString DisplayedGuidanceComparisonSelectedCaseId;
|
||||
bool bDisplayedGuidanceComparisonSingleCase = false;
|
||||
if (!ResolveDisplayedGuidanceComparisonContext(
|
||||
DisplayedRunRecap,
|
||||
DisplayedGuidanceComparisonBrief,
|
||||
DisplayedGuidanceComparisonDeck,
|
||||
DisplayedGuidanceComparisonSelectedCaseId,
|
||||
bDisplayedGuidanceComparisonSingleCase)
|
||||
|| DisplayedGuidanceComparisonDeck == nullptr
|
||||
|| DisplayedGuidanceComparisonSelectedCaseId.IsEmpty())
|
||||
{
|
||||
return FHyperTwistTrainingDeck();
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingCase* SelectedCase = DisplayedGuidanceComparisonDeck->Cases.FindByPredicate(
|
||||
[&DisplayedGuidanceComparisonSelectedCaseId](const FHyperTwistTrainingCase& Candidate)
|
||||
{
|
||||
return Candidate.CaseId == DisplayedGuidanceComparisonSelectedCaseId;
|
||||
});
|
||||
if (SelectedCase == nullptr)
|
||||
{
|
||||
return FHyperTwistTrainingDeck();
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck SingleCaseDeck = *DisplayedGuidanceComparisonDeck;
|
||||
SingleCaseDeck.Cases = { *SelectedCase };
|
||||
SingleCaseDeck.DeckId = FString::Printf(
|
||||
TEXT("%s_case_%s"),
|
||||
DisplayedGuidanceComparisonDeck->DeckId.IsEmpty() ? TEXT("guidance") : *DisplayedGuidanceComparisonDeck->DeckId,
|
||||
SelectedCase->CaseId.IsEmpty() ? TEXT("selected") : *SelectedCase->CaseId
|
||||
);
|
||||
SingleCaseDeck.Title = FString::Printf(
|
||||
TEXT("%s (Selected Case)"),
|
||||
DisplayedGuidanceComparisonDeck->Title.IsEmpty() ? TEXT("Guidance Comparison") : *DisplayedGuidanceComparisonDeck->Title
|
||||
);
|
||||
return SingleCaseDeck;
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
||||
{
|
||||
const bool bHasActiveRun = CachedRunState.Session.IsStructurallyValid()
|
||||
|
|
@ -2722,6 +3041,20 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
);
|
||||
}
|
||||
}
|
||||
const EHyperTwistCoachDashboardOutcomeAction GuidanceOutcomeAction = DeriveGuidanceOutcomeAction();
|
||||
const bool bCanRedirectGuidanceOutcome =
|
||||
CachedCoachPanelState.bCanStartCoachFollowUpRun
|
||||
|| CachedCoachPanelState.bCanStartQueuedRun
|
||||
|| CachedCoachPanelState.bCanStartCoachRecommendedRun;
|
||||
const bool bCanApplyGuidanceOutcomeAction =
|
||||
GuidanceOutcomeAction != EHyperTwistCoachDashboardOutcomeAction::None
|
||||
&& !bHasLiveAttemptTimer
|
||||
&& (!bHasActiveRun
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Completed
|
||||
|| CachedRunState.Session.SessionState == EHyperTwistTrainingSessionState::Aborted)
|
||||
&& (GuidanceOutcomeAction != EHyperTwistCoachDashboardOutcomeAction::RedirectCoachGuidance
|
||||
|| bCanRedirectGuidanceOutcome);
|
||||
const FString GuidanceOutcomeActionLabel = BuildGuidanceOutcomeActionLabel(GuidanceOutcomeAction);
|
||||
const bool bCanStartPreviewDeck =
|
||||
!bHasLiveAttemptTimer && !bHasActiveRun && ActivePreviewDeck != nullptr && ActivePreviewDeck->IsStructurallyValid();
|
||||
const bool bCanStartPreviewCase = bCanStartPreviewDeck && SelectedGuidancePreviewCase != nullptr;
|
||||
|
|
@ -2862,6 +3195,14 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
GuidanceOutcomeDetailTextBlock->SetText(FText::FromString(GuidanceOutcomeDetailLine));
|
||||
}
|
||||
if (GuidanceOutcomeActionButtonLabel != nullptr)
|
||||
{
|
||||
GuidanceOutcomeActionButtonLabel->SetText(FText::FromString(GuidanceOutcomeActionLabel));
|
||||
}
|
||||
if (GuidanceOutcomeActionButton != nullptr)
|
||||
{
|
||||
GuidanceOutcomeActionButton->SetIsEnabled(bCanApplyGuidanceOutcomeAction);
|
||||
}
|
||||
if (RepeatRunButtonLabel != nullptr)
|
||||
{
|
||||
RepeatRunButtonLabel->SetText(FText::FromString(TEXT("Repeat Run")));
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@ enum class EHyperTwistCoachDashboardGuidancePreviewLane : uint8
|
|||
FollowUp
|
||||
};
|
||||
|
||||
enum class EHyperTwistCoachDashboardOutcomeAction : uint8
|
||||
{
|
||||
None,
|
||||
RepeatSelectedCase,
|
||||
RepeatPreviewDeck,
|
||||
BroadenPreviewDeck,
|
||||
RedirectCoachGuidance
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class UNREALHYPERTWIST_API UHyperTwistCoachDashboardWidget : public UHyperTwistTrainingPanelWidget
|
||||
{
|
||||
|
|
@ -137,6 +146,9 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool ContinueCurrentRunFlow();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool ApplyGuidanceOutcomeAction();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool StartLiveAttemptTimer();
|
||||
|
||||
|
|
@ -206,6 +218,12 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceOutcomeDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> GuidanceOutcomeActionButton = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceOutcomeActionButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> CoachHandoffHeaderTextBlock = nullptr;
|
||||
|
||||
|
|
@ -566,6 +584,9 @@ protected:
|
|||
UFUNCTION()
|
||||
void HandleContinueRunClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleGuidanceOutcomeActionClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleClearRunClicked();
|
||||
|
||||
|
|
@ -632,6 +653,16 @@ private:
|
|||
const FHyperTwistTrainingDeck* GetActiveGuidancePreviewDeck() const;
|
||||
const FHyperTwistCoachBrief* GetActiveGuidancePreviewBrief() const;
|
||||
FHyperTwistTrainingDeck BuildSelectedGuidancePreviewCaseDeck() const;
|
||||
bool ResolveDisplayedGuidanceComparisonContext(
|
||||
const FHyperTwistTrainingSessionSummary*& OutDisplayedRunRecap,
|
||||
const FHyperTwistCoachBrief*& OutDisplayedGuidanceComparisonBrief,
|
||||
const FHyperTwistTrainingDeck*& OutDisplayedGuidanceComparisonDeck,
|
||||
FString& OutDisplayedGuidanceComparisonSelectedCaseId,
|
||||
bool& bOutDisplayedGuidanceComparisonSingleCase
|
||||
) const;
|
||||
EHyperTwistCoachDashboardOutcomeAction DeriveGuidanceOutcomeAction() const;
|
||||
FString BuildGuidanceOutcomeActionLabel(EHyperTwistCoachDashboardOutcomeAction Action) const;
|
||||
FHyperTwistTrainingDeck BuildGuidanceOutcomeSelectedCaseDeck() const;
|
||||
void CaptureActiveGuidanceLaunchContext(
|
||||
const FString& SessionId,
|
||||
const FHyperTwistTrainingDeck& Deck,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue