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

Binary file not shown.

View File

@@ -47,15 +47,15 @@ FString FlxAnimQueueDecoder::DebugString(std::string_view queue) {
FlxAnimQueueDecoder decoder(queue); FlxAnimQueueDecoder decoder(queue);
while (!decoder.AtEOF()) { while (!decoder.AtEOF()) {
FlxAnimStep step = decoder.ReadStep(); FlxAnimStep step = decoder.ReadStep();
FString stepdebug = FlxAnimStepDecoder::DebugString(step); FString stepdebug = FlxAnimStepDecoder::DebugString(step.Body);
result.Appendf(TEXT("%s\n"), *stepdebug); result.Appendf(TEXT("%s\n"), *stepdebug);
} }
return result; return result;
} }
FString FlxAnimStepDecoder::DebugString(const FlxAnimStep& step) { FString FlxAnimStepDecoder::DebugString(std::string_view body) {
FString result; FString result;
FlxAnimStepDecoder decoder(step); FlxAnimStepDecoder decoder(body);
bool first = true; bool first = true;
while (!decoder.AtEOF()) { while (!decoder.AtEOF()) {
FlxAnimField field = decoder.ReadField(); FlxAnimField field = decoder.ReadField();
@@ -83,6 +83,78 @@ FString FlxAnimStepDecoder::DebugString(const FlxAnimStep& step) {
return result; 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() { FlxAnimTracker::FlxAnimTracker() {
AQ.Empty(); AQ.Empty();

View File

@@ -141,11 +141,12 @@ class FlxAnimStepDecoder {
private: private:
FlxStringDecoder Decoder; FlxStringDecoder Decoder;
static bool ClearProperties(const FString& prefix, UObject* obj);
static bool SetProperty(const FString& name, UObject *obj, const FlxAnimField& value);
public: public:
// Initialize the FlxAnimStepDecoder from the FlxAnimStep. // Initialize the FlxAnimStepDecoder from the FlxAnimStep.
// //
FlxAnimStepDecoder(const FlxAnimStep &step) : Decoder(step.Body) {} FlxAnimStepDecoder(std::string_view body) : Decoder(body) {}
FlxAnimStepDecoder(const FlxAnimStoredStep& step) : Decoder(step.Body) {}
// Return true if the parser has reached the end of the string. // Return true if the parser has reached the end of the string.
// //
@@ -157,7 +158,33 @@ public:
// Convert an AnimStep to an FString. // Convert an AnimStep to an FString.
// //
static FString DebugString(const FlxAnimStep &step); static FString DebugString(std::string_view body);
// Unpack an AnimStep into a UObject
//
// Stores the key-value pairs of the animation step into
// properties of a UObject. For example, if the key-value
// pair "color=blue" is present in the AnimStep, then this
// routine tries to find a string property "color" in the
// UObject, and then it sets that property to "blue."
//
// 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
// contain one of the necessary properties. It can also
// 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.
//
// If pre-clear is true, then all properties of the UObject
// starting with the specified prefix are cleared before
// unpacking the animation step.
//
static bool UnpackInto(std::string_view body, const FString &prefix, bool preclear, UObject* obj);
}; };
//////////////////////////////////////////////// ////////////////////////////////////////////////

View File

@@ -104,6 +104,15 @@ void AIntegrationGameModeBase::MaybeTriggerUpdateTask(float deltaseconds) {
} }
} }
//#pragma optimize( "", off )
//void SetLocal(UObject* obj, const char *name, int value) {
// FString sname((const UTF8CHAR *)name);
// FName nname(sname);
// UClass* uclass = obj->GetClass();
// FProperty* fprop = FindFProperty<FProperty>(uclass, nname);
// FStructProperty* sprop = FindFProperty<FStructProperty>(uclass, nname);
//}
void AIntegrationGameModeBase::UpdateTangibles() { void AIntegrationGameModeBase::UpdateTangibles() {
if (!Playing) return; if (!Playing) return;
FlxLockedWrapper w(LockableWrapper); FlxLockedWrapper w(LockableWrapper);
@@ -130,6 +139,9 @@ void AIntegrationGameModeBase::UpdateTangibles() {
FlxAnimStoredStep step; FlxAnimStoredStep step;
ElxAnimPlaybackMode mode = t->AnimTracker.GetNextStep(step); ElxAnimPlaybackMode mode = t->AnimTracker.GetNextStep(step);
bool started = false; bool started = false;
if (mode != ElxAnimPlaybackMode::INVALID) {
FlxAnimStepDecoder::UnpackInto(step.Body, TEXT("aq"), true, t->Actor);
}
switch (mode) { switch (mode) {
case ElxAnimPlaybackMode::INVALID: case ElxAnimPlaybackMode::INVALID:
started = false; // Nothing to do. started = false; // Nothing to do.