好处:解决代码之间的耦合性
原理:
接收端:在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
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
RemoveListener
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