diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index d41144f..2ada3a6 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -33,6 +33,9 @@ namespace HyperTwistCoachDashboardWidgetInternal int32 QueueAcceptedDeltaCount = 0; int32 FollowUpAcceptedDeltaCount = 0; int32 RecommendedAcceptedDeltaCount = 0; + int32 DeferredOverflowQueueAcceptedDeltaCount = 0; + int32 DeferredOverflowFollowUpAcceptedDeltaCount = 0; + int32 DeferredOverflowRecommendedAcceptedDeltaCount = 0; int32 QueueRecommendationCount = 0; int32 FollowUpRecommendationCount = 0; int32 RecommendedRecommendationCount = 0; @@ -40,8 +43,10 @@ namespace HyperTwistCoachDashboardWidgetInternal int32 FollowUpScore = 0; int32 RecommendedScore = 0; EHandoffRecommendationKind PreferredKind = EHandoffRecommendationKind::None; + EHandoffRecommendationKind PreferredDeferredOverflowKind = EHandoffRecommendationKind::None; bool bHasAcceptedSignal = false; bool bHasRecommendationSignal = false; + bool bHasDeferredOverflowAcceptedSignal = false; bool bHasSignal = false; }; @@ -394,6 +399,12 @@ namespace HyperTwistCoachDashboardWidgetInternal bHasPreviousEntry ? PreviousEntry.AcceptedFollowUpHandoffCount : 0; const int32 PreviousRecommendedCount = bHasPreviousEntry ? PreviousEntry.AcceptedRecommendedHandoffCount : 0; + const int32 PreviousDeferredOverflowQueuedCount = + bHasPreviousEntry ? PreviousEntry.AcceptedDeferredOverflowQueuedHandoffCount : 0; + const int32 PreviousDeferredOverflowFollowUpCount = + bHasPreviousEntry ? PreviousEntry.AcceptedDeferredOverflowFollowUpHandoffCount : 0; + const int32 PreviousDeferredOverflowRecommendedCount = + bHasPreviousEntry ? PreviousEntry.AcceptedDeferredOverflowRecommendedHandoffCount : 0; const int32 QueuedDelta = FMath::Max(0, Entry.AcceptedQueuedHandoffCount - PreviousQueuedCount); @@ -401,6 +412,19 @@ namespace HyperTwistCoachDashboardWidgetInternal FMath::Max(0, Entry.AcceptedFollowUpHandoffCount - PreviousFollowUpCount); const int32 RecommendedDelta = FMath::Max(0, Entry.AcceptedRecommendedHandoffCount - PreviousRecommendedCount); + const int32 DeferredOverflowQueuedDelta = FMath::Max( + 0, + Entry.AcceptedDeferredOverflowQueuedHandoffCount - PreviousDeferredOverflowQueuedCount + ); + const int32 DeferredOverflowFollowUpDelta = FMath::Max( + 0, + Entry.AcceptedDeferredOverflowFollowUpHandoffCount - PreviousDeferredOverflowFollowUpCount + ); + const int32 DeferredOverflowRecommendedDelta = FMath::Max( + 0, + Entry.AcceptedDeferredOverflowRecommendedHandoffCount + - PreviousDeferredOverflowRecommendedCount + ); if (QueuedDelta > 0) { @@ -420,6 +444,27 @@ namespace HyperTwistCoachDashboardWidgetInternal Bias.RecommendedScore += RecommendedDelta * 3; Bias.bHasAcceptedSignal = true; } + if (DeferredOverflowQueuedDelta > 0) + { + Bias.DeferredOverflowQueueAcceptedDeltaCount += DeferredOverflowQueuedDelta; + Bias.QueueScore += DeferredOverflowQueuedDelta * 2; + Bias.bHasAcceptedSignal = true; + Bias.bHasDeferredOverflowAcceptedSignal = true; + } + if (DeferredOverflowFollowUpDelta > 0) + { + Bias.DeferredOverflowFollowUpAcceptedDeltaCount += DeferredOverflowFollowUpDelta; + Bias.FollowUpScore += DeferredOverflowFollowUpDelta * 2; + Bias.bHasAcceptedSignal = true; + Bias.bHasDeferredOverflowAcceptedSignal = true; + } + if (DeferredOverflowRecommendedDelta > 0) + { + Bias.DeferredOverflowRecommendedAcceptedDeltaCount += DeferredOverflowRecommendedDelta; + Bias.RecommendedScore += DeferredOverflowRecommendedDelta * 2; + Bias.bHasAcceptedSignal = true; + Bias.bHasDeferredOverflowAcceptedSignal = true; + } if (Entry.RecommendedHandoffKindLabel.Equals(TEXT("queue"), ESearchCase::IgnoreCase)) { @@ -477,6 +522,32 @@ namespace HyperTwistCoachDashboardWidgetInternal EHandoffRecommendationKind::Recommended, Bias.RecommendedScore, Bias.RecommendedAcceptedDeltaCount); + int32 BestDeferredOverflowCount = 0; + const auto ConsiderDeferredOverflowKind = + [&BestDeferredOverflowCount, &Bias]( + const EHandoffRecommendationKind Kind, + const int32 Count) + { + if (Count <= 0) + { + return; + } + + if (Count > BestDeferredOverflowCount) + { + BestDeferredOverflowCount = Count; + Bias.PreferredDeferredOverflowKind = Kind; + } + }; + ConsiderDeferredOverflowKind( + EHandoffRecommendationKind::Queue, + Bias.DeferredOverflowQueueAcceptedDeltaCount); + ConsiderDeferredOverflowKind( + EHandoffRecommendationKind::FollowUp, + Bias.DeferredOverflowFollowUpAcceptedDeltaCount); + ConsiderDeferredOverflowKind( + EHandoffRecommendationKind::Recommended, + Bias.DeferredOverflowRecommendedAcceptedDeltaCount); Bias.bHasSignal = Bias.PreferredKind != EHandoffRecommendationKind::None; return Bias; @@ -4410,6 +4481,12 @@ void UHyperTwistCoachDashboardWidget::RecordCoachHandoffHistorySnapshot( CachedCoachQueueExecutionSummary.StartedFollowUpHandoffEventCount; Entry.AcceptedRecommendedHandoffCount = CachedCoachQueueExecutionSummary.StartedRecommendedHandoffEventCount; + Entry.AcceptedDeferredOverflowQueuedHandoffCount = + CachedCoachQueueExecutionSummary.StartedDeferredOverflowQueuedHandoffEventCount; + Entry.AcceptedDeferredOverflowFollowUpHandoffCount = + CachedCoachQueueExecutionSummary.StartedDeferredOverflowFollowUpHandoffEventCount; + Entry.AcceptedDeferredOverflowRecommendedHandoffCount = + CachedCoachQueueExecutionSummary.StartedDeferredOverflowRecommendedHandoffEventCount; Entry.ClosureContinuationBias = ClosureContinuationBias; Entry.ClosureSuppressionBias = ClosureSuppressionBias; Entry.bQueueReady = bQueueReady; @@ -4441,6 +4518,12 @@ void UHyperTwistCoachDashboardWidget::RecordCoachHandoffHistorySnapshot( == Entry.AcceptedFollowUpHandoffCount && HandoffHistoryEntries.Last().AcceptedRecommendedHandoffCount == Entry.AcceptedRecommendedHandoffCount + && HandoffHistoryEntries.Last().AcceptedDeferredOverflowQueuedHandoffCount + == Entry.AcceptedDeferredOverflowQueuedHandoffCount + && HandoffHistoryEntries.Last().AcceptedDeferredOverflowFollowUpHandoffCount + == Entry.AcceptedDeferredOverflowFollowUpHandoffCount + && HandoffHistoryEntries.Last().AcceptedDeferredOverflowRecommendedHandoffCount + == Entry.AcceptedDeferredOverflowRecommendedHandoffCount && HandoffHistoryEntries.Last().ClosureContinuationBias == Entry.ClosureContinuationBias && HandoffHistoryEntries.Last().ClosureSuppressionBias @@ -4929,6 +5012,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() const bool bRecommendedReadyForHandoff = CachedCoachPanelState.bCanStartCoachRecommendedRun; bool bHandoffRecommendationUsedHistory = false; + bool bHandoffRecommendationUsedDeferredOverflowHistory = false; if (!bCanUseCoachHandoff) { CoachHandoffRecommendationStatusLine = @@ -4943,7 +5027,26 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() if (HandoffClosureBias.bHasSignal && HandoffClosureBias.ContinuationBias >= HandoffClosureBias.SuppressionBias + 2) { - if (HandoffHistoryBias.PreferredKind + if (HandoffHistoryBias.PreferredDeferredOverflowKind + == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp + && bFollowUpReadyForHandoff) + { + HandoffRecommendationKind = + HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp; + bHandoffRecommendationUsedHistory = true; + bHandoffRecommendationUsedDeferredOverflowHistory = true; + } + else if (HandoffHistoryBias.PreferredDeferredOverflowKind + == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue + && bQueueReadyForHandoff + && bQueueLooksFollowUpOrRecovery) + { + HandoffRecommendationKind = + HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue; + bHandoffRecommendationUsedHistory = true; + bHandoffRecommendationUsedDeferredOverflowHistory = true; + } + else if (HandoffHistoryBias.PreferredKind == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp && bFollowUpReadyForHandoff) { @@ -4974,7 +5077,26 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() else if (HandoffClosureBias.bHasSignal && HandoffClosureBias.SuppressionBias >= HandoffClosureBias.ContinuationBias + 2) { - if (HandoffHistoryBias.PreferredKind + if (HandoffHistoryBias.PreferredDeferredOverflowKind + == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended + && bRecommendedReadyForHandoff) + { + HandoffRecommendationKind = + HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended; + bHandoffRecommendationUsedHistory = true; + bHandoffRecommendationUsedDeferredOverflowHistory = true; + } + else if (HandoffHistoryBias.PreferredDeferredOverflowKind + == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue + && bQueueReadyForHandoff + && bQueueLooksRecommendedOrPrimary) + { + HandoffRecommendationKind = + HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue; + bHandoffRecommendationUsedHistory = true; + bHandoffRecommendationUsedDeferredOverflowHistory = true; + } + else if (HandoffHistoryBias.PreferredKind == HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended && bRecommendedReadyForHandoff) { @@ -5074,7 +5196,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() } CoachHandoffRecommendationDetailLine = FString::Printf( - TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"), + TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s%s | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | deferred-overflow accepted q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"), HandoffClosureBias.ContinuationBias, HandoffClosureBias.SuppressionBias, bQueueReadyForHandoff ? TEXT("yes") : TEXT("no"), @@ -5086,6 +5208,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() bDashboardHandoffMemorySource ? TEXT(" | Accepted dashboard handoffs are actively reinforcing this recommendation.") : TEXT(""), + bHandoffRecommendationUsedDeferredOverflowHistory + ? TEXT(" | Deferred-overflow handoff history directly tipped the recommendation.") + : TEXT(""), bHandoffRecommendationUsedHistory ? TEXT(" | Retained handoff history actively weighted this recommendation.") : TEXT(""), @@ -5106,6 +5231,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() HandoffHistoryBias.QueueAcceptedDeltaCount, HandoffHistoryBias.FollowUpAcceptedDeltaCount, HandoffHistoryBias.RecommendedAcceptedDeltaCount, + HandoffHistoryBias.DeferredOverflowQueueAcceptedDeltaCount, + HandoffHistoryBias.DeferredOverflowFollowUpAcceptedDeltaCount, + HandoffHistoryBias.DeferredOverflowRecommendedAcceptedDeltaCount, HandoffHistoryBias.QueueRecommendationCount, HandoffHistoryBias.FollowUpRecommendationCount, HandoffHistoryBias.RecommendedRecommendationCount @@ -5167,10 +5295,13 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() const FString HandoffHistoryDetailLine = SelectedHandoffHistoryEntry != nullptr ? FString::Printf( - TEXT("Accepted queued/follow-up/recommended: %d/%d/%d | queue source: %s | preferred lane: %s | memory source: %s | recovery action: %s | recovery source: %s | closure continuation bias %d | closure suppression bias %d | readiness queue/follow-up/recommended: %s/%s/%s || %s"), + TEXT("Accepted queued/follow-up/recommended: %d/%d/%d | deferred-overflow queued/follow-up/recommended: %d/%d/%d | queue source: %s | preferred lane: %s | memory source: %s | recovery action: %s | recovery source: %s | closure continuation bias %d | closure suppression bias %d | readiness queue/follow-up/recommended: %s/%s/%s || %s"), SelectedHandoffHistoryEntry->AcceptedQueuedHandoffCount, SelectedHandoffHistoryEntry->AcceptedFollowUpHandoffCount, SelectedHandoffHistoryEntry->AcceptedRecommendedHandoffCount, + SelectedHandoffHistoryEntry->AcceptedDeferredOverflowQueuedHandoffCount, + SelectedHandoffHistoryEntry->AcceptedDeferredOverflowFollowUpHandoffCount, + SelectedHandoffHistoryEntry->AcceptedDeferredOverflowRecommendedHandoffCount, SelectedHandoffHistoryEntry->QueueSourceLabel.IsEmpty() ? TEXT("n/a") : *SelectedHandoffHistoryEntry->QueueSourceLabel, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp index 63eb9d3..933a4f5 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp @@ -375,9 +375,13 @@ namespace HyperTwistTrainingRepositoryLibraryInternal } } const int32 WeightedFollowUpRecoverySignal = - ExplicitFollowUpRecoverySignal + ExplicitFollowUpHandoffSignal; + ExplicitFollowUpRecoverySignal + + ExplicitFollowUpHandoffSignal + + ExplicitDeferredOverflowFollowUpHandoffSignal; const int32 WeightedRecommendedRecoverySignal = - ExplicitRecommendedRecoverySignal + ExplicitRecommendedHandoffSignal; + ExplicitRecommendedRecoverySignal + + ExplicitRecommendedHandoffSignal + + ExplicitDeferredOverflowRecommendedHandoffSignal; const bool bQueueHistoryPrefersFollowUp = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp @@ -401,7 +405,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal + (QueueExecutionSummary.bHasArchiveAwareFriction ? 1.0f : 0.0f) + FMath::Min(static_cast(QueueExecutionSummary.CompletedEventCount), 3.0f) + FMath::Min(static_cast(QueueExecutionSummary.ManualRescheduleEventCount) * 0.5f, 2.0f) - + static_cast(ExplicitQueuedHandoffSignal); + + static_cast(ExplicitQueuedHandoffSignal) + + static_cast(ExplicitDeferredOverflowQueuedHandoffSignal); if (PromoteRecoveryActionPressure > 0.0f || LaunchRecoveryActionPressure > 0.0f) { if (PromoteRecoveryActionPressure > LaunchRecoveryActionPressure) @@ -5793,9 +5798,13 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der } } const int32 WeightedFollowUpRecoverySignal = - ExplicitFollowUpRecoverySignal + ExplicitFollowUpHandoffSignal; + ExplicitFollowUpRecoverySignal + + ExplicitFollowUpHandoffSignal + + ExplicitDeferredOverflowFollowUpHandoffSignal; const int32 WeightedRecommendedRecoverySignal = - ExplicitRecommendedRecoverySignal + ExplicitRecommendedHandoffSignal; + ExplicitRecommendedRecoverySignal + + ExplicitRecommendedHandoffSignal + + ExplicitDeferredOverflowRecommendedHandoffSignal; const bool bQueueHistoryPrefersFollowUp = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp @@ -5819,7 +5828,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der + (QueueExecutionSummary.bHasArchiveAwareFriction ? 1.0f : 0.0f) + FMath::Min(static_cast(QueueExecutionSummary.CompletedEventCount), 3.0f) + FMath::Min(static_cast(QueueExecutionSummary.ManualRescheduleEventCount) * 0.5f, 2.0f) - + static_cast(ExplicitQueuedHandoffSignal); + + static_cast(ExplicitQueuedHandoffSignal) + + static_cast(ExplicitDeferredOverflowQueuedHandoffSignal); if (PromoteRecoveryActionPressure > 0.0f || LaunchRecoveryActionPressure > 0.0f) { if (PromoteRecoveryActionPressure > LaunchRecoveryActionPressure) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index 270fc97..ffc5566 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -243,6 +243,9 @@ struct FHyperTwistCoachDashboardHandoffHistoryEntry int32 AcceptedQueuedHandoffCount = 0; int32 AcceptedFollowUpHandoffCount = 0; int32 AcceptedRecommendedHandoffCount = 0; + int32 AcceptedDeferredOverflowQueuedHandoffCount = 0; + int32 AcceptedDeferredOverflowFollowUpHandoffCount = 0; + int32 AcceptedDeferredOverflowRecommendedHandoffCount = 0; int32 ClosureContinuationBias = 0; int32 ClosureSuppressionBias = 0; bool bQueueReady = false;