关于订阅事件的理解,借鉴博客Circle,学习总结
订阅者模式和事件机制
原文链接:http://blog.csdn.net/u013108312/article/details/52184686
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UniEventDispatcher
{
/// <summary>
/// 定义事件分发委托
/// </summary>
public delegate void OnNotification(Notification notific);
/// <summary>
///通知中心
/// </summary>
public class NotificationCenter
{
/// <summary>
/// 通知中心单例
/// </summary>
private static NotificationCenter instance = null;
public static NotificationCenter Get()
{
if (instance == null)
{
instance = new NotificationCenter();
return instance;
}
return instance;
}
/// <summary>
/// 存储事件的字典
/// </summary>
private Dictionary<string, OnNotification> eventListeners
= new Dictionary<string, OnNotification>();
/// <summary>
/// 注册事件
/// </summary>
/// <param name="eventKey">事件Key</param>
/// <param name="eventListener">事件监听器</param>
public void AddEventListener(string eventKey, OnNotification eventListener)
{
if (!eventListeners.ContainsKey(eventKey))
{
eventListeners.Add(eventKey, eventListener);
}
}
/// <summary>
/// 移除事件
/// </summary>
/// <param name="eventKey">事件Key</param>
public void RemoveEventListener(string eventKey)
{
if (!eventListeners.ContainsKey(eventKey))
return;
eventListeners[eventKey] = null;
eventListeners.Remove(eventKey);
}
/// <summary>
/// 分发事件
/// </summary>
/// <param name="eventKey">事件Key</param>
/// <param name="notific">通知</param>
public void DispatchEvent(string eventKey, Notification notific)
{
if (!eventListeners.ContainsKey(eventKey))
return;
eventListeners[eventKey](notific);
}
/// <summary>
/// 分发事件
/// </summary>
/// <param name="eventKey">事件Key</param>
/// <param name="sender">发送者</param>
/// <param name="param">通知内容</param>
public void DispatchEvent(string eventKey, GameObject sender, object param)
{
if (!eventListeners.ContainsKey(eventKey))
return;
eventListeners[eventKey](new Notification(sender, param));
}
/// <summary>
/// 分发事件
/// </summary>
/// <param name="eventKey">事件Key</param>
/// <param name="param">通知内容</param>
public void DispatchEvent(string eventKey, object param)
{
if (!eventListeners.ContainsKey(eventKey))
return;
eventListeners[eventKey](new Notification(param));
}
/// <summary>
/// 是否存在指定事件的监听器
/// </summary>
public Boolean HasEventListener(string eventKey)
{
return eventListeners.ContainsKey(eventKey);
}
}
}
注意到在这个“通知中心”中,我们首先实现了单例模式,这样我们可以通过Get方法来获取该“通知中心”的唯一实例,其次这里利用一个字典来存储对所有事件的引用,这样保证外部可以通过AddEventListener和RemoveEventListener这两个方法来进行事件的添加和移除,对于添加的事件引用我们可以通过DispatchEvent方法来分发一个事件,事件的回调函数采用委托来实现,注意到这个委托需要一个Notification类型,对该类型简单定义如下:
using System;
using UnityEngine;
namespace UniEventDispatcher
{
public class Notification
{
/// <summary>
/// 通知发送者
/// </summary>
public GameObject sender;
/// <summary>
/// 通知内容
/// 备注:在发送消息时需要装箱、解析消息时需要拆箱
/// 所以这是一个糟糕的设计,需要注意。
/// </summary>
public object param;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sender">通知发送者</param>
/// <param name="param">通知内容</param>
public Notification(GameObject sender, object param)
{
this.sender = sender;
this.param = param;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="param"></param>
public Notification(object param)
{
this.sender = null;
this.param = param;
}
/// <summary>
/// 实现ToString方法
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("sender={0},param={1}", this.sender, this.param);
}
}
}
使用事件机制的一个示例
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UniEventDispatcher;
public class Example : MonoBehaviour
{
void Start()
{
//在接收者中注册事件及其回调方法
NotificationCenter.Get().AddEventListener("ChangeValue", ChangeValue);
}
void Update()
{
if (Input.GetMouseButtonDown(0)){
OnValueChanged(Random.Range(0,100));
}
}
public void OnValueChanged(float value)
{
//分发事件,注意和接收者协议一致
NotificationCenter.Get().DispatchEvent("ChangeValue", value);
}
/// <summary>
/// 得到的数值
/// </summary>
/// <param name="notific"></param>
public void ChangeValue(Notification notific)
{
Debug.Log("接受到的数值:"+notific.param.ToString());
}
/// <summary>
/// 移除订阅事件
/// </summary>
void OnDestroy()
{
NotificationCenter.Get().RemoveEventListener("ChangeValue");
}
}