一个监听对象触发多个委托方法~~~~~~~~~~~~~~~~~~~~~
关于委托,简单又不简单,挺饶人的。。。
下面一则逻辑,就是使用委托来完成的,它主要是通过一个类来统一管理委托,包括添加监听事件、删去监听事件、挂起监听事件。
作用:
1、 可用来添加相同数据类型的事件,通过数据类型来调用所有被监听的同一数据类型的事件
2、 可用来添加不同数据类型的事件,通过数据类型来调用被监听的事件
优点在于便于管理,可以注册所有数据类型的委托方法,
但是可以只让其中具有相同数据类型的委托方法执行,其他数据类型的委托方法不执行。(可以部分委托方法执行)
而一般“ += ”添加注册委托的方法,则不能一次只执行其中一部分的委托。(不可以部分委托方法执行)
单例类,用来统一管理委托的脚本:
using System;
using System.Collections.Generic;
using UnityEngine;
public class EventArgs
{
}
public class EventManager
{
public static EventManager _eventManager;
public static EventManager GetInstance()
{
if(_eventManager ==null)
{
_eventManager = new EventManager();
}
return _eventManager;
}
//定义委托,带有一个参数e方法,类型为T
//T相当于类型的泛型,可以代指任何类型,比如ing,sting等等。EventDelegate<T>是类数据类型
public delegate void EventDelegate<T>(T e) where T: EventArgs;
//定义字典,_daletate
readonly Dictionary <Type,Delegate> _delegate = new Dictionary<Type, Delegate>();
//添加监听
public void AddListener <T> (EventDelegate<T> listener) where T: EventArgs//参数表示事件
{
Delegate d;
//获取与制定键相关联的值,放入d中,没有则为false,有则为true。
if(_delegate.TryGetValue(typeof(T),out d))
{
//Combine()新的委托,它的调用列表将 d 和 listener 的调用列表按该顺序连接在一起。 如果 listener 为 null,
//则返回 d,如果 d 为空引用,则返回 listener,如果 d 和 listener 均为空引用,则返回空引用。
_delegate[typeof(T)] = Delegate.Combine(d,listener);//连接在同一字典下
}
else
{
//键对应的值
_delegate[typeof(T)] = listener;
}
}
//移除监听
public void RemoveListener <T> ( EventDelegate<T> listener )where T:EventArgs
{
Delegate d;
if(_delegate.TryGetValue(typeof(T),out d))
{
//如果d中找到了listener列表,则移去listener列表;如果listener为null,则返回d;如果d为空引用,则返回null;
//一个新委托,其调用列表的构成方法为:获取 source 的调用列表,如果在 source 的调用列表中找到了 value 的调用列表,则从中移除 value 的最后一个调用列表。
// 如果 value 为 null,或在 source 的调用列表中没有找到 value 的调用列表,则返回 source。 如果 value 的调用列表等于 source 的调用列表,或 source 为空引用,则返回空引用。
Delegate currentDel = Delegate.Remove(d,listener);
if(currentDel == null)
{
_delegate.Remove(typeof(T));
}
else
{
//如果d中没有listener,返回d,赋值给currentDel表示返回原委托列表,放回原字典中
//如果d中有listener,移去listener,返回d,赋值给currentDel表示返回原委托列表,放回原字典中
_delegate[typeof(T)] = currentDel;
}
}
}
//执行指定类型T的委托
public void Raise <T> (T e) where T :EventArgs
{
if(e == null)
{
throw new ArgumentException("e");
}
Delegate d;
if(_delegate.TryGetValue(typeof(T),out d))
{
EventDelegate <T> callback = d as EventDelegate<T>;
if(callback != null)
{
//执行委托
callback(e);
}
}
}
}
向EventManager中添加注册事件,逻辑如下:
using UnityEngine;
using System.Collections;
public class EventListener : MonoBehaviour {
void Start ()
{
EventManager.GetInstance().AddListener<EventArgs>(OnReceive);
}
public void OnReceive(EventArgs e)
{
print("Lee");
}
}
定义UIEventArgs类继承EventArgs类,自定义新的数据类型,向EventManager中添加注册事件,逻辑如下:
using UnityEngine;
using System.Collections;
public class UIEventArgs : EventArgs
{
private bool _isOpen;
public bool IsOpen
{
get
{
return _isOpen;
}
set
{
_isOpen = value;
}
}
}
使用新定义的数据类型,注册事件
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
void Start ()
{
EventManager.GetInstance().AddListener<UIEventArgs>(OnReceiveTwo);
}
void OnReceiveTwo(UIEventArgs e)
{
print("Guan");
}
}
【参考】http://blog.csdn.net/nateyang/article/details/8860495