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;
							 | 
						|||
| 
								 | 
							
								};
							 |