Rearrange FormatDataLibrary to have less module coupling.
This commit is contained in:
@@ -797,3 +797,12 @@ void UlxAnimationStepLibrary::AnimationStepApplySkeletalMesh(const FlxAnimationS
|
||||
}
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxAnimationStepLibrary::FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(AnimationStepDebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,11 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Animation Step")
|
||||
static void AnimationStepApplySkeletalMesh(const FlxAnimationStep& step, bool FallbackToBP,
|
||||
USkeletalMeshComponent* MeshComp, USkeletalMesh* Fallback = nullptr);
|
||||
|
||||
// Allows you to pass an animation step to Format Message.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Animation Step")
|
||||
static FFormatArgumentData FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,9 +1,51 @@
|
||||
|
||||
#include "FormatDataLibrary.h"
|
||||
#include "LuaCall.h"
|
||||
#include "AnimQueue.h"
|
||||
#include "MovementComponentState.h"
|
||||
#include "Common.h"
|
||||
#include "Kismet/KismetTextLibrary.h"
|
||||
#include "UObject/UObjectIterator.h"
|
||||
|
||||
void UlxFormatDataLibrary::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
Super::Initialize(Collection);
|
||||
ScanForConverters();
|
||||
}
|
||||
|
||||
void UlxFormatDataLibrary::ScanForConverters()
|
||||
{
|
||||
Converters.Empty();
|
||||
for (TObjectIterator<UClass> It; It; ++It)
|
||||
{
|
||||
UClass* Class = *It;
|
||||
for (TFieldIterator<UFunction> FuncIt(Class, EFieldIteratorFlags::ExcludeSuper); FuncIt; ++FuncIt)
|
||||
{
|
||||
UFunction* Function = *FuncIt;
|
||||
|
||||
// Must have an AutoConvertedValue parameter.
|
||||
if (Function->FindPropertyByName(TEXT("AutoConvertedValue")) == nullptr) continue;
|
||||
|
||||
// Must have a Name parameter that is a string.
|
||||
FProperty* NameProp = Function->FindPropertyByName(TEXT("Name"));
|
||||
if (NameProp == nullptr) continue;
|
||||
if (CastField<FStrProperty>(NameProp) == nullptr) continue;
|
||||
|
||||
// Must return FFormatArgumentData.
|
||||
FStructProperty* ReturnProp = CastField<FStructProperty>(Function->GetReturnProperty());
|
||||
if (ReturnProp == nullptr) continue;
|
||||
if (ReturnProp->Struct->GetFName() != TEXT("FormatArgumentData")) continue;
|
||||
|
||||
// Must have exactly three properties: AutoConvertedValue, Name, and ReturnValue.
|
||||
int PropCount = 0;
|
||||
for (TFieldIterator<FProperty> PropIt(Function); PropIt; ++PropIt) PropCount++;
|
||||
if (PropCount != 3) continue;
|
||||
|
||||
Converters.Add(Function);
|
||||
}
|
||||
}
|
||||
for (UFunction* Func : Converters)
|
||||
{
|
||||
UE_LOG(LogLuprexIntegration, Display, TEXT("FormatData converter: %s::%s"), *Func->GetOuterUClass()->GetName(), *Func->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
@@ -149,33 +191,6 @@ FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataTransform(const FTra
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(AutoConvertedValue->DebugString());
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(UlxAnimationStepLibrary::AnimationStepDebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(UlxMovementComponentStateLibrary::DebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBlank(const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
|
||||
@@ -2,9 +2,26 @@
|
||||
//
|
||||
// FormatDataLibrary.h
|
||||
//
|
||||
// Functions that convert data into
|
||||
// FFormatArgumentData structs, so that the data
|
||||
// can be passed to FText::Format.
|
||||
// The 'Format Message' and 'Format Log Message' nodes can format
|
||||
// ints, strings, vectors, and more. To support a new data type,
|
||||
// all you need to do is implement a blueprint-callable conversion
|
||||
// function like this one:
|
||||
//
|
||||
// UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"))
|
||||
// static FFormatArgumentData FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name);
|
||||
//
|
||||
// This conversion function must have three things:
|
||||
//
|
||||
// * It returns FFormatArgumentData
|
||||
// * It accepts 'AutoConvertedValue', the value you want to format,
|
||||
// * It accepts 'Name', which must be copied into the FFormatArgumentData.
|
||||
//
|
||||
// The parameter names are required: you must use exactly these parameter
|
||||
// names if you want this to act as a conversion function. You can put a
|
||||
// conversion function like that anywhere in the system, in any UCLASS.
|
||||
// This module will find and use it.
|
||||
//
|
||||
// This file also contains the built-in converters for standard types.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -15,31 +32,40 @@
|
||||
#include "HAL/Platform.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "EditorSubsystem.h"
|
||||
|
||||
#include "FormatDataLibrary.generated.h"
|
||||
|
||||
class UlxLuaValues;
|
||||
struct FlxAnimationStep;
|
||||
struct FlxMovementComponentState;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UlxFormatDataLibrary
|
||||
//
|
||||
// The FormatLogMessage K2Node scans this library using
|
||||
// reflection, looking for functions that have a parameter
|
||||
// named "AutoConvertedValue". It uses the type of that
|
||||
// parameter to determine which function to call for a given
|
||||
// pin type.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
UCLASS(MinimalAPI)
|
||||
class UlxFormatDataLibrary : public UBlueprintFunctionLibrary
|
||||
class UlxFormatDataLibrary : public UEditorSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
|
||||
// Get all converter functions (functions with an
|
||||
// "AutoConvertedValue" parameter) found across all
|
||||
// loaded classes.
|
||||
//
|
||||
const TArray<UFunction*>& GetConverters() const { return Converters; }
|
||||
|
||||
private:
|
||||
// Scan all loaded classes for converter functions.
|
||||
//
|
||||
void ScanForConverters();
|
||||
|
||||
// Cached list of converter functions.
|
||||
//
|
||||
TArray<UFunction*> Converters;
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name);
|
||||
@@ -89,15 +115,6 @@ public:
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataTransform(const FTransform &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name);
|
||||
|
||||
// For pins that were never connected.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
#include "FormatMessage.h"
|
||||
#include "Editor.h"
|
||||
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "BlueprintActionDatabaseRegistrar.h"
|
||||
@@ -305,11 +306,11 @@ UFunction *ToFormatArgumentData(const UEdGraphSchema_K2 *Schema, const FEdGraphP
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataBlank));
|
||||
}
|
||||
|
||||
// Try to find a match in the UlxFormatDataLibrary.
|
||||
// Scan the cached converter list for a matching type.
|
||||
//
|
||||
for (auto It = TFieldIterator<UFunction>(UlxFormatDataLibrary::StaticClass()); It; ++It)
|
||||
UlxFormatDataLibrary* FormatDataLib = GEditor->GetEditorSubsystem<UlxFormatDataLibrary>();
|
||||
for (UFunction* Function : FormatDataLib->GetConverters())
|
||||
{
|
||||
UFunction* Function = *It;
|
||||
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("AutoConvertedValue"));
|
||||
FEdGraphPinType ValuePinType;
|
||||
bool Convertible = Schema->ConvertPropertyToPinType(ValueProperty, ValuePinType);
|
||||
@@ -319,7 +320,7 @@ UFunction *ToFormatArgumentData(const UEdGraphSchema_K2 *Schema, const FEdGraphP
|
||||
}
|
||||
|
||||
// A general handler for Enums. You can override this for specific enums by
|
||||
// putting that particular enum into the UlxFormatDataLibrary.
|
||||
// putting that particular enum into any class with an AutoConvertedValue function.
|
||||
//
|
||||
if ((PinType.PinCategory == UEdGraphSchema_K2::PC_Byte) && (nullptr != Cast<const UEnum>(PinType.PinSubCategoryObject)))
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@ public class Integration : ModuleRules
|
||||
"BlueprintGraph",
|
||||
"UMG",
|
||||
"UMGEditor",
|
||||
"EditorSubsystem",
|
||||
});
|
||||
|
||||
// Uncomment if you are using Slate UI
|
||||
|
||||
@@ -543,5 +543,12 @@ void UlxLuaValues::ReadBoolean(ElxSuccessOrWrongType &Status, bool &Result, bool
|
||||
Result = FlxStreamBuffer(Data[Cursor++]).read_bool();
|
||||
}
|
||||
|
||||
|
||||
FFormatArgumentData UlxLuaValues::FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(AutoConvertedValue->DebugString());
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,4 +277,9 @@ public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "Status"), Category = "Luprex|Lua Value Array")
|
||||
void ReadBoolean(ElxSuccessOrWrongType &Status, bool &Result, bool LogErrorOnWrongType = false);
|
||||
|
||||
// Allows you to pass a LuaValues to Format Message.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Lua Value Array")
|
||||
static FFormatArgumentData FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name);
|
||||
};
|
||||
|
||||
@@ -62,3 +62,12 @@ FlxMovementComponentState UlxMovementComponentStateLibrary::SetFakeMovementCompo
|
||||
}
|
||||
return State;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxMovementComponentStateLibrary::FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(DebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -126,4 +126,9 @@ public:
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Movement Component State", meta = (DefaultToSelf = "Actor", AutoCreateRefTerm = "State"))
|
||||
static FlxMovementComponentState SetFakeMovementComponentState(AActor *Actor, const FlxMovementComponentState &State);
|
||||
|
||||
// Allows you to pass a MovementComponentState to Format Message.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Movement Component State")
|
||||
static FFormatArgumentData FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user