Skip to content

Commit

Permalink
feat: Add PredefinedTypeAttribute & CppTypeSystem
Browse files Browse the repository at this point in the history
  • Loading branch information
Pd233 committed Oct 21, 2023
1 parent ca1adf2 commit a793e7c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 20 deletions.
12 changes: 12 additions & 0 deletions src/Generation/PredefinedTypeAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hosihikari.NativeInterop.Generation;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class PredefinedTypeAttribute : Attribute
{
}
54 changes: 54 additions & 0 deletions src/Unmanaged/CppTypeSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Hosihikari.NativeInterop.Unmanaged.Attributes;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Hosihikari.NativeInterop.Unmanaged;

public static class CppTypeSystem
{
public static unsafe void* GetVTable(void* ptr) => (void*)Unsafe.Read<long>(ptr);

public static unsafe TVtable* GetVTable<TVtable>(void* ptr)
where TVtable : unmanaged, ICppVtable
=> (TVtable*)GetVTable(ptr);

public static unsafe TVtable* GetVTable<T, TVtable>(nint ptr, bool cheekAttribute = true)
where T : class, ICppInstance<T>
where TVtable : unmanaged, ICppVtable
{
if (cheekAttribute && typeof(T).GetCustomAttribute<VirtualCppClassAttribute>() is not null)
return GetVTable<TVtable>((void*)ptr);

throw new InvalidOperationException("\'VirtualCppClassAttribute\' instance is null.");
}

public static unsafe ValuePointer<TVtable> GetVTable<T, TVtable>(Pointer<T> ptr, bool cheekAttribute = true)
where T : class, ICppInstance<T>
where TVtable : unmanaged, ICppVtable
=> GetVTable<T, TVtable>(ptr, cheekAttribute);

public static unsafe ref TVtable GetVTable<T, TVtable>(T obj, bool cheekAttribute = true)
where T : class, ICppInstance<T>
where TVtable : unmanaged, ICppVtable
=> ref *GetVTable<T, TVtable>(obj.Pointer, cheekAttribute);
}

public static class CppTypeSystemUtils
{
public static T As<T>(this ICppInstanceNonGeneric @this, bool releaseSrc = false)
where T : class, IDisposable, ICppInstance<T>
{
if (releaseSrc)
{
T temp = T.ConstructInstance(@this.Pointer, @this.IsOwner, @this.IsTempStackValue);
@this.Pointer = 0;
@this.IsOwner = false;
@this.IsTempStackValue = false;

@this.Dispose();

return temp;
}
return T.ConstructInstance(@this.Pointer, false, true);
}
}
20 changes: 0 additions & 20 deletions src/Unmanaged/ICppInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,3 @@ public interface ICppInstance<TSelf> : ICppInstanceNonGeneric
/// <param name="ins"></param>
public static unsafe abstract implicit operator void*(TSelf ins);
}

public static class Utils
{
public static T As<T>(this ICppInstanceNonGeneric @this, bool releaseSrc = false)
where T : class, IDisposable, ICppInstance<T>
{
if (releaseSrc)
{
T temp = T.ConstructInstance(@this.Pointer, @this.IsOwner, @this.IsTempStackValue);
@this.Pointer = 0;
@this.IsOwner = false;
@this.IsTempStackValue = false;

@this.Dispose();

return temp;
}
return T.ConstructInstance(@this.Pointer, false, true);
}
}
9 changes: 9 additions & 0 deletions src/Unmanaged/ValuePointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ namespace Hosihikari.NativeInterop.Unmanaged;

public readonly ref T Target => ref Unsafe.AsRef<T>(_ptr.ToPointer());

public readonly T* Pointer => (T*)_ptr;


private ValuePointer(nint ptr) => _ptr = ptr;

public ValuePointer(T* ptr) => _ptr = (nint)ptr;

public static explicit operator ValuePointer<T>(nint ptr) => new(ptr);

public static implicit operator nint(ValuePointer<T> ptr) => ptr._ptr;

public static implicit operator ValuePointer<T>(T* ptr) => new(ptr);

public static implicit operator T*(ValuePointer<T> ptr) => ptr.Pointer;
}

0 comments on commit a793e7c

Please sign in to comment.