MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Init.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12#pragma once
13
14#include "CoreMinimal.h"
15#include "Mcro/FunctionTraits.h"
16
18{
19 using namespace Mcro::FunctionTraits;
20
21 template <typename T, typename... Args>
22 concept CUObjectInitializable = CUObject<T> && requires(T* t, Args... args)
23 {
24 t->Initialize(args...);
25 };
26
27 /**
28 * @brief
29 * Mirror of `FStaticConstructObjectParameters` but it's a plain C++ object and doesn't have a constructor so
30 * designated initialization with named members is possible
31 */
33 {
34 /**
35 * @brief
36 * The object to create this object within (the Outer property for the new object will be set to the value
37 * specified here).
38 */
39 UObject* Outer = (UObject*)GetTransientPackage();
40
41 /** @brief The class of the object to create */
42 const UClass* Class;
43
44 /** @brief
45 * The name to give the new object. If no value (`NAME_None`) is specified, the object will be given a unique
46 * name in the form of `ClassName_#`.
47 */
48 FName Name = NAME_None;
49
50 /**
51 * @brief
52 * The ObjectFlags to assign to the new object. some flags can affect the behavior of constructing the object.
53 */
54 EObjectFlags Flags = RF_NoFlags;
55
56 /**
57 * @brief The `InternalObjectFlags` to assign to the new object. Some flags can affect the behavior of
58 * constructing the object.
59 */
60 EInternalObjectFlags InternalSetFlags = EInternalObjectFlags::None;
61
62 /**
63 * @brief
64 * If true, copy transient from the class defaults instead of the pass in archetype ptr (often these are the same)
65 */
66 bool bCopyTransientsFromClassDefaults = false;
67
68 /** @brief If true, Template is guaranteed to be an archetype */
69 bool bAssumeTemplateIsArchetype = false;
70
71 /**
72 * @brief
73 * If specified, the property values from this object will be copied to the new object, and the new object's
74 * `ObjectArchetype` value will be set to this object. If nullptr, the class default object is used instead.
75 */
76 UObject* Template = nullptr;
77
78 /** @brief Contains the mappings of instanced objects and components to their templates */
79 FObjectInstancingGraph* InstanceGraph = nullptr;
80
81 /** @brief Assign an external Package to the created object if non-null */
82 UPackage* ExternalPackage = nullptr;
83
84 /** @brief Callback for custom code to initialize properties before `PostInitProperties` runs */
85 TFunction<void()> PropertyInitCallback;
86 };
87
88 namespace Detail
89 {
90 template <CUObject T, typename... Args>
91 void InitObject(T* object, Args&&... args) {}
92
93 template <CUObject T, typename... Args>
94 requires CUObjectInitializable<T, Args...>
95 void InitObject(T* object, Args&&... args)
96 {
97 object->Initialize(FWD(args)...);
98 }
99 }
100
101 /**
102 * @brief
103 * Create a new object which can also be initialized with an `Initialize` function if it has one.
104 * In case it has an `Initialize` function the `args` parameters should match them. This is an equivalent to
105 * the template Mcro::SharedObjects::MakeShareableInit
106 *
107 * @tparam T Type of initializable UObject
108 * @tparam Args Arguments for the Initialize function
109 * @param params Parameters for every new object
110 * @param args Arguments for the Initialize function
111 * @return The new object
112 */
113 template <CUObject T, typename... Args>
114 T* NewInit(FConstructObjectParameters&& params, Args&&... args)
115 {
116 T* result = NewObject<T>(
117 params.Outer,
118 params.Class ? params.Class : T::StaticClass(),
119 params.Name,
120 params.Flags,
121 params.Template,
122 params.bCopyTransientsFromClassDefaults,
123 params.InstanceGraph,
124 params.ExternalPackage
125 );
126 Detail::InitObject(result, FWD(args)...);
127 return result;
128 }
129
130 /**
131 * @brief
132 * Equivalent to Mcro::Construct::Construct but for UObjects.
133 *
134 * Usage:
135 * @code
136 * using namespace Mcro::UObjects::Init;
137 *
138 * auto myObject = Construct({}, [](UMyObject& _)
139 * {
140 * _.Foo = 42;
141 * _.Bar();
142 * // etc...
143 * });
144 * static_assert(std::is_same_v<decltype(myObject), UMyObject*>);
145 * @endcode
146 *
147 * Notice how the object type is deduced from the argument of the initializer.
148 *
149 * @tparam Initializer Initializer function type
150 * @param params Parameters for every new object
151 * @param init A setup function for the newly created UObject
152 * @return The new object
153 */
154 template <
155 CFunctorObject Initializer,
156 typename TArg = TFunction_Arg<Initializer, 0>,
157 CUObject T = std::decay_t<TArg>
158 >
159 requires std::is_lvalue_reference_v<TArg>
160 T* ConstructObject(FConstructObjectParameters&& params, Initializer&& init)
161 {
162 T* result = NewObject<T>(
163 params.Outer,
164 params.Class ? params.Class : T::StaticClass(),
165 params.Name,
166 params.Flags,
167 params.Template,
168 params.bCopyTransientsFromClassDefaults,
169 params.InstanceGraph,
170 params.ExternalPackage
171 );
172 init(*result);
173 return result;
174 }
175
176 /**
177 * @brief
178 * Equivalent to Mcro::Construct::Construct but for `UObjects`. If the constructed `UObject` type also has an
179 * `Initialize` function call that too after the lambda initializer. The `args` parameters should match the
180 * signature of `Initialize` in that case.
181 *
182 * Usage:
183 * @code
184 * using namespace Mcro::UObjects::Init;
185 *
186 * auto myObject = Construct({}, [](UMyObject& _)
187 * {
188 * _.Foo = 42;
189 * _.Bar();
190 * // etc...
191 * });
192 * static_assert(std::is_same_v<decltype(myObject), UMyObject*>);
193 * @endcode
194 *
195 * Notice how the object type is deduced from the argument of the initializer.
196 *
197 * @tparam Initializer Initializer function type
198 * @tparam Args Arguments for the Initialize function
199 * @param params Parameters for every new object
200 * @param init A setup function for the newly created UObject
201 * @param args Arguments for the Initialize function
202 * @return The new object
203 */
204 template <
205 CFunctorObject Initializer,
206 typename... Args,
207 typename TArg = TFunction_Arg<Initializer, 0>,
208 CUObject T = std::decay_t<TArg>
209 >
210 requires std::is_lvalue_reference_v<TArg>
211 T* ConstructInit(FConstructObjectParameters&& params, Initializer&& init, Args&&... args)
212 {
213 T* result = NewObject<T>(
214 params.Outer,
215 params.Class ? params.Class : T::StaticClass(),
216 params.Name,
217 params.Flags,
218 params.Template,
219 params.bCopyTransientsFromClassDefaults,
220 params.InstanceGraph,
221 params.ExternalPackage
222 );
223 init(*result);
224 Detail::InitObject(result, FWD(args)...);
225 return result;
226 }
227}
#define FWD(...)
Shorten forwarding expression with this macro so one may not need to specify explicit type.
Definition Macros.h:100
typename TFunctionTraits< std::decay_t< T > >::template Arg< I > TFunction_Arg
Shorthand for getting a type of a function argument at given position I.
void InitObject(T *object, Args &&... args)
Definition Init.h:91
T * ConstructObject(FConstructObjectParameters &&params, Initializer &&init)
Equivalent to Mcro::Construct::Construct but for UObjects.
Definition Init.h:160
T * ConstructInit(FConstructObjectParameters &&params, Initializer &&init, Args &&... args)
Equivalent to Mcro::Construct::Construct but for UObjects. If the constructed UObject type also has a...
Definition Init.h:211
T * NewInit(FConstructObjectParameters &&params, Args &&... args)
Create a new object which can also be initialized with an Initialize function if it has one....
Definition Init.h:114
Mirror of FStaticConstructObjectParameters but it's a plain C++ object and doesn't have a constructor...
Definition Init.h:33
TFunction< void()> PropertyInitCallback
Callback for custom code to initialize properties before PostInitProperties runs.
Definition Init.h:85
const UClass * Class
The class of the object to create.
Definition Init.h:42