事件的监听与广播系统,解耦合

时间:2019-11-07
本文章向大家介绍事件的监听与广播系统,解耦合,主要包括事件的监听与广播系统,解耦合使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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