개발/C#

[C#] CustomEventHandler

min1119 2023. 12. 12. 23:42
  • 타 대상에게 일어나는 특정 이벤트에 대한 처리를 일괄적으로 하고싶었음
  • 여러 이벤트를 한 번에 관리하고 싶어서 EventHandlerList를 사용하였음
  • EventHandlerList의 key 오브젝트를 한 번에 관리 & 재사용을 하고 싶어 이전에 제작한 ObjectPool을 사용함
public class EventKey : IRecycle
{
    public void Reset() { }
}

 

public class CustomEventArgs : EventArgs, IRecycle
{
    public object?[]? Values { get; private set; }

    public void Set(params object?[]? values)
    {
        Values = values;
    }

    public void Reset()
    {
        Values = null;
    }
}

 

public class CustomEventHandlerList : IRecycle
{
    private static ObjectPool<EventKey> _eventKeyObjectPool = new ObjectPool<EventKey>();

    private ConcurrentDictionary<int, EventKey> _eventKeyMapping = new();
    private EventHandlerList _eventHandlerList = new EventHandlerList();

    public EventHandler? this[int eventType]
    {
        get
        {
            if (false == _eventKeyMapping.TryGetValue(eventType, out var eventKey) ||
                _eventHandlerList[eventKey] is not EventHandler eventHandler)
            {
                return null;
            }

            return eventHandler;
        }
    }

    public bool TryGetValue(int eventType, [NotNullWhen(true)] out EventHandler? value)
    {
        if (this[eventType] is not EventHandler eventHandler)
        {
            value = null;
            return false;
        }

        value  = eventHandler;
        return true;

    }

    public void Add(int eventType, EventHandler eventHandler)
    {
        if (false == _eventKeyMapping.TryGetValue(eventType, out var eventKey))
        {
            eventKey = _eventKeyObjectPool.GetObject();
            _eventKeyMapping.TryAdd(eventType, eventKey);
        }

        _eventHandlerList.AddHandler(eventKey, eventHandler);
    }

    public void Remove(int eventType, EventHandler eventHandler)
    {
        if (false == _eventKeyMapping.TryGetValue(eventType, out var eventKey))
        {
            return;
        }

        _eventHandlerList.RemoveHandler(eventKey, eventHandler);
    }

    public void NotifyEvent(int eventType, CustomEventArgs args)
    {
        this[eventType]?.Invoke(eventType, args);
    }

    public void Reset()
    {
        _eventHandlerList.Dispose();

        foreach (var eventKey in _eventKeyMapping.Values)
        {
            _eventKeyObjectPool.ReturnObject(eventKey);
        }

        _eventKeyMapping.Clear();
    }
}

 

public class CustomEventHandlerManager<T> where T : notnull
{
    static private ObjectPool<CustomEventHandlerList> _handlerPool = new();
    private ConcurrentDictionary<T, CustomEventHandlerList> _targetEventHandlerLists = new();

    private CustomEventHandlerList? this[T key]
    {
        get
        {
            if (false == _targetEventHandlerLists.TryGetValue(key, out var handlerList))
            {
                return null;
            }

            return handlerList;
        }
    }

    public void Add(T key, int eventType, [NotNull] EventHandler handler)
    {
        if(false == _targetEventHandlerLists.TryGetValue(key, out var eventHandlerList))
        {
            eventHandlerList = new();
            _targetEventHandlerLists.TryAdd(key, eventHandlerList);
        }

        eventHandlerList.Add(eventType, handler);
    }

    public void Remove(T key, int eventType, [NotNull] EventHandler handler)
    {
        if (false == _targetEventHandlerLists.TryGetValue(key, out var eventHandlerList))
        {
            return;
        }

        eventHandlerList.Remove(eventType, handler);
    }

    public bool TryRemove(T key)
    {
        if (false == _targetEventHandlerLists.TryRemove(key, out var handlerList))
        {
            return false;
        }

        _handlerPool.ReturnObject(handlerList);
        return true;
    }

    public void NotifyEvent(T key, int eventType, [NotNull] CustomEventArgs args)
    {
        this[key]?.NotifyEvent(eventType, args);
    }
}

Git : https://github.com/ChoiMingyeong/Devoram.git

 

GitHub - ChoiMingyeong/Devoram: Devoram Engine Repository

Devoram Engine Repository. Contribute to ChoiMingyeong/Devoram development by creating an account on GitHub.

github.com

Permalink : 

EventKey - https://github.com/ChoiMingyeong/Devoram/blob/7fd2ce00c55dd8a29c494afd41c60a24394c2124/Devoram/DevoramUtility/EventKey.cs

CustomEventArgs - https://github.com/ChoiMingyeong/Devoram/blob/7fd2ce00c55dd8a29c494afd41c60a24394c2124/Devoram/DevoramUtility/CustomEventArgs.cs

CustomEventHandlerList - https://github.com/ChoiMingyeong/Devoram/blob/7fd2ce00c55dd8a29c494afd41c60a24394c2124/Devoram/DevoramUtility/CustomEventHandlerList.cs

CustomEventHandlerManager - https://github.com/ChoiMingyeong/Devoram/blob/7fd2ce00c55dd8a29c494afd41c60a24394c2124/Devoram/DevoramUtility/CustomEventHandlerManager.cs

'개발 > C#' 카테고리의 다른 글

[C#] Bools  (0) 2023.12.09
[C#] ObjectPool  (2) 2023.12.07
[C#] ConcurrentList  (4) 2023.12.06
[C#] Singleton  (2) 2023.12.05