More work on anim queues

This commit is contained in:
2023-10-12 18:15:56 -04:00
parent 334a95481d
commit f7249e4d29
3 changed files with 56 additions and 28 deletions

View File

@@ -29,9 +29,12 @@ static bool ClearProperties(const FString& prefix, UObject* obj) {
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();
FName nname(name);
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
FName nname(prefix + sname);
switch (field.Type) {
case ElxAnimValueType::STRING: {
FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname);
@@ -66,29 +69,35 @@ static bool SetProperty(const FString& name, UObject* obj, const FlxAnimationFie
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();
std::string_view body((const char*)(Body.GetData()), Body.Num());
FlxAnimationStepDecoder decoder(body);
bool ok = true;
if (preclear) {
ok &= ClearProperties(prefix, into);
}
bool ok = ClearProperties(prefix, into);
while (!decoder.AtEOF()) {
FlxAnimationField field = decoder.ReadField();
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
ok &= SetProperty(prefix + sname, into, field);
if (Finished && !field.Persistent) continue;
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;
}
FString UlxAnimationStepLibrary::AnimationStepDebugString(const FlxAnimationStep& step) {
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) {
step.Unpack(prefix, into, true);
step.Unpack(prefix, into);
}
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) {
return step.Finished;
}
@@ -149,8 +162,10 @@ double UlxAnimationStepLibrary::AnimationStepGetFloat(const FlxAnimationStep& st
return field.X;
}
#pragma optimize("", off)
FString UlxAnimationStepLibrary::AnimationStepGetString(const FlxAnimationStep& step, const FString& name) {
if (step.Finished && (name == TEXT("action"))) {
return TEXT("idle");
}
FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != ElxAnimValueType::STRING) return TEXT("");
return FString(field.S.size(), (const UTF8CHAR*)(field.S.data()));
@@ -210,12 +225,16 @@ FlxAnimationField FlxAnimationStepDecoder::ReadField() {
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;
FlxAnimationStepDecoder decoder(body);
result.Appendf(TEXT("Hash=%016llx"), hash);
if (injectidle) {
result.Appendf(TEXT(" action=idle"));
}
while (!decoder.AtEOF()) {
FlxAnimationField field = decoder.ReadField();
if (persistentonly && !field.Persistent) continue;
result.Append(TEXT(" "));
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
@@ -247,7 +266,7 @@ FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
FlxAnimQueueDecoder decoder(queue);
while (!decoder.AtEOF()) {
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);
}
return result;
@@ -339,6 +358,7 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
while (!newsteps.IsEmpty()) {
FlxAnimationStepView step = newsteps.Pop();
AQ.EmplaceLast(step.Hash, step.Body);
}
// If there are too many animations in AQ, discard
@@ -357,10 +377,13 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
}
FlxAnimationStep FlxAnimTracker::GetCurrentAnimation() {
FlxAnimationStep result;
for (int i = 0; i < AQ.Num(); i++) {
if (!AQ[i].Finished) {
return AQ[i];
}
}
return AQ.Last();
result = AQ.Last();
result.Hash = 0;
return result;
}

View File

@@ -58,6 +58,14 @@ public:
// 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
@@ -65,16 +73,10 @@ public:
// fail if there's a type mismatch. For example, "color=blue"
// cannot be stored in a property "color" of type int.
//
// 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.
// Automatically injects a boolean property "idle" representing
// whether the property's finished flag is set.
//
// If pre-clear is true, then all properties of the UObject
// starting with the specified prefix are cleared before
// unpacking the animation step.
//
bool Unpack(const FString& prefix, UObject* into, bool preclear = true) const;
bool Unpack(const FString& prefix, UObject* into) const;
// Auto-Execute
//
@@ -108,7 +110,10 @@ public:
static FString AnimationStepDebugString(const FlxAnimationStep& step);
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)
static bool AnimationStepIsIdle(const FlxAnimationStep &step);
@@ -241,7 +246,7 @@ public:
// 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);
};
////////////////////////////////////////////////