using System; using System.Collections.Generic; using System.Text; namespace BITKit { /// 泛型事件,简单的事件接口 public interface IGenericEvent { void AddListener(Action action); void Invoke(T value); void Invoke() where T : new(); void RemoveListener(Action action); void AddListener(TKey key, Action action); void Invoke(TKey key, T value); void RemoveListener(TKey key, Action action); void SetDirect(int key, object value); void GetDirect(int key, out object value); void GetDirect(int key,out T value); } /// 泛型数据库,主要使用方式为Get和Set public interface IDatabase { T Get(string key = Constant.System.Internal); void Set(T value); void Set(string key = Constant.System.Internal, T value = default); } public class GenericEvent : IGenericEvent, IDatabase { private readonly Dictionary _directDirection = new(); private readonly Dictionary> events = new(); private readonly Dictionary dictionary = new(); public const string defaultEventName = nameof(GenericEvent); public void Clear() { _directDirection.Clear(); events.Clear(); dictionary.Clear(); } public void AddListener(Action action) => AddListener(defaultEventName, action); public void Invoke(T value) => Invoke(defaultEventName, value); public void RemoveListener(Action action) => RemoveListener(defaultEventName, action); public void AddListener(string key, Action action) { key = key.GetType(); var list = events.Get(key); list.Add(action); } public void AddListenerDirect(string key, Action action) { events.Get(key).Add(action); } public void Invoke(string key, T value) { key = key.GetType(); var list = events.Get(key); dictionary.Set(key, value); list.ToArray().ForEach(x => { if (x is Action action) { action.Invoke(value); } }); } public void InvokeDirect(string key,object value) { foreach (var x in events.Get(key)) { if (x is Action action) { //Console.WriteLine(action.Method); action.Invoke(value); } else { throw new ArgumentException($"事件{key}的监听器{x}不是Action类型"); } } // list.ToArray().ForEach(x => // { // if (x is Action action) // { // action.Invoke(value); // } // else // { // Console.WriteLine(x); // } // }); } public void Invoke(string typeName, object value) { var key = $"{typeName}.{defaultEventName}"; var list = events.Get(key); //BIT4Log.Log($"{key}\t@\t{list.Count}"); foreach (var item in list.ToArray()) { //BIT4Log.Log($"event:{item}"); item.GetType().GetMethod("Invoke").Invoke(item, new object[] { value }); } } public T Get(string key = Constant.System.Internal) { key = key.GetType(); var value = dictionary.Get(key); if (value is T t) { return t; } return default; } public object Get(string key = Constant.System.Internal) { return dictionary[key]; } public void Set(T value) => dictionary.Set(Constant.System.Internal.GetType(), value); public void Set(string key, T value) => dictionary.Set(key.GetType(), value); public void Set(Type type, object value) => dictionary.Set($"{type.FullName}.{Constant.System.Internal}", value); public void SetDirect(string key, object value) => dictionary.Set(key, value); public void RemoveListener(string key, Action action) { key = key.GetType(); var list = events.Get(key); list.TryRemove(action); } public void SetDirect(int key, object value) { _directDirection.Set(key, value); } public void GetDirect(int key,out object value) { value = _directDirection.Get(key); } public T GetOrAddDirect(int key,Func factory) { if (_directDirection.TryGetValue(key, out var v)) return v is T t ? t : default; var value = factory.Invoke(); _directDirection.Add(key, value); return value; } public void GetDirect(int key,out T value) { try { value = (T) _directDirection.Get(key); } catch (InvalidCastException) { value = default; } } public void DebugAllValues() { StringBuilder stringBuilder = new(); stringBuilder.AppendLine($"Event Count:{events.Count}"); foreach (var x in events) { stringBuilder.AppendLine(x.ToString()); } BIT4Log.Log(stringBuilder); } public string GetName() => nameof(GenericEvent); public object GetDiagnostics() { StringBuilder stringBuilder = new("——————Dictionary"); foreach (var x in dictionary) { stringBuilder.AppendLine(x.ToString()); } stringBuilder.AppendLine("——————Events"); foreach (var x in events) { stringBuilder.AppendLine($"{x.Key}\t{x.Value.Count}"); } return stringBuilder; } public void Invoke() where T : new() => Invoke(new T()); public bool TryGetObjectDirect(string key, out object value) { return dictionary.TryGetValue(key, out value); } } }