前言
游戏开发中抛事件,收事件也是比较常用的解耦方式,我所理解的设计模式旁观者模式有类似的原理,所以事件系统在一个框架中还是蛮重要的一块,本生事件系统不算一个大系统,代码量不多,主要是思路就是注册监听。
代码
EventManager1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144//-------------------------------------------
// Copyright © Aladdin. All rights reserved.
// Homepage: http://dingxiaowei.cn/
// Author: Aladdin
// Time: 2019/3/22 11:02:40
//-------------------------------------------
using GF.Debug;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace GF.EventSystem
{
/// <summary>
/// 消息分发器
/// </summary>
public class EventManager
{
private static EventManager instance;
public static EventManager Instance
{
get
{
if (null == instance)
instance = new EventManager();
return instance;
}
set
{
instance = value;
}
}
/// <summary>
/// 委托事件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender"></param>
/// <param name="evt"></param>
public delegate void EventHandler<T>(object sender, T evt);
/// <summary>
/// 注册事件字典
/// </summary>
public Dictionary<Type, List<object>> handlers = new Dictionary<Type, List<object>>();
/// <summary>
/// 注册事件
/// </summary>
/// <typeparam name="T">Class类型</typeparam>
/// <param name="handler">函数</param>
public void Register<T>(EventHandler<T> handler)
{
Debugger.Log("注册事件:" + handler.Method.Name);
Register(typeof(T), handler);
}
private void Register<T>(Type EventType, EventHandler<T> handler)
{
if (!handlers.ContainsKey(EventType))
{
handlers.Add(EventType, new List<object>());
}
if (!handlers[EventType].Contains(handler))
{
handlers[EventType].Add(handler);
}
}
/// <summary>
/// 分发事件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender"></param>
/// <param name="evt"></param>
public void Publish<T>(object sender, T evt)
{
subscribe(null, typeof(T), evt);
}
/// <summary>
/// 发送通知事件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender"></param>
/// <param name="EventType"></param>
/// <param name="evt"></param>
private void publish<T>(object sender, Type EventType, T evt)
{
if (handlers.ContainsKey(EventType))
{
Debugger.Log("public event key:" + typeof(T));
//移除所有的无效事件
handlers[EventType].RemoveAll(delegate (object handler) { return handler == null; });
for (int i = 0; i < handlers[EventType].Count; i++)
{
object handler = handlers[EventType][i];
MethodInfo method = handler.GetType().GetMethod("Invoke");
method.Invoke(handler, new object[] { sender, evt });
}
}
else
{
Debugger.Log(string.Format("<color=red>未注册的Key:{0}</color>", EventType));
}
}
/// <summary>
/// 注销事件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="handler">注册函数名</param>
public void UnRegister<T>(EventHandler<T> handler)
{
UnRegister(typeof(T), handler);
}
private void UnRegister<T>(Type EventType, EventHandler<T> handler)
{
if (handlers.ContainsKey(EventType))
{
handlers[EventType].Remove(handler);
Debugger.Log("Remove Event:" + handler);
if (0 == handlers[EventType].Count)//注册事件为空时,移除字典Key
{
handlers.Remove(EventType);
}
}
}
/// <summary>
/// 清空注册事件
/// </summary>
public void Clear()
{
handlers.Clear();
}
}
}
使用
监听消息
EventManager.Instance.Register<FishRoundData>(onFrameData);
取消监听
EventManager.Instance.UnRegister<FishRoundData>(onFrameData);
监听消息回调
1 | private void onFrameData(object sender, FishRoundData data) |
分发消息
EventManager.Instance.Publish<FishRoundData>(this, roundData.Value);
改进
我们可以将要监听的事件结构抽象一下,然后每新增一个消息就直接继承这个基类,这样我们监听消息回调就是一个统一的方法,然后强转data变成自定义的事件结构。
事件基类 GFEventArgs
1 | /// <summary> |
游戏事件基类
1 | /// <summary> |
EventManager
1 | internal sealed class EventManager1 |
使用
Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
1 | private void OnOpenUIFormSuccess(object sender, GameEventArgs e) |
GFFramework地址
https://github.com/dingxiaowei/GFFrameWork