Implement code to unpack anim steps into UObject

This commit is contained in:
2023-09-18 19:24:52 -04:00
parent fb65d23230
commit b74f9495fc
4 changed files with 119 additions and 8 deletions

View File

@@ -47,15 +47,15 @@ FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
FlxAnimQueueDecoder decoder(queue);
while (!decoder.AtEOF()) {
FlxAnimStep step = decoder.ReadStep();
FString stepdebug = FlxAnimStepDecoder::DebugString(step);
FString stepdebug = FlxAnimStepDecoder::DebugString(step.Body);
result.Appendf(TEXT("%s\n"), *stepdebug);
}
return result;
}
FString FlxAnimStepDecoder::DebugString(const FlxAnimStep& step) {
FString FlxAnimStepDecoder::DebugString(std::string_view body) {
FString result;
FlxAnimStepDecoder decoder(step);
FlxAnimStepDecoder decoder(body);
bool first = true;
while (!decoder.AtEOF()) {
FlxAnimField field = decoder.ReadField();
@@ -83,6 +83,78 @@ FString FlxAnimStepDecoder::DebugString(const FlxAnimStep& step) {
return result;
}
bool FlxAnimStepDecoder::ClearProperties(const FString& prefix, UObject* obj) {
UClass* uclass = obj->GetClass();
if (prefix.IsEmpty()) {
return false;
}
FName prefixlo(prefix);
FName prefixhi(prefix + TEXT("\xFFFF"));
for (TFieldIterator<FProperty> It(uclass); It; ++It)
{
FProperty* fprop = *It;
bool match1 = (fprop->GetFName().Compare(prefixlo) > 0);
bool match2 = (fprop->GetFName().Compare(prefixhi) < 0);
if (match1 && match2) {
uint8* pptr = fprop->ContainerPtrToValuePtr<uint8>(obj);
fprop->ClearValue(pptr);
}
}
return true;
}
bool FlxAnimStepDecoder::SetProperty(const FString& name, UObject* obj, const FlxAnimField& field) {
UClass* uclass = obj->GetClass();
FName nname(name);
switch (field.Type) {
case ElxAnimValueType::STRING: {
FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname);
if (fprop == nullptr) return false;
FString* pptr = fprop->ContainerPtrToValuePtr<FString>(obj);
*pptr = FString(field.S.size(), (const UTF8CHAR*)field.S.data());
return true;
}
case ElxAnimValueType::NUMBER: {
FDoubleProperty* fprop = FindFProperty<FDoubleProperty>(uclass, nname);
if (fprop == nullptr) return false;
double* pptr = fprop->ContainerPtrToValuePtr<double>(obj);
fprop->SetPropertyValue(pptr, field.X);
return true;
}
case ElxAnimValueType::BOOLEAN: {
FBoolProperty* fprop = FindFProperty<FBoolProperty>(uclass, nname);
if (fprop == nullptr) return false;
uint8* pptr = fprop->ContainerPtrToValuePtr<uint8>(obj);
fprop->SetPropertyValue(pptr, (field.X == 1.0));
return true;
}
case ElxAnimValueType::XYZ: {
FStructProperty* fprop = FindFProperty<FStructProperty>(uclass, nname);
if (fprop == nullptr) return false;
if (fprop->Struct != TBaseStructure<FVector>::Get()) return false;
FVector* pptr = fprop->ContainerPtrToValuePtr<FVector>(obj);
*pptr = FVector(field.X, field.Y, field.Z);
return true;
}
}
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 ok = true;
if (preclear) {
ok &= ClearProperties(prefix, obj);
}
while (!decoder.AtEOF()) {
FlxAnimField field = decoder.ReadField();
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
ok &= SetProperty(prefix + sname, obj, field);
}
return ok;
}
FlxAnimTracker::FlxAnimTracker() {
AQ.Empty();