UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
VVMCppClassInfo.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if WITH_VERSE_VM || defined(__INTELLISENSE__)
6
8#include "HAL/Platform.h"
11#include "VerseVM/VVMOpResult.h"
12#include "VerseVM/VVMVerse.h"
13#include <type_traits>
14
15class FJsonObject;
16class FJsonValue;
17
18namespace Verse
19{
20enum class ECompares : uint8;
21enum class EValueStringFormat;
22enum class EValueJSONFormat;
23enum class EVisitState;
24struct FAbstractVisitor;
25struct FAllocationContext;
26struct FDebuggerVisitor;
28struct FOp;
29struct FRunningContext;
31struct VCell;
32struct VTask;
33struct VValue;
35
36// MSVC and clang-cl have a non-portable __super that can be used to validate the user's super-class declaration.
37#if defined(_MSC_VER)
38#define VCPPCLASSINFO_PORTABLE_MSC_SUPER \
39 /* disable non-standard extension warning */ \
40 __pragma(warning(push)) __pragma(warning(disable : 4495)) __super __pragma(warning(pop))
41#else
42#define VCPPCLASSINFO_PORTABLE_MSC_SUPER Super
43#endif
44
45#define DECLARE_BASE_VCPPCLASSINFO(API) \
46protected: \
47 auto CheckSuperClass() \
48 { \
49 return this; \
50 } \
51 \
52 API void VisitInheritedAndNonInheritedReferences(::Verse::FAbstractVisitor& Visitor); \
53 API void VisitInheritedAndNonInheritedReferences(::Verse::FMarkStackVisitor& Visitor); \
54 \
55public: \
56 API static ::Verse::VCppClassInfo StaticCppClassInfo;
57
58#define DECLARE_DERIVED_VCPPCLASSINFO(API, SuperClass) \
59private: \
60 template <typename TVisitor> \
61 void VisitReferencesImpl(TVisitor&); /* to be implemented by the user. */ \
62 \
63protected: \
64 auto CheckSuperClass() \
65 { \
66 auto SuperThis = VCPPCLASSINFO_PORTABLE_MSC_SUPER::CheckSuperClass(); \
67 static_assert(std::is_same_v<decltype(SuperThis), SuperClass*>, \
68 "Declared super-class " #SuperClass " does not match actual super-class."); \
69 return this; \
70 } \
71 \
72 API void VisitInheritedAndNonInheritedReferences(::Verse::FAbstractVisitor& Visitor); \
73 API void VisitInheritedAndNonInheritedReferences(::Verse::FMarkStackVisitor& Visitor); \
74 \
75public: \
76 using Super = SuperClass; \
77 API static ::Verse::VCppClassInfo StaticCppClassInfo;
78
79#define DEFINE_BASE_OR_DERIVED_VCPPCLASSINFO(CellType, SuperClassInfoPtr) \
80 ::Verse::VCppClassInfo CellType::StaticCppClassInfo = { \
81 TEXT(#CellType), \
82 (SuperClassInfoPtr), \
83 sizeof(CellType), \
84 [](::Verse::VCell* This, ::Verse::FMarkStackVisitor& Visitor) -> void { \
85 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
86 This->StaticCast<CellType>().VisitInheritedAndNonInheritedReferences(Visitor); \
87 }, \
88 [](::Verse::VCell* This, ::Verse::FAbstractVisitor& Visitor) -> void { \
89 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
90 ::Verse::FAbstractVisitor::FReferrerContext Context(Visitor, FReferenceToken(This)); \
91 This->StaticCast<CellType>().VisitInheritedAndNonInheritedReferences(Visitor); \
92 }, \
93 [](::Verse::VCell* This) -> void { \
94 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
95 This->StaticCast<CellType>().ConductCensusImpl(); \
96 }, \
97 std::is_trivially_destructible_v<CellType> ? nullptr : [](::Verse::VCell* This) -> void { \
98 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
99 This->StaticCast<CellType>().~CellType(); \
100 }, \
101 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, ::Verse::VCell* Other, const TFunction<void(::Verse::VValue, ::Verse::VValue)>& HandlePlaceholder) -> ::Verse::ECompares { \
102 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
103 return This->StaticCast<CellType>().EqualImpl(Context, Other, HandlePlaceholder); \
104 }, \
105 [](::Verse::VCell* This) -> uint32 { \
106 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
107 return This->StaticCast<CellType>().GetTypeHashImpl(); \
108 }, \
109 [](::Verse::FAllocationContext Context, ::Verse::VCell* This) -> ::Verse::VValue { \
110 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
111 return This->StaticCast<CellType>().MeltImpl(Context); \
112 }, \
113 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, ::Verse::VTask* Task, ::Verse::FOp* AwaitPC) -> ::Verse::FOpResult { \
114 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
115 return This->StaticCast<CellType>().FreezeImpl(Context, Task, AwaitPC); \
116 }, \
117 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, ::Verse::VValue InputValue) -> bool { \
118 /* TODO(SOL-8589): Subsumes is currently reachable from the closed. */ \
119 return This->StaticCast<CellType>().SubsumesImpl(Context, InputValue); \
120 }, \
121 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, ::Verse::FDebuggerVisitor& Visitor) -> void { \
122 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
123 This->StaticCast<CellType>().VisitMembersImpl(Context, Visitor); \
124 }, \
125 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, FUtf8StringBuilderBase& Builder, ::Verse::EValueStringFormat Format, TSet<const void*>& VisitedObjects, uint32 RecursionDepth) -> void { \
126 /* TODO(SOL-8589): AppendToString is currently reachable from the closed. */ \
127 This->StaticCast<CellType>().AppendToStringImpl(Context, Builder, Format, VisitedObjects, RecursionDepth); \
128 }, \
129 [](::Verse::FRunningContext Context, ::Verse::VCell* This, ::Verse::EValueJSONFormat Format, TMap<const void*, ::Verse::EVisitState>& VisitedObjects, const ::Verse::VerseVMToJsonCallback& Callback, uint32 RecursionDepth, FJsonObject* Defs) -> TSharedPtr<FJsonValue> { \
130 /* TODO(SOL-8589): ToJSON is currently reachable from the closed. */ \
131 return This->StaticCast<CellType>().ToJSONImpl(Context, Format, VisitedObjects, Callback, RecursionDepth, Defs); \
132 }, \
133 [](::Verse::FRunningContext Context, ::Verse::VCell* This, const FJsonValue& JsonValue, ::Verse::EValueJSONFormat Format) -> ::Verse::VValue { \
134 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
135 return This->StaticCast<CellType>().FromJSONImpl(Context, JsonValue, Format); \
136 }, \
137 [](::Verse::FAllocationContext Context, ::Verse::VCell*& This, ::Verse::FStructuredArchiveVisitor& Visitor) -> void { \
138 /* TODO(SOL-8589): SerializeLayout is currently reachable from the closed. */ \
139 CellType* Scratch = This != nullptr ? &This->StaticCast<CellType>() : nullptr; \
140 CellType::SerializeLayout(Context, Scratch, Visitor); \
141 This = Scratch; \
142 }, \
143 [](::Verse::FAllocationContext Context, ::Verse::VCell* This, ::Verse::FStructuredArchiveVisitor& Visitor) -> void { \
144 /* TODO(SOL-8589): Serialize is currently reachable from the closed. */ \
145 This->StaticCast<CellType>().SerializeImpl(Context, Visitor); \
146 }, \
147 CellType::SerializeIdentity}; \
148 ::Verse::VCppClassInfoRegister CellType##_Register(&CellType::StaticCppClassInfo);
149
150#define DEFINE_BASE_VCPPCLASSINFO(CellType) \
151 DEFINE_BASE_OR_DERIVED_VCPPCLASSINFO(CellType, nullptr) \
152 void CellType::VisitInheritedAndNonInheritedReferences(::Verse::FAbstractVisitor& Visitor) \
153 { \
154 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
155 VisitReferencesImpl(Visitor); \
156 } \
157 \
158 void CellType::VisitInheritedAndNonInheritedReferences(::Verse::FMarkStackVisitor& Visitor) \
159 { \
160 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
161 VisitReferencesImpl(Visitor); \
162 }
163
164#define DEFINE_DERIVED_VCPPCLASSINFO(CellType) \
165 static_assert(!std::is_same_v<CellType::Super, CellType>, #CellType " declares itself as its super-class in DECLARE_DERIVED_VCPPCLASSINFO."); \
166 static_assert(std::is_base_of_v<CellType::Super, CellType>, #CellType " doesn't derive from the super-class declared by DECLARE_DERIVED_VCPPCLASSINFO."); \
167 static_assert(std::is_base_of_v<::Verse::VCell, CellType::Super>, #CellType "'s super-class as declared by DECLARE_DERIVED_VCPPCLASSINFO does not derive from VCell."); \
168 static_assert(!std::is_polymorphic_v<CellType>, "VCell-derived C++ classes must not have virtual methods."); \
169 DEFINE_BASE_OR_DERIVED_VCPPCLASSINFO(CellType, &CellType::Super::StaticCppClassInfo) \
170 void CellType::VisitInheritedAndNonInheritedReferences(::Verse::FAbstractVisitor& Visitor) \
171 { \
172 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
173 Super::VisitInheritedAndNonInheritedReferences(Visitor); \
174 VisitReferencesImpl(Visitor); \
175 } \
176 \
177 void CellType::VisitInheritedAndNonInheritedReferences(::Verse::FMarkStackVisitor& Visitor) \
178 { \
179 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
180 Super::VisitInheritedAndNonInheritedReferences(Visitor); \
181 VisitReferencesImpl(Visitor); \
182 }
183
184#define DEFINE_TRIVIAL_VISIT_REFERENCES(CellType) \
185 template <typename TVisitor> \
186 void CellType::VisitReferencesImpl(TVisitor&) \
187 { \
188 AutoRTFM::UnreachableIfClosed("#jira SOL-8416"); \
189 }
190
191// C++ information; this is where the "vtable" goes.
192struct VCppClassInfo
193{
194 const TCHAR* Name;
195 VCppClassInfo* SuperClass;
196 size_t SizeWithoutFields;
201 ECompares (*Equal)(FAllocationContext Context, VCell* This, VCell* Other, const TFunction<void(::Verse::VValue, ::Verse::VValue)>& HandlePlaceholder);
202 uint32 (*GetTypeHash)(VCell* This);
203 VValue (*Melt)(FAllocationContext Context, VCell* This);
204 FOpResult (*Freeze)(FAllocationContext Context, VCell* This, VTask*, FOp* AwaitPC);
205 bool (*Subsumes)(FAllocationContext Context, VCell* This, VValue);
206 void (*VisitMembers)(FAllocationContext Context, VCell* This, FDebuggerVisitor& Visitor);
207 void (*AppendToString)(FAllocationContext Context, VCell* This, FUtf8StringBuilderBase& Builder, EValueStringFormat Format, TSet<const void*>& VisitedObjects, uint32 RecursionDepth);
213
214 bool IsA(const VCppClassInfo* Other) const
215 {
216 for (const VCppClassInfo* Current = this; Current; Current = Current->SuperClass)
217 {
218 if (Current == Other)
219 {
220 return true;
221 }
222 }
223 return false;
224 }
225
227 {
228 MarkReferencesImpl(This, Visitor);
229 }
230
232 {
233 VisitReferencesImpl(This, Visitor);
234 }
235
236 COREUOBJECT_API FString DebugName() const;
237};
238
240{
241 VCppClassInfo* CppClassInfo;
243
246};
247
249{
251};
252
253// Extension point for VisitReferencesImpl and F*Visitor method instantiations
254template <typename VisitorType, typename ValueType>
255void Visit(VisitorType& Visitor, ValueType& Value) = delete;
256
257template <typename VisitorType, typename KeyType, typename ValueType>
259{
260 Visitor.Visit(Value.Key, TEXT("Key"));
261 Visitor.Visit(Value.Value, TEXT("Value"));
262}
263
264} // namespace Verse
265#endif // WITH_VERSE_VM
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
void AppendToString(const FStringFormatArg &Arg, StringType &StringToAppendTo)
Definition StringFormatter.cpp:64
decltype(auto) Visit(Func &&Callable, Variants &&... Args)
Definition TVariant.h:271
#define V_FORCEINLINE
Definition VVMVerse.h:30
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition JsonObject.h:23
Definition JsonValue.h:22
Definition AndroidPlatformMisc.h:14
Definition UnrealString.h.inl:34
Definition SharedPointer.h:692
Definition StringBuilder.h:79
@ Visitor
Definition XmppMultiUserChat.h:94
Definition Array.h:3955
bool IsA(const UStruct *)
Definition MassEntityElementTypes.h:49
Definition Archive.h:36
EValueJSONFormat
Definition VVMJson.h:47
EValueStringFormat
Definition VVMValuePrinting.h:17
EVisitState
Definition VVMJson.h:54
Definition Tuple.h:652