1 module voxelman.eventdispatcher.plugin; 2 3 import pluginlib; 4 import voxelman.core.config; 5 import tharsis.prof : Profiler; 6 7 abstract class GameEvent { 8 Profiler profiler; 9 bool continuePropagation = true; 10 } 11 12 template isGameEvent(T) 13 { 14 enum bool isGameEvent = is(typeof( 15 (inout int = 0) 16 { 17 T t; 18 t.profiler = new Profiler(null); 19 t.continuePropagation = true; 20 })); 21 } 22 23 private class ValidGameEventClass : GameEvent { 24 25 } 26 private struct ValidGameEvent { 27 Profiler profiler; 28 bool continuePropagation = true; 29 } 30 private struct InvalidEvent1 {} 31 private struct InvalidEvent2 {Profiler profiler;} 32 private struct InvalidEvent3 {bool continuePropagation;} 33 static assert(isGameEvent!ValidGameEvent); 34 static assert(isGameEvent!ValidGameEventClass); 35 static assert(!isGameEvent!InvalidEvent1); 36 static assert(!isGameEvent!InvalidEvent2); 37 static assert(!isGameEvent!InvalidEvent3); 38 39 private alias EventHandler = void delegate(ref GameEvent event); 40 41 shared static this() 42 { 43 pluginRegistry.regClientPlugin(new EventDispatcherPlugin); 44 pluginRegistry.regServerPlugin(new EventDispatcherPlugin); 45 } 46 47 class EventDispatcherPlugin : IPlugin 48 { 49 mixin IdAndSemverFrom!(voxelman.eventdispatcher.plugininfo); 50 51 Profiler profiler; 52 53 void subscribeToEvent(Event)(void delegate(ref Event event) handler) 54 { 55 static assert(isGameEvent!Event, Event.stringof ~ " must contain Profiler profiler; and bool continuePropagation;"); 56 _eventHandlers[typeid(Event)] ~= cast(EventHandler)handler; 57 } 58 59 void postEvent(Event)(auto ref Event event) 60 { 61 static assert(isGameEvent!Event, stringof(Event) ~ " must contain Profiler profiler; and bool continuePropagation;"); 62 auto handlers = typeid(Event) in _eventHandlers; 63 if (!handlers) return; 64 65 event.profiler = profiler; 66 foreach(handler; *handlers) 67 { 68 (cast(void delegate(ref Event))handler)(event); 69 if (!event.continuePropagation) break; 70 } 71 } 72 73 private: 74 75 EventHandler[][TypeInfo] _eventHandlers; 76 }