1 module eventmanager.eventdispatcher;
2 
3 import std.container : SList;
4 import std.algorithm.comparison : equal;
5 import std.stdio;
6 
7 import eventmanager.eventlistenerinterface;
8 import eventmanager.eventinterface;
9 import eventmanager.eventlist;
10 
11 interface EventDispatcherInterface
12 {
13     public void attachListener(EventListenerInterface listener) @safe;
14     public EventListInterface dispatch(EventInterface event, TypeInfo eventType) @safe;
15 }
16 
17 class EventDispatcher : EventDispatcherInterface
18 {
19     // To clarify, this is a hashmap where an object type maps
20     // to a singly linked list of eventlistenerinterfaces.
21     private SList!EventListenerInterface[TypeInfo] listenerMap;
22     
23     public void attachListener(EventListenerInterface listener) @safe
24     {
25         auto listenerType = typeid(listener);
26         auto interestedEvents = listener.getInterestedEvents();
27 
28         foreach (eventType; interestedEvents) {
29             if (!(eventType in this.listenerMap)) {
30                 this.listenerMap[eventType] = SList!EventListenerInterface(listener);
31             } else {
32                 this.listenerMap[eventType].insertFront(listener);
33             }
34         }
35     }
36 
37     public EventListInterface dispatch(EventInterface event, TypeInfo eventType) @safe
38     {
39         auto eventList = new EventList();
40         
41         if(this.noListenersInterestedInThisEvent(eventType)) {
42             return eventList;
43         }
44 
45         event.setEventReceived();
46 
47         auto interestedListeners = this.listenerMap[eventType];
48 
49         foreach (listener; interestedListeners) {
50             eventList.append(listener.handleEvent(event, eventType));
51         }
52 
53         event.setEventDispatched();
54 
55         return eventList;
56     }    
57 
58     private bool noListenersInterestedInThisEvent(TypeInfo eventType) @safe {
59         return !(eventType in this.listenerMap);
60     }
61 }