素材巴巴 > 程序开发 >

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 快速上手 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。