Unity 委托使用(2)

一个监听对象触发多个委托方法~~~~~~~~~~~~~~~~~~~~~


关于委托,简单又不简单,挺饶人的。。。

 

下面一则逻辑,就是使用委托来完成的,它主要是通过一个类来统一管理委托,包括添加监听事件、删去监听事件、挂起监听事件。

 

作用:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值