void FExposedValueHandler::Initialize(FAnimNode_Base* AnimNode, UObject* AnimInstanceObject) { if(bInitialized) { return; } if (BoundFunction != NAME_None) { // we cant call FindFunction on anything but the game thread as it accesses a shared map in the object's class check(IsInGameThread()); Function = AnimInstanceObject->FindFunction(BoundFunction); check(Function); } else { Function = NULL; } // initialize copy records for(FExposedValueCopyRecord& CopyRecord : CopyRecords) { UProperty* SourceProperty = AnimInstanceObject->GetClass()->FindPropertyByName(CopyRecord.SourcePropertyName); check(SourceProperty); if(UArrayProperty* SourceArrayProperty = Cast<UArrayProperty>(SourceProperty)) { // the compiler should not be generating any code that calls down this path at the moment - it is untested check(false); // FScriptArrayHelper ArrayHelper(SourceArrayProperty, SourceProperty->ContainerPtrToValuePtr<uint8>(AnimInstanceObject)); // check(ArrayHelper.IsValidIndex(CopyRecord.SourceArrayIndex)); // CopyRecord.Source = ArrayHelper.GetRawPtr(CopyRecord.SourceArrayIndex); // CopyRecord.Size = ArrayHelper.Num() * SourceArrayProperty->Inner->GetSize(); } else { if(CopyRecord.SourceSubPropertyName != NAME_None) { void* Source = SourceProperty->ContainerPtrToValuePtr<uint8>(AnimInstanceObject, 0); UStructProperty* SourceStructProperty = CastChecked<UStructProperty>(SourceProperty); UProperty* SourceStructSubProperty = SourceStructProperty->Struct->FindPropertyByName(CopyRecord.SourceSubPropertyName); CopyRecord.Source = SourceStructSubProperty->ContainerPtrToValuePtr<uint8>(Source, CopyRecord.SourceArrayIndex); CopyRecord.Size = SourceStructSubProperty->GetSize(); CopyRecord.CachedBoolSourceProperty = Cast<UBoolProperty>(SourceStructSubProperty); CopyRecord.CachedSourceContainer = Source; } else { CopyRecord.Source = SourceProperty->ContainerPtrToValuePtr<uint8>(AnimInstanceObject, CopyRecord.SourceArrayIndex); CopyRecord.Size = SourceProperty->GetSize(); CopyRecord.CachedBoolSourceProperty = Cast<UBoolProperty>(SourceProperty); CopyRecord.CachedSourceContainer = AnimInstanceObject; } } if(UArrayProperty* DestArrayProperty = Cast<UArrayProperty>(CopyRecord.DestProperty)) { FScriptArrayHelper ArrayHelper(DestArrayProperty, CopyRecord.DestProperty->ContainerPtrToValuePtr<uint8>(AnimNode)); check(ArrayHelper.IsValidIndex(CopyRecord.DestArrayIndex)); CopyRecord.Dest = ArrayHelper.GetRawPtr(CopyRecord.DestArrayIndex); CopyRecord.CachedBoolDestProperty = Cast<UBoolProperty>(CopyRecord.DestProperty); if(CopyRecord.bInstanceIsTarget) { CopyRecord.CachedDestContainer = AnimInstanceObject; } else { CopyRecord.CachedDestContainer = AnimNode; } } else { CopyRecord.Dest = CopyRecord.DestProperty->ContainerPtrToValuePtr<uint8>(AnimNode, CopyRecord.DestArrayIndex); if(CopyRecord.bInstanceIsTarget) { CopyRecord.CachedDestContainer = AnimInstanceObject; CopyRecord.Dest = CopyRecord.DestProperty->ContainerPtrToValuePtr<uint8>(AnimInstanceObject, CopyRecord.DestArrayIndex); } else { CopyRecord.CachedDestContainer = AnimNode; } CopyRecord.CachedBoolDestProperty = Cast<UBoolProperty>(CopyRecord.DestProperty); CopyRecord.CachedStructDestProperty = Cast<UStructProperty>(CopyRecord.DestProperty); } } bInitialized = true; }