Guest User

Untitled

a guest
Nov 23rd, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.26 KB | None | 0 0
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using UnityEngine;
  4.  
  5. namespace Lacuna
  6. {
  7. public enum UpdateMode
  8. {
  9. Timed,
  10. FixedUpdate,
  11. Update,
  12. LateUpdate
  13. }
  14.  
  15. public interface IFixedUpdate
  16. {
  17. void OnFixedUpdate();
  18. }
  19.  
  20. public interface IUpdate
  21. {
  22. void OnUpdate();
  23. }
  24.  
  25. public interface ILateUpdate
  26. {
  27. void OnLateUpdate();
  28. }
  29.  
  30. public unsafe class MainEventManager : MonoBehaviour
  31. {
  32. private struct TickedAction
  33. {
  34. public readonly ushort suid;
  35. public readonly Action action;
  36.  
  37. public TickedAction(ushort suid, Action action)
  38. {
  39. this.suid = suid;
  40. this.action = action;
  41. }
  42. }
  43.  
  44. private struct TimedAction
  45. {
  46. public readonly ushort suid;
  47. private readonly float _timer;
  48. private float _timerAct;
  49. private readonly Action _action;
  50.  
  51. public TimedAction(ushort suid, float timer, Action action)
  52. {
  53. this.suid = suid;
  54. _timer = _timerAct = timer;
  55. _action = action;
  56. }
  57.  
  58. [MethodImpl(256)]
  59. public void Tick()
  60. {
  61. if ((_timerAct -= Time.deltaTime) > 0)
  62. return;
  63. _timerAct = _timer;
  64. _action();
  65. }
  66. }
  67.  
  68. private const int LIM_SUID_STRUCTURE = 8191; //Clip last to dodge unchecked
  69. private static readonly long[] _suids = new long[LIM_SUID_STRUCTURE];
  70.  
  71. private static ushort GetSUID()
  72. {
  73. fixed (long* l_ptr = _suids)
  74. {
  75. long* l_ptrAct = l_ptr;
  76. for (int i = 0; i < LIM_SUID_STRUCTURE; i++)
  77. {
  78. for (int x = 0; x < sizeof(long); x++)
  79. {
  80. if (((*l_ptrAct >> x) & 1) == 1)
  81. continue;
  82. *l_ptrAct |= 1 << x;
  83. return (ushort) ((i * 8) + x);
  84. }
  85. l_ptrAct++;
  86. }
  87. throw new Exception("Reached SUID limit");
  88. }
  89. }
  90.  
  91. private static void FreeSUID(ushort suid)
  92. {
  93. _suids[suid / 8] &= ~(1 << (suid % 8));
  94. }
  95.  
  96. //No collection class usage to negate possibility of accessor non-inlining
  97.  
  98. private const int EXPAND_COUNT = 25;
  99.  
  100. private static IFixedUpdate _fixedUpdateRef;
  101. private static IFixedUpdate[] _arrFu = new IFixedUpdate[EXPAND_COUNT];
  102. private static IUpdate _updateRef;
  103. private static IUpdate[] _arrU = new IUpdate[EXPAND_COUNT];
  104. private static ILateUpdate _lateUpdateRef;
  105. private static ILateUpdate[] _arrLu = new ILateUpdate[EXPAND_COUNT];
  106. private static TimedAction[] _ticksTimed = new TimedAction[EXPAND_COUNT];
  107.  
  108. private static TickedAction[] _ticksFU = new TickedAction[EXPAND_COUNT],
  109. _ticksU = new TickedAction[EXPAND_COUNT],
  110. _ticksLU = new TickedAction[EXPAND_COUNT];
  111.  
  112. private static int _limFu, _limU, _limLu, _limTicksTimed, _limTicksFU, _limTicksU, _limTicksLU;
  113.  
  114. #region MANAGEMENT
  115.  
  116. public static void RegisterBehaviour(object behaviour)
  117. {
  118. _fixedUpdateRef = behaviour as IFixedUpdate;
  119. if (_fixedUpdateRef != null)
  120. {
  121. if (++_limFu >= _arrFu.Length)
  122. {
  123. var tmp = new IFixedUpdate[_limFu + EXPAND_COUNT];
  124. for (int i = 0; i < _arrFu.Length; i++)
  125. tmp[i] = _arrFu[i];
  126. _arrFu = tmp;
  127. }
  128. _arrFu[_limFu - 1] = _fixedUpdateRef;
  129. }
  130. _updateRef = behaviour as IUpdate;
  131. if (_updateRef != null)
  132. {
  133. if (++_limU >= _arrU.Length)
  134. {
  135. var tmp = new IUpdate[_limU + EXPAND_COUNT];
  136. for (int i = 0; i < _arrU.Length; i++)
  137. tmp[i] = _arrU[i];
  138. _arrU = tmp;
  139. }
  140. _arrU[_limU - 1] = _updateRef;
  141. }
  142. _lateUpdateRef = behaviour as ILateUpdate;
  143. if (_lateUpdateRef == null)
  144. return;
  145. if (++_limLu >= _arrLu.Length)
  146. {
  147. var tmp = new ILateUpdate[_limLu + EXPAND_COUNT];
  148. for (int i = 0; i < _arrLu.Length; i++)
  149. tmp[i] = _arrLu[i];
  150. _arrLu = tmp;
  151. }
  152. _arrLu[_limLu - 1] = _lateUpdateRef;
  153. }
  154.  
  155. public static void KillBehaviour(object behaviour)
  156. {
  157. _fixedUpdateRef = behaviour as IFixedUpdate;
  158. if (_fixedUpdateRef != null)
  159. {
  160. for (int i = 0; i < _limFu; i++)
  161. {
  162. if (_arrFu[i] != _fixedUpdateRef)
  163. continue;
  164. if (i != _limFu - 1)
  165. {
  166. for (int x = i + 1; x < _limFu; x++)
  167. _arrFu[x - 1] = _arrFu[x];
  168. _limFu--;
  169. }
  170. break;
  171. }
  172. }
  173. _updateRef = behaviour as IUpdate;
  174. if (_updateRef != null)
  175. {
  176. for (int i = 0; i < _limU; i++)
  177. {
  178. if (_arrU[i] != _updateRef)
  179. continue;
  180. if (i != _limU - 1)
  181. {
  182. for (int x = i + 1; x < _limU; x++)
  183. _arrU[x - 1] = _arrU[x];
  184. _limU--;
  185. }
  186. break;
  187. }
  188. }
  189. _lateUpdateRef = behaviour as ILateUpdate;
  190. if (_lateUpdateRef == null)
  191. return;
  192. for (int i = 0; i < _limLu; i++)
  193. {
  194. if (_arrLu[i] != _lateUpdateRef)
  195. continue;
  196. if (i != _limLu - 1)
  197. {
  198. for (int x = i + 1; x < _limLu; x++)
  199. _arrLu[x - 1] = _arrLu[x];
  200. _limLu--;
  201. }
  202. break;
  203. }
  204. }
  205.  
  206. public static ushort RegisterTick(Action callback, float timer)
  207. {
  208. if(callback == null)
  209. throw new ArgumentException("Callback cannot be null");
  210. if (++_limTicksTimed >= _ticksTimed.Length)
  211. {
  212. TimedAction[] tmp = new TimedAction[_limTicksTimed + EXPAND_COUNT];
  213. for (int i = 0; i < _ticksTimed.Length; i++)
  214. tmp[i] = _ticksTimed[i];
  215. _ticksTimed = tmp;
  216. }
  217. ushort suid = GetSUID();
  218. _ticksTimed[_limTicksTimed - 1] = new TimedAction(suid, timer, callback);
  219. return suid;
  220. }
  221.  
  222. public static ushort RegisterTick(Action callback, UpdateMode updateMode)
  223. {
  224. if(callback == null)
  225. throw new ArgumentException("Callback cannot be null");
  226. ushort suid = GetSUID();
  227. switch (updateMode)
  228. {
  229. case(UpdateMode.FixedUpdate):
  230. if (++_limTicksFU > _ticksFU.Length)
  231. {
  232. TickedAction[] tmp = new TickedAction[_limTicksFU + EXPAND_COUNT];
  233. for (int i = 0; i < _ticksFU.Length; i++)
  234. tmp[i] = _ticksFU[i];
  235. _ticksFU = tmp;
  236. }
  237. _ticksFU[_limTicksFU - 1] = new TickedAction(suid, callback);
  238. break;
  239. case(UpdateMode.Update):
  240. if (++_limTicksU > _ticksU.Length)
  241. {
  242. TickedAction[] tmp = new TickedAction[_limTicksU + EXPAND_COUNT];
  243. for (int i = 0; i < _ticksU.Length; i++)
  244. tmp[i] = _ticksU[i];
  245. _ticksU = tmp;
  246. }
  247. _ticksU[_limTicksU - 1] = new TickedAction(suid, callback);
  248. break;
  249. case(UpdateMode.LateUpdate):
  250. if (++_limTicksLU > _ticksLU.Length)
  251. {
  252. TickedAction[] tmp = new TickedAction[_limTicksLU + EXPAND_COUNT];
  253. for (int i = 0; i < _ticksLU.Length; i++)
  254. tmp[i] = _ticksLU[i];
  255. _ticksLU = tmp;
  256. }
  257. _ticksLU[_limTicksLU - 1] = new TickedAction(suid, callback);
  258. break;
  259. }
  260. return suid;
  261. }
  262.  
  263. public static void KillTick(ushort suid)
  264. {
  265. for (int i = 0; i < _limTicksTimed; i++)
  266. {
  267. if (_ticksTimed[i].suid != suid)
  268. continue;
  269. if (i == _limTicksTimed - 1)
  270. {
  271. _limTicksTimed--;
  272. return;
  273. }
  274. for (int x = i + 1; x < _limTicksTimed; x++)
  275. _ticksTimed[x - 1] = _ticksTimed[x];
  276. return;
  277. }
  278. for (int i = 0; i < _limTicksFU; i++)
  279. {
  280. if (_ticksFU[i].suid != suid)
  281. continue;
  282. if (i == _limTicksFU - 1)
  283. {
  284. _limTicksFU--;
  285. return;
  286. }
  287. for (int x = i + 1; x < _limTicksFU; x++)
  288. _ticksFU[x - 1] = _ticksFU[x];
  289. return;
  290. }
  291. for (int i = 0; i < _limTicksU; i++)
  292. {
  293. if (_ticksU[i].suid != suid)
  294. continue;
  295. if (i == _limTicksU - 1)
  296. {
  297. _limTicksU--;
  298. return;
  299. }
  300. for (int x = i + 1; x < _limTicksU; x++)
  301. _ticksU[x - 1] = _ticksU[x];
  302. return;
  303. }
  304. for (int i = 0; i < _limTicksLU; i++)
  305. {
  306. if (_ticksLU[i].suid != suid)
  307. continue;
  308. if (i == _limTicksLU - 1)
  309. {
  310. _limTicksLU--;
  311. return;
  312. }
  313. for (int x = i + 1; x < _limTicksLU; x++)
  314. _ticksLU[x - 1] = _ticksLU[x];
  315. return;
  316. }
  317. }
  318.  
  319. #endregion
  320.  
  321. #region TICKING
  322.  
  323. private void Update()
  324. {
  325. for (int i = 0; i < _limU; i++)
  326. _arrU[i].OnUpdate();
  327. for (int i = 0; i < _limTicksTimed; i++)
  328. _ticksTimed[i].Tick();
  329. for (int i = 0; i < _limTicksU; i++)
  330. _ticksU[i].action();
  331. }
  332.  
  333. private void FixedUpdate()
  334. {
  335. for (int i = 0; i < _limFu; i++)
  336. _arrFu[i].OnFixedUpdate();
  337. for (int i = 0; i < _limTicksFU; i++)
  338. _ticksFU[i].action();
  339. }
  340.  
  341. private void LateUpdate()
  342. {
  343. for (int i = 0; i < _limLu; i++)
  344. _arrLu[i].OnLateUpdate();
  345. for (int i = 0; i < _limTicksLU; i++)
  346. _ticksLU[i].action();
  347. }
  348.  
  349. #endregion
  350. }
  351. }
Add Comment
Please, Sign In to add comment