diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 23b06db..7c50816 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -6371,6 +6371,110 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap QueueRecoveryWeighting.bHasMethodDrillMemorySignal; Entry.bUsedMethodDrillRecoveryMemoryForHandoff = bUsedMethodDrillRecoveryMemoryForHandoff; + auto SourceUsesStrongRetainedMethodDrillRecoveryPosture = [](const FString& SourceLabel) + { + return SourceLabel.Contains(TEXT("method-drill-recovery-posture-strong")); + }; + auto SourceUsesWeakRetainedMethodDrillRecoveryPosture = [](const FString& SourceLabel) + { + return SourceLabel.Contains(TEXT("method-drill-recovery-posture-weak")); + }; + auto SourceUsesGenericMethodDrillRecoveryMemory = [](const FString& SourceLabel) + { + return SourceLabel.Contains(TEXT("method-drill-recovery-strong")) + || SourceLabel.Contains(TEXT("method-drill-recovery-weak")) + || SourceLabel.Contains(TEXT("method-drill-recovery-memory-strong")) + || SourceLabel.Contains(TEXT("method-drill-recovery-memory-weak")); + }; + const FString GuidanceSourceLabel = CachedCoachPanelState.PreferredGuidanceSourceLabel; + const bool bStrongPacketPosture = + SourceUsesStrongRetainedMethodDrillRecoveryPosture(GuidanceSourceLabel) + || SourceUsesStrongRetainedMethodDrillRecoveryPosture( + Entry.PreferredRecoveryActionSourceLabel + ); + const bool bWeakPacketPosture = + SourceUsesWeakRetainedMethodDrillRecoveryPosture(GuidanceSourceLabel) + || SourceUsesWeakRetainedMethodDrillRecoveryPosture( + Entry.PreferredRecoveryActionSourceLabel + ); + const bool bGenericRecoveryPacket = + !bStrongPacketPosture + && !bWeakPacketPosture + && ( + SourceUsesGenericMethodDrillRecoveryMemory(GuidanceSourceLabel) + || SourceUsesGenericMethodDrillRecoveryMemory( + Entry.PreferredRecoveryActionSourceLabel + ) + ); + Entry.bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture = bStrongPacketPosture; + Entry.bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture = bWeakPacketPosture; + Entry.bGeneratedPacketUsedGenericMethodDrillRecoveryMemory = bGenericRecoveryPacket; + if (Entry.RecommendedHandoffKindLabel.Equals(TEXT("queue"), ESearchCase::IgnoreCase)) + { + if (const FHyperTwistTrainingCoachSessionQueueStateEntry* SelectedQueueEntry = + FindSelectedQueueEntry()) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("queue-entry"); + Entry.GeneratedGuidancePacketSourceLabel = SelectedQueueEntry->SourceLabel; + Entry.GeneratedGuidancePacketHeadline = SelectedQueueEntry->Headline; + Entry.GeneratedGuidancePacketActionLabel = + SelectedQueueEntry->Headline.IsEmpty() + ? SelectedQueueEntry->SourceLabel + : SelectedQueueEntry->Headline; + Entry.GeneratedGuidancePacketFocusCaseCount = SelectedQueueEntry->FocusCaseIds.Num(); + } + } + else if (Entry.RecommendedHandoffKindLabel.Equals(TEXT("follow-up"), ESearchCase::IgnoreCase)) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("follow-up-packet"); + Entry.GeneratedGuidancePacketSourceLabel = GuidanceSourceLabel; + Entry.GeneratedGuidancePacketHeadline = CachedCoachFollowUpBrief.Headline; + Entry.GeneratedGuidancePacketActionLabel = CachedCoachFollowUpBrief.PrimaryActionLabel; + Entry.GeneratedGuidancePacketFocusCaseCount = CachedCoachFollowUpBrief.FocusCaseIds.Num(); + } + else if (Entry.RecommendedHandoffKindLabel.Equals(TEXT("recommended"), ESearchCase::IgnoreCase)) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("recommended-brief"); + Entry.GeneratedGuidancePacketSourceLabel = GuidanceSourceLabel; + Entry.GeneratedGuidancePacketHeadline = CachedCoachBrief.Headline; + Entry.GeneratedGuidancePacketActionLabel = CachedCoachBrief.PrimaryActionLabel; + Entry.GeneratedGuidancePacketFocusCaseCount = CachedCoachBrief.FocusCaseIds.Num(); + } + if (Entry.GeneratedGuidancePacketKindLabel.IsEmpty()) + { + if (!CachedCoachFollowUpBrief.Headline.IsEmpty() + || !CachedCoachFollowUpBrief.PrimaryActionLabel.IsEmpty() + || CachedCoachFollowUpBrief.FocusCaseIds.Num() > 0) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("follow-up-packet"); + Entry.GeneratedGuidancePacketSourceLabel = GuidanceSourceLabel; + Entry.GeneratedGuidancePacketHeadline = CachedCoachFollowUpBrief.Headline; + Entry.GeneratedGuidancePacketActionLabel = CachedCoachFollowUpBrief.PrimaryActionLabel; + Entry.GeneratedGuidancePacketFocusCaseCount = CachedCoachFollowUpBrief.FocusCaseIds.Num(); + } + else if (const FHyperTwistTrainingCoachSessionQueueStateEntry* SelectedQueueEntry = + FindSelectedQueueEntry()) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("queue-entry"); + Entry.GeneratedGuidancePacketSourceLabel = SelectedQueueEntry->SourceLabel; + Entry.GeneratedGuidancePacketHeadline = SelectedQueueEntry->Headline; + Entry.GeneratedGuidancePacketActionLabel = + SelectedQueueEntry->Headline.IsEmpty() + ? SelectedQueueEntry->SourceLabel + : SelectedQueueEntry->Headline; + Entry.GeneratedGuidancePacketFocusCaseCount = SelectedQueueEntry->FocusCaseIds.Num(); + } + else if (!CachedCoachBrief.Headline.IsEmpty() + || !CachedCoachBrief.PrimaryActionLabel.IsEmpty() + || CachedCoachBrief.FocusCaseIds.Num() > 0) + { + Entry.GeneratedGuidancePacketKindLabel = TEXT("recommended-brief"); + Entry.GeneratedGuidancePacketSourceLabel = GuidanceSourceLabel; + Entry.GeneratedGuidancePacketHeadline = CachedCoachBrief.Headline; + Entry.GeneratedGuidancePacketActionLabel = CachedCoachBrief.PrimaryActionLabel; + Entry.GeneratedGuidancePacketFocusCaseCount = CachedCoachBrief.FocusCaseIds.Num(); + } + } if (!Entry.IsStructurallyValid()) { return; @@ -6400,6 +6504,22 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap == Entry.bStrongPressureDominant && MethodDrillRecoveryMemoryHistoryEntries.Last().bWeakPressureDominant == Entry.bWeakPressureDominant + && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketKindLabel + == Entry.GeneratedGuidancePacketKindLabel + && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketSourceLabel + == Entry.GeneratedGuidancePacketSourceLabel + && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketHeadline + == Entry.GeneratedGuidancePacketHeadline + && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketActionLabel + == Entry.GeneratedGuidancePacketActionLabel + && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketFocusCaseCount + == Entry.GeneratedGuidancePacketFocusCaseCount + && MethodDrillRecoveryMemoryHistoryEntries.Last().bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture + == Entry.bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture + && MethodDrillRecoveryMemoryHistoryEntries.Last().bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture + == Entry.bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture + && MethodDrillRecoveryMemoryHistoryEntries.Last().bGeneratedPacketUsedGenericMethodDrillRecoveryMemory + == Entry.bGeneratedPacketUsedGenericMethodDrillRecoveryMemory && MethodDrillRecoveryMemoryHistoryEntries.Last().bUsedMethodDrillRecoveryMemoryForRecovery == Entry.bUsedMethodDrillRecoveryMemoryForRecovery && MethodDrillRecoveryMemoryHistoryEntries.Last().bUsedMethodDrillRecoveryMemoryForHandoff @@ -8280,16 +8400,48 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() : (SelectedMethodDrillRecoveryMemoryHistoryEntry->bWeakPressureDominant ? HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::Weak : HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::None)); + const FString MethodDrillRecoveryMemoryGeneratedPacketKindLine = + SelectedMethodDrillRecoveryMemoryHistoryEntry == nullptr + || SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketKindLabel.IsEmpty() + ? TEXT("none") + : SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketKindLabel; + const FString MethodDrillRecoveryMemoryGeneratedPacketSourceLine = + SelectedMethodDrillRecoveryMemoryHistoryEntry == nullptr + || SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketSourceLabel.IsEmpty() + ? TEXT("n/a") + : HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketSourceLabel); + const FString MethodDrillRecoveryMemoryGeneratedPacketHeadlineLine = + SelectedMethodDrillRecoveryMemoryHistoryEntry == nullptr + || SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketHeadline.IsEmpty() + ? TEXT("n/a") + : SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketHeadline; + const FString MethodDrillRecoveryMemoryGeneratedPacketActionLine = + SelectedMethodDrillRecoveryMemoryHistoryEntry == nullptr + || SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketActionLabel.IsEmpty() + ? TEXT("n/a") + : SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketActionLabel; + const FString MethodDrillRecoveryMemoryGeneratedPacketStanceLine = + SelectedMethodDrillRecoveryMemoryHistoryEntry == nullptr + ? TEXT("n/a") + : (SelectedMethodDrillRecoveryMemoryHistoryEntry->bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture + ? TEXT("strong retained drill-recovery continuation") + : (SelectedMethodDrillRecoveryMemoryHistoryEntry->bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture + ? TEXT("weak retained drill-recovery redirect") + : (SelectedMethodDrillRecoveryMemoryHistoryEntry->bGeneratedPacketUsedGenericMethodDrillRecoveryMemory + ? TEXT("generic drill-recovery memory") + : TEXT("none")))); const FString MethodDrillRecoveryMemoryHistoryStatusLine = SelectedMethodDrillRecoveryMemoryHistoryEntry != nullptr && SelectedMethodDrillRecoveryMemoryHistoryEntry->IsStructurallyValid() ? FString::Printf( - TEXT("Drill recovery memory history: %d entries | selected %d/%d | %s | %s | Stance: %s | Recorded: %s"), + TEXT("Drill recovery memory history: %d entries | selected %d/%d | %s | %s | Packet: %s | Stance: %s | Recorded: %s"), MethodDrillRecoveryMemoryHistoryEntries.Num(), SelectedMethodDrillRecoveryMemoryHistoryIndex + 1, MethodDrillRecoveryMemoryHistoryEntries.Num(), *MethodDrillRecoveryMemoryActionLabel, *SelectedMethodDrillRecoveryMemoryHistoryEntry->RecommendedHandoffKindLabel, + *MethodDrillRecoveryMemoryGeneratedPacketKindLine, *HyperTwistCoachDashboardWidgetInternal::DescribeMethodDrillRecoveryMemoryBias( SelectedMethodDrillRecoveryMemoryHistoryBias), *SelectedMethodDrillRecoveryMemoryHistoryEntry->RecordedAtUtc) @@ -8298,7 +8450,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() SelectedMethodDrillRecoveryMemoryHistoryEntry != nullptr && SelectedMethodDrillRecoveryMemoryHistoryEntry->IsStructurallyValid() ? FString::Printf( - TEXT("Source: %s | Strong/weak/history %d/%d/%d avg %.1f | Dominant pressure: %s | Stance: %s | Recovery memory tipped: %s | Handoff memory tipped: %s | Recovery posture: %s | Handoff posture: %s"), + TEXT("Source: %s | Strong/weak/history %d/%d/%d avg %.1f | Dominant pressure: %s | Stance: %s | Recovery memory tipped: %s | Handoff memory tipped: %s | Packet kind: %s | Packet source: %s | Packet headline: %s | Packet action: %s | Packet focus %d | Packet stance: %s | Recovery posture: %s | Handoff posture: %s"), *MethodDrillRecoveryMemorySourceLine, SelectedMethodDrillRecoveryMemoryHistoryEntry->StrongMethodDrillRecoveryHistoryCount, SelectedMethodDrillRecoveryMemoryHistoryEntry->WeakMethodDrillRecoveryHistoryCount, @@ -8313,9 +8465,15 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() SelectedMethodDrillRecoveryMemoryHistoryEntry->bUsedMethodDrillRecoveryMemoryForHandoff ? TEXT("yes") : TEXT("no"), + *MethodDrillRecoveryMemoryGeneratedPacketKindLine, + *MethodDrillRecoveryMemoryGeneratedPacketSourceLine, + *MethodDrillRecoveryMemoryGeneratedPacketHeadlineLine, + *MethodDrillRecoveryMemoryGeneratedPacketActionLine, + SelectedMethodDrillRecoveryMemoryHistoryEntry->GeneratedGuidancePacketFocusCaseCount, + *MethodDrillRecoveryMemoryGeneratedPacketStanceLine, *SelectedMethodDrillRecoveryMemoryHistoryEntry->QueueRecoveryStatusLine, *SelectedMethodDrillRecoveryMemoryHistoryEntry->HandoffRecommendationStatusLine) - : TEXT("Drill recovery memory detail: retained upstream strong-vs-weak drill-recovery pressure, resulting recovery posture, and resulting handoff posture will accumulate here for later comparison."); + : TEXT("Drill recovery memory detail: retained upstream strong-vs-weak drill-recovery pressure, resulting generated queue-entry or follow-up packet lane, and resulting recovery/handoff posture will accumulate here for later comparison."); const FString PreferredDeferredRecoveryEntryId = FindFirstDeferredQueueEntryId(); const bool bCanApplyQueueRecovery = !bHasLiveAttemptTimer diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index aa6040a..4a5cc04 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -337,12 +337,20 @@ struct FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry FString RecommendedHandoffKindLabel; FString QueueRecoveryStatusLine; FString HandoffRecommendationStatusLine; + FString GeneratedGuidancePacketKindLabel; + FString GeneratedGuidancePacketSourceLabel; + FString GeneratedGuidancePacketHeadline; + FString GeneratedGuidancePacketActionLabel; + int32 GeneratedGuidancePacketFocusCaseCount = 0; int32 MethodDrillRecoveryHistoryCount = 0; int32 StrongMethodDrillRecoveryHistoryCount = 0; int32 WeakMethodDrillRecoveryHistoryCount = 0; float MethodDrillRecoveryAverageOutcomeScore = 0.0f; bool bStrongPressureDominant = false; bool bWeakPressureDominant = false; + bool bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture = false; + bool bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture = false; + bool bGeneratedPacketUsedGenericMethodDrillRecoveryMemory = false; bool bUsedMethodDrillRecoveryMemoryForRecovery = false; bool bUsedMethodDrillRecoveryMemoryForHandoff = false;