[CGLContext] Subclass NativeObject + numerous other code updates (#13154)

* Subclass NativeObject to reuse object lifetime code.
* Enable nullability and fix code accordingly.
* Use the null-safe NativeObjectExtensions.GetHandle extension method to get
  the handle instead of checking for null (avoids some code duplication).
* Call 'GetCheckedHandle ()' (which will throw an ObjectDisposedException if
  Handle == IntPtr.Zero) instead of manually checking for IntPtr.Zero and
  throwing ObjectDisposedException.
* Use the 'Runtime.GetNSObject<T> (IntPtr, bool)' overload to specify handle
  ownership, to avoid having to call NSObject.DangerousReleaes manually later.
* Remove the (IntPtr) constructor for NET.
This commit is contained in:
Rolf Bjarne Kvinge 2021-10-29 16:03:15 +02:00 коммит произвёл GitHub
Родитель 23881c9f80
Коммит 635e115127
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 22 добавлений и 42 удалений

Просмотреть файл

@ -25,9 +25,12 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#nullable enable
using System;
using System.Runtime.InteropServices;
using CoreFoundation;
using ObjCRuntime;
using Foundation;
using System.Runtime.Versioning;
@ -41,72 +44,49 @@ namespace OpenGL {
[Obsolete ("Starting with macos10.14 Use 'Metal' Framework instead.", DiagnosticId = "BI1234", UrlFormat = "https://github.com/xamarin/xamarin-macios/wiki/Obsolete")]
#endif
#endif
public class CGLContext : INativeObject, IDisposable {
IntPtr handle;
public class CGLContext : NativeObject {
#if !COREBUILD
#if !NET
public CGLContext (IntPtr handle)
{
if (handle == IntPtr.Zero)
throw new Exception ("Invalid parameters to context creation");
CGLRetainContext (handle);
this.handle = handle;
}
internal CGLContext ()
: base (handle, false, verify: true)
{
}
#endif
[Preserve (Conditional=true)]
internal CGLContext (IntPtr handle, bool owns)
: base (handle, owns, true)
{
if (!owns)
CGLRetainContext (handle);
this.handle = handle;
}
~CGLContext ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
public IntPtr Handle {
get { return handle; }
}
[DllImport (Constants.OpenGLLibrary)]
extern static void CGLRetainContext (IntPtr handle);
[DllImport (Constants.OpenGLLibrary)]
extern static void CGLReleaseContext (IntPtr handle);
protected virtual void Dispose (bool disposing)
protected override void Retain ()
{
if (handle != IntPtr.Zero){
CGLReleaseContext (handle);
handle = IntPtr.Zero;
}
CGLRetainContext (GetCheckedHandle ());
}
protected override void Release ()
{
CGLReleaseContext (GetCheckedHandle ());
}
[DllImport (Constants.OpenGLLibrary)]
extern static CGLErrorCode CGLLockContext (IntPtr ctx);
public CGLErrorCode Lock ()
{
return CGLLockContext (this.handle);
return CGLLockContext (Handle);
}
[DllImport (Constants.OpenGLLibrary)]
extern static CGLErrorCode CGLUnlockContext (IntPtr ctx);
public CGLErrorCode Unlock ()
{
return CGLUnlockContext (this.handle);
return CGLUnlockContext (Handle);
}
[DllImport (Constants.OpenGLLibrary)]
@ -115,21 +95,21 @@ namespace OpenGL {
[DllImport (Constants.OpenGLLibrary)]
extern static IntPtr CGLGetCurrentContext ();
public static CGLContext CurrentContext {
public static CGLContext? CurrentContext {
get {
IntPtr ctx = CGLGetCurrentContext ();
if (ctx != IntPtr.Zero)
return new CGLContext (ctx);
return new CGLContext (ctx, false);
else
return null;
}
set {
CGLErrorCode retValue = CGLSetCurrentContext (value?.Handle ?? IntPtr.Zero);
var retValue = CGLSetCurrentContext (value.GetHandle ());
if (retValue != CGLErrorCode.NoError)
throw new Exception ("Error setting the Current Context");
}
}
#endif // !COREBUILD
}
}