From b149714f20a19ffe2093eff983b0ae9ae8fa8d0c Mon Sep 17 00:00:00 2001 From: jyelon Date: Wed, 25 Feb 2026 14:48:14 -0500 Subject: [PATCH] Reduce coupling in the unreal side --- Source/Integration/AnimQueue.cpp | 122 ++++++++++++++++++ Source/Integration/AnimQueue.h | 117 ----------------- Source/Integration/AssetLookup.cpp | 10 +- Source/Integration/AssetLookup.h | 8 +- Source/Integration/Common.h | 20 ++- Source/Integration/Integration.Build.cs | 1 + Source/Integration/LuaCall.cpp | 2 +- Source/Integration/LuaCallNode.cpp | 2 +- Source/Integration/LuprexGameModeBase.cpp | 10 -- Source/Integration/LuprexGameModeBase.h | 27 +--- .../{StringDecoder.h => StreamBuffer.h} | 0 Source/Integration/StringDecoder.cpp | 3 - Source/Integration/Tangible.cpp | 1 + 13 files changed, 161 insertions(+), 162 deletions(-) rename Source/Integration/{StringDecoder.h => StreamBuffer.h} (100%) delete mode 100644 Source/Integration/StringDecoder.cpp diff --git a/Source/Integration/AnimQueue.cpp b/Source/Integration/AnimQueue.cpp index fe7e9e1a..a354d987 100644 --- a/Source/Integration/AnimQueue.cpp +++ b/Source/Integration/AnimQueue.cpp @@ -1,6 +1,7 @@ #include "AnimQueue.h" #include "Common.h" +#include "StreamBuffer.h" #include "UtilityLibrary.h" #include "GameFramework/Actor.h" #include "Components/MeshComponent.h" @@ -10,6 +11,127 @@ #include "Materials/MaterialInstanceDynamic.h" #include + +//////////////////////////////////////////////////////////// +// +// An animation step that doesn't actually store the step, +// it just contains a pointer to the string. +// +//////////////////////////////////////////////////////////// + +struct FlxAnimationStepView { + int64 Hash; + std::string_view Body; + + FlxAnimationStepView() : Hash(0), Body("") {} + FlxAnimationStepView(int64 h, std::string_view b) : Hash(h), Body(b) {} +}; + +//////////////////////////////////////////////////////////// +// +// FlxAnimationField +// +// A single field from an animation step: a variable name, a +// persistent flag, a type, and value storage. +// +// IMPORTANT: Stores a string_view, not a string, so the lifetime +// of this field is only as long as the step you're parsing. +// +// Boolean values are stored in X as 1 or 0. Double values +// are stored in X. +// +//////////////////////////////////////////////////////////// + +struct FlxAnimationField { + std::string_view Name; + bool Persistent; + LuaValueType Type; + double X, Y, Z; + std::string_view S; +}; + +//////////////////////////////////////////////////////////// +// +// FlxAnimationStepDecoder +// +// Stream reader for a single animation step. Reads one +// FlxAnimationField at a time until EOF. +// +//////////////////////////////////////////////////////////// + +class FlxAnimationStepDecoder { +private: + FlxStreamBuffer Decoder; + +public: + // Initialize from an encoded step body. + // + FlxAnimationStepDecoder(std::string_view body) : Decoder(body) {} + + // Return true if the parser has reached EOF. + // + bool AtEOF() { return Decoder.empty(); } + + // Read one field. + // + FlxAnimationField ReadField(); + + // Convert an animation step to a debug string. + // + static FString DebugString(bool finished, int64 hash, std::string_view body); +}; + +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// FlxAnimQueueDecoder +// +// Stream reader for animation queues. Reads one +// FlxAnimationStepView at a time until EOF. +// +//////////////////////////////////////////////////////////// + +class FlxAnimQueueDecoder { +private: + FlxStreamBuffer Decoder; + + // Read from the header immediately on + // construction. + // + int SizeLimit; + int ActualSize; + +public: + // Initialize with an encoded animation queue. + // + FlxAnimQueueDecoder(std::string_view s); + + // Get the size limit of the animation queue. + // + int GetSizeLimit() const { return SizeLimit; } + + // Get the actual size of the animation queue. + // + int GetActualSize() const { return ActualSize; } + + // Return true if the parser has reached EOF. + // + bool AtEOF() { return Decoder.empty(); } + + // Read one animation step. + // + FlxAnimationStepView ReadStep(); + + // Peek at the hash of the next step. + // + int64 PeekHash(); + + // Convert an AnimQueue to an FString. + // + // static FString DebugString(std::string_view s); +}; + FlxAnimationStep::FlxAnimationStep(int64 hash, std::string_view body) { Finished = false; Hash = hash; diff --git a/Source/Integration/AnimQueue.h b/Source/Integration/AnimQueue.h index e1514a26..181eef96 100644 --- a/Source/Integration/AnimQueue.h +++ b/Source/Integration/AnimQueue.h @@ -2,10 +2,8 @@ #include "CoreMinimal.h" #include "CoreUObject.h" -#include "StringDecoder.h" #include "Containers/Deque.h" #include "Kismet/BlueprintFunctionLibrary.h" - #include "AnimQueue.generated.h" //////////////////////////////////////////////////////////// @@ -153,121 +151,6 @@ public: USkeletalMeshComponent* MeshComp, USkeletalMesh* Fallback = nullptr); }; -//////////////////////////////////////////////////////////// -// -// An animation step that doesn't actually store the step, -// it just contains a pointer to the string. -// -//////////////////////////////////////////////////////////// - -struct FlxAnimationStepView { - int64 Hash; - std::string_view Body; - - FlxAnimationStepView() : Hash(0), Body("") {} - FlxAnimationStepView(int64 h, std::string_view b) : Hash(h), Body(b) {} -}; - -//////////////////////////////////////////////////////////// -// -// FlxAnimationField -// -// A single field from an animation step: a variable name, a -// persistent flag, a type, and value storage. -// -// Boolean values are stored in X as 1 or 0. Double values -// are stored in X. -// -//////////////////////////////////////////////////////////// - -struct FlxAnimationField { - std::string_view Name; - bool Persistent; - LuaValueType Type; - double X, Y, Z; - std::string_view S; -}; - -//////////////////////////////////////////////////////////// -// -// FlxAnimQueueDecoder -// -// Stream reader for animation queues. Reads one -// FlxAnimationStepView at a time until EOF. -// -//////////////////////////////////////////////////////////// - -class FlxAnimQueueDecoder { -private: - FlxStreamBuffer Decoder; - - // Read from the header immediately on - // construction. - // - int SizeLimit; - int ActualSize; - -public: - // Initialize with an encoded animation queue. - // - FlxAnimQueueDecoder(std::string_view s); - - // Get the size limit of the animation queue. - // - int GetSizeLimit() const { return SizeLimit; } - - // Get the actual size of the animation queue. - // - int GetActualSize() const { return ActualSize; } - - // Return true if the parser has reached EOF. - // - bool AtEOF() { return Decoder.empty(); } - - // Read one animation step. - // - FlxAnimationStepView ReadStep(); - - // Peek at the hash of the next step. - // - int64 PeekHash(); - - // Convert an AnimQueue to an FString. - // - // static FString DebugString(std::string_view s); -}; - -//////////////////////////////////////////////////////////// -// -// FlxAnimationStepDecoder -// -// Stream reader for a single animation step. Reads one -// FlxAnimationField at a time until EOF. -// -//////////////////////////////////////////////////////////// - -class FlxAnimationStepDecoder { -private: - FlxStreamBuffer Decoder; - -public: - // Initialize from an encoded step body. - // - FlxAnimationStepDecoder(std::string_view body) : Decoder(body) {} - - // Return true if the parser has reached EOF. - // - bool AtEOF() { return Decoder.empty(); } - - // Read one field. - // - FlxAnimationField ReadField(); - - // Convert an animation step to a debug string. - // - static FString DebugString(bool finished, int64 hash, std::string_view body); -}; - //////////////////////////////////////////////////////////// // // FlxAnimTracker diff --git a/Source/Integration/AssetLookup.cpp b/Source/Integration/AssetLookup.cpp index c18a5ea0..d7b88cf7 100644 --- a/Source/Integration/AssetLookup.cpp +++ b/Source/Integration/AssetLookup.cpp @@ -3,7 +3,7 @@ #include "AssetRegistry/IAssetRegistry.h" #include "AssetRegistry/AssetData.h" #include "AssetRegistry/AssetRegistryState.h" -#include "LuprexGameModeBase.h" +#include "Kismet/GameplayStatics.h" #include "Components/Widget.h" #include "WidgetBlueprint.h" #include "Blueprint/UserWidget.h" @@ -15,6 +15,12 @@ const ElxValidOrNotValid NotValid = ElxValidOrNotValid::NotValid; const ElxValidOrNotValid Valid = ElxValidOrNotValid::Valid; +void UlxAssetLookup::Initialize(FSubsystemCollectionBase& Collection) +{ + Super::Initialize(Collection); + RebuildIndex(); +} + void UlxAssetLookup::RebuildIndex() { IAssetRegistry::GetChecked().WaitForCompletion(); @@ -63,7 +69,7 @@ void UlxAssetLookup::ReportFailedLoad(const FString &ClassName, const FString &N UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name) { - const UlxAssetLookup *Lookup = ALuprexGameModeBase::FromContext(Context)->GetAssetLookup(); + const UlxAssetLookup *Lookup = UGameplayStatics::GetGameInstance(Context)->GetSubsystem(); const FString *Path = Lookup->AssetPaths.Find(MakeTuple(Class->GetName(), FName(Name))); if (Path == nullptr) { diff --git a/Source/Integration/AssetLookup.h b/Source/Integration/AssetLookup.h index 88e3dadf..32e533f9 100644 --- a/Source/Integration/AssetLookup.h +++ b/Source/Integration/AssetLookup.h @@ -14,8 +14,9 @@ #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" -#include "Common.h" +#include "Subsystems/GameInstanceSubsystem.h" #include "Templates/Tuple.h" +#include "Common.h" #include "AssetLookup.generated.h" class AActor; @@ -32,10 +33,13 @@ class UAnimSequence; //////////////////////////////////////////////////////////// UCLASS(MinimalAPI) -class UlxAssetLookup : public UObject +class UlxAssetLookup : public UGameInstanceSubsystem { GENERATED_BODY() +public: + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + private: TMap, FString> AssetPaths; diff --git a/Source/Integration/Common.h b/Source/Integration/Common.h index 3e7bb104..96b61abb 100644 --- a/Source/Integration/Common.h +++ b/Source/Integration/Common.h @@ -11,7 +11,7 @@ #pragma once #include - +#include "CommonActivatableWidget.h" #include "Common.generated.h" //////////////////////////////////////////////////////////// @@ -131,3 +131,21 @@ DECLARE_LOG_CATEGORY_EXTERN(LogLuprex, Display, All); // Messages about the Luprex integration with Unreal. // DECLARE_LOG_CATEGORY_EXTERN(LogLuprexIntegration, Display, All); + +//////////////////////////////////////////////////////////// +// +// UlxLuaWidget +// +//////////////////////////////////////////////////////////// + +class UlxLuaValues; + +UCLASS(BlueprintType) +class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Luprex|Miscellaneous") + void ReadLuaConfiguration(UlxLuaValues *Config); +}; diff --git a/Source/Integration/Integration.Build.cs b/Source/Integration/Integration.Build.cs index 9ddb568e..f8cf152c 100644 --- a/Source/Integration/Integration.Build.cs +++ b/Source/Integration/Integration.Build.cs @@ -7,6 +7,7 @@ public class Integration : ModuleRules public Integration(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + bUseUnity = false; PublicDependencyModuleNames.AddRange(new string[] { "Core", diff --git a/Source/Integration/LuaCall.cpp b/Source/Integration/LuaCall.cpp index e84d667a..42dd2b5d 100644 --- a/Source/Integration/LuaCall.cpp +++ b/Source/Integration/LuaCall.cpp @@ -2,7 +2,7 @@ #include "LuaCall.h" #include "LuprexGameModeBase.h" #include "Tangible.h" -#include "StringDecoder.h" +#include "StreamBuffer.h" #include "EdGraphSchema_K2.h" diff --git a/Source/Integration/LuaCallNode.cpp b/Source/Integration/LuaCallNode.cpp index 30a031bd..ee417892 100644 --- a/Source/Integration/LuaCallNode.cpp +++ b/Source/Integration/LuaCallNode.cpp @@ -2,7 +2,7 @@ #include "LuaCallNode.h" -#include "StringDecoder.h" +#include "StreamBuffer.h" #include "GameFramework/Actor.h" #include "BlueprintActionDatabaseRegistrar.h" diff --git a/Source/Integration/LuprexGameModeBase.cpp b/Source/Integration/LuprexGameModeBase.cpp index d10c5a6e..4462ab32 100644 --- a/Source/Integration/LuprexGameModeBase.cpp +++ b/Source/Integration/LuprexGameModeBase.cpp @@ -20,7 +20,6 @@ using namespace LpxCommonTypes; ALuprexGameModeBase::ALuprexGameModeBase() { TangibleManager = nullptr; - AssetLookup = nullptr; PlayerId = 0; EngineSeconds = 0.0; MustCallLookAtChanged = false; @@ -71,11 +70,6 @@ void ALuprexGameModeBase::ResetToInitialState() TangibleManager = nullptr; } - if (AssetLookup != nullptr) { - AssetLookup->ConditionalBeginDestroy(); - AssetLookup = nullptr; - } - // Stop the tick functions. FWorldDelegates::OnWorldPreActorTick.Remove(OnWorldPreActorTickHandle); FWorldDelegates::OnWorldPostActorTick.Remove(OnWorldPostActorTickHandle); @@ -274,10 +268,6 @@ void ALuprexGameModeBase::InitializeGlobalState() OnWorldPostActorTickHandle = FWorldDelegates::OnWorldPostActorTick.AddUObject(this, &ALuprexGameModeBase::OnWorldPostActorTick); } - // Initialize the asset lookup table. - AssetLookup = NewObject(this); - AssetLookup->RebuildIndex(); - // Initialize the tangible manager. TangibleManager = NewObject(this); TangibleManager->Init(this); diff --git a/Source/Integration/LuprexGameModeBase.h b/Source/Integration/LuprexGameModeBase.h index db7dfd80..8acdea73 100644 --- a/Source/Integration/LuprexGameModeBase.h +++ b/Source/Integration/LuprexGameModeBase.h @@ -6,31 +6,15 @@ #include "Engine/HitResult.h" #include "GameFramework/GameModeBase.h" #include "lpx-enginewrapper.hpp" -#include "StringDecoder.h" +#include "StreamBuffer.h" #include "TangibleManager.h" -#include "AssetLookup.h" #include "LuprexSockets.h" #include "TriggeredTask.h" #include "BreakToDebugger.h" -#include "Blueprint/UserWidget.h" -#include "Widgets/CommonActivatableWidgetContainer.h" -#include "CommonActivatableWidget.h" #include "LuprexGameModeBase.generated.h" -class UlxLuaValues; - -UCLASS(BlueprintType) -class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget -{ - GENERATED_BODY() - -public: - UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Luprex|Miscellaneous") - void ReadLuaConfiguration(UlxLuaValues *Config); -}; - /** - * + * */ UCLASS(BlueprintType) class INTEGRATION_API ALuprexGameModeBase : public AGameModeBase, public FRunnable @@ -90,9 +74,6 @@ public: FlxStreamBuffer &GetLuaCallBuffer() { return LuaCallBuffer; } - // Get the Asset Lookup table. - const UlxAssetLookup *GetAssetLookup() const { return AssetLookup; } - // Transfer console output from the Luprex engine to unreal. void UpdateConsoleOutput(); @@ -120,10 +101,6 @@ public: // Get the current Luprex Game Mode Base, given a Context object. static ALuprexGameModeBase *FromContext(const UObject *Context); - // Asset Lookup by Name. - UPROPERTY() - UlxAssetLookup *AssetLookup; - UPROPERTY() UlxTangibleManager *TangibleManager; diff --git a/Source/Integration/StringDecoder.h b/Source/Integration/StreamBuffer.h similarity index 100% rename from Source/Integration/StringDecoder.h rename to Source/Integration/StreamBuffer.h diff --git a/Source/Integration/StringDecoder.cpp b/Source/Integration/StringDecoder.cpp deleted file mode 100644 index b5390bca..00000000 --- a/Source/Integration/StringDecoder.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "StringDecoder.h" - - diff --git a/Source/Integration/Tangible.cpp b/Source/Integration/Tangible.cpp index ddc49e1c..08e0ba16 100644 --- a/Source/Integration/Tangible.cpp +++ b/Source/Integration/Tangible.cpp @@ -3,6 +3,7 @@ #include "Tangible.h" #include "TangibleManager.h" +#include "AssetLookup.h" #include "LuprexGameModeBase.h" #define DEFAULT_BLUEPRINT (TEXT("StaticMesh"))