| @ -0,0 +1,57 @@ | ||||
| #include "CSBindsManager.h" | ||||
| #include "UnrealSharpBinds.h" | ||||
|  | ||||
| FCSBindsManager* FCSBindsManager::BindsManagerInstance = nullptr; | ||||
|  | ||||
| FCSBindsManager* FCSBindsManager::Get() | ||||
| { | ||||
| 	if (!BindsManagerInstance) | ||||
| 	{ | ||||
| 		BindsManagerInstance = new FCSBindsManager(); | ||||
| 	} | ||||
|  | ||||
| 	return BindsManagerInstance; | ||||
| } | ||||
|  | ||||
| void FCSBindsManager::RegisterExportedFunction(const FName& ClassName, const FCSExportedFunction& ExportedFunction) | ||||
| { | ||||
| 	FCSBindsManager* Instance = Get(); | ||||
| 	TArray<FCSExportedFunction>& ExportedFunctions = Instance->ExportedFunctionsMap.FindOrAdd(ClassName); | ||||
| 	ExportedFunctions.Add(ExportedFunction); | ||||
| } | ||||
|  | ||||
| void* FCSBindsManager::GetBoundFunction(const TCHAR* InOuterName, const TCHAR* InFunctionName, int32 ManagedFunctionSize) | ||||
| { | ||||
| 	TRACE_CPUPROFILER_EVENT_SCOPE(UCSBindsManager::GetBoundFunction); | ||||
| 	 | ||||
| 	FCSBindsManager* Instance = Get(); | ||||
| 	FName ManagedOuterName = FName(InOuterName); | ||||
| 	FName ManagedFunctionName = FName(InFunctionName); | ||||
| 	 | ||||
| 	TArray<FCSExportedFunction>* ExportedFunctions = Instance->ExportedFunctionsMap.Find(ManagedOuterName); | ||||
|  | ||||
| 	if (!ExportedFunctions) | ||||
| 	{ | ||||
| 		UE_LOG(LogUnrealSharpBinds, Error, TEXT("Failed to get BoundNativeFunction: No exported functions found for %s"), InOuterName); | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	for (FCSExportedFunction& NativeFunction : *ExportedFunctions) | ||||
| 	{ | ||||
| 		if (NativeFunction.Name != ManagedFunctionName) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
| 			 | ||||
| 		if (NativeFunction.Size != ManagedFunctionSize) | ||||
| 		{ | ||||
| 			UE_LOG(LogUnrealSharpBinds, Error, TEXT("Failed to get BoundNativeFunction: Function size mismatch for %s::%s."), InOuterName, InFunctionName); | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 			 | ||||
| 		return NativeFunction.FunctionPointer; | ||||
| 	} | ||||
|  | ||||
| 	UE_LOG(LogUnrealSharpBinds, Error, TEXT("Failed to get BoundNativeFunction: No function found for %s.%s"), *ManagedOuterName.ToString(), *ManagedFunctionName.ToString()); | ||||
| 	return nullptr; | ||||
| } | ||||
| @ -0,0 +1,11 @@ | ||||
| #include "CSExportedFunction.h" | ||||
|  | ||||
| #include "CSBindsManager.h" | ||||
|  | ||||
| FCSExportedFunction::FCSExportedFunction(const FName& OuterName, const FName& Name, void* InFunctionPointer, int32 InSize): | ||||
| 	Name(Name), | ||||
| 	FunctionPointer(InFunctionPointer), | ||||
| 	Size(InSize) | ||||
| { | ||||
| 	FCSBindsManager::RegisterExportedFunction(OuterName, *this); | ||||
| } | ||||
| @ -0,0 +1,18 @@ | ||||
| #include "UnrealSharpBinds.h" | ||||
|  | ||||
| #define LOCTEXT_NAMESPACE "FUnrealSharpBindsModule" | ||||
|  | ||||
| DEFINE_LOG_CATEGORY(LogUnrealSharpBinds); | ||||
|  | ||||
| void FUnrealSharpBindsModule::StartupModule() | ||||
| { | ||||
| } | ||||
|  | ||||
| void FUnrealSharpBindsModule::ShutdownModule() | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| #undef LOCTEXT_NAMESPACE | ||||
|      | ||||
| IMPLEMENT_MODULE(FUnrealSharpBindsModule, UnrealSharpBinds) | ||||
| @ -0,0 +1,23 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CSExportedFunction.h" | ||||
|  | ||||
| // Native bound function. If you want to bind a function to C#, use this macro. | ||||
| // The managed delegate signature must match the native function signature + outer name, and all params need to be blittable. | ||||
| #define UNREALSHARP_FUNCTION() | ||||
|  | ||||
| class FCSBindsManager | ||||
| { | ||||
| public: | ||||
| 	 | ||||
| 	static FCSBindsManager* Get(); | ||||
| 	 | ||||
| 	UNREALSHARPBINDS_API static void RegisterExportedFunction(const FName& ClassName, const FCSExportedFunction& ExportedFunction); | ||||
|  | ||||
| 	UNREALSHARPBINDS_API static void* GetBoundFunction(const TCHAR* InOuterName, const TCHAR* InFunctionName, int32 ManagedFunctionSize); | ||||
|  | ||||
| private: | ||||
| 	FCSBindsManager() = default; | ||||
| 	static FCSBindsManager* BindsManagerInstance; | ||||
| 	TMap<FName, TArray<FCSExportedFunction>> ExportedFunctionsMap; | ||||
| }; | ||||
| @ -0,0 +1,50 @@ | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * Thin wrapper around sizeof(T) used for getting the size of a function's arguments. | ||||
|  * @tparam T The type we want the size of | ||||
|  */ | ||||
| template <typename T> | ||||
| struct TArgSize | ||||
| { | ||||
| 	constexpr static size_t Size = sizeof(T); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Specialization for reference qualified types so we can get the size of the pointer instead of the object itself. | ||||
|  * @tparam T The type we want the size of | ||||
|  */ | ||||
| template <typename T> | ||||
| struct TArgSize<T&> | ||||
| { | ||||
| 	constexpr static size_t Size = sizeof(T*); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Constant expression for the size of an argument | ||||
|  * @tparam T The type we want the size of | ||||
|  */ | ||||
| template <typename T> | ||||
| constexpr size_t ArgSize = TArgSize<T>::Size; | ||||
|  | ||||
| template <typename ReturnType, typename... Args> | ||||
| constexpr size_t GetFunctionSize(ReturnType (*)(Args...)) | ||||
| { | ||||
| 	if constexpr (std::is_void_v<ReturnType>) | ||||
| 	{ | ||||
| 		return (ArgSize<Args> + ... + 0); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return ArgSize<ReturnType> + (ArgSize<Args> + ... + 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| struct UNREALSHARPBINDS_API FCSExportedFunction | ||||
| { | ||||
| 	FName Name; | ||||
| 	void* FunctionPointer; | ||||
| 	int32 Size; | ||||
|  | ||||
| 	FCSExportedFunction(const FName& OuterName, const FName& Name, void* InFunctionPointer, int32 InSize); | ||||
| }; | ||||
| @ -0,0 +1,16 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "Modules/ModuleManager.h" | ||||
|  | ||||
| DECLARE_LOG_CATEGORY_EXTERN(LogUnrealSharpBinds, Log, All); | ||||
|  | ||||
| class FUnrealSharpBindsModule : public IModuleInterface | ||||
| { | ||||
| public: | ||||
|      | ||||
|     // IModuleInterface interface | ||||
|     virtual void StartupModule() override; | ||||
|     virtual void ShutdownModule() override; | ||||
|     // End of IModuleInterface interface | ||||
| }; | ||||
| @ -0,0 +1,26 @@ | ||||
| using UnrealBuildTool; | ||||
|  | ||||
| public class UnrealSharpBinds : ModuleRules | ||||
| { | ||||
|     public UnrealSharpBinds(ReadOnlyTargetRules Target) : base(Target) | ||||
|     { | ||||
|         PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; | ||||
|  | ||||
|         PublicDependencyModuleNames.AddRange( | ||||
|             new string[] | ||||
|             { | ||||
|                 "Core", | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         PrivateDependencyModuleNames.AddRange( | ||||
|             new string[] | ||||
|             { | ||||
|                 "CoreUObject", | ||||
|                 "Engine", | ||||
|                 "Slate", | ||||
|                 "SlateCore" | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user