一、首先定义一份消息号(消息号用来标记发出的每一条消息,接收者通过注册要监听的消息号来监听相应的消息)

public enum MSG_IDS
{
NONE = -,
MSG_TEST01 = ,
MSG_TEST02 = ,
}

二、然后定义一个消息类,作为消息的载体

public class Notification {
    MSG_IDS id = MSG_IDS.NONE; //消息号
    public MSG_IDS Id{get { return id; }}
    Dictionary<string, object> infos;// 消息内容,消息要传递的具体信息     public Notification(MSG_IDS id)
    {
        this.id = id;
        infos = new Dictionary<string, object>();
    }
   //消息索引器,用字符串做key(注意key不能重复)
    public object this[string id]
    {
        get {
            if(infos.ContainsKey(id))
            {
                return infos[id];
            }else
            {
                Debug.LogError("不存在参数:" + id);
                return null;
            }
        }
        set {
            if(infos.ContainsKey(id))
            {
                infos[id] = value;
            }else
            {
                infos.Add(id, value);
            }
        }
    }
}

三、组件ID生成器,这个主要用于标记组件内的事件,以便移除

public class IDCreator{
uint curMaxId = ;
List<uint> recycleIndex = new List<uint>();
public uint GetNewID()
{
if (recycleIndex.Count > )
{
uint id = recycleIndex[recycleIndex.Count - ];
recycleIndex.RemoveAt(recycleIndex.Count - );
return id;
}
if (curMaxId == UInt32.MaxValue)
{
Debug.LogError("ID 溢出");
return curMaxId;
}
return curMaxId++;
}
public void Recycle(uint id)
{
recycleIndex.Add(id);
}
}

四、消息管理器

public class MsgController{
    public delegate void MsgDel(Notification notify);
    private Dictionary<MSG_IDS, List<MsgDel>> MsgDic;
    private Dictionary<uint, Dictionary<MSG_IDS, MsgDel>> MsgDicMap;
    private static MsgController _instance = null;
    
    public static MsgController Instance
    {
        get
        {
            if(_instance == null)_instance = new MsgController();
            return _instance;
        }
    }     private static IDCreator _componentID = null;
    /// <summary>
    /// 组件唯一id生成器
    /// </summary>
    public static IDCreator ComponentID
    {
        get
        {
            if (_componentID == null) _componentID = new IDCreator();
            return _componentID;
        }
    }     /// <summary>
    /// 添加监听
    /// </summary>
    /// <param name="msgId"></param>
    /// <param name="msg"></param>
    public void AddNotification(uint index, MSG_IDS msgId, MsgDel msg)
    {
        try
        {
            if (MsgDic == null)
            {
                MsgDic = new Dictionary<MSG_IDS, List<MsgDel>>();
            }
            if (MsgDicMap == null)
            {
                MsgDicMap = new Dictionary<uint, Dictionary<MSG_IDS, MsgDel>>();
            }             //按消息号保存消息列表
            if (!MsgDic.ContainsKey(msgId))
            {
                List<MsgDel> list = new List<MsgDel>();
                MsgDic.Add(msgId, list);
            }
            MsgDic[msgId].Add(msg);
            //按id索引保存消息列表
            if (!MsgDicMap.ContainsKey(index))
            {
                Dictionary<MSG_IDS, MsgDel> map = new Dictionary<MSG_IDS, MsgDel>();
                MsgDicMap.Add(index, map);
            }
            MsgDicMap[index].Add(msgId, msg);
        }catch(Exception e)
        { throw (e); }
    }     /// <summary>
    /// 移除一个组件上的所有事件
    /// </summary>
    /// <param name="index"></param>
    public void RemoveAllNotification(uint index)
    {
        if(MsgDicMap.ContainsKey(index))
        {
            foreach (var map in MsgDicMap[index])
            {
                RemoveNotification(map.Key, map.Value);
            }
        MsgDicMap.Remove(index);
            _componentID.Recycle(index);//回收id以便重复利用
        }
    }     /// <summary>
    /// 移除某个id对应的监听事件
    /// </summary>
    /// <param name="msgId"></param>
    /// <param name="msg"></param>
    public void RemoveNotification(MSG_IDS msgId, MsgDel msg)
    {
        try
        {
            MsgDic[msgId].Remove(msg);
        }catch(Exception e)
        {
            Debug.LogError("找不到消息:" + msgId);
            throw(e);
        }
    }     /// <summary>
    /// 发送通知
    /// </summary>
    /// <param name="notify"></param>
    public void SendMsg(Notification notify)
    {
        try
        {
            if (MsgDic.ContainsKey(notify.Id))
            {
                List<MsgDel> msgs = MsgDic[notify.Id];
                for (int i = 0; i < msgs.Count; i++)
                {
                    msgs[i](notify);
                }
            }
        }catch(Exception e)
        { throw (e); }
    }

四、发送、接收消息实例

public class Sender : MonoBehaviour {
   int n = 0;public void Btn1()
{
Notification notify = new Notification(MSG_IDS.MSG_TEST01);
        notify["text"] = "第" + (++n) + "次 string ";
        MsgController.Instance.SendMsg(notify);
}
  int m = 0;public void Btn2()
{
Notification notify = new Notification(MSG_IDS.MSG_TEST02);
        notify["value"] = ++m;
        MsgController.Instance.SendMsg(notify);
}
}
public class Listener01 : MonoBehaviour
{
    uint eventIndex = 0;
    void OnEnable()
    {
        eventIndex = MsgController.ComponentID.GetNewID();//获取一个组件id,这个id的意义在于,当一个组件上加了很多监听时,不需要一个个移除。一个个移除很麻烦,也很容易出错
        MsgController.Instance.AddNotification(eventIndex, MSG_IDS.MSG_TEST01, MsgListener01);
        MsgController.Instance.AddNotification(eventIndex, MSG_IDS.MSG_TEST02, MsgListener02);
    }     void OnDisable()
    {
        MsgController.Instance.RemoveAllNotification(eventIndex);//移除所有组件id为eventIndex的监听(并不关心eventIndex的值是多少)
    }     public void MsgListener01(Notification notify)
    {
        string text = (string)notify["text"];
        Debug.LogError(transform.name + " " + text);
    }     public void MsgListener02(Notification notify)
    {
        int v = (int)notify["value"];
        Debug.LogError(transform.name + " " + v.ToString());
    }
}

Unity 消息管理(观察煮模式)的更多相关文章

  1. 4.Node.js 微信消息管理

    一.写在前面的话   当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应.   消息推送也是 ...

  2. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  3. 九、EnterpriseFrameWork框架基础功能之消息管理

    记得阿朱在<走出软件作坊>一书中有一章讲客户提的需求太邪门了,鼠标键盘不太会用要程序员开发一个语音输入功能,还要系统中带类似QQ的功能:确实刚开始的客户的想法有点天真,但是随着信息化的越来 ...

  4. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版新增消息管理

    在V3.0版本的Web(Mvc.WebForm)与WinForm中我们新增了“消息管理”模块.“消息管理”模块是对框架的所有消息进行管理.通过左侧的消息分类可以查看所选分类的所有消息列表.在主界面上我 ...

  5. 微信公众号开发C#系列-7、消息管理-接收事件推送

    1.概述 在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息.其中,某些事件推送在发生后,是允许 ...

  6. 微信公众号开发C#系列-6、消息管理-普通消息接受处理

    1.概述 通过前面章节的学习,我们已经对微信的开发有了基本的掌握与熟悉,基本可以上手做复杂的应用了.本篇我们将详细讲解微信消息管理中普通消息的接收与处理.当普通微信用户向公众账号发消息时,微信服务器将 ...

  7. 使用Ajax轮询模拟简单的站内信箱(消息管理)功能

    前一段时间项目需要写一个类似于站内信箱的消息管理的功能,由于对前端不是很熟悉,刚开始不知道怎么做,后来看了网上的方案,现模拟一个非常简单的消息管理. 我们首先看一下最终效果的样式,就是非常简单的一个样 ...

  8. 17.0-uC/OS-III消息管理

    消息传递 有些情况下任务或ISR与另一个任务间进行通信,这种信息交换叫做作业间的通信. 可以有两种方法实现这种通信: 全局变量. 发送消息. 1.果使用全局变量,任务或ISR就须确保它独占该变量.如果 ...

  9. Unity消息简易框架 Advanced C# messenger

    Unity消息简易框架 Advanced C# messenger Unity C# 消息机制  [转载 雨凇MOMO博客] https://www.xuanyusong.com/archives/2 ...

随机推荐

  1. window的Navigator 对象

    Navigator 对象包含有关浏览器的信息. Navigator 对象属性 document.write("浏览器的代码名:" + navigator.appCodeName + ...

  2. http请求之get和post的区别

    前言:大家现在度娘一下,查得最多的区别,可能就是: “Get把参数写在URL中,Post通过请求体来传参的” “GET没有POST安全,因为Get参数直接显示在URL上” “Get请求在URL中传送的 ...

  3. Gitlab--安装及汉化

    简介 gitlab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git 项目仓库,可通过Web界面迚行访问公开的戒者私人项目.Ruby on Rails 是一个可以使你开 ...

  4. ScrollView与ListView的事件冲突

    布局文件 当ListView嵌套在ScrollView中时,会发生冲突,导致ListView控件的拉动效果消失‘ 解决办法: 重写ListView的onTouchEvent(),并在返回前调用getP ...

  5. mv,rm等命令出现unrecognized option提示的解决方法

    出现这个提示,一般是由于命令操作的文件名最前面有"--"字符, 让命令误以为是--开头的长选项 解决: 命令后加上"--", shell把 -- 之后的参数当做 ...

  6. maven(二):创建一个可用的maven项目,完整过程

    环境:eclipse4.5 (内置maven插件) 创建maven项目 文件菜单--新建--其他-- maven project 下一步 选择web 结构 group id:  指项目在maven本地 ...

  7. [20171214]hashcat破解oracle口令.txt

    [20171214]hashcat破解oracle口令.txt hashcat is the world's fastest and most advanced password recovery u ...

  8. 洗礼灵魂,修炼python(46)--巩固篇—如虎添翼的property

    @property 在前面装饰器一章中,提过一句话,装饰器也可以用于类中,确实可以的,并且python的类也内置了一部分装饰器.并且在前两章的hasattr等四个内置方法中,也说过其用法很类似装饰器, ...

  9. Intel P4 CPU

    1. P4 CPU 结构 奔4处理器是Intel的经典之作,它是采用乱序执行内核的超标量处理器.P4采用的微架构称为 Net Burst,基本结构如下: 奔4处理器微架构被分成了4大部分: (1)存储 ...

  10. Resct配置less

    配置less 安装less-loader yarn add less-loader 打开 webpack.config.dev.js 和 webpack.config.prod.js 找到  test ...