Files
stgsharp/源代码/StgSharp/Graphics/GL/GLhandle.cs
T

158 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace System
{
/// <summary>
/// A handle to an OpenGL object,
/// must be indexed from a <see cref="glHandleSet"/>.
/// Direct call will cause <see langword="InvalidOperationException"/>
/// </summary>
public unsafe struct glHandle
{
internal uint* valuePtr;
internal glHandleSet source;
public glHandle()
{
throw new InvalidOperationException();
}
public static glHandle Alloc(uint value)
{
glHandle ret = default;
ret.source = new glHandleSet(1);
*ret.valuePtr = value;
return ret;
}
internal glHandle(uint* val, glHandleSet set)
{
source = set;
valuePtr = val;
}
public IntPtr Handle
{
get
{
if (source.handle == (uint*)0)
{
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
}
return (IntPtr)valuePtr;
}
}
public uint Value
{
get
{
if (source.handle == (uint*)0)
{
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
}
return *valuePtr;
}
set
{
if (source.handle == (uint*)0)
{
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
}
*valuePtr = value;
}
}
}
/// <summary>
/// A handle to an OpenGL object.
/// </summary>
public unsafe class glHandleSet
{
private readonly uint[] _value;
internal int length;
internal uint* handle;
public glHandle this[int index]
{
get
{
if (index > length)
{
throw new IndexOutOfRangeException();
}
return new glHandle(handle + index, this);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetValue(int index, uint value)
{
_value[index] = value;
}
public glHandleSet(int count)
{
_value = new uint[count];
length = count;
handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject();
}
/// <summary>
/// temporarily release the handle of GLhandle sets.
/// Please call <see cref="Pin"/> method before indexing.
/// </summary>
public void Free()
{
if (_value == null)
{
return;
}
GCHandle h = GCHandle.FromIntPtr((IntPtr)handle);
h.Free();
handle = (uint*)0;
}
public void Pin()
{
if (_value == null)
{
return;
}
handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject();
}
/// <summary>
/// Realse all resource in this handle.
/// This will release all resource in this <see cref="glHandle"/>.
/// This <see langword="glHandle"/> will be not usable.
/// </summary>
public void Release()
{
if (_value == null)
{
return;
}
else
{
GCHandle.FromIntPtr((IntPtr)handle).Free();
handle = (uint*)IntPtr.Zero;
}
}
}
}