using System; using System.Collections.Generic; namespace TEngine { /// /// 通过LogicSys来驱动且具备Unity完整生命周期的单例(不继承MonoBehaviour)。 /// Update、FixUpdate以及LateUpdate这些敏感帧更新需要加上对应的Attribute以最优化性能。 /// /// 完整生命周期的类型。 public abstract class BehaviourSingleton : BaseBehaviourSingleton where T : BaseBehaviourSingleton, new() { private static T _instance; public static T Instance { get { if (null == _instance) { _instance = new T(); Log.Assert(_instance != null); _instance.Awake(); RegSingleton(_instance); } return _instance; } } private static void RegSingleton(BaseBehaviourSingleton inst) { BehaviourSingleSystem.Instance.RegSingleton(inst); } } #region Attribute /// /// 帧更新属性。 /// 适用于BehaviourSingleton。 /// [AttributeUsage(AttributeTargets.Class)] public class UpdateAttribute : Attribute { } /// /// 物理帧更新属性。 /// 适用于BehaviourSingleton。 /// [AttributeUsage(AttributeTargets.Class)] public class FixedUpdateAttribute : Attribute { } /// /// 后帧更新属性。 /// 适用于BehaviourSingleton。 /// [AttributeUsage(AttributeTargets.Class)] public class LateUpdateAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class)] public class RoleLoginAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class)] public class RoleLogoutAttribute : Attribute { } #endregion /// /// 基础Behaviour单例。 /// (抽象类) /// public abstract class BaseBehaviourSingleton { /// /// 是否已经Start。 /// public bool IsStart = false; public virtual void Awake() { } public virtual void Start() { } /// /// 帧更新。 /// 需要UpdateAttribute。 /// public virtual void Update() { } /// /// 后帧更新。 /// 需要LateUpdateAttribute。 /// public virtual void LateUpdate() { } /// /// 物理帧更新。 /// 需要FixedUpdateAttribute。 /// public virtual void FixedUpdate() { } public virtual void Destroy() { } public virtual void OnPause() { } public virtual void OnResume() { } public virtual void OnDrawGizmos() { } } /// /// 通过LogicSys来驱动且具备Unity完整生命周期的驱动系统(不继承MonoBehaviour)。 /// public sealed class BehaviourSingleSystem : BaseLogicSys { private readonly List _listInst = new List(); private readonly List _listStart = new List(); private readonly List _listUpdate = new List(); private readonly List _listLateUpdate = new List(); private readonly List _listFixedUpdate = new List(); /// /// 注册单例。 /// 调用Instance时自动调用。 /// /// 单例实例。 internal void RegSingleton(BaseBehaviourSingleton inst) { Log.Assert(!_listInst.Contains(inst)); _listInst.Add(inst); _listStart.Add(inst); if (HadAttribute(inst.GetType())) { _listUpdate.Add(inst); } if (HadAttribute(inst.GetType())) { _listLateUpdate.Add(inst); } if (HadAttribute(inst.GetType())) { _listFixedUpdate.Add(inst); } } public void UnRegSingleton(BaseBehaviourSingleton inst) { if (inst == null) { Log.Error($"BaseBehaviourSingleton Is Null"); return; } Log.Assert(_listInst.Contains(inst)); if (_listInst.Contains(inst)) { _listInst.Remove(inst); } if (_listStart.Contains(inst)) { _listStart.Remove(inst); } if (_listUpdate.Contains(inst)) { _listUpdate.Remove(inst); } if (_listLateUpdate.Contains(inst)) { _listLateUpdate.Remove(inst); } inst.Destroy(); inst = null; } public override void OnUpdate() { var listStart = _listStart; var listToUpdate = _listUpdate; int count = listStart.Count; if (count > 0) { for (int i = 0; i < count; i++) { var inst = listStart[i]; Log.Assert(!inst.IsStart); inst.IsStart = true; inst.Start(); } listStart.Clear(); } var listUpdateCnt = listToUpdate.Count; for (int i = 0; i < listUpdateCnt; i++) { var inst = listToUpdate[i]; TProfiler.BeginFirstSample(inst.GetType().FullName); inst.Update(); TProfiler.EndFirstSample(); } } public override void OnLateUpdate() { var listLateUpdate = _listLateUpdate; var listLateUpdateCnt = listLateUpdate.Count; for (int i = 0; i < listLateUpdateCnt; i++) { var inst = listLateUpdate[i]; TProfiler.BeginFirstSample(inst.GetType().FullName); inst.LateUpdate(); TProfiler.EndFirstSample(); } } public override void OnFixedUpdate() { var listFixedUpdate = _listFixedUpdate; var listFixedUpdateCnt = listFixedUpdate.Count; for (int i = 0; i < listFixedUpdateCnt; i++) { var inst = listFixedUpdate[i]; TProfiler.BeginFirstSample(inst.GetType().FullName); inst.FixedUpdate(); TProfiler.EndFirstSample(); } } public override void OnDestroy() { int count = _listInst.Count; for (int i = 0; i < count; i++) { var inst = _listInst[i]; inst.Destroy(); } } public override void OnApplicationPause(bool pause) { int count = _listInst.Count; for (int i = 0; i < count; i++) { var inst = _listInst[i]; if (pause) { inst.OnPause(); } else { inst.OnResume(); } } } public override void OnDrawGizmos() { int count = _listInst.Count; for (int i = 0; i < count; i++) { var inst = _listInst[i]; inst.OnDrawGizmos(); } } private bool HadAttribute(Type type) where T : Attribute { T attribute = Attribute.GetCustomAttribute(type, typeof(T)) as T; return attribute != null; } } }