Expose dashboard drill follow-up history navigation surface
This commit is contained in:
parent
f595934829
commit
4fd3991016
5 changed files with 267 additions and 4 deletions
|
|
@ -8325,6 +8325,122 @@ UHyperTwistCoachDashboardWidget::GetSelectedMethodDrillFollowUpHistoryInspectSur
|
|||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryNavigationInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetDisplayedMethodDrillFollowUpHistoryNavigationInspectSurface() const
|
||||
{
|
||||
FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryNavigationInspectSurface Surface;
|
||||
Surface.Headline = TEXT("Method-drill follow-up history navigation");
|
||||
|
||||
const FHyperTwistCoachDashboardMethodDrillFollowUpWeighting Weighting =
|
||||
BuildMethodDrillFollowUpWeighting();
|
||||
const FHyperTwistCoachDashboardMethodDrillFollowUpHistoryEntry* SelectedEntry =
|
||||
SelectedMethodDrillFollowUpHistoryIndex >= 0
|
||||
&& SelectedMethodDrillFollowUpHistoryIndex < MethodDrillFollowUpHistoryEntries.Num()
|
||||
? &MethodDrillFollowUpHistoryEntries[SelectedMethodDrillFollowUpHistoryIndex]
|
||||
: nullptr;
|
||||
const bool bNavigationEnabled = MethodDrillFollowUpHistoryEntries.Num() > 1;
|
||||
|
||||
Surface.PreviousLabel = !DisplayedPreviousMethodDrillFollowUpNavigationLabel.IsEmpty()
|
||||
? DisplayedPreviousMethodDrillFollowUpNavigationLabel
|
||||
: TEXT("Prev Drill Follow-Up");
|
||||
Surface.NextLabel = !DisplayedNextMethodDrillFollowUpNavigationLabel.IsEmpty()
|
||||
? DisplayedNextMethodDrillFollowUpNavigationLabel
|
||||
: TEXT("Next Drill Follow-Up");
|
||||
Surface.SelectedEntryIndex = SelectedMethodDrillFollowUpHistoryIndex;
|
||||
Surface.HistoryEntryCount = MethodDrillFollowUpHistoryEntries.Num();
|
||||
Surface.bHasSelectedEntry =
|
||||
SelectedEntry != nullptr && SelectedEntry->IsStructurallyValid();
|
||||
Surface.bSelectedEntryIsLatest =
|
||||
Surface.bHasSelectedEntry
|
||||
&& SelectedMethodDrillFollowUpHistoryIndex
|
||||
== MethodDrillFollowUpHistoryEntries.Num() - 1;
|
||||
Surface.bPreviousEnabled = bNavigationEnabled;
|
||||
Surface.bNextEnabled = bNavigationEnabled;
|
||||
Surface.bHasHistoryWeighting = Weighting.IsStructurallyValid();
|
||||
Surface.bPreferDrillFollowUp = Weighting.bPreferDrillFollowUp;
|
||||
Surface.bPreferCoachHandoff = Weighting.bPreferCoachHandoff;
|
||||
Surface.bHasUpstreamStructureSignal = Weighting.bHasUpstreamStructureSignal;
|
||||
Surface.OutcomePreferenceLine = !Weighting.IsStructurallyValid()
|
||||
? TEXT("no retained drill follow-up history yet")
|
||||
: (Weighting.bPreferDrillFollowUp
|
||||
? (Weighting.bUsedUpstreamNarrowStructureSignal
|
||||
? TEXT("retained drill-follow-up packet structure history favors staying narrow with drill follow-up")
|
||||
: TEXT("retained drill history favors staying narrow with drill follow-up"))
|
||||
: (Weighting.bPreferCoachHandoff
|
||||
? (Weighting.bUsedUpstreamBroadStructureSignal
|
||||
? TEXT("retained drill-follow-up packet structure history favors handing control back to broader coach guidance")
|
||||
: TEXT("retained drill history favors handing control back to broader coach guidance"))
|
||||
: TEXT("retained drill history is balanced")));
|
||||
|
||||
if (!Surface.bHasSelectedEntry)
|
||||
{
|
||||
Surface.SelectedEntryOrdinal = TEXT("none");
|
||||
Surface.RecordedAtUtc = TEXT("n/a");
|
||||
Surface.StageLabel = TEXT("n/a");
|
||||
Surface.DiagnosticStateLabel = TEXT("n/a");
|
||||
Surface.RecommendedReviewGradeLabel = TEXT("n/a");
|
||||
Surface.SuggestedModeLabel = TEXT("n/a");
|
||||
Surface.PacketStructureLabel = TEXT("n/a");
|
||||
Surface.PacketStanceLabel = TEXT("n/a");
|
||||
Surface.StatusLine =
|
||||
TEXT("Drill follow-up navigation: no retained drill follow-up outcomes recorded yet.");
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s: %s | %s: %s | preference: %s | selected latest: no"),
|
||||
*Surface.PreviousLabel,
|
||||
Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.NextLabel,
|
||||
Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.OutcomePreferenceLine);
|
||||
return Surface;
|
||||
}
|
||||
|
||||
Surface.SelectedEntryOrdinal = FString::Printf(
|
||||
TEXT("%d/%d"),
|
||||
SelectedMethodDrillFollowUpHistoryIndex + 1,
|
||||
MethodDrillFollowUpHistoryEntries.Num());
|
||||
Surface.RecordedAtUtc = SelectedEntry->RecordedAtUtc.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: SelectedEntry->RecordedAtUtc;
|
||||
Surface.StageLabel =
|
||||
SelectedEntry->StageLabel.IsEmpty() ? TEXT("n/a") : SelectedEntry->StageLabel;
|
||||
Surface.DiagnosticStateLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->DiagnosticState);
|
||||
Surface.RecommendedReviewGradeLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->RecommendedReviewGrade);
|
||||
Surface.SuggestedModeLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(
|
||||
SelectedEntry->SuggestedMode);
|
||||
Surface.PacketStructureLabel =
|
||||
SelectedEntry->PacketStructureLabel.IsEmpty()
|
||||
? TEXT("default")
|
||||
: SelectedEntry->PacketStructureLabel;
|
||||
Surface.PacketStanceLabel =
|
||||
SelectedEntry->PacketStanceLabel.IsEmpty()
|
||||
? TEXT("none")
|
||||
: SelectedEntry->PacketStanceLabel;
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Drill follow-up navigation: selected %s | Stage: %s | review %s | packet: %s | Recorded: %s"),
|
||||
*Surface.SelectedEntryOrdinal,
|
||||
*Surface.StageLabel,
|
||||
*Surface.RecommendedReviewGradeLabel,
|
||||
*Surface.PacketStructureLabel,
|
||||
*Surface.RecordedAtUtc);
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("%s: %s | %s: %s | state: %s | mode: %s | preference: %s | stance: %s | selected latest: %s"),
|
||||
*Surface.PreviousLabel,
|
||||
Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.NextLabel,
|
||||
Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"),
|
||||
*Surface.DiagnosticStateLabel,
|
||||
*Surface.SuggestedModeLabel,
|
||||
*Surface.OutcomePreferenceLine,
|
||||
*Surface.PacketStanceLabel,
|
||||
Surface.bSelectedEntryIsLatest ? TEXT("yes") : TEXT("no"));
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface
|
||||
UHyperTwistCoachDashboardWidget::GetSelectedHandoffHistoryInspectSurface() const
|
||||
{
|
||||
|
|
@ -24348,8 +24464,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
if (PreviousMethodDrillFollowUpHistoryButtonLabel != nullptr)
|
||||
{
|
||||
DisplayedPreviousMethodDrillFollowUpNavigationLabel = TEXT("Prev Drill Follow-Up");
|
||||
PreviousMethodDrillFollowUpHistoryButtonLabel->SetText(FText::FromString(
|
||||
TEXT("Prev Drill Follow-Up")));
|
||||
DisplayedPreviousMethodDrillFollowUpNavigationLabel));
|
||||
}
|
||||
if (PreviousMethodDrillFollowUpHistoryButton != nullptr)
|
||||
{
|
||||
|
|
@ -24358,8 +24475,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
if (NextMethodDrillFollowUpHistoryButtonLabel != nullptr)
|
||||
{
|
||||
DisplayedNextMethodDrillFollowUpNavigationLabel = TEXT("Next Drill Follow-Up");
|
||||
NextMethodDrillFollowUpHistoryButtonLabel->SetText(FText::FromString(
|
||||
TEXT("Next Drill Follow-Up")));
|
||||
DisplayedNextMethodDrillFollowUpNavigationLabel));
|
||||
}
|
||||
if (NextMethodDrillFollowUpHistoryButton != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -767,6 +767,10 @@ public:
|
|||
FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface
|
||||
GetSelectedMethodDrillFollowUpHistoryInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryNavigationInspectSurface
|
||||
GetDisplayedMethodDrillFollowUpHistoryNavigationInspectSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface
|
||||
GetSelectedHandoffHistoryInspectSurface() const;
|
||||
|
|
@ -2014,6 +2018,8 @@ private:
|
|||
FString DisplayedNextMethodDrillRecoveryNavigationLabel;
|
||||
FString DisplayedPreviousMethodDrillRecoveryMemoryNavigationLabel;
|
||||
FString DisplayedNextMethodDrillRecoveryMemoryNavigationLabel;
|
||||
FString DisplayedPreviousMethodDrillFollowUpNavigationLabel;
|
||||
FString DisplayedNextMethodDrillFollowUpNavigationLabel;
|
||||
FString DisplayedPreviousAttemptNavigationLabel;
|
||||
FString DisplayedNextAttemptNavigationLabel;
|
||||
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
|
||||
|
|
|
|||
|
|
@ -9298,6 +9298,93 @@ struct FHyperTwistTrainingCoachDashboardMethodDrillRecoveryMemoryHistoryNavigati
|
|||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryNavigationInspectSurface
|
||||
{
|
||||
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 PreviousLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString NextLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SelectedEntryOrdinal;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RecordedAtUtc;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StageLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DiagnosticStateLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RecommendedReviewGradeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SuggestedModeLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PacketStructureLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PacketStanceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString OutcomePreferenceLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SelectedEntryIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 HistoryEntryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasSelectedEntry = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bSelectedEntryIsLatest = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreviousEnabled = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNextEnabled = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasHistoryWeighting = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreferDrillFollowUp = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreferCoachHandoff = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasUpstreamStructureSignal = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasSelectedEntry
|
||||
|| bPreviousEnabled
|
||||
|| bNextEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 retained-history navigation/control lane and adds the method-drill recovery memory history navigation control inspect surface over already-retained upstream drill-recovery memory snapshots, so gameplay/Blueprint callers can inspect the live prev/next drill-memory labels, enablement posture, selected retained memory ordinal, and action/handoff/bias/latest-selection context without scraping button text or reopening retained-history derivation
|
||||
- the next clean move is to continue that same retained-history navigation/control lane and expose the method-drill follow-up history navigation control surface rather than drifting back into backend continuity or reopening the already-inspectable history detail seams
|
||||
- the latest landed bounded `Phase 4` packet stays on that same retained-history navigation/control lane and adds the method-drill follow-up history navigation control inspect surface over already-retained drill follow-up outcomes, so gameplay/Blueprint callers can inspect the live prev/next drill-follow-up labels, enablement posture, selected retained follow-up ordinal, and review/preference/latest-selection context without scraping button text or reopening retained-history derivation
|
||||
- the next clean move is to continue that same retained-history navigation/control lane and expose the handoff history navigation control surface rather than drifting back into backend continuity or reopening the already-inspectable history detail seams
|
||||
- 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
|
||||
|
||||
## Donor portfolio phase taxonomy
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
# HyperTwist Phase 4 dashboard method-drill follow-up history navigation control inspect surface packet
|
||||
|
||||
- bounded Phase `4` dashboard-consumer slice
|
||||
- date: `2026-05-10`
|
||||
|
||||
## Intent
|
||||
|
||||
Stay on the retained-history navigation/control lane inside `UHyperTwistCoachDashboardWidget` and expose the method-drill follow-up history navigation controls directly to gameplay and Blueprint callers.
|
||||
|
||||
## Why this packet exists
|
||||
|
||||
The dashboard already derived and displayed:
|
||||
|
||||
- the previous drill-follow-up-history button label
|
||||
- the next drill-follow-up-history button label
|
||||
- the enablement posture for both controls
|
||||
|
||||
But that control state still only surfaced through button text and button enabled state. Callers still had to inspect widget controls directly to understand whether retained drill-follow-up navigation is available and which retained follow-up outcome is currently selected.
|
||||
|
||||
## What changed
|
||||
|
||||
- added `FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryNavigationInspectSurface`
|
||||
- added `GetDisplayedMethodDrillFollowUpHistoryNavigationInspectSurface()`
|
||||
- retained the exact displayed previous/next drill-follow-up-history labels inside the widget so the new inspect surface reports 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 live previous/next drill-follow-up-history labels
|
||||
- whether drill-follow-up-history navigation is currently enabled
|
||||
- the selected retained follow-up ordinal, recorded time, stage label, diagnostic state, and review grade
|
||||
- the retained outcome-preference line, packet structure / stance posture, and latest-selection posture
|
||||
|
||||
without scraping button text or reopening retained-history derivation.
|
||||
|
||||
## Validation
|
||||
|
||||
- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln`
|
||||
- passed with `0 Warning(s), 0 Error(s)`
|
||||
|
||||
## Next clean slice
|
||||
|
||||
Stay on the retained-history navigation/control lane and expose the handoff history navigation control surface.
|
||||
Loading…
Add table
Reference in a new issue