- 타 대상에게 일어나는 특정 이벤트에 대한 처리를 일괄적으로 하고싶었음
- 여러 이벤트를 한 번에 관리하고 싶어서 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 :
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 |