http://www.voidcn.com/article/p-wgsrxllo-btn.html
https://www.cnblogs.com/cyjb/archive/2013/03/21/DelegateBuilder.html
队列初始化时会把非继承自MonoBehaviour的自动注册到消息事件
自动把类的所有不同参数的OnHandle注册到事件字典
对模块间的消息进行解耦,和消息中心是一样的
继承自MonoBehaviour的函数,自己在Awake注册消息事件
using UnityEngine;
public class Test : MonoBehaviour
{
private void Awake()
{
MsgEventManager.AddEvent(this);
}
private void Start()
{
Msg.Send();//发送消息
Msg.Send(6);
}
public void OnHandle(int x)
{
Debug.Log(x);
}
void OnHandle()
{
Debug.Log("Test");
}
}
public class Test2
{
void OnHandle()
{
Debug.Log("miao");
}
}
using System.Collections.Generic;
using System.Text;
public class Msg : MonoSingle {
bool isSendComplete= true;
static StringBuilder stringBuilder = new StringBuilder();
Queue queue = new Queue();
public static void Send()
{
Inst.queue.Enqueue(new Data { key = string.Empty, parameter = null });
}
public static void Send(T arg)
{
Inst.queue.Enqueue(new Data{key= arg.GetType().Name, parameter= new object[1] { arg } });
}
public static void Send(T arg, T1 arg1)
{
object[] parameter = new object[2];
parameter[0] = arg;
parameter[1] = arg1;
stringBuilder.Append(arg.GetType().Name);
stringBuilder.Append(arg1.GetType().Name);
Inst.queue.Enqueue(new Data{key=stringBuilder.ToString(),parameter=parameter});
stringBuilder.Length=0;
}
public static void Send(T arg,T1 arg1,T2 arg2)
{
object[] parameter = new object[3];
parameter[0] = arg;
parameter[1] = arg1;
parameter[2] = arg2;
stringBuilder.Append(arg.GetType().Name);
stringBuilder.Append(arg1.GetType().Name);
stringBuilder.Append(arg2.GetType().Name);
Inst.queue.Enqueue(new Data{key=stringBuilder.ToString(),parameter=parameter});
stringBuilder.Length=0;
}
public static void Send(T arg,T1 arg1,T2 arg2,T3 arg3)
{
object[] parameter = new object[4];
parameter[0] = arg;
parameter[1] = arg1;
parameter[2] = arg2;
parameter[3] = arg3;
stringBuilder.Append(arg.GetType().Name);
stringBuilder.Append(arg1.GetType().Name);
stringBuilder.Append(arg2.GetType().Name);
stringBuilder.Append(arg3.GetType().Name);
Inst.queue.Enqueue(new Data{key=stringBuilder.ToString(),parameter=parameter});
stringBuilder.Length=0;
}
public static void Send(T arg,T1 arg1,T2 arg2,T3 arg3,T4 arg4)
{
object[] parameter = new object[5];
parameter[0] = arg;
parameter[1] = arg1;
parameter[2] = arg2;
parameter[3] = arg3;
parameter[4] = arg4;
stringBuilder.Append(arg.GetType().Name);
stringBuilder.Append(arg1.GetType().Name);
stringBuilder.Append(arg2.GetType().Name);
stringBuilder.Append(arg3.GetType().Name);
stringBuilder.Append(arg4.GetType().Name);
Inst.queue.Enqueue(new Data{key=stringBuilder.ToString(),parameter=parameter});
stringBuilder.Length=0;
}
void Update ()
{
if(queue.Count>0 && isSendComplete)
{
isSendComplete = false;
var data = queue.Dequeue();
MsgEventManager.Inst.Invoke(data.key,data.parameter);
isSendComplete = true;
}
}
struct Data
{
public string key;
public object [] parameter;
}
}
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using UnityEngine;
public class MsgEventManager:Single
{
static readonly string handleStr="OnHandle";
static Type monoBehaviour = typeof(MonoBehaviour);
Dictionary dic = new Dictionary();
StringBuilder stringBuilder = new StringBuilder();
public MsgEventManager()
{
var assembly = Assembly.GetAssembly(typeof(MsgEventManager));
foreach(var type in assembly.GetTypes())
{
if (IsSubclassOfMonoBehaviour(type) || type.IsInterface)
continue;
var methods = type.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
foreach (var method in methods)
{
if (method.Name == handleStr)
{
var key = GetKey(method);
var instance = Activator.CreateInstance(type);
AddMethod(key, instance, method);
}
}
}
}
public static void AddEvent(object obj)
{
var type = obj.GetType();
var methods = type.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
foreach(var method in methods)
{
if(method.Name == handleStr)
{
var key = Inst.GetKey(method);
Inst.AddMethod(key, obj, method);
}
}
}
public void Invoke(string key, object[]parameter)
{
if (!dic.ContainsKey(key))
return;
dic[key].DynamicInvoke(parameter);
}
void AddMethod(string key, object obj, MethodInfo method)
{
var tmp = CreateDelegate(obj, method);
if (!dic.ContainsKey(key))
{
dic.Add(key, tmp);
}
else
{
dic[key] = Delegate.Combine(dic[key], tmp);
}
}
bool IsSubclassOfMonoBehaviour(Type type)
{
while (type != null)
{
if (type == monoBehaviour)
{
return true;
}
type = type.BaseType;
}
return false;
}
string GetKey(MethodInfo value)
{
foreach(var parameter in value.GetParameters())
{
stringBuilder.Append(parameter.ParameterType.Name);
}
string result = stringBuilder.ToString();
stringBuilder.Length=0;
return result;
}
private Delegate CreateDelegate(object instance, MethodInfo method)
{
var parametersInfo = method.GetParameters();
Expression[] expArgs = new Expression[parametersInfo.Length];
List lstParamExpressions = new List();
for (int i = 0; i < expArgs.Length; i++)
{
expArgs[i] = Expression.Parameter(parametersInfo[i].ParameterType, parametersInfo[i].Name);
lstParamExpressions.Add((ParameterExpression)expArgs[i]);
}
MethodCallExpression callExpression = Expression.Call(Expression.Constant(instance), method, expArgs);
LambdaExpression lambdaExpression = Expression.Lambda(callExpression, lstParamExpressions.ToArray());
return lambdaExpression.Compile();
}
}