using System; using System.Collections.Generic; using UnityEngine; namespace TEngine { #region Architecture abstract class Architecture : ILogicSys, IArchitecture where T : Architecture, new() { private bool _init; private readonly List _systems = new List(); private readonly List _models = new List(); public static readonly Action OnRegisterPatch = architecture => { }; private static T _architecture; #region AttributeList private List _updateSystems; private List _lateUpdateSystems; private List _fixedUpdateSystems; private List _roleLoginSystems; private List _roleLogoutSystems; #endregion public static IArchitecture Interface { get { if (_architecture == null) { MakeSureArchitecture(); } return _architecture; } } public static T Instance { get { if (_architecture == null) { MakeSureArchitecture(); } return _architecture; } } static void MakeSureArchitecture() { if (_architecture == null) { _architecture = new T(); _architecture.Init(); if (OnRegisterPatch != null) { OnRegisterPatch.Invoke(_architecture); } foreach (var architectureModel in _architecture._models) { architectureModel.Init(); } _architecture._models.Clear(); foreach (var architectureSystem in _architecture._systems) { architectureSystem.Init(); } _architecture._systems.Clear(); _architecture._init = true; } } protected abstract void Init(); private readonly Container _container = new Container(); public void RegisterSystem(TSystem system) where TSystem : ISystem { system.SetArchitecture(this); _container.Register(system); if (!_init) { ProcessAttribute(system); _systems.Add(system); } else { system.Init(); } } public void ProcessAttribute(TSystem system) where TSystem : ISystem { Type systemType = system.GetType(); SubSystem instance = system as SubSystem; if (HadAttribute(systemType)) { if (_updateSystems == null) { _updateSystems = new List(); } _updateSystems.Add(instance); } if (HadAttribute(systemType)) { if (_lateUpdateSystems == null) { _lateUpdateSystems = new List(); } _lateUpdateSystems.Add(instance); } if (HadAttribute(systemType)) { if (_fixedUpdateSystems == null) { _fixedUpdateSystems = new List(); } _fixedUpdateSystems.Add(instance); } if (HadAttribute(systemType)) { if (_roleLoginSystems == null) { _roleLoginSystems = new List(); } _roleLoginSystems.Add(instance); } if (HadAttribute(systemType)) { if (_roleLogoutSystems == null) { _roleLogoutSystems = new List(); } _roleLogoutSystems.Add(instance); } } private bool HadAttribute(Type type) where TAttribute : Attribute { TAttribute attribute = Attribute.GetCustomAttribute(type, typeof(TAttribute)) as TAttribute; return attribute != null; } public void RegisterModel(TModel model) where TModel : IModel { model.SetArchitecture(this); _container.Register(model); if (!_init) { _models.Add(model); } else { model.Init(); } } public void RegisterUtility(TUtility utility) where TUtility : IUtility { _container.Register(utility); } public TSystem GetSystem() where TSystem : class, ISystem { return _container.Get(); } public TModel GetModel() where TModel : class, IModel { return _container.Get(); } public TUtility GetUtility() where TUtility : class, IUtility { return _container.Get(); } public void SendCommand() where TCommand : ICommand, new() { var command = new TCommand(); command.SetArchitecture(this); command.Execute(); } public void SendCommand(TCommand command) where TCommand : ICommand { command.SetArchitecture(this); command.Execute(); } public TResult SendQuery(IQuery query) { query.SetArchitecture(this); return query.Do(); } private readonly TypeEventSystem _typeEventSystem = new TypeEventSystem(); public void SendEvent() where TEvent : new() { _typeEventSystem.Send(); } public void SendEvent(TEvent e) { _typeEventSystem.Send(e); } public IUnRegister RegisterEvent(Action onEvent) { return _typeEventSystem.Register(onEvent); } public void UnRegisterEvent(Action onEvent) { _typeEventSystem.UnRegister(onEvent); } #region 生命周期 public virtual void OnActive() { } public virtual bool OnInit() { return true; } public virtual void OnDestroy() { } public virtual void OnStart() { } public virtual void OnUpdate() { if (_updateSystems != null) { foreach (var system in _updateSystems) { system.OnUpdate(); } } } public virtual void OnLateUpdate() { if (_lateUpdateSystems != null) { foreach (var system in _lateUpdateSystems) { system.OnLateUpdate(); } } } public virtual void OnFixedUpdate() { if (_fixedUpdateSystems != null) { foreach (var system in _fixedUpdateSystems) { system.OnLateUpdate(); } } } public virtual void OnRoleLogin() { if (_roleLoginSystems != null) { foreach (var system in _roleLoginSystems) { system.OnRoleLogin(); } } } public virtual void OnRoleLogout() { if (_roleLogoutSystems != null) { foreach (var system in _roleLogoutSystems) { system.OnRoleLogout(); } } } public virtual void OnDrawGizmos() { } public virtual void OnApplicationPause(bool pause) { } #endregion } public interface IArchitecture { void RegisterSystem(T system) where T : ISystem; void RegisterModel(T model) where T : IModel; void RegisterUtility(T utility) where T : IUtility; T GetSystem() where T : class, ISystem; T GetModel() where T : class, IModel; T GetUtility() where T : class, IUtility; void SendCommand() where T : ICommand, new(); void SendCommand(T command) where T : ICommand; TResult SendQuery(IQuery query); void SendEvent() where T : new(); void SendEvent(T e); IUnRegister RegisterEvent(Action onEvent); void UnRegisterEvent(Action onEvent); } public interface IOnEvent { void OnEvent(T e); } public static class OnGlobalEventExtension { public static IUnRegister RegisterEvent(this IOnEvent self) where T : struct { return TypeEventSystem.Global.Register(self.OnEvent); } public static void UnRegisterEvent(this IOnEvent self) where T : struct { TypeEventSystem.Global.UnRegister(self.OnEvent); } } #endregion #region Controller public interface IController : IBelongToArchitecture, ICanSendCommand, ICanGetSystem, ICanGetModel, ICanRegisterEvent, ICanSendQuery { } #endregion #region System public interface ISystem : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetUtility, ICanRegisterEvent, ICanSendEvent, ICanGetSystem { void Init(); } abstract class SubSystem : ISystem, ILogicSys { private IArchitecture _architecture; IArchitecture IBelongToArchitecture.GetArchitecture() { return _architecture; } void ICanSetArchitecture.SetArchitecture(IArchitecture architecture) { _architecture = architecture; } void ISystem.Init() { OnInit(); } protected abstract void OnInit(); public virtual void OnDestroy() { } public virtual void OnStart() { } public virtual void OnUpdate() { } public virtual void OnLateUpdate() { } public virtual void OnFixedUpdate() { } public virtual void OnRoleLogin() { } public virtual void OnRoleLogout() { } public virtual void OnDrawGizmos() { } public virtual void OnApplicationPause(bool pause) { } bool ILogicSys.OnInit() { return true; } } #endregion #region Model public interface IModel : IBelongToArchitecture, ICanSetArchitecture, ICanGetUtility, ICanSendEvent { void Init(); } public abstract class AbstractModel : IModel { private IArchitecture _architecture; IArchitecture IBelongToArchitecture.GetArchitecture() { return _architecture; } void ICanSetArchitecture.SetArchitecture(IArchitecture architecture) { _architecture = architecture; } void IModel.Init() { OnInit(); } protected abstract void OnInit(); } #endregion #region Utility public interface IUtility { } #endregion #region Command public interface ICommand : IBelongToArchitecture, ICanSetArchitecture, ICanGetSystem, ICanGetModel, ICanGetUtility, ICanSendEvent, ICanSendCommand, ICanSendQuery { void Execute(); } public abstract class AbstractCommand : ICommand { private IArchitecture _architecture; IArchitecture IBelongToArchitecture.GetArchitecture() { return _architecture; } void ICanSetArchitecture.SetArchitecture(IArchitecture architecture) { _architecture = architecture; } void ICommand.Execute() { OnExecute(); } protected abstract void OnExecute(); } #endregion #region Query public interface IQuery : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetSystem, ICanSendQuery { TResult Do(); } public abstract class AbstractQuery : IQuery { public T Do() { return OnDo(); } protected abstract T OnDo(); private IArchitecture _architecture; public IArchitecture GetArchitecture() { return _architecture; } public void SetArchitecture(IArchitecture architecture) { _architecture = architecture; } } #endregion #region Rule public interface IBelongToArchitecture { IArchitecture GetArchitecture(); } public interface ICanSetArchitecture { void SetArchitecture(IArchitecture architecture); } public interface ICanGetModel : IBelongToArchitecture { } public static class CanGetModelExtension { public static T GetModel(this ICanGetModel self) where T : class, IModel { return self.GetArchitecture().GetModel(); } } public interface ICanGetSystem : IBelongToArchitecture { } public static class CanGetSystemExtension { public static T GetSystem(this ICanGetSystem self) where T : class, ISystem { return self.GetArchitecture().GetSystem(); } } public interface ICanGetUtility : IBelongToArchitecture { } public static class CanGetUtilityExtension { public static T GetUtility(this ICanGetUtility self) where T : class, IUtility { return self.GetArchitecture().GetUtility(); } } public interface ICanRegisterEvent : IBelongToArchitecture { } public static class CanRegisterEventExtension { public static IUnRegister RegisterEvent(this ICanRegisterEvent self, Action onEvent) { return self.GetArchitecture().RegisterEvent(onEvent); } public static void UnRegisterEvent(this ICanRegisterEvent self, Action onEvent) { self.GetArchitecture().UnRegisterEvent(onEvent); } } public interface ICanSendCommand : IBelongToArchitecture { } public static class CanSendCommandExtension { public static void SendCommand(this ICanSendCommand self) where T : ICommand, new() { self.GetArchitecture().SendCommand(); } public static void SendCommand(this ICanSendCommand self, T command) where T : ICommand { self.GetArchitecture().SendCommand(command); } } public interface ICanSendEvent : IBelongToArchitecture { } public static class CanSendEventExtension { public static void SendEvent(this ICanSendEvent self) where T : new() { self.GetArchitecture().SendEvent(); } public static void SendEvent(this ICanSendEvent self, T e) { self.GetArchitecture().SendEvent(e); } } public interface ICanSendQuery : IBelongToArchitecture { } public static class CanSendQueryExtension { public static TResult SendQuery(this ICanSendQuery self, IQuery query) { return self.GetArchitecture().SendQuery(query); } } #endregion #region TypeEventSystem public interface IUnRegister { void UnRegister(); } public interface IUnRegisterList { List UnregisterList { get; } } public static class UnRegisterListExtension { public static void AddToUnregisterList(this IUnRegister self, IUnRegisterList unRegisterList) { unRegisterList.UnregisterList.Add(self); } public static void UnRegisterAll(this IUnRegisterList self) { foreach (var unRegister in self.UnregisterList) { unRegister.UnRegister(); } self.UnregisterList.Clear(); } } /// /// 自定义可注销的类 /// public struct CustomUnRegister : IUnRegister { /// /// 委托对象 /// private Action _onUnRegister; /// /// 带参构造函数 /// /// public CustomUnRegister(Action onUnRegister) { _onUnRegister = onUnRegister; } /// /// 资源释放 /// public void UnRegister() { _onUnRegister.Invoke(); _onUnRegister = null; } } public class UnRegisterOnDestroyTrigger : MonoBehaviour { private readonly HashSet _unRegisters = new HashSet(); public void AddUnRegister(IUnRegister unRegister) { _unRegisters.Add(unRegister); } public void RemoveUnRegister(IUnRegister unRegister) { _unRegisters.Remove(unRegister); } private void OnDestroy() { foreach (var unRegister in _unRegisters) { unRegister.UnRegister(); } _unRegisters.Clear(); } } public static class UnRegisterExtension { public static IUnRegister UnRegisterWhenGameObjectDestroyed(this IUnRegister unRegister, GameObject gameObject) { var trigger = gameObject.GetComponent(); if (!trigger) { trigger = gameObject.AddComponent(); } trigger.AddUnRegister(unRegister); return unRegister; } } public class TypeEventSystem { private readonly EasyEvents _events = new EasyEvents(); public static readonly TypeEventSystem Global = new TypeEventSystem(); public void Send() where T : new() { var eventInfo = _events.GetEvent>(); if (eventInfo != null) { eventInfo.Trigger(new T()); } } public void Send(T e) { var eventInfo = _events.GetEvent>(); if (eventInfo != null) { eventInfo.Trigger(e); } } public IUnRegister Register(Action onEvent) { var e = _events.GetOrAddEvent>(); return e.Register(onEvent); } public void UnRegister(Action onEvent) { var e = _events.GetEvent>(); if (e != null) { e.UnRegister(onEvent); } } } #endregion #region Redux public class Container { private readonly Dictionary _instances = new Dictionary(); public void Register(T instance) { var key = typeof(T); if (_instances.ContainsKey(key)) { _instances[key] = instance; } else { _instances.Add(key, instance); } } public T Get() where T : class { var key = typeof(T); object ret; if (_instances.TryGetValue(key, out ret)) { return ret as T; } return null; } } #endregion #region BindableProperty public interface IBindableProperty : IReadonlyBindableProperty { new T Value { get; set; } void SetValueWithoutEvent(T newValue); } public interface IReadonlyBindableProperty { T Value { get; } IUnRegister RegisterWithInitValue(Action action); void UnRegister(Action onValueChanged); IUnRegister Register(Action onValueChanged); } public abstract class BindAbleProperty : IBindableProperty { public BindAbleProperty(T defaultValue = default(T)) { _value = defaultValue; } protected T _value; public T Value { get { return GetValue(); } set { if (value == null && _value == null) return; if (value != null && value.Equals(_value)) return; SetValue(value); if (_onValueChanged != null) { _onValueChanged.Invoke(value); } } } protected virtual void SetValue(T newValue) { _value = newValue; } protected virtual T GetValue() { return _value; } public void SetValueWithoutEvent(T newValue) { _value = newValue; } private Action _onValueChanged = v => { }; public IUnRegister Register(Action onValueChanged) { _onValueChanged += onValueChanged; return new BindablePropertyUnRegister() { BindAbleProperty = this, OnValueChanged = onValueChanged }; } public IUnRegister RegisterWithInitValue(Action onValueChanged) { onValueChanged(_value); return Register(onValueChanged); } public static implicit operator T(BindAbleProperty property) { return property.Value; } public override string ToString() { return Value.ToString(); } public void UnRegister(Action onValueChanged) { _onValueChanged -= onValueChanged; } } public class BindablePropertyUnRegister : IUnRegister { public BindAbleProperty BindAbleProperty { get; set; } public Action OnValueChanged { get; set; } public void UnRegister() { BindAbleProperty.UnRegister(OnValueChanged); BindAbleProperty = null; OnValueChanged = null; } } #endregion #region EasyEvent public interface IEasyEvent { } public class EasyEvent : IEasyEvent { private Action _onEvent = () => { }; public IUnRegister Register(Action onEvent) { _onEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { _onEvent -= onEvent; } public void Trigger() { if (_onEvent != null) { _onEvent.Invoke(); } } } public class EasyEvent : IEasyEvent { private Action _onEvent = e => { }; public IUnRegister Register(Action onEvent) { _onEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { _onEvent -= onEvent; } public void Trigger(T t) { if (_onEvent != null) { _onEvent.Invoke(t); } } } public class EasyEvent : IEasyEvent { private Action _onEvent = (t, k) => { }; public IUnRegister Register(Action onEvent) { _onEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { _onEvent -= onEvent; } public void Trigger(T t, K k) { if (_onEvent != null) { _onEvent.Invoke(t, k); } } } public class EasyEvent : IEasyEvent { private Action _onEvent = (t, k, s) => { }; public IUnRegister Register(Action onEvent) { _onEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { _onEvent -= onEvent; } public void Trigger(T t, K k, S s) { if (_onEvent != null) { _onEvent.Invoke(t, k, s); } } } public class EasyEvents { private static readonly EasyEvents GlobalEvents = new EasyEvents(); public static T Get() where T : IEasyEvent { return GlobalEvents.GetEvent(); } public static void Register() where T : IEasyEvent, new() { GlobalEvents.AddEvent(); } private readonly Dictionary _typeEvents = new Dictionary(); public void AddEvent() where T : IEasyEvent, new() { _typeEvents.Add(typeof(T), new T()); } public T GetEvent() where T : IEasyEvent { IEasyEvent e; if (_typeEvents.TryGetValue(typeof(T), out e)) { return (T)e; } return default(T); } public T GetOrAddEvent() where T : IEasyEvent, new() { var eType = typeof(T); IEasyEvent e; if (_typeEvents.TryGetValue(eType, out e)) { return (T)e; } var t = new T(); _typeEvents.Add(eType, t); return t; } } #endregion }