| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- //
- // TODO: optimization, remove the static initializer, so we do not need to add code
- // at JIT/AOT time to probe for static class initialization
- //
- using System;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- namespace Urho {
- public partial class RefCounted : IDisposable {
- internal IntPtr handle;
- public IntPtr Handle => handle;
- internal RefCounted (UrhoObjectFlag empty) { }
-
- protected RefCounted (IntPtr handle)
- {
- if (handle == IntPtr.Zero)
- throw new ArgumentException ($"Attempted to instantiate a {GetType()} with a null handle");
- this.handle = handle;
- Runtime.RegisterObject (this);
- }
-
- public void Dispose ()
- {
- DeleteNativeObject();
- Dispose (true);
- GC.SuppressFinalize (this);
- }
- /// <summary>
- /// Called by RefCounted::~RefCounted - we don't need to check Refs here - just mark it as deleted and remove from cache
- /// </summary>
- internal void HandleNativeDelete()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- [DllImport(Consts.NativeImport, CallingConvention = CallingConvention.Cdecl)]
- static extern void TryDeleteRefCounted(IntPtr handle);
- /// <summary>
- /// Try to delete underlying native object if nobody uses it (Refs==0)
- /// </summary>
- void DeleteNativeObject()
- {
- if (!IsDeleted)
- {
- try
- {
- TryDeleteRefCounted(handle);
- }
- catch (Exception exc)
- {
- //should not happen, JIC.
- throw new InvalidOperationException("Underlying native object is already deleted", exc);
- }
- }
- }
- protected virtual void Dispose (bool disposing)
- {
- if (IsDeleted)
- return;
-
- if (disposing)
- {
- IsDeleted = true;
- OnDeleted();
- }
- Runtime.UnregisterObject(handle);
- }
- [Conditional("DEBUG")]
- protected void CheckAccess()
- {
- if (IsDeleted)
- throw new InvalidOperationException("The underlying native object was deleted");
- if (handle == IntPtr.Zero)
- throw new InvalidOperationException("Object has zero handle");
-
- //TODO: check thread
- }
- protected void CheckEngine()
- {
- UrhoPlatformInitializer.DefaultInit();
- }
- /// <summary>
- /// True if underlying native object is deleted
- /// </summary>
- public bool IsDeleted { get; private set; }
- protected virtual void OnDeleted() { }
- public override bool Equals (object other)
- {
- if (other == null)
- return false;
- if (other.GetType () != GetType ())
- return false;
- var or = other as RefCounted;
- if (or != null && or.handle == handle)
- return true;
- return false;
- }
- public static bool operator ==(RefCounted _a, RefCounted _b)
- {
- object a = _a;
- object b = _b;
- if (a == null){
- if (b == null)
- return true;
- return false;
- } else {
- if (b == null)
- return false;
- return _a.handle == _b.handle;
- }
- }
-
- public static bool operator !=(RefCounted _a, RefCounted _b)
- {
- object a = _a;
- object b = _b;
- if (a == null)
- return b != null;
- else {
- if (b == null)
- return true;
- return _a.handle != _b.handle;
- }
- }
- public override int GetHashCode ()
- {
- if (IntPtr.Size == 8) //means 64bit
- return unchecked ((int) (long) handle);
- return (int) handle;
- }
- ~RefCounted ()
- {
- DeleteNativeObject();
- Dispose (false);
- }
- }
- }
|