0%

ET-EventSystem

事件注册

  • 通过遍历已加载到程序域中的程序集,获得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
    11
    EventAttribute 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
26
public 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
    15
    namespace ET.Client
    {
    // 此处为class对象打上SceneType标签,并集成AEvent明确需要接受的事件类型
    [Event(SceneType.Client)]
    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
    29
    namespace 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;
    }


    }
    }