Retain closure recovery history on dashboard
This commit is contained in:
parent
77c8e66539
commit
61cef5b7d6
2 changed files with 367 additions and 0 deletions
|
|
@ -186,11 +186,13 @@ void UHyperTwistCoachDashboardWidget::RefreshCoachDashboardView()
|
|||
RefreshLiveAttemptClock();
|
||||
}
|
||||
RecordQueueSuppressionSnapshot();
|
||||
RecordClosureRecoverySnapshot();
|
||||
SyncRetainedRunRecap();
|
||||
SyncSelectedQueueEntry();
|
||||
SyncSelectedAttempt();
|
||||
SyncSelectedGuidanceDecisionHistoryEntry();
|
||||
SyncSelectedQueueSuppressionHistoryEntry();
|
||||
SyncSelectedClosureRecoveryHistoryEntry();
|
||||
SyncPreferredGuidancePreviewLane(false);
|
||||
UpdateDashboardPresentation();
|
||||
}
|
||||
|
|
@ -1031,6 +1033,47 @@ bool UHyperTwistCoachDashboardWidget::SelectNextQueueSuppressionHistoryEntry()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::SelectPreviousClosureRecoveryHistoryEntry()
|
||||
{
|
||||
if (ClosureRecoveryHistoryEntries.Num() <= 0)
|
||||
{
|
||||
SelectedClosureRecoveryIndex = INDEX_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SelectedClosureRecoveryIndex == INDEX_NONE)
|
||||
{
|
||||
SyncSelectedClosureRecoveryHistoryEntry();
|
||||
return SelectedClosureRecoveryIndex != INDEX_NONE;
|
||||
}
|
||||
|
||||
SelectedClosureRecoveryIndex =
|
||||
(SelectedClosureRecoveryIndex - 1 + ClosureRecoveryHistoryEntries.Num())
|
||||
% ClosureRecoveryHistoryEntries.Num();
|
||||
UpdateDashboardPresentation();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::SelectNextClosureRecoveryHistoryEntry()
|
||||
{
|
||||
if (ClosureRecoveryHistoryEntries.Num() <= 0)
|
||||
{
|
||||
SelectedClosureRecoveryIndex = INDEX_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SelectedClosureRecoveryIndex == INDEX_NONE)
|
||||
{
|
||||
SyncSelectedClosureRecoveryHistoryEntry();
|
||||
return SelectedClosureRecoveryIndex != INDEX_NONE;
|
||||
}
|
||||
|
||||
SelectedClosureRecoveryIndex =
|
||||
(SelectedClosureRecoveryIndex + 1) % ClosureRecoveryHistoryEntries.Num();
|
||||
UpdateDashboardPresentation();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UHyperTwistCoachDashboardWidget::StartLiveAttemptTimer()
|
||||
{
|
||||
if (!CachedRunState.Session.IsStructurallyValid() || !CachedRunState.CurrentSelection.TrainingCase.IsStructurallyValid())
|
||||
|
|
@ -1326,6 +1369,16 @@ void UHyperTwistCoachDashboardWidget::HandleNextQueueSuppressionClicked()
|
|||
SelectNextQueueSuppressionHistoryEntry();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandlePreviousClosureRecoveryClicked()
|
||||
{
|
||||
SelectPreviousClosureRecoveryHistoryEntry();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandleNextClosureRecoveryClicked()
|
||||
{
|
||||
SelectNextClosureRecoveryHistoryEntry();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandleClearRunClicked()
|
||||
{
|
||||
ClearActiveTrainingRun();
|
||||
|
|
@ -2036,6 +2089,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
TEXT("CoachClosureRecoveryDetail"),
|
||||
8
|
||||
);
|
||||
ClosureRecoveryHistoryHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachClosureRecoveryHistoryHeader"),
|
||||
2
|
||||
);
|
||||
ClosureRecoveryHistoryStatusTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachClosureRecoveryHistoryStatus"),
|
||||
2
|
||||
);
|
||||
ClosureRecoveryHistoryDetailTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachClosureRecoveryHistoryDetail"),
|
||||
8
|
||||
);
|
||||
QueueRecoveryHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
|
|
@ -2210,6 +2281,40 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
NextQueueSuppressionButtonLabel = NextQueueSuppressionLabelRaw;
|
||||
}
|
||||
|
||||
UHorizontalBox* ClosureRecoveryNavRow = WidgetTree->ConstructWidget<UHorizontalBox>(
|
||||
UHorizontalBox::StaticClass(),
|
||||
TEXT("CoachDashboardClosureRecoveryNavRow")
|
||||
);
|
||||
if (ClosureRecoveryNavRow != nullptr)
|
||||
{
|
||||
if (UVerticalBoxSlot* ClosureRecoveryNavRowSlot = RootLayout->AddChildToVerticalBox(ClosureRecoveryNavRow))
|
||||
{
|
||||
ClosureRecoveryNavRowSlot->SetPadding(FMargin(0.0f, 4.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
UTextBlock* PreviousClosureRecoveryLabelRaw = nullptr;
|
||||
PreviousClosureRecoveryButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
ClosureRecoveryNavRow,
|
||||
TEXT("PreviousClosureRecoveryButton"),
|
||||
TEXT("PreviousClosureRecoveryButtonLabel"),
|
||||
TEXT("Prev Closure"),
|
||||
PreviousClosureRecoveryLabelRaw
|
||||
);
|
||||
PreviousClosureRecoveryButtonLabel = PreviousClosureRecoveryLabelRaw;
|
||||
|
||||
UTextBlock* NextClosureRecoveryLabelRaw = nullptr;
|
||||
NextClosureRecoveryButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
ClosureRecoveryNavRow,
|
||||
TEXT("NextClosureRecoveryButton"),
|
||||
TEXT("NextClosureRecoveryButtonLabel"),
|
||||
TEXT("Next Closure"),
|
||||
NextClosureRecoveryLabelRaw
|
||||
);
|
||||
NextClosureRecoveryButtonLabel = NextClosureRecoveryLabelRaw;
|
||||
}
|
||||
|
||||
UHorizontalBox* AttemptInputRow = WidgetTree->ConstructWidget<UHorizontalBox>(
|
||||
UHorizontalBox::StaticClass(),
|
||||
TEXT("CoachDashboardAttemptInputRow")
|
||||
|
|
@ -2524,6 +2629,20 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
&UHyperTwistCoachDashboardWidget::HandleNextQueueSuppressionClicked
|
||||
);
|
||||
}
|
||||
if (PreviousClosureRecoveryButton != nullptr)
|
||||
{
|
||||
PreviousClosureRecoveryButton->OnClicked.AddDynamic(
|
||||
this,
|
||||
&UHyperTwistCoachDashboardWidget::HandlePreviousClosureRecoveryClicked
|
||||
);
|
||||
}
|
||||
if (NextClosureRecoveryButton != nullptr)
|
||||
{
|
||||
NextClosureRecoveryButton->OnClicked.AddDynamic(
|
||||
this,
|
||||
&UHyperTwistCoachDashboardWidget::HandleNextClosureRecoveryClicked
|
||||
);
|
||||
}
|
||||
if (RepeatRunButton != nullptr)
|
||||
{
|
||||
RepeatRunButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleRepeatRunClicked);
|
||||
|
|
@ -2806,6 +2925,21 @@ void UHyperTwistCoachDashboardWidget::SyncSelectedQueueSuppressionHistoryEntry()
|
|||
}
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::SyncSelectedClosureRecoveryHistoryEntry()
|
||||
{
|
||||
if (ClosureRecoveryHistoryEntries.Num() <= 0)
|
||||
{
|
||||
SelectedClosureRecoveryIndex = INDEX_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedClosureRecoveryIndex < 0
|
||||
|| SelectedClosureRecoveryIndex >= ClosureRecoveryHistoryEntries.Num())
|
||||
{
|
||||
SelectedClosureRecoveryIndex = ClosureRecoveryHistoryEntries.Num() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::SyncPreferredGuidancePreviewLane(const bool bForceAdoptPreferredLane)
|
||||
{
|
||||
const FHyperTwistCoachDashboardGuidanceLanePreference Preference = BuildGuidanceLanePreference();
|
||||
|
|
@ -3645,6 +3779,89 @@ void UHyperTwistCoachDashboardWidget::RecordQueueSuppressionSnapshot()
|
|||
SelectedQueueSuppressionIndex = QueueSuppressionHistoryEntries.Num() - 1;
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::RecordClosureRecoverySnapshot()
|
||||
{
|
||||
const int32 HistoricalKeepCount =
|
||||
CachedCoachSchedulePolicySummary.HistoricalFollowUpContinuationCount;
|
||||
const int32 HistoricalSuppressCount =
|
||||
CachedCoachSchedulePolicySummary.HistoricalBorderlineFollowUpSuppressionCount;
|
||||
const FHyperTwistCoachSignal* ClosureRecoverySignal = CachedCoachSignals.FindByPredicate(
|
||||
[](const FHyperTwistCoachSignal& Signal)
|
||||
{
|
||||
return Signal.SignalId == TEXT("closure_history_follow_up_continuation")
|
||||
|| Signal.SignalId == TEXT("closure_history_recommended_suppression");
|
||||
}
|
||||
);
|
||||
const bool bHasClosureSignal = ClosureRecoverySignal != nullptr;
|
||||
|
||||
FHyperTwistCoachDashboardClosureRecoveryEntry Entry;
|
||||
Entry.RecordedAtUtc = FDateTime::UtcNow().ToIso8601();
|
||||
Entry.HistoricalFollowUpContinuationCount = HistoricalKeepCount;
|
||||
Entry.HistoricalBorderlineFollowUpSuppressionCount = HistoricalSuppressCount;
|
||||
Entry.bFollowUpContinuationFromRecoveryHistory =
|
||||
CachedCoachSchedulePolicySummary.bFollowUpContinuationFromRecoveryHistory;
|
||||
Entry.bBorderlineFollowUpSuppressedByRecoveryHistory =
|
||||
CachedCoachSchedulePolicySummary.bBorderlineFollowUpSuppressedByRecoveryHistory;
|
||||
Entry.PreferredGuidanceLane = CachedCoachPanelState.PreferredGuidanceLane;
|
||||
Entry.PreferredGuidanceSourceLabel = CachedCoachPanelState.PreferredGuidanceSourceLabel;
|
||||
Entry.ClosurePolicyLine = CachedCoachSchedulePolicySummary.ClosurePolicyLine;
|
||||
if (bHasClosureSignal)
|
||||
{
|
||||
Entry.ActiveSignalId = ClosureRecoverySignal->SignalId;
|
||||
Entry.ActiveSignalHeadline = ClosureRecoverySignal->Headline;
|
||||
Entry.ActiveSignalDetail = ClosureRecoverySignal->Detail;
|
||||
Entry.ActiveSignalScore = ClosureRecoverySignal->Score;
|
||||
Entry.bActiveSignalPromoted =
|
||||
CachedCoachBrief.Signals.Num() > 0
|
||||
&& CachedCoachBrief.Signals[0].SignalId == ClosureRecoverySignal->SignalId;
|
||||
}
|
||||
|
||||
const bool bHasClosureRecoveryHistory =
|
||||
HistoricalKeepCount > 0
|
||||
|| HistoricalSuppressCount > 0
|
||||
|| Entry.bFollowUpContinuationFromRecoveryHistory
|
||||
|| Entry.bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
|| bHasClosureSignal;
|
||||
if (!bHasClosureRecoveryHistory || !Entry.IsStructurallyValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool bMatchesLastEntry = ClosureRecoveryHistoryEntries.Num() > 0
|
||||
&& ClosureRecoveryHistoryEntries.Last().HistoricalFollowUpContinuationCount
|
||||
== Entry.HistoricalFollowUpContinuationCount
|
||||
&& ClosureRecoveryHistoryEntries.Last().HistoricalBorderlineFollowUpSuppressionCount
|
||||
== Entry.HistoricalBorderlineFollowUpSuppressionCount
|
||||
&& ClosureRecoveryHistoryEntries.Last().bFollowUpContinuationFromRecoveryHistory
|
||||
== Entry.bFollowUpContinuationFromRecoveryHistory
|
||||
&& ClosureRecoveryHistoryEntries.Last().bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
== Entry.bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
&& ClosureRecoveryHistoryEntries.Last().PreferredGuidanceLane
|
||||
== Entry.PreferredGuidanceLane
|
||||
&& ClosureRecoveryHistoryEntries.Last().PreferredGuidanceSourceLabel
|
||||
== Entry.PreferredGuidanceSourceLabel
|
||||
&& ClosureRecoveryHistoryEntries.Last().ClosurePolicyLine
|
||||
== Entry.ClosurePolicyLine
|
||||
&& ClosureRecoveryHistoryEntries.Last().ActiveSignalId
|
||||
== Entry.ActiveSignalId
|
||||
&& ClosureRecoveryHistoryEntries.Last().bActiveSignalPromoted
|
||||
== Entry.bActiveSignalPromoted;
|
||||
if (bMatchesLastEntry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClosureRecoveryHistoryEntries.Add(Entry);
|
||||
constexpr int32 MaxRetainedClosureRecoveryEntries = 16;
|
||||
if (ClosureRecoveryHistoryEntries.Num() > MaxRetainedClosureRecoveryEntries)
|
||||
{
|
||||
const int32 ExcessCount =
|
||||
ClosureRecoveryHistoryEntries.Num() - MaxRetainedClosureRecoveryEntries;
|
||||
ClosureRecoveryHistoryEntries.RemoveAt(0, ExcessCount, EAllowShrinking::No);
|
||||
}
|
||||
SelectedClosureRecoveryIndex = ClosureRecoveryHistoryEntries.Num() - 1;
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
||||
{
|
||||
const bool bHasActiveRun = CachedRunState.Session.IsStructurallyValid()
|
||||
|
|
@ -5393,6 +5610,60 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
? *ClosureRecoverySignal->Detail
|
||||
: TEXT("")
|
||||
);
|
||||
const FHyperTwistCoachDashboardClosureRecoveryEntry* SelectedClosureRecoveryEntry =
|
||||
SelectedClosureRecoveryIndex >= 0
|
||||
&& SelectedClosureRecoveryIndex < ClosureRecoveryHistoryEntries.Num()
|
||||
? &ClosureRecoveryHistoryEntries[SelectedClosureRecoveryIndex]
|
||||
: nullptr;
|
||||
const FString SelectedClosureHistoryLaneLabel =
|
||||
SelectedClosureRecoveryEntry != nullptr
|
||||
? (SelectedClosureRecoveryEntry->PreferredGuidanceLane
|
||||
== EHyperTwistTrainingCoachGuidanceLane::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: (SelectedClosureRecoveryEntry->PreferredGuidanceLane
|
||||
== EHyperTwistTrainingCoachGuidanceLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("none")))
|
||||
: TEXT("none");
|
||||
const FString ClosureRecoveryHistoryStatusLine =
|
||||
SelectedClosureRecoveryEntry != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Closure history: %d entries | selected %d/%d | Lane: %s | Recorded: %s"),
|
||||
ClosureRecoveryHistoryEntries.Num(),
|
||||
SelectedClosureRecoveryIndex + 1,
|
||||
ClosureRecoveryHistoryEntries.Num(),
|
||||
*SelectedClosureHistoryLaneLabel,
|
||||
*SelectedClosureRecoveryEntry->RecordedAtUtc
|
||||
)
|
||||
: TEXT("Closure history: no retained closure-recovery shifts recorded yet.");
|
||||
const FString ClosureRecoveryHistoryDetailLine =
|
||||
SelectedClosureRecoveryEntry != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Policy: %s | keep %d | suppress %d | continuation active: %s | borderline suppression active: %s | source: %s | promoted: %s | signal: %s%s%s"),
|
||||
SelectedClosureRecoveryEntry->ClosurePolicyLine.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *SelectedClosureRecoveryEntry->ClosurePolicyLine,
|
||||
SelectedClosureRecoveryEntry->HistoricalFollowUpContinuationCount,
|
||||
SelectedClosureRecoveryEntry->HistoricalBorderlineFollowUpSuppressionCount,
|
||||
SelectedClosureRecoveryEntry->bFollowUpContinuationFromRecoveryHistory
|
||||
? TEXT("yes")
|
||||
: TEXT("no"),
|
||||
SelectedClosureRecoveryEntry->bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
? TEXT("yes")
|
||||
: TEXT("no"),
|
||||
SelectedClosureRecoveryEntry->PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *SelectedClosureRecoveryEntry->PreferredGuidanceSourceLabel,
|
||||
SelectedClosureRecoveryEntry->bActiveSignalPromoted ? TEXT("yes") : TEXT("no"),
|
||||
SelectedClosureRecoveryEntry->ActiveSignalHeadline.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *SelectedClosureRecoveryEntry->ActiveSignalHeadline,
|
||||
SelectedClosureRecoveryEntry->ActiveSignalDetail.IsEmpty() ? TEXT("") : TEXT(" || detail: "),
|
||||
SelectedClosureRecoveryEntry->ActiveSignalDetail.IsEmpty()
|
||||
? TEXT("")
|
||||
: *SelectedClosureRecoveryEntry->ActiveSignalDetail
|
||||
)
|
||||
: TEXT("Closure history detail: retained keep-vs-suppress shifts will accumulate here as recovery history changes the closure posture over time.");
|
||||
if (ClosureRecoveryHeaderTextBlock != nullptr)
|
||||
{
|
||||
ClosureRecoveryHeaderTextBlock->SetText(FText::FromString(TEXT("[Closure Recovery]")));
|
||||
|
|
@ -5405,6 +5676,34 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
ClosureRecoveryDetailTextBlock->SetText(FText::FromString(ClosureRecoveryDetailLine));
|
||||
}
|
||||
if (ClosureRecoveryHistoryHeaderTextBlock != nullptr)
|
||||
{
|
||||
ClosureRecoveryHistoryHeaderTextBlock->SetText(FText::FromString(TEXT("[Closure Recovery History]")));
|
||||
}
|
||||
if (ClosureRecoveryHistoryStatusTextBlock != nullptr)
|
||||
{
|
||||
ClosureRecoveryHistoryStatusTextBlock->SetText(FText::FromString(ClosureRecoveryHistoryStatusLine));
|
||||
}
|
||||
if (ClosureRecoveryHistoryDetailTextBlock != nullptr)
|
||||
{
|
||||
ClosureRecoveryHistoryDetailTextBlock->SetText(FText::FromString(ClosureRecoveryHistoryDetailLine));
|
||||
}
|
||||
if (PreviousClosureRecoveryButtonLabel != nullptr)
|
||||
{
|
||||
PreviousClosureRecoveryButtonLabel->SetText(FText::FromString(TEXT("Prev Closure")));
|
||||
}
|
||||
if (PreviousClosureRecoveryButton != nullptr)
|
||||
{
|
||||
PreviousClosureRecoveryButton->SetIsEnabled(ClosureRecoveryHistoryEntries.Num() > 1);
|
||||
}
|
||||
if (NextClosureRecoveryButtonLabel != nullptr)
|
||||
{
|
||||
NextClosureRecoveryButtonLabel->SetText(FText::FromString(TEXT("Next Closure")));
|
||||
}
|
||||
if (NextClosureRecoveryButton != nullptr)
|
||||
{
|
||||
NextClosureRecoveryButton->SetIsEnabled(ClosureRecoveryHistoryEntries.Num() > 1);
|
||||
}
|
||||
if (QueueRecoveryHeaderTextBlock != nullptr)
|
||||
{
|
||||
QueueRecoveryHeaderTextBlock->SetText(FText::FromString(TEXT("[Queue Recovery]")));
|
||||
|
|
|
|||
|
|
@ -179,6 +179,35 @@ struct FHyperTwistCoachDashboardQueueSuppressionEntry
|
|||
}
|
||||
};
|
||||
|
||||
struct FHyperTwistCoachDashboardClosureRecoveryEntry
|
||||
{
|
||||
FString RecordedAtUtc;
|
||||
int32 HistoricalFollowUpContinuationCount = 0;
|
||||
int32 HistoricalBorderlineFollowUpSuppressionCount = 0;
|
||||
bool bFollowUpContinuationFromRecoveryHistory = false;
|
||||
bool bBorderlineFollowUpSuppressedByRecoveryHistory = false;
|
||||
EHyperTwistTrainingCoachGuidanceLane PreferredGuidanceLane =
|
||||
EHyperTwistTrainingCoachGuidanceLane::None;
|
||||
FString PreferredGuidanceSourceLabel;
|
||||
FString ClosurePolicyLine;
|
||||
FString ActiveSignalId;
|
||||
FString ActiveSignalHeadline;
|
||||
FString ActiveSignalDetail;
|
||||
float ActiveSignalScore = 0.0f;
|
||||
bool bActiveSignalPromoted = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !RecordedAtUtc.IsEmpty()
|
||||
&& (HistoricalFollowUpContinuationCount > 0
|
||||
|| HistoricalBorderlineFollowUpSuppressionCount > 0
|
||||
|| bFollowUpContinuationFromRecoveryHistory
|
||||
|| bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
|| !ActiveSignalId.IsEmpty()
|
||||
|| !ClosurePolicyLine.IsEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class UNREALHYPERTWIST_API UHyperTwistCoachDashboardWidget : public UHyperTwistTrainingPanelWidget
|
||||
{
|
||||
|
|
@ -224,6 +253,9 @@ public:
|
|||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
int32 SelectedQueueSuppressionIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
int32 SelectedClosureRecoveryIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool bHasLiveAttemptTimer = false;
|
||||
|
||||
|
|
@ -317,6 +349,12 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool SelectNextQueueSuppressionHistoryEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool SelectPreviousClosureRecoveryHistoryEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool SelectNextClosureRecoveryHistoryEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool StartLiveAttemptTimer();
|
||||
|
||||
|
|
@ -593,6 +631,27 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> ClosureRecoveryDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> ClosureRecoveryHistoryHeaderTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> ClosureRecoveryHistoryStatusTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> ClosureRecoveryHistoryDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> PreviousClosureRecoveryButton = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> PreviousClosureRecoveryButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> NextClosureRecoveryButton = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> NextClosureRecoveryButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> QueueRecoveryHeaderTextBlock = nullptr;
|
||||
|
||||
|
|
@ -863,6 +922,12 @@ protected:
|
|||
UFUNCTION()
|
||||
void HandleNextQueueSuppressionClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandlePreviousClosureRecoveryClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleNextClosureRecoveryClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleClearRunClicked();
|
||||
|
||||
|
|
@ -919,6 +984,7 @@ private:
|
|||
void SyncSelectedGuidancePreviewCase();
|
||||
void SyncSelectedGuidanceDecisionHistoryEntry();
|
||||
void SyncSelectedQueueSuppressionHistoryEntry();
|
||||
void SyncSelectedClosureRecoveryHistoryEntry();
|
||||
void SyncPreferredGuidancePreviewLane(bool bForceAdoptPreferredLane);
|
||||
void UpdateDashboardPresentation();
|
||||
void RefreshLiveAttemptClock();
|
||||
|
|
@ -959,6 +1025,7 @@ private:
|
|||
bool bSucceeded
|
||||
);
|
||||
void RecordQueueSuppressionSnapshot();
|
||||
void RecordClosureRecoverySnapshot();
|
||||
void RecordGuidanceOutcomeDecision(
|
||||
EHyperTwistCoachDashboardOutcomeAction RecommendedAction,
|
||||
EHyperTwistCoachDashboardOutcomeAction AppliedAction,
|
||||
|
|
@ -1009,6 +1076,7 @@ private:
|
|||
FHyperTwistCoachDashboardQueueRecoveryOutcome QueueRecoveryOutcome;
|
||||
TArray<FHyperTwistCoachDashboardQueueRecoveryOutcome> QueueRecoveryOutcomeHistory;
|
||||
TArray<FHyperTwistCoachDashboardQueueSuppressionEntry> QueueSuppressionHistoryEntries;
|
||||
TArray<FHyperTwistCoachDashboardClosureRecoveryEntry> ClosureRecoveryHistoryEntries;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane::None;
|
||||
int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue