UE4 source in unusual but useful API (includes slate common method) (continually updated)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/zhangxiaofan666/article/details/97622295

1.SNew

This function is often used in Slate layer, commonly used in creating a control Slate , equivalent UObject layer NewObject <> ();

DETAILED code shown below, the back .HAlign (HAlign_Right) which are disposed in this Slate style control, such as the Box is horizontally centered or right alignment, such as what proportion like Padding

SNew(SBox)
		.HAlign(HAlign_Right)
			[
				SNew(SHorizontalBox)
				+SHorizontalBox::Slot()
				.Padding(FMargin(5.0f, 0.0f))
				.AutoWidth()
				[
					SNew(STextBlock)
					.Font(FEditorStyle::GetFontStyle("TinyText"))
					.Text(this, &FPaperTileMapDetailsCustomization::GetLayerSettingsHeadingText)
					.ToolTipText(LOCTEXT("LayerSettingsTooltip", "Properties specific to the currently selected layer"))
					]
				]

 

2.  TSharedRef<SWidget>  UWidget::TakeWidget();

UWidget is transformed into a way of SWIdget, SWIdget layer in Slate, UWidget in UObject layer, a layer SWIdget UWidget sleeve, can be understood as just UWidget shell, usually with at the source can be found in the beginning of the control in the U generally create Slate layer control by the constructor and the like Snew () mode, then the reference is placed in the Private

The role of this function is: do a UMG controls bridge leading to Slate , our custom controls can turn into UMG Slate in SWidget by the function

The official explanation is as follows:

	/**
	 * Gets the underlying slate widget or constructs it if it doesn't exist.  If you're looking to replace
	 * what slate widget gets constructed look for RebuildWidget.  For extremely special cases where you actually
	 * need to change the the GC Root widget of the constructed User Widget - you need to use TakeDerivedWidget
	 * you must also take care to not call TakeWidget before calling TakeDerivedWidget, as that would put the wrong
	 * expected wrapper around the resulting widget being constructed.
	 */
	TSharedRef<SWidget> TakeWidget();

How to turn into UUserWidget Swidget?

 bool UMyBlueprintFunctionLibrary::TestUMGWidget(UUserWidget* InWidget)
 {
 
     TSharedRef<SWidget> Widget = InWidget->TakeWidget();
     
     TSharedRef<SObjectWidget> ObjWidget = StaticCastSharedRef<SObjectWidget>(Widget);
 
     return ObjWidget->GetWidgetObject() == InWidget;
 
 }

 

3.FSlateTexture2DRHIRef* FAssetThumbnailPool::AccessTexture( const FAssetData& AssetData, uint32 Width, uint32 Height )

The function of the role: to set a good length and breadth AssetData and pictures for the rendered thumbnail image data is returned to FSlateTexture2DRHIRef *

	/**
	 * Accesses the texture for an object.  If a thumbnail was recently rendered this function simply returns the thumbnail.  If it was not, it requests a new one be generated
	 * No assumptions should be made about whether or not it was rendered
	 *
	 * @param Asset The asset to get the thumbnail for
	 * @param Width	The width of the thumbnail
	 * @param Height The height of the thumbnail
	 * @return The thumbnail for the asset or NULL if one could not be produced
	 */
	FSlateTexture2DRHIRef* AccessTexture( const FAssetData& AssetData, uint32 Width, uint32 Height );

 

4.

const * FObjectThumbnail ThumbnailTools :: FindCachedThumbnail (const FString & InFullName)

FObjectThumbnail* ThumbnailTools::GetThumbnailForObject( UObject* InObject )

UObject reference or incoming path memory, you can get the rendered FObjectThumbnail

/** Searches for an object's thumbnail in memory and returns it if found */
    const FObjectThumbnail* FindCachedThumbnail( const FString& InFullName )

/** Returns the thumbnail for the specified object or NULL if one doesn't exist yet */
	FObjectThumbnail* GetThumbnailForObject( UObject* InObject )

 

5 ObjectType* TSharedPtr::Get()

Often TSharedPtr pointer stored in Slate layer, but if the function returns a TSharedPtr is not enough, because it is read-only, can not be assigned, we can return to the object by Get () method of the reference

	/**
	 * Returns the object referenced by this pointer, or nullptr if no object is reference
	 *
	 * @return  The object owned by this shared pointer, or nullptr
	 */
	FORCEINLINE ObjectType* Get() const
	{
		return Object;
	}

 

UTexture2D* FImageUtils::CreateTexture2D

(int32 SrcWidth, int32 SrcHeight, const TArray<FColor> &SrcData, UObject* Outer, const FString& Name, const EObjectFlags &Flags, const FCreateTexture2DParameters& InParams)

It encapsulates the Create Texture2D in FimageUtils class, import and export functions

	/**
	 * Creates a 2D texture from a array of raw color data.
	 *
	 * @param SrcWidth		Source image width.
	 * @param SrcHeight		Source image height.
	 * @param SrcData		Source image data.
	 * @param Outer			Outer for the texture object.
	 * @param Name			Name for the texture object.
	 * @param Flags			Object flags for the texture object.
	 * @param InParams		Params about how to set up the texture.
	 * @return				Returns a pointer to the constructed 2D texture object.
	 *
	 */
	ENGINE_API static UTexture2D* CreateTexture2D(int32 SrcWidth, int32 SrcHeight, const TArray<FColor> &SrcData, UObject* Outer, const FString& Name, const EObjectFlags &Flags, const FCreateTexture2DParameters& InParams);

 

7 FString UObjectBaseUtility :: GetPathName () const

Get UObject path, UObjectBaseUtility parent is UObject

/**
 * Returns the fully qualified pathname for this object, in the format:
 * 'Outermost.[Outer:]Name'
 *
 * @param	StopOuter	if specified, indicates that the output string should be relative to this object.  if StopOuter
 *						does not exist in this object's Outer chain, the result would be the same as passing NULL.
 *
 * @note	safe to call on NULL object pointers!
 */
FString UObjectBaseUtility::GetPathName( const UObject* StopOuter/*=NULL*/ ) const
{
	FString Result;
	GetPathName(StopOuter, Result);
	return Result;
}

 

FString UObjectBaseUtility :: GetFullName () const

Gets the name of UObject

/**
 * Returns the fully qualified pathname for this object as well as the name of the class, in the format:
 * 'ClassName Outermost.[Outer:]Name'.
 *
 * @param	StopOuter	if specified, indicates that the output string should be relative to this object.  if StopOuter
 *						does not exist in this object's Outer chain, the result would be the same as passing NULL.
 *
 * @note	safe to call on NULL object pointers!
 */
FString UObjectBaseUtility::GetFullName( const UObject* StopOuter/*=NULL*/ ) const
{
	FString Result;  
	if( this != nullptr )
	{
		Result.Empty(128);
		GetClass()->AppendName(Result);
		Result += TEXT(" ");
		GetPathName( StopOuter, Result );
		// could possibly put a Result.Shrink() here, but this isn't used much in a shipping game
	}
	else
	{
		Result += TEXT("None");
	}
	return Result;  
}

 

9 FPaths:RootDir()

Gets the root path

	/**
	 * Returns the root directory of the engine directory tree
	 *
	 * @return Root directory.
	 */
	static FString FPaths:RootDir();

The class also encapsulates some other paths, such as absolute and relative paths path switching

 static FString ConvertRelativePathToFull (const FString & InPath );

 

10 static FString FPaths: GetPath (const FString & InPath)

Get the path before the file name

	// Returns the path in front of the filename
	static FString FPaths:GetPath(const FString& InPath);

 

11 IModuleInterface& FModuleManager::LoadModuleChecked( const FName InModuleName )

Load a specific module, we say ue4 is more than one module loaded

	/**
	 * Loads the specified module, checking to ensure it exists.
	 *
	 * @param InModuleName The base name of the module file.  Should not include path, extension or platform/configuration info.  This is just the "module name" part of the module file name.  Names should be globally unique.
	 * @return The loaded module, or nullptr if the load operation failed.
	 * @see AbandonModule, IsModuleLoaded, LoadModuleChecked, LoadModulePtr, LoadModuleWithFailureReason, UnloadModule
	 */
	IModuleInterface& LoadModuleChecked( const FName InModuleName );

Usage: This usage is to get the Image module, and then create a JPEG of IMageWrapper pointer

	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);

 

12 

bool FFileHelper::SaveArrayToFile(TArrayView<const uint8> Array, const TCHAR* Filename, IFileManager* FileManager /*= &IFileManager::Get()*/, uint32 WriteFlags)
 

It means for storing binary data as a file

	/**
	 * Save a binary array to a file.
	 */
	static bool SaveArrayToFile(TArrayView<const uint8> Array, const TCHAR* Filename, IFileManager* FileManager=&IFileManager::Get(), uint32 WriteFlags = 0);

Usage: This function is stored as a picture format ObjectThumbnail

	FObjectThumbnail _objectThumnail;
	ThumbnailTools::RenderThumbnail(obj, _imageRes, _imageRes, ThumbnailTools::EThumbnailTextureFlushMode::AlwaysFlush, NULL, &_objectThumnail);
	TArray<uint8> _myData = _objectThumnail.GetUncompressedImageData();

	TArray<FColor> _imageRawColor;
	for (int i = 0; i < _myData.Num(); i += 4)
	{
		_imageRawColor.Add(FColor(_myData[i + 2], _myData[i + 1], _myData[i], _myData[i + 3]));
	}
	FString _fileName = OutputPath.ToString() +"/"+ obj->GetName() + FString(".jpg");
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
	ImageWrapper->SetRaw(_imageRawColor.GetData(), _imageRawColor.GetAllocatedSize(), _imageRes, _imageRes, ERGBFormat::BGRA, 8);
	const TArray<uint8>& _ImageData = ImageWrapper->GetCompressed(100); 	
 	FFileHelper::SaveArrayToFile(_ImageData, *_fileName);	

 

13 new FExtender()

a new container, slate layer is often used for adding various controls

 

14 

TSharedRef< const FExtensionBase > FExtender::AddToolBarExtension( FName ExtensionHook, EExtensionHook::Position HookPosition, const TSharedPtr< FUICommandList >& CommandList, const FToolBarExtensionDelegate& ToolBarExtensionDelegate )

TSharedRef <const FExtensionBase> :: FExtender AddMenuExtension (the FName ExtensionHook, the Position EExtensionHook :: HookPosition, const TSharedPtr <FUICommandList> CommandList &, const FMenuExtensionDelegate & MenuExtensionDelegate)
TSharedRef <const FExtensionBase> :: FExtender AddMenuBarExtension (the FName ExtensionHook, EExtensionHook :: HookPosition the Position, const TSharedPtr <FUICommandList> & CommandList,
const FMenuBarExtensionDelegate & MenuBarExtensionDelegate) method of adding three common slate-style controls, particularly to a new use of a container, and then add three, add in the last module in the

	
	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
	
	{
		TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
		MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FThumbnailExporterModule::AddMenuExtension));

		LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
	}
	
	{
		TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
		ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FThumbnailExporterModule::AddToolbarExtension));
		
		LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
	}

 

15 

FTabSpawnerEntry& FGlobalTabmanager::RegisterNomadTabSpawner( const FName TabId, const FOnSpawnTab& OnSpawnTab )

After addition of enough, have to register, in order to modify the editor controls various styles slate layers, the specific code as follows

	FGlobalTabmanager::Get()->RegisterNomadTabSpawner(ThumbnailExporterTabName, FOnSpawnTab::CreateRaw(this, &FThumbnailExporterModule::OnSpawnPluginTab))
		.SetDisplayName(LOCTEXT("FThumbnailExporterTabTitle", "ThumbnailExporter"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);

 

16 

bool UAssetManager::GetAssetDataForPath(const FSoftObjectPath& ObjectPath, FAssetData& AssetData) const

Get AssetManager, acquires the resource information resource path

Official explained as follows: the specific code used in the second stage

	/** Gets the FAssetData at a specific path, handles redirectors and blueprint classes correctly. Returns true if it found a valid data */
	virtual bool GetAssetDataForPath(const FSoftObjectPath& ObjectPath, FAssetData& AssetData) const;
	UAssetManager& AssetManager = UAssetManager::Get();
	FAssetData MeshObjectAssetData;
	AssetManager.GetAssetDataForPath(MeshObject->GetPathName(), MeshObjectAssetData);

 

17

FAssetThumbnailPool::FAssetThumbnailPool( uint32 InNumInPool, const TAttribute<bool>& InAreRealTimeThumbnailsAllowed, double InMaxFrameTimeAllowance, uint32 InMaxRealTimeThumbnailsPerFrame )

This function is a new personal feeling a thread pool, the thread pool is designed to render a variety Thumbnail

The official explanation is as follows:

The interpretation of FAssetThumbnailPool

/**
 * Utility class for keeping track of, rendering, and recycling thumbnails rendered in Slate              
 */
class FAssetThumbnailPool : public FTickableEditorObject

The meaning of each parameter constructor:

	/**
	 * Constructor 
	 *
	 * @param InNumInPool						The number of thumbnails allowed in the pool
	 * @param InAreRealTimeThumbnailsAllowed	Attribute that determines if thumbnails should be rendered in real-time
	 * @param InMaxFrameTimeAllowance			The maximum number of seconds per tick to spend rendering thumbnails
	 * @param InMaxRealTimeThumbnailsPerFrame	The maximum number of real-time thumbnails to render per tick
	 */
	UNREALED_API FAssetThumbnailPool( uint32 InNumInPool, const TAttribute<bool>& InAreRealTimeThumbnailsAllowed = true, double InMaxFrameTimeAllowance = 0.005, uint32 InMaxRealTimeThumbnailsPerFrame = 3 );

Using the following code:

	TSharedPtr<FAssetThumbnailPool> ThumbnailPool1 = MakeShareable(new FAssetThumbnailPool(50, true));

 

18

TSharedRef< ObjectType, Mode > ToSharedRef() const

Will turn into a TSharedPtr TSharedRef

	/**
	 * Converts a shared pointer to a shared reference.  The pointer *must* be valid or an assertion will trigger.
	 *
	 * @return  Reference to the object
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	FORCEINLINE TSharedRef< ObjectType, Mode > ToSharedRef() const
	{
 		// If this assert goes off, it means a shared reference was created from a shared pointer that was nullptr.
 		// Shared references are never allowed to be null.  Consider using TSharedPtr instead.
		check( IsValid() );
		return TSharedRef< ObjectType, Mode >( *this );
	}

usage:

	TSharedPtr<SWidget> MySWidget;
	TSharedRef<SWidget> MySWidgetRef=MySWidget.ToSharedRef();

 

19

UTexture2D* UKismetRenderingLibrary::ImportFileAsTexture2D(UObject* WorldContextObject, const FString& Filename)

UTexture2D* UKismetRenderingLibrary::ImportBufferAsTexture2D(UObject* WorldContextObject, const TArray<uint8>& Buffer)

Path for incoming images or pictures Buffer, generating a picture


UTexture2D* UKismetRenderingLibrary::ImportFileAsTexture2D(UObject* WorldContextObject, const FString& Filename)
{
	return FImageUtils::ImportFileAsTexture2D(Filename);
}

UTexture2D* UKismetRenderingLibrary::ImportBufferAsTexture2D(UObject* WorldContextObject, const TArray<uint8>& Buffer)

 

20

void UKismetRenderingLibrary::ExportTexture2D(UObject* WorldContextObject, UTexture2D* Texture, const FString& FilePath, const FString& FileName)

The Texture2D a picture output to disk

	/**
	 * Exports a Texture2D as a HDR image onto the disk.
	 */
	UFUNCTION(BlueprintCallable, Category = "Rendering", meta = (Keywords = "ExportTexture2D", WorldContext = "WorldContextObject"))
	static ENGINE_API void ExportTexture2D(UObject* WorldContextObject, UTexture2D* Texture, const FString& FilePath, const FString& FileName);

 

21

UFunction*  UClass::FindFunction(FName InName) const

Action: it directly to a function pointer by function name UClass

	/** 
	 * This signature intentionally hides the method declared in UObject to make it private.
	 * Call FindFunctionByName instead; This method will search for a function declared in UClass instead of the class it was called on
	 */
	UFunction* FindFunctionChecked(FName InName) const
	{
		return UObject::FindFunctionChecked(InName);
	}

usage:

	SkyDataAsset = FAssetData(SkyData);
	UFunction* SetSkyData = SkyController->FindFunction(TEXT("EditorSetSkyData"));
	SkyController->ProcessEvent(SetSkyData, &SkyData);

 

22

virtual void AActor::ProcessEvent(UFunction* Function, void* Parameters)

effect:

All parameters passed to the function and function pointers Struct has directly call the function

This function is achieved cpp below, we can see, in fact, it is called the father of the function

void AActor::ProcessEvent(UFunction* Function, void* Parameters)
{
	LLM_SCOPE(ELLMTag::EngineMisc);

	#if WITH_EDITOR
	static const FName CallInEditorMeta(TEXT("CallInEditor"));
	const bool bAllowScriptExecution = GAllowActorScriptExecutionInEditor || Function->GetBoolMetaData(CallInEditorMeta);
	#else
	const bool bAllowScriptExecution = GAllowActorScriptExecutionInEditor;
	#endif
	UWorld* MyWorld = GetWorld();
	if( ((MyWorld && (MyWorld->AreActorsInitialized() || bAllowScriptExecution)) || HasAnyFlags(RF_ClassDefaultObject)) && !IsGarbageCollecting() )
	{
#if !UE_BUILD_SHIPPING
		if (!ProcessEventDelegate.IsBound() || !ProcessEventDelegate.Execute(this, Function, Parameters))
		{
			Super::ProcessEvent(Function, Parameters);
		}
#else
		Super::ProcessEvent(Function, Parameters);
#endif
	}
}

Parent is UObject, the function to achieve the following, feeling a little obscure, and then study available

void UObject::ProcessEvent( UFunction* Function, void* Parms )
{
	checkf(!IsUnreachable(),TEXT("%s  Function: '%s'"), *GetFullName(), *Function->GetPathName());
	checkf(!FUObjectThreadContext::Get().IsRoutingPostLoad, TEXT("Cannot call UnrealScript (%s - %s) while PostLoading objects"), *GetFullName(), *Function->GetFullName());

#if LIGHTWEIGHT_PROCESS_EVENT_COUNTER
	CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && ProcessEventCounter == 0);
	TGuardValue<int32> PECounter(ProcessEventCounter, ProcessEventCounter+1);
#endif

#if DO_BLUEPRINT_GUARD
	FBlueprintExceptionTracker& BlueprintExceptionTracker = FBlueprintExceptionTracker::Get();
	TGuardValue<int32> EntryCounter( BlueprintExceptionTracker.ScriptEntryTag, BlueprintExceptionTracker.ScriptEntryTag+1);

	CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && BlueprintExceptionTracker.ScriptEntryTag == 1);
#endif

#if TOTAL_OVERHEAD_SCRIPT_STATS
	FBlueprintEventTimer::FScopedVMTimer VMTime;
#endif // TOTAL_OVERHEAD_SCRIPT_STATS

	// Reject.
	if (IsPendingKill())
	{
		return;
	}
	
#if WITH_EDITORONLY_DATA
	// Cannot invoke script events when the game thread is paused for debugging.
	if(GIntraFrameDebuggingGameThread)
	{
		if(GFirstFrameIntraFrameDebugging)
		{
			UE_LOG(LogScriptCore, Warning, TEXT("Cannot call UnrealScript (%s - %s) while stopped at a breakpoint."), *GetFullName(), *Function->GetFullName());
		}

		return;
	}
#endif	// WITH_EDITORONLY_DATA

	if ((Function->FunctionFlags & FUNC_Native) != 0)
	{
		int32 FunctionCallspace = GetFunctionCallspace(Function, Parms, NULL);
		if (FunctionCallspace & FunctionCallspace::Remote)
		{
			CallRemoteFunction(Function, Parms, NULL, NULL);
		}

		if ((FunctionCallspace & FunctionCallspace::Local) == 0)
		{
			return;
		}
	}
	else if (Function->Script.Num() == 0)
	{
		return;
	}
	checkSlow((Function->ParmsSize == 0) || (Parms != NULL));

#if PER_FUNCTION_SCRIPT_STATS
	const bool bShouldTrackFunction = Stats::IsThreadCollectingData();
	FScopeCycleCounterUObject FunctionScope(bShouldTrackFunction ? Function : nullptr);
#endif // PER_FUNCTION_SCRIPT_STATS

#if STATS || ENABLE_STATNAMEDEVENTS
	const bool bShouldTrackObject = GVerboseScriptStats && Stats::IsThreadCollectingData();
	FScopeCycleCounterUObject ContextScope(bShouldTrackObject ? this : nullptr);
#endif

#if UE_BLUEPRINT_EVENTGRAPH_FASTCALLS
	// Fast path for ubergraph calls
	int32 EventGraphParams;
	if (Function->EventGraphFunction != nullptr)
	{
		// Call directly into the event graph, skipping the stub thunk function
		EventGraphParams = Function->EventGraphCallOffset;
		Parms = &EventGraphParams;
		Function = Function->EventGraphFunction;

		// Validate assumptions required for this optimized path (EventGraphFunction should have only been filled out if these held)
		checkSlow(Function->ParmsSize == sizeof(EventGraphParams));
		checkSlow(Function->FirstPropertyToInit == nullptr);
		checkSlow(Function->PostConstructLink == nullptr);
	}
#endif

	// Scope required for scoped script stats.
	{
		uint8* Frame = NULL;
#if USE_UBER_GRAPH_PERSISTENT_FRAME
		if (Function->HasAnyFunctionFlags(FUNC_UbergraphFunction))
		{
			Frame = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(this, Function);
		}
#endif
		const bool bUsePersistentFrame = (NULL != Frame);
		if (!bUsePersistentFrame)
		{
			Frame = (uint8*)FMemory_Alloca(Function->PropertiesSize);
			// zero the local property memory
			FMemory::Memzero(Frame + Function->ParmsSize, Function->PropertiesSize - Function->ParmsSize);
		}

		// initialize the parameter properties
		FMemory::Memcpy(Frame, Parms, Function->ParmsSize);

		// Create a new local execution stack.
		FFrame NewStack(this, Function, Frame, NULL, Function->Children);

		checkSlow(NewStack.Locals || Function->ParmsSize == 0);



		// if the function has out parameters, fill the stack frame's out parameter info with the info for those params 
		if ( Function->HasAnyFunctionFlags(FUNC_HasOutParms) )
		{
			FOutParmRec** LastOut = &NewStack.OutParms;
			for ( UProperty* Property = (UProperty*)Function->Children; Property && (Property->PropertyFlags&(CPF_Parm)) == CPF_Parm; Property = (UProperty*)Property->Next )
			{
				// this is used for optional parameters - the destination address for out parameter values is the address of the calling function
				// so we'll need to know which address to use if we need to evaluate the default parm value expression located in the new function's
				// bytecode
				if ( Property->HasAnyPropertyFlags(CPF_OutParm) )
				{
					CA_SUPPRESS(6263)
					FOutParmRec* Out = (FOutParmRec*)FMemory_Alloca(sizeof(FOutParmRec));
					// set the address and property in the out param info
					// note that since C++ doesn't support "optional out" we can ignore that here
					Out->PropAddr = Property->ContainerPtrToValuePtr<uint8>(Parms);
					Out->Property = Property;

					// add the new out param info to the stack frame's linked list
					if (*LastOut)
					{
						(*LastOut)->NextOutParm = Out;
						LastOut = &(*LastOut)->NextOutParm;
					}
					else
					{
						*LastOut = Out;
					}
				}
			}

			// set the next pointer of the last item to NULL to mark the end of the list
			if (*LastOut)
			{
				(*LastOut)->NextOutParm = NULL;
			}
		}

		if (!bUsePersistentFrame)
		{
			for (UProperty* LocalProp = Function->FirstPropertyToInit; LocalProp != NULL; LocalProp = (UProperty*)LocalProp->Next)
			{
				LocalProp->InitializeValue_InContainer(NewStack.Locals);
			}
		}

		// Call native function or UObject::ProcessInternal.
		const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;
		uint8* ReturnValueAddress = bHasReturnParam ? ((uint8*)Parms + Function->ReturnValueOffset) : nullptr;
		Function->Invoke(this, NewStack, ReturnValueAddress);

		if (!bUsePersistentFrame)
		{
			// Destroy local variables except function parameters.!! see also UObject::CallFunctionByNameWithArguments
			// also copy back constructed value parms here so the correct copy is destroyed when the event function returns
			for (UProperty* P = Function->DestructorLink; P; P = P->DestructorLinkNext)
			{
				if (!P->IsInContainer(Function->ParmsSize))
				{
					P->DestroyValue_InContainer(NewStack.Locals);
				}
				else if (!(P->PropertyFlags & CPF_OutParm))
				{
					FMemory::Memcpy(P->ContainerPtrToValuePtr<uint8>(Parms), P->ContainerPtrToValuePtr<uint8>(NewStack.Locals), P->ArrayDim * P->ElementSize);
				}
			}
		}
	}

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
#if WITH_EDITORONLY_DATA
	FBlueprintCoreDelegates::OnScriptExecutionEnd.Broadcast();
#endif
#endif
}

 

23 

template< class ObjectType >
FORCEINLINE SharedPointerInternals::FRawPtrProxy< ObjectType > MakeShareable( ObjectType* InObject )

Action: A pointer to an object implicitly converted into a shared pointers

usage

TSharedRef<IDetailCustomization> FCWPVPActorDetailPanel::MakeInstance()
{
	return MakeShareable(new FCWPVPActorDetailPanel);
}

The source explained:

/**
 * MakeShareable utility function.  Wrap object pointers with MakeShareable to allow them to be implicitly
 * converted to shared pointers!  This is useful in assignment operations, or when returning a shared
 * pointer from a function.
 */
// NOTE: The following is an Unreal extension to standard shared_ptr behavior
template< class ObjectType >
FORCEINLINE SharedPointerInternals::FRawPtrProxy< ObjectType > MakeShareable( ObjectType* InObject )
{
	return SharedPointerInternals::FRawPtrProxy< ObjectType >( InObject );
}

 

Guess you like

Origin blog.csdn.net/zhangxiaofan666/article/details/97622295