Unity 消息队列
程序开发
2023-09-18 20:00:44
参考链接
http://www.voidcn.com/article/p-wgsrxllo-btn.html
https://www.cnblogs.com/cyjb/archive/2013/03/21/DelegateBuilder.html
这个队列做了什么
队列初始化时会把非继承自MonoBehaviour的自动注册到消息事件
自动把类的所有不同参数的OnHandle注册到事件字典
对模块间的消息进行解耦,和消息中心是一样的
继承自MonoBehaviour的怎么办
继承自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();}
}
标签:
上一篇:
Angular 快速上手
下一篇:
相关文章
-
无相关信息