124 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| #include "CSManagedCallbacksCache.h"
 | |
| #include "CSManagedGCHandle.generated.h"
 | |
| 
 | |
| enum class GCHandleType : char
 | |
| {
 | |
| 	Null,
 | |
| 	StrongHandle,
 | |
| 	WeakHandle,
 | |
| 	PinnedHandle,
 | |
| };
 | |
| 
 | |
| struct FGCHandleIntPtr
 | |
| {
 | |
| 	bool operator == (const FGCHandleIntPtr& Other) const
 | |
| 	{
 | |
| 		return IntPtr == Other.IntPtr;
 | |
| 	}
 | |
| 
 | |
| 	bool operator != (const FGCHandleIntPtr& Other) const
 | |
| 	{
 | |
| 		return IntPtr != Other.IntPtr;
 | |
| 	}
 | |
| 	
 | |
| 	// Pointer to the managed object in C#
 | |
| 	uint8* IntPtr = nullptr;
 | |
| };
 | |
| 
 | |
| static_assert(sizeof(FGCHandleIntPtr) == sizeof(void *));
 | |
| 
 | |
| struct FGCHandle
 | |
| {
 | |
| 	FGCHandleIntPtr Handle;
 | |
| 	GCHandleType Type = GCHandleType::Null;
 | |
| 
 | |
| 	static FGCHandle Null() { return FGCHandle(nullptr, GCHandleType::Null); }
 | |
| 
 | |
| 	bool IsNull() const { return !Handle.IntPtr; }
 | |
| 	bool IsWeakPointer() const { return Type == GCHandleType::WeakHandle; }
 | |
| 	
 | |
| 	FGCHandleIntPtr GetHandle() const { return Handle; }
 | |
| 	uint8* GetPointer() const { return Handle.IntPtr; };
 | |
| 	
 | |
| 	void Dispose(FGCHandleIntPtr AssemblyHandle = FGCHandleIntPtr())
 | |
| 	{
 | |
| 		if (!Handle.IntPtr || Type == GCHandleType::Null)
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		FCSManagedCallbacks::ManagedCallbacks.Dispose(Handle, AssemblyHandle);
 | |
| 	
 | |
| 		Handle.IntPtr = nullptr;
 | |
| 		Type = GCHandleType::Null;
 | |
| 	}
 | |
| 
 | |
| 	void operator = (const FGCHandle& Other)
 | |
| 	{
 | |
| 		Handle = Other.Handle;
 | |
| 		Type = Other.Type;
 | |
| 	}
 | |
| 	
 | |
| 	operator void*() const
 | |
| 	{
 | |
| 		return Handle.IntPtr;
 | |
| 	}
 | |
| 
 | |
| 	FGCHandle(){}
 | |
| 	FGCHandle(const FGCHandleIntPtr InHandle, const GCHandleType InType) : Handle(InHandle), Type(InType) {}
 | |
| 
 | |
| 	FGCHandle(uint8* InHandle, const GCHandleType InType) : Type(InType)
 | |
| 	{
 | |
| 		Handle.IntPtr = InHandle;
 | |
| 	}
 | |
| 
 | |
| 	FGCHandle(const FGCHandleIntPtr InHandle) : Handle(InHandle)
 | |
| 	{
 | |
| 		Type = GCHandleType::Null;
 | |
| 	}
 | |
| };
 | |
| 
 | |
| struct FScopedGCHandle
 | |
| {
 | |
|     
 | |
|     FGCHandleIntPtr Handle;
 | |
| 
 | |
|     explicit FScopedGCHandle(FGCHandleIntPtr InHandle) : Handle(InHandle) {}
 | |
| 
 | |
|     FScopedGCHandle(const FScopedGCHandle&) = delete;
 | |
|     FScopedGCHandle(FScopedGCHandle&&) = delete;
 | |
| 
 | |
|     ~FScopedGCHandle()
 | |
|     {
 | |
|         if (Handle.IntPtr != nullptr) 
 | |
|         {
 | |
|             FCSManagedCallbacks::ManagedCallbacks.FreeHandle(Handle);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     FScopedGCHandle& operator=(const FScopedGCHandle&) = delete;
 | |
|     FScopedGCHandle& operator=(FScopedGCHandle&&) = delete;
 | |
| };
 | |
| 
 | |
| USTRUCT()
 | |
| struct FSharedGCHandle
 | |
| {
 | |
|     GENERATED_BODY()
 | |
| 
 | |
|     FSharedGCHandle() = default;
 | |
|     explicit FSharedGCHandle(FGCHandleIntPtr InHandle) : Handle(MakeShared<FScopedGCHandle>(InHandle)) {}
 | |
| 
 | |
|     FGCHandleIntPtr GetHandle() const
 | |
|     {
 | |
|         if (Handle == nullptr) 
 | |
|         {
 | |
|             return FGCHandleIntPtr();
 | |
|         }
 | |
|         
 | |
|         return Handle->Handle;
 | |
|     }
 | |
|     
 | |
| private:
 | |
|     TSharedPtr<FScopedGCHandle> Handle;
 | |
| }; |