Feed drill recovery memory history upstream

This commit is contained in:
axiomlogicnexus 2026-04-29 04:47:50 +02:00
parent 1b55663331
commit 6eaff4e00f
5 changed files with 465 additions and 17 deletions

View file

@ -28,6 +28,13 @@ namespace HyperTwistCoachDashboardWidgetInternal
Recommended
};
enum class EMethodDrillRecoveryMemoryBias : uint8
{
None,
Strong,
Weak
};
struct FHandoffHistoryDashboardBias
{
int32 QueueAcceptedDeltaCount = 0;
@ -150,6 +157,30 @@ namespace HyperTwistCoachDashboardWidgetInternal
{
return TEXT("accepted drill-driven recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-queued"))
{
return TEXT("accepted strong drill-recovery-memory queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-follow-up"))
{
return TEXT("accepted strong drill-recovery-memory follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-recommended"))
{
return TEXT("accepted strong drill-recovery-memory recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-queued"))
{
return TEXT("accepted weak drill-recovery-memory queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-follow-up"))
{
return TEXT("accepted weak drill-recovery-memory follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-recommended"))
{
return TEXT("accepted weak drill-recovery-memory recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-queued"))
{
return TEXT("accepted queued handoff history");
@ -206,6 +237,30 @@ namespace HyperTwistCoachDashboardWidgetInternal
{
return TEXT("accepted drill-driven recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued"))
{
return TEXT("accepted strong drill-recovery-memory queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up"))
{
return TEXT("accepted strong drill-recovery-memory follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended"))
{
return TEXT("accepted strong drill-recovery-memory recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued"))
{
return TEXT("accepted weak drill-recovery-memory queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up"))
{
return TEXT("accepted weak drill-recovery-memory follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended"))
{
return TEXT("accepted weak drill-recovery-memory recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued"))
{
return TEXT("accepted deferred-overflow queued outcome handoff");
@ -262,6 +317,14 @@ namespace HyperTwistCoachDashboardWidgetInternal
{
return TEXT("weak drill-driven recovery history");
}
if (SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-strong"))
{
return TEXT("successful retained drill-recovery-memory history");
}
if (SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-weak"))
{
return TEXT("weak retained drill-recovery-memory history");
}
return SourceLabel.IsEmpty() ? TEXT("n/a") : SourceLabel;
}
@ -283,8 +346,38 @@ namespace HyperTwistCoachDashboardWidgetInternal
FString DashboardHandoffSourceLabel(
const EHyperTwistTrainingCoachHandoffKind HandoffKind,
const bool bDeferredFirstSuppressionDriven,
const bool bMethodDrillDriven = false)
const bool bMethodDrillDriven = false,
const EMethodDrillRecoveryMemoryBias MethodDrillRecoveryMemoryBias =
EMethodDrillRecoveryMemoryBias::None)
{
if (MethodDrillRecoveryMemoryBias == EMethodDrillRecoveryMemoryBias::Strong)
{
switch (HandoffKind)
{
case EHyperTwistTrainingCoachHandoffKind::Queue:
return TEXT("dashboard-handoff-method-drill-recovery-strong-queued");
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
return TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up");
case EHyperTwistTrainingCoachHandoffKind::Recommended:
return TEXT("dashboard-handoff-method-drill-recovery-strong-recommended");
default:
return FString();
}
}
if (MethodDrillRecoveryMemoryBias == EMethodDrillRecoveryMemoryBias::Weak)
{
switch (HandoffKind)
{
case EHyperTwistTrainingCoachHandoffKind::Queue:
return TEXT("dashboard-handoff-method-drill-recovery-weak-queued");
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
return TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up");
case EHyperTwistTrainingCoachHandoffKind::Recommended:
return TEXT("dashboard-handoff-method-drill-recovery-weak-recommended");
default:
return FString();
}
}
if (bMethodDrillDriven)
{
switch (HandoffKind)
@ -783,6 +876,49 @@ namespace HyperTwistCoachDashboardWidgetInternal
}
}
}
EMethodDrillRecoveryMemoryBias DeriveRetainedMethodDrillRecoveryMemoryBias(
const TArray<FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry>& Entries,
const bool bForRecovery)
{
int32 StrongCount = 0;
int32 WeakCount = 0;
for (const FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry& Entry : Entries)
{
if (!Entry.IsStructurallyValid())
{
continue;
}
const bool bEntryApplies = bForRecovery
? Entry.bUsedMethodDrillRecoveryMemoryForRecovery
: Entry.bUsedMethodDrillRecoveryMemoryForHandoff;
if (!bEntryApplies)
{
continue;
}
if (Entry.bStrongPressureDominant)
{
StrongCount += 1;
}
else if (Entry.bWeakPressureDominant)
{
WeakCount += 1;
}
}
if (StrongCount > WeakCount && StrongCount > 0)
{
return EMethodDrillRecoveryMemoryBias::Strong;
}
if (WeakCount > StrongCount && WeakCount > 0)
{
return EMethodDrillRecoveryMemoryBias::Weak;
}
return EMethodDrillRecoveryMemoryBias::None;
}
}
void UHyperTwistCoachDashboardWidget::NativeConstruct()
@ -954,6 +1090,12 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture()
&& (QueueRecoveryWeighting.PreferredActionKind
== FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::LaunchRecovery
|| (!QueueRecoveryWeighting.IsStructurallyValid() && bUpstreamPrefersLaunchRecovery));
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
RetainedMethodDrillRecoveryMemoryBias =
HyperTwistCoachDashboardWidgetInternal::DeriveRetainedMethodDrillRecoveryMemoryBias(
MethodDrillRecoveryMemoryHistoryEntries,
true
);
auto StartRunAndRefresh = [this](const FHyperTwistTrainingRunState& RunState)
{
@ -996,7 +1138,11 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture()
return bSucceeded;
};
auto BuildRecoveryLaunchSourceLabel =
[bHasDeferredFirstSuppressionSignal, bUseMethodDrillRecoverySignal](
[
bHasDeferredFirstSuppressionSignal,
bUseMethodDrillRecoverySignal,
RetainedMethodDrillRecoveryMemoryBias
](
const EHyperTwistTrainingCoachHandoffKind HandoffKind)
{
if (bHasDeferredFirstSuppressionSignal)
@ -1011,7 +1157,9 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture()
return HyperTwistCoachDashboardWidgetInternal::DashboardHandoffSourceLabel(
HandoffKind,
false,
true
RetainedMethodDrillRecoveryMemoryBias
== HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::None,
RetainedMethodDrillRecoveryMemoryBias
);
}
@ -4457,6 +4605,12 @@ FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::BuildSelectedGuidancePr
FString UHyperTwistCoachDashboardWidget::ResolveDashboardHandoffStartActionSourceLabel(
const EHyperTwistTrainingCoachHandoffKind HandoffKind) const
{
if (!DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel.IsEmpty()
&& DisplayedCoachHandoffRecommendationKind == HandoffKind)
{
return DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel;
}
const bool bUseDeferredFirstSuppressionLabel =
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal
&& DisplayedCoachHandoffRecommendationKind == HandoffKind;
@ -6548,6 +6702,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
DisplayedCoachHandoffRecommendationKind = EHyperTwistTrainingCoachHandoffKind::None;
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false;
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false;
DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel.Reset();
FString CoachHandoffRecommendationStatusLine;
FString CoachHandoffRecommendationDetailLine;
const bool bQueueReadyForHandoff = CachedCoachPanelState.bCanStartQueuedRun;
@ -6571,6 +6726,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
&& CachedCoachPanelState.WeakMethodDrillRecoveryHistoryCount
> CachedCoachPanelState.StrongMethodDrillRecoveryHistoryCount
&& CachedCoachPanelState.MethodDrillRecoveryAverageOutcomeScore <= 45.0f;
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
RetainedMethodDrillRecoveryMemoryHandoffBias =
HyperTwistCoachDashboardWidgetInternal::DeriveRetainedMethodDrillRecoveryMemoryBias(
MethodDrillRecoveryMemoryHistoryEntries,
false
);
if (!bCanUseCoachHandoff)
{
CoachHandoffRecommendationStatusLine =
@ -6969,6 +7130,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting =
bHandoffRecommendationUsedMethodDrillWeighting
|| bHandoffRecommendationUsedMethodDrillRecoveryMemory;
if (bHandoffRecommendationUsedMethodDrillRecoveryMemory
&& RetainedMethodDrillRecoveryMemoryHandoffBias
!= HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::None)
{
DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel =
HyperTwistCoachDashboardWidgetInternal::DashboardHandoffSourceLabel(
DisplayedCoachHandoffRecommendationKind,
false,
false,
RetainedMethodDrillRecoveryMemoryHandoffBias
);
}
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%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 | deferred-first recommendation q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"),

View file

@ -41,14 +41,22 @@ namespace HyperTwistTrainingCoachLibraryInternal
return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-"))
|| SourceLabel == TEXT("dashboard-handoff-method-drill-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended");
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended");
}
bool IsMethodDrillRecoveryMemorySource(const FString& SourceLabel)
{
return IsMethodDrillDashboardHandoffSource(SourceLabel)
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-strong")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-weak");
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-weak")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-strong")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-weak");
}
FString DescribeCoachHandoffKind(const EHyperTwistTrainingCoachHandoffKind HandoffKind)
@ -122,6 +130,30 @@ namespace HyperTwistTrainingCoachLibraryInternal
{
return TEXT("accepted drill-driven recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-queued"))
{
return TEXT("accepted strong drill-recovery-memory queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-follow-up"))
{
return TEXT("accepted strong drill-recovery-memory follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-strong-recommended"))
{
return TEXT("accepted strong drill-recovery-memory recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-queued"))
{
return TEXT("accepted weak drill-recovery-memory queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-follow-up"))
{
return TEXT("accepted weak drill-recovery-memory follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recovery-weak-recommended"))
{
return TEXT("accepted weak drill-recovery-memory recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-queue-follow-up"))
{
return TEXT("queue follow-up recovery memory");
@ -166,6 +198,30 @@ namespace HyperTwistTrainingCoachLibraryInternal
{
return TEXT("accepted drill-driven recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued"))
{
return TEXT("accepted strong drill-recovery-memory queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up"))
{
return TEXT("accepted strong drill-recovery-memory follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended"))
{
return TEXT("accepted strong drill-recovery-memory recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued"))
{
return TEXT("accepted weak drill-recovery-memory queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up"))
{
return TEXT("accepted weak drill-recovery-memory follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended"))
{
return TEXT("accepted weak drill-recovery-memory recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued"))
{
return TEXT("accepted deferred-overflow queued outcome handoff");
@ -222,6 +278,14 @@ namespace HyperTwistTrainingCoachLibraryInternal
{
return TEXT("weak drill-driven recovery history");
}
if (SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-strong"))
{
return TEXT("successful retained drill-recovery-memory history");
}
if (SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-weak"))
{
return TEXT("weak retained drill-recovery-memory history");
}
return SourceLabel.IsEmpty() ? TEXT("none") : SourceLabel;
}

View file

@ -76,13 +76,35 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
return SourceLabel == TEXT("dashboard-handoff-method-drill-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended")
|| SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-"));
}
bool IsStrongMethodDrillRecoveryDashboardHandoffSource(const FString& SourceLabel)
{
return SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended");
}
bool IsWeakMethodDrillRecoveryDashboardHandoffSource(const FString& SourceLabel)
{
return SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended");
}
bool IsMethodDrillRecoveryCoachMemorySource(const FString& SourceLabel)
{
return SourceLabel == TEXT("coach-memory-method-drill-recovery-strong")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-weak");
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-weak")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-strong")
|| SourceLabel == TEXT("coach-memory-method-drill-recovery-memory-weak");
}
EHyperTwistTrainingCoachHandoffKind DashboardHandoffKindFromSourceLabel(const FString& SourceLabel)
@ -90,21 +112,27 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
if (SourceLabel == TEXT("dashboard-handoff-queued")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-queued"))
|| SourceLabel == TEXT("dashboard-handoff-method-drill-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-queued"))
{
return EHyperTwistTrainingCoachHandoffKind::Queue;
}
if (SourceLabel == TEXT("dashboard-handoff-follow-up")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up"))
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-follow-up"))
{
return EHyperTwistTrainingCoachHandoffKind::FollowUp;
}
if (SourceLabel == TEXT("dashboard-handoff-recommended")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-recommended")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended"))
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-strong-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recovery-weak-recommended"))
{
return EHyperTwistTrainingCoachHandoffKind::Recommended;
}
@ -526,6 +554,24 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
0,
MethodDrillRecoveryStartedCount - MethodDrillRecoveryCompletedCount
);
const int32 StrongMethodDrillRecoveryMemoryStartedCount =
QueueExecutionSummary.StartedStrongMethodDrillRecoveryMemoryHandoffEventCount;
const int32 StrongMethodDrillRecoveryMemoryCompletedCount =
QueueExecutionSummary.CompletedStrongMethodDrillRecoveryMemoryHandoffEventCount;
const int32 StrongMethodDrillRecoveryMemoryOutstandingCount = FMath::Max(
0,
StrongMethodDrillRecoveryMemoryStartedCount
- StrongMethodDrillRecoveryMemoryCompletedCount
);
const int32 WeakMethodDrillRecoveryMemoryStartedCount =
QueueExecutionSummary.StartedWeakMethodDrillRecoveryMemoryHandoffEventCount;
const int32 WeakMethodDrillRecoveryMemoryCompletedCount =
QueueExecutionSummary.CompletedWeakMethodDrillRecoveryMemoryHandoffEventCount;
const int32 WeakMethodDrillRecoveryMemoryOutstandingCount = FMath::Max(
0,
WeakMethodDrillRecoveryMemoryStartedCount
- WeakMethodDrillRecoveryMemoryCompletedCount
);
if (MethodDrillRecoveryStartedCount > 0)
{
Snapshot.MethodDrillRecoveryHistoryCount += MethodDrillRecoveryStartedCount;
@ -559,6 +605,24 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
1,
3)
: 0;
const int32 RetainedMethodDrillRecoveryLaunchBias =
StrongMethodDrillRecoveryMemoryStartedCount > 0
? FMath::Clamp(
(StrongMethodDrillRecoveryMemoryCompletedCount * 2)
- StrongMethodDrillRecoveryMemoryStartedCount
+ 1,
1,
3)
: 0;
const int32 RetainedMethodDrillRecoveryPromoteBias =
WeakMethodDrillRecoveryMemoryStartedCount > 0
? FMath::Clamp(
(WeakMethodDrillRecoveryMemoryOutstandingCount * 2)
- WeakMethodDrillRecoveryMemoryCompletedCount
+ 1,
1,
3)
: 0;
if (ExplicitQueuedHandoffSignal > 0
|| ExplicitFollowUpHandoffSignal > 0
|| ExplicitRecommendedHandoffSignal > 0)
@ -606,14 +670,16 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
+ ExplicitDeferredFirstFollowUpHandoffSignal
+ ExplicitMethodDrillQueuedHandoffSignal
+ ExplicitMethodDrillFollowUpHandoffSignal
+ MethodDrillRecoveryLaunchBias;
+ MethodDrillRecoveryLaunchBias
+ RetainedMethodDrillRecoveryLaunchBias;
const int32 WeightedRecommendedRecoverySignal =
ExplicitRecommendedRecoverySignal
+ ExplicitRecommendedHandoffSignal
+ ExplicitDeferredOverflowRecommendedHandoffSignal
+ ExplicitDeferredFirstRecommendedHandoffSignal
+ ExplicitMethodDrillRecommendedHandoffSignal
+ MethodDrillRecoveryPromoteBias;
+ MethodDrillRecoveryPromoteBias
+ RetainedMethodDrillRecoveryPromoteBias;
const bool bQueueHistoryPrefersFollowUp =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
@ -630,7 +696,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
+ FMath::Min(static_cast<float>(QueueExecutionSummary.PromotedEventCount), 3.0f)
+ (DominantDeferredLane != EHyperTwistTrainingCoachGuidanceLane::None ? 1.5f : 0.0f)
- (QueueExecutionSummary.bHasCompletionGap ? 1.0f : 0.0f)
+ (static_cast<float>(MethodDrillRecoveryPromoteBias) * 1.5f);
+ (static_cast<float>(MethodDrillRecoveryPromoteBias) * 1.5f)
+ (static_cast<float>(RetainedMethodDrillRecoveryPromoteBias) * 1.75f);
const float LaunchRecoveryActionPressure =
(QueueExecutionSummary.bHasCompletionGap ? 4.0f : 0.0f)
+ (QueueExecutionSummary.bHasBlockedFollowUpFriction ? 2.5f : 0.0f)
@ -645,7 +712,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
+ static_cast<float>(ExplicitMethodDrillQueuedHandoffSignal)
+ static_cast<float>(ExplicitMethodDrillFollowUpHandoffSignal)
+ static_cast<float>(ExplicitMethodDrillRecommendedHandoffSignal) * 0.5f
+ (static_cast<float>(MethodDrillRecoveryLaunchBias) * 1.75f);
+ (static_cast<float>(MethodDrillRecoveryLaunchBias) * 1.75f)
+ (static_cast<float>(RetainedMethodDrillRecoveryLaunchBias) * 2.0f);
if (PromoteRecoveryActionPressure > 0.0f || LaunchRecoveryActionPressure > 0.0f)
{
if (PromoteRecoveryActionPressure > LaunchRecoveryActionPressure)
@ -674,6 +742,29 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
}
}
if (Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::LaunchRecovery
&& RetainedMethodDrillRecoveryLaunchBias > 0
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillRecoveryCoachMemorySource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)))
{
Snapshot.PreferredQueueRecoveryActionSourceLabel =
TEXT("coach-memory-method-drill-recovery-memory-strong");
}
else if (Snapshot.PreferredQueueRecoveryAction
== EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred
&& RetainedMethodDrillRecoveryPromoteBias > 0
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillRecoveryCoachMemorySource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)))
{
Snapshot.PreferredQueueRecoveryActionSourceLabel =
TEXT("coach-memory-method-drill-recovery-memory-weak");
}
else if (Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::LaunchRecovery
&& bStrongMethodDrillRecoveryHistory
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
@ -716,10 +807,18 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
{
Snapshot.FollowUpGuidanceContinueBias += MethodDrillRecoveryLaunchBias;
}
if (RetainedMethodDrillRecoveryLaunchBias > 0)
{
Snapshot.FollowUpGuidanceContinueBias += RetainedMethodDrillRecoveryLaunchBias;
}
if (MethodDrillRecoveryPromoteBias > 0)
{
Snapshot.RecommendedGuidanceContinueBias += MethodDrillRecoveryPromoteBias;
}
if (RetainedMethodDrillRecoveryPromoteBias > 0)
{
Snapshot.RecommendedGuidanceContinueBias += RetainedMethodDrillRecoveryPromoteBias;
}
if (bQueueHistoryPrefersFollowUp
&& Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred)
{
@ -6559,6 +6658,24 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
0,
MethodDrillRecoveryStartedCount - MethodDrillRecoveryCompletedCount
);
const int32 StrongMethodDrillRecoveryMemoryStartedCount =
QueueExecutionSummary.StartedStrongMethodDrillRecoveryMemoryHandoffEventCount;
const int32 StrongMethodDrillRecoveryMemoryCompletedCount =
QueueExecutionSummary.CompletedStrongMethodDrillRecoveryMemoryHandoffEventCount;
const int32 StrongMethodDrillRecoveryMemoryOutstandingCount = FMath::Max(
0,
StrongMethodDrillRecoveryMemoryStartedCount
- StrongMethodDrillRecoveryMemoryCompletedCount
);
const int32 WeakMethodDrillRecoveryMemoryStartedCount =
QueueExecutionSummary.StartedWeakMethodDrillRecoveryMemoryHandoffEventCount;
const int32 WeakMethodDrillRecoveryMemoryCompletedCount =
QueueExecutionSummary.CompletedWeakMethodDrillRecoveryMemoryHandoffEventCount;
const int32 WeakMethodDrillRecoveryMemoryOutstandingCount = FMath::Max(
0,
WeakMethodDrillRecoveryMemoryStartedCount
- WeakMethodDrillRecoveryMemoryCompletedCount
);
if (MethodDrillRecoveryStartedCount > 0)
{
Snapshot.MethodDrillRecoveryHistoryCount += MethodDrillRecoveryStartedCount;
@ -6592,6 +6709,24 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
1,
3)
: 0;
const int32 RetainedMethodDrillRecoveryLaunchBias =
StrongMethodDrillRecoveryMemoryStartedCount > 0
? FMath::Clamp(
(StrongMethodDrillRecoveryMemoryCompletedCount * 2)
- StrongMethodDrillRecoveryMemoryStartedCount
+ 1,
1,
3)
: 0;
const int32 RetainedMethodDrillRecoveryPromoteBias =
WeakMethodDrillRecoveryMemoryStartedCount > 0
? FMath::Clamp(
(WeakMethodDrillRecoveryMemoryOutstandingCount * 2)
- WeakMethodDrillRecoveryMemoryCompletedCount
+ 1,
1,
3)
: 0;
if (ExplicitQueuedHandoffSignal > 0
|| ExplicitFollowUpHandoffSignal > 0
|| ExplicitRecommendedHandoffSignal > 0)
@ -6639,14 +6774,16 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
+ ExplicitDeferredFirstFollowUpHandoffSignal
+ ExplicitMethodDrillQueuedHandoffSignal
+ ExplicitMethodDrillFollowUpHandoffSignal
+ MethodDrillRecoveryLaunchBias;
+ MethodDrillRecoveryLaunchBias
+ RetainedMethodDrillRecoveryLaunchBias;
const int32 WeightedRecommendedRecoverySignal =
ExplicitRecommendedRecoverySignal
+ ExplicitRecommendedHandoffSignal
+ ExplicitDeferredOverflowRecommendedHandoffSignal
+ ExplicitDeferredFirstRecommendedHandoffSignal
+ ExplicitMethodDrillRecommendedHandoffSignal
+ MethodDrillRecoveryPromoteBias;
+ MethodDrillRecoveryPromoteBias
+ RetainedMethodDrillRecoveryPromoteBias;
const bool bQueueHistoryPrefersFollowUp =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
@ -6663,7 +6800,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
+ FMath::Min(static_cast<float>(QueueExecutionSummary.PromotedEventCount), 3.0f)
+ (DominantDeferredLane != EHyperTwistTrainingCoachGuidanceLane::None ? 1.5f : 0.0f)
- (QueueExecutionSummary.bHasCompletionGap ? 1.0f : 0.0f)
+ (static_cast<float>(MethodDrillRecoveryPromoteBias) * 1.5f);
+ (static_cast<float>(MethodDrillRecoveryPromoteBias) * 1.5f)
+ (static_cast<float>(RetainedMethodDrillRecoveryPromoteBias) * 1.75f);
const float LaunchRecoveryActionPressure =
(QueueExecutionSummary.bHasCompletionGap ? 4.0f : 0.0f)
+ (QueueExecutionSummary.bHasBlockedFollowUpFriction ? 2.5f : 0.0f)
@ -6678,7 +6816,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
+ static_cast<float>(ExplicitMethodDrillQueuedHandoffSignal)
+ static_cast<float>(ExplicitMethodDrillFollowUpHandoffSignal)
+ static_cast<float>(ExplicitMethodDrillRecommendedHandoffSignal) * 0.5f
+ (static_cast<float>(MethodDrillRecoveryLaunchBias) * 1.75f);
+ (static_cast<float>(MethodDrillRecoveryLaunchBias) * 1.75f)
+ (static_cast<float>(RetainedMethodDrillRecoveryLaunchBias) * 2.0f);
if (PromoteRecoveryActionPressure > 0.0f || LaunchRecoveryActionPressure > 0.0f)
{
if (PromoteRecoveryActionPressure > LaunchRecoveryActionPressure)
@ -6707,6 +6846,29 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
}
}
if (Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::LaunchRecovery
&& RetainedMethodDrillRecoveryLaunchBias > 0
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillRecoveryCoachMemorySource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)))
{
Snapshot.PreferredQueueRecoveryActionSourceLabel =
TEXT("coach-memory-method-drill-recovery-memory-strong");
}
else if (Snapshot.PreferredQueueRecoveryAction
== EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred
&& RetainedMethodDrillRecoveryPromoteBias > 0
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
|| HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillRecoveryCoachMemorySource(
Snapshot.PreferredQueueRecoveryActionSourceLabel)))
{
Snapshot.PreferredQueueRecoveryActionSourceLabel =
TEXT("coach-memory-method-drill-recovery-memory-weak");
}
else if (Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::LaunchRecovery
&& bStrongMethodDrillRecoveryHistory
&& (Snapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|| Snapshot.PreferredQueueRecoveryActionSourceLabel.StartsWith(TEXT("queue-history"))
@ -6749,10 +6911,18 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
{
Snapshot.FollowUpGuidanceContinueBias += MethodDrillRecoveryLaunchBias;
}
if (RetainedMethodDrillRecoveryLaunchBias > 0)
{
Snapshot.FollowUpGuidanceContinueBias += RetainedMethodDrillRecoveryLaunchBias;
}
if (MethodDrillRecoveryPromoteBias > 0)
{
Snapshot.RecommendedGuidanceContinueBias += MethodDrillRecoveryPromoteBias;
}
if (RetainedMethodDrillRecoveryPromoteBias > 0)
{
Snapshot.RecommendedGuidanceContinueBias += RetainedMethodDrillRecoveryPromoteBias;
}
if (bQueueHistoryPrefersFollowUp
&& Snapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred)
{
@ -8541,6 +8711,12 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
const bool bMethodDrillDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
const bool bStrongMethodDrillRecoveryDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsStrongMethodDrillRecoveryDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
const bool bWeakMethodDrillRecoveryDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsWeakMethodDrillRecoveryDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue)
{
Summary.StartedQueuedHandoffEventCount += 1;
@ -8589,6 +8765,14 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
Summary.StartedMethodDrillRecommendedHandoffEventCount += 1;
}
}
if (bStrongMethodDrillRecoveryDashboardHandoff)
{
Summary.StartedStrongMethodDrillRecoveryMemoryHandoffEventCount += 1;
}
if (bWeakMethodDrillRecoveryDashboardHandoff)
{
Summary.StartedWeakMethodDrillRecoveryMemoryHandoffEventCount += 1;
}
if (Summary.LastStartedAtUtc.IsEmpty()
|| HyperTwistTrainingRepositoryLibraryInternal::CompareUtcStrings(
HistoryEntry.EventAtUtc,
@ -8639,6 +8823,12 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
if (HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel))
{
const bool bStrongMethodDrillRecoveryDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsStrongMethodDrillRecoveryDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
const bool bWeakMethodDrillRecoveryDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsWeakMethodDrillRecoveryDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
const EHyperTwistTrainingCoachHandoffKind CompletedHandoffKind =
HyperTwistTrainingRepositoryLibraryInternal::DashboardHandoffKindFromSourceLabel(
HistoryEntry.StartActionSourceLabel);
@ -8654,6 +8844,14 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
{
Summary.CompletedMethodDrillRecommendedHandoffEventCount += 1;
}
if (bStrongMethodDrillRecoveryDashboardHandoff)
{
Summary.CompletedStrongMethodDrillRecoveryMemoryHandoffEventCount += 1;
}
if (bWeakMethodDrillRecoveryDashboardHandoff)
{
Summary.CompletedWeakMethodDrillRecoveryMemoryHandoffEventCount += 1;
}
}
CompletedCountsByEntryId.FindOrAdd(HistoryEntry.EntryId) += 1;
if (Summary.LastCompletedAtUtc.IsEmpty()

View file

@ -1448,6 +1448,7 @@ private:
EHyperTwistTrainingCoachHandoffKind::None;
bool bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false;
bool bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false;
FString DisplayedCoachHandoffMethodDrillRecoveryMemoryStartActionSourceLabel;
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
EHyperTwistCoachDashboardGuidancePreviewLane::None;
int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE;

View file

@ -3678,6 +3678,18 @@ struct FHyperTwistTrainingCoachSessionQueueExecutionSummary
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 CompletedMethodDrillRecommendedHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedStrongMethodDrillRecoveryMemoryHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 CompletedStrongMethodDrillRecoveryMemoryHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedWeakMethodDrillRecoveryMemoryHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 CompletedWeakMethodDrillRecoveryMemoryHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 PromotedFollowUpEventCount = 0;