Now passing FlxAnimationStep into the blueprint
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user