QFrameWork学习(二) 简易消息机制

文章地址:https://www.cnblogs.com/liangxiegame/p/Unity-you-xi-kuang-jia-da-jian-wu-jian-yi-xiao-xi-.html

 

一、遍历list删除元素

       说简易消息机制之前,文章里有个细节点,就是遍历list删除其中的元素。这里使用了反向循环,原因解释一下。比如一个list 含 A B C D E F,假设此时遍历到i=3这时候删除D,同时E也顺位变成索引3,此时再遍历下去就会接着4开始走,那么就落下了一个元素。为了解决这个问题使用反向循环就OK了。

 

二、简易消息机制

        说实话,知道消息机制是非常好用且常用的,但是具体应该在哪里用合适,看完这篇文章也并没有明白,只不过是知道了大概的实现方式。

        首先有两个接口类:

public interface IMsgSender
{
}

public interface IMsgReceiver 
{
}

 

        这里没有任何东西,原文中将注册和发送的方法写成了this扩展方法,可能是为了他那个实现方便。接下来是个消息分发器,配合C#中this扩展方法使用静态类

public static class QMsgDispatcher  {
    /// 
    /// 每个消息名字维护一组消息捕捉器。
    /// 
    private static Dictionary> mMsgHandlerDict
        = new Dictionary> ();
        
    class LogicMsgHandler {

        public IMsgReceiver receiver;
        public  VoidDelegate.WithParams callback;

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

 

        这里就是注册时使用,保存一个接收消息的对象和回调方法。接下来就将注册的消息和方法都保存在字典对象里。

    /// 
    /// 注册消息,
    /// 注意第一个参数,使用了C# this的扩展,
    /// 所以只有实现IMsgReceiver的对象才能调用此方法
    /// 
    public static void RegisterLogicMsg(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 List ();
        }

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

       发送消息的时候,遍历调用每个注册者储存的回调,如果注册者为空就从列表中删除。这里使用了反向删除,由于是在遍历同时删除,原因一开始我解释了。

    /// 
    /// 发送消息
    /// 注意第一个参数
    /// 
    public static void SendLogicMsg(this IMsgSender sender, string msgName,params object[] 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;

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

 

 

        这里都使用了字符串,可以改成枚举转int。然后也只有一个字典,应该可以根据需要改成多个字典或者其他的方式。代码还是很简单,并且从需求上来讲,和本身的事件的作用有些相似。

 

你可能感兴趣的:(#,框架QFramework)