事件的监听与广播系统,解耦合
PS:这是在siki学院上看到的一套系统,地址奉上 ===> http://www.sikiedu.com/my/course/304
记录一下学习心得以及和自己的UI框架搭配使用,正所谓取众家之所长嘛
在Unity开发的道路就是需要不断的学习,时刻保持汲取的状态,才是我们开发人员需要的
这套系统的主旨在解耦合上,核心思维是通过添加监听,广播来实现函数的调用,说白了也就是消息机制
现在Unity的开发个人认为可以大致分为三种框架:
一、没有任何框架的开发
这种开发没有任何可讲的,常见于各类功能的demo,想起什么写什么,没有任何规范性可言
二、单例框架的开发
这一类属于常见,使用单例模式对各个模块进行管理,不同模块之间的交互和相同模块之间的交互都是通过管理类来执行,
虽然看起来是降低了耦合性,但是还不能达到一个很理想的解耦状态
三、消息机制框架
这种类型的开发框架常用于比较大型的游戏中,mmo、moba之类的等等,现在要说的只是其中的一种
话不多说,言归正传,底层实现由三个脚本构成:CallBack、EventCenter、EventType
一、EventCenter事件中心
主要功能有添加监听,移除监听,以及广播事件,需要注意的是这里只封装到了最多五个参数的监听,我想这应该也差不多了吧,如果有更多的需求依葫芦画瓢继续封装就行
同样的,有添加监听就会有移除监听,同样也是只封装到五个参数的,最后就是广播事件了,对应的也是只到五个参数的,好了,废话不说,上代码
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 6 public class EventCenter 7 { 8 private static Dictionary<EventType, Delegate> m_EventTable = new Dictionary<EventType, Delegate>(); 9 10 #region 添加监听 11 /// <summary> 12 /// 重复代码的提取 13 /// </summary> 14 /// <param name="eventType"></param> 15 /// <param name="callBack"></param> 16 private static void OnListenerAdding(EventType eventType, Delegate callBack) 17 { 18 if (!m_EventTable.ContainsKey(eventType)) 19 { 20 m_EventTable.Add(eventType, null); 21 } 22 Delegate d = m_EventTable[eventType]; 23 if (d != null && d.GetType() != callBack.GetType()) 24 { 25 throw new Exception(string.Format("尝试为事件{0}添加不同类型的委托,当前事件所对应的委托是{1},要添加的委托类型为{2}", eventType, d.GetType(), callBack.GetType())); 26 } 27 } 28 29 /// <summary> 30 /// 无参添加 31 /// </summary> 32 /// <param name="eventType"></param> 33 /// <param name="callBack"></param> 34 public static void AddListener(EventType eventType, CallBack callBack) 35 { 36 OnListenerAdding(eventType, callBack); 37 m_EventTable[eventType] = (CallBack)m_EventTable[eventType] + callBack; 38 } 39 40 /// <summary> 41 /// 1个参数添加 42 /// </summary> 43 /// <typeparam name="T"></typeparam> 44 /// <param name="eventType"></param> 45 /// <param name="callBack"></param> 46 public static void AddListener<T>(EventType eventType, CallBack<T> callBack) 47 { 48 OnListenerAdding(eventType, callBack); 49 m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] + callBack; 50 } 51 52 /// <summary> 53 /// 2个参数添加 54 /// </summary> 55 /// <typeparam name="T"></typeparam> 56 /// <param name="eventType"></param> 57 /// <param name="callBack"></param> 58 public static void AddListener<T,X>(EventType eventType, CallBack<T,X> callBack) 59 { 60 OnListenerAdding(eventType, callBack); 61 m_EventTable[eventType] = (CallBack<T,X>)m_EventTable[eventType] + callBack; 62 } 63 64 /// <summary> 65 /// 3个参数添加 66 /// </summary> 67 /// <typeparam name="T"></typeparam> 68 /// <param name="eventType"></param> 69 /// <param name="callBack"></param> 70 public static void AddListener<T, X,Y>(EventType eventType, CallBack<T, X, Y> callBack) 71 { 72 OnListenerAdding(eventType, callBack); 73 m_EventTable[eventType] = (CallBack<T, X, Y>)m_EventTable[eventType] + callBack; 74 } 75 76 /// <summary> 77 /// 4个参数添加 78 /// </summary> 79 /// <typeparam name="T"></typeparam> 80 /// <param name="eventType"></param> 81 /// <param name="callBack"></param> 82 public static void AddListener<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack) 83 { 84 OnListenerAdding(eventType, callBack); 85 m_EventTable[eventType] = (CallBack<T, X, Y, Z>)m_EventTable[eventType] + callBack; 86 } 87 88 /// <summary> 89 /// 5个参数添加 90 /// </summary> 91 /// <typeparam name="T"></typeparam> 92 /// <param name="eventType"></param> 93 /// <param name="callBack"></param> 94 public static void AddListener<T, X, Y, Z, W>(EventType eventType, CallBack<T, X, Y, Z, W> callBack) 95 { 96 OnListenerAdding(eventType, callBack); 97 m_EventTable[eventType] = (CallBack<T, X, Y, Z, W>)m_EventTable[eventType] + callBack; 98 } 99 #endregion 100 101 #region 移除监听 102 /// <summary> 103 /// 重复代码提取 104 /// </summary> 105 /// <param name="eventType"></param> 106 /// <param name="callBack"></param> 107 private static void OnListenerRemoving(EventType eventType, Delegate callBack) 108 { 109 if (m_EventTable.ContainsKey(eventType)) 110 { 111 Delegate d = m_EventTable[eventType]; 112 if (d == null) 113 { 114 throw new Exception(string.Format("移除监听错误: 事件{0}没有对应的委托", eventType)); 115 } 116 else if (d.GetType() != callBack.GetType()) 117 { 118 throw new Exception(string.Format("移除监听错误: 尝试为事件{0}移除不同类型的委托,当前委托类型为{1},要移除的类型为{2}", eventType, d.GetType(), callBack.GetType())); 119 } 120 } 121 else 122 { 123 throw new Exception(string.Format("移除监听错误: 没有事件码{0}", eventType)); 124 } 125 } 126 127 private static void OnListenerRemoved(EventType eventType) { if (m_EventTable[eventType] == null) m_EventTable.Remove(eventType); } 128 129 /// <summary> 130 /// 无参移除 131 /// </summary> 132 /// <param name="eventType"></param> 133 /// <param name="callBack"></param> 134 public static void RemoveListener(EventType eventType, CallBack callBack) 135 { 136 OnListenerRemoving(eventType, callBack); 137 m_EventTable[eventType] = (CallBack)m_EventTable[eventType] - callBack; 138 OnListenerRemoved(eventType); 139 } 140 141 /// <summary> 142 /// 1个参数移除 143 /// </summary> 144 /// <typeparam name="T"></typeparam> 145 /// <param name="eventType"></param> 146 /// <param name="callBack"></param> 147 public static void RemoveListener<T>(EventType eventType, CallBack<T> callBack) 148 { 149 OnListenerRemoving(eventType, callBack); 150 m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] - callBack; 151 OnListenerRemoved(eventType); 152 } 153 154 /// <summary> 155 /// 2个参数移除 156 /// </summary> 157 /// <typeparam name="T"></typeparam> 158 /// <param name="eventType"></param> 159 /// <param name="callBack"></param> 160 public static void RemoveListener<T, X>(EventType eventType, CallBack<T, X> callBack) 161 { 162 OnListenerRemoving(eventType, callBack); 163 m_EventTable[eventType] = (CallBack<T, X>)m_EventTable[eventType] - callBack; 164 OnListenerRemoved(eventType); 165 } 166 167 /// <summary> 168 /// 3个参数移除 169 /// </summary> 170 /// <typeparam name="T"></typeparam> 171 /// <param name="eventType"></param> 172 /// <param name="callBack"></param> 173 public static void RemoveListener<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack) 174 { 175 OnListenerRemoving(eventType, callBack); 176 m_EventTable[eventType] = (CallBack<T, X, Y>)m_EventTable[eventType] - callBack; 177 OnListenerRemoved(eventType); 178 } 179 180 /// <summary> 181 /// 4个参数移除 182 /// </summary> 183 /// <typeparam name="T"></typeparam> 184 /// <param name="eventType"></param> 185 /// <param name="callBack"></param> 186 public static void RemoveListener<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack) 187 { 188 OnListenerRemoving(eventType, callBack); 189 m_EventTable[eventType] = (CallBack<T, X, Y, Z>)m_EventTable[eventType] - callBack; 190 OnListenerRemoved(eventType); 191 } 192 /// <summary> 193 /// 5个参数移除 194 /// </summary> 195 /// <typeparam name="T"></typeparam> 196 /// <param name="eventType"></param> 197 /// <param name="callBack"></param> 198 public static void RemoveListener<T, X, Y, Z, W>(EventType eventType, CallBack<T, X, Y, Z, W> callBack) 199 { 200 OnListenerRemoving(eventType, callBack); 201 m_EventTable[eventType] = (CallBack<T, X, Y, Z, W>)m_EventTable[eventType] - callBack; 202 OnListenerRemoved(eventType); 203 } 204 205 #endregion 206 207 #region 广播事件 208 /// <summary> 209 /// 广播事件 210 /// </summary> 211 /// <param name="eventType"></param> 212 public static void BroadCast(EventType eventType) 213 { 214 Delegate d; 215 if (m_EventTable.TryGetValue(eventType, out d)) 216 { 217 CallBack callBack = d as CallBack; 218 if (callBack != null) 219 { 220 callBack(); 221 } 222 else 223 { 224 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 225 } 226 } 227 228 } 229 /// <summary> 230 /// 1个参数广播 231 /// </summary> 232 /// <typeparam name="T"></typeparam> 233 /// <param name="eventType"></param> 234 /// <param name="arg"></param> 235 public static void BroadCast<T>(EventType eventType, T arg) 236 { 237 Delegate d; 238 if (m_EventTable.TryGetValue(eventType, out d)) 239 { 240 CallBack<T> callBack = d as CallBack<T>; 241 if (callBack != null) 242 { 243 callBack(arg); 244 } 245 else 246 { 247 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 248 } 249 } 250 } 251 252 /// <summary> 253 /// 2个参数广播 254 /// </summary> 255 /// <typeparam name="T"></typeparam> 256 /// <typeparam name="X"></typeparam> 257 /// <param name="eventType"></param> 258 /// <param name="arg1"></param> 259 /// <param name="arg2"></param> 260 public static void BroadCast<T, X>(EventType eventType, T arg1, X arg2) 261 { 262 Delegate d; 263 if (m_EventTable.TryGetValue(eventType, out d)) 264 { 265 CallBack<T, X> callBack = d as CallBack<T, X>; 266 if (callBack != null) 267 { 268 callBack(arg1,arg2); 269 } 270 else 271 { 272 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 273 } 274 } 275 } 276 277 /// <summary> 278 /// 3个参数广播 279 /// </summary> 280 /// <typeparam name="T"></typeparam> 281 /// <typeparam name="X"></typeparam> 282 /// <param name="eventType"></param> 283 /// <param name="arg1"></param> 284 /// <param name="arg2"></param> 285 public static void BroadCast<T, X, Y>(EventType eventType, T arg1, X arg2, Y arg3) 286 { 287 Delegate d; 288 if (m_EventTable.TryGetValue(eventType, out d)) 289 { 290 CallBack<T, X, Y> callBack = d as CallBack<T, X, Y>; 291 if (callBack != null) 292 { 293 callBack(arg1, arg2, arg3); 294 } 295 else 296 { 297 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 298 } 299 } 300 } 301 302 /// <summary> 303 /// 4个参数广播 304 /// </summary> 305 /// <typeparam name="T"></typeparam> 306 /// <typeparam name="X"></typeparam> 307 /// <param name="eventType"></param> 308 /// <param name="arg1"></param> 309 /// <param name="arg2"></param> 310 public static void BroadCast<T, X, Y, Z>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4) 311 { 312 Delegate d; 313 if (m_EventTable.TryGetValue(eventType, out d)) 314 { 315 CallBack<T, X, Y, Z> callBack = d as CallBack<T, X, Y, Z>; 316 if (callBack != null) 317 { 318 callBack(arg1, arg2, arg3,arg4); 319 } 320 else 321 { 322 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 323 } 324 } 325 } 326 327 /// <summary> 328 /// 5个参数广播 329 /// </summary> 330 /// <typeparam name="T"></typeparam> 331 /// <typeparam name="X"></typeparam> 332 /// <param name="eventType"></param> 333 /// <param name="arg1"></param> 334 /// <param name="arg2"></param> 335 public static void BroadCast<T, X, Y, Z, W>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4, W arg5) 336 { 337 Delegate d; 338 if (m_EventTable.TryGetValue(eventType, out d)) 339 { 340 CallBack<T, X, Y, Z, W> callBack = d as CallBack<T, X, Y, Z, W>; 341 if (callBack != null) 342 { 343 callBack(arg1, arg2, arg3, arg4, arg5); 344 } 345 else 346 { 347 throw new Exception(string.Format("广播事件错误: 事件{0}对应的委托有不同的类型", eventType)); 348 } 349 } 350 } 351 #endregion 352 }
二、CallBack回调
1 public delegate void CallBack(); 2 public delegate void CallBack<T>(T arg); 3 public delegate void CallBack<T, X>(T arg1, X arg2); 4 public delegate void CallBack<T, X, Y>(T arg1, X arg2, Y arg3); 5 public delegate void CallBack<T, X, Y, Z>(T arg1, X arg2, Y arg3, Z arg4); 6 public delegate void CallBack<T, X, Y, Z, W>(T arg1, X arg2, Y arg3, Z arg4, W arg5);
三、EventType事件类型
也就是常说的不同事件的对应码,注意,在使用的过程中,添加了什么事件,事件需要几个参数,什么类型的参数,一定要在心里梳理清楚,不然很容易搞乱
1 public enum EventType 2 { 3 MAINSKILL, 4 SKILLONE, 5 SKILLTWO, 6 SKILLTHREE, 7 BEGAINDARG, 8 ONDARG, 9 ENDDARG, 10 SHOWSTART, 11 HIDESTART, 12 SHOWREGIST, 13 HIDEREGIST, 14 SHOWMESSAGETIPS, 15 HASREGIST, 16 }
接下来看看我配合着之前说的UI框架的使用
这样是为了避免对对象的直接引用
最后需要再ondestory移除一下监听
原文地址:https://www.cnblogs.com/shawnlen/p/11811622.html
- python3 下 Zabbix监控调用graph.get并且下载监控图
- 用R语言复盘美国总统大选结果~
- 最新Apache Spark平台的NLP库,助你轻松搞定自然语言处理任务
- 使用Seq2Seq+attention实现简单的Chatbot
- R语言可视化——用ggplot构造期待已久的雷达图
- 【实战】最新Deep Learning with Keras图书加代码,教你从零开发一个复杂深度学习模型(附下载)
- 基于zabbix 自动抓取每天监控数据!/usr/local/python/bin/python3.5
- 大过年的,一起来用Seq2Seq来作对联吧!
- python3 下调用zabbix api 获取多个机房的IP
- TensorFlow从0到1 - 14 - 交叉熵损失函数——防止学习缓慢
- 用优雅的配色来缔造图表专业主义~
- python文件名与包名冲突
- python3 Zabbix监控-api的使用-python
- 安装python虚拟环境
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python五十九课——正则表达式的拓展内容
- 配置SVN的hooks功能自动更新代码
- python六十课——高阶函数之map
- python六十一课——高阶函数之reduce
- python六十二课——高阶函数之filter
- Nginx优化配置详解
- python六十三课——高阶函数之sorted
- python六十四课——高阶函数练习题(一)
- python六十四课——高阶函数练习题(二)
- python六十四课——高阶函数练习题(三)
- Jenkins+Maven+Svn实现代码自动打包与发布
- python六十五课——单元测试(一)
- python六十六课——单元测试(二)
- Linux企业生产常见问题集合(一)答案
- python六十八课——网络编程之UDP协议