笔记-事件监听广播

好处:解决代码之间的耦合性

原理:
接收端:在Start()或者Awake()中增加监听,等待发起端的广播,执行相应的程序。
发起段:需要时发起广播即可。

使用非常简单:

接收端:
	void Start () 
	{
			//添加监听
	        EventCenter.AddListener(EventType.oneParam,Show1);
	}
	void OnDestroy()
    {
		//不用要及时移除
        EventCenter.RemoveListener(EventType.oneParam, Show1);
    }
	void Show1(string s)
    {
    	//代码块,有一个参数
        GetComponent().text = s;
    }
发起端(是一个button组件)
	void Start () {
		GetComponent

代码:
1.使用枚举类型建立事件码,有需求随时添加,知道事件码含义即可

public enum EventType
{
    noParam,//无参数
    oneParam,//1个参数,string
    twoParam,//2个参数,(string,string)
    threeParam,//三个参数1,(string,int,float)
    threeParam2//三个参数1,(string,string,string)
}

2.创建事件中心脚本类:EventCenter

  • 定义一个字典Dictionary保存事件类型和事件委托
    key:EventType
    valua:Delegate
   private static Dictionary e_table = new Dictionary();

给EventCenter增加静态方法。添加监听AddListener,移除监听RemoveListener,广播方法Broadcast。

AddListener方法
1.判断事件表e_table是否包含事件码
2.没有把事件码添加到表格中
3.存在事件码,当前事件类型是否与已存在的相符合,不符合抛出错误
4.符合将委托加到表中

    public static void AddListener(EventType et,Action a)
    {
        //判断是否已经有事件类型,没有进行添加
        if (!e_table.ContainsKey(et))
        {
            e_table.Add(et, null);
        }
        //判断要添加的方法类型是否符合要求
        Delegate d = e_table[et];
        if (d != null && d.GetType() != a.GetType())
        {
            //类型不符合,抛出一个异常提示
            throw new Exception(string.Format("要添加事件类型{0}与当前类型{1}不一致\n事件类型{2}", a.GetType(), d.GetType(), et));
        }
        //将事件添加到表里,需要把e_table[et](Delegate)强转成Action
        e_table[et] = (Action) e_table[et] + a;
    }

RemoveListener方法过程类似

    public static void RemoveListener(EventType et, Action a)
    {
        //移除监听条件判断
        if (!e_table.ContainsKey(et))
        {
            //事件不存在,抛出异常提示
            throw new Exception(string.Format("事件{0}不存在", et));
        }

        Delegate d = e_table[et];
        if (d == null)
        {
            //没有对应委托
            throw new Exception(String.Format("事件类型{0}没有对应委托{1}", et, a.GetType()));
        }
        else if (d.GetType() != a.GetType())
        {
            //类型不一致
            throw new Exception(String.Format("移除监听错误:尝试为事件{0}移除不同类型的委托,当前委托类型为{1},要移除的委托类型为{2}", et, d.GetType(), a.GetType()));
        }       
         //移除监听
        e_table[et] = (Action) e_table[et] - a;
    }

Broadcast方法 广播

    public static void Broadcast(EventType et)
    {
        Delegate d;
        if (e_table.TryGetValue(et ,out d))
        {
            //判断类型是否一致
            Action a = d as Action;
            if (a==null)
            {
                //强转不成功,说明类型不一致
                throw new Exception("类型不一致");
            }
            else
            {
                //一致执行委托
                a();
            }
        }
    }

-使用泛型实现多参数
AddListener(EventType et, Action a)
RemoveListener(EventType et, Action a)
Broadcast(EventType et,T1 arg1,T2 arg2,…)
Action可以支持多16个参数,一般用不到那么多

以下写个2个参数的实现

    public static void AddListener(EventType et,Action a)
    {
        //判断是否已经有事件类型,没有进行添加
        if (!e_table.ContainsKey(et))
        {
            e_table.Add(et, null);
        }
        //判断要添加的方法类型是否符合要求
        Delegate d = e_table[et];
        if (d != null && d.GetType() != a.GetType())
        {
            //类型不符合,抛出一个异常提示
            throw new Exception(string.Format("要添加事件类型{0}与当前类型{1}不一致\n事件类型{2}", a.GetType(), d.GetType(), et));
        }
        //将事件添加到表里,需要把e_table[et](Delegate)强转成Action
        e_table[et] = (Action) e_table[et] + a;
    }

 public static void RemoveListener(EventType et, Action a)
    {
        //移除监听条件判断
        if (!e_table.ContainsKey(et))
        {
            //事件不存在,抛出异常提示
            throw new Exception(string.Format("事件{0}不存在", et));
        }

        Delegate d = e_table[et];
        if (d == null)
        {
            //没有对应委托
            throw new Exception(String.Format("事件类型{0}没有对应委托{1}", et, a.GetType()));
        }
        else if (d.GetType() != a.GetType())
        {
            //类型不一致
            throw new Exception(String.Format("移除监听错误:尝试为事件{0}移除不同类型的委托,当前委托类型为{1},要移除的委托类型为{2}", et, d.GetType(), a.GetType()));
        }       
         //移除监听
        e_table[et] = (Action) e_table[et] - a;
    }

public static void Broadcast(EventType et,T1 arg1,T2 arg2)
    {
        Delegate d;
        if (e_table.TryGetValue(et ,out d))
        {
            //判断类型是否一致
            Action a = d as Action;
            if (a==null)
            {
                //强转不成功,说明类型不一致
                throw new Exception("类型不一致");
            }
            else
            {
                //一致执行委托
                a(arg1,arg2);
            }
        }
    }

更多例子:https://github.com/zecymo3/EventCenter

你可能感兴趣的:(学习记录)