Net.Like.Xue.Tokyo/Assets/BITKit/Core/Utility/GenericEvent.cs

204 lines
6.6 KiB
C#
Raw Normal View History

2024-11-03 16:42:23 +08:00
using System;
using System.Collections.Generic;
using System.Text;
namespace BITKit
{
/// <summary>泛型事件,简单的事件接口</summary>
public interface IGenericEvent<TKey>
{
void AddListener<T>(Action<T> action);
void Invoke<T>(T value);
void Invoke<T>() where T : new();
void RemoveListener<T>(Action<T> action);
void AddListener<T>(TKey key, Action<T> action);
void Invoke<T>(TKey key, T value);
void RemoveListener<T>(TKey key, Action<T> action);
void SetDirect(int key, object value);
void GetDirect(int key, out object value);
void GetDirect<T>(int key,out T value);
}
/// <summary>泛型数据库主要使用方式为Get和Set</summary>
public interface IDatabase
{
T Get<T>(string key = Constant.System.Internal);
void Set<T>(T value);
void Set<T>(string key = Constant.System.Internal, T value = default);
}
public class GenericEvent : IGenericEvent<string>, IDatabase
{
private readonly Dictionary<int,object> _directDirection = new();
private readonly Dictionary<string, List<object>> events = new();
private readonly Dictionary<string, object> dictionary = new();
public const string defaultEventName = nameof(GenericEvent);
public void Clear()
{
_directDirection.Clear();
events.Clear();
dictionary.Clear();
}
public void AddListener<T>(Action<T> action) =>
AddListener<T>(defaultEventName, action);
public void Invoke<T>(T value) =>
Invoke<T>(defaultEventName, value);
public void RemoveListener<T>(Action<T> action) =>
RemoveListener<T>(defaultEventName, action);
public void AddListener<T>(string key, Action<T> action)
{
key = key.GetType<T>();
var list = events.Get(key);
list.Add(action);
}
public void AddListenerDirect(string key, Action<object> action)
{
events.Get(key).Add(action);
}
public void Invoke<T>(string key, T value)
{
key = key.GetType<T>();
var list = events.Get(key);
dictionary.Set(key, value);
list.ToArray().ForEach(x =>
{
if (x is Action<T> action)
{
action.Invoke(value);
}
});
}
public void InvokeDirect(string key,object value)
{
foreach (var x in events.Get(key))
{
if (x is Action<object> action)
{
//Console.WriteLine(action.Method);
action.Invoke(value);
}
else
{
throw new ArgumentException($"事件{key}的监听器{x}不是Action<object>类型");
}
}
// list.ToArray().ForEach(x =>
// {
// if (x is Action<object> 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<GenericEvent>($"{key}\t@\t{list.Count}");
foreach (var item in list.ToArray())
{
//BIT4Log.Log<GenericEvent>($"event:{item}");
item.GetType().GetMethod("Invoke").Invoke(item, new object[] { value });
}
}
public T Get<T>(string key = Constant.System.Internal)
{
key = key.GetType<T>();
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>(T value) => dictionary.Set(Constant.System.Internal.GetType<T>(), value);
public void Set<T>(string key, T value) => dictionary.Set(key.GetType<T>(), 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<T>(string key, Action<T> action)
{
key = key.GetType<T>();
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<T>(int key,Func<T> 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<T>(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<GenericEvent>(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<T>() where T : new() => Invoke(new T());
public bool TryGetObjectDirect(string key, out object value)
{
return dictionary.TryGetValue(key, out value);
}
}
}