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

204 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}