Now passing FlxAnimationStep into the blueprint

This commit is contained in:
2023-09-19 22:08:15 -04:00
parent b74f9495fc
commit 1d8bdfc7bf
5 changed files with 222 additions and 191 deletions

View File

@@ -1,89 +1,13 @@
#include "AnimQueue.h"
FlxAnimStep FlxAnimQueueDecoder::ReadStep() {
FlxAnimStep result;
result.Hash = Decoder.read_uint64();
result.Body = Decoder.read_string_view();
return result;
FlxAnimationStep::FlxAnimationStep(uint64 hash, std::string_view body) {
Hash = hash;
Body.SetNum(body.size());
memcpy(Body.GetData(), body.data(), body.size());
}
FlxAnimField FlxAnimStepDecoder::ReadField() {
FlxAnimField result;
result.Name = Decoder.read_string_view();
result.Persistent = Decoder.read_bool();
result.Type = (ElxAnimValueType)Decoder.read_uint8();
switch (result.Type) {
case ElxAnimValueType::STRING: {
result.S = Decoder.read_string_view();
break;
}
case ElxAnimValueType::NUMBER: {
result.X = Decoder.read_double();
break;
}
case ElxAnimValueType::BOOLEAN: {
result.X = Decoder.read_bool() ? 1.0 : 0.0;
break;
}
case ElxAnimValueType::XYZ: {
result.X = Decoder.read_double();
result.Y = Decoder.read_double();
result.Z = Decoder.read_double();
break;
}
default: {
Decoder.set_at_eof();
result.Type = ElxAnimValueType::BOOLEAN;
result.X = 0;
break;
}
}
return result;
}
FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
FString result;
FlxAnimQueueDecoder decoder(queue);
while (!decoder.AtEOF()) {
FlxAnimStep step = decoder.ReadStep();
FString stepdebug = FlxAnimStepDecoder::DebugString(step.Body);
result.Appendf(TEXT("%s\n"), *stepdebug);
}
return result;
}
FString FlxAnimStepDecoder::DebugString(std::string_view body) {
FString result;
FlxAnimStepDecoder decoder(body);
bool first = true;
while (!decoder.AtEOF()) {
FlxAnimField field = decoder.ReadField();
if (!first) {
result.Append(TEXT(" "));
}
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
switch (field.Type) {
case ElxAnimValueType::STRING:
result.Append(FString(field.S.size(), (const UTF8CHAR*)field.S.data()));
break;
case ElxAnimValueType::NUMBER:
result.Appendf(TEXT("%lf"), field.X);
break;
case ElxAnimValueType::BOOLEAN:
result.Append((field.X) == 1.0 ? TEXT("true") : TEXT("false"));
break;
case ElxAnimValueType::XYZ:
result.Appendf(TEXT("%lf,%lf,%lf"), field.X, field.Y, field.Z);
break;
}
first = false;
}
return result;
}
bool FlxAnimStepDecoder::ClearProperties(const FString& prefix, UObject* obj) {
static bool ClearProperties(const FString& prefix, UObject* obj) {
UClass* uclass = obj->GetClass();
if (prefix.IsEmpty()) {
return false;
@@ -103,7 +27,7 @@ bool FlxAnimStepDecoder::ClearProperties(const FString& prefix, UObject* obj) {
return true;
}
bool FlxAnimStepDecoder::SetProperty(const FString& name, UObject* obj, const FlxAnimField& field) {
static bool SetProperty(const FString& name, UObject* obj, const FlxAnimationField& field) {
UClass* uclass = obj->GetClass();
FName nname(name);
switch (field.Type) {
@@ -140,28 +64,118 @@ bool FlxAnimStepDecoder::SetProperty(const FString& name, UObject* obj, const Fl
return false;
}
#pragma optimize("", off)
bool FlxAnimStepDecoder::UnpackInto(std::string_view body, const FString& prefix, bool preclear, UObject* obj) {
UClass* uclass = obj->GetClass();
FlxAnimStepDecoder decoder(body);
bool FlxAnimationStep::Unpack(const FString& prefix, UObject* into, bool preclear) 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, obj);
ok &= ClearProperties(prefix, into);
}
while (!decoder.AtEOF()) {
FlxAnimField field = decoder.ReadField();
FlxAnimationField field = decoder.ReadField();
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
ok &= SetProperty(prefix + sname, obj, field);
ok &= SetProperty(prefix + sname, 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);
}
void UlxAnimationStepLibrary::UnpackAnimationStep(const FlxAnimationStep& step,
const FString& prefix, UObject* into, bool preclear) {
step.Unpack(prefix, into, preclear);
};
FlxAnimationStepView FlxAnimQueueDecoder::ReadStep() {
FlxAnimationStepView result;
result.Hash = Decoder.read_uint64();
result.Body = Decoder.read_string_view();
return result;
}
FlxAnimationField FlxAnimationStepDecoder::ReadField() {
FlxAnimationField result;
result.Name = Decoder.read_string_view();
result.Persistent = Decoder.read_bool();
result.Type = (ElxAnimValueType)Decoder.read_uint8();
switch (result.Type) {
case ElxAnimValueType::STRING: {
result.S = Decoder.read_string_view();
break;
}
case ElxAnimValueType::NUMBER: {
result.X = Decoder.read_double();
break;
}
case ElxAnimValueType::BOOLEAN: {
result.X = Decoder.read_bool() ? 1.0 : 0.0;
break;
}
case ElxAnimValueType::XYZ: {
result.X = Decoder.read_double();
result.Y = Decoder.read_double();
result.Z = Decoder.read_double();
break;
}
default: {
Decoder.set_at_eof();
result.Type = ElxAnimValueType::BOOLEAN;
result.X = 0;
break;
}
}
return result;
}
FString FlxAnimationStepDecoder::DebugString(uint64 hash, std::string_view body) {
FString result;
FlxAnimationStepDecoder decoder(body);
result.Appendf(TEXT("Hash=%016llx"), hash);
while (!decoder.AtEOF()) {
FlxAnimationField field = decoder.ReadField();
result.Append(TEXT(" "));
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
switch (field.Type) {
case ElxAnimValueType::STRING:
result.Append(FString(field.S.size(), (const UTF8CHAR*)field.S.data()));
break;
case ElxAnimValueType::NUMBER:
result.Appendf(TEXT("%lf"), field.X);
break;
case ElxAnimValueType::BOOLEAN:
result.Append((field.X) == 1.0 ? TEXT("true") : TEXT("false"));
break;
case ElxAnimValueType::XYZ:
result.Appendf(TEXT("%lf,%lf,%lf"), field.X, field.Y, field.Z);
break;
}
}
return result;
}
FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
FString result;
FlxAnimQueueDecoder decoder(queue);
while (!decoder.AtEOF()) {
FlxAnimationStepView step = decoder.ReadStep();
FString stepdebug = FlxAnimationStepDecoder::DebugString(step.Hash, step.Body);
result.Appendf(TEXT("%s\n"), *stepdebug);
}
return result;
}
FlxAnimTracker::FlxAnimTracker() {
AQ.Empty();
FirstSeqno = 0;
HashToSeqno.Empty();
UnstartedSeqno = 0;
PlaybackMode = ElxAnimPlaybackMode::INVALID;
PlaybackMode = ElxAnimationMode::INVALID;
AbortedHashes.Empty();
}
@@ -195,10 +209,10 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
// after the matching record onto a stack of new records.
//
FlxAnimQueueDecoder decoder(encqueue);
TArray<FlxAnimStep> newsteps;
TArray<FlxAnimationStepView> newsteps;
int32 matchingseqno = -1;
while (!decoder.AtEOF()) {
FlxAnimStep step = decoder.ReadStep();
FlxAnimationStepView step = decoder.ReadStep();
int32* stepseq = HashToSeqno.Find(step.Hash);
if (stepseq == nullptr) {
newsteps.Emplace(step);
@@ -233,13 +247,13 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
//
if (UnstartedSeqno > (FirstSeqno + AQ.Num())) {
UnstartedSeqno = matchingseqno;
PlaybackMode = ElxAnimPlaybackMode::BLEND_TO_FINAL;
PlaybackMode = ElxAnimationMode::BlendToFinal;
}
// Transfer the new animations onto the queue.
//
while (!newsteps.IsEmpty()) {
FlxAnimStep step = newsteps.Pop();
FlxAnimationStepView step = newsteps.Pop();
int32 seqno = FirstSeqno + AQ.Num();
AQ.EmplaceLast(step.Hash, step.Body);
HashToSeqno.Emplace(step.Hash, seqno);
@@ -268,7 +282,7 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
} else {
UnstartedSeqno = FirstSeqno + AQ.Num() - 1;
}
PlaybackMode = ElxAnimPlaybackMode::WARP_TO_FINAL;
PlaybackMode = ElxAnimationMode::WarpToFinal;
}
}
@@ -279,15 +293,15 @@ TArray<uint64> FlxAnimTracker::GetAborted() {
return result;
}
ElxAnimPlaybackMode FlxAnimTracker::GetNextStep(FlxAnimStoredStep &step) {
ElxAnimationMode FlxAnimTracker::GetNextStep(FlxAnimationStep &step) {
int offset = UnstartedSeqno - FirstSeqno;
if (offset < AQ.Num()) {
step = AQ[offset];
return PlaybackMode;
} else {
step.Hash = 0;
step.Body = "";
return ElxAnimPlaybackMode::INVALID;
step.Body.Empty();
return ElxAnimationMode::INVALID;
}
}
@@ -296,6 +310,6 @@ void FlxAnimTracker::StartedStep(uint64 hash) {
check(offset < AQ.Num());
check(AQ[offset].Hash == hash);
UnstartedSeqno += 1;
PlaybackMode = ElxAnimPlaybackMode::START_ANIMATION;
PlaybackMode = ElxAnimationMode::StartAnimation;
}