UActorComponent* FComponentVisualizer::GetComponentFromPropertyName(const AActor* CompOwner, const FPropertyNameAndIndex& Property) { UActorComponent* ResultComp = NULL; if(CompOwner && Property.IsValid()) { UClass* ActorClass = CompOwner->GetClass(); UProperty* Prop = FindField<UProperty>(ActorClass, Property.Name); if (UObjectProperty* ObjectProp = Cast<UObjectProperty>(Prop)) { UObject* Object = ObjectProp->GetObjectPropertyValue(ObjectProp->ContainerPtrToValuePtr<void>(CompOwner, Property.Index)); ResultComp = Cast<UActorComponent>(Object); } else if (UArrayProperty* ArrayProp = Cast<UArrayProperty>(Prop)) { if (UObjectProperty* InnerProp = Cast<UObjectProperty>(ArrayProp->Inner)) { FScriptArrayHelper ArrayHelper(ArrayProp, ArrayProp->ContainerPtrToValuePtr<void>(CompOwner)); UObject* Object = InnerProp->GetObjectPropertyValue(ArrayHelper.GetRawPtr(Property.Index)); ResultComp = Cast<UActorComponent>(Object); } } } return ResultComp; }
uint8* UAnimSequenceBase::FindNotifyPropertyData(int32 NotifyIndex, UArrayProperty*& ArrayProperty) { // initialize to NULL ArrayProperty = NULL; if(Notifies.IsValidIndex(NotifyIndex)) { // find Notifies property start point UProperty* Property = FindField<UProperty>(GetClass(), TEXT("Notifies")); // found it and if it is array if(Property && Property->IsA(UArrayProperty::StaticClass())) { // find Property Value from UObject we got uint8* PropertyValue = Property->ContainerPtrToValuePtr<uint8>(this); // it is array, so now get ArrayHelper and find the raw ptr of the data ArrayProperty = CastChecked<UArrayProperty>(Property); FScriptArrayHelper ArrayHelper(ArrayProperty, PropertyValue); if(ArrayProperty->Inner && NotifyIndex < ArrayHelper.Num()) { //Get property data based on selected index return ArrayHelper.GetRawPtr(NotifyIndex); } } } return NULL; }
bool FStructureEditorUtils::Fill_MakeStructureDefaultValue(const UProperty* Property, uint8* PropertyData) { bool bResult = true; if (const UStructProperty* StructProperty = Cast<const UStructProperty>(Property)) { if (const UUserDefinedStruct* InnerStruct = Cast<const UUserDefinedStruct>(StructProperty->Struct)) { bResult &= Fill_MakeStructureDefaultValue(InnerStruct, PropertyData); } } else if (const UArrayProperty* ArrayProp = Cast<const UArrayProperty>(Property)) { StructProperty = Cast<const UStructProperty>(ArrayProp->Inner); const UUserDefinedStruct* InnerStruct = StructProperty ? Cast<const UUserDefinedStruct>(StructProperty->Struct) : NULL; if(InnerStruct) { FScriptArrayHelper ArrayHelper(ArrayProp, PropertyData); for (int32 Index = 0; Index < ArrayHelper.Num(); ++Index) { uint8* const ValuePtr = ArrayHelper.GetRawPtr(Index); bResult &= Fill_MakeStructureDefaultValue(InnerStruct, ValuePtr); } } } return bResult; }
const TCHAR* UArrayProperty::ImportText_Internal( const TCHAR* Buffer, void* Data, int32 PortFlags, UObject* Parent, FOutputDevice* ErrorText ) const { checkSlow(Inner); if ( *Buffer++ != TCHAR('(') ) { return NULL; } FScriptArrayHelper ArrayHelper(this, Data); // only clear the array if we're not importing localized text if ( (PortFlags&PPF_LocalizedOnly) == 0 ) { ArrayHelper.EmptyValues(); } SkipWhitespace(Buffer); int32 Index = 0; ArrayHelper.ExpandForIndex(0); while ((Buffer != NULL) && (*Buffer != TCHAR(')'))) { SkipWhitespace(Buffer); if (*Buffer != TCHAR(',')) { // Parse the item Buffer = Inner->ImportText(Buffer, ArrayHelper.GetRawPtr(Index), PortFlags | PPF_Delimited, Parent, ErrorText); if(!Buffer) { return NULL; } SkipWhitespace(Buffer); } if (*Buffer == TCHAR(',')) { Buffer++; Index++; ArrayHelper.ExpandForIndex(Index); } else { break; } } // Make sure we ended on a ) if (*Buffer++ != TCHAR(')')) { return NULL; } return Buffer; }
void UArrayProperty::DestroyValueInternal( void* Dest ) const { FScriptArrayHelper ArrayHelper(this, Dest); ArrayHelper.EmptyValues(); //@todo UE4 potential double destroy later from this...would be ok for a script array, but still ((FScriptArray*)Dest)->~FScriptArray(); }
void UKismetArrayLibrary::GenericArray_Clear(void* TargetArray, const UArrayProperty* ArrayProp) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); ArrayHelper.EmptyValues(); } }
//------------------------------------------------------------------------------ static int32 LinkerPlaceholderObjectImpl::ResolvePlaceholderValues(const TArray<const UProperty*>& PropertyChain, int32 ChainIndex, uint8* ValueAddress, UObject* OldValue, UObject* ReplacementValue) { int32 ReplacementCount = 0; for (int32 PropertyIndex = ChainIndex; PropertyIndex >= 0; --PropertyIndex) { const UProperty* Property = PropertyChain[PropertyIndex]; if (PropertyIndex == 0) { #if USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS check(Property->IsA<UObjectProperty>()); #endif // USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS const UObjectProperty* ReferencingProperty = (const UObjectProperty*)Property; if (ReferencingProperty->GetObjectPropertyValue(ValueAddress) == OldValue) { // @TODO: use an FArchiver with ReferencingProperty->SerializeItem() // so that we can utilize CheckValidObject() ReferencingProperty->SetObjectPropertyValue(ValueAddress, ReplacementValue); // @TODO: unfortunately, this is currently protected //ReferencingProperty->CheckValidObject(ValueAddress); ++ReplacementCount; } } else if (const UArrayProperty* ArrayProperty = Cast<const UArrayProperty>(Property)) { #if USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS const UProperty* NextProperty = PropertyChain[PropertyIndex - 1]; check(NextProperty == ArrayProperty->Inner); #endif // USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS // because we can't know which array entry was set with a reference // to this object, we have to comb through them all FScriptArrayHelper ArrayHelper(ArrayProperty, ValueAddress); for (int32 ArrayIndex = 0; ArrayIndex < ArrayHelper.Num(); ++ArrayIndex) { uint8* MemberAddress = ArrayHelper.GetRawPtr(ArrayIndex); ReplacementCount += ResolvePlaceholderValues(PropertyChain, PropertyIndex - 1, MemberAddress, OldValue, ReplacementValue); } // the above recursive call chewed through the rest of the // PropertyChain, no need to keep on here break; } else { const UProperty* NextProperty = PropertyChain[PropertyIndex - 1]; #if USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS check(NextProperty->GetOuter() == Property); #endif // USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS ValueAddress = Property->ContainerPtrToValuePtr<uint8>(ValueAddress, /*ArrayIndex =*/0); } } return ReplacementCount; }
int32 UKismetArrayLibrary::GenericArray_Length(const void* TargetArray, const UArrayProperty* ArrayProp) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); return ArrayHelper.Num(); } return 0; }
int32 UKismetArrayLibrary::GenericArray_LastIndex(const void* TargetArray, const UArrayProperty* ArrayProp) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); return ArrayHelper.Num() - 1; } return INDEX_NONE; }
int32 UKismetArrayLibrary::GenericArray_Add(void* TargetArray, const UArrayProperty* ArrayProp, const void* NewItem) { int32 NewIndex = INDEX_NONE; if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); UProperty* InnerProp = ArrayProp->Inner; NewIndex = ArrayHelper.AddValue(); InnerProp->CopySingleValueToScriptVM(ArrayHelper.GetRawPtr(NewIndex), NewItem); } return NewIndex; }
/** * Creates new copies of components * * @param Data pointer to the address of the instanced object referenced by this UComponentProperty * @param DefaultData pointer to the address of the default value of the instanced object referenced by this UComponentProperty * @param Owner the object that contains this property's data * @param InstanceGraph contains the mappings of instanced objects and components to their templates */ void UArrayProperty::InstanceSubobjects( void* Data, void const* DefaultData, UObject* Owner, FObjectInstancingGraph* InstanceGraph ) { if( Data && Inner->ContainsInstancedObjectProperty()) { FScriptArrayHelper ArrayHelper(this, Data); FScriptArrayHelper DefaultArrayHelper(this, DefaultData); for( int32 ElementIndex = 0; ElementIndex < ArrayHelper.Num(); ElementIndex++ ) { uint8* DefaultValue = (DefaultData && ElementIndex < DefaultArrayHelper.Num()) ? DefaultArrayHelper.GetRawPtr(ElementIndex) : NULL; Inner->InstanceSubobjects( ArrayHelper.GetRawPtr(ElementIndex), DefaultValue, Owner, InstanceGraph ); } } }
void USpeedTreeImportData::SaveOptions() { int32 PortFlags = 0; for (UProperty* Property = GetClass()->PropertyLink; Property; Property = Property->PropertyLinkNext) { if (!Property->HasAnyPropertyFlags(CPF_Config)) { continue; } FString Section = TEXT("SpeedTree_Import_UI_Option_") + GetClass()->GetName(); FString Key = Property->GetName(); const bool bIsPropertyInherited = Property->GetOwnerClass() != GetClass(); UObject* SuperClassDefaultObject = GetClass()->GetSuperClass()->GetDefaultObject(); UArrayProperty* Array = dynamic_cast<UArrayProperty*>(Property); if (Array) { FConfigSection* Sec = GConfig->GetSectionPrivate(*Section, 1, 0, *GEditorPerProjectIni); check(Sec); Sec->Remove(*Key); FScriptArrayHelper_InContainer ArrayHelper(Array, this); for (int32 i = 0; i < ArrayHelper.Num(); i++) { FString Buffer; Array->Inner->ExportTextItem(Buffer, ArrayHelper.GetRawPtr(i), ArrayHelper.GetRawPtr(i), this, PortFlags); Sec->Add(*Key, *Buffer); } } else { TCHAR TempKey[MAX_SPRINTF] = TEXT(""); for (int32 Index = 0; Index < Property->ArrayDim; Index++) { if (Property->ArrayDim != 1) { FCString::Sprintf(TempKey, TEXT("%s[%i]"), *Property->GetName(), Index); Key = TempKey; } FString Value; Property->ExportText_InContainer(Index, Value, this, this, this, PortFlags); GConfig->SetString(*Section, *Key, *Value, *GEditorPerProjectIni); } } } GConfig->Flush(0); }
// Clears the value of the given property. void ClearPropertyValue( UProperty* Property, UProperty* Outer, void* Data, int32 ArrayIndex ) { UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Outer); if (ArrayProperty != nullptr) { check(ArrayProperty->Inner == Property) FScriptArrayHelper ArrayHelper(ArrayProperty, ArrayProperty->template ContainerPtrToValuePtr<void>(Data)); ArrayIndex = ArrayHelper.AddValue(); } Property->ClearValue_InContainer(Data, ArrayIndex); }
void UKismetArrayLibrary::GenericArray_Resize(void* TargetArray, const UArrayProperty* ArrayProp, int32 Size) { if( TargetArray ) { if(Size >= 0) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); ArrayHelper.Resize(Size); } else { UE_LOG(LogArray, Warning, TEXT("Attempted to resize an array using negative size: Array = %s, Size = %d!"), *ArrayProp->GetName(), Size); } } }
void UKismetArrayLibrary::GenericArray_Remove(void* TargetArray, const UArrayProperty* ArrayProp, int32 IndexToRemove) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); if( ArrayHelper.IsValidIndex(IndexToRemove) ) { ArrayHelper.RemoveValues(IndexToRemove, 1); } else { UE_LOG(LogArray, Warning, TEXT("Attempted to remove an item from an invalid index from array %s [%d/%d]!"), *ArrayProp->GetName(), IndexToRemove, GetLastIndex(ArrayHelper)); } } }
void UKismetArrayLibrary::GenericArray_Remove(void* TargetArray, const UArrayProperty* ArrayProp, int32 IndexToRemove) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); if( ArrayHelper.IsValidIndex(IndexToRemove) ) { ArrayHelper.RemoveValues(IndexToRemove, 1); } else { FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Attempted to remove an item from an invalid index from array %s [%d/%d]!"), *ArrayProp->GetName(), IndexToRemove, GetLastIndex(ArrayHelper)), ELogVerbosity::Warning); } } }
void UKismetArrayLibrary::GenericArray_Resize(void* TargetArray, const UArrayProperty* ArrayProp, int32 Size) { if( TargetArray ) { if(Size >= 0) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); ArrayHelper.Resize(Size); } else { FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Attempted to resize an array using negative size: Array = %s, Size = %d!"), *ArrayProp->GetName(), Size), ELogVerbosity::Warning); } } }
void UKismetArrayLibrary::GenericArray_Shuffle(void* TargetArray, const UArrayProperty* ArrayProp) { if (TargetArray) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); int32 LastIndex = ArrayHelper.Num() - 1; for (int32 i = 0; i < LastIndex; ++i) { int32 Index = FMath::RandRange(0, LastIndex); if (i != Index) { ArrayHelper.SwapValues(i, Index); } } } }
FComponentVisualizer::FPropertyNameAndIndex FComponentVisualizer::GetComponentPropertyName(const UActorComponent* Component) { if (Component) { const AActor* CompOwner = Component->GetOwner(); if (CompOwner) { // Iterate over UObject* fields of this actor UClass* ActorClass = CompOwner->GetClass(); for (TFieldIterator<UObjectProperty> It(ActorClass); It; ++It) { // See if this property points to the component in question UObjectProperty* ObjectProp = *It; for (int32 Index = 0; Index < ObjectProp->ArrayDim; ++Index) { UObject* Object = ObjectProp->GetObjectPropertyValue(ObjectProp->ContainerPtrToValuePtr<void>(CompOwner, Index)); if (Object == Component) { // It does! Return this name return FPropertyNameAndIndex(ObjectProp->GetFName(), Index); } } } // If nothing found, look in TArray<UObject*> fields for (TFieldIterator<UArrayProperty> It(ActorClass); It; ++It) { UArrayProperty* ArrayProp = *It; if (UObjectProperty* InnerProp = Cast<UObjectProperty>(It->Inner)) { FScriptArrayHelper ArrayHelper(ArrayProp, ArrayProp->ContainerPtrToValuePtr<void>(CompOwner)); for (int32 Index = 0; Index < ArrayHelper.Num(); ++Index) { UObject* Object = InnerProp->GetObjectPropertyValue(ArrayHelper.GetRawPtr(Index)); if (Object == Component) { return FPropertyNameAndIndex(ArrayProp->GetFName(), Index); } } } } } } // Didn't find actor property referencing this component return FPropertyNameAndIndex(); }
void UKismetArrayLibrary::GenericArray_Get(void* TargetArray, const UArrayProperty* ArrayProp, int32 Index, void* Item) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); UProperty* InnerProp = ArrayProp->Inner; if( ArrayHelper.IsValidIndex(Index) ) { InnerProp->CopyCompleteValueFromScriptVM(Item, ArrayHelper.GetRawPtr(Index)); } else { FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Attempted to get an item from array %s out of bounds [%d/%d]!"), *ArrayProp->GetName(), Index, GetLastIndex(ArrayHelper)), ELogVerbosity::Warning); InnerProp->InitializeValue(Item); } } }
void UKismetArrayLibrary::GenericArray_Get(void* TargetArray, const UArrayProperty* ArrayProp, int32 Index, void* Item) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); UProperty* InnerProp = ArrayProp->Inner; if( ArrayHelper.IsValidIndex(Index) ) { InnerProp->CopyCompleteValueFromScriptVM(Item, ArrayHelper.GetRawPtr(Index)); } else { UE_LOG(LogArray, Warning, TEXT("Attempted to get an item from array %s out of bounds [%d/%d]!"), *ArrayProp->GetName(), Index, GetLastIndex(ArrayHelper)); InnerProp->InitializeValue(Item); } } }
void UKismetArrayLibrary::GenericArray_Insert(void* TargetArray, const UArrayProperty* ArrayProp, const void* NewItem, int32 Index) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); UProperty* InnerProp = ArrayProp->Inner; if (ArrayHelper.IsValidIndex(Index) || (Index >= 0 && Index <= ArrayHelper.Num()) ) { ArrayHelper.InsertValues(Index, 1); InnerProp->CopySingleValueToScriptVM(ArrayHelper.GetRawPtr(Index), NewItem); } else { FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Attempted to insert an item into array %s out of bounds [%d/%d]!"), *ArrayProp->GetName(), Index, GetLastIndex(ArrayHelper)), ELogVerbosity::Warning); } } }
bool FDataTableExporterJSON::WriteStructEntry(const void* InRowData, const UProperty* InProperty, const void* InPropertyData) { if (const UNumericProperty *NumProp = Cast<const UNumericProperty>(InProperty)) { if (NumProp->IsInteger()) { const int64 PropertyValue = NumProp->GetSignedIntPropertyValue(InPropertyData); JsonWriter->WriteValue(InProperty->GetName(), PropertyValue); } else { const double PropertyValue = NumProp->GetFloatingPointPropertyValue(InPropertyData); JsonWriter->WriteValue(InProperty->GetName(), PropertyValue); } } else if (const UBoolProperty* BoolProp = Cast<const UBoolProperty>(InProperty)) { const bool PropertyValue = BoolProp->GetPropertyValue(InPropertyData); JsonWriter->WriteValue(InProperty->GetName(), PropertyValue); } else if (const UArrayProperty* ArrayProp = Cast<const UArrayProperty>(InProperty)) { JsonWriter->WriteArrayStart(InProperty->GetName()); FScriptArrayHelper ArrayHelper(ArrayProp, InPropertyData); for (int32 ArrayEntryIndex = 0; ArrayEntryIndex < ArrayHelper.Num(); ++ArrayEntryIndex) { const void* ArrayEntryData = ArrayHelper.GetRawPtr(ArrayEntryIndex); WriteArrayEntry(ArrayProp->Inner, ArrayEntryData); } JsonWriter->WriteArrayEnd(); } else { const FString PropertyValue = DataTableUtils::GetPropertyValueAsString(InProperty, (uint8*)InRowData); JsonWriter->WriteValue(InProperty->GetName(), PropertyValue); } return true; }
void UArrayProperty::SerializeItem( FArchive& Ar, void* Value, void const* Defaults ) const { checkSlow(Inner); // Ensure that the Inner itself has been loaded before calling SerializeItem() on it Ar.Preload(Inner); FScriptArrayHelper ArrayHelper(this, Value); int32 n = ArrayHelper.Num(); Ar << n; if( Ar.IsLoading() ) { ArrayHelper.EmptyAndAddValues(n); } ArrayHelper.CountBytes( Ar ); for( int32 i=0; i<n; i++ ) { Inner->SerializeItem( Ar, ArrayHelper.GetRawPtr(i) ); } }
int32 UKismetArrayLibrary::GenericArray_Find(const void* TargetArray, const UArrayProperty* ArrayProperty, const void* ItemToFind) { int32 ResultIndex = INDEX_NONE; if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray); UProperty* InnerProp = ArrayProperty->Inner; // compare against each element in the array for (int32 Idx = 0; Idx < ArrayHelper.Num() && ResultIndex == INDEX_NONE; Idx++) { if (InnerProp->Identical(ItemToFind,ArrayHelper.GetRawPtr(Idx))) { ResultIndex = Idx; } } } // assign the resulting index return ResultIndex; }
bool SetPropertyValue( UProperty* Property, UProperty* Outer, void* Data, int32 ArrayIndex, const PropertyType& Value ) { PropertyType* ValuePtr = nullptr; UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Outer); if (ArrayProperty != nullptr) { if (ArrayProperty->Inner != Property) { return false; } FScriptArrayHelper ArrayHelper(ArrayProperty, ArrayProperty->template ContainerPtrToValuePtr<void>(Data)); int32 Index = ArrayHelper.AddValue(); ValuePtr = (PropertyType*)ArrayHelper.GetRawPtr(Index); } else { UPropertyType* TypedProperty = Cast<UPropertyType>(Property); if (TypedProperty == nullptr) { return false; } ValuePtr = TypedProperty->template ContainerPtrToValuePtr<PropertyType>(Data, ArrayIndex); } if (ValuePtr == nullptr) { return false; } *ValuePtr = Value; return true; }
uint8* UAnimSequenceBase::FindArrayProperty(const TCHAR* PropName, UArrayProperty*& ArrayProperty, int32 ArrayIndex) { // find Notifies property start point UProperty* Property = FindField<UProperty>(GetClass(), PropName); // found it and if it is array if (Property && Property->IsA(UArrayProperty::StaticClass())) { // find Property Value from UObject we got uint8* PropertyValue = Property->ContainerPtrToValuePtr<uint8>(this); // it is array, so now get ArrayHelper and find the raw ptr of the data ArrayProperty = CastChecked<UArrayProperty>(Property); FScriptArrayHelper ArrayHelper(ArrayProperty, PropertyValue); if (ArrayProperty->Inner && ArrayIndex < ArrayHelper.Num()) { //Get property data based on selected index return ArrayHelper.GetRawPtr(ArrayIndex); } } return NULL; }
void UKismetArrayLibrary::GenericArray_Set(void* TargetArray, const UArrayProperty* ArrayProp, int32 Index, const void* NewItem, bool bSizeToFit) { if( TargetArray ) { FScriptArrayHelper ArrayHelper(ArrayProp, TargetArray); UProperty* InnerProp = ArrayProp->Inner; // Expand the array, if desired if (!ArrayHelper.IsValidIndex(Index) && bSizeToFit && (Index >= 0)) { ArrayHelper.ExpandForIndex(Index); } if (ArrayHelper.IsValidIndex(Index)) { InnerProp->CopySingleValueToScriptVM(ArrayHelper.GetRawPtr(Index), NewItem); } else { FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Attempted to set an invalid index on array %s [%d/%d]!"), *ArrayProp->GetName(), Index, GetLastIndex(ArrayHelper)), ELogVerbosity::Warning); } } }
bool FFrontendFilter_GameplayTags::ProcessProperty(void* Data, UProperty* Prop) const { void* InnerData = Prop->ContainerPtrToValuePtr<void>(Data); if (UStructProperty* StructProperty = Cast<UStructProperty>(Prop)) { if (StructProperty->Struct == FGameplayTag::StaticStruct()) { FGameplayTag& ThisTag = *static_cast<FGameplayTag*>(InnerData); const bool bAnyTagIsOK = TagContainer->Num() == 0; const bool bPassesTagSearch = bAnyTagIsOK || TagContainer->HasTag(ThisTag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::IncludeParentTags); return bPassesTagSearch; } else { return ProcessStruct(InnerData, StructProperty->Struct); } } else if (UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Prop)) { FScriptArrayHelper ArrayHelper(ArrayProperty, InnerData); for (int32 ArrayIndex = 0; ArrayIndex < ArrayHelper.Num(); ++ArrayIndex) { void* ArrayData = ArrayHelper.GetRawPtr(ArrayIndex); if (ProcessProperty(ArrayData, ArrayProperty->Inner)) { return true; } } } return false; }
void FPoseLinkMappingRecord::PatchLinkIndex(uint8* DestinationPtr, int32 LinkID, int32 SourceLinkID) const { checkSlow(IsValid()); DestinationPtr = ChildProperty->ContainerPtrToValuePtr<uint8>(DestinationPtr); if (ChildPropertyIndex != INDEX_NONE) { UArrayProperty* ArrayProperty = CastChecked<UArrayProperty>(ChildProperty); FScriptArrayHelper ArrayHelper(ArrayProperty, DestinationPtr); check(ArrayHelper.IsValidIndex(ChildPropertyIndex)); DestinationPtr = ArrayHelper.GetRawPtr(ChildPropertyIndex); } // Check to guard against accidental infinite loops check((LinkID == INDEX_NONE) || (LinkID != SourceLinkID)); // Patch the pose link FPoseLinkBase& PoseLink = *((FPoseLinkBase*)DestinationPtr); PoseLink.LinkID = LinkID; PoseLink.SourceLinkID = SourceLinkID; }