using System.Threading.Tasks; using System.Collections.Generic; using System; using UnityEngine; using System.Reflection; /* 修改第三版 将事件从IArchitecture中剥离 */ namespace Blue { #region Architecture /// /// 所有功能在 IArchitecture 接口中定义 /// 1. 注册/获取Service、Model、Utility; /// 2. 发送命令、事件、查询 /// 3. 注册、取消注册事件 /// public interface IArchitecture { void SetArchitecture(IArchitecture instance); void InitArchitecture(); void RegisterService(T service) where T : IService; void RegisterModel(T Model) where T : IModel; void RegisterUtility(T utility) where T : IUtility; T GetService() where T : class, IService; T GetModel() where T : class, IModel; T GetUtility() where T : class, IUtility; } public abstract class AbstractArchitecture : IArchitecture where T : AbstractArchitecture, new() { private IOCContainer mContainer = new IOCContainer(); // 将类型、对象存储进IOC容器 private ICommandHandler commandHandler = new DefaultCommandHandler(); private IQueryHandler queryHandler = new DefaultQueryHandler(); private ITypeEventSystem mTypeEventSystem = new TypeEventSystem(); private HashSet mService; private HashSet mModels; protected abstract void Init(); private static IArchitecture mArchitectureInstance; void IArchitecture.SetArchitecture(IArchitecture instance) { mArchitectureInstance = instance; CanGetModelExtension.SetArchitecture(mArchitectureInstance); CanGetServiceExtension.SetArchitecture(mArchitectureInstance); CanGetUtilityExtension.SetArchitecture(mArchitectureInstance); CanSendCommandExtension.SetCommandHandler(commandHandler); CanSendQueryExtension.SetQueryHandler(queryHandler); CanRegisterEventExtension.SetTypeEventSystem(mTypeEventSystem); CanSendEventExtension.SetTypeEventSystem(mTypeEventSystem); } void IArchitecture.InitArchitecture() { StartInit(); FinishInit(); } private void StartInit() { mService = new HashSet(); mModels = new HashSet(); Init(); foreach (var architectureModel in mModels) { architectureModel.OnInit(); } foreach (var service in mService) { service.OnInit(); } } private void FinishInit() { mService.Clear(); mModels.Clear(); mService = null; mModels = null; } public void RegisterService(TService service) where TService : IService { mContainer.Register(service); mService.Add(service); } public void RegisterModel(TModel model) where TModel : IModel { mContainer.Register(model); mModels.Add(model); } public void RegisterUtility(TUtility utility) where TUtility : IUtility { mContainer.Register(utility); } public TService GetService() where TService : class, IService { return mContainer.Get(); } public TModel GetModel() where TModel : class, IModel { return mContainer.Get(); } public TUtility GetUtility() where TUtility : class, IUtility { return mContainer.Get(); } } /// /// 启动 Architecture /// internal sealed class ArchitectureInitiator { private ArchitectureInitiator() { } private static ArchitectureInitiator mInstance; private IArchitecture architectureInstance = null; // Architecture 实例 private Type architectureType = typeof(IArchitecture); private bool architectureInited; // Architecture 是否初始化完成 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] private static void Initiate() { mInstance = new ArchitectureInitiator(); Type[] typeArr = Assembly.GetExecutingAssembly().GetTypes(); // 获取正在执行的程序集类型数组 for (int i = 0; i < typeArr.Length; i++) { Type tmpType = typeArr[i]; if (!tmpType.IsInterface) { if (mInstance.IsArchitecture(tmpType)) { mInstance.CreateArchitectureInstance(tmpType); } } } mInstance.RegisterArchitecture(); mInstance.InitArchitecture(); } private void RegisterArchitecture() { if (architectureInstance != null) { architectureInstance.SetArchitecture(architectureInstance); } } private void InitArchitecture() { if (architectureInstance != null) { architectureInstance.InitArchitecture(); } } private bool IsArchitecture(Type tmpType) { if (architectureInited) { return false; } if (tmpType.IsAbstract) { return false; } return architectureType.IsAssignableFrom(tmpType); // 确定指定类型 c 的实例是否能分配给当前类型的变量 } private void CreateArchitectureInstance(Type archiType) { if (architectureInstance == null) { architectureInstance = (IArchitecture)Activator.CreateInstance(archiType); architectureInited = true; } else { throw new Exception("More than one Architecture sub-class in the application,it should be only one!"); } } } public interface IOnEvent { void OnEvent(T e); } public static class OnGlobalEventExtension { public static IUnRegister RegisterEvent(this IOnEvent self) where T : struct, IEvent { return TypeEventSystem.Global.Register(self.OnEvent); } public static void UnRegisterEvent(this IOnEvent self) where T : struct, IEvent { TypeEventSystem.Global.UnRegister(self.OnEvent); } } #endregion #region Controller public interface IController : ICanGetUtility, ICanGetService, ICanGetModel, ICanRegisterEvent, ICanSendQuery, ICanSendCommand { } #endregion #region Service public interface IService : ICanGetService, ICanGetModel, ICanGetUtility, ICanRegisterEvent, ICanSendEvent { void OnInit(); } #endregion #region Model public interface IModel : ICanGetUtility, ICanSendEvent { void OnInit(); } #endregion #region Utility public interface IUtility { } #endregion #region Command public interface ICommand : ICanGetService, ICanGetModel, ICanGetUtility, ICanSendEvent, ICanSendCommand, ICanSendQuery { void OnExcute(); } public interface ICommand : ICanGetService, ICanGetModel, ICanGetUtility, ICanSendEvent, ICanSendCommand, ICanSendQuery { T OnExcute(); } public interface ICommandHandler { void ExcuteCommand(ICommand command); void ExcuteCommand() where T : ICommand, new(); T ExcuteCommand(ICommand command); } public class DefaultCommandHandler : ICommandHandler { public void ExcuteCommand(ICommand command) { command.OnExcute(); } public void ExcuteCommand() where T : ICommand, new() { ExcuteCommand(new T()); } public T ExcuteCommand(ICommand command) { return command.OnExcute(); } } #endregion #region Query public interface IQuery : ICanGetModel, ICanGetService, ICanSendQuery { T DoQuery(); } public interface IQueryAsync : ICanGetModel, ICanGetService, ICanSendQuery { void DoQueryAsync(Action onQueryCompleted); } public interface IQueryResult { void OnQuerySucceed(Action onQuerySucceed); void OnQueryFailed(Action onQueryFailed); } public interface IQueryHandler { T DoQuery(IQuery query); K DoQuery() where T : IQuery, new(); IQueryResult DoQueryAsync(IQuery query); IQueryResult DoQueryAsync() where T : IQuery, new(); } public class DefaultQueryHandler : IQueryHandler { public T DoQuery(IQuery query) { return query.DoQuery(); } public K DoQuery() where T : IQuery, new() { return DoQuery(new T()); } public IQueryResult DoQueryAsync(IQuery query) { DefaultQueryResult queryResult = new DefaultQueryResult(); var queryTask = Task.Run(() => { return query.DoQuery(); }); var awaiter = queryTask.GetAwaiter(); awaiter.OnCompleted(() => { if (queryTask.IsFaulted | queryTask.IsCanceled) { queryResult.TriggerFailed(); } else { queryResult.TriggerSuccess(awaiter.GetResult()); } }); return queryResult; } public IQueryResult DoQueryAsync() where T : IQuery, new() { return DoQueryAsync(new T()); } } public class DefaultQueryResult : IQueryResult { private Action mOnQuerySucceed; private Action mOnQueryFailed; public void OnQuerySucceed(Action onQuerySucceed) { mOnQuerySucceed += onQuerySucceed; } public void OnQueryFailed(Action onQueryFailed) { mOnQueryFailed += onQueryFailed; } public void TriggerSuccess(T result) { mOnQuerySucceed?.Invoke(result); } public void TriggerFailed() { mOnQueryFailed?.Invoke(); } } #endregion #region Rule /// /// 能够 GetModel 的接口 /// public interface ICanGetModel { } /// /// ICanGetModel 的静态扩展 GetModel /// public static class CanGetModelExtension { public static T GetModel(this ICanGetModel self) where T : class, IModel { return _architecture.GetModel(); } private static IArchitecture _architecture; public static void SetArchitecture(IArchitecture architecture) { _architecture = architecture; } } /// /// 能够 GetService 的接口 /// public interface ICanGetService { } /// /// ICanGetService 的静态扩展 GetService /// public static class CanGetServiceExtension { public static T GetService(this ICanGetService self) where T : class, IService { return _architecture.GetService(); } private static IArchitecture _architecture; public static void SetArchitecture(IArchitecture architecture) { _architecture = architecture; } } /// /// 能够 GetUtility 的接口 /// public interface ICanGetUtility { } /// /// ICanGetUtility 的静态扩展 GetUtility /// public static class CanGetUtilityExtension { public static T GetUtility(this ICanGetUtility self) where T : class, IUtility { return _architecture.GetUtility(); } private static IArchitecture _architecture; public static void SetArchitecture(IArchitecture architecture) { _architecture = architecture; } } /// /// 能够 RegisterEvent 的接口 /// public interface ICanRegisterEvent { } /// /// ICanRegisterEvent 的静态扩展 RegisterEvent /// public static class CanRegisterEventExtension { public static IUnRegister RegisterEvent(this ICanRegisterEvent self, Action onEvent) where T : IEvent { if (typeEventSystem == null) return null; return typeEventSystem.Register(onEvent); } public static void UnRegisterEvent(this ICanRegisterEvent self, Action onEvent) where T : IEvent { typeEventSystem.UnRegister(onEvent); } private static ITypeEventSystem typeEventSystem; public static void SetTypeEventSystem(ITypeEventSystem mTypeEventSystem) { typeEventSystem = mTypeEventSystem; } } /// /// 能够 SendCommand 的接口 /// public interface ICanSendCommand { } /// /// ICanSendCommand 的静态扩展 SendCommand /// public static class CanSendCommandExtension { public static void SendCommand(this ICanSendCommand self) where T : ICommand, new() { mCommandHandler.ExcuteCommand(); } public static void SendCommand(this ICanSendCommand self, T command) where T : ICommand { mCommandHandler.ExcuteCommand(command); } public static T SendCommand(this ICanSendCommand self, ICommand command) { return mCommandHandler.ExcuteCommand(command); } private static ICommandHandler mCommandHandler; public static void SetCommandHandler(ICommandHandler commandHandler) { mCommandHandler = commandHandler; } } /// /// 能够 SendEvent 的接口 /// public interface ICanSendEvent { } /// /// ICanSendEvent 的静态扩展 SendEvent /// public static class CanSendEventExtension { public static void SendEvent(this ICanSendEvent self) where T : IEvent, new() { typeEventSystem.Send(); } public static void SendEvent(this ICanSendEvent self, T e) where T : IEvent { typeEventSystem.Send(e); } private static ITypeEventSystem typeEventSystem; public static void SetTypeEventSystem(ITypeEventSystem mTypeEventSystem) { typeEventSystem = mTypeEventSystem; } } /// /// 能够 SendQuery 的接口 /// public interface ICanSendQuery { } /// /// ICanSendQuery 的静态扩展 SendQuery /// public static class CanSendQueryExtension { public static T SendQuery(this ICanSendQuery self, IQuery queryInstance) { return _queryHandler.DoQuery(queryInstance); } public static K SendQuery(this ICanSendQuery self) where T : IQuery, new() { return _queryHandler.DoQuery(); } public static IQueryResult SendQueryAsync(this ICanSendQuery self, IQuery queryInstance) { return _queryHandler.DoQueryAsync(queryInstance); } public static IQueryResult SendQueryAsync(this ICanSendQuery self) where T : IQuery, new() { return _queryHandler.DoQueryAsync(); } private static IQueryHandler _queryHandler; public static void SetQueryHandler(IQueryHandler queryHandler) { _queryHandler = queryHandler; } } #endregion #region TypeEventSystem /// /// 取消监听接口 /// public interface IUnRegister { void UnRegister(); } /// /// 取消监听列表接口 /// public interface IUnRegisterList { List UnRegistersList { get; } } /// /// 取消监听列表接口的静态扩展 /// 【IUnRegister 添加进 IUnRegisterList】 /// 【IUnRegisterList全部取消监听】 /// public static class IUnRegisterListExtension { public static void AddToUnRegisterList(this IUnRegister self, IUnRegisterList unRegisterList) { unRegisterList.UnRegistersList.Add(self); } public static void UnRegisterAll(this IUnRegisterList self) { foreach (IUnRegister unRegister in self.UnRegistersList) { unRegister.UnRegister(); } self.UnRegistersList.Clear(); } } /// /// 取消监听的类 /// public struct CustomUnRegister : IUnRegister { private Action mOnUnregister { get; set; } public CustomUnRegister(Action onUnRegsiter) { mOnUnregister = onUnRegsiter; } public void UnRegister() { mOnUnregister?.Invoke(); mOnUnregister = null; } } /// /// 物体销毁时触发取消监听 /// public class UnRegisterOnDestroyTrigger : MonoBehaviour { private readonly HashSet mUnRegisters = new HashSet(); public void AddUnRegister(IUnRegister unRegister) { mUnRegisters.Add(unRegister); } public void RemoveUnRegister(IUnRegister unRegister) { mUnRegisters.Remove(unRegister); } private void OnDestroy() { foreach (IUnRegister unRegister in mUnRegisters) { unRegister.UnRegister(); } mUnRegisters.Clear(); } } /// /// 取消监听的静态扩展 /// 【物体销毁时触发取消监听】 /// 【组件所属物体销毁时触发取消监听】 /// public static class UnRegisterExtension { /// /// 物体:物体销毁时触发取消监听 /// /// 取消监听的接口 /// 物体对象 /// 取消监听的接口 public static IUnRegister UnRegisterWhenGameObjectDestroyed(this IUnRegister unRegister, GameObject go) { UnRegisterOnDestroyTrigger trigger = go.GetComponent(); if (!trigger) { trigger = go.AddComponent(); } trigger.AddUnRegister(unRegister); return unRegister; } /// /// 组件:物体销毁时触发取消监听 /// /// 取消监听的接口 /// 组件对象 /// 取消监听的接口 public static IUnRegister UnRegisterWhenGameObjectDestroyed(this IUnRegister unRegister, T component) where T : Component { return unRegister.UnRegisterWhenGameObjectDestroyed(component.gameObject); } } public interface ITypeEventSystem { IUnRegister Register(Action onEvent) where T : IEvent; void UnRegister(Action onEvent) where T : IEvent; void Send() where T : IEvent, new(); void Send(T e) where T : IEvent; } public class TypeEventSystem : ITypeEventSystem { private readonly EasyEvents mEvents = new EasyEvents(); public static readonly TypeEventSystem Global = new TypeEventSystem(); public void Send() where T : IEvent, new() { mEvents.GetEvent>()?.Trigger(new T()); } public void Send(T e) where T : IEvent { mEvents.GetEvent>()?.Trigger(e); } public IUnRegister Register(Action onEvent) where T : IEvent { var e = mEvents.GetOrAddEvent>(); return e.Register(onEvent); } public void UnRegister(Action onEvent) where T : IEvent { var e = mEvents.GetEvent>(); if (e != null) { e.UnRegister(onEvent); } } } #endregion #region IOC /// /// IOC 容器 ,将类型对应的对象存储进字典 /// 【注册 + 获取】 /// public class IOCContainer { private Dictionary mInstances = new Dictionary(); /// /// IOC 容器注册方法 /// /// 实例 /// 指定类型 public void Register(T instance) { Type key = typeof(T); if (mInstances.ContainsKey(key)) { mInstances[key] = instance; } else { mInstances.Add(key, instance); } } /// /// IOC 容器获取方法 /// /// 指定类型 public T Get() where T : class { Type key = typeof(T); if (mInstances.TryGetValue(key, out object retInstance)) { return retInstance as T; } return null; } } #endregion #region BindableProperty public interface IReadonlyBindableProperty { T Value { get; } IUnRegister Register(Action onValueChanged); void UnRegister(Action onValueChanged); IUnRegister RegisterWithInitValue(Action action); } public interface IBindableProperty : IReadonlyBindableProperty { new T Value { get; set; } void SetValueWithoutEvent(T newValue); } public class BindableProperty : IBindableProperty { private Action mOnValueChanged = (v) => { }; public BindableProperty(T defaultValue = default) { mValue = defaultValue; } protected T mValue; public T Value { get => GetValue(); set { if (value == null && mValue == null) return; if (value != null && value.Equals(mValue)) return; SetValue(value); mOnValueChanged?.Invoke(value); } } protected virtual void SetValue(T newValue) { mValue = newValue; } protected virtual T GetValue() { return mValue; } public void SetValueWithoutEvent(T newValue) { mValue = newValue; } public IUnRegister Register(Action onValueChanged) { mOnValueChanged += onValueChanged; return new BindablePropertyUnRegister() { BindableProperty = this, OnValueChanged = onValueChanged }; } public IUnRegister RegisterWithInitValue(Action onValueChanged) { onValueChanged(mValue); 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) { mOnValueChanged -= 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 mOnEvent = () => { }; public IUnRegister Register(Action onEvent) { mOnEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { mOnEvent -= onEvent; } public void Trigger() { mOnEvent?.Invoke(); } } public class EasyEvent : IEasyEvent { private Action mOnEvent = e => { }; public IUnRegister Register(Action onEvent) { mOnEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { mOnEvent -= onEvent; } public void Trigger(T t) { mOnEvent?.Invoke(t); } } public class EasyEvent : IEasyEvent { private Action mOnEvent = (t, k) => { }; public IUnRegister Register(Action onEvent) { mOnEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { mOnEvent -= onEvent; } public void Trigger(T t, K k) { mOnEvent?.Invoke(t, k); } } public class EasyEvent : IEasyEvent { private Action mOnEvent = (t, k, s) => { }; public IUnRegister Register(Action onEvent) { mOnEvent += onEvent; return new CustomUnRegister(() => { UnRegister(onEvent); }); } public void UnRegister(Action onEvent) { mOnEvent -= onEvent; } public void Trigger(T t, K k, S s) { mOnEvent?.Invoke(t, k, s); } } public class EasyEvents { private static EasyEvents mGlobalEvents = new EasyEvents(); public static T Get() where T : IEasyEvent { return mGlobalEvents.GetEvent(); } public static void Register() where T : IEasyEvent, new() { mGlobalEvents.AddEvent(); } private Dictionary mTypeEvents = new Dictionary(); public void AddEvent() where T : IEasyEvent, new() { mTypeEvents.Add(typeof(T), new T()); } public T GetEvent() where T : IEasyEvent { if (mTypeEvents.TryGetValue(typeof(T), out IEasyEvent e)) { return (T)e; } return default; } public T GetOrAddEvent() where T : IEasyEvent, new() { var eType = typeof(T); if (mTypeEvents.TryGetValue(eType, out var e)) { return (T)e; } var t = new T(); mTypeEvents.Add(eType, t); return t; } } #endregion #region Event public interface IEvent { } #endregion }