More refactoring on Animation Queue Changed
This commit is contained in:
Binary file not shown.
BIN
Content/Luprex/lxUtilityMacroLibrary.uasset
LFS
Normal file
BIN
Content/Luprex/lxUtilityMacroLibrary.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "AnimQueue.h"
|
#include "AnimQueue.h"
|
||||||
|
#include "UtilityLibrary.h"
|
||||||
|
|
||||||
FlxAnimationStep::FlxAnimationStep(uint64 hash, std::string_view body) {
|
FlxAnimationStep::FlxAnimationStep(uint64 hash, std::string_view body) {
|
||||||
Finished = false;
|
Finished = false;
|
||||||
@@ -9,16 +10,14 @@ FlxAnimationStep::FlxAnimationStep(uint64 hash, std::string_view body) {
|
|||||||
Blueprint = UlxAnimationStepLibrary::AnimationStepGetString(*this, "bp");
|
Blueprint = UlxAnimationStepLibrary::AnimationStepGetString(*this, "bp");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ClearProperties(const FString& prefix, UObject* obj) {
|
static void ClearProperties(const FString& prefix, UObject* obj, FProperty *except) {
|
||||||
UClass* uclass = obj->GetClass();
|
UClass* uclass = obj->GetClass();
|
||||||
if (prefix.IsEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
FName prefixlo(prefix);
|
FName prefixlo(prefix);
|
||||||
FName prefixhi(prefix + TEXT("\xFFFF"));
|
FName prefixhi(prefix + TEXT("\xFFFF"));
|
||||||
for (TFieldIterator<FProperty> It(uclass); It; ++It)
|
for (TFieldIterator<FProperty> It(uclass); It; ++It)
|
||||||
{
|
{
|
||||||
FProperty* fprop = *It;
|
FProperty* fprop = *It;
|
||||||
|
if (fprop == except) continue;
|
||||||
bool match1 = (fprop->GetFName().Compare(prefixlo) > 0);
|
bool match1 = (fprop->GetFName().Compare(prefixlo) > 0);
|
||||||
bool match2 = (fprop->GetFName().Compare(prefixhi) < 0);
|
bool match2 = (fprop->GetFName().Compare(prefixhi) < 0);
|
||||||
if (match1 && match2) {
|
if (match1 && match2) {
|
||||||
@@ -26,7 +25,6 @@ static bool ClearProperties(const FString& prefix, UObject* obj) {
|
|||||||
fprop->ClearValue(pptr);
|
fprop->ClearValue(pptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
@@ -70,25 +68,66 @@ static bool SetProperty(const FString& prefix, UObject* obj, const FlxAnimationF
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
bool FlxAnimationStep::Unpack(const FString& prefix, UObject* into) const {
|
static FStructProperty *FindAnimationStepProperty(UClass *uclass, const FString &prefix) {
|
||||||
UClass* uclass = into->GetClass();
|
FName nname(prefix + TEXT("Animation Step"));
|
||||||
std::string_view body((const char*)(Body.GetData()), Body.Num());
|
FStructProperty* fprop = FindFProperty<FStructProperty>(uclass, nname);
|
||||||
|
if (fprop == nullptr) return nullptr;
|
||||||
|
if (fprop->Struct != TBaseStructure<FlxAnimationStep>::Get()) return nullptr;
|
||||||
|
return fprop;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma optimize("", off)
|
||||||
|
void UlxAnimationStepLibrary::UnpackAnimationStep(bool &bChanged, FString &Action, const FlxAnimationStep& step, UObject* target, const FString& prefix) {
|
||||||
|
bChanged = false;
|
||||||
|
Action = TEXT("");
|
||||||
|
|
||||||
|
if (prefix.IsEmpty()) {
|
||||||
|
UlxUtilityLibrary::Assert(false, TEXT("You may not pass an empty string for prefix"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UClass* uclass = target->GetClass();
|
||||||
|
std::string_view body((const char*)(step.Body.GetData()), step.Body.Num());
|
||||||
FlxAnimationStepDecoder decoder(body);
|
FlxAnimationStepDecoder decoder(body);
|
||||||
bool ok = ClearProperties(prefix, into);
|
|
||||||
|
FStructProperty* stepproperty = FindAnimationStepProperty(uclass, prefix);
|
||||||
|
if (stepproperty == nullptr) {
|
||||||
|
UE_LOG(LogBlueprint, Error, TEXT("Target object: %s Prefix: %s"), *(target->GetName()), *prefix);
|
||||||
|
UlxUtilityLibrary::Assert(false, TEXT("Target object does not have an variable named '<prefix> Animation Step'"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlxAnimationStep* stepstorage = stepproperty->ContainerPtrToValuePtr<FlxAnimationStep>(target);
|
||||||
|
uint64 oldhash = stepstorage->Hash;
|
||||||
|
|
||||||
|
FlxAnimationField actionfield;
|
||||||
|
actionfield.Name = "action";
|
||||||
|
actionfield.Persistent = false;
|
||||||
|
actionfield.Type = SimpleDynamicTag::STRING;
|
||||||
|
actionfield.S = "unknown";
|
||||||
|
|
||||||
|
// Decode everything. If an action field is found, save it for later.
|
||||||
|
ClearProperties(prefix, target, stepproperty);
|
||||||
while (!decoder.AtEOF()) {
|
while (!decoder.AtEOF()) {
|
||||||
FlxAnimationField field = decoder.ReadField();
|
FlxAnimationField field = decoder.ReadField();
|
||||||
if (Finished && !field.Persistent) continue;
|
if ((field.Type == SimpleDynamicTag::STRING) && (field.Name == "action")) {
|
||||||
ok &= SetProperty(prefix, into, field);
|
actionfield.S = field.S;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (Finished) {
|
if (step.Finished && !field.Persistent) continue;
|
||||||
FlxAnimationField field;
|
SetProperty(prefix, target, field);
|
||||||
field.Name = "action";
|
|
||||||
field.Persistent = false;
|
|
||||||
field.Type = SimpleDynamicTag::STRING;
|
|
||||||
field.S = "idle";
|
|
||||||
ok &= SetProperty(prefix, into, field);
|
|
||||||
}
|
}
|
||||||
return ok;
|
|
||||||
|
// Store the action field.
|
||||||
|
if (step.Finished) actionfield.S = "idle";
|
||||||
|
SetProperty(prefix, target, actionfield);
|
||||||
|
|
||||||
|
// Store the whole step.
|
||||||
|
*stepstorage = step;
|
||||||
|
|
||||||
|
// Return the correct values.
|
||||||
|
Action = FString(actionfield.S.size(), (const UTF8CHAR*)actionfield.S.data());
|
||||||
|
bChanged = (step.Hash != oldhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep& step) {
|
FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep& step) {
|
||||||
@@ -96,10 +135,6 @@ FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep
|
|||||||
return FlxAnimationStepDecoder::DebugString(step.Finished, step.Finished, step.Hash, body);
|
return FlxAnimationStepDecoder::DebugString(step.Finished, step.Finished, step.Hash, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlxAnimationStepLibrary::UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& prefix) {
|
|
||||||
step.Unpack(prefix, into);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FlxAnimationField FindAnimationFieldLL(const FlxAnimationStep& step, std::string_view name) {
|
static FlxAnimationField FindAnimationFieldLL(const FlxAnimationStep& step, std::string_view name) {
|
||||||
std::string_view body((const char*)(step.Body.GetData()), step.Body.Num());
|
std::string_view body((const char*)(step.Body.GetData()), step.Body.Num());
|
||||||
FlxAnimationStepDecoder decoder(body);
|
FlxAnimationStepDecoder decoder(body);
|
||||||
|
|||||||
@@ -36,34 +36,6 @@ public:
|
|||||||
FlxAnimationStep() : Finished(false), Hash(0), Body(), Blueprint() {}
|
FlxAnimationStep() : Finished(false), Hash(0), Body(), Blueprint() {}
|
||||||
FlxAnimationStep(uint64 h, std::string_view b);
|
FlxAnimationStep(uint64 h, std::string_view b);
|
||||||
|
|
||||||
// Unpack an AnimStep into a UObject
|
|
||||||
//
|
|
||||||
// Stores the key-value pairs of the animation step into
|
|
||||||
// properties of a UObject. For example, if the key-value
|
|
||||||
// pair "color=blue" is present in the AnimStep, then this
|
|
||||||
// routine tries to find a string property "color" in the
|
|
||||||
// UObject, and then it sets that property to "blue."
|
|
||||||
//
|
|
||||||
// The prefix is prepended to the key names. For example,
|
|
||||||
// if one of the key-value pairs is "color=blue", and the
|
|
||||||
// prefix is "aq", then the property "aqColor=blue" will be
|
|
||||||
// stored in the UObject.
|
|
||||||
//
|
|
||||||
// All properties of the UObject starting with the specified
|
|
||||||
// prefix are cleared before unpacking the animation step.
|
|
||||||
//
|
|
||||||
// Returns true if all of the key-value pairs in the
|
|
||||||
// animation step could be unpacked into fields of the UObject.
|
|
||||||
// This could fail, for instance, if the UObject just doesn't
|
|
||||||
// contain one of the necessary properties. It can also
|
|
||||||
// fail if there's a type mismatch. For example, "color=blue"
|
|
||||||
// cannot be stored in a property "color" of type int.
|
|
||||||
//
|
|
||||||
// Automatically injects a boolean property "idle" representing
|
|
||||||
// whether the property's finished flag is set.
|
|
||||||
//
|
|
||||||
bool Unpack(const FString& prefix, UObject* into) const;
|
|
||||||
|
|
||||||
// Auto-Execute
|
// Auto-Execute
|
||||||
//
|
//
|
||||||
// These functions automatically update certain actor
|
// These functions automatically update certain actor
|
||||||
@@ -95,8 +67,29 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Animation Step")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Animation Step")
|
||||||
static FString AnimationStepDebugString(const FlxAnimationStep& step);
|
static FString AnimationStepDebugString(const FlxAnimationStep& step);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "into"), Category = "Luprex|Animation Step")
|
// Stores the key-value pairs in properties of the target object.
|
||||||
static void UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& VariableNamePrefix = TEXT("aq"));
|
//
|
||||||
|
// The animation step contains key-value pairs. The goal of this function
|
||||||
|
// is to store these in properties of the target. The prefix parameter
|
||||||
|
// is prepended to the property names.
|
||||||
|
//
|
||||||
|
// For example, suppose the key-value pairs are "color=blue, speed=20",
|
||||||
|
// and suppose the prefix is "aq". In that case, two properties would
|
||||||
|
// be written: "aq Color" would be set to "blue", and "aq Speed" would be
|
||||||
|
// set to 20. In addition, a property "aq Animation Step" would
|
||||||
|
// be written, containing the entire animation step.
|
||||||
|
//
|
||||||
|
// If the step contains a key-value pair, but there is no corresponding
|
||||||
|
// property in the target, then the key-value pair is silently
|
||||||
|
// ignored. If the target contains properties that begin with the prefix,
|
||||||
|
// but which don't have any corresponding key-value pair, those properties
|
||||||
|
// are cleared.
|
||||||
|
//
|
||||||
|
// Returns 'Changed' if the hash-value of the "aq Animation Step" property
|
||||||
|
// has changed. Returns 'Action' string from the action=xxx property.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Animation Step")
|
||||||
|
static void UnpackAnimationStep(bool &bChanged, FString &Action, const FlxAnimationStep& step, UObject* target, const FString& VariableNamePrefix = TEXT("aq"));
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Animation Step")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Animation Step")
|
||||||
static bool AnimationStepEqual(const FlxAnimationStep &StepA, const FlxAnimationStep &StepB);
|
static bool AnimationStepEqual(const FlxAnimationStep &StepA, const FlxAnimationStep &StepB);
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ void UlxUtilityLibrary::CallFunctionByName(UObject *object, const FString &namep
|
|||||||
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// UFunction* function = object->FindFunction(FName(*fullname));
|
UFunction* function = object->FindFunction(FName(*fullname));
|
||||||
|
|
||||||
UClass *uclass = object->GetClass();
|
|
||||||
UFunction* function = uclass->FindFunctionByName(FName(*fullname));
|
|
||||||
if (function == nullptr) {
|
if (function == nullptr) {
|
||||||
function = object->FindFunction(FName(*fallback));
|
function = object->FindFunction(FName(*fallback));
|
||||||
if (function == nullptr) {
|
if (function == nullptr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user