Size: 63864
Comment:
|
← Revision 9 as of 2021-11-02 08:25:38 ⇥
Size: 64910
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
研究一下:UObject::PostInitProperties虚函数 {{{#!highlight c++ // UObjectGlobals.cpp /** * Called after the C++ constructor and after the properties have been initialized, including those loaded from config. * This is called before any serialization or other setup has happened. */ virtual void PostInitProperties(); }}} 函数注释描述得很清楚,PostInitProperties函数在C++构造函数之后,且在属性已经初始化了(包括从config里还原了值)以后被立即调用,此时,序列化和其他创建工作尚未开始。注意这些描述都是在UObject的语境下。<<BR>> 引擎'''唯一'''的一处Obj->PostInitProperties()调用,发生在FObjectInitializer::PostConstructInit()之中。而PostConstructInit在~FObjectInitializer()中被调用。 ---- 再看一看UObject::PostLoad():<<BR>> {{{#!highlight c++ // Obj.cpp UObject::ConditionalPostLoad() { UObject::ConditionalPostLoadSubobjects();->{ UObject::PostLoadSubobjects();} UObject::PostLoad(); } }}} ---- |
研究一下:UObject::PostInitProperties虚函数
函数注释描述得很清楚,PostInitProperties函数在C++构造函数之后,且在属性已经初始化了(包括从config里还原了值)以后被立即调用,此时,序列化和其他创建工作尚未开始。注意这些描述都是在UObject的语境下。
引擎唯一的一处Obj->PostInitProperties()调用,发生在FObjectInitializer::PostConstructInit()之中。而PostConstructInit在~FObjectInitializer()中被调用。
再看一看UObject::PostLoad():
1 // Copyright Epic Games, Inc. All Rights Reserved.
2
3 #pragma once
4
5 /*=============================================================================
6 Object.h: Direct base class for all UE4 objects
7 =============================================================================*/
8
9 #include "CoreMinimal.h"
10 #include "UObject/Script.h"
11 #include "UObject/ObjectMacros.h"
12 #include "UObject/UObjectBaseUtility.h"
13 #include "ProfilingDebugging/ResourceSize.h"
14 #include "UObject/PrimaryAssetId.h"
15
16 struct FAssetData;
17 class FConfigCacheIni;
18 class FEditPropertyChain;
19 class ITargetPlatform;
20 class ITransactionObjectAnnotation;
21 class FTransactionObjectEvent;
22 struct FFrame;
23 struct FObjectInstancingGraph;
24 struct FPropertyChangedChainEvent;
25 class UClass;
26
27 DECLARE_LOG_CATEGORY_EXTERN(LogObj, Log, All);
28
29 /** Parameter enum for CastChecked() function, defines when it will check/assert */
30 namespace ECastCheckedType
31 {
32 enum Type
33 {
34 /** Null is okay, only assert on incorrect type */
35 NullAllowed,
36 /** Null is not allowed, assert on incorrect type or null */
37 NullChecked
38 };
39 };
40
41 /**
42 * The base class of all UE4 objects. The type of an object is defined by its UClass.
43 * This provides support functions for creating and using objects, and virtual functions that should be overridden in child classes.
44 *
45 * @see https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/Objects
46 */
47 class COREUOBJECT_API UObject : public UObjectBaseUtility
48 {
49 // Declarations, normally created by UnrealHeaderTool boilerplate code
50 DECLARE_CLASS(UObject,UObject,CLASS_Abstract|CLASS_NoExport|CLASS_Intrinsic|CLASS_MatchedSerializers,CASTCLASS_None,TEXT("/Script/CoreUObject"),NO_API)
51 DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(UObject)
52 typedef UObject WithinClass;
53 static UObject* __VTableCtorCaller(FVTableHelper& Helper)
54 {
55 return new (EC_InternalUseOnlyConstructor, (UObject*)GetTransientPackage(), NAME_None, RF_NeedLoad | RF_ClassDefaultObject | RF_TagGarbageTemp) UObject(Helper);
56 }
57 static const TCHAR* StaticConfigName()
58 {
59 return TEXT("Engine");
60 }
61 static void StaticRegisterNativesUObject()
62 {
63 }
64
65 /** Default constructor */
66 UObject();
67
68 /** Deprecated constructor, ObjectInitializer is no longer needed but is supported for older classes. */
69 UObject(const FObjectInitializer& ObjectInitializer);
70
71 /** DO NOT USE. This constructor is for internal usage only for statically-created objects. */
72 UObject(EStaticConstructor, EObjectFlags InFlags);
73
74 /** DO NOT USE. This constructor is for internal usage only for hot-reload purposes. */
75 UObject(FVTableHelper& Helper);
76
77 UE_DEPRECATED(4.23, "CreateDefaultSubobject no longer takes bAbstract as a parameter.")
78 UObject* CreateDefaultSubobject(FName SubobjectFName, UClass* ReturnType, UClass* ClassToCreateByDefault, bool bIsRequired, bool bAbstract, bool bIsTransient)
79 {
80 return CreateDefaultSubobject(SubobjectFName, ReturnType, ClassToCreateByDefault, bIsRequired, bIsTransient);
81 }
82
83 /** Utility function for templates below */
84 UObject* CreateDefaultSubobject(FName SubobjectFName, UClass* ReturnType, UClass* ClassToCreateByDefault, bool bIsRequired, bool bIsTransient);
85
86 /**
87 * Create a component or subobject only to be used with the editor. They will be stripped out in packaged builds.
88 * @param TReturnType Class of return type, all overrides must be of this type
89 * @param SubobjectName Name of the new component
90 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
91 */
92 template<class TReturnType>
93 TReturnType* CreateEditorOnlyDefaultSubobject(FName SubobjectName, bool bTransient = false)
94 {
95 UClass* ReturnType = TReturnType::StaticClass();
96 return static_cast<TReturnType*>(CreateEditorOnlyDefaultSubobjectImpl(SubobjectName, ReturnType, bTransient));
97 }
98
99 /**
100 * Create a component or subobject.
101 * @param TReturnType Class of return type, all overrides must be of this type
102 * @param SubobjectName Name of the new component
103 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
104 */
105 template<class TReturnType>
106 TReturnType* CreateDefaultSubobject(FName SubobjectName, bool bTransient = false)
107 {
108 UClass* ReturnType = TReturnType::StaticClass();
109 return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, ReturnType, ReturnType, /*bIsRequired =*/ true, bTransient));
110 }
111
112 /**
113 * Create a component or subobject, allows creating a child class and returning the parent class.
114 * @param TReturnType Class of return type, all overrides must be of this type
115 * @param TClassToConstructByDefault Class of object to actually construct, must be a subclass of TReturnType
116 * @param SubobjectName Name of the new component
117 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
118 */
119 template<class TReturnType, class TClassToConstructByDefault>
120 TReturnType* CreateDefaultSubobject(FName SubobjectName, bool bTransient = false)
121 {
122 return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, TReturnType::StaticClass(), TClassToConstructByDefault::StaticClass(), /*bIsRequired =*/ true, bTransient));
123 }
124
125 /**
126 * Create an optional component or subobject. Optional subobjects will not get created
127 * if a derived class specified DoNotCreateDefaultSubobject with the subobject's name.
128 * @param TReturnType Class of return type, all overrides must be of this type
129 * @param SubobjectName Name of the new component
130 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
131 */
132 template<class TReturnType>
133 TReturnType* CreateOptionalDefaultSubobject(FName SubobjectName, bool bTransient = false)
134 {
135 UClass* ReturnType = TReturnType::StaticClass();
136 return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, ReturnType, ReturnType, /*bIsRequired =*/ false, bTransient));
137 }
138
139 /**
140 * Create an optional component or subobject. Optional subobjects will not get created
141 * if a derived class specified DoNotCreateDefaultSubobject with the subobject's name.
142 * @param TReturnType Class of return type, all overrides must be of this type
143 * @param TClassToConstructByDefault Class of object to actually construct, must be a subclass of TReturnType
144 * @param SubobjectName Name of the new component
145 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
146 */
147 template<class TReturnType, class TClassToConstructByDefault>
148 TReturnType* CreateOptionalDefaultSubobject(FName SubobjectName, bool bTransient = false)
149 {
150 return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, TReturnType::StaticClass(), TClassToConstructByDefault::StaticClass(), /*bIsRequired =*/ false, bTransient));
151 }
152 /**
153 * Create a subobject that has the Abstract class flag, child classes are expected to override this by calling SetDefaultSubobjectClass with the same name and a non-abstract class.
154 * @param TReturnType Class of return type, all overrides must be of this type
155 * @param SubobjectName Name of the new component
156 * @param bTransient True if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
157 */
158 template<class TReturnType>
159 UE_DEPRECATED(4.23, "CreateAbstract did not work as intended and has been deprecated in favor of CreateDefaultObject")
160 TReturnType* CreateAbstractDefaultSubobject(FName SubobjectName, bool bTransient = false)
161 {
162 UClass* ReturnType = TReturnType::StaticClass();
163 return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, ReturnType, ReturnType, /*bIsRequired =*/ true, bTransient));
164 }
165
166 /**
167 * Gets all default subobjects associated with this object instance.
168 * @param OutDefaultSubobjects Array containing all default subobjects of this object.
169 */
170 void GetDefaultSubobjects(TArray<UObject*>& OutDefaultSubobjects);
171
172 /**
173 * Finds a subobject associated with this object instance by its name
174 * @param Name Object name to look for
175 */
176 UObject* GetDefaultSubobjectByName(FName ToFind);
177
178 /*----------------------------------
179 UObject interface
180 ----------------------------------*/
181
182 protected:
183 /**
184 * This function actually does the work for the GetDetailedInfo() and is virtual.
185 * It should only be called from GetDetailedInfo as GetDetailedInfo is safe to call on NULL object pointers
186 */
187 virtual FString GetDetailedInfoInternal() const { return TEXT("No_Detailed_Info_Specified"); }
188
189 public:
190 /**
191 * Called after the C++ constructor and after the properties have been initialized, including those loaded from config.
192 * This is called before any serialization or other setup has happened.
193 */
194 virtual void PostInitProperties();
195
196 /**
197 * Called after the C++ constructor has run on the CDO for a class. This is an obscure routine used to deal with the recursion
198 * in the construction of the default materials
199 */
200 virtual void PostCDOContruct()
201 {
202 }
203
204 /**
205 * Called from within SavePackage on the passed in base/root object. The return value of this function will be passed to PostSaveRoot.
206 * This is used to allow objects used as a base to perform required actions before saving and cleanup afterwards.
207 * @param Filename: Name of the file being saved to (includes path)
208
209 * @return Whether PostSaveRoot needs to perform internal cleanup
210 */
211 virtual bool PreSaveRoot(const TCHAR* Filename)
212 {
213 return false;
214 }
215
216 /**
217 * Called from within SavePackage on the passed in base/root object.
218 * This function is called after the package has been saved and can perform cleanup.
219 *
220 * @param bCleanupIsRequired Whether PreSaveRoot dirtied state that needs to be cleaned up
221 */
222 virtual void PostSaveRoot( bool bCleanupIsRequired ) {}
223
224 /**
225 * Presave function. Gets called once before an object gets serialized for saving. This function is necessary
226 * for save time computation as Serialize gets called three times per object from within SavePackage.
227 *
228 * @warning: Objects created from within PreSave will NOT have PreSave called on them!!!
229 */
230 virtual void PreSave(const class ITargetPlatform* TargetPlatform);
231
232 /**
233 * Note that the object will be modified. If we are currently recording into the
234 * transaction buffer (undo/redo), save a copy of this object into the buffer and
235 * marks the package as needing to be saved.
236 *
237 * @param bAlwaysMarkDirty if true, marks the package dirty even if we aren't
238 * currently recording an active undo/redo transaction
239 * @return true if the object was saved to the transaction buffer
240 */
241 #if WITH_EDITOR
242 virtual bool Modify( bool bAlwaysMarkDirty=true );
243
244 /** Utility to allow overrides of Modify to avoid doing work if this object cannot be safely modified */
245 bool CanModify() const;
246 #else
247 FORCEINLINE bool Modify(bool bAlwaysMarkDirty = true) { return false; }
248 #endif
249
250 #if WITH_EDITOR
251 /**
252 * Called when the object was loaded from another class via active class redirects.
253 */
254 virtual void LoadedFromAnotherClass(const FName& OldClassName) {}
255 #endif
256
257 /**
258 * Called before calling PostLoad() in FAsyncPackage::PostLoadObjects(). This is the safeguard to prevent PostLoad() from stalling the main thread.
259 */
260 virtual bool IsReadyForAsyncPostLoad() const { return true; }
261
262 /**
263 * Do any object-specific cleanup required immediately after loading an object.
264 * This is not called for newly-created objects, and by default will always execute on the game thread.
265 */
266 virtual void PostLoad();
267
268 /**
269 * Instances components for objects being loaded from disk, if necessary. Ensures that component references
270 * between nested components are fixed up correctly.
271 *
272 * @param OuterInstanceGraph when calling this method on subobjects, specifies the instancing graph which contains all instanced
273 * subobjects and components for a subobject root.
274 */
275 virtual void PostLoadSubobjects(FObjectInstancingGraph* OuterInstanceGraph);
276
277 /**
278 * Called before destroying the object. This is called immediately upon deciding to destroy the object, to allow the object to begin an
279 * asynchronous cleanup process.
280 */
281 virtual void BeginDestroy();
282
283 /**
284 * Called to check if the object is ready for FinishDestroy. This is called after BeginDestroy to check the completion of the
285 * potentially asynchronous object cleanup.
286 * @return True if the object's asynchronous cleanup has completed and it is ready for FinishDestroy to be called.
287 */
288 virtual bool IsReadyForFinishDestroy() { return true; }
289
290 #if WITH_EDITOR
291 /**
292 * Called in response to the linker changing, this can only happen in the editor
293 */
294 virtual void PostLinkerChange() {}
295 #endif
296
297 /**
298 * Called to finish destroying the object. After UObject::FinishDestroy is called, the object's memory should no longer be accessed.
299 *
300 * @warning Because properties are destroyed here, Super::FinishDestroy() should always be called at the end of your child class's FinishDestroy() method, rather than at the beginning.
301 */
302 virtual void FinishDestroy();
303
304 /**
305 * Handles reading, writing, and reference collecting using FArchive.
306 * This implementation handles all FProperty serialization, but can be overridden for native variables.
307 */
308 virtual void Serialize(FArchive& Ar);
309 virtual void Serialize(FStructuredArchive::FRecord Record);
310
311 /** After a critical error, perform any mission-critical cleanup, such as restoring the video mode orreleasing hardware resources. */
312 virtual void ShutdownAfterError() {}
313
314 /**
315 * This is called when property is modified by InterpPropertyTracks
316 *
317 * @param PropertyThatChanged Property that changed
318 */
319 virtual void PostInterpChange(FProperty* PropertyThatChanged) {}
320
321 #if WITH_EDITOR
322 /**
323 * This is called when a property is about to be modified externally
324 *
325 * @param PropertyThatWillChange Property that will be changed
326 */
327 virtual void PreEditChange(FProperty* PropertyAboutToChange);
328
329 /**
330 * This alternate version of PreEditChange is called when properties inside structs are modified. The property that was actually modified
331 * is located at the tail of the list. The head of the list of the FStructProperty member variable that contains the property that was modified.
332 *
333 * @param PropertyAboutToChange the property that is about to be modified
334 */
335 virtual void PreEditChange( class FEditPropertyChain& PropertyAboutToChange );
336
337 /**
338 * Called by the editor to query whether a property of this object is allowed to be modified.
339 * The property editor uses this to disable controls for properties that should not be changed.
340 * When overriding this function you should always call the parent implementation first.
341 *
342 * @param InProperty The property to query
343 *
344 * @return true if the property can be modified in the editor, otherwise false
345 */
346 virtual bool CanEditChange( const FProperty* InProperty ) const;
347
348 /**
349 * Intentionally non-virtual as it calls the FPropertyChangedEvent version
350 */
351 void PostEditChange();
352
353 /**
354 * Called when a property on this object has been modified externally
355 *
356 * @param PropertyThatChanged the property that was modified
357 */
358 virtual void PostEditChangeProperty( struct FPropertyChangedEvent& PropertyChangedEvent);
359
360 /**
361 * This alternate version of PostEditChange is called when properties inside structs are modified. The property that was actually modified
362 * is located at the tail of the list. The head of the list of the FStructProperty member variable that contains the property that was modified.
363 */
364 virtual void PostEditChangeChainProperty( struct FPropertyChangedChainEvent& PropertyChangedEvent );
365
366 /** Called before applying a transaction to the object. Default implementation simply calls PreEditChange. */
367 virtual void PreEditUndo();
368
369 /** Called after applying a transaction to the object. Default implementation simply calls PostEditChange. */
370 virtual void PostEditUndo();
371
372 /** Called after applying a transaction to the object in cases where transaction annotation was provided. Default implementation simply calls PostEditChange. */
373 virtual void PostEditUndo(TSharedPtr<ITransactionObjectAnnotation> TransactionAnnotation);
374
375 /**
376 * Called after the object has been transacted in some way.
377 * TransactionEvent describes what actually happened.
378 * @note Unlike PostEditUndo (which is called for any object in the transaction), this is only called on objects that are actually changed by the transaction.
379 */
380 virtual void PostTransacted(const FTransactionObjectEvent& TransactionEvent);
381
382 /** Find or create and populate an annotation object with any external data required for applying a transaction */
383 TSharedPtr<ITransactionObjectAnnotation> FindOrCreateTransactionAnnotation() const;
384
385 /** Create and restore a previously serialized annotation object with any external data required for applying a transaction */
386 TSharedPtr<ITransactionObjectAnnotation> CreateAndRestoreTransactionAnnotation(FArchive& Ar) const;
387
388 protected:
389 /** Factory a new annotation object and optionally populate it with data */
390 enum class ETransactionAnnotationCreationMode : uint8 { DefaultInstance, FindOrCreate };
391 virtual TSharedPtr<ITransactionObjectAnnotation> FactoryTransactionAnnotation(const ETransactionAnnotationCreationMode InCreationMode) const { return nullptr; }
392
393 private:
394 /**
395 * Test the selection state of a UObject
396 *
397 * @return true if the object is selected, false otherwise.
398 * @todo UE4 this doesn't belong here, but it doesn't belong anywhere else any better
399 */
400 virtual bool IsSelectedInEditor() const;
401
402 public:
403 #endif // WITH_EDITOR
404
405 /** Called at the end of Rename(), but only if the rename was actually carried out */
406 virtual void PostRename(UObject* OldOuter, const FName OldName) {}
407
408 /**
409 * Called before duplication.
410 *
411 * @param DupParams the full parameters the object will be duplicated with.
412 * Allows access to modify params such as the duplication seed for example for pre-filling the dup-source => dup-target map used by StaticDuplicateObject.
413 * @see FObjectDuplicationParameters
414 */
415 virtual void PreDuplicate(FObjectDuplicationParameters& DupParams) {}
416
417 /**
418 * Called after duplication & serialization and before PostLoad. Used to e.g. make sure UStaticMesh's UModel gets copied as well.
419 * Note: NOT called on components on actor duplication (alt-drag or copy-paste). Use PostEditImport as well to cover that case.
420 */
421 virtual void PostDuplicate(bool bDuplicateForPIE) {}
422 virtual void PostDuplicate(EDuplicateMode::Type DuplicateMode)
423 {
424 PostDuplicate(DuplicateMode == EDuplicateMode::PIE);
425 }
426
427 /**
428 * Called during saving to determine the load flags to save with the object.
429 * If false, this object will be discarded on clients
430 *
431 * @return true if this object should be loaded on clients
432 */
433 virtual bool NeedsLoadForClient() const;
434
435 /**
436 * Called during saving to determine the load flags to save with the object.
437 * If false, this object will be discarded on servers
438 *
439 * @return true if this object should be loaded on servers
440 */
441 virtual bool NeedsLoadForServer() const;
442
443 /**
444 * Called during saving to determine the load flags to save with the object.
445 * If false, this object will be discarded on the target platform
446 *
447 * @return true if this object should be loaded on the target platform
448 */
449 virtual bool NeedsLoadForTargetPlatform(const class ITargetPlatform* TargetPlatform) const;
450
451 /**
452 * Called during saving to include this object in client/servers running in editor builds, even if they wouldn't normally be.
453 * If false, this object will still get loaded if NeedsLoadForServer/Client are true
454 *
455 * @return true if this object should always be loaded for games running in editor builds
456 */
457 virtual bool NeedsLoadForEditorGame() const
458 {
459 return false;
460 }
461
462 /**
463 * Called during saving to determine if the object is forced to be editor only or not
464 *
465 * @return true if this object should never be loaded outside the editor
466 */
467 virtual bool IsEditorOnly() const
468 {
469 return false;
470 }
471
472 /**
473 * Called during saving to determine if the object's references are used in game even when the object itself
474 * is never loaded outside the editor (because e.g. its references are followed during cooking)
475 *
476 * @return true if this object's references should be marked as used in game even when the object is editoronly
477 */
478 virtual bool HasNonEditorOnlyReferences() const
479 {
480 return false;
481 }
482
483 /**
484 * Called during async load to determine if PostLoad can be called on the loading thread.
485 *
486 * @return true if this object's PostLoad is thread safe
487 */
488 virtual bool IsPostLoadThreadSafe() const
489 {
490 return false;
491 }
492
493 /**
494 * Called during garbage collection to determine if an object can have its destructor called on a worker thread.
495 *
496 * @return true if this object's destructor is thread safe
497 */
498 virtual bool IsDestructionThreadSafe() const;
499
500 /**
501 * Called during cooking. Must return all objects that will be Preload()ed when this is serialized at load time. Only used by the EDL.
502 *
503 * @param OutDeps all objects that will be preloaded when this is serialized at load time
504 */
505 virtual void GetPreloadDependencies(TArray<UObject*>& OutDeps);
506
507 /**
508 * Called during cooking. Returns a list of objects. The packages containing those objects will be prestreamed, when the package containing this is loaded. Only used by the EDL.
509 *
510 * @param OutPrestream all objects that will be prestreamed when this packages is streamed
511 */
512 virtual void GetPrestreamPackages(TArray<UObject*>& OutPrestream)
513 {
514 }
515
516 /**
517 * Update the list of classes that we should exclude from dedicated server builds
518 */
519 static void UpdateClassesExcludedFromDedicatedServer(const TArray<FString>& InClassNames, const TArray<FString>& InModulesNames);
520
521 /**
522 * Update the list of classes that we should exclude from dedicated client builds
523 */
524 static void UpdateClassesExcludedFromDedicatedClient(const TArray<FString>& InClassNames, const TArray<FString>& InModulesNames);
525
526 /**
527 * Determines if you can create an object from the supplied template in the current context (editor, client only, dedicated server, game/listen)
528 * This calls NeedsLoadForClient & NeedsLoadForServer
529 */
530 static bool CanCreateInCurrentContext(UObject* Template);
531
532 /**
533 * Exports the property values for the specified object as text to the output device.
534 * Override this if you need custom support for copy/paste.
535 *
536 * @param Out The output device to send the exported text to
537 * @param Indent Number of spaces to prepend to each line of output
538 *
539 * @see ImportCustomProperties()
540 */
541 virtual void ExportCustomProperties(FOutputDevice& Out, uint32 Indent) {}
542
543 /**
544 * Exports the property values for the specified object as text to the output device. Required for Copy&Paste
545 * Override this if you need custom support for copy/paste.
546 *
547 * @param SourceText The input data (zero terminated), will never be null
548 * @param Warn For error reporting, will never be null
549 *
550 * @see ExportCustomProperties()
551 */
552 virtual void ImportCustomProperties(const TCHAR* SourceText, FFeedbackContext* Warn) {}
553
554 /**
555 * Called after importing property values for this object (paste, duplicate or .t3d import)
556 * Allow the object to perform any cleanup for properties which shouldn't be duplicated or
557 * are unsupported by the script serialization
558 */
559 virtual void PostEditImport() {}
560
561 /**
562 * Called from ReloadConfig after the object has reloaded its configuration data.
563 */
564 virtual void PostReloadConfig( class FProperty* PropertyThatWasLoaded ) {}
565
566 /**
567 * Rename this object to a unique name, or change its outer.
568 * @warning Unless ForceNoResetLoaders is passed in, this will cause a flush of all level streaming.
569 *
570 * @param NewName The new name of the object, if null then NewOuter should be set
571 * @param NewOuter New Outer this object will be placed within, if null it will use the current outer
572 * @param Flags Flags to specify what happens during the rename
573 */
574 virtual bool Rename(const TCHAR* NewName=nullptr, UObject* NewOuter=nullptr, ERenameFlags Flags=REN_None);
575
576 /** Return a one line description of an object for viewing in the thumbnail view of the generic browser */
577 virtual FString GetDesc() { return TEXT( "" ); }
578
579 /** Return the UStruct corresponding to the sidecar data structure that stores data that is constant for all instances of this class. */
580 virtual UScriptStruct* GetSparseClassDataStruct() const;
581
582 #if WITH_EDITOR
583 virtual void MoveDataToSparseClassDataStruct() const {}
584 #endif
585
586 #if WITH_ENGINE
587 /**
588 * Returns what UWorld this object is contained within.
589 * By default this will follow its Outer chain, but it should be overridden if that will not work.
590 */
591 virtual class UWorld* GetWorld() const;
592
593 /** Internal function used by UEngine::GetWorldFromContextObject() */
594 class UWorld* GetWorldChecked(bool& bSupported) const;
595
596 /** Checks to see if GetWorld() is implemented on a specific class */
597 bool ImplementsGetWorld() const;
598 #endif
599
600 /**
601 * Callback for retrieving a textual representation of natively serialized properties. Child classes should implement this method if they wish
602 * to have natively serialized property values included in things like diffcommandlet output.
603 *
604 * @param out_PropertyValues receives the property names and values which should be reported for this object. The map's key should be the name of
605 * the property and the map's value should be the textual representation of the property's value. The property value should
606 * be formatted the same way that FProperty::ExportText formats property values (i.e. for arrays, wrap in quotes and use a comma
607 * as the delimiter between elements, etc.)
608 * @param ExportFlags bitmask of EPropertyPortFlags used for modifying the format of the property values
609 *
610 * @return true if property values were added to the map.
611 */
612 virtual bool GetNativePropertyValues( TMap<FString,FString>& out_PropertyValues, uint32 ExportFlags=0 ) const
613 {
614 return false;
615 }
616
617 /**
618 * Get the size of the object/resource for use in memory tools or to display to artists/LDs in the Editor
619 * This is the extended version which separates up the used memory into different memory regions (the actual definition of which may be platform specific).
620 *
621 * @param CumulativeResourceSize Struct used to count up the cumulative size of the resource as to be displayed to artists/LDs in the Editor.
622 */
623 virtual void GetResourceSizeEx(FResourceSizeEx& CumulativeResourceSize);
624
625 /**
626 * Get the size of the object/resource for use in memory tools or to display to artists/LDs in the Editor
627 * This is the simple version which just returns the total number of bytes used by this object.
628 *
629 * @param Mode Indicates which resource size should be returned.
630 * @return The cumulative size of this object in memory
631 */
632 SIZE_T GetResourceSizeBytes(EResourceSizeMode::Type Mode)
633 {
634 FResourceSizeEx ResSize = FResourceSizeEx(Mode);
635 GetResourceSizeEx(ResSize);
636 return ResSize.GetTotalMemoryBytes();
637 }
638
639 /**
640 * Returns the name of the exporter factory used to export this object
641 * Used when multiple factories have the same extension
642 */
643 virtual FName GetExporterName( void )
644 {
645 return( FName( TEXT( "" ) ) );
646 }
647
648 /**
649 * Callback used to allow object register its direct object references that are not already covered by
650 * the token stream.
651 *
652 * @param InThis Object to collect references from.
653 * @param Collector FReferenceCollector objects to be used to collect references.
654 */
655 static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector);
656
657 /**
658 * Helper function to call AddReferencedObjects for this object's class.
659 *
660 * @param Collector FReferenceCollector objects to be used to collect references.
661 */
662 void CallAddReferencedObjects(FReferenceCollector& Collector);
663
664 /**
665 * Save information for StaticAllocateObject in the case of overwriting an existing object.
666 * StaticAllocateObject will call delete on the result after calling Restore()
667 *
668 * @return An FRestoreForUObjectOverwrite that can restore the object or NULL if this is not necessary.
669 */
670 virtual FRestoreForUObjectOverwrite* GetRestoreForUObjectOverwrite()
671 {
672 return NULL;
673 }
674
675 /**
676 * Returns whether native properties are identical to the one of the passed in component.
677 *
678 * @param Other Other component to compare against
679 *
680 * @return true if native properties are identical, false otherwise
681 */
682 virtual bool AreNativePropertiesIdenticalTo( UObject* Other ) const
683 {
684 return true;
685 }
686
687 /** Struct used by GetAssetRegistryTags() to return tag info */
688 struct FAssetRegistryTag
689 {
690 /** Enum specifying the type of this tag */
691 enum ETagType
692 {
693 /** This tag should not be shown in the UI */
694 TT_Hidden,
695 /** This tag should be shown, and sorted alphabetically in the UI */
696 TT_Alphabetical,
697 /** This tag should be shown, and is a number */
698 TT_Numerical,
699 /** This tag should be shown, and is an "x" delimited list of dimensions */
700 TT_Dimensional,
701 /** This tag should be shown, and is a timestamp formatted via FDateTime::ToString */
702 TT_Chronological,
703 };
704
705 /** Flags controlling how this tag should be shown in the UI */
706 enum ETagDisplay
707 {
708 /** No special display */
709 TD_None = 0,
710 /** For TT_Chronological, include the date */
711 TD_Date = 1<<0,
712 /** For TT_Chronological, include the time */
713 TD_Time = 1<<1,
714 /** For TT_Chronological, specifies that the timestamp should be displayed using the invariant timezone (typically for timestamps that are already in local time) */
715 TD_InvariantTz = 1<<2,
716 /** For TT_Numerical, specifies that the number is a value in bytes that should be displayed using FText::AsMemory */
717 TD_Memory = 1<<3,
718 };
719
720 /** Logical name of this tag */
721 FName Name;
722
723 /** Value string for this tag, may represent any data type */
724 FString Value;
725
726 /** Broad description of kind of data represented in Value */
727 ETagType Type;
728
729 /** Flags describing more detail for displaying in the UI */
730 uint32 DisplayFlags;
731
732 FAssetRegistryTag(FName InName, const FString& InValue, ETagType InType, uint32 InDisplayFlags = TD_None)
733 : Name(InName), Value(InValue), Type(InType), DisplayFlags(InDisplayFlags) {}
734
735 #if WITH_EDITOR
736 /** Callback */
737 DECLARE_MULTICAST_DELEGATE_TwoParams(FOnGetObjectAssetRegistryTags, const UObject* /*Object*/, TArray<FAssetRegistryTag>& /*InOutTags*/);
738 COREUOBJECT_API static FOnGetObjectAssetRegistryTags OnGetExtraObjectTags;
739 #endif // WITH_EDITOR
740 };
741
742 /**
743 * Gathers a list of asset registry searchable tags which are name/value pairs with some type information
744 * This only needs to be implemented for asset objects
745 *
746 * @param OutTags A list of key-value pairs associated with this object and their types
747 */
748 virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const;
749
750 /** Gathers a list of asset registry tags for an FAssetData */
751 void GetAssetRegistryTags(FAssetData& Out) const;
752
753 /** Get the common tag name used for all asset source file import paths */
754 static const FName& SourceFileTagName();
755
756 #if WITH_EDITOR
757 /**
758 * Additional data pertaining to asset registry tags used by the editor
759 */
760 struct FAssetRegistryTagMetadata
761 {
762 FText DisplayName;
763 FText TooltipText;
764 FText Suffix;
765 FString ImportantValue;
766
767 /** Set override display name */
768 FAssetRegistryTagMetadata& SetDisplayName(const FText& InDisplayName)
769 {
770 DisplayName = InDisplayName;
771 return *this;
772 }
773
774 /** Set tooltip text pertaining to the asset registry tag in the column view header */
775 FAssetRegistryTagMetadata& SetTooltip(const FText& InTooltipText)
776 {
777 TooltipText = InTooltipText;
778 return *this;
779 }
780
781 /** Set suffix appended to the tag value */
782 FAssetRegistryTagMetadata& SetSuffix(const FText& InSuffix)
783 {
784 Suffix = InSuffix;
785 return *this;
786 }
787
788 /** Set value deemed to be 'important' for this registry tag */
789 FAssetRegistryTagMetadata& SetImportantValue(const FString& InImportantValue)
790 {
791 ImportantValue = InImportantValue;
792 return *this;
793 }
794 };
795
796 /** Gathers a collection of asset registry tag metadata */
797 virtual void GetAssetRegistryTagMetadata(TMap<FName, FAssetRegistryTagMetadata>& OutMetadata) const;
798
799 /** The metadata tags to be transferred from the UMetaData to the Asset Registry */
800 static TSet<FName>& GetMetaDataTagsForAssetRegistry();
801
802 #endif
803
804 /** Returns true if this object is considered an asset. */
805 virtual bool IsAsset() const;
806
807 /**
808 * Returns an Type:Name pair representing the PrimaryAssetId for this object.
809 * Assets that need to be globally referenced at runtime should return a valid Identifier.
810 * If this is valid, the object can be referenced by identifier using the AssetManager
811 */
812 virtual FPrimaryAssetId GetPrimaryAssetId() const;
813
814 /** Returns true if this object is considered a localized resource. */
815 virtual bool IsLocalizedResource() const;
816
817 /** Returns true if this object is safe to add to the root set. */
818 virtual bool IsSafeForRootSet() const;
819
820 /**
821 * Tags objects that are part of the same asset with the specified object flag, used for GC checking
822 *
823 * @param ObjectFlags Object Flags to enable on the related objects
824 */
825 virtual void TagSubobjects(EObjectFlags NewFlags);
826
827 /** Returns properties that are replicated for the lifetime of the actor channel */
828 virtual void GetLifetimeReplicatedProps( TArray< class FLifetimeProperty > & OutLifetimeProps ) const;
829
830 /** IsNameStableForNetworking means an object can be referred to its path name (relative to outer) over the network */
831 virtual bool IsNameStableForNetworking() const;
832
833 /** IsFullNameStableForNetworking means an object can be referred to its full path name over the network */
834 virtual bool IsFullNameStableForNetworking() const;
835
836 /** IsSupportedForNetworking means an object can be referenced over the network */
837 virtual bool IsSupportedForNetworking() const;
838
839 /** Returns a list of sub-objects that have stable names for networking */
840 virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*> &ObjList) {}
841
842 /** Called right before receiving a bunch */
843 virtual void PreNetReceive();
844
845 /** Called right after receiving a bunch */
846 virtual void PostNetReceive();
847
848 /** Called right after calling all OnRep notifies (called even when there are no notifies) */
849 virtual void PostRepNotifies() {}
850
851 /** Called right before being marked for destruction due to network replication */
852 virtual void PreDestroyFromReplication();
853
854 #if WITH_EDITOR
855 /**
856 * @return Returns Valid if this object has data validation rules set up for it and the data for this object is valid. Returns Invalid if it does not pass the rules. Returns NotValidated if no rules are set for this object.
857 */
858 virtual EDataValidationResult IsDataValid(TArray<FText>& ValidationErrors);
859 #endif // WITH_EDITOR
860
861 /*----------------------------------------------------------
862 Non virtual functions, not intended to be overridden
863 ----------------------------------------------------------*/
864
865 /**
866 * Test the selection state of a UObject
867 *
868 * @return true if the object is selected, false otherwise.
869 * @todo UE4 this doesn't belong here, but it doesn't belong anywhere else any better
870 */
871 bool IsSelected() const;
872
873 #if WITH_EDITOR
874 /**
875 * Calls PreEditChange on all instances based on an archetype in AffectedObjects. Recurses on any instances.
876 *
877 * @param AffectedObjects the array of objects which have this object in their ObjectArchetype chain and will be affected by the change.
878 * Objects which have this object as their direct ObjectArchetype are removed from the list once they're processed.
879 */
880 void PropagatePreEditChange( TArray<UObject*>& AffectedObjects, FEditPropertyChain& PropertyAboutToChange );
881
882 /**
883 * Calls PostEditChange on all instances based on an archetype in AffectedObjects. Recurses on any instances.
884 *
885 * @param AffectedObjects the array of objects which have this object in their ObjectArchetype chain and will be affected by the change.
886 * Objects which have this object as their direct ObjectArchetype are removed from the list once they're processed.
887 */
888 void PropagatePostEditChange( TArray<UObject*>& AffectedObjects, FPropertyChangedChainEvent& PropertyChangedEvent );
889 #endif // WITH_EDITOR
890
891 /**
892 * Serializes the script property data located at Data. When saving, only saves those properties which differ from the corresponding
893 * value in the specified 'DiffObject' (usually the object's archetype).
894 *
895 * @param Ar the archive to use for serialization
896 */
897 void SerializeScriptProperties( FArchive& Ar ) const;
898
899 /**
900 * Serializes the script property data located at Data. When saving, only saves those properties which differ from the corresponding
901 * value in the specified 'DiffObject' (usually the object's archetype).
902 *
903 * @param Slot the archive slot to serialize to
904 */
905 void SerializeScriptProperties( FStructuredArchive::FSlot Slot ) const;
906
907 /**
908 * Wrapper function for InitProperties() which handles safely tearing down this object before re-initializing it
909 * from the specified source object.
910 *
911 * @param SourceObject the object to use for initializing property values in this object. If not specified, uses this object's archetype.
912 * @param InstanceGraph contains the mappings of instanced objects and components to their templates
913 */
914 void ReinitializeProperties( UObject* SourceObject=NULL, struct FObjectInstancingGraph* InstanceGraph=NULL );
915
916 /**
917 * This will return detail info about this specific object. (e.g. AudioComponent will return the name of the cue,
918 * ParticleSystemComponent will return the name of the ParticleSystem) The idea here is that in many places
919 * you have a component of interest but what you really want is some characteristic that you can use to track
920 * down where it came from.
921 *
922 * @note safe to call on NULL object pointers!
923 */
924 FString GetDetailedInfo() const;
925
926 /**
927 * Called before destroying the object. This is called immediately upon deciding to destroy the object, to allow the object to begin an
928 * asynchronous cleanup process.
929 */
930 bool ConditionalBeginDestroy();
931
932 /** Called when an object is actually destroyed, memory should never be accessed again */
933 bool ConditionalFinishDestroy();
934
935 /** PostLoad if needed. */
936 void ConditionalPostLoad();
937
938 /**
939 * Instances subobjects and components for objects being loaded from disk, if necessary. Ensures that references
940 * between nested components are fixed up correctly.
941 *
942 * @param OuterInstanceGraph when calling this method on subobjects, specifies the instancing graph which contains all instanced
943 * subobjects and components for a subobject root.
944 */
945 void ConditionalPostLoadSubobjects( struct FObjectInstancingGraph* OuterInstanceGraph=NULL );
946
947 #if WITH_EDITOR
948 /**
949 * Starts caching of platform specific data for the target platform
950 * Called when cooking before serialization so that object can prepare platform specific data
951 * Not called during normal loading of objects
952 *
953 * @param TargetPlatform target platform to cache platform specific data for
954 */
955 virtual void BeginCacheForCookedPlatformData( const ITargetPlatform* TargetPlatform ) { }
956
957 /**
958 * Have we finished loading all the cooked platform data for the target platforms requested in BeginCacheForCookedPlatformData
959 *
960 * @param TargetPlatform target platform to check for cooked platform data
961 */
962 virtual bool IsCachedCookedPlatformDataLoaded( const ITargetPlatform* TargetPlatform ) { return true; }
963
964 /**
965 * All caching has finished for this object (all IsCachedCookedPlatformDataLoaded functions have finished for all platforms)
966 */
967 virtual void WillNeverCacheCookedPlatformDataAgain() { }
968
969 /**
970 * Clears cached cooked platform data for specific platform
971 *
972 * @param TargetPlatform target platform to cache platform specific data for
973 */
974 virtual void ClearCachedCookedPlatformData( const ITargetPlatform* TargetPlatform ) { }
975
976 /**
977 * Clear all cached cooked platform data
978 *
979 * @param TargetPlatform target platform to cache platform specific data for
980 */
981 virtual void ClearAllCachedCookedPlatformData() { }
982
983 /**
984 * Called during cook to allow objects to generate additional cooked files alongside their cooked package.
985 * @note These should typically match the name of the package, but with a different extension.
986 *
987 * @param PackageFilename full path to the package that this object is being saved to on disk
988 * @param TargetPlatform target platform to cook additional files for
989 */
990 UE_DEPRECATED(4.23, "Use the new CookAdditionalFilesOverride that provides a function to write the files")
991 virtual void CookAdditionalFiles(const TCHAR* PackageFilename, const ITargetPlatform* TargetPlatform) { }
992
993 /**
994 * Called during cook to allow objects to generate additional cooked files alongside their cooked package.
995 * @note Implement CookAdditionalFilesOverride to define sub class behavior.
996 *
997 * @param PackageFilename full path to the package that this object is being saved to on disk
998 * @param TargetPlatform target platform to cook additional files for
999 * @param WriteAdditionalFile function for writing the additional files
1000 */
1001 void CookAdditionalFiles(const TCHAR* PackageFilename, const ITargetPlatform* TargetPlatform,
1002 TFunctionRef<void(const TCHAR* Filename, void* Data, int64 Size)> WriteAdditionalFile)
1003 {
1004 CookAdditionalFilesOverride(PackageFilename, TargetPlatform, WriteAdditionalFile);
1005 }
1006
1007 private:
1008 /**
1009 * Called during cook to allow objects to generate additional cooked files alongside their cooked package.
1010 * Files written using the provided function will be handled as part of the saved cooked package
1011 * and contribute to package total file size, and package hash when enabled.
1012 * @note These should typically match the name of the package, but with a different extension.
1013 *
1014 * @param PackageFilename full path to the package that this object is being saved to on disk
1015 * @param TargetPlatform target platform to cook additional files for
1016 * @param WriteAdditionalFile function for writing the additional files
1017 */
1018 virtual void CookAdditionalFilesOverride(const TCHAR* PackageFilename, const ITargetPlatform* TargetPlatform,
1019 TFunctionRef<void(const TCHAR* Filename, void* Data, int64 Size)> WriteAdditionalFile)
1020 {
1021 PRAGMA_DISABLE_DEPRECATION_WARNINGS;
1022 CookAdditionalFiles(PackageFilename, TargetPlatform);
1023 PRAGMA_ENABLE_DEPRECATION_WARNINGS;
1024 }
1025
1026 public:
1027 #endif
1028 /**
1029 * Determine if this object has SomeObject in its archetype chain.
1030 */
1031 inline bool IsBasedOnArchetype( const UObject* const SomeObject ) const;
1032
1033 /** Returns a UFunction with the specified name, wrapper for UClass::FindFunctionByName() */
1034 UFunction* FindFunction( FName InName ) const;
1035
1036 /** Version of FindFunction() that will assert if the function was not found */
1037 UFunction* FindFunctionChecked( FName InName ) const;
1038
1039 /**
1040 * Given OtherObject (which will be the same type as 'this'), recursively find any matching sub-objects from 'this' that also exist within OtherObject, and add the mappings to ObjectMapping.
1041 *
1042 * @param OtherObject The to find matching sub-objects within.
1043 * @param ObjectMapping The complete mapping between this object hierarchy and the other object hierarchy.
1044 */
1045 virtual void BuildSubobjectMapping(UObject* OtherObject, TMap<UObject*, UObject*>& ObjectMapping) const;
1046
1047 /**
1048 * Uses the TArchiveObjectReferenceCollector to build a list of all components referenced by this object which have this object as the outer
1049 *
1050 * @param OutDefaultSubobjects the array that should be populated with the default subobjects "owned" by this object
1051 * @param bIncludeNestedSubobjects controls whether subobjects which are contained by this object, but do not have this object
1052 * as its direct Outer should be included
1053 */
1054 void CollectDefaultSubobjects( TArray<UObject*>& OutDefaultSubobjects, bool bIncludeNestedSubobjects=false ) const;
1055
1056 /**
1057 * Checks default sub-object assumptions.
1058 *
1059 * @param bForceCheck Force checks even if not enabled globally.
1060 * @return true if the assumptions are met, false otherwise.
1061 */
1062 bool CheckDefaultSubobjects(bool bForceCheck = false) const;
1063
1064 /**
1065 * Save configuration out to ini files
1066 * @warning Must be safe to call on class-default object
1067 */
1068 void SaveConfig( uint64 Flags=CPF_Config, const TCHAR* Filename=NULL, FConfigCacheIni* Config=GConfig, bool bAllowCopyToDefaultObject=true );
1069
1070 /**
1071 * Saves just the section(s) for this class into the default ini file for the class (with just the changes from base)
1072 */
1073 void UpdateDefaultConfigFile(const FString& SpecificFileLocation = "");
1074
1075 /**
1076 * Saves just the section(s) for this class into the global user ini file for the class (with just the changes from base)
1077 */
1078 void UpdateGlobalUserConfigFile();
1079
1080 /**
1081 * Saves just the section(s) for this class into the project user ini file for the class (with just the changes from base)
1082 */
1083 void UpdateProjectUserConfigFile();
1084
1085 /**
1086 * Saves just the property into the global user ini file for the class (with just the changes from base)
1087 */
1088 void UpdateSinglePropertyInConfigFile(const FProperty* InProperty, const FString& InConfigIniName);
1089
1090 private:
1091 /**
1092 * Saves just the section(s) for this class into the given ini file for the class (with just the changes from base)
1093 */
1094 void UpdateSingleSectionOfConfigFile(const FString& ConfigIniName);
1095
1096 /**
1097 * Ensures that current thread is NOT during vtable ptr retrieval process
1098 * of some UClass.
1099 */
1100 void EnsureNotRetrievingVTablePtr() const;
1101
1102 public:
1103 /**
1104 * Get the default config filename for the specified UObject
1105 */
1106 FString GetDefaultConfigFilename() const;
1107
1108 /**
1109 * Get the global user override config filename for the specified UObject
1110 */
1111 FString GetGlobalUserConfigFilename() const;
1112
1113 /**
1114 * Get the project user override config filename for the specified UObject
1115 */
1116 FString GetProjectUserConfigFilename() const;
1117
1118 /** Returns the override config hierarchy platform (if NDAd platforms need defaults to not be in Base*.ini but still want editor to load them) */
1119 virtual const TCHAR* GetConfigOverridePlatform() const { return nullptr; }
1120
1121 /**
1122 * Allows PerObjectConfig classes, to override the ini section name used for the PerObjectConfig object.
1123 *
1124 * @param SectionName Reference to the unmodified config section name, that can be altered/modified
1125 */
1126 virtual void OverridePerObjectConfigSection(FString& SectionName) {}
1127
1128 /**
1129 * Imports property values from an .ini file.
1130 *
1131 * @param Class the class to use for determining which section of the ini to retrieve text values from
1132 * @param Filename indicates the filename to load values from; if not specified, uses ConfigClass's ClassConfigName
1133 * @param PropagationFlags indicates how this call to LoadConfig should be propagated; expects a bitmask of UE4::ELoadConfigPropagationFlags values.
1134 * @param PropertyToLoad if specified, only the ini value for the specified property will be imported.
1135 */
1136 void LoadConfig( UClass* ConfigClass=NULL, const TCHAR* Filename=NULL, uint32 PropagationFlags=UE4::LCPF_None, class FProperty* PropertyToLoad=NULL );
1137
1138 /**
1139 * Wrapper method for LoadConfig that is used when reloading the config data for objects at runtime which have already loaded their config data at least once.
1140 * Allows the objects the receive a callback that its configuration data has been reloaded.
1141 *
1142 * @param Class the class to use for determining which section of the ini to retrieve text values from
1143 * @param Filename indicates the filename to load values from; if not specified, uses ConfigClass's ClassConfigName
1144 * @param PropagationFlags indicates how this call to LoadConfig should be propagated; expects a bitmask of UE4::ELoadConfigPropagationFlags values.
1145 * @param PropertyToLoad if specified, only the ini value for the specified property will be imported
1146 */
1147 void ReloadConfig( UClass* ConfigClass=NULL, const TCHAR* Filename=NULL, uint32 PropagationFlags=UE4::LCPF_None, class FProperty* PropertyToLoad=NULL );
1148
1149 /** Import an object from a file. */
1150 void ParseParms( const TCHAR* Parms );
1151
1152 /**
1153 * Outputs a string to an arbitrary output device, describing the list of objects which are holding references to this one.
1154 *
1155 * @param Ar the output device to send output to
1156 * @param Referencers optionally allows the caller to specify the list of references to output.
1157 */
1158 void OutputReferencers( FOutputDevice& Ar, FReferencerInformationList* Referencers=NULL );
1159
1160 /** Called by OutputReferencers() to get the internal list of referencers to write */
1161 void RetrieveReferencers( TArray<FReferencerInformation>* OutInternalReferencers, TArray<FReferencerInformation>* OutExternalReferencers);
1162
1163 /**
1164 * Changes the linker and linker index to the passed in one. A linker of NULL and linker index of INDEX_NONE
1165 * indicates that the object is without a linker.
1166 *
1167 * @param LinkerLoad New LinkerLoad object to set
1168 * @param LinkerIndex New LinkerIndex to set
1169 * @param bShouldDetachExisting If true, detach existing linker and call PostLinkerChange
1170 */
1171 void SetLinker( FLinkerLoad* LinkerLoad, int32 LinkerIndex, bool bShouldDetachExisting=true );
1172
1173 /**
1174 * Return the template that an object with this class, outer and name would be
1175 *
1176 * @return the archetype for this object
1177 */
1178 static UObject* GetArchetypeFromRequiredInfo(const UClass* Class, const UObject* Outer, FName Name, EObjectFlags ObjectFlags);
1179
1180 /**
1181 * Return the template this object is based on.
1182 *
1183 * @return the archetype for this object
1184 */
1185 UObject* GetArchetype() const;
1186
1187 /**
1188 * Builds a list of objects which have this object in their archetype chain.
1189 *
1190 * @param Instances receives the list of objects which have this one in their archetype chain
1191 */
1192 void GetArchetypeInstances( TArray<UObject*>& Instances );
1193
1194 /**
1195 * Wrapper for calling UClass::InstanceSubobjectTemplates() for this object.
1196 */
1197 void InstanceSubobjectTemplates( struct FObjectInstancingGraph* InstanceGraph = NULL );
1198
1199 /**
1200 * Returns true if this object implements the interface T, false otherwise.
1201 */
1202 template<class T>
1203 bool Implements() const;
1204
1205
1206 /*-----------------------------
1207 Virtual Machine
1208 -----------------------------*/
1209
1210 /** Called by VM to execute a UFunction with a filled in UStruct of parameters */
1211 virtual void ProcessEvent( UFunction* Function, void* Parms );
1212
1213 /**
1214 * Return the space this function should be called. Checks to see if this function should
1215 * be called locally, remotely, or simply absorbed under the given conditions
1216 *
1217 * @param Function function to call
1218 * @param Stack stack frame for the function call
1219 * @return bitmask representing all callspaces that apply to this UFunction in the given context
1220 */
1221 virtual int32 GetFunctionCallspace( UFunction* Function, FFrame* Stack )
1222 {
1223 return FunctionCallspace::Local;
1224 }
1225
1226 /**
1227 * Call the actor's function remotely
1228 *
1229 * @param Function function to call
1230 * @param Parameters arguments to the function call
1231 * @param Stack stack frame for the function call
1232 */
1233 virtual bool CallRemoteFunction( UFunction* Function, void* Parms, struct FOutParmRec* OutParms, FFrame* Stack )
1234 {
1235 return false;
1236 }
1237
1238 /** Handle calling a function by name when executed from the console or a command line */
1239 bool CallFunctionByNameWithArguments( const TCHAR* Cmd, FOutputDevice& Ar, UObject* Executor, bool bForceCallWithNonExec = false );
1240
1241 /** Internal VM method for executing a function */
1242 void CallFunction( FFrame& Stack, RESULT_DECL, UFunction* Function );
1243
1244 /**
1245 * Internal function call processing.
1246 * @warning: might not write anything to Result if proper type isn't returned.
1247 */
1248 DECLARE_FUNCTION(ProcessInternal);
1249
1250 /**
1251 * This function handles a console exec sent to the object; it is virtual so 'nexus' objects like
1252 * a player controller can reroute the command to several different objects.
1253 */
1254 virtual bool ProcessConsoleExec(const TCHAR* Cmd, FOutputDevice& Ar, UObject* Executor)
1255 {
1256 return CallFunctionByNameWithArguments(Cmd, Ar, Executor);
1257 }
1258
1259 /** advances Stack's code past the parameters to the given Function and if the function has a return value, copies the zero value for that property to the memory for the return value
1260 * @param Stack the script stack frame
1261 * @param Result pointer to where the return value should be written
1262 * @param Function the function being called
1263 */
1264 void SkipFunction(FFrame& Stack, RESULT_DECL, UFunction* Function);
1265
1266 /**
1267 * Called on the target when a class is loaded with ClassGeneratedBy is loaded. Should regenerate the class if needed, and return the updated class
1268 * @return Updated instance of the class, if needed, or NULL if no regeneration was necessary
1269 */
1270 virtual UClass* RegenerateClass(UClass* ClassToRegenerate, UObject* PreviousCDO) { return NULL; };
1271
1272 /**
1273 * Returns whether this object is contained in or part of a blueprint object
1274 */
1275 bool IsInBlueprint() const;
1276
1277 /**
1278 * Destroy properties that won't be destroyed by the native destructor
1279 */
1280 void DestroyNonNativeProperties();
1281
1282 /** Called during subobject creation to mark this component as editor only, which causes it to get stripped in packaged builds */
1283 virtual void MarkAsEditorOnlySubobject() { }
1284
1285 /**
1286 * Abort with a member function call at the top of the callstack, helping to ensure that most platforms will stuff this object's memory into the resulting minidump.
1287 */
1288 void AbortInsideMemberFunction() const;
1289
1290 // UnrealScript intrinsics, do not call directly
1291
1292 // Undefined native handler
1293 DECLARE_FUNCTION(execUndefined);
1294
1295 // Variables
1296 DECLARE_FUNCTION(execLocalVariable);
1297 DECLARE_FUNCTION(execInstanceVariable);
1298 DECLARE_FUNCTION(execDefaultVariable);
1299 DECLARE_FUNCTION(execLocalOutVariable);
1300 DECLARE_FUNCTION(execInterfaceVariable);
1301 DECLARE_FUNCTION(execClassSparseDataVariable);
1302 DECLARE_FUNCTION(execInterfaceContext);
1303 DECLARE_FUNCTION(execArrayElement);
1304 DECLARE_FUNCTION(execBoolVariable);
1305 DECLARE_FUNCTION(execClassDefaultVariable);
1306 DECLARE_FUNCTION(execEndFunctionParms);
1307
1308 // Do Nothing
1309 DECLARE_FUNCTION(execNothing);
1310 DECLARE_FUNCTION(execNothingOp4a);
1311
1312 /** Breakpoint; only observed in the editor; executing it at any other time is a NOP */
1313 DECLARE_FUNCTION(execBreakpoint);
1314
1315 /** Tracepoint; only observed in the editor; executing it at any other time is a NOP */
1316 DECLARE_FUNCTION(execTracepoint);
1317 DECLARE_FUNCTION(execWireTracepoint);
1318
1319 /** Instrumentation event for profiling; only observed in the builds with blueprint instrumentation */
1320 DECLARE_FUNCTION(execInstrumentation);
1321
1322 DECLARE_FUNCTION(execEndOfScript);
1323
1324 /** failsafe for functions that return a value - returns the zero value for a property and logs that control reached the end of a non-void function */
1325 DECLARE_FUNCTION(execReturnNothing);
1326 DECLARE_FUNCTION(execEmptyParmValue);
1327
1328 // Commands
1329 DECLARE_FUNCTION(execJump);
1330 DECLARE_FUNCTION(execJumpIfNot);
1331 DECLARE_FUNCTION(execAssert);
1332
1333 /**
1334 * Push a code offset onto the execution flow stack for future execution.
1335 * Current execution continues to the next instruction after the push one.
1336 */
1337 DECLARE_FUNCTION(execPushExecutionFlow);
1338
1339 /**
1340 * Pops a code offset from the execution flow stack and starts execution there.
1341 * If there are no stack entries left, it is treated as an execution error.
1342 */
1343 DECLARE_FUNCTION(execPopExecutionFlow);
1344 DECLARE_FUNCTION(execComputedJump);
1345
1346 /**
1347 * Pops a code offset from the execution flow stack and starts execution there, if a condition is not true.
1348 * If there are no stack entries left, it is treated as an execution error.
1349 */
1350 DECLARE_FUNCTION(execPopExecutionFlowIfNot);
1351
1352
1353 // Assignment
1354 DECLARE_FUNCTION(execLet);
1355 DECLARE_FUNCTION(execLetObj);
1356 DECLARE_FUNCTION(execLetWeakObjPtr);
1357 DECLARE_FUNCTION(execLetBool);
1358 DECLARE_FUNCTION(execLetDelegate);
1359 DECLARE_FUNCTION(execLetMulticastDelegate);
1360
1361 // Delegates
1362 DECLARE_FUNCTION(execAddMulticastDelegate);
1363 DECLARE_FUNCTION(execClearMulticastDelegate);
1364 DECLARE_FUNCTION(execEatReturnValue);
1365 DECLARE_FUNCTION(execRemoveMulticastDelegate);
1366
1367 // Context expressions
1368 DECLARE_FUNCTION(execSelf);
1369 DECLARE_FUNCTION(execContext);
1370 DECLARE_FUNCTION(execContext_FailSilent);
1371 DECLARE_FUNCTION(execStructMemberContext);
1372
1373 // Function calls
1374 DECLARE_FUNCTION(execVirtualFunction);
1375 DECLARE_FUNCTION(execFinalFunction);
1376 DECLARE_FUNCTION(execLocalVirtualFunction);
1377 DECLARE_FUNCTION(execLocalFinalFunction);
1378
1379 // Struct comparison
1380 DECLARE_FUNCTION(execStructCmpEq);
1381 DECLARE_FUNCTION(execStructCmpNe);
1382 DECLARE_FUNCTION(execStructMember);
1383
1384 DECLARE_FUNCTION(execEqualEqual_DelegateDelegate);
1385 DECLARE_FUNCTION(execNotEqual_DelegateDelegate);
1386 DECLARE_FUNCTION(execEqualEqual_DelegateFunction);
1387 DECLARE_FUNCTION(execNotEqual_DelegateFunction);
1388
1389 // Constants
1390 DECLARE_FUNCTION(execIntConst);
1391 DECLARE_FUNCTION(execInt64Const);
1392 DECLARE_FUNCTION(execUInt64Const);
1393 DECLARE_FUNCTION(execSkipOffsetConst);
1394 DECLARE_FUNCTION(execFloatConst);
1395 DECLARE_FUNCTION(execStringConst);
1396 DECLARE_FUNCTION(execUnicodeStringConst);
1397 DECLARE_FUNCTION(execTextConst);
1398 DECLARE_FUNCTION(execPropertyConst);
1399 DECLARE_FUNCTION(execObjectConst);
1400 DECLARE_FUNCTION(execSoftObjectConst);
1401 DECLARE_FUNCTION(execFieldPathConst);
1402
1403 DECLARE_FUNCTION(execInstanceDelegate);
1404 DECLARE_FUNCTION(execNameConst);
1405 DECLARE_FUNCTION(execByteConst);
1406 DECLARE_FUNCTION(execIntZero);
1407 DECLARE_FUNCTION(execIntOne);
1408 DECLARE_FUNCTION(execTrue);
1409 DECLARE_FUNCTION(execFalse);
1410 DECLARE_FUNCTION(execNoObject);
1411 DECLARE_FUNCTION(execNullInterface);
1412 DECLARE_FUNCTION(execIntConstByte);
1413 DECLARE_FUNCTION(execRotationConst);
1414 DECLARE_FUNCTION(execVectorConst);
1415 DECLARE_FUNCTION(execTransformConst);
1416 DECLARE_FUNCTION(execStructConst);
1417 DECLARE_FUNCTION(execSetArray);
1418 DECLARE_FUNCTION(execSetSet);
1419 DECLARE_FUNCTION(execSetMap);
1420 DECLARE_FUNCTION(execArrayConst);
1421 DECLARE_FUNCTION(execSetConst);
1422 DECLARE_FUNCTION(execMapConst);
1423
1424 // Object construction
1425 DECLARE_FUNCTION(execNew);
1426 DECLARE_FUNCTION(execClassContext);
1427 DECLARE_FUNCTION(execNativeParm);
1428
1429 // Conversions
1430 DECLARE_FUNCTION(execDynamicCast);
1431 DECLARE_FUNCTION(execMetaCast);
1432 DECLARE_FUNCTION(execPrimitiveCast);
1433 DECLARE_FUNCTION(execInterfaceCast);
1434
1435 // Cast functions
1436 DECLARE_FUNCTION(execObjectToBool);
1437 DECLARE_FUNCTION(execInterfaceToBool);
1438 DECLARE_FUNCTION(execObjectToInterface);
1439 DECLARE_FUNCTION(execInterfaceToInterface);
1440 DECLARE_FUNCTION(execInterfaceToObject);
1441
1442 // Dynamic array functions
1443 // Array support
1444 DECLARE_FUNCTION(execGetDynArrayElement);
1445 DECLARE_FUNCTION(execSetDynArrayElement);
1446 DECLARE_FUNCTION(execGetDynArrayLength);
1447 DECLARE_FUNCTION(execSetDynArrayLength);
1448 DECLARE_FUNCTION(execDynArrayInsert);
1449 DECLARE_FUNCTION(execDynArrayRemove);
1450 DECLARE_FUNCTION(execDynArrayFind);
1451 DECLARE_FUNCTION(execDynArrayFindStruct);
1452 DECLARE_FUNCTION(execDynArrayAdd);
1453 DECLARE_FUNCTION(execDynArrayAddItem);
1454 DECLARE_FUNCTION(execDynArrayInsertItem);
1455 DECLARE_FUNCTION(execDynArrayRemoveItem);
1456 DECLARE_FUNCTION(execDynArraySort);
1457
1458 DECLARE_FUNCTION(execBindDelegate);
1459 DECLARE_FUNCTION(execCallMulticastDelegate);
1460
1461 DECLARE_FUNCTION(execLetValueOnPersistentFrame);
1462
1463 DECLARE_FUNCTION(execCallMathFunction);
1464
1465 DECLARE_FUNCTION(execSwitchValue);
1466
1467 DECLARE_FUNCTION(execArrayGetByRef);
1468
1469 /** Wrapper struct to hold the entrypoint in the right memory address */
1470 struct Object_eventExecuteUbergraph_Parms
1471 {
1472 int32 EntryPoint;
1473 };
1474
1475 /** Execute the ubergraph from a specific entry point */
1476 void ExecuteUbergraph(int32 EntryPoint)
1477 {
1478 Object_eventExecuteUbergraph_Parms Parms;
1479 Parms.EntryPoint=EntryPoint;
1480 ProcessEvent(FindFunctionChecked(NAME_ExecuteUbergraph),&Parms);
1481 }
1482
1483 protected:
1484 /** Checks it's ok to perform subobjects check at this time. */
1485 bool CanCheckDefaultSubObjects(bool bForceCheck, bool& bResult) const;
1486
1487 /**
1488 * Checks default sub-object assumptions.
1489 *
1490 * @return true if the assumptions are met, false otherwise.
1491 */
1492 virtual bool CheckDefaultSubobjectsInternal() const;
1493
1494 private:
1495 void ProcessContextOpcode(FFrame& Stack, RESULT_DECL, bool bCanFailSilent);
1496
1497 /**
1498 * Create a component or subobject only to be used with the editor.
1499 * @param Outer outer to construct the subobject in
1500 * @param ReturnType type of the new component
1501 * @param SubobjectName name of the new component
1502 * @param bTransient true if the component is being assigned to a transient property
1503 */
1504 UObject* CreateEditorOnlyDefaultSubobjectImpl(FName SubobjectName, UClass* ReturnType, bool bTransient = false);
1505
1506 public:
1507
1508 enum class ENetFields_Private
1509 {
1510 NETFIELD_REP_START = 0,
1511 NETFIELD_REP_END = -1
1512 };
1513
1514 virtual void ValidateGeneratedRepEnums(const TArray<struct FRepRecord>& ClassReps) const {}
1515
1516 private:
1517
1518 friend struct FObjectNetPushIdHelper;
1519 virtual void SetNetPushIdDynamic(const int32 NewNetPushId)
1520 {
1521 // This method should only be called on Objects that are networked, and those should
1522 // always have this implemented (by UHT).
1523 check(false);
1524 }
1525
1526 public:
1527
1528 /** Should only ever be used by internal systems. */
1529 virtual int32 GetNetPushIdDynamic() const
1530 {
1531 return INDEX_NONE;
1532 }
1533 };
1534
1535 struct FObjectNetPushIdHelper
1536 {
1537 private:
1538 friend struct FNetPrivatePushIdHelper;
1539
1540 static void SetNetPushIdDynamic(UObject* Object, const int32 NewNetPushId)
1541 {
1542 Object->SetNetPushIdDynamic(NewNetPushId);
1543 }
1544 };
1545
1546 /**
1547 * Test validity of object
1548 *
1549 * @param Test The object to test
1550 * @return Return true if the object is usable: non-null and not pending kill
1551 */
1552 FORCEINLINE bool IsValid(const UObject *Test)
1553 {
1554 return Test && !Test->IsPendingKill();
1555 }