Widen gameplay coach surface orchestration
This commit is contained in:
parent
7b32abdb9f
commit
023536695e
6 changed files with 505 additions and 6 deletions
|
|
@ -2,6 +2,89 @@
|
|||
|
||||
#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"
|
||||
|
||||
namespace HyperTwistTrainingPanelWidgetInternal
|
||||
{
|
||||
FString ResolveCoachHandoffStartActionSourceLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const EHyperTwistTrainingCoachHandoffKind HandoffKind,
|
||||
const FString& FallbackSourceLabel
|
||||
)
|
||||
{
|
||||
if (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
&& !PanelState.PreferredQueueRecoveryActionSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredQueueRecoveryActionSourceLabel;
|
||||
}
|
||||
|
||||
if (PanelState.PreferredCoachHandoffKind == HandoffKind
|
||||
&& !PanelState.PreferredCoachHandoffSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredCoachHandoffSourceLabel;
|
||||
}
|
||||
|
||||
if ((HandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp
|
||||
|| HandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended)
|
||||
&& !PanelState.PreferredGuidanceSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredGuidanceSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredCoachHandoffSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredCoachHandoffSourceLabel;
|
||||
}
|
||||
|
||||
if (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
&& !PanelState.NextQueueSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.NextQueueSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredLaunchBudgetSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredLaunchBudgetSourceLabel;
|
||||
}
|
||||
|
||||
return FallbackSourceLabel;
|
||||
}
|
||||
|
||||
FString ResolvePrimaryCoachActionStartActionSourceLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FString& FallbackSourceLabel
|
||||
)
|
||||
{
|
||||
if (PanelState.PreferredQueueRecoveryAction != EHyperTwistTrainingQueueRecoveryAction::None)
|
||||
{
|
||||
return ResolveCoachHandoffStartActionSourceLabel(
|
||||
PanelState,
|
||||
EHyperTwistTrainingCoachHandoffKind::Queue,
|
||||
FallbackSourceLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (PanelState.PreferredCoachHandoffKind != EHyperTwistTrainingCoachHandoffKind::None)
|
||||
{
|
||||
return ResolveCoachHandoffStartActionSourceLabel(
|
||||
PanelState,
|
||||
PanelState.PreferredCoachHandoffKind,
|
||||
FallbackSourceLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredGuidanceSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredGuidanceSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredLaunchBudgetSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredLaunchBudgetSourceLabel;
|
||||
}
|
||||
|
||||
return FallbackSourceLabel;
|
||||
}
|
||||
}
|
||||
|
||||
void UHyperTwistTrainingPanelWidget::NativeConstruct()
|
||||
{
|
||||
Super::NativeConstruct();
|
||||
|
|
@ -315,6 +398,34 @@ FHyperTwistTrainingDeck UHyperTwistTrainingPanelWidget::BuildActiveMethodDrillFo
|
|||
return CachedMethodDrillFollowUpDeck;
|
||||
}
|
||||
|
||||
FString UHyperTwistTrainingPanelWidget::ResolveCoachHandoffStartActionSourceLabel(
|
||||
const EHyperTwistTrainingCoachHandoffKind HandoffKind
|
||||
) const
|
||||
{
|
||||
return HyperTwistTrainingPanelWidgetInternal::ResolveCoachHandoffStartActionSourceLabel(
|
||||
CachedCoachPanelState,
|
||||
HandoffKind,
|
||||
FString::Printf(
|
||||
TEXT("coach-panel-%s"),
|
||||
HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
? TEXT("queue")
|
||||
: (HandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("handoff")))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
FString UHyperTwistTrainingPanelWidget::ResolvePrimaryCoachActionStartActionSourceLabel() const
|
||||
{
|
||||
return HyperTwistTrainingPanelWidgetInternal::ResolvePrimaryCoachActionStartActionSourceLabel(
|
||||
CachedCoachPanelState,
|
||||
TEXT("coach-panel-primary-action")
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
|
||||
const int32 MaxCases,
|
||||
const FString& StartActionSourceLabel
|
||||
|
|
@ -395,6 +506,55 @@ FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachQueueEntry
|
|||
return CachedRunState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartDisplayedCoachRecommendedRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartCoachRecommendedRun(
|
||||
MaxCases,
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Recommended)
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartDisplayedCoachFollowUpRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartCoachFollowUpRun(
|
||||
MaxCases,
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::FollowUp)
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartDisplayedPrimaryCoachAction(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartPrimaryCoachAction(MaxCases, ResolvePrimaryCoachActionStartActionSourceLabel());
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartDisplayedNextQueuedCoachRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartNextQueuedCoachRun(
|
||||
MaxCases,
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Queue)
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartDisplayedCoachQueueEntry(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
if (CachedCoachPanelState.ActiveQueueEntryId.IsEmpty())
|
||||
{
|
||||
return FHyperTwistTrainingRunState();
|
||||
}
|
||||
|
||||
return StartCoachQueueEntry(CachedCoachPanelState.ActiveQueueEntryId, MaxCases);
|
||||
}
|
||||
|
||||
bool UHyperTwistTrainingPanelWidget::DeferCoachQueueEntry(
|
||||
const FString& EntryId,
|
||||
const FString& DeferredUntilUtc,
|
||||
|
|
@ -446,6 +606,19 @@ bool UHyperTwistTrainingPanelWidget::PromoteCoachQueueEntry(
|
|||
return bSucceeded;
|
||||
}
|
||||
|
||||
bool UHyperTwistTrainingPanelWidget::PromoteDisplayedCoachQueueEntry()
|
||||
{
|
||||
if (CachedCoachPanelState.ActiveQueueEntryId.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return PromoteCoachQueueEntry(
|
||||
CachedCoachPanelState.ActiveQueueEntryId,
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Queue)
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartActiveMethodDrillFollowUpRun(
|
||||
const FString& SessionId
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,89 @@
|
|||
|
||||
#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"
|
||||
|
||||
namespace HyperTwistTrainingSessionActorInternal
|
||||
{
|
||||
FString ResolveCoachHandoffStartActionSourceLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const EHyperTwistTrainingCoachHandoffKind HandoffKind,
|
||||
const FString& FallbackSourceLabel
|
||||
)
|
||||
{
|
||||
if (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
&& !PanelState.PreferredQueueRecoveryActionSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredQueueRecoveryActionSourceLabel;
|
||||
}
|
||||
|
||||
if (PanelState.PreferredCoachHandoffKind == HandoffKind
|
||||
&& !PanelState.PreferredCoachHandoffSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredCoachHandoffSourceLabel;
|
||||
}
|
||||
|
||||
if ((HandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp
|
||||
|| HandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended)
|
||||
&& !PanelState.PreferredGuidanceSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredGuidanceSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredCoachHandoffSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredCoachHandoffSourceLabel;
|
||||
}
|
||||
|
||||
if (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
&& !PanelState.NextQueueSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.NextQueueSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredLaunchBudgetSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredLaunchBudgetSourceLabel;
|
||||
}
|
||||
|
||||
return FallbackSourceLabel;
|
||||
}
|
||||
|
||||
FString ResolvePrimaryCoachActionStartActionSourceLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FString& FallbackSourceLabel
|
||||
)
|
||||
{
|
||||
if (PanelState.PreferredQueueRecoveryAction != EHyperTwistTrainingQueueRecoveryAction::None)
|
||||
{
|
||||
return ResolveCoachHandoffStartActionSourceLabel(
|
||||
PanelState,
|
||||
EHyperTwistTrainingCoachHandoffKind::Queue,
|
||||
FallbackSourceLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (PanelState.PreferredCoachHandoffKind != EHyperTwistTrainingCoachHandoffKind::None)
|
||||
{
|
||||
return ResolveCoachHandoffStartActionSourceLabel(
|
||||
PanelState,
|
||||
PanelState.PreferredCoachHandoffKind,
|
||||
FallbackSourceLabel
|
||||
);
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredGuidanceSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredGuidanceSourceLabel;
|
||||
}
|
||||
|
||||
if (!PanelState.PreferredLaunchBudgetSourceLabel.IsEmpty())
|
||||
{
|
||||
return PanelState.PreferredLaunchBudgetSourceLabel;
|
||||
}
|
||||
|
||||
return FallbackSourceLabel;
|
||||
}
|
||||
}
|
||||
|
||||
AHyperTwistTrainingSessionActor::AHyperTwistTrainingSessionActor()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
|
|
@ -296,6 +379,34 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartRunFromTemplat
|
|||
return CachedRunState;
|
||||
}
|
||||
|
||||
FString AHyperTwistTrainingSessionActor::ResolveCoachHandoffStartActionSourceLabel(
|
||||
const EHyperTwistTrainingCoachHandoffKind HandoffKind
|
||||
) const
|
||||
{
|
||||
return HyperTwistTrainingSessionActorInternal::ResolveCoachHandoffStartActionSourceLabel(
|
||||
CachedCoachPanelState,
|
||||
HandoffKind,
|
||||
FString::Printf(
|
||||
TEXT("coach-session-actor-%s"),
|
||||
HandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue
|
||||
? TEXT("queue")
|
||||
: (HandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: (HandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("handoff")))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
FString AHyperTwistTrainingSessionActor::ResolvePrimaryCoachActionStartActionSourceLabel() const
|
||||
{
|
||||
return HyperTwistTrainingSessionActorInternal::ResolvePrimaryCoachActionStartActionSourceLabel(
|
||||
CachedCoachPanelState,
|
||||
TEXT("coach-session-actor-primary-action")
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
|
|
@ -304,7 +415,7 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommend
|
|||
this,
|
||||
AutoStartSessionId + TEXT("_coach"),
|
||||
MaxCases > 0 ? MaxCases : DefaultCoachMaxCases,
|
||||
FString()
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Recommended)
|
||||
);
|
||||
RefreshCachedTrainingState();
|
||||
return CachedRunState;
|
||||
|
|
@ -318,7 +429,7 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachFollowUpT
|
|||
this,
|
||||
AutoStartSessionId + TEXT("_follow_up"),
|
||||
MaxCases > 0 ? MaxCases : DefaultCoachMaxCases,
|
||||
FString()
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::FollowUp)
|
||||
);
|
||||
RefreshCachedTrainingState();
|
||||
return CachedRunState;
|
||||
|
|
@ -332,7 +443,7 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartPrimaryCoachTr
|
|||
this,
|
||||
AutoStartSessionId + TEXT("_primary"),
|
||||
MaxCases > 0 ? MaxCases : DefaultCoachMaxCases,
|
||||
FString()
|
||||
ResolvePrimaryCoachActionStartActionSourceLabel()
|
||||
);
|
||||
RefreshCachedTrainingState();
|
||||
return CachedRunState;
|
||||
|
|
@ -346,7 +457,7 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartNextQueuedCoac
|
|||
this,
|
||||
AutoStartSessionId + TEXT("_queue"),
|
||||
MaxCases > 0 ? MaxCases : DefaultCoachMaxCases,
|
||||
FString()
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Queue)
|
||||
);
|
||||
RefreshCachedTrainingState();
|
||||
return CachedRunState;
|
||||
|
|
@ -367,6 +478,46 @@ FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachQueueEntr
|
|||
return CachedRunState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartDisplayedCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartCoachRecommendedTrainingRun(MaxCases);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartDisplayedCoachFollowUpTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartCoachFollowUpTrainingRun(MaxCases);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartDisplayedPrimaryCoachTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartPrimaryCoachTrainingRun(MaxCases);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartDisplayedNextQueuedCoachTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
return StartNextQueuedCoachTrainingRun(MaxCases);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartDisplayedCoachQueueEntryTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
{
|
||||
if (CachedCoachPanelState.ActiveQueueEntryId.IsEmpty())
|
||||
{
|
||||
return FHyperTwistTrainingRunState();
|
||||
}
|
||||
|
||||
return StartCoachQueueEntryTrainingRun(CachedCoachPanelState.ActiveQueueEntryId, MaxCases);
|
||||
}
|
||||
|
||||
bool AHyperTwistTrainingSessionActor::DeferCoachQueueEntry(
|
||||
const FString& EntryId,
|
||||
const FString& DeferredUntilUtc,
|
||||
|
|
@ -409,12 +560,22 @@ bool AHyperTwistTrainingSessionActor::PromoteCoachQueueEntry(const FString& Entr
|
|||
const bool bSucceeded = UHyperTwistTrainingRuntimeLibrary::PromoteCoachSessionQueueEntry(
|
||||
this,
|
||||
EntryId,
|
||||
FString()
|
||||
ResolveCoachHandoffStartActionSourceLabel(EHyperTwistTrainingCoachHandoffKind::Queue)
|
||||
);
|
||||
RefreshCachedTrainingState();
|
||||
return bSucceeded;
|
||||
}
|
||||
|
||||
bool AHyperTwistTrainingSessionActor::PromoteDisplayedCoachQueueEntry()
|
||||
{
|
||||
if (CachedCoachPanelState.ActiveQueueEntryId.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return PromoteCoachQueueEntry(CachedCoachPanelState.ActiveQueueEntryId);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRepositoryRoundTripVerification
|
||||
AHyperTwistTrainingSessionActor::VerifyRepositoryRoundTrip()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -206,6 +206,14 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Drill")
|
||||
FHyperTwistTrainingDeck BuildActiveMethodDrillFollowUpDeck();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FString ResolveCoachHandoffStartActionSourceLabel(
|
||||
EHyperTwistTrainingCoachHandoffKind HandoffKind
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FString ResolvePrimaryCoachActionStartActionSourceLabel() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedRun(
|
||||
int32 MaxCases,
|
||||
|
|
@ -236,6 +244,21 @@ public:
|
|||
int32 MaxCases
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachRecommendedRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachFollowUpRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedPrimaryCoachAction(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedNextQueuedCoachRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachQueueEntry(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
bool DeferCoachQueueEntry(
|
||||
const FString& EntryId,
|
||||
|
|
@ -257,6 +280,9 @@ public:
|
|||
const FString& StartActionSourceLabel
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
bool PromoteDisplayedCoachQueueEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Drill")
|
||||
FHyperTwistTrainingRunState StartActiveMethodDrillFollowUpRun(const FString& SessionId);
|
||||
|
||||
|
|
|
|||
|
|
@ -187,6 +187,14 @@ public:
|
|||
const FString& SessionId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FString ResolveCoachHandoffStartActionSourceLabel(
|
||||
EHyperTwistTrainingCoachHandoffKind HandoffKind
|
||||
) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FString ResolvePrimaryCoachActionStartActionSourceLabel() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
|
|
@ -205,6 +213,21 @@ public:
|
|||
int32 MaxCases
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachFollowUpTrainingRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedPrimaryCoachTrainingRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedNextQueuedCoachTrainingRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartDisplayedCoachQueueEntryTrainingRun(int32 MaxCases);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
bool DeferCoachQueueEntry(
|
||||
const FString& EntryId,
|
||||
|
|
@ -223,6 +246,9 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
bool PromoteCoachQueueEntry(const FString& EntryId);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
bool PromoteDisplayedCoachQueueEntry();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training")
|
||||
FHyperTwistTrainingRepositoryRoundTripVerification VerifyRepositoryRoundTrip();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ Current correction call from the source-exposed audit and current execution refr
|
|||
- the imported generated-mode gap is closed; request/config/selection plumbing and the bounded clean-room executor are already landed in first-party code
|
||||
- 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 current next bounded packet is to widen into the first thin gameplay-facing consumers of coach scheduling and recommendations, starting from the already-exposed panel-widget and session-actor coach state/action surfaces without reopening backend continuity or analytics policy work
|
||||
- the latest landed bounded `Phase 4` packet widens the first gameplay-facing coach consumer layer by giving the panel-widget and session-actor surfaces displayed coach-action helpers plus default source-label routing, so gameplay/Blueprint callers no longer have to fabricate coach provenance or manually chase active queue-entry ids just to launch the current action
|
||||
- the current next bounded packet is to stay on those same surfaces and expose one thin, truthful primary-action descriptor / availability layer for gameplay callers so they can bind a single coach CTA without reconstructing queue-vs-follow-up-vs-recommended state from the raw panel booleans
|
||||
- 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
|
||||
|
||||
## Current execution-reality references
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
# HyperTwist Phase 4 gameplay coach surface orchestration packet
|
||||
|
||||
Created on `2026-05-07`
|
||||
|
||||
Status:
|
||||
|
||||
- first-party HyperTwist packet
|
||||
- bounded Phase `4` gameplay-facing consumer slice
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet starts the first thin gameplay-facing consumer widening above the now-stable coach scheduling and recommendation backend by making the panel-widget and session-actor surfaces executable without extra caller-side provenance glue.
|
||||
|
||||
The open tasks were:
|
||||
|
||||
- stop forcing gameplay / Blueprint callers to invent their own coach start-action source labels before they can launch the currently displayed recommended, follow-up, queue, or primary coach action
|
||||
- stop dropping coach provenance entirely on the session-actor path when those actions are launched or deferred work is promoted
|
||||
- expose one thin displayed-action helper layer so callers can act on the retained panel state directly instead of manually wiring active queue-entry ids every time
|
||||
|
||||
It is not:
|
||||
|
||||
- a new backend continuity packet
|
||||
- a new analytics-selection packet
|
||||
- a dashboard rewrite
|
||||
- a broader gameplay UI integration pass
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- add panel-widget helpers that resolve default coach handoff / primary-action source labels from the cached coach panel state
|
||||
- add panel-widget helpers that launch the currently displayed recommended, follow-up, primary, next-queued, and active queue-entry actions without extra caller-side routing
|
||||
- add panel-widget helper coverage for promoting the currently displayed queue entry
|
||||
- update the session-actor launch and promotion path to stop recording empty source labels
|
||||
- mirror the same displayed-action helper layer on the session actor for gameplay-facing Blueprint consumers
|
||||
|
||||
Out of scope:
|
||||
|
||||
- changing coach recommendation policy
|
||||
- changing queue execution policy
|
||||
- changing retained dashboard continuity behavior
|
||||
- widening into a richer gameplay HUD or CTA presentation pass in the same packet
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- the recognition-assisted coach-to-review closure lane was already documented as complete
|
||||
- the repo already exposed rich cached coach state on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
|
||||
- those surfaces already had the raw launch verbs for recommended, follow-up, queue, and queue-entry work
|
||||
|
||||
But the first gameplay-facing consumer seam was still obvious:
|
||||
|
||||
- the widget surface still required callers to supply coach start-action source labels themselves
|
||||
- the actor surface launched and promoted coach work with empty source labels, which threw away provenance and downstream analytics context
|
||||
- callers still had to manually thread the active queue-entry id out of cached panel state for common displayed-action cases
|
||||
|
||||
That meant:
|
||||
|
||||
- the backend was ready
|
||||
- but the first gameplay-facing consumer layer still imposed avoidable orchestration work and provenance loss on the caller
|
||||
|
||||
So the next bounded move was:
|
||||
|
||||
- keep the backend untouched
|
||||
- and make the existing panel/actor surfaces honest thin consumers of the current coach panel state
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
|
||||
- added coach handoff and primary-action source-label resolvers driven by `CachedCoachPanelState`
|
||||
- added displayed-action helpers for recommended, follow-up, primary, next-queued, and active queue-entry coach launches
|
||||
- added a displayed queue-entry promotion helper
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
|
||||
- added the same source-label resolvers and displayed-action helpers for gameplay-facing actor callers
|
||||
- updated existing actor launch and queue-promotion methods so they no longer pass empty start-action source labels into the runtime path
|
||||
|
||||
## Product effect
|
||||
|
||||
The first gameplay-facing coach consumers are now thinner and more truthful:
|
||||
|
||||
- gameplay / Blueprint callers can execute the displayed coach action surface without manufacturing source labels first
|
||||
- session-actor launches and queue promotions now preserve coach provenance instead of silently dropping it
|
||||
- callers no longer need to manually copy `ActiveQueueEntryId` out of cached panel state for the common displayed queue-entry path
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- panel-widget callers can resolve default coach source labels from the cached coach panel state
|
||||
- panel-widget callers can launch the displayed recommended, follow-up, primary, next-queued, and active queue-entry actions through dedicated helpers
|
||||
- session-actor launches and queue promotions no longer record empty source labels
|
||||
- session-actor callers get the same displayed-action helper layer
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm the panel widget compiles with the new displayed-action and source-label helper surface
|
||||
3. confirm the session actor compiles with the new displayed-action helper surface
|
||||
4. confirm actor-side coach launches and queue promotions now route non-empty source labels
|
||||
|
||||
## Validation result
|
||||
|
||||
- full `Development Editor|Win64` build succeeded on `2026-05-07`
|
||||
- build completed clean with `0` warnings and `0` errors
|
||||
|
||||
## Next bounded follow-on slice
|
||||
|
||||
- stay on the same gameplay-facing consumer lane and expose one thin primary coach CTA descriptor / availability surface on the panel-widget and session-actor layer so gameplay callers can bind a single truthful coach action without reconstructing queue-vs-follow-up-vs-recommended state from raw booleans
|
||||
Loading…
Add table
Reference in a new issue