1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/events.h"
24 
25 namespace Common {
26 
EventDispatcher()27 EventDispatcher::EventDispatcher() : _autoFreeMapper(false), _mapper(nullptr) {
28 }
29 
~EventDispatcher()30 EventDispatcher::~EventDispatcher() {
31 	for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
32 		if (i->autoFree)
33 			delete i->source;
34 	}
35 
36 	for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
37 		if (i->autoFree)
38 			delete i->observer;
39 	}
40 
41 	if (_autoFreeMapper) {
42 		delete _mapper;
43 	}
44 	_mapper = nullptr;
45 }
46 
dispatch()47 void EventDispatcher::dispatch() {
48 	Event event;
49 
50 	dispatchPoll();
51 
52 	for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
53 		while (i->source->pollEvent(event)) {
54 			// We only try to process the events via the setup event mapper, when
55 			// we have a setup mapper and when the event source allows mapping.
56 			assert(_mapper);
57 			List<Event> mappedEvents = _mapper->mapEvent(event, i->source);
58 
59 			for (List<Event>::iterator j = mappedEvents.begin(); j != mappedEvents.end(); ++j) {
60 				const Event mappedEvent = *j;
61 				dispatchEvent(mappedEvent);
62 			}
63 		}
64 	}
65 
66 	List<Event> delayedEvents = _mapper->getDelayedEvents();
67 	for (List<Event>::iterator k = delayedEvents.begin(); k != delayedEvents.end(); ++k) {
68 		const Event delayedEvent = *k;
69 		dispatchEvent(delayedEvent);
70 	}
71 }
72 
clearEvents()73 void EventDispatcher::clearEvents() {
74 	Event event;
75 
76 	for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
77 		while (i->source->pollEvent(event)) {}
78 	}
79 }
80 
81 
registerMapper(EventMapper * mapper,bool autoFree)82 void EventDispatcher::registerMapper(EventMapper *mapper, bool autoFree) {
83 	if (_autoFreeMapper) {
84 		delete _mapper;
85 	}
86 	_mapper = mapper;
87 	_autoFreeMapper = autoFree;
88 }
89 
90 
registerSource(EventSource * source,bool autoFree)91 void EventDispatcher::registerSource(EventSource *source, bool autoFree) {
92 	SourceEntry newEntry;
93 
94 	newEntry.source = source;
95 	newEntry.autoFree = autoFree;
96 
97 	_sources.push_back(newEntry);
98 }
99 
unregisterSource(EventSource * source)100 void EventDispatcher::unregisterSource(EventSource *source) {
101 	for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
102 		if (i->source == source) {
103 			if (i->autoFree)
104 				delete source;
105 
106 			_sources.erase(i);
107 			return;
108 		}
109 	}
110 }
111 
registerObserver(EventObserver * obs,uint priority,bool autoFree,bool notifyPoll)112 void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree, bool notifyPoll) {
113 	ObserverEntry newEntry;
114 
115 	newEntry.observer = obs;
116 	newEntry.priority = priority;
117 	newEntry.autoFree = autoFree;
118 	newEntry.poll = notifyPoll;
119 
120 	for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
121 		if (i->priority < priority) {
122 			_observers.insert(i, newEntry);
123 			return;
124 		}
125 	}
126 
127 	_observers.push_back(newEntry);
128 }
129 
unregisterObserver(EventObserver * obs)130 void EventDispatcher::unregisterObserver(EventObserver *obs) {
131 	for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
132 		if (i->observer == obs) {
133 			if (i->autoFree)
134 				delete obs;
135 
136 			_observers.erase(i);
137 			return;
138 		}
139 	}
140 }
141 
dispatchEvent(const Event & event)142 void EventDispatcher::dispatchEvent(const Event &event) {
143 	for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
144 		if (i->observer->notifyEvent(event))
145 			break;
146 	}
147 }
148 
dispatchPoll()149 void EventDispatcher::dispatchPoll() {
150 	for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
151 		if (i->poll == true)
152 			if (i->observer->notifyPoll())
153 				break;
154 	}
155 }
156 
157 } // End of namespace Common
158