Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Runtime.CompilerServices;
- using UnityEngine;
- namespace Lacuna
- {
- public enum UpdateMode
- {
- Timed,
- FixedUpdate,
- Update,
- LateUpdate
- }
- public interface IFixedUpdate
- {
- void OnFixedUpdate();
- }
- public interface IUpdate
- {
- void OnUpdate();
- }
- public interface ILateUpdate
- {
- void OnLateUpdate();
- }
- public unsafe class MainEventManager : MonoBehaviour
- {
- private struct TickedAction
- {
- public readonly ushort suid;
- public readonly Action action;
- public TickedAction(ushort suid, Action action)
- {
- this.suid = suid;
- this.action = action;
- }
- }
- private struct TimedAction
- {
- public readonly ushort suid;
- private readonly float _timer;
- private float _timerAct;
- private readonly Action _action;
- public TimedAction(ushort suid, float timer, Action action)
- {
- this.suid = suid;
- _timer = _timerAct = timer;
- _action = action;
- }
- [MethodImpl(256)]
- public void Tick()
- {
- if ((_timerAct -= Time.deltaTime) > 0)
- return;
- _timerAct = _timer;
- _action();
- }
- }
- private const int LIM_SUID_STRUCTURE = 8191; //Clip last to dodge unchecked
- private static readonly long[] _suids = new long[LIM_SUID_STRUCTURE];
- private static ushort GetSUID()
- {
- fixed (long* l_ptr = _suids)
- {
- long* l_ptrAct = l_ptr;
- for (int i = 0; i < LIM_SUID_STRUCTURE; i++)
- {
- for (int x = 0; x < sizeof(long); x++)
- {
- if (((*l_ptrAct >> x) & 1) == 1)
- continue;
- *l_ptrAct |= 1 << x;
- return (ushort) ((i * 8) + x);
- }
- l_ptrAct++;
- }
- throw new Exception("Reached SUID limit");
- }
- }
- private static void FreeSUID(ushort suid)
- {
- _suids[suid / 8] &= ~(1 << (suid % 8));
- }
- //No collection class usage to negate possibility of accessor non-inlining
- private const int EXPAND_COUNT = 25;
- private static IFixedUpdate _fixedUpdateRef;
- private static IFixedUpdate[] _arrFu = new IFixedUpdate[EXPAND_COUNT];
- private static IUpdate _updateRef;
- private static IUpdate[] _arrU = new IUpdate[EXPAND_COUNT];
- private static ILateUpdate _lateUpdateRef;
- private static ILateUpdate[] _arrLu = new ILateUpdate[EXPAND_COUNT];
- private static TimedAction[] _ticksTimed = new TimedAction[EXPAND_COUNT];
- private static TickedAction[] _ticksFU = new TickedAction[EXPAND_COUNT],
- _ticksU = new TickedAction[EXPAND_COUNT],
- _ticksLU = new TickedAction[EXPAND_COUNT];
- private static int _limFu, _limU, _limLu, _limTicksTimed, _limTicksFU, _limTicksU, _limTicksLU;
- #region MANAGEMENT
- public static void RegisterBehaviour(object behaviour)
- {
- _fixedUpdateRef = behaviour as IFixedUpdate;
- if (_fixedUpdateRef != null)
- {
- if (++_limFu >= _arrFu.Length)
- {
- var tmp = new IFixedUpdate[_limFu + EXPAND_COUNT];
- for (int i = 0; i < _arrFu.Length; i++)
- tmp[i] = _arrFu[i];
- _arrFu = tmp;
- }
- _arrFu[_limFu - 1] = _fixedUpdateRef;
- }
- _updateRef = behaviour as IUpdate;
- if (_updateRef != null)
- {
- if (++_limU >= _arrU.Length)
- {
- var tmp = new IUpdate[_limU + EXPAND_COUNT];
- for (int i = 0; i < _arrU.Length; i++)
- tmp[i] = _arrU[i];
- _arrU = tmp;
- }
- _arrU[_limU - 1] = _updateRef;
- }
- _lateUpdateRef = behaviour as ILateUpdate;
- if (_lateUpdateRef == null)
- return;
- if (++_limLu >= _arrLu.Length)
- {
- var tmp = new ILateUpdate[_limLu + EXPAND_COUNT];
- for (int i = 0; i < _arrLu.Length; i++)
- tmp[i] = _arrLu[i];
- _arrLu = tmp;
- }
- _arrLu[_limLu - 1] = _lateUpdateRef;
- }
- public static void KillBehaviour(object behaviour)
- {
- _fixedUpdateRef = behaviour as IFixedUpdate;
- if (_fixedUpdateRef != null)
- {
- for (int i = 0; i < _limFu; i++)
- {
- if (_arrFu[i] != _fixedUpdateRef)
- continue;
- if (i != _limFu - 1)
- {
- for (int x = i + 1; x < _limFu; x++)
- _arrFu[x - 1] = _arrFu[x];
- _limFu--;
- }
- break;
- }
- }
- _updateRef = behaviour as IUpdate;
- if (_updateRef != null)
- {
- for (int i = 0; i < _limU; i++)
- {
- if (_arrU[i] != _updateRef)
- continue;
- if (i != _limU - 1)
- {
- for (int x = i + 1; x < _limU; x++)
- _arrU[x - 1] = _arrU[x];
- _limU--;
- }
- break;
- }
- }
- _lateUpdateRef = behaviour as ILateUpdate;
- if (_lateUpdateRef == null)
- return;
- for (int i = 0; i < _limLu; i++)
- {
- if (_arrLu[i] != _lateUpdateRef)
- continue;
- if (i != _limLu - 1)
- {
- for (int x = i + 1; x < _limLu; x++)
- _arrLu[x - 1] = _arrLu[x];
- _limLu--;
- }
- break;
- }
- }
- public static ushort RegisterTick(Action callback, float timer)
- {
- if(callback == null)
- throw new ArgumentException("Callback cannot be null");
- if (++_limTicksTimed >= _ticksTimed.Length)
- {
- TimedAction[] tmp = new TimedAction[_limTicksTimed + EXPAND_COUNT];
- for (int i = 0; i < _ticksTimed.Length; i++)
- tmp[i] = _ticksTimed[i];
- _ticksTimed = tmp;
- }
- ushort suid = GetSUID();
- _ticksTimed[_limTicksTimed - 1] = new TimedAction(suid, timer, callback);
- return suid;
- }
- public static ushort RegisterTick(Action callback, UpdateMode updateMode)
- {
- if(callback == null)
- throw new ArgumentException("Callback cannot be null");
- ushort suid = GetSUID();
- switch (updateMode)
- {
- case(UpdateMode.FixedUpdate):
- if (++_limTicksFU > _ticksFU.Length)
- {
- TickedAction[] tmp = new TickedAction[_limTicksFU + EXPAND_COUNT];
- for (int i = 0; i < _ticksFU.Length; i++)
- tmp[i] = _ticksFU[i];
- _ticksFU = tmp;
- }
- _ticksFU[_limTicksFU - 1] = new TickedAction(suid, callback);
- break;
- case(UpdateMode.Update):
- if (++_limTicksU > _ticksU.Length)
- {
- TickedAction[] tmp = new TickedAction[_limTicksU + EXPAND_COUNT];
- for (int i = 0; i < _ticksU.Length; i++)
- tmp[i] = _ticksU[i];
- _ticksU = tmp;
- }
- _ticksU[_limTicksU - 1] = new TickedAction(suid, callback);
- break;
- case(UpdateMode.LateUpdate):
- if (++_limTicksLU > _ticksLU.Length)
- {
- TickedAction[] tmp = new TickedAction[_limTicksLU + EXPAND_COUNT];
- for (int i = 0; i < _ticksLU.Length; i++)
- tmp[i] = _ticksLU[i];
- _ticksLU = tmp;
- }
- _ticksLU[_limTicksLU - 1] = new TickedAction(suid, callback);
- break;
- }
- return suid;
- }
- public static void KillTick(ushort suid)
- {
- for (int i = 0; i < _limTicksTimed; i++)
- {
- if (_ticksTimed[i].suid != suid)
- continue;
- if (i == _limTicksTimed - 1)
- {
- _limTicksTimed--;
- return;
- }
- for (int x = i + 1; x < _limTicksTimed; x++)
- _ticksTimed[x - 1] = _ticksTimed[x];
- return;
- }
- for (int i = 0; i < _limTicksFU; i++)
- {
- if (_ticksFU[i].suid != suid)
- continue;
- if (i == _limTicksFU - 1)
- {
- _limTicksFU--;
- return;
- }
- for (int x = i + 1; x < _limTicksFU; x++)
- _ticksFU[x - 1] = _ticksFU[x];
- return;
- }
- for (int i = 0; i < _limTicksU; i++)
- {
- if (_ticksU[i].suid != suid)
- continue;
- if (i == _limTicksU - 1)
- {
- _limTicksU--;
- return;
- }
- for (int x = i + 1; x < _limTicksU; x++)
- _ticksU[x - 1] = _ticksU[x];
- return;
- }
- for (int i = 0; i < _limTicksLU; i++)
- {
- if (_ticksLU[i].suid != suid)
- continue;
- if (i == _limTicksLU - 1)
- {
- _limTicksLU--;
- return;
- }
- for (int x = i + 1; x < _limTicksLU; x++)
- _ticksLU[x - 1] = _ticksLU[x];
- return;
- }
- }
- #endregion
- #region TICKING
- private void Update()
- {
- for (int i = 0; i < _limU; i++)
- _arrU[i].OnUpdate();
- for (int i = 0; i < _limTicksTimed; i++)
- _ticksTimed[i].Tick();
- for (int i = 0; i < _limTicksU; i++)
- _ticksU[i].action();
- }
- private void FixedUpdate()
- {
- for (int i = 0; i < _limFu; i++)
- _arrFu[i].OnFixedUpdate();
- for (int i = 0; i < _limTicksFU; i++)
- _ticksFU[i].action();
- }
- private void LateUpdate()
- {
- for (int i = 0; i < _limLu; i++)
- _arrLu[i].OnLateUpdate();
- for (int i = 0; i < _limTicksLU; i++)
- _ticksLU[i].action();
- }
- #endregion
- }
- }
Add Comment
Please, Sign In to add comment