AtomicEngine.cs 5.9 KB

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