Quarantine untracked drill source prototypes

This commit is contained in:
axiomlogicnexus 2026-04-29 00:54:35 +02:00
parent 7a715358a0
commit a43840781b
5 changed files with 304 additions and 0 deletions

View file

@ -0,0 +1,64 @@
# Untracked Source Prototype Quarantine
Created on `2026-04-29`
## Purpose
This note records untracked prototype-style source files that were found under
`C:\HyperTwist\UnrealHyperTwist\Source\...` but were not part of the tracked
first-party runtime.
The goal is to keep the product worktree clean without losing potentially
useful exploratory code.
## Quarantined on 2026-04-29
Original untracked paths:
- `C:\HyperTwist\UnrealHyperTwist\Source\HyperTwistCore\Public\DrillTypes.h`
- `C:\HyperTwist\UnrealHyperTwist\Source\HyperTwistTraining\Public\HyperTwistDrillManager.h`
- `C:\HyperTwist\UnrealHyperTwist\Source\HyperTwistTraining\Private\HyperTwistDrillManager.cpp`
Quarantine destination:
- `C:\HyperTwist\docs\quarantine\untracked-source-prototypes\2026-04-29\Source\HyperTwistCore\Public\DrillTypes.h`
- `C:\HyperTwist\docs\quarantine\untracked-source-prototypes\2026-04-29\Source\HyperTwistTraining\Public\HyperTwistDrillManager.h`
- `C:\HyperTwist\docs\quarantine\untracked-source-prototypes\2026-04-29\Source\HyperTwistTraining\Private\HyperTwistDrillManager.cpp`
## Why these were quarantined instead of committed into runtime
These files were not treated as live product code because:
- they existed as untracked top-level source trees outside the tracked
`Source\UnrealHyperTwist` module surface
- no `Build.cs` files existed for `Source\HyperTwistCore` or
`Source\HyperTwistTraining`
- exact-name search found no references outside the prototype files themselves
- the contents describe a much earlier and narrower drill-manager concept than
the current first-party `HyperTwistTraining` stack
Operationally, they are preserved as prototype artifacts, not accepted as
integrated runtime modules.
## Reintegration rule
Do not move these files back under `Source\...` unless all of the following are
true:
1. there is a deliberate product task that needs them
2. they are reviewed against the current first-party training architecture
3. they are either reshaped into existing tracked modules or given a real
module/build definition
4. their runtime role is explicit and not duplicative of the current owned
`HyperTwistTraining` surfaces
## Workflow guidance
If future prototype code appears under top-level `Source\...` paths without a
real module definition or tracked task, prefer this same pattern:
1. inspect whether it is integrated or stray
2. quarantine it into `docs\quarantine\untracked-source-prototypes\<date>\...`
3. update this note with the original path and rationale
This keeps the runtime tree clean while preserving handoff context.

View file

@ -0,0 +1,11 @@
# Untracked source prototypes preserved on 2026-04-29
These files were moved out of the live `Source\...` tree because they were
untracked standalone prototypes, not integrated product modules.
See:
- `C:\HyperTwist\docs\ops\UNTRACKED_SOURCE_PROTOTYPE_QUARANTINE.md`
The folder layout below preserves the original relative source paths so the
prototype can be reviewed later without polluting the runtime tree.

View file

@ -0,0 +1,51 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "DrillTypes.generated.h"
// Represents a single step or case within a drill.
USTRUCT(BlueprintType)
struct HYPERTWISTCORE_API FDrillCase
{
GENERATED_BODY()
// The initial state to present to the user (e.g., a scrambled cube state).
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drill")
FString InitialState;
// The target for a recognition drill (e.g., name of the algorithm).
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drill")
FString RecognitionTarget;
// The solution or next step.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drill")
FString Solution;
};
// A DataAsset that defines a collection of drill cases.
UCLASS(BlueprintType)
class HYPERTWISTCORE_API UHyperTwistDrillAsset : public UDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drill")
TArray<FDrillCase> DrillCases;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Drill")
FString MethodName; // e.g., "OLL", "PLL"
};
// Represents the user's saved progress and favorites.
USTRUCT(BlueprintType)
struct HYPERTWISTCORE_API FDrillUserData
{
GENERATED_BODY()
UPROPERTY()
TArray<FString> FavoriteCases; // Storing by InitialState as a key
UPROPERTY()
TArray<FString> QueuedBatch; // A list of asset paths
};

View file

@ -0,0 +1,109 @@
#include "HyperTwistDrillManager.h"
#include "DrillTypes.h"
#include "Misc/Paths.h"
#include "Serialization/JsonSerializer.h"
#include "Serialization/JsonObjectConverter.h"
#include "HAL/PlatformFileManager.h"
#include "Misc/FileHelper.h"
void UHyperTwistDrillManager::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
CurrentState = EDrillState::Idle;
CurrentCaseIndex = -1;
LoadUserData();
}
void UHyperTwistDrillManager::Deinitialize()
{
SaveUserData();
Super::Deinitialize();
}
FString GetSaveFilePath()
{
return FPaths::ProjectSavedDir() + TEXT("DrillUserData.json");
}
void UHyperTwistDrillManager::LoadUserData()
{
FString FilePath = GetSaveFilePath();
FString JsonString;
if (FFileHelper::LoadFileToString(JsonString, *FilePath))
{
FJsonObjectConverter::JsonObjectStringToUStruct(JsonString, &UserData, 0, 0);
}
}
void UHyperTwistDrillManager::SaveUserData()
{
FString JsonString;
if (FJsonObjectConverter::UStructToJsonObjectString(UserData, JsonString))
{
FFileHelper::SaveStringToFile(JsonString, *GetSaveFilePath());
}
}
void UHyperTwistDrillManager::SetState(EDrillState NewState)
{
if (CurrentState != NewState)
{
CurrentState = NewState;
OnDrillStateChanged.Broadcast(CurrentState);
}
}
void UHyperTwistDrillManager::StartDrill(UHyperTwistDrillAsset* DrillAsset)
{
if (!DrillAsset || DrillAsset->DrillCases.Num() == 0)
{
return;
}
ActiveDrillQueue = DrillAsset->DrillCases;
CurrentCaseIndex = 0;
OnNewDrillCase.Broadcast(ActiveDrillQueue[CurrentCaseIndex]);
SetState(EDrillState::Presenting);
}
void UHyperTwistDrillManager::Next()
{
if (CurrentState == EDrillState::Idle || ActiveDrillQueue.Num() == 0)
{
return;
}
CurrentCaseIndex++;
if (ActiveDrillQueue.IsValidIndex(CurrentCaseIndex))
{
OnNewDrillCase.Broadcast(ActiveDrillQueue[CurrentCaseIndex]);
SetState(EDrillState::Presenting);
}
else
{
// Drill finished
CurrentCaseIndex = -1;
ActiveDrillQueue.Empty();
SetState(EDrillState::Idle);
}
}
void UHyperTwistDrillManager::ShowSolution()
{
if (CurrentState == EDrillState::Presenting || CurrentState == EDrillState::AwaitingInput)
{
SetState(EDrillState::ShowingSolution);
}
}
void UHyperTwistDrillManager::AddCurrentCaseToFavorites()
{
if (ActiveDrillQueue.IsValidIndex(CurrentCaseIndex))
{
const FString& caseId = ActiveDrillQueue[CurrentCaseIndex].InitialState;
UserData.FavoriteCases.AddUnique(caseId);
SaveUserData();
}
}

View file

@ -0,0 +1,69 @@
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "HyperTwistDrillManager.generated.h"
// Forward declarations
struct FDrillCase;
class UHyperTwistDrillAsset;
UENUM(BlueprintType)
enum class EDrillState : uint8
{
Idle,
Presenting, // Showing the initial state
AwaitingInput, // Waiting for user to recognize/solve
ShowingSolution
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDrillStateChanged, EDrillState, NewState);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnNewDrillCase, const FDrillCase&, NewCase);
UCLASS()
class HYPERTWISTTRAINING_API UHyperTwistDrillManager : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
//~ Begin USubsystem
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
//~ End USubsystem
UFUNCTION(BlueprintCallable, Category = "Drill")
void StartDrill(UHyperTwistDrillAsset* DrillAsset);
UFUNCTION(BlueprintCallable, Category = "Drill")
void Next();
UFUNCTION(BlueprintCallable, Category = "Drill")
void ShowSolution();
UFUNCTION(BlueprintCallable, Category = "Drill")
void AddCurrentCaseToFavorites();
UPROPERTY(BlueprintAssignable, Category = "Drill")
FOnDrillStateChanged OnDrillStateChanged;
UPROPERTY(BlueprintAssignable, Category = "Drill")
FOnNewDrillCase OnNewDrillCase;
private:
void LoadUserData();
void SaveUserData();
void SetState(EDrillState NewState);
UPROPERTY()
TArray<FDrillCase> ActiveDrillQueue;
UPROPERTY()
int32 CurrentCaseIndex;
UPROPERTY()
EDrillState CurrentState;
UPROPERTY()
struct FDrillUserData UserData;
};