UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
InterchangeBaseNodeUtilities.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
7#include "UObject/Class.h"
8#include "UObject/Object.h"
10
11//Interchange namespace
12namespace UE
13{
14namespace Interchange
15{
16
20template<typename ItemType>
22{
23public:
25 {
26 LLM_SCOPE_BYNAME(TEXT("Interchange"));
27
28 Attributes = nullptr;
29 KeyCount = NAME_None;
30 }
31
33 {
34 LLM_SCOPE_BYNAME(TEXT("Interchange"));
35
36 check(InAttributes.IsValid());
37 Attributes = InAttributes;
38 KeyCount = BaseKeyName;
39 }
40
41 static const FString& IndexKey()
42 {
43 static FString IndexKeyString = TEXT("_NameIndex_");
44 return IndexKeyString;
45 }
46
48 {
49 //The Class must be initialise properly before we can use it
51 if (!ensure(AttributePtr.IsValid()))
52 {
53 return 0;
54 }
55 int32 ItemCount = 0;
56 if (AttributePtr->ContainAttribute(GetKeyCount()))
57 {
58 FAttributeStorage::TAttributeHandle<int32> Handle = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
59 if (Handle.IsValid())
60 {
61 Handle.Get(ItemCount);
62 }
63 }
64 return ItemCount;
65 }
66
67 void GetItem(const int32 Index, ItemType& OutItem) const
68 {
69 //The Class must be initialise properly before we can use it
71 if (!ensure(AttributePtr.IsValid()))
72 {
73 return;
74 }
75 int32 ItemCount = 0;
76 if (!AttributePtr->ContainAttribute(GetKeyCount()))
77 {
78 return;
79 }
80
81 FAttributeStorage::TAttributeHandle<int32> Handle = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
82 if (!Handle.IsValid())
83 {
84 return;
85 }
86 Handle.Get(ItemCount);
87 if (Index >= ItemCount)
88 {
89 return;
90 }
91 FAttributeKey DepIndexKey = GetIndexKey(Index);
93 if (!HandleItem.IsValid())
94 {
95 return;
96 }
98 }
99
101 {
102 //The Class must be initialise properly before we can use it
104 if (!ensure(AttributePtr.IsValid()))
105 {
106 OutItems.Empty();
107 return;
108 }
109 int32 ItemCount = 0;
110 if (!AttributePtr->ContainAttribute(GetKeyCount()))
111 {
112 OutItems.Empty();
113 return;
114 }
115
116 FAttributeStorage::TAttributeHandle<int32> Handle = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
117 if (!Handle.IsValid())
118 {
119 return;
120 }
121 Handle.Get(ItemCount);
122
123 //Reuse as much memory we can to avoid allocation
124 OutItems.Reset(ItemCount);
125 for (int32 NameIndex = 0; NameIndex < ItemCount; ++NameIndex)
126 {
127 FAttributeKey DepIndexKey = GetIndexKey(NameIndex);
129 if (!HandleItem.IsValid())
130 {
131 continue;
132 }
133 ItemType& OutItem = OutItems.AddDefaulted_GetRef();
134 HandleItem.Get(OutItem);
135 }
136 }
137
138 bool AddItem(const ItemType& Item)
139 {
140 //The Class must be initialise properly before we can use it
142 if (!ensure(AttributePtr.IsValid()))
143 {
144 return false;
145 }
146
147 if (!AttributePtr->ContainAttribute(GetKeyCount()))
148 {
149 const int32 DependencyCount = 0;
150 EAttributeStorageResult Result = AttributePtr->RegisterAttribute<int32>(GetKeyCount(), DependencyCount);
152 {
153 LogAttributeStorageErrors(Result, TEXT("TArrayAttributeHelper.AddName"), GetKeyCount());
154 return false;
155 }
156 }
157 FAttributeStorage::TAttributeHandle<int32> Handle = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
158 if (!ensure(Handle.IsValid()))
159 {
160 return false;
161 }
162 int32 ItemIndex = 0;
163 Handle.Get(ItemIndex);
164 FAttributeKey ItemIndexKey = GetIndexKey(ItemIndex);
165 EAttributeStorageResult AddItemResult = AttributePtr->RegisterAttribute<ItemType>(ItemIndexKey, Item);
167 {
168 LogAttributeStorageErrors(AddItemResult, TEXT("TArrayAttributeHelper.AddName"), ItemIndexKey);
169 return false;
170 }
171
172 //Success, increment the item counter
173 ItemIndex++;
174 Handle.Set(ItemIndex);
175 return true;
176 }
177
178 bool RemoveItem(const ItemType& ItemToDelete)
179 {
180 //The Class must be initialise properly before we can use it
182 if (!ensure(AttributePtr.IsValid()))
183 {
184 return false;
185 }
186
187 int32 ItemCount = 0;
188 if (!AttributePtr->ContainAttribute(GetKeyCount()))
189 {
190 return false;
191 }
192 FAttributeStorage::TAttributeHandle<int32> Handle = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
193 if (!Handle.IsValid())
194 {
195 return false;
196 }
197 Handle.Get(ItemCount);
199 for (int32 ItemIndex = 0; ItemIndex < ItemCount; ++ItemIndex)
200 {
201 FAttributeKey DepIndexKey = GetIndexKey(ItemIndex);
203 if (!HandleItem.IsValid())
204 {
205 continue;
206 }
207 ItemType Item;
208 HandleItem.Get(Item);
209 //Remove at most one item
210 if (DecrementKey == 0 && Item == ItemToDelete)
211 {
212 //Remove this entry
213 AttributePtr->UnregisterAttribute(DepIndexKey);
214 Handle.Set(ItemCount - 1);
215 //We have to rename the key for all the next item
216 DecrementKey++;
217 }
218 else if (DecrementKey > 0)
219 {
220 FAttributeKey NewDepIndexKey = GetIndexKey(ItemIndex - DecrementKey);
223 {
224 EAttributeStorageResult RegisterResult = AttributePtr->RegisterAttribute<ItemType>(NewDepIndexKey, Item);
226 {
227 LogAttributeStorageErrors(RegisterResult, TEXT("TArrayAttributeHelper.RemoveItem"), NewDepIndexKey);
228 }
229 }
230 else
231 {
232 LogAttributeStorageErrors(UnregisterResult, TEXT("TArrayAttributeHelper.RemoveItem"), DepIndexKey);
233 }
234
235 //Avoid doing more code in the for since the HandleItem is now invalid
236 continue;
237 }
238 }
239 return true;
240 }
241
243 {
244 //The Class must be initialise properly before we can use it
246 if (!ensure(AttributePtr.IsValid()))
247 {
248 return false;
249 }
250
251 int32 ItemCount = 0;
252 if (!AttributePtr->ContainAttribute(GetKeyCount()))
253 {
254 return false;
255 }
256 FAttributeStorage::TAttributeHandle<int32> HandleCount = AttributePtr->GetAttributeHandle<int32>(GetKeyCount());
257 if (!HandleCount.IsValid())
258 {
259 return false;
260 }
261 HandleCount.Get(ItemCount);
262 //Remove all attribute one by one
263 for (int32 NameIndex = 0; NameIndex < ItemCount; ++NameIndex)
264 {
265 FAttributeKey DepIndexKey = GetIndexKey(NameIndex);
266 AttributePtr->UnregisterAttribute(DepIndexKey);
267 }
268 //Make sure Count is zero
269 ItemCount = 0;
270 HandleCount.Set(ItemCount);
271 return true;
272 }
273
274private:
276 FAttributeKey KeyCount;
277 FAttributeKey GetKeyCount() const
278 {
279 ensure(!KeyCount.Key.IsEmpty()); return KeyCount;
280 }
281
282 FAttributeKey GetIndexKey(int32 Index) const
283 {
284 FString DepIndexKeyString = GetKeyCount().ToString() + IndexKey() + FString::FromInt(Index);
286 }
287};
288
292template<typename KeyType, typename ValueType>
294{
295 template<typename T>
297
298public:
300 {
301 LLM_SCOPE_BYNAME(TEXT("Interchange"));
302
303 Attributes = InAttributes;
304 FString BaseTryName = BaseKeyName;
306 if (!InAttributes->ContainAttribute(KeyCountKey))
307 {
308 EAttributeStorageResult Result = InAttributes->RegisterAttribute<int32>(KeyCountKey, 0);
310 KeyCountHandle = InAttributes->GetAttributeHandle<int32>(KeyCountKey);
311 }
312 else
313 {
314 KeyCountHandle = InAttributes->GetAttributeHandle<int32>(KeyCountKey);
315 RebuildCache();
316 }
317 }
318
324
326 {
327 Attributes.Reset();
328 }
329
330 bool SetKeyValue(const KeyType& InKey, const ValueType& InValue)
331 {
332 const uint32 Hash = GetTypeHash(InKey);
334 }
335
336 bool GetValue(const KeyType& InKey, ValueType& OutValue) const
337 {
338 const uint32 Hash = GetTypeHash(InKey);
340 }
341
342 bool RemoveKey(const KeyType& InKey)
343 {
344 const uint32 Hash = GetTypeHash(InKey);
345 return RemoveKeyByHash(Hash, InKey);
346 }
347
348 bool RemoveKeyAndGetValue(const KeyType& InKey, ValueType& OutValue)
349 {
350 const uint32 Hash = GetTypeHash(InKey);
352 }
353
354 bool SetKeyValueByHash(uint32 Hash, const KeyType& InKey, const ValueType& InValue)
355 {
357 if (!ensure(AttributesPtr.IsValid()))
358 {
359 return false;
360 }
361
362 if (TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>* Pair = CachedKeysAndValues.FindByHash(Hash, InKey))
363 {
364 Pair->Value.Set(InValue);
365 }
366 else
367 {
368 FAttributeKey IndexKey = GetKeyAttribute(CachedKeysAndValues.Num());
369 FAttributeKey AttributeKey = GetValueAttribute(InKey);
370 ensure(AttributesPtr->RegisterAttribute<KeyType>(IndexKey, InKey) == EAttributeStorageResult::Operation_Success);
372 CachedKeysAndValues.AddByHash(
373 Hash
374 , InKey
376 AttributesPtr->GetAttributeHandle<KeyType>(IndexKey)
377 , AttributesPtr->GetAttributeHandle<ValueType>(AttributeKey)
378 ));
379 KeyCountHandle.Set(CachedKeysAndValues.Num());
380 }
381
382 return true;
383 }
384
385
386 bool GetValueByHash(uint32 Hash, const KeyType& InKey, ValueType& OutValue) const
387 {
389 if (!ensure(AttributesPtr.IsValid()))
390 {
391 return false;
392 }
393
394 if (const TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>* Pair = CachedKeysAndValues.FindByHash(Hash, InKey))
395 {
396 return Pair->Value.Get(OutValue) == EAttributeStorageResult::Operation_Success;
397 }
398
399 return false;
400 }
401
402
403 bool RemoveKeyByHash(uint32 Hash, const KeyType& InKey)
404 {
406 if (!ensure(AttributesPtr.IsValid()))
407 {
408 return false;
409 }
410
411 if (TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>* Pair = CachedKeysAndValues.FindByHash(Hash, InKey))
412 {
413 return RemoveBySwap(Hash, InKey, *Pair);
414 }
415
416 return false;
417 }
418
419 bool RemoveKeyAndGetValueByHash(uint32 Hash, const KeyType& InKey, ValueType& OutValue)
420 {
422 if (!ensure(AttributesPtr.IsValid()))
423 {
424 return false;
425 }
426
427 if (TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>* Pair = CachedKeysAndValues.FindByHash(Hash, InKey))
428 {
430 {
431 return RemoveBySwap(Hash, InKey, *Pair);
432 }
433 }
434
435 return false;
436 }
437
439 {
440 CachedKeysAndValues.Reserve(Number);
441 }
442
444 {
445 EmptyInternal(NumOfExpectedElements);
446 }
447
449 {
450 return CachedKeysAndValues.Num();
451 }
452
454 {
456 if (!ensure(AttributesPtr.IsValid()))
457 {
458 return *this;
459 }
460
461 // Empty
462 EmptyInternal(InMap.Num());
463
464 KeyCountHandle.Set(InMap.Num());
465
466 for (const TPair<KeyType, ValueType>& Pair : InMap)
467 {
468 SetKeyValue(Pair.Key, Pair.Value);
469 }
470
471 return *this;
472 }
473
475 {
477 Map.Reserve(CachedKeysAndValues.Num());
478
479 for (const TPair<KeyType, TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>>& Pair : CachedKeysAndValues)
480 {
481 KeyType Key;
482 Pair.Value.Key.Get(Key);
483 ValueType Value;
484 Pair.Value.Value.Get(Value);
485
486 Map.Add(MoveTemp(Key), MoveTemp(Value));
487 }
488
489 return Map;
490 }
491
493 {
494 LLM_SCOPE_BYNAME(TEXT("Interchange"));
495
497 if (AttributesPtr.IsValid() && KeyCountHandle.IsValid())
498 {
499 int32 KeyCount;
500 if (KeyCountHandle.Get(KeyCount) == EAttributeStorageResult::Operation_Success)
501 {
502 CachedKeysAndValues.Empty(KeyCount);
503
504 for (int32 Index = 0; Index < KeyCount; Index++)
505 {
506 TAttributeHandle<KeyType> KeyAttribute = AttributesPtr->GetAttributeHandle<KeyType>(GetKeyAttribute(Index));
507 if (!ensure(KeyAttribute.IsValid()))
508 {
509 continue;
510 }
511
512 KeyType Key;
513 KeyAttribute.Get(Key);
514
515 TAttributeHandle<ValueType> ValueAttribute = AttributesPtr->GetAttributeHandle<ValueType>(GetValueAttribute(Key));
516 if (!ensure(ValueAttribute.IsValid()))
517 {
518 continue;
519 }
520
521 CachedKeysAndValues.Add(Key, TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>(KeyAttribute, ValueAttribute));
522 }
523 }
524 }
525 }
526
527private:
528 FAttributeKey GetKeyAttribute(int32 Index) const
529 {
530 static const FString KeyIndex = TEXT("_KeyIndex_");
531 FString IndexedKey = KeyCountHandle.GetKey().ToString();
532 IndexedKey.Reserve(KeyIndex.Len() + 16 /*Max size for a int32*/);
533 IndexedKey.Append(KeyIndex);
534 IndexedKey.AppendInt(Index);
536 }
537
538 FAttributeKey GetValueAttribute(const KeyType& InKey) const
539 {
540 static const FString KeyChars = TEXT("_Key_");
541 FString ValueAttribute = KeyCountHandle.GetKey().ToString();
543 ValueAttribute.Reserve(KeyChars.Len() + Key.Len());
544 ValueAttribute.Append(KeyChars);
545 ValueAttribute.Append(Key);
546 return FAttributeKey(MoveTemp(ValueAttribute));
547 }
548
549 TAttributeHandle<KeyType> GetLastKeyAttributeHandle() const
550 {
552 if (!ensure(AttributesPtr.IsValid()))
553 {
554 return {};
555 }
556 return AttributesPtr->GetAttributeHandle<KeyType>(GetKeyAttribute(CachedKeysAndValues.Num() - 1));
557 }
558
560 {
562 if (!ensure(AttributesPtr.IsValid()))
563 {
564 return false;
565 }
566
567 TAttributeHandle<KeyType> LastKeyIndex = GetLastKeyAttributeHandle();
568 KeyType LastKey;
569 LastKeyIndex.Get(LastKey);
570 CachedKeysAndValues[LastKey].Key = CachedPair.Key;
571 CachedPair.Key.Set(MoveTemp(LastKey));
572
573 AttributesPtr->UnregisterAttribute(LastKeyIndex.GetKey());
574 AttributesPtr->UnregisterAttribute(CachedPair.Value.GetKey());
575 CachedKeysAndValues.RemoveByHash(Hash, InKey);
576 KeyCountHandle.Set(CachedKeysAndValues.Num());
577
578 return true;
579 }
580
581 void EmptyInternal(int32 NumOfExpectedElements)
582 {
584 if (!ensure(AttributesPtr.IsValid()))
585 {
586 return;
587 }
588
589 for (const TPair<KeyType, TPair<TAttributeHandle<KeyType>, TAttributeHandle<ValueType>>>& Pair : CachedKeysAndValues)
590 {
591 const FAttributeKey& KeyAttribute = Pair.Value.Key.GetKey();
592 AttributesPtr->UnregisterAttribute(KeyAttribute);
593
594 const FAttributeKey& ValueAttribute = Pair.Value.Value.GetKey();
595 AttributesPtr->UnregisterAttribute(ValueAttribute);
596 }
597 CachedKeysAndValues.Empty(NumOfExpectedElements);
598 KeyCountHandle.Set(0);
599 }
600
602 TAttributeHandle<int32> KeyCountHandle; //Assign in Initialize function, it will ensure if its the default value (NAME_None) when using the class
604};
605
606} //ns Interchange
607} //ns UE
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define LLM_SCOPE_BYNAME(...)
Definition LowLevelMemTracker.h:1098
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition SharedPointer.h:692
Definition SharedPointer.h:153
Definition SharedPointer.h:1295
UE_FORCEINLINE_HINT TSharedPtr< ObjectType, Mode > Pin() const &
Definition SharedPointer.h:1512
UE_FORCEINLINE_HINT void Reset()
Definition SharedPointer.h:1544
Definition InterchangeBaseNodeUtilities.h:22
static const FString & IndexKey()
Definition InterchangeBaseNodeUtilities.h:41
void Initialize(const TSharedPtr< FAttributeStorage, ESPMode::ThreadSafe > &InAttributes, const FString &BaseKeyName)
Definition InterchangeBaseNodeUtilities.h:32
bool RemoveItem(const ItemType &ItemToDelete)
Definition InterchangeBaseNodeUtilities.h:178
int32 GetCount() const
Definition InterchangeBaseNodeUtilities.h:47
~TArrayAttributeHelper()
Definition InterchangeBaseNodeUtilities.h:24
bool RemoveAllItems()
Definition InterchangeBaseNodeUtilities.h:242
void GetItems(TArray< ItemType > &OutItems) const
Definition InterchangeBaseNodeUtilities.h:100
void GetItem(const int32 Index, ItemType &OutItem) const
Definition InterchangeBaseNodeUtilities.h:67
bool AddItem(const ItemType &Item)
Definition InterchangeBaseNodeUtilities.h:138
Definition InterchangeBaseNodeUtilities.h:294
void Empty(int32 NumOfExpectedElements=0)
Definition InterchangeBaseNodeUtilities.h:443
TMapAttributeHelper(TMapAttributeHelper &&)=default
bool SetKeyValueByHash(uint32 Hash, const KeyType &InKey, const ValueType &InValue)
Definition InterchangeBaseNodeUtilities.h:354
TMapAttributeHelper & operator=(const TMap< KeyType, ValueType > &InMap)
Definition InterchangeBaseNodeUtilities.h:453
~TMapAttributeHelper()
Definition InterchangeBaseNodeUtilities.h:325
bool RemoveKey(const KeyType &InKey)
Definition InterchangeBaseNodeUtilities.h:342
TMap< KeyType, ValueType > ToMap() const
Definition InterchangeBaseNodeUtilities.h:474
TMapAttributeHelper(const TMapAttributeHelper &)=default
void RebuildCache()
Definition InterchangeBaseNodeUtilities.h:492
bool RemoveKeyAndGetValue(const KeyType &InKey, ValueType &OutValue)
Definition InterchangeBaseNodeUtilities.h:348
bool RemoveKeyByHash(uint32 Hash, const KeyType &InKey)
Definition InterchangeBaseNodeUtilities.h:403
TMapAttributeHelper & operator=(TMapAttributeHelper &&)=default
bool GetValue(const KeyType &InKey, ValueType &OutValue) const
Definition InterchangeBaseNodeUtilities.h:336
void Initialize(const TSharedRef< FAttributeStorage, ESPMode::ThreadSafe > &InAttributes, const FString &BaseKeyName)
Definition InterchangeBaseNodeUtilities.h:299
int32 GetCount() const
Definition InterchangeBaseNodeUtilities.h:448
bool GetValueByHash(uint32 Hash, const KeyType &InKey, ValueType &OutValue) const
Definition InterchangeBaseNodeUtilities.h:386
bool SetKeyValue(const KeyType &InKey, const ValueType &InValue)
Definition InterchangeBaseNodeUtilities.h:330
void Reserve(int32 Number)
Definition InterchangeBaseNodeUtilities.h:438
bool RemoveKeyAndGetValueByHash(uint32 Hash, const KeyType &InKey, ValueType &OutValue)
Definition InterchangeBaseNodeUtilities.h:419
TMapAttributeHelper & operator=(const TMapAttributeHelper &)=default
bool IsAttributeStorageResultSuccess(const EAttributeStorageResult Result)
Definition AttributeStorage.h:392
void LogAttributeStorageErrors(const EAttributeStorageResult Result, const FString OperationName, const FAttributeKey AttributeKey)
Definition AttributeStorage.cpp:1038
uint32 GetTypeHash(const FAttributeKey &AttributeKey)
Definition AttributeStorage.h:185
EAttributeStorageResult
Definition AttributeStorage.h:351
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition AttributeCurve.h:23
FWrappedAttribute Value
Definition AttributeCurve.h:54
Definition Tuple.h:652
static StringType ToString(const T &Value)
Definition UnrealString.h:204
Definition AttributeStorage.h:67
const FString & ToString() const
Definition AttributeStorage.h:173
FString Key
Definition AttributeStorage.h:68