MyClass.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. namespace Atomic
  5. {
  6. public static class AtomicSharp
  7. {
  8. [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
  9. private static extern int atomicsharp_initialize ();
  10. [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
  11. private static extern bool atomicsharp_runframe ();
  12. public static bool RunFrame()
  13. {
  14. GC.Collect();
  15. GC.WaitForPendingFinalizers();
  16. GC.Collect();
  17. NativeCore.ReleaseExpiredNativeReferences ();
  18. return atomicsharp_runframe ();
  19. }
  20. public static void Initialize()
  21. {
  22. ContainerModule.Initialize ();
  23. CoreModule.Initialize ();
  24. IOModule.Initialize ();
  25. ResourceModule.Initialize ();
  26. GraphicsModule.Initialize ();
  27. SceneModule.Initialize ();
  28. AtomicPlayer.PlayerModule.Initialize ();
  29. atomicsharp_initialize ();
  30. }
  31. }
  32. public static partial class Constants
  33. {
  34. public const string LIBNAME = "/Users/josh/Dev/atomic/AtomicGameEngineSharp-build/Source/AtomicSharp/AtomicSharp";
  35. }
  36. public partial class RefCounted
  37. {
  38. protected RefCounted (IntPtr native)
  39. {
  40. nativeInstance = native;
  41. }
  42. public IntPtr nativeInstance;
  43. static public void _AddRef(IntPtr native)
  44. {
  45. csb_Atomic_RefCounted_AddRef(native);
  46. }
  47. static public void _ReleaseRef(IntPtr native)
  48. {
  49. csb_Atomic_RefCounted_ReleaseRef(native);
  50. }
  51. [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
  52. public static extern IntPtr csb_RefCounted_GetClassID (IntPtr self);
  53. }
  54. static class NativeCore
  55. {
  56. // given an existing instance classID, construct the managed instance, with downcast support (ask for Component, get StaticModel for example)
  57. public static Dictionary<IntPtr, Func<IntPtr, RefCounted>> nativeClassIDToManagedConstructor = new Dictionary<IntPtr, Func<IntPtr, RefCounted>>();
  58. public static Dictionary<IntPtr, WeakReference> nativeLookup = new Dictionary<IntPtr, WeakReference> ();
  59. public static IntPtr RegisterNative (IntPtr native, RefCounted r)
  60. {
  61. var w = new WeakReference (r);
  62. NativeCore.nativeLookup [native] = w;
  63. RefCounted._AddRef (native);
  64. return native;
  65. }
  66. public static void ReleaseExpiredNativeReferences()
  67. {
  68. List<IntPtr> released = new List<IntPtr> ();
  69. foreach(KeyValuePair<IntPtr, WeakReference> entry in nativeLookup)
  70. {
  71. if (entry.Value.Target == null || !entry.Value.IsAlive) {
  72. released.Add (entry.Key);
  73. } else {
  74. }
  75. }
  76. foreach (IntPtr native in released) {
  77. RefCounted._ReleaseRef(native);
  78. nativeLookup.Remove (native);
  79. }
  80. }
  81. // wraps an existing native instance, with downcast support
  82. public static T WrapNative<T> (IntPtr native) where T:RefCounted
  83. {
  84. if (native == IntPtr.Zero)
  85. return null;
  86. WeakReference w;
  87. // first see if we're already available
  88. if (nativeLookup.TryGetValue (native, out w)) {
  89. if (w.IsAlive) {
  90. // we're alive!
  91. return (T)w.Target;
  92. } else {
  93. // we were seen before, but have since been GC'd, remove!
  94. nativeLookup.Remove (native);
  95. }
  96. }
  97. IntPtr classID = RefCounted.csb_RefCounted_GetClassID (native);
  98. // and store, with downcast support for instance Component -> StaticModel
  99. w = new WeakReference (nativeClassIDToManagedConstructor[classID](native));
  100. NativeCore.nativeLookup [native] = w;
  101. // store a ref, so native side will not be released while we still have a reference in managed code
  102. RefCounted._AddRef (native);
  103. return (T) w.Target;
  104. }
  105. }
  106. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  107. public struct Vector3
  108. {
  109. public Vector3 (float x, float y, float z)
  110. {
  111. this.x = x;
  112. this.y = y;
  113. this.z = z;
  114. }
  115. public override string ToString()
  116. {
  117. return x + ", " + y + ", " + z;
  118. }
  119. public float x;
  120. public float y;
  121. public float z;
  122. }
  123. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  124. public struct Vector4
  125. {
  126. }
  127. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  128. public struct Vector2
  129. {
  130. }
  131. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  132. public struct Quaternion
  133. {
  134. }
  135. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  136. public struct Color
  137. {
  138. }
  139. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  140. public struct IntRect
  141. {
  142. }
  143. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  144. public struct IntVector2
  145. {
  146. }
  147. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  148. public struct BoundingBox
  149. {
  150. }
  151. [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  152. public struct Rect
  153. {
  154. }
  155. }