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