More work on anim queues
This commit is contained in:
BIN
Content/TangibleActor.uasset
LFS
BIN
Content/TangibleActor.uasset
LFS
Binary file not shown.
@@ -29,9 +29,12 @@ static bool ClearProperties(const FString& prefix, UObject* obj) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetProperty(const FString& name, UObject* obj, const FlxAnimationField& field) {
|
#pragma optimize("", off)
|
||||||
|
|
||||||
|
static bool SetProperty(const FString& prefix, UObject* obj, const FlxAnimationField& field) {
|
||||||
UClass* uclass = obj->GetClass();
|
UClass* uclass = obj->GetClass();
|
||||||
FName nname(name);
|
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
|
||||||
|
FName nname(prefix + sname);
|
||||||
switch (field.Type) {
|
switch (field.Type) {
|
||||||
case ElxAnimValueType::STRING: {
|
case ElxAnimValueType::STRING: {
|
||||||
FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname);
|
FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname);
|
||||||
@@ -66,29 +69,35 @@ static bool SetProperty(const FString& name, UObject* obj, const FlxAnimationFie
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FlxAnimationStep::Unpack(const FString& prefix, UObject* into, bool preclear) const {
|
#pragma optimize("", off)
|
||||||
|
bool FlxAnimationStep::Unpack(const FString& prefix, UObject* into) const {
|
||||||
UClass* uclass = into->GetClass();
|
UClass* uclass = into->GetClass();
|
||||||
std::string_view body((const char*)(Body.GetData()), Body.Num());
|
std::string_view body((const char*)(Body.GetData()), Body.Num());
|
||||||
FlxAnimationStepDecoder decoder(body);
|
FlxAnimationStepDecoder decoder(body);
|
||||||
bool ok = true;
|
bool ok = ClearProperties(prefix, into);
|
||||||
if (preclear) {
|
|
||||||
ok &= ClearProperties(prefix, into);
|
|
||||||
}
|
|
||||||
while (!decoder.AtEOF()) {
|
while (!decoder.AtEOF()) {
|
||||||
FlxAnimationField field = decoder.ReadField();
|
FlxAnimationField field = decoder.ReadField();
|
||||||
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
|
if (Finished && !field.Persistent) continue;
|
||||||
ok &= SetProperty(prefix + sname, into, field);
|
ok &= SetProperty(prefix, into, field);
|
||||||
|
}
|
||||||
|
if (Finished) {
|
||||||
|
FlxAnimationField field;
|
||||||
|
field.Name = "action";
|
||||||
|
field.Persistent = false;
|
||||||
|
field.Type = ElxAnimValueType::STRING;
|
||||||
|
field.S = "idle";
|
||||||
|
ok &= SetProperty(prefix, into, field);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep& step) {
|
FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep& step) {
|
||||||
std::string_view body((const char*)(step.Body.GetData()), step.Body.Num());
|
std::string_view body((const char*)(step.Body.GetData()), step.Body.Num());
|
||||||
return FlxAnimationStepDecoder::DebugString(step.Hash, body);
|
return FlxAnimationStepDecoder::DebugString(step.Finished, step.Finished, step.Hash, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlxAnimationStepLibrary::UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& prefix) {
|
void UlxAnimationStepLibrary::UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& prefix) {
|
||||||
step.Unpack(prefix, into, true);
|
step.Unpack(prefix, into);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FlxAnimationField FindAnimationFieldLL(const FlxAnimationStep& step, std::string_view name) {
|
static FlxAnimationField FindAnimationFieldLL(const FlxAnimationStep& step, std::string_view name) {
|
||||||
@@ -133,6 +142,10 @@ void FlxAnimationStep::AutoUpdatePlane(FName *planep) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UlxAnimationStepLibrary::AnimationStepEqual(const FlxAnimationStep &stepa, const FlxAnimationStep &stepb) {
|
||||||
|
return (stepa.Finished == stepb.Finished) && (stepa.Hash == stepb.Hash);
|
||||||
|
}
|
||||||
|
|
||||||
bool UlxAnimationStepLibrary::AnimationStepIsIdle(const FlxAnimationStep &step) {
|
bool UlxAnimationStepLibrary::AnimationStepIsIdle(const FlxAnimationStep &step) {
|
||||||
return step.Finished;
|
return step.Finished;
|
||||||
}
|
}
|
||||||
@@ -149,8 +162,10 @@ double UlxAnimationStepLibrary::AnimationStepGetFloat(const FlxAnimationStep& st
|
|||||||
return field.X;
|
return field.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize("", off)
|
|
||||||
FString UlxAnimationStepLibrary::AnimationStepGetString(const FlxAnimationStep& step, const FString& name) {
|
FString UlxAnimationStepLibrary::AnimationStepGetString(const FlxAnimationStep& step, const FString& name) {
|
||||||
|
if (step.Finished && (name == TEXT("action"))) {
|
||||||
|
return TEXT("idle");
|
||||||
|
}
|
||||||
FlxAnimationField field = FindAnimationField(step, name);
|
FlxAnimationField field = FindAnimationField(step, name);
|
||||||
if (field.Type != ElxAnimValueType::STRING) return TEXT("");
|
if (field.Type != ElxAnimValueType::STRING) return TEXT("");
|
||||||
return FString(field.S.size(), (const UTF8CHAR*)(field.S.data()));
|
return FString(field.S.size(), (const UTF8CHAR*)(field.S.data()));
|
||||||
@@ -210,12 +225,16 @@ FlxAnimationField FlxAnimationStepDecoder::ReadField() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString FlxAnimationStepDecoder::DebugString(uint64 hash, std::string_view body) {
|
FString FlxAnimationStepDecoder::DebugString(bool injectidle, bool persistentonly, uint64 hash, std::string_view body) {
|
||||||
FString result;
|
FString result;
|
||||||
FlxAnimationStepDecoder decoder(body);
|
FlxAnimationStepDecoder decoder(body);
|
||||||
result.Appendf(TEXT("Hash=%016llx"), hash);
|
result.Appendf(TEXT("Hash=%016llx"), hash);
|
||||||
|
if (injectidle) {
|
||||||
|
result.Appendf(TEXT(" action=idle"));
|
||||||
|
}
|
||||||
while (!decoder.AtEOF()) {
|
while (!decoder.AtEOF()) {
|
||||||
FlxAnimationField field = decoder.ReadField();
|
FlxAnimationField field = decoder.ReadField();
|
||||||
|
if (persistentonly && !field.Persistent) continue;
|
||||||
result.Append(TEXT(" "));
|
result.Append(TEXT(" "));
|
||||||
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
|
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
|
||||||
result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
|
result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
|
||||||
@@ -247,7 +266,7 @@ FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
|
|||||||
FlxAnimQueueDecoder decoder(queue);
|
FlxAnimQueueDecoder decoder(queue);
|
||||||
while (!decoder.AtEOF()) {
|
while (!decoder.AtEOF()) {
|
||||||
FlxAnimationStepView step = decoder.ReadStep();
|
FlxAnimationStepView step = decoder.ReadStep();
|
||||||
FString stepdebug = FlxAnimationStepDecoder::DebugString(step.Hash, step.Body);
|
FString stepdebug = FlxAnimationStepDecoder::DebugString(false, false, step.Hash, step.Body);
|
||||||
result.Appendf(TEXT("%s\n"), *stepdebug);
|
result.Appendf(TEXT("%s\n"), *stepdebug);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -339,6 +358,7 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
|
|||||||
while (!newsteps.IsEmpty()) {
|
while (!newsteps.IsEmpty()) {
|
||||||
FlxAnimationStepView step = newsteps.Pop();
|
FlxAnimationStepView step = newsteps.Pop();
|
||||||
AQ.EmplaceLast(step.Hash, step.Body);
|
AQ.EmplaceLast(step.Hash, step.Body);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are too many animations in AQ, discard
|
// If there are too many animations in AQ, discard
|
||||||
@@ -357,10 +377,13 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlxAnimationStep FlxAnimTracker::GetCurrentAnimation() {
|
FlxAnimationStep FlxAnimTracker::GetCurrentAnimation() {
|
||||||
|
FlxAnimationStep result;
|
||||||
for (int i = 0; i < AQ.Num(); i++) {
|
for (int i = 0; i < AQ.Num(); i++) {
|
||||||
if (!AQ[i].Finished) {
|
if (!AQ[i].Finished) {
|
||||||
return AQ[i];
|
return AQ[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AQ.Last();
|
result = AQ.Last();
|
||||||
|
result.Hash = 0;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,14 @@ public:
|
|||||||
// routine tries to find a string property "color" in the
|
// routine tries to find a string property "color" in the
|
||||||
// UObject, and then it sets that property to "blue."
|
// 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
|
// Returns true if all of the key-value pairs in the
|
||||||
// animation step could be unpacked into fields of the UObject.
|
// animation step could be unpacked into fields of the UObject.
|
||||||
// This could fail, for instance, if the UObject just doesn't
|
// This could fail, for instance, if the UObject just doesn't
|
||||||
@@ -65,16 +73,10 @@ public:
|
|||||||
// fail if there's a type mismatch. For example, "color=blue"
|
// fail if there's a type mismatch. For example, "color=blue"
|
||||||
// cannot be stored in a property "color" of type int.
|
// cannot be stored in a property "color" of type int.
|
||||||
//
|
//
|
||||||
// The prefix is prepended to the key names. For example,
|
// Automatically injects a boolean property "idle" representing
|
||||||
// if one of the key-value pairs is "color=blue", and the
|
// whether the property's finished flag is set.
|
||||||
// prefix is "aq", then the property "aqColor=blue" will be
|
|
||||||
// stored in the UObject.
|
|
||||||
//
|
//
|
||||||
// If pre-clear is true, then all properties of the UObject
|
bool Unpack(const FString& prefix, UObject* into) const;
|
||||||
// starting with the specified prefix are cleared before
|
|
||||||
// unpacking the animation step.
|
|
||||||
//
|
|
||||||
bool Unpack(const FString& prefix, UObject* into, bool preclear = true) const;
|
|
||||||
|
|
||||||
// Auto-Execute
|
// Auto-Execute
|
||||||
//
|
//
|
||||||
@@ -108,7 +110,10 @@ public:
|
|||||||
static FString AnimationStepDebugString(const FlxAnimationStep& step);
|
static FString AnimationStepDebugString(const FlxAnimationStep& step);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "into"), Category = Luprex)
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "into"), Category = Luprex)
|
||||||
static void UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& VariableNamePrefix);
|
static void UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& VariableNamePrefix = TEXT("aq"));
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
||||||
|
static bool AnimationStepEqual(const FlxAnimationStep &StepA, const FlxAnimationStep &StepB);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
||||||
static bool AnimationStepIsIdle(const FlxAnimationStep &step);
|
static bool AnimationStepIsIdle(const FlxAnimationStep &step);
|
||||||
@@ -241,7 +246,7 @@ public:
|
|||||||
|
|
||||||
// Convert an AnimStep to an FString.
|
// Convert an AnimStep to an FString.
|
||||||
//
|
//
|
||||||
static FString DebugString(uint64 hash, std::string_view body);
|
static FString DebugString(bool injectidle, bool persistentonly, uint64 hash, std::string_view body);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user