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
}