事件注册
- 通过遍历已加载到程序域中的程序集,获得assemblies下所有定义的类型types。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// CodeLoader.cs中的代码片段
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Dictionary<string, Type> types = AssemblyHelper.GetAssemblyTypes(assemblies);
EventSystem.Instance.Add(types);
// AssemblyHelper
public static class AssemblyHelper
{
public static Dictionary<string, Type> GetAssemblyTypes(params Assembly[] args)
{
Dictionary<string, Type> types = new Dictionary<string, Type>();
foreach (Assembly ass in args)
{
foreach (Type type in ass.GetTypes())
{
// type.FullName 该类型的完全限定名,包括其命名空间,但不包括程序集
types[type.FullName] = type;
}
}
return types;
}
} - EventSystem.Add(Dictionary<string, Type> addTypes)
遍历字典addTypes参数,即前面得到的types变量,将所有逻辑中打上不同功能属性标签的type分类存储,
其中[EventAttribute]标签存储在名为allEvents的字典中。1
2
3
4
5
6
7
8
9
10
11EventAttribute eventAttribute = attr as EventAttribute;
Type eventType = obj.Type;
EventInfo eventInfo = new(obj, eventAttribute.SceneType);
if (!this.allEvents.ContainsKey(eventType))
{
this.allEvents.Add(eventType, new List<EventInfo>());
}
this.allEvents[eventType].Add(eventInfo);
事件派发
事件派发分为Publish和PublishAsync两种,但核心思路其实是一样的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public void Publish<T>(Scene scene, T a) where T : struct
{
List<EventInfo> iEvents;
if (!this.allEvents.TryGetValue(typeof (T), out iEvents))
{
return;
}
SceneType sceneType = scene.SceneType;
foreach (EventInfo eventInfo in iEvents)
{
if (sceneType != eventInfo.SceneType && eventInfo.SceneType != SceneType.None)
{
continue;
}
if (!(eventInfo.IEvent is AEvent<T> aEvent))
{
Log.Error($"event error: {eventInfo.IEvent.GetType().Name}");
continue;
}
aEvent.Handle(scene, a).Coroutine();
}
}
- Publish逻辑中,通过this.allEvents.TryGetValue(typeof (T), out iEvents),获得了继承自AEvent
的对象集合 - 遍历对象集合,筛选出满足sceneType和eventType的类型对象进行事件派发
- 举个创建客户端场景之后时间派发流程的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15namespace ET.Client
{
// 此处为class对象打上SceneType标签,并集成AEvent明确需要接受的事件类型
[ ]
public class AfterCreateClientScene_AddComponent: AEvent<EventType.AfterCreateClientScene>
{
protected override async ETTask Run(Scene scene, EventType.AfterCreateClientScene args)
{
var fuiEvent = scene.AddComponent<FUIEventComponent>();
fuiEvent.AddComponent<CDComponent>();
scene.AddComponent<FUIComponent>();
await ETTask.CompletedTask;
}
}
}1
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
29namespace ET.Client
{
public static class SceneFactory
{
public static async ETTask<Scene> CreateClientScene(int zone, string name)
{
await ETTask.CompletedTask;
// 创建ClientScene时指定SceneType
Scene clientScene = EntitySceneFactory.CreateScene(zone, SceneType.Client, name, ClientSceneManagerComponent.Instance);
clientScene.AddComponent<CurrentScenesComponent>();
clientScene.AddComponent<ObjectWait>();
clientScene.AddComponent<PlayerComponent>();
// 创建完ClientScene后派发事件
EventSystem.Instance.Publish(clientScene, new EventType.AfterCreateClientScene());
return clientScene;
}
public static Scene CreateCurrentScene(long id, int zone, string name, CurrentScenesComponent currentScenesComponent)
{
Scene currentScene = EntitySceneFactory.CreateScene(id, IdGenerater.Instance.GenerateInstanceId(), zone, SceneType.Current, name, currentScenesComponent);
currentScenesComponent.Scene = currentScene;
EventSystem.Instance.Publish(currentScene, new EventType.AfterCreateCurrentScene());
return currentScene;
}
}
}