|
@@ -0,0 +1,1064 @@
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System;
|
|
|
+using UnityEngine;
|
|
|
+using System.Reflection;
|
|
|
+
|
|
|
+
|
|
|
+修改第三版
|
|
|
+将事件从IArchitecture中剥离
|
|
|
+*/
|
|
|
+namespace Blue
|
|
|
+{
|
|
|
+
|
|
|
+ #region Architecture
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface IArchitecture
|
|
|
+ {
|
|
|
+ void SetArchitecture(IArchitecture instance);
|
|
|
+ void InitArchitecture();
|
|
|
+
|
|
|
+ void RegisterService<T>(T service) where T : IService;
|
|
|
+ void RegisterModel<T>(T Model) where T : IModel;
|
|
|
+ void RegisterUtility<T>(T utility) where T : IUtility;
|
|
|
+
|
|
|
+ T GetService<T>() where T : class, IService;
|
|
|
+ T GetModel<T>() where T : class, IModel;
|
|
|
+ T GetUtility<T>() where T : class, IUtility;
|
|
|
+ }
|
|
|
+
|
|
|
+ public abstract class AbstractArchitecture<T> : IArchitecture where T : AbstractArchitecture<T>, new()
|
|
|
+ {
|
|
|
+ private IOCContainer mContainer = new IOCContainer();
|
|
|
+ private ICommandHandler commandHandler = new DefaultCommandHandler();
|
|
|
+ private IQueryHandler queryHandler = new DefaultQueryHandler();
|
|
|
+ private ITypeEventSystem mTypeEventSystem = new TypeEventSystem();
|
|
|
+ private HashSet<IService> mService;
|
|
|
+ private HashSet<IModel> 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<IService>();
|
|
|
+ mModels = new HashSet<IModel>();
|
|
|
+ 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>(TService service) where TService : IService
|
|
|
+ {
|
|
|
+ mContainer.Register<TService>(service);
|
|
|
+
|
|
|
+ mService.Add(service);
|
|
|
+ }
|
|
|
+ public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
|
|
+ {
|
|
|
+ mContainer.Register<TModel>(model);
|
|
|
+
|
|
|
+ mModels.Add(model);
|
|
|
+ }
|
|
|
+ public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
|
|
|
+ {
|
|
|
+ mContainer.Register<TUtility>(utility);
|
|
|
+ }
|
|
|
+
|
|
|
+ public TService GetService<TService>() where TService : class, IService
|
|
|
+ {
|
|
|
+ return mContainer.Get<TService>();
|
|
|
+ }
|
|
|
+ public TModel GetModel<TModel>() where TModel : class, IModel
|
|
|
+ {
|
|
|
+ return mContainer.Get<TModel>();
|
|
|
+ }
|
|
|
+ public TUtility GetUtility<TUtility>() where TUtility : class, IUtility
|
|
|
+ {
|
|
|
+ return mContainer.Get<TUtility>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ internal sealed class ArchitectureInitiator
|
|
|
+ {
|
|
|
+ private ArchitectureInitiator() { }
|
|
|
+ private static ArchitectureInitiator mInstance;
|
|
|
+
|
|
|
+ private IArchitecture architectureInstance = null;
|
|
|
+ private Type architectureType = typeof(IArchitecture);
|
|
|
+ private bool architectureInited;
|
|
|
+
|
|
|
+ [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);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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<T>
|
|
|
+ {
|
|
|
+ void OnEvent(T e);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class OnGlobalEventExtension
|
|
|
+ {
|
|
|
+ public static IUnRegister RegisterEvent<T>(this IOnEvent<T> self) where T :struct,IEvent
|
|
|
+ {
|
|
|
+ return TypeEventSystem.Global.Register<T>(self.OnEvent);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void UnRegisterEvent<T>(this IOnEvent<T> self) where T : struct,IEvent
|
|
|
+ {
|
|
|
+ TypeEventSystem.Global.UnRegister<T>(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<T> : ICanGetService, ICanGetModel, ICanGetUtility,
|
|
|
+ ICanSendEvent, ICanSendCommand, ICanSendQuery
|
|
|
+ {
|
|
|
+ T OnExcute();
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface ICommandHandler
|
|
|
+ {
|
|
|
+ void ExcuteCommand(ICommand command);
|
|
|
+ void ExcuteCommand<T>() where T : ICommand, new();
|
|
|
+ T ExcuteCommand<T>(ICommand<T> command);
|
|
|
+ }
|
|
|
+
|
|
|
+ public class DefaultCommandHandler : ICommandHandler
|
|
|
+ {
|
|
|
+ public void ExcuteCommand(ICommand command)
|
|
|
+ {
|
|
|
+ command.OnExcute();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ExcuteCommand<T>() where T : ICommand, new()
|
|
|
+ {
|
|
|
+ ExcuteCommand(new T());
|
|
|
+ }
|
|
|
+
|
|
|
+ public T ExcuteCommand<T>(ICommand<T> command)
|
|
|
+ {
|
|
|
+ return command.OnExcute();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region Query
|
|
|
+
|
|
|
+ public interface IQuery<T> : ICanGetModel, ICanGetService, ICanSendQuery
|
|
|
+ {
|
|
|
+ T DoQuery();
|
|
|
+ }
|
|
|
+ public interface IQueryAsync : ICanGetModel, ICanGetService, ICanSendQuery
|
|
|
+ {
|
|
|
+ void DoQueryAsync<T>(Action<T> onQueryCompleted);
|
|
|
+ }
|
|
|
+ public interface IQueryResult<T>
|
|
|
+ {
|
|
|
+ void OnQuerySucceed(Action<T> onQuerySucceed);
|
|
|
+ void OnQueryFailed(Action onQueryFailed);
|
|
|
+ }
|
|
|
+ public interface IQueryHandler
|
|
|
+ {
|
|
|
+ T DoQuery<T>(IQuery<T> query);
|
|
|
+ K DoQuery<T, K>() where T : IQuery<K>, new();
|
|
|
+
|
|
|
+ IQueryResult<T> DoQueryAsync<T>(IQuery<T> query);
|
|
|
+ IQueryResult<K> DoQueryAsync<T, K>() where T : IQuery<K>, new();
|
|
|
+ }
|
|
|
+
|
|
|
+ public class DefaultQueryHandler : IQueryHandler
|
|
|
+ {
|
|
|
+ public T DoQuery<T>(IQuery<T> query)
|
|
|
+ {
|
|
|
+ return query.DoQuery();
|
|
|
+ }
|
|
|
+
|
|
|
+ public K DoQuery<T, K>() where T : IQuery<K>, new()
|
|
|
+ {
|
|
|
+ return DoQuery(new T());
|
|
|
+ }
|
|
|
+
|
|
|
+ public IQueryResult<T> DoQueryAsync<T>(IQuery<T> query)
|
|
|
+ {
|
|
|
+ DefaultQueryResult<T> queryResult = new DefaultQueryResult<T>();
|
|
|
+ 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<K> DoQueryAsync<T, K>() where T : IQuery<K>, new()
|
|
|
+ {
|
|
|
+ return DoQueryAsync(new T());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class DefaultQueryResult<T> : IQueryResult<T>
|
|
|
+ {
|
|
|
+ private Action<T> mOnQuerySucceed;
|
|
|
+ private Action mOnQueryFailed;
|
|
|
+
|
|
|
+ public void OnQuerySucceed(Action<T> 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
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanGetModel
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanGetModelExtension
|
|
|
+ {
|
|
|
+ public static T GetModel<T>(this ICanGetModel self) where T : class, IModel
|
|
|
+ {
|
|
|
+ return _architecture.GetModel<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static IArchitecture _architecture;
|
|
|
+ public static void SetArchitecture(IArchitecture architecture)
|
|
|
+ {
|
|
|
+ _architecture = architecture;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanGetService
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanGetServiceExtension
|
|
|
+ {
|
|
|
+ public static T GetService<T>(this ICanGetService self) where T : class, IService
|
|
|
+ {
|
|
|
+ return _architecture.GetService<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static IArchitecture _architecture;
|
|
|
+ public static void SetArchitecture(IArchitecture architecture)
|
|
|
+ {
|
|
|
+ _architecture = architecture;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanGetUtility
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanGetUtilityExtension
|
|
|
+ {
|
|
|
+ public static T GetUtility<T>(this ICanGetUtility self) where T : class, IUtility
|
|
|
+ {
|
|
|
+ return _architecture.GetUtility<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static IArchitecture _architecture;
|
|
|
+ public static void SetArchitecture(IArchitecture architecture)
|
|
|
+ {
|
|
|
+ _architecture = architecture;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanRegisterEvent
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanRegisterEventExtension
|
|
|
+ {
|
|
|
+ public static IUnRegister RegisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent) where T : IEvent
|
|
|
+ {
|
|
|
+ return typeEventSystem.Register<T>(onEvent);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void UnRegisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent) where T : IEvent
|
|
|
+ {
|
|
|
+ typeEventSystem.UnRegister<T>(onEvent);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ITypeEventSystem typeEventSystem;
|
|
|
+ public static void SetTypeEventSystem(ITypeEventSystem mTypeEventSystem)
|
|
|
+ {
|
|
|
+ typeEventSystem = mTypeEventSystem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanSendCommand
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanSendCommandExtension
|
|
|
+ {
|
|
|
+ public static void SendCommand<T>(this ICanSendCommand self) where T : ICommand, new()
|
|
|
+ {
|
|
|
+ mCommandHandler.ExcuteCommand<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SendCommand<T>(this ICanSendCommand self, T command) where T : ICommand
|
|
|
+ {
|
|
|
+ mCommandHandler.ExcuteCommand(command);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static T SendCommand<T>(this ICanSendCommand self, ICommand<T> command)
|
|
|
+ {
|
|
|
+ return mCommandHandler.ExcuteCommand(command);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ICommandHandler mCommandHandler;
|
|
|
+ public static void SetCommandHandler(ICommandHandler commandHandler)
|
|
|
+ {
|
|
|
+ mCommandHandler = commandHandler;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanSendEvent
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanSendEventExtension
|
|
|
+ {
|
|
|
+ public static void SendEvent<T>(this ICanSendEvent self) where T : IEvent, new()
|
|
|
+ {
|
|
|
+ typeEventSystem.Send<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SendEvent<T>(this ICanSendEvent self, T e) where T : IEvent
|
|
|
+ {
|
|
|
+ typeEventSystem.Send<T>(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ITypeEventSystem typeEventSystem;
|
|
|
+ public static void SetTypeEventSystem(ITypeEventSystem mTypeEventSystem)
|
|
|
+ {
|
|
|
+ typeEventSystem = mTypeEventSystem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface ICanSendQuery
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static class CanSendQueryExtension
|
|
|
+ {
|
|
|
+ public static T SendQuery<T>(this ICanSendQuery self, IQuery<T> queryInstance)
|
|
|
+ {
|
|
|
+ return _queryHandler.DoQuery<T>(queryInstance);
|
|
|
+ }
|
|
|
+ public static K SendQuery<T, K>(this ICanSendQuery self) where T : IQuery<K>, new()
|
|
|
+ {
|
|
|
+ return _queryHandler.DoQuery<T, K>();
|
|
|
+ }
|
|
|
+ public static IQueryResult<T> SendQueryAsync<T>(this ICanSendQuery self, IQuery<T> queryInstance)
|
|
|
+ {
|
|
|
+ return _queryHandler.DoQueryAsync<T>(queryInstance);
|
|
|
+ }
|
|
|
+ public static IQueryResult<K> SendQueryAsync<T, K>(this ICanSendQuery self) where T : IQuery<K>, new()
|
|
|
+ {
|
|
|
+ return _queryHandler.DoQueryAsync<T, K>();
|
|
|
+ }
|
|
|
+ private static IQueryHandler _queryHandler;
|
|
|
+ public static void SetQueryHandler(IQueryHandler queryHandler)
|
|
|
+ {
|
|
|
+ _queryHandler = queryHandler;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region TypeEventSystem
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface IUnRegister
|
|
|
+ {
|
|
|
+ void UnRegister();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public interface IUnRegisterList
|
|
|
+ {
|
|
|
+ List<IUnRegister> UnRegistersList { get; }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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<IUnRegister> mUnRegisters = new HashSet<IUnRegister>();
|
|
|
+
|
|
|
+ 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<UnRegisterOnDestroyTrigger>();
|
|
|
+
|
|
|
+ if (!trigger)
|
|
|
+ {
|
|
|
+ trigger = go.AddComponent<UnRegisterOnDestroyTrigger>();
|
|
|
+ }
|
|
|
+
|
|
|
+ trigger.AddUnRegister(unRegister);
|
|
|
+
|
|
|
+ return unRegister;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static IUnRegister UnRegisterWhenGameObjectDestroyed<T>(this IUnRegister unRegister, T component) where T : Component
|
|
|
+ {
|
|
|
+ return unRegister.UnRegisterWhenGameObjectDestroyed(component.gameObject);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface ITypeEventSystem
|
|
|
+ {
|
|
|
+ IUnRegister Register<T>(Action<T> onEvent) where T: IEvent;
|
|
|
+ void UnRegister<T>(Action<T> onEvent) where T: IEvent;
|
|
|
+ void Send<T>() where T: IEvent, new();
|
|
|
+ void Send<T>(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<T>() where T : IEvent,new()
|
|
|
+ {
|
|
|
+ mEvents.GetEvent<EasyEvent<T>>()?.Trigger(new T());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Send<T>(T e) where T: IEvent
|
|
|
+ {
|
|
|
+ mEvents.GetEvent<EasyEvent<T>>()?.Trigger(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ public IUnRegister Register<T>(Action<T> onEvent)where T: IEvent
|
|
|
+ {
|
|
|
+ var e = mEvents.GetOrAddEvent<EasyEvent<T>>();
|
|
|
+ return e.Register(onEvent);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UnRegister<T>(Action<T> onEvent)where T: IEvent
|
|
|
+ {
|
|
|
+ var e = mEvents.GetEvent<EasyEvent<T>>();
|
|
|
+ if (e != null)
|
|
|
+ {
|
|
|
+ e.UnRegister(onEvent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region IOC
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public class IOCContainer
|
|
|
+ {
|
|
|
+ private Dictionary<Type, object> mInstances = new Dictionary<Type, object>();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void Register<T>(T instance)
|
|
|
+ {
|
|
|
+ Type key = typeof(T);
|
|
|
+
|
|
|
+ if (mInstances.ContainsKey(key))
|
|
|
+ {
|
|
|
+ mInstances[key] = instance;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ mInstances.Add(key, instance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public T Get<T>() 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>
|
|
|
+ {
|
|
|
+ T Value { get; }
|
|
|
+
|
|
|
+ IUnRegister Register(Action<T> onValueChanged);
|
|
|
+ void UnRegister(Action<T> onValueChanged);
|
|
|
+ IUnRegister RegisterWithInitValue(Action<T> action);
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IBindableProperty<T> : IReadonlyBindableProperty<T>
|
|
|
+ {
|
|
|
+ new T Value { get; set; }
|
|
|
+ void SetValueWithoutEvent(T newValue);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public class BindableProperty<T> : IBindableProperty<T>
|
|
|
+ {
|
|
|
+ private Action<T> 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<T> onValueChanged)
|
|
|
+ {
|
|
|
+ mOnValueChanged += onValueChanged;
|
|
|
+ return new BindablePropertyUnRegister<T>()
|
|
|
+ {
|
|
|
+ BindableProperty = this,
|
|
|
+ OnValueChanged = onValueChanged
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ public IUnRegister RegisterWithInitValue(Action<T> onValueChanged)
|
|
|
+ {
|
|
|
+ onValueChanged(mValue);
|
|
|
+ return Register(onValueChanged);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static implicit operator T(BindableProperty<T> property)
|
|
|
+ {
|
|
|
+ return property.Value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override string ToString()
|
|
|
+ {
|
|
|
+ return Value.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UnRegister(Action<T> onValueChanged)
|
|
|
+ {
|
|
|
+ mOnValueChanged -= onValueChanged;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class BindablePropertyUnRegister<T> : IUnRegister
|
|
|
+ {
|
|
|
+ public BindableProperty<T> BindableProperty { get; set; }
|
|
|
+
|
|
|
+ public Action<T> 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<T> : IEasyEvent
|
|
|
+ {
|
|
|
+ private Action<T> mOnEvent = e => { };
|
|
|
+
|
|
|
+ public IUnRegister Register(Action<T> onEvent)
|
|
|
+ {
|
|
|
+ mOnEvent += onEvent;
|
|
|
+
|
|
|
+ return new CustomUnRegister(() =>
|
|
|
+ {
|
|
|
+ UnRegister(onEvent);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UnRegister(Action<T> onEvent)
|
|
|
+ {
|
|
|
+ mOnEvent -= onEvent;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Trigger(T t)
|
|
|
+ {
|
|
|
+ mOnEvent?.Invoke(t);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class EasyEvent<T, K> : IEasyEvent
|
|
|
+ {
|
|
|
+ private Action<T, K> mOnEvent = (t, k) => { };
|
|
|
+
|
|
|
+ public IUnRegister Register(Action<T, K> onEvent)
|
|
|
+ {
|
|
|
+ mOnEvent += onEvent;
|
|
|
+
|
|
|
+ return new CustomUnRegister(() =>
|
|
|
+ {
|
|
|
+ UnRegister(onEvent);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UnRegister(Action<T, K> onEvent)
|
|
|
+ {
|
|
|
+ mOnEvent -= onEvent;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Trigger(T t, K k)
|
|
|
+ {
|
|
|
+ mOnEvent?.Invoke(t, k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class EasyEvent<T, K, S> : IEasyEvent
|
|
|
+ {
|
|
|
+ private Action<T, K, S> mOnEvent = (t, k, s) => { };
|
|
|
+
|
|
|
+ public IUnRegister Register(Action<T, K, S> onEvent)
|
|
|
+ {
|
|
|
+ mOnEvent += onEvent;
|
|
|
+
|
|
|
+ return new CustomUnRegister(() =>
|
|
|
+ {
|
|
|
+ UnRegister(onEvent);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UnRegister(Action<T, K, S> 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<T>() where T : IEasyEvent
|
|
|
+ {
|
|
|
+ return mGlobalEvents.GetEvent<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void Register<T>() where T : IEasyEvent, new()
|
|
|
+ {
|
|
|
+ mGlobalEvents.AddEvent<T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ private Dictionary<Type, IEasyEvent> mTypeEvents = new Dictionary<Type, IEasyEvent>();
|
|
|
+
|
|
|
+ public void AddEvent<T>() where T : IEasyEvent, new()
|
|
|
+ {
|
|
|
+ mTypeEvents.Add(typeof(T), new T());
|
|
|
+ }
|
|
|
+
|
|
|
+ public T GetEvent<T>() where T : IEasyEvent
|
|
|
+ {
|
|
|
+ if (mTypeEvents.TryGetValue(typeof(T), out IEasyEvent e))
|
|
|
+ {
|
|
|
+ return (T)e;
|
|
|
+ }
|
|
|
+
|
|
|
+ return default;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T GetOrAddEvent<T>() 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
|
|
|
+}
|