public record GameEventModel;
๋ผ๋ record class ๊ฐ ์์ต๋๋ค
public interface IGameEventSubscriber<T> where T : GameEventModel
{
ย ย public void OnNewEvent(T model);
}
๋ผ๋ Subscriber ๋ฅผ ๋ง๋ค์ด์ ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ต๋๋ค
ย ย private List<object> subscribers = new List<object>();
ย ย public void Publish<T>(T model) where T : GameEventModel
ย ย {
ย ย ย ย DebugConsole.Log(
ย ย ย ย ย ย GetType(),
ย ย ย ย ย ย string.Format("New event {0} // {1}", model, string.Join(", \n", subscribers)));
ย ย ย ย var channel = from subscriber in subscribers
ย ย ย ย ย ย where subscriber is IGameEventSubscriber<T>
ย ย ย ย ย ย select (IGameEventSubscriber<T>)subscriber;
ย ย ย ย foreach (var subscriber in channel.ToList())
ย ย ย ย {
ย ย ย ย ย ย DebugConsole.Log(
ย ย ย ย ย ย ย ย GetType(),
ย ย ย ย ย ย ย ย string.Format("New event {0} => {1}", model, subscriber));
ย ย ย ย ย ย subscriber.OnNewEvent(model);
ย ย ย ย }
ย ย }
object collection ์ ๋ชจ๋ subscriber ๋ฅผ ๋ด๊ณ
LINQ ๋ก ํด๋น ํ์ ์ธ์ง ๊ฒ์ฌ ํ ๋ฃจํ๋ฅผ ๋๋ฆฝ๋๋ค
์ด ๋, ์์์ ์ด๋ฒคํธย
public sealed record UnitDeadEvent : GameEventModel
์ ์ ํํด์ Subscriber ๊ฐ ๋์ํ๊ฒ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ
ย ย public List<GameEventModel> Foo()
ย ย public List<UnitDeadEvent> Bob()
Foo ๋ก ์ป์ collection ์ model ์ ์ ์์ ์ผ๋ก ์ ๋ฌ์ด ๋์ง ์๊ณ
Bob ๋ก ์ป์ collection ์ model ์ ์ ์์ ์ผ๋ก ์ ๋ฌ์ด ๋ฉ๋๋ค
๋น๋ก Foo ๋ก ์ป์ย collection ๋ด ์์ดํ ๋ค์ GameEventModel ์ด์ง๋ง, GetType ์ ์ฐ์ด๋ณด๋ฉด ํ์คํ UnitDeadEvent ๋ก ๋์ค๋๋ฐ์.
์ Foo ๋ ์๋๋ ๊ฒ์ผ๊น์?
์ค๊ฐ ์ค๊ฐ ๋งฅ๋ฝ์ด ๋๋ฌด ๋๊ฒจ์ ์ดํดํ๊ธฐ ํ๋ค๊ธด ํ๋ฐ ๋ฌธ์ ์๊ธธ๋งํ ๋ถ๋ถ ์ฐพ์๋ณด๋ฉด IGameEventSubscriber[UnitDeadEvent] ๋ IGameEventSubscriber[GameEventModel] ์ธํฐํ์ด์ค๋ GameEventModel์ด๋ผ๋ T๋ฅผ ๊ฐ์ง๋ค๋ ์ ๋ง๊ณ ๋ ์ ํ ๋ณ๊ฐ์ ์ธํฐํ์ด์ค๋ผ๋ ์ ? UnitDeadEvent์ ์ธ์คํด์ค์ is GameEventModel์ true์ธ๋ฐ IGameEventSubscriber[UnitDeadEvent]๋ฅผ ์์๋ฐ์ ์ธ์คํด์ค์ is IGameEventSubscriber[GameEventModel] ๋ฐ์ผ๋ฉด false๋๊น ๊ฐ์๊ธฐ ๋์จ Foo๋ Bob๋๋งค ์์งํ ๋ด๊ฐ ์ ๋๋ก ์ดํดํ๋์ง๋ ๋ชจ๋ฅด๊ฒ์ด ๋ฏธ์ ํน์๋ผ๋ ๋์๋ ๊น ๋จ๊น
์ ๋๊ธ์ฒ๋ผ subscriber is IGameEventSubscriber[T] ๋ถ๋ถ์ด ๋ฌธ์ ์. Subscriber์๋ค๊ฐ ์๋ง IGameEventSubscriber[UnitDaedEvent] ๊ฐ์ฒด๋ฅผ ๋ฃ์ด๋์ํ ๋ฐ ๊ทธ๊ฑด ์ ๊ตฌ๋ฌธ์ ํต๊ณผํ์ง ๋ชปํจ. ๊ทธ๋ฆฌ๊ณ C#์์ ์ ๋ค๋ฆญ ํจ์๋ฅผ ํธ์ถํ๋ค๊ณ ํด์ ์๋์ผ๋ก ํด๋น ์ค๋ธ์ ํธ์ ์ค์ ํ์ ์ผ๋ก T๊ฐ ์ ๋ ฅ๋๋๊ฒ ์๋. ์ฆ GameEventModel์ธ ์ค๋ธ์ ํธ๋ก Publish๋ฅผ ํธ์ถํ๋ฉด ๊ทธ๊ฑด ๊ทธ๋ฅ Publish[GameEventModel] ๋ก ํธ์ถ๋์ง ์๋์ผ๋ก ํด๋น ์ค๋ธ์ ํธ์ ์ค์ ํ์ ์ธ UnitDeadEvent๋ก ํธ์ถ๋์ง ์์
๋ค๊ฐ ํ๋ ค๋ ๋ฐฉ์์ ์ด๋ป๊ฒ ๊ตฌํํ ์ง ์ข ์๊ฐํด ๋ดค๋๋ฐ IGameEventSubscriber[T] ๋ฅผ ์ธํฐํ์ด์ค ๋ง๊ณ ํด๋์ค๋ก ๋ฐ๊พผ ๋ค์์ IsTarget(GameEventModel m) ๊ฐ์ ํจ์๋ฅผ ์ถ๊ฐํด์ ์์ Linq์ where๋ถ๋ถ์ ๋์ฒดํ๋๊ฒ ์ด๋จ๊น? ๊ทธ๋ฆฌ๊ณ Publishํจ์๋ ๊ตณ์ด T๋ฅผ ๋์ ํ ์ ๋ค๋ฆญ ํจ์์ผ ํ์๊ฐ ์์ด ๋ณด์.. ์ ์ด์ Foo๋ฆฌ์คํธ๋ฅผ ๊ฐ์ง๊ณ ๋๋ฆฐ๋ค๋๊ฑด ์ถ์ํ๋ฅผ ์ด์ฉํ๊ฒ ๋ค๋๊ฑด๋ฐ ๊ทธ๋ฌ๋ฉด Publish(GameEventModel m) ๊ฐ ๋๋๊ฒ ๋ง์ง ์๋ ์ถ๋ค