UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
TypedElementHandle.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include <type_traits>
6#include "CoreMinimal.h"
8
9#include "TypedElementHandle.generated.h"
10
18{
19public:
21
29
31 {
32 if (this != &InOther)
33 {
35
36 if (InOther)
37 {
39 }
40 }
41 return *this;
42 }
43
45 : DataPtr(InOther.DataPtr)
48#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
49 {
50 InOther.DataPtr = nullptr;
51#if UE_TYPED_ELEMENT_HAS_REFTRACKING
52 InOther.ReferenceId = INDEX_NONE;
53#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
54 checkSlow(!InOther.IsSet());
55 }
56
58 {
59 if (this != &InOther)
60 {
62
63 DataPtr = InOther.DataPtr;
64#if UE_TYPED_ELEMENT_HAS_REFTRACKING
65 ReferenceId = InOther.ReferenceId;
66#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
67
68 InOther.DataPtr = nullptr;
69#if UE_TYPED_ELEMENT_HAS_REFTRACKING
70 InOther.ReferenceId = INDEX_NONE;
71#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
72 checkSlow(!InOther.IsSet());
73 }
74 return *this;
75 }
76
81
82 inline explicit operator bool() const
83 {
84 return IsSet();
85 }
86
90 inline bool IsSet() const
91 {
92 return DataPtr != nullptr;
93 }
94
98 inline void Release()
99 {
101 }
102
106 inline const FTypedElementId& GetId() const
107 {
108 return DataPtr
109 ? DataPtr->GetId()
111 }
112
117 template <typename ElementDataType>
118 inline bool IsDataOfType() const
119 {
120 return GetId().GetTypeId() == ElementDataType::StaticTypeId();
121 }
122
127 template <typename ElementDataType>
128 const ElementDataType* GetData(const bool bSilent = false) const
129 {
130 if (!DataPtr)
131 {
132 if (!bSilent)
133 {
134 FFrame::KismetExecutionMessage(TEXT("Element handle data is null!"), ELogVerbosity::Error);
135 }
136 return nullptr;
137 }
138
140 {
141 if (!bSilent)
142 {
143 FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Element handle data type is '%d', but '%d' (%s) was requested!"), GetId().GetTypeId(), ElementDataType::StaticTypeId(), *ElementDataType::StaticTypeName().ToString()), ELogVerbosity::Error);
144 }
145 return nullptr;
146 }
147
148 return static_cast<const ElementDataType*>(DataPtr->GetUntypedData());
149 }
150
155 template <typename ElementDataType>
156 inline const ElementDataType& GetDataChecked() const
157 {
158 checkf(DataPtr, TEXT("Element handle data is null!"));
159 checkf(IsDataOfType<ElementDataType>(), TEXT("Element handle data type is '%d', but '%d' (%s) was requested!"), GetId().GetTypeId(), ElementDataType::StaticTypeId(), *ElementDataType::StaticTypeName().ToString());
160 return *static_cast<const ElementDataType*>(DataPtr->GetUntypedData());
161 }
162
168 {
169 FTypedElementId ElementId;
170 if (IsSet())
171 {
172 DataPtr->AddRef(/*bCanTrackReference*/false); // Cannot track element ID references as we have no space to store the reference ID
173 ElementId.Private_InitializeNoRef(DataPtr->GetId().GetTypeId(), DataPtr->GetId().GetElementId());
174 }
175 return ElementId;
176 }
177
183 {
184 checkf(InOutElementId == GetId(), TEXT("Element ID does not match this handle!"));
185 if (InOutElementId)
186 {
187 DataPtr->ReleaseRef(INDEX_NONE); // Cannot track element ID references as we have no space to store the reference ID
188 InOutElementId.Private_DestroyNoRef();
189 }
190 }
191
193 {
194 return InLHS.DataPtr == InRHS.DataPtr;
195 }
196
198 {
199 return !(InLHS == InRHS);
200 }
201
203 {
204 return GetTypeHash(InElementHandle.GetId());
205 }
206
208 {
209 DataPtr = &InData;
210 }
211
213 {
215 RegisterRef();
216 }
217
219 {
220 DataPtr = nullptr;
221#if UE_TYPED_ELEMENT_HAS_REFTRACKING
223#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
224 }
225
227 {
228 UnregisterRef();
230 }
231
233 {
234 return DataPtr;
235 }
236
237private:
238 inline void RegisterRef()
239 {
240 if (DataPtr)
241 {
242#if !UE_TYPED_ELEMENT_HAS_REFTRACKING
244#endif // !UE_TYPED_ELEMENT_HAS_REFTRACKING
245 ReferenceId = DataPtr->AddRef(/*bCanTrackReference*/true);
246 }
247 }
248
249 inline void UnregisterRef()
250 {
251 if (DataPtr)
252 {
253#if !UE_TYPED_ELEMENT_HAS_REFTRACKING
255#endif // !UE_TYPED_ELEMENT_HAS_REFTRACKING
256 DataPtr->ReleaseRef(ReferenceId);
257 }
258 }
259
260 const FTypedElementInternalData* DataPtr = nullptr;
261#if UE_TYPED_ELEMENT_HAS_REFTRACKING
263#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
264};
265
269template <typename BaseInterfaceType>
271{
272public:
273 TTypedElementBase() = default;
274
277
285
287 {
288 if (this != &InOther)
289 {
291 InterfacePtr = InOther.InterfacePtr;
292
293 InOther.InterfacePtr = nullptr;
294 checkSlow(!InOther.IsSet());
295 }
296 return *this;
297 }
298
303
304 inline explicit operator bool() const
305 {
306 return IsSet();
307 }
308
312 inline bool IsSet() const
313 {
315 && InterfacePtr;
316 }
317
321 inline void Release()
322 {
324 }
325
330 {
331 return InterfacePtr;
332 }
333
338 inline U& GetInterfaceChecked() const
339 {
340 static_assert(std::is_same<U, BaseInterfaceType>::value, "Don't explicitly specify U!");
341 checkf(InterfacePtr, TEXT("Interface is null!"));
342 return *InterfacePtr;
343 }
344
345 inline friend bool operator==(const TTypedElementBase& InLHS, const TTypedElementBase& InRHS)
346 {
347 return static_cast<const FTypedElementHandle&>(InLHS) == static_cast<const FTypedElementHandle&>(InRHS)
348 && InLHS.InterfacePtr == InRHS.InterfacePtr;
349 }
350
351 inline friend bool operator!=(const TTypedElementBase& InLHS, const TTypedElementBase& InRHS)
352 {
353 return !(InLHS == InRHS);
354 }
355
357 {
358 return HashCombine(GetTypeHash(static_cast<const FTypedElementHandle&>(InElement)), GetTypeHash(InElement.InterfacePtr));
359 }
360
366
372
374 {
376 InterfacePtr = nullptr;
377 }
378
384
385protected:
387};
388
394template <typename BaseInterfaceType>
395struct TTypedElement : public TTypedElementBase<BaseInterfaceType>
396{
397};
398
399// The typed element InterfacePtr will points toward the vtable of the interface
401
407template <typename ElementDataType>
409{
410public:
412
415
417 : DataPtr(InOther.DataPtr)
418 {
419 InOther.DataPtr = nullptr;
420 checkSlow(!InOther.IsSet());
421 }
422
424 {
425 if (this != &InOther)
426 {
427 DataPtr = InOther.DataPtr;
428
429 InOther.DataPtr = nullptr;
430 checkSlow(!InOther.IsSet());
431 }
432 return *this;
433 }
434
436 {
437 checkf(!IsSet(), TEXT("Element owner was still set during destruction! This will leak an element, and you should destroy this element prior to destruction!"));
438 }
439
440 inline explicit operator bool() const
441 {
442 return IsSet();
443 }
444
448 inline bool IsSet() const
449 {
450 return DataPtr != nullptr;
451 }
452
456 inline const FTypedElementId& GetId() const
457 {
458 return DataPtr
459 ? DataPtr->GetId()
461 }
462
467 inline U* GetData() const
468 {
469 static_assert(std::is_same<U, ElementDataType>::value, "Don't explicitly specify U!");
470 return DataPtr
471 ? &DataPtr->GetMutableData()
472 : nullptr;
473 }
474
479 inline U& GetDataChecked() const
480 {
481 static_assert(std::is_same<U, ElementDataType>::value, "Don't explicitly specify U!");
482 checkf(DataPtr, TEXT("Handle data is null!"));
483 return DataPtr->GetMutableData();
484 }
485
491 {
492 FTypedElementId ElementId;
493 if (IsSet())
494 {
495 DataPtr->AddRef(/*bCanTrackReference*/false); // Cannot track element ID references as we have no space to store the reference ID
496 ElementId.Private_InitializeNoRef(DataPtr->GetId().GetTypeId(), DataPtr->GetId().GetElementId());
497 }
498 return ElementId;
499 }
500
506 {
507 checkf(InOutElementId == GetId(), TEXT("Element ID does not match this owner!"));
508 if (InOutElementId)
509 {
510 DataPtr->ReleaseRef(INDEX_NONE); // Cannot track element ID references as we have no space to store the reference ID
511 InOutElementId.Private_DestroyNoRef();
512 }
513 }
514
520 {
522 if (IsSet())
523 {
525 }
526 return ElementHandle;
527 }
528
534 {
535 checkf(InOutElementHandle.GetId() == GetId(), TEXT("Element handle ID does not match this owner!"));
536 InOutElementHandle.Release();
537 }
538
539 inline friend bool operator==(const TTypedElementOwner& InLHS, const TTypedElementOwner& InRHS)
540 {
541 return InLHS.DataPtr == InRHS.DataPtr;
542 }
543
544 inline friend bool operator!=(const TTypedElementOwner& InLHS, const TTypedElementOwner& InRHS)
545 {
546 return !(InLHS == InRHS);
547 }
548
550 {
551 return GetTypeHash(InElementOwner.GetId());
552 }
553
558
564
566 {
567 DataPtr = nullptr;
568#if UE_TYPED_ELEMENT_HAS_REFTRACKING
570#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
571 }
572
574 {
575 UnregisterRef();
577 }
578
580 {
581 return DataPtr;
582 }
583
584private:
585 inline void RegisterRef()
586 {
587 if (DataPtr)
588 {
589#if !UE_TYPED_ELEMENT_HAS_REFTRACKING
591#endif // !UE_TYPED_ELEMENT_HAS_REFTRACKING
592 ReferenceId = DataPtr->AddRef(/*bCanTrackReference*/true);
593 }
594 }
595
596 inline void UnregisterRef()
597 {
598 if (DataPtr)
599 {
600#if !UE_TYPED_ELEMENT_HAS_REFTRACKING
602#endif // !UE_TYPED_ELEMENT_HAS_REFTRACKING
603 DataPtr->ReleaseRef(ReferenceId);
604 }
605 }
606
608#if UE_TYPED_ELEMENT_HAS_REFTRACKING
610#endif // UE_TYPED_ELEMENT_HAS_REFTRACKING
611};
613
614
623USTRUCT(BlueprintType)
625{
627public:
628
630
632 : InternalData(InOther.InternalData)
633 {
634 }
635
637 : InternalData(MoveTemp(InOther.InternalData))
638 {
639 }
640
642 {
643 InternalData = InOther.InternalData;
644 return *this;
645 }
646
648 {
649 InternalData = MoveTemp(InOther.InternalData);
650 return *this;
651 }
652
654 {
655 return InternalData == InOther.InternalData;
656 }
657
659 {
660 return !(*this == InOther);
661 }
662
663 inline explicit operator bool() const
664 {
665 return IsSet();
666 }
667
668 inline bool IsSet() const
669 {
670 return InternalData.IsSet();
671 }
672
673 inline void Release()
674 {
675 InternalData.Release();
676 }
677
682
683 inline const FTypedElementId& GetId() const
684 {
685 return InternalData.GetId();
686 }
687
702
703private:
705};
706
708UCLASS()
710{
712
713public:
717 UFUNCTION(BlueprintPure, Category="TypedElementFramework|Handle", meta=(ScriptMethod, ScriptOperator="bool"))
719 {
720 return ElementHandle.IsSet();
721 }
722
726 UFUNCTION(BlueprintCallable, Category="TypedElementFramework|Handle", meta=(ScriptMethod))
731
735 UFUNCTION(BlueprintPure, Category="TypedElementFramework|Handle", meta=(DisplayName="Equal (TypedElementHandle)", CompactNodeTitle="==", Keywords="== equal", ScriptMethod, ScriptOperator="=="))
737 {
738 return LHS == RHS;
739 }
740
744 UFUNCTION(BlueprintPure, Category="TypedElementFramework|Handle", meta=(DisplayName="NotEqual (TypedElementHandle)", CompactNodeTitle="!=", Keywords="!= not equal", ScriptMethod, ScriptOperator="!="))
746 {
747 return LHS != RHS;
748 }
749};
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
#define UPARAM(...)
Definition ObjectMacros.h:748
#define GENERATED_BODY(...)
Definition ObjectMacros.h:765
#define UFUNCTION(...)
Definition ObjectMacros.h:745
#define UCLASS(...)
Definition ObjectMacros.h:776
#define USTRUCT(...)
Definition ObjectMacros.h:746
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
int32 FTypedElementReferenceId
Definition TypedElementLimits.h:34
#define UE_TYPED_ELEMENT_HAS_REFTRACKING
Definition TypedElementLimits.h:9
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
if(Failed) console_printf("Failed.\n")
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition TypedElementData.h:375
Definition TypedElementData.h:157
void ReleaseRef(const FTypedElementReferenceId InReferenceId) const
Definition TypedElementData.h:241
const FTypedElementId & GetId() const
Definition TypedElementData.h:212
virtual const void * GetUntypedData() const
Definition TypedElementData.h:303
FTypedElementReferenceId AddRef(const bool bCanTrackReference) const
Definition TypedElementData.h:217
Definition TypedElementData.h:328
Definition Object.h:95
Definition TypedElementHandle.h:710
UFUNCTION(BlueprintPure, Category="TypedElementFramework|Handle", meta=(DisplayName="Equal (TypedElementHandle)", CompactNodeTitle="==", Keywords="== equal", ScriptMethod, ScriptOperator="==")) static bool Equal(const FScriptTypedElementHandle &LHS
UFUNCTION(BlueprintPure, Category="TypedElementFramework|Handle", meta=(DisplayName="NotEqual (TypedElementHandle)", CompactNodeTitle="!=", Keywords="!= not equal", ScriptMethod, ScriptOperator="!=")) static bool NotEqual(const FScriptTypedElementHandle &LHS
@ Error
Definition LogVerbosity.h:28
static COREUOBJECT_API void KismetExecutionMessage(const TCHAR *Message, ELogVerbosity::Type Verbosity, FName WarningId=FName())
Definition ScriptCore.cpp:644
Definition TypedElementHandle.h:625
bool IsSet() const
Definition TypedElementHandle.h:668
FTypedElementHandle GetTypedElementHandle() const
Definition TypedElementHandle.h:692
FScriptTypedElementHandle(FScriptTypedElementHandle &&InOther)
Definition TypedElementHandle.h:636
void Private_Initialize(FScriptTypedElementInternalDataPtr &&InInternalData)
Definition TypedElementHandle.h:678
FScriptTypedElementHandle & operator=(FScriptTypedElementHandle &&InOther)
Definition TypedElementHandle.h:647
const FTypedElementId & GetId() const
Definition TypedElementHandle.h:683
bool operator!=(const FScriptTypedElementHandle &InOther) const
Definition TypedElementHandle.h:658
FScriptTypedElementHandle & operator=(const FScriptTypedElementHandle &InOther)
Definition TypedElementHandle.h:641
bool operator==(const FScriptTypedElementHandle &InOther) const
Definition TypedElementHandle.h:653
void Release()
Definition TypedElementHandle.h:673
FScriptTypedElementHandle(const FScriptTypedElementHandle &InOther)
Definition TypedElementHandle.h:631
FScriptTypedElementHandle()=default
Definition TypedElementHandle.h:18
void Private_DestroyReleaseRef()
Definition TypedElementHandle.h:226
const FTypedElementId & GetId() const
Definition TypedElementHandle.h:106
FTypedElementId AcquireId() const
Definition TypedElementHandle.h:167
friend bool operator==(const FTypedElementHandle &InLHS, const FTypedElementHandle &InRHS)
Definition TypedElementHandle.h:192
FTypedElementHandle(FTypedElementHandle &&InOther)
Definition TypedElementHandle.h:44
FTypedElementHandle & operator=(FTypedElementHandle &&InOther)
Definition TypedElementHandle.h:57
void Private_DestroyNoRef()
Definition TypedElementHandle.h:218
bool IsDataOfType() const
Definition TypedElementHandle.h:118
void Private_InitializeNoRef(const FTypedElementInternalData &InData)
Definition TypedElementHandle.h:207
FTypedElementHandle()=default
void Private_InitializeAddRef(const FTypedElementInternalData &InData)
Definition TypedElementHandle.h:212
const ElementDataType & GetDataChecked() const
Definition TypedElementHandle.h:156
void ReleaseId(FTypedElementId &InOutElementId) const
Definition TypedElementHandle.h:182
friend bool operator!=(const FTypedElementHandle &InLHS, const FTypedElementHandle &InRHS)
Definition TypedElementHandle.h:197
~FTypedElementHandle()
Definition TypedElementHandle.h:77
const FTypedElementInternalData * Private_GetInternalData() const
Definition TypedElementHandle.h:232
FTypedElementHandle(const FTypedElementHandle &InOther)
Definition TypedElementHandle.h:22
FTypedElementHandle & operator=(const FTypedElementHandle &InOther)
Definition TypedElementHandle.h:30
bool IsSet() const
Definition TypedElementHandle.h:90
friend uint32 GetTypeHash(const FTypedElementHandle &InElementHandle)
Definition TypedElementHandle.h:202
void Release()
Definition TypedElementHandle.h:98
const ElementDataType * GetData(const bool bSilent=false) const
Definition TypedElementHandle.h:128
Definition TypedElementId.h:17
void Private_InitializeNoRef(const FTypedHandleTypeId InTypeId, const FTypedHandleElementId InElementId)
Definition TypedElementId.h:104
FTypedHandleElementId GetElementId() const
Definition TypedElementId.h:73
static TYPEDELEMENTFRAMEWORK_API const FTypedElementId Unset
Definition TypedElementId.h:116
FTypedHandleTypeId GetTypeId() const
Definition TypedElementId.h:65
Definition TypedElementHandle.h:271
void Release()
Definition TypedElementHandle.h:321
TTypedElementBase(TTypedElementBase &&InOther)
Definition TypedElementHandle.h:278
TTypedElementBase & operator=(const TTypedElementBase &)=default
friend bool operator==(const TTypedElementBase &InLHS, const TTypedElementBase &InRHS)
Definition TypedElementHandle.h:345
friend uint32 GetTypeHash(const TTypedElementBase &InElement)
Definition TypedElementHandle.h:356
void Private_InitializeAddRef(const FTypedElementInternalData &InData, BaseInterfaceType *InInterfacePtr)
Definition TypedElementHandle.h:367
TTypedElementBase & operator=(TTypedElementBase &&InOther)
Definition TypedElementHandle.h:286
U & GetInterfaceChecked() const
Definition TypedElementHandle.h:338
BaseInterfaceType * InterfacePtr
Definition TypedElementHandle.h:386
friend bool operator!=(const TTypedElementBase &InLHS, const TTypedElementBase &InRHS)
Definition TypedElementHandle.h:351
TTypedElementBase()=default
bool IsSet() const
Definition TypedElementHandle.h:312
~TTypedElementBase()
Definition TypedElementHandle.h:299
BaseInterfaceType * GetInterface() const
Definition TypedElementHandle.h:329
TTypedElementBase(const TTypedElementBase &)=default
void Private_DestroyReleaseRef()
Definition TypedElementHandle.h:379
void Private_InitializeNoRef(const FTypedElementInternalData &InData, BaseInterfaceType *InInterfacePtr)
Definition TypedElementHandle.h:361
void Private_DestroyNoRef()
Definition TypedElementHandle.h:373
Definition TypedElementHandle.h:409
U & GetDataChecked() const
Definition TypedElementHandle.h:479
TTypedElementOwner(const TTypedElementOwner &)=delete
void ReleaseHandle(FTypedElementHandle &InOutElementHandle) const
Definition TypedElementHandle.h:533
TTypedElementOwner & operator=(const TTypedElementOwner &)=delete
bool IsSet() const
Definition TypedElementHandle.h:448
void Private_DestroyReleaseRef()
Definition TypedElementHandle.h:573
TTypedElementOwner & operator=(TTypedElementOwner &&InOther)
Definition TypedElementHandle.h:423
void Private_InitializeNoRef(TTypedElementInternalData< ElementDataType > &InData)
Definition TypedElementHandle.h:554
const TTypedElementInternalData< ElementDataType > * Private_GetInternalData() const
Definition TypedElementHandle.h:579
FTypedElementId AcquireId() const
Definition TypedElementHandle.h:490
TTypedElementOwner(TTypedElementOwner &&InOther)
Definition TypedElementHandle.h:416
friend bool operator==(const TTypedElementOwner &InLHS, const TTypedElementOwner &InRHS)
Definition TypedElementHandle.h:539
U * GetData() const
Definition TypedElementHandle.h:467
const FTypedElementId & GetId() const
Definition TypedElementHandle.h:456
FTypedElementHandle AcquireHandle() const
Definition TypedElementHandle.h:519
friend uint32 GetTypeHash(const TTypedElementOwner &InElementOwner)
Definition TypedElementHandle.h:549
void ReleaseId(FTypedElementId &InOutElementId) const
Definition TypedElementHandle.h:505
~TTypedElementOwner()
Definition TypedElementHandle.h:435
friend bool operator!=(const TTypedElementOwner &InLHS, const TTypedElementOwner &InRHS)
Definition TypedElementHandle.h:544
TTypedElementOwner()=default
void Private_DestroyNoRef()
Definition TypedElementHandle.h:565
void Private_InitializeAddRef(TTypedElementInternalData< ElementDataType > &InData)
Definition TypedElementHandle.h:559
Definition TypedElementHandle.h:396