赞
踩
较之上一节我们添加了两个UBoxComponent作为变量,以及从TestFunc1——6共六种常用的函数
其中TestFunc5需要在cpp中有实现
MyActor.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "MyActor.generated.h" UCLASS() class REFLECTTEST_API AMyActor : public AActor { GENERATED_BODY() private: UPROPERTY() class UBoxComponent* MyBoxComponent; UPROPERTY(EditDefaultsOnly, Category = "BoxComponent") class UBoxComponent* MyBoxComponent2; public: UFUNCTION(BlueprintCallable, Category = "TestFunc") void TestFunc1() {} UFUNCTION(BlueprintCallable, Category = "TestFunc") bool TestFunc2() { return true; } UFUNCTION(BlueprintCallable, Category = "TestFunc") void TestFunc3(int32 IntValue, const FString& Name, bool bShowInWindows) {} UFUNCTION() bool TestFunc4() { return true; } UFUNCTION(BlueprintNativeEvent, Category = "TestFunc") bool TestFunc5(int32 IntValue); UFUNCTION(BlueprintImplementableEvent, Category = "TestFunc") bool TestFunc6(bool bShowWindows); public: // Sets default values for this actor's properties AMyActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; };
MyActor.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "../Public/MyActor.h" bool AMyActor::TestFunc5_Implementation(int32 IntValue) { return true; } // Sets default values AMyActor::AMyActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned void AMyActor::BeginPlay() { Super::BeginPlay(); } // Called every frame void AMyActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); }
原有的ReflectTest_Source_ReflectTest_Public_MyActor_h_11_PRIVATE_PROPERTY_OFFSET 和ReflectTest_Source_ReflectTest_Public_MyActor_h_11_RPC_WRAPPERS在AActor为空宏,在此节中将会详细拆解。
之前已拆解过的ReflectTest_Source_ReflectTest_Public_MyActor_h_11_INCLASS 和ReflectTest_Source_ReflectTest_Public_MyActor_h_11_STANDARD_CONSTRUCTORS 不再讨论
//2.2拆解
ReflectTest_Source_ReflectTest_Public_MyActor_h_11_PRIVATE_PROPERTY_OFFSET
//2.3拆解
ReflectTest_Source_ReflectTest_Public_MyActor_h_11_RPC_WRAPPERS
ReflectTest_Source_ReflectTest_Public_MyActor_h_11_CALLBACK_WRAPPERS
//上一节已分析
ReflectTest_Source_ReflectTest_Public_MyActor_h_11_INCLASS
ReflectTest_Source_ReflectTest_Public_MyActor_h_11_STANDARD_CONSTRUCTORS
FORCEINLINE static uint32 __PPO__MyBoxComponent() {
return STRUCT_OFFSET(AMyActor, MyBoxComponent);
}
FORCEINLINE static uint32 __PPO__MyBoxComponent2() {
return STRUCT_OFFSET(AMyActor, MyBoxComponent2);
}
此层拆解为去除各种宏后的最终程序样式,替换过程较为血腥,已省略
#if 0 /*execTestFunc5原始状态*/ DECLARE_FUNCTION(execTestFunc5) { P_GET_PROPERTY(UIntProperty,Z_Param_IntValue); P_FINISH; P_NATIVE_BEGIN; *(bool*)Z_Param__Result = P_THIS->TestFunc5_Implementation(Z_Param_IntValue); P_NATIVE_END; } #endif /*execTestFunc5完全拆解后*/ //Context:我们的对象 Stack:栈帧 Z_Param__Result:函数返回值 static void execTestFunc5(UObject* Context, FFrame& Stack, void* const Z_Param__Result) { //三、P_GET_PROPERTY(UIntProperty,Z_Param_IntValue); //替换检查字节码的步骤 //验证参数的顺序是否正确以及类型是否兼容 UIntProperty::TCppType Z_Param_IntValue = UIntProperty::GetDefaultPropertyValue(); Stack.StepCompiledIn<UIntProperty>(&Z_Param_IntValue); //P_FINISH展开 //效果类似Code++; Stack.Code += !!Stack.Code; //P_NATIVE_BEGIN展开 { //SCOPED_SCRIPT_NATIVE_TIMER(ScopedNativeCallTimer);展开 //记录函数运行时间 FBlueprintEventTimer::FScopedNativeTimer ScopedNativeCallTimer; *(bool*)Z_Param__Result = P_THIS->TestFunc5_Implementation(Z_Param_IntValue); //P_NATIVE_END展开 } } static void execTestFunc4(UObject* Context, FFrame& Stack, void* const Z_Param__Result) { Stack.Code += !!Stack.Code; /* increment the code ptr unless it is null */ { FBlueprintEventTimer::FScopedNativeTimer ScopedNativeCallTimer; *(bool*)Z_Param__Result = P_THIS->TestFunc4(); } } static void execTestFunc3(UObject* Context, FFrame& Stack, void* const Z_Param__Result) { //P_GET_PROPERTY(UIntProperty,Z_Param_IntValue); UIntProperty::TCppType Z_Param_IntValue = UIntProperty::GetDefaultPropertyValue(); Stack.StepCompiledIn<UIntProperty>(&Z_Param_IntValue); //P_GET_PROPERTY(UStrProperty,Z_Param_Name); UStrProperty::TCppType Z_Param_Name = UStrProperty::GetDefaultPropertyValue(); Stack.StepCompiledIn<UStrProperty>(&Z_Param_Name); //P_GET_UBOOL(Z_Param_bShowInWindows); // translate the bitfield into a bool type for non-intel platforms uint32 Z_Param_bShowInWindows32 = 0; bool Z_Param_bShowInWindows = false; Stack.StepCompiledIn<UBoolProperty>(&Z_Param_bShowInWindows32); Z_Param_bShowInWindows = !!Z_Param_bShowInWindows32; //P_FINISH; Stack.Code += !!Stack.Code; //P_NATIVE_BEGIN; { FBlueprintEventTimer::FScopedNativeTimer ScopedNativeCallTimer; (ThisClass*)(Context)->TestFunc3(Z_Param_IntValue, Z_Param_Name, Z_Param_bShowInWindows); //P_NATIVE_END; } } static void execTestFunc2(UObject* Context, FFrame& Stack, void* const Z_Param__Result) { Stack.Code += !!Stack.Code; { FBlueprintEventTimer::FScopedNativeTimer ScopedNativeCallTimer; *(bool*)Z_Param__Result = (ThisClass*)(Context)->TestFunc2(); } } static void execTestFunc1(UObject* Context, FFrame& Stack, void* const Z_Param__Result) { Stack.Code += !!Stack.Code; { FBlueprintEventTimer::FScopedNativeTimer ScopedNativeCallTimer; (ThisClass*)(Context)->TestFunc1(); } }
- 一个用于构造时开始计时析构时停止计时的Timer类
- { Timer timer; FunctionName(); }
- 将{Timer timer和}封装为Begin和End宏
struct FFrame : public FOutputDevice { public: // Variables. UFunction* Node; //蓝图节点 UObject* Object; //函数所属对象 uint8* Code; //字节码数组 uint8* Locals; //局部变量 //最近使用变量的指针和地址 UProperty* MostRecentProperty; uint8* MostRecentPropertyAddress; /** The execution flow stack for compiled Kismet code */ //流程栈——每执行一个流程后弹出,再执行下一个流程 FlowStackType FlowStack; /** Previous frame on the stack */ //上一帧(之前使用的Frame) FFrame* PreviousFrame; /** contains information on any out parameters */ //外界参数包,存放所有外界参数(返回值,&) FOutParmRec* OutParms; /** If a class is compiled in then this is set to the property chain for compiled-in functions. In that case, we follow the links to setup the args instead of executing by code. */ //属性链,存放函数的参数 UField* PropertyChainForCompiledIn; /** Currently executed native function */ //原生函数 UFunction* CurrentNativeFunction; bool bArrayContextFailed; public: // Constructors. FFrame(UObject* InObject, UFunction* InNode, void* InLocals, FFrame* InPreviousFrame = NULL, UField* InPropertyChainForCompiledIn = NULL); virtual ~FFrame() { #if DO_BLUEPRINT_GUARD FBlueprintExceptionTracker& BlueprintExceptionTracker = FBlueprintExceptionTracker::Get(); if (BlueprintExceptionTracker.ScriptStack.Num()) { BlueprintExceptionTracker.ScriptStack.Pop(false); } #endif } // Functions. //指针当前帧 COREUOBJECT_API void Step(UObject* Context, RESULT_DECL) { int32 B = *Code++; //GNative是一个函数指针,存放函数数组 (GNatives[B])(Context, *this, RESULT_PARAM); } /** Replacement for Step that uses an explicitly specified property to unpack arguments **/ COREUOBJECT_API void StepExplicitProperty(void* const Result, UProperty* Property); /** Replacement for Step that checks the for byte code, and if none exists, then PropertyChainForCompiledIn is used. Also, makes an effort to verify that the params are in the correct order and the types are compatible. **/ template<class TProperty> FORCEINLINE_DEBUGGABLE void StepCompiledIn(void* const Result); /** Replacement for Step that checks the for byte code, and if none exists, then PropertyChainForCompiledIn is used. Also, makes an effort to verify that the params are in the correct order and the types are compatible. **/ template<class TProperty, typename TNativeType> FORCEINLINE_DEBUGGABLE TNativeType& StepCompiledInRef(void* const TemporaryBuffer); COREUOBJECT_API virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category) override; COREUOBJECT_API static void KismetExecutionMessage(const TCHAR* Message, ELogVerbosity::Type Verbosity, FName WarningId = FName()); /** Returns the current script op code */ const uint8 PeekCode() const { return *Code; } /** Skips over the number of op codes specified by NumOps */ void SkipCode(const int32 NumOps) { Code += NumOps; } //读取不同的类型 template<typename TNumericType> TNumericType ReadInt(); float ReadFloat(); FName ReadName(); UObject* ReadObject(); int32 ReadWord(); UProperty* ReadProperty(); /** May return null */ UProperty* ReadPropertyUnchecked(); /** * Reads a value from the bytestream, which represents the number of bytes to advance * the code pointer for certain expressions. * * @param ExpressionField receives a pointer to the field representing the expression; used by various execs * to drive VM logic */ CodeSkipSizeType ReadCodeSkipCount(); /** * Reads a value from the bytestream which represents the number of bytes that should be zero'd out if a NULL context * is encountered * * @param ExpressionField receives a pointer to the field representing the expression; used by various execs * to drive VM logic */ VariableSizeType ReadVariableSize(UProperty** ExpressionField); /** * This will return the StackTrace of the current callstack from the last native entry point **/ COREUOBJECT_API FString GetStackTrace() const; /** * This will return the StackTrace of the all script frames currently active **/ COREUOBJECT_API static FString GetScriptCallstack(); /** * This will return a string of the form "ScopeName.FunctionName" associated with this stack frame: */ COREUOBJECT_API FString GetStackDescription() const; #if DO_BLUEPRINT_GUARD static void InitPrintScriptCallstack(); #endif };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。