签到

05月05日
尚未签到

共有回帖数 0

    下一点守候

    等级:
    什么是消息机制?








    23333333,让我先笑一会。为什么用消息机制?  三个字,解!!!!耦!!!!合!!!!。我的框架中的消息机制用例:1.接收者using UnityEngine;  
    using System.Collections;

    using QFramework;

    /// summary/// 1.接收者需要实现IMsgReceiver接口。/// 2.使用this.RegisterLogicMsg注册消息和回调函数。/// /summarypublicclass Receiver : MonoBehaviour,IMsgReceiver {

       voidAwake(){
           this.RegisterLogicMsg ("Receiver Show Sth", ReceiverMsg);

    //        this.UnRegisterLogicMsg ("Receiver Show Sth", ReceiverMsg);

       }


       voidReceiverMsg(params object[] paramList){
           foreach (var sth in paramList) {
               QPrint.Warn (sth.ToString());
           }
       }
    }
    2.发送者using UnityEngine;  
    using System.Collections;  
    using QFramework;

    /// summary/// 1.发送者需要,实现IMsgSender接口/// 2.调用this.SendLogicMsg发送Receiver Show Sth消息,并传入两个参数/// /summarypublicclass Sender : MonoBehaviour,IMsgSender {

       // Update is called once per framevoidUpdate(){
           this.SendLogicMsg ("Receiver Show Sth","你好","世界");
       }
    }
    3.运行结果



    使用起来几行代码的事情,实现起来就没这么简单了。如何实现的?  可以看到接收者实现了接口IMsgReceiver,发送者实现了接口IMsgSender。 那先看下这两个接口定义。
    IMsgReceiver:using UnityEngine;  
    using System.Collections;

    namespaceQFramework {

       publicinterfaceIMsgReceiver  {


       }
    }
    IMsgSenderusing UnityEngine;  
    using System.Collections;

    namespaceQFramework {

       publicinterfaceIMsgSender  {

       }
    }
    毛都没有啊。也没有SendLogicMsg或者ReceiveLogicMsg方法的定义啊。答案是使用C# this的扩展方式实现接口方法。 不清楚的童鞋请百度C# this扩展,有好多文章就不介绍了。 以上先告一段落,先介绍个重要的角色,MsgDispatcher(消息分发器)。贴上第一部分代码:namespaceQFramework {  
       ///summary/// 消息分发器/// C# this扩展 需要静态类////summarypublicstaticclassQMsgDispatcher  {

           ///summary/// 消息捕捉器////summaryclassLogicMsgHandler {

               public IMsgReceiver receiver;
               public  VoidDelegate.WithParams callback;

               /*
                * VoidDelegate.WithParams 是一种委托 ,定义是这样的
                *
                *  public class VoidDelegate{
                *      public delegate void WithParams(params object[] paramList);
                *  }
                */publicLogicMsgHandler(IMsgReceiver receiver,VoidDelegate.WithParams callback){
                   this.receiver = receiver;
                   this.callback = callback;
               }
           }

           ///summary/// 每个消息名字维护一组消息捕捉器。////summarystatic Dictionarystring,ListLogicMsgHandler mMsgHandlerDict = new Dictionarystring,ListLogicMsgHandler ();
    读注释!!!贴上注册消息的代码///summary/// 注册消息,/// 注意第一个参数,使用了C# this的扩展,/// 所以只有实现IMsgReceiver的对象才能调用此方法////summarypublicstaticvoidRegisterLogicMsg(this IMsgReceiver self, string msgName,VoidDelegate.WithParams callback){
               // 略过if (string.IsNullOrEmpty(msgName)) {
                   QPrint.FrameworkWarn("RegisterMsg:" + msgName + " is Null or Empty");
                   return;
               }

               // 略过if (null == callback) {
                   QPrint.FrameworkWarn ("RegisterMsg:" + msgName + " callback is Null");
                   return;
               }

               // 略过if (!mMsgHandlerDict.ContainsKey (msgName)) {
                   mMsgHandlerDict [msgName] = new ListLogicMsgHandler ();
               }

               // 看下这里var handlers = mMsgHandlerDict [msgName];

               // 略过// 防止重复注册foreach (var handler in handlers) {
                   if (handler.receiver == self && handler.callback == callback) {
                       QPrint.FrameworkWarn ("RegisterMsg:" + msgName + " ayready Register");
                       return;
                   }
               }

               // 再看下这里
               handlers.Add (new LogicMsgHandler (self, callback));
           }
    为了节省您时间,略过部分的代码就不要看了,什么?!!你都看了!!!! 23333发送消息相关的代码///summary/// 发送消息/// 注意第一个参数////summarypublicstaticvoidSendLogicMsg(this IMsgSender sender, string msgName,paramsobject[] paramList ){
               // 略过,不用看if (string.IsNullOrEmpty(msgName)) {
                   QPrint.FrameworkError("SendMsg is Null or Empty");
                   return;
               }

               // 略过,不用看if (!mMsgHandlerDict.ContainsKey(msgName)){
                   QPrint.FrameworkWarn("SendMsg is UnRegister");
                   return;
               }

               // 开始看!!!!var handlers = mMsgHandlerDict[msgName];


               var handlerCount = handlers.Count;

               // 之所以是从后向前遍历,是因为  从前向后遍历删除后索引值会不断变化// 参考文章,http://www.2cto.com/kf/201312/266723.htmlfor (int index = handlerCount - 1;index = 0;index--)
               {
                   var handler = handlers[index];

                   if (handler.receiver != null) {
                       QPrint.FrameworkLog ("SendLogicMsg:" + msgName + " Succeed");
                       handler.callback (paramList);
                   } else {
                       handlers.Remove (handler);
                   }
               }
           }
    OK主要的部分全都贴出来啦
    以上代码以全部上传到Github上边
    贴出代码地址:消息机制相关代码地址可以改进的地方:  1.目前整个游戏的消息都由一个字典维护,可以改进为每个模块维护一个字典或者其他方式。   2.消息名字类型由字符串定义的,可以改成枚举转unsigned int方式。   3.欢迎补充。坑  1.如果是MonoBehaviour注册消息之后,GameObject Destroy之前一定要注销消息,之前的解决方案是,自定义一个基类来维护该对象已经注册的消息列表,然后在基类的OnDestory时候遍历卸载。   2.欢迎补充。附:我的框架地址
    转载请注明地址:凉鞋的笔记

    楼主 2016-10-29 14:10 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知