diff --git a/Assets/GameScripts/HotFix/GameBase/Redux.cs b/Assets/GameScripts/HotFix/GameBase/Redux.cs new file mode 100644 index 00000000..24a18d4a --- /dev/null +++ b/Assets/GameScripts/HotFix/GameBase/Redux.cs @@ -0,0 +1,1118 @@ +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 +} \ No newline at end of file