sistema de eventos EventSystem

sistema de eventos EventSystem

El sistema de eventos es esencial en el desarrollo. El sistema de eventos utiliza el patrón de observador para reducir en gran medida el acoplamiento del programa. El artículo anterior también habló sobre el sistema de eventos, pero no es lo suficientemente eficiente y conciso. Cómo implementar un evento en un manera ligera, eficiente y elegante? Todavía se desarrolla en base al administrador de ensamblaje anterior AssemblyManager y al sistema de administración singleton SingletonSystem . El principio fundamental es utilizar la reflexión para obtener interfaces de eventos basadas en la reflexión para crear instancias de clases de procesamiento en lugar de suscribirse manualmente a eventos.

1.IEvento

public interface IEvent
{
    
    
    Type GetEventType();
    void Invoke(object self);
}

2.Controlador de eventos

public abstract class EventHandler<T> : IEvent where T : struct
{
    
    
    private readonly Type _selfType = typeof(T);
    public Type GetEventType()
    {
    
    
        return _selfType;
    }
    public abstract void Handler(T eventStruct);
    public void Invoke(object self)
    {
    
    
        try
        {
    
    
            Handler((T)self);
        }
        catch (Exception ex)
        {
    
    
            Debug.LogError($"{
      
      _selfType.Name} Error : {
      
      ex.Message}");
            return;
        }
    }
}

3.Información del evento

public sealed class EventInfo
{
    
    
    public readonly Type Type;
    public readonly IEvent Event;

    public EventInfo(Type type, IEvent @event)
    {
    
    
        Type = type;
        Event = @event;
    }
}

4.Sistema de eventos

public class EventSystem : Singleton<EventSystem>
{
    
    
    private readonly OneToManyList<Type, IEvent> _events = new();
    private readonly OneToManyList<int, EventInfo> _assemblyEvents = new();
    protected override void Load(int assemblyName)
    {
    
    
        foreach (Type type in AssemblyManager.ForEach(assemblyName, typeof(IEvent)))
        {
    
    
            IEvent @event = (IEvent)Activator.CreateInstance(type);
            if (@event != null)
            {
    
    
                Type thisType = @event.GetEventType();
                _events.Add(thisType, @event);
                _assemblyEvents.Add(assemblyName, new EventInfo(thisType, @event));
            }
        }
    }

    protected override void UnLoad(int assemblyName)
    {
    
    
        if(_assemblyEvents.TryGetValue(assemblyName,out List<EventInfo> events))
        {
    
    
            foreach (EventInfo info in events)
            {
    
    
                _events.RemoveValue(info.Type, info.Event);
            }

            _assemblyEvents.RemoveByKey(assemblyName);
        }
    }

    public void Publish<TEventData>(TEventData eventData) where TEventData : struct
    {
    
    
        if (!_events.TryGetValue(eventData.GetType(), out List<IEvent> list))
            return;

        foreach (IEvent @event in list)
        {
    
    
            try
            {
    
    
                @event?.Invoke(eventData);
            }
            catch (Exception ex)
            {
    
    
                Debug.LogError(ex.Message);
                return;
            }
        }
    }

    public override void Dispose()
    {
    
    
        _events.Clear();
        _assemblyEvents.Clear();
        base.Dispose();
    }
}

Los parámetros pasados ​​por cada evento aquí se pueden administrar utilizando un grupo de referencia para evitar crear repetidamente el mismo objeto y consumir rendimiento.

5. Prueba

public class Test : MonoBehaviour
{
    
    
    void Start()
    {
    
    
        SingletonSystem.Initialize();
        AssemblyManager.Initialize();
    }


    private void Update()
    {
    
    
        SingletonSystem.Update();

        if (Input.GetKeyDown(KeyCode.P))
        {
    
    
            EventSystem.Instance.Publish<AgeEvent>(new AgeEvent() {
    
     Age = 18 });
        }
    }
}

public struct AgeEvent
{
    
    
    public int Age;
}

public class AgeChangeHandler : EventHandler<AgeEvent>
{
    
    
    public override void Handler(AgeEvent eventStruct)
    {
    
    
        Debug.Log(eventStruct.Age);
    }
}

おすすめ

転載: blog.csdn.net/zzzsss123333/article/details/132634921