In-depth study on the realization principle of Unreal 4 reflection system (I.)

Source: Internet
Author: User

The previous translation of the article mentions the basic principle and application of UE4 reflection system, this time we through the code to delve into the UE4 reflection system, because the reflection system in the UE4 involved in more things, so I intend to divide several articles analysis. I assume that the reader has a certain understanding of UE4 and a certain C + + base, if you do not understand how UE4 is used, then learn how to use the UE4 engine, otherwise it may seem difficult.

Here is a diagram of a class that I've compiled with a reflection system:

As can be seen from the above, Uobject is the core of the entire reflection system, and the type of support reflected in the UE4 has been mentioned in the previous article, including C + + classes, structs, functions, member variables, and enumerations, as well as Tarray support (only some template types, such as Tarray and Tsubclassof, are supported. And their template types cannot be nested types), but TMap is not supported. The support for these things is inseparable from the classes above, such as Uclass, Ublueprintgeneratedclass, Ufunction, Uenum, and Uproperty, as well as the subclasses that inherit from them. Each inherited uobject and supports a reflection system type has a corresponding uclass, or its subclasses (such as the blueprint corresponding to the curriculum Ublueprintgeneratedclass class, it inherits from Uclass), if it is a specific blueprint type, such as the Action Blueprint, Widget blueprints, etc., as shown in. Umetadata is metadata that stores the extra information that some editors need, such as its classification (category), hint (tooltip), and so on, which is not used when it is finally packaged. As for our reflection system needs to access the float, int32 and other variables, are inherited from the Uproperty subclass to represent, specifically, according to the listed objects to go to the code to find the corresponding class to see its specific implementation.

The following is a simple code example that illustrates the implementation of reflection in UE4, first I create a project called Reflectionstudy (only basic code), which is to facilitate the analysis of the Code, as stated in the first article, If you want your implemented class to support reflection, then you must follow the relevant guidelines, such as using Uenum (), Uclass (), Ustruct (), Ufunction (), and Uproperty (), and so on, UHT will generate corresponding code that supports reflection based on these macros. Let's analyze the code separately, and the generated code is stored under your project Reflectionstudy\intermediate\build\win64\ue4editor\inc\reflectionstudy path.

It is generally divided into several types of files:

    1. ReflectionStudy.generated.cpp a project has only one, this file is used to generate reflection information for each class that supports reflection, such as registering properties, adding source data, and so on.
    2. Reflectionstudy.generated.dep.h This file contains the above 1. The header file used by the ReflectionStudy.generated.cpp.
    3. ReflectionStudyClasses.h
    4. *.generated.h This is the code for each of the corresponding macros generated for each reflector-supported header file.

Definition of Class class

Let's take the following code as an example, in order to see the specific implementation of some usages, we have specifically added the following properties and methods.

Fill out your copyright notice in the Description page of Project Settings. #pragma once#include "Gameframework/gamemode . h "#include" Reflectionstudygamemode.generated.h "/*** */uclass () class Reflectionstudy_api Areflectionstudygamemode : Public Agamemode{generated_body () Protected:uproperty (blueprintreadwrite, Category = "Areflectionstudygamemode") Float score; Ufunction (blueprintcallable, Category = "Areflectionstudygamemode") void Callablefunctest (); Ufunction (blueprintnativeevent, Category = "Areflectionstudygamemode") void Navtivefunctest (); Ufunction (blueprintimplementableevent, Category = "Areflectionstudygamemode") void Implementablefunctest ();};

  

UHT-generated. generated.h files

Because the corresponding Reflectionstudygamemode.generated.h header file is longer, we only list the key parts to explain.

#define REFLECTIONSTUDY_SOURCE_REFLECTIONSTUDY_REFLECTIONSTUDYGAMEMODE_H_14_RPC_WRAPPERS_NO_PURE_DECLS Virtual void Navtivefunctest_implementation ();  Declare_function (execnavtivefunctest) {p_finish; P_native_begin; This->navtivefunctest_implementation (); P_native_end; }  declare_function (execcallablefunctest) {p_finish; P_native_begin; This->callablefunctest (); P_native_end; }

  

As you can see, the function we defined above, UHT helped us to automatically generate the above code, as to why it would generate such a function, it is because of the UE4 blueprint calling convention, each function is preceded by an exec prefix, about the implementation of the blueprint because I do not know very clearly now, So there may be an introduction to the blueprint implementation in the back, these functions are called by the UE4 virtual machine, if it contains parameters and return values, then there will be a corresponding from the virtual machine stack to take parameters and set the return value of the code, the reader can self-verify.

Define REFLECTIONSTUDY_SOURCE_REFLECTIONSTUDY_REFLECTIONSTUDYGAMEMODE_H_14_INCLASS_NO_PURE_DECLS private:static void Staticregisternativesareflectionstudygamemode (); Friend Reflectionstudy_api class uclass* Z_construct_uclass_areflectionstudygamemode (); Public:declare_class (Areflectionstudygamemode, Agamemode, compiled_in_flags (0 | class_transient | Class_config), 0, TEXT ("/script/reflectionstudy"), No_api) Declare_serializer (Areflectionstudygamemode)/** Indicates whether the class is compiled into the engine */enum {isintrinsic=compiled_in_intrinsic};

  

    • Staticregisternativesareflectionstudygamemode This function is used to register C + + native functions exposed to virtual machines.
    • Friend Reflectionstudy_api class uclass* Z_construct_uclass_areflectionstudygamemode (); Declares a friend function, which is used to construct the corresponding uclass of this class.
    • DECLARE_CLASS This macro is more complex, mainly defines the Staticclass (), and so on, the specific implementation of the reader to open its definition can be seen.
    • Declare_serializer defines the serialization code.
    • enum {isintrinsic=compiled_in_intrinsic}; As the note says, it is used to mark whether the class is compiled into the engine.

  

#define Reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_enhanced_constructors/** Standard Constructor, called after all reflected properties has been initialized */NO_API areflectionstudygamemode (const FOBJECTI nitializer& Objectinitializer = Fobjectinitializer::get ()): Super (Objectinitializer) {}; Private:/** private copy-constructor, should never be used */NO_API areflectionstudygamemode (const areflectionstudygame mode& InCopy); Public:declare_vtable_ptr_helper_ctor (No_api, Areflectionstudygamemode); Define_vtable_ptr_helper_ctor_caller (Areflectionstudygamemode); Define_default_object_initializer_constructor_call (Areflectionstudygamemode)

  

    • No_api areflectionstudygamemode (const fobjectinitializer& Objectinitializer = Fobjectinitializer::get ()): Super ( Objectinitializer) {}; \ defines a standard constructor that is called after all reflection properties have been initialized.
    • No_api areflectionstudygamemode (const areflectionstudygamemode& InCopy); \ Prevent the copy constructor from being called
    • Declare_vtable_ptr_helper_ctor (No_api, Areflectionstudygamemode); \ Define_vtable_ptr_helper_ctor_caller (Areflectionstudygamemode); \ Hot Load related, this is UE4 inside the relatively good function, we also do not discuss in detail here, this if later on this piece of understanding will also open a separate topic to explain.
    • Define_default_object_initializer_constructor_call defines a default constructor, as shown in the following code:

      static void __defaultconstructor (const fobjectinitializer& X) {new ((einternal*) x.getobj ()) Tclass (X);}

  

#define Reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_generated_body PRAGMA_DISABLE_ Deprecation_warnings Public:     reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_rpc_ Wrappers_no_pure_decls     Reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_callback_ WRAPPERS     reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_inclass_no_pure_decls     Reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h_14_enhanced_constructors private:pragma_enable _deprecation_warnings

  

This code is a reference to the above explained macro, with the following macro finally implemented in class to define a Generated_body () can be included in the above all the definition of the content into the class.

#undef current_file_id#define current_file_id Reflectionstudy_source_reflectionstudy_reflectionstudygamemode_h

All generated_body () related macros are defined as follows

This pair of macros are used to help implement Generated_body () and Generated_ustruct_body () #define Body_macro_combine_i Nner (a,b,c,d) a# #B # #C # #D # define Body_macro_combine (a,b,c,d) Body_macro_combine_inner (a,b,c,d) #define Generated_ Body_legacy (...) Body_macro_combine (current_file_id,_,__line__,_generated_body_legacy) #define GENERATED_BODY (...) Body_macro_combine (current_file_id,_,__line__,_generated_body) #define GENERATED_USTRUCT_BODY (...) Generated_body () #define GENERATED_UCLASS_BODY (...) Generated_body_legacy () #define GENERATED_UINTERFACE_BODY (...) Generated_body_legacy () #define GENERATED_IINTERFACE_BODY (...) Generated_body_legacy ()

  

This reflectionstudygamemode.generated.h file inside the content of the basic analysis is finished, the following we look at the corresponding code ReflectionStudy.generated.cpp, combined with the previous explanation, I believe you on the entire UE4 reflex system there is a Generally understood.

What's relevant in the. generated.cpp file
fname reflectionstudy_implementablefunctest = FName (TEXT (" Implementablefunctest "));    FName reflectionstudy_navtivefunctest = FName (TEXT ("navtivefunctest")); void Areflectionstudygamemode::implementablefunctest () {processevent (findfunctionchecked (REFLECTIONSTUDY_Implem    entablefunctest), NULL); } void Areflectionstudygamemode::navtivefunctest () {processevent (findfunctionchecked (reflectionstudy_navtive    functest), NULL); } void Areflectionstudygamemode::staticregisternativesareflectionstudygamemode () {fnativefunctionregistrar:: Registerfunction (Areflectionstudygamemode::staticclass (), "Callablefunctest", (Native) &        Areflectionstudygamemode::execcallablefunctest); Fnativefunctionregistrar::registerfunction (Areflectionstudygamemode::staticclass (), "NavtiveFuncTest", (Native)    &areflectionstudygamemode::execnavtivefunctest); } implement_class (Areflectionstudygamemode, 3618622309); 

  

    • Just contact UE4 when, if is the function of blueprintimplementabeevent, is not the discovery does not need to realize, then did not feel strange at that time, the above code explained clearly, that is UE4 help us realize, You can see that it calls the Processevent method, which is implemented in Uobject.
    • Staticregisternativesareflectionstudygamemode adds native C + + functions to the Uclass returned by Areflectionstudygamemode::staticclass ().
    • Implement_class defines a static global variable that is used to register Uclass when the program is started.

  

ufunction* z_construct_ufunction_areflectionstudygamemode_callablefunctest () {uobject* Outer=Z_Construct_UClass_ Areflectionstudygamemode (); static ufunction* returnfunction = Null;if (! returnfunction) {returnfunction = new (Ec_internaluseonlyconstructor, Outer, TEXT ("Callablefunctest"), rf_public| Rf_transient| rf_markasnative) Ufunction (Fobjectinitializer (), NULL, 0x04080401, 65535); Returnfunction->bind (); Returnfunction->staticlink (); #if with_metadataumetadata* MetaData = Returnfunction->getoutermost () GetMetaData (); Metadata->setvalue (returnfunction, Text ("Category"), Text ("Areflectionstudygamemode")); Metadata->setvalue (returnfunction, Text ("Modulerelativepath"), Text ("ReflectionStudyGameMode.h")); #endif} return returnfunction;}

  

    • This function registers a function named Callablefunctest in the Uclass class returned by Areflectionstudygamemode, and if # if With_metadata is the metadata we mentioned earlier, It is important to note that the category category specified in our class is specified here and placed in its (upackage) umetadata. Z_construct_ufunction_areflectionstudygamemode_implementablefunctest () and Z_construct_ufunction_ Areflectionstudygamemode_navtivefunctest () implementation in the same way as above, I will not write it out here.

  

uclass* Z_construct_uclass_areflectionstudygamemode () {static uclass* Outerclass = Null;if (! Outerclass) {Z_construct_uclass_agamemode (); Z_construct_upackage__script_reflectionstudy (); outerclass = Areflectionstudygamemode::staticclass (); Outerclass->classflags & class_constructed) {uobjectforceregistration (Outerclass);OuterClass-> Classflags |= 0x2090028c;outerclass->linkchild (z_construct_ufunction_areflectionstudygamemode_ Callablefunctest ()); Outerclass->linkchild (Z_construct_ufunction_areflectionstudygamemode_ Implementablefunctest ()); Outerclass->linkchild (Z_construct_ufunction_areflectionstudygamemode_ Navtivefunctest ()); pragma_disable_deprecation_warningsuproperty* Newprop_score = new (Ec_internaluseonlyconstructor, OuterClass, TEXT (" Score "), rf_public| Rf_transient| rf_markasnative) Ufloatproperty (Cpp_property_base (Score, Areflectionstudygamemode), 0x0020080000000004); Pragma_enable_deprecation_warningsouterclass->addfunctiontofunctionmapwithoverriddenname (Z_ConstRuct_ufunction_areflectionstudygamemode_callablefunctest (), "callablefunctest"); 3059784748outerclass->addfunctiontofunctionmapwithoverriddenname (Z_construct_ufunction_ Areflectionstudygamemode_implementablefunctest (), "implementablefunctest"); 4773450outerclass->addfunctiontofunctionmapwithoverriddenname (Z_construct_ufunction_ Areflectionstudygamemode_navtivefunctest (), "navtivefunctest"); 2500148308outerclass->classconfigname = FName (TEXT ("Game")); Outerclass->staticlink (); #if with_ metadataumetadata* MetaData = Outerclass->getoutermost ()->getmetadata (); Metadata->setvalue (Outerclass, Text ("Hidecategories"), Text ("Info Rendering movementreplication Replication Actor Input Movement Collision Rendering utilities| Transformation ")); Metadata->setvalue (Outerclass, Text ("Includepath"), Text ("ReflectionStudyGameMode.h")); Metadata->setvalue (Outerclass, Text ("Modulerelativepath"), Text ("ReflectionStudyGameMode.h")); Metadata->setvalue (Outerclass, TEXT ("ShowcateGories "), TEXT (" input| Mouseinput input| TouchInput ")); Metadata->setvalue (Newprop_score, Text ("Category"), Text ("Areflectionstudygamemode")); Metadata->setvalue (Newprop_score, Text ("Modulerelativepath"), Text ("ReflectionStudyGameMode.h")); #endif}} Check (Outerclass->getclass ()); return outerclass;}

  

    • This function is to generate Areflectionstudygamemode Uclass objects and register all ufunction and Uproperty
    • Z_construct_uclass_agamemode (); Because it inherits from Agamemode, so Agamemode's uclass must be valid.
    • Z_construct_upackage__script_reflectionstudy (); Make sure that Upackage has been created.
    • The code in the #if With_metadata macro is also used to create metadata.
Static Fcompiledindefer Z_compiledindefer_uclass_areflectionstudygamemode (Z_construct_uclass_ Areflectionstudygamemode, &areflectionstudygamemode::staticclass, TEXT ("Areflectionstudygamemode"), False, nullptr, nullptr);D efine_vtable_ptr_helper_ctor (Areflectionstudygamemode);
    • The first line of code is used to hold a static function that creates a uclass, and then the static build Uclass function is executed.
    • Define_vtable_ptr_helper_ctor defines a parameter as a fvtablehelper constructor.

  

upackage* Z_construct_upackage__script_reflectionstudy () {static upackage* Returnpackage = NULL;if (! Returnpackage) {returnpackage = castchecked<upackage> (Staticfindobjectfast (Upackage::staticclass (), NULL, FName (TEXT ("/script/reflectionstudy")), False, false)); Returnpackage->setpackageflags (Pkg_compiledin | 0x00000000); Fguid Guid; GUID.A = 0X00B770A5; guid.b = 0X8BECE3AF; GUID.C = 0x00000000; GUID.D = 0x00000000; Returnpackage->setguid (GUID);} return returnpackage;}

  

Used to return the upackage of the current module, this parameter Getoutermost () function is used in the above code, and this upackage is returned.

Summarize

So far we have made a brief introduction to the support of UE4 in the reflection system, I believe we have a certain understanding, confined to the length, we end this article, we will continue to discuss other ustruct, Uenum, and other implementations, as well as their entire reflection system running flow. As I am not particularly familiar with the UE4, so it may be said that the inaccuracy of the place, if there is a wrong place, please correct me, but also hope that we can discuss together. Of course, I'll talk about it later. Implementation of other modules in the UE4, such as the implementation of the entire blueprint, multi-threaded rendering, and physical rendering and other content.

Since the top class diagram size is too large, the uploaded images are not particularly clear, high-definition artwork can be downloaded here.

In-depth study on the realization principle of Unreal 4 reflection system (I.)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.