[Scummvm-cvs-logs] SF.net SVN: scummvm:[42717] scummvm/trunk/common

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sat Jul 25 02:58:45 CEST 2009


Revision: 42717
          http://scummvm.svn.sourceforge.net/scummvm/?rev=42717&view=rev
Author:   lordhoto
Date:     2009-07-25 00:58:44 +0000 (Sat, 25 Jul 2009)

Log Message:
-----------
Add new event dispatching API.

Modified Paths:
--------------
    scummvm/trunk/common/events.h

Added Paths:
-----------
    scummvm/trunk/common/events.cpp

Added: scummvm/trunk/common/events.cpp
===================================================================
--- scummvm/trunk/common/events.cpp	                        (rev 0)
+++ scummvm/trunk/common/events.cpp	2009-07-25 00:58:44 UTC (rev 42717)
@@ -0,0 +1,136 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/events.h"
+
+DECLARE_SINGLETON(Common::EventDispatcher);
+
+namespace Common {
+
+EventDispatcher::EventDispatcher() : _mapper(0) {
+}
+
+EventDispatcher::~EventDispatcher() {
+	for (Common::List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
+		if (i->autoFree)
+			delete i->source;
+	}
+
+	for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+		if (i->autoFree)
+			delete i->observer;
+	}
+
+	delete _mapper;
+	_mapper = 0;
+}
+
+void EventDispatcher::dispatch() {
+	Common::Event event;
+
+	for (Common::List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
+		while (i->source->pollEvent(event)) {
+			if (_mapper) {
+				if (_mapper->notifyEvent(event)) {
+					// We allow the event mapper to create multiple events, when
+					// eating an event.
+					while (_mapper->pollEvent(event))
+						dispatchEvent(event);
+
+					// Try getting another event from the current EventSource.
+					continue;
+				}
+			}
+
+			dispatchEvent(event);
+		}
+	}
+}
+
+void EventDispatcher::registerMapper(EventMapper *mapper) {
+	if (_mapper)
+		delete _mapper;
+	_mapper = mapper;
+}
+
+void EventDispatcher::registerSource(EventSource *source, bool autoFree) {
+	SourceEntry newEntry;
+
+	newEntry.source = source;
+	newEntry.autoFree = autoFree;
+
+	_sources.push_back(newEntry);
+}
+
+void EventDispatcher::unregisterSource(EventSource *source) {
+	for (Common::List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
+		if (i->source == source) {
+			if (i->autoFree)
+				delete source;
+
+			_sources.erase(i);
+			return;
+		}
+	}	
+}
+
+void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree) {
+	ObserverEntry newEntry;
+
+	newEntry.observer = obs;
+	newEntry.priority = priority;
+	newEntry.autoFree = autoFree;
+
+	for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+		if (i->priority < priority) {
+			_observers.insert(i, newEntry);
+			return;
+		}
+	}
+
+	_observers.push_back(newEntry);
+}
+
+void EventDispatcher::unregisterObserver(EventObserver *obs) {
+	for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+		if (i->observer == obs) {
+			if (i->autoFree)
+				delete obs;
+
+			_observers.erase(i);
+			return;
+		}
+	}
+}
+
+void EventDispatcher::dispatchEvent(const Event &event) {
+	for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+		if (i->observer->notifyEvent(event))
+			break;
+	}
+}
+
+} // end of namespace Common
+


Property changes on: scummvm/trunk/common/events.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/common/events.h
===================================================================
--- scummvm/trunk/common/events.h	2009-07-24 21:36:59 UTC (rev 42716)
+++ scummvm/trunk/common/events.h	2009-07-25 00:58:44 UTC (rev 42717)
@@ -31,6 +31,9 @@
 #include "common/rect.h"
 #include "common/noncopyable.h"
 
+#include "common/list.h"
+#include "common/singleton.h"
+
 namespace Common {
 
 /**
@@ -126,6 +129,146 @@
 	Event() : type(EVENT_INVALID), synthetic(false) {}
 };
 
+/**
+ * A source of Events.
+ *
+ * An example for this is OSystem, it provides events created by the system
+ * and or user.
+ */
+class EventSource {
+public:
+	virtual ~EventSource() {}
+
+	/**
+	 * Queries a event from the source.
+	 *
+	 * @param	event 	a reference to the event struct, where the event should be stored.
+	 * @return	true if an event was polled, false otherwise.
+	 */
+	virtual bool pollEvent(Event &event) = 0;
+};
+
+/**
+ * Object which catches and processes Events.
+ *
+ * An example for this is the Engine object, it is catching events and processing them.
+ */
+class EventObserver {
+public:
+	virtual ~EventObserver() {}
+
+	/**
+	 * Notifies the source of an incoming event.
+	 *
+	 * An obeser is supposed to eat the event, with returning true, when
+	 * it might want prevent other observers from preventing to receive
+	 * the event. An usage example here is the keymapper:
+	 * If it processes an Event, it should 'eat' it and create a new
+	 * event, which the EventDispatcher will then catch.
+	 *
+	 * @param	event	the event, which is incoming.
+	 * @return	true if this observer uses this event, false otherwise.
+	 */
+	virtual bool notifyEvent(const Event &event) = 0;
+};
+
+/**
+ * A event mapper, which will map events to others.
+ *
+ * An example for this is the Keymapper.
+ */
+class EventMapper : public EventSource, public EventObserver {
+};
+
+/**
+ * Dispatches events from various sources to various observers.
+ *
+ * EventDispatcher is using a priority based approach. Observers
+ * with higher priority will be notified before observers with
+ * lower priority. Because of the possibility that oberservers
+ * might 'eat' events, not all observers might be notified.
+ *
+ * Another speciality is the support for a event mapper, which
+ * will catch events and create new events out of them. This
+ * mapper will be processed before an event is sent to the
+ * observers. 
+ */
+class EventDispatcher : public Singleton<EventDispatcher> {
+	friend class Singleton<SingletonBaseType>;
+public:
+	/**
+	 * Tries to catch events from the registered event
+	 * sources and dispatch them to the observers.
+	 */
+	void dispatch();
+
+	/**
+	 * Registers an event mapper with the dispatcher.
+	 *
+	 * The ownership of the "mapper" variable will pass
+	 * to the EventDispatcher, thus it will be deleted
+	 * with "delete", when EventDispatcher is destroyed.
+	 *
+	 * Note there is only one mapper per EventDispatcher
+	 * possible, thus when this method is called twice,
+	 * the former mapper will be destroied.
+	 */
+	void registerMapper(EventMapper *mapper);
+
+	/**
+	 * Queries the setup event mapper.
+	 */
+	EventMapper *queryMapper() const { return _mapper; }
+
+	/**
+	 * Registers a new EventSource with the Dispatcher.
+	 */
+	void registerSource(EventSource *source, bool autoFree);
+
+	/**
+	 * Unregisters a EventSource.
+	 *
+	 * This takes the "autoFree" flag passed to registerSource into account.
+	 */
+	void unregisterSource(EventSource *source);
+
+	/**
+	 * Registers a new EventObserver with the Dispatcher.
+	 */
+	void registerObserver(EventObserver *obs, uint priority, bool autoFree);
+
+	/**
+	 * Unregisters a EventObserver.
+	 *
+	 * This takes the "autoFree" flag passed to registerObserver into account.
+	 */
+	void unregisterObserver(EventObserver *obs);
+private:
+	EventDispatcher();
+	~EventDispatcher();
+
+	EventMapper *_mapper;
+
+	struct Entry {
+		bool autoFree;
+	};
+
+	struct SourceEntry : public Entry {
+		EventSource *source;
+	};
+	
+	Common::List<SourceEntry> _sources;
+
+	struct ObserverEntry : public Entry {
+		uint priority;
+		EventObserver *observer;
+	};
+
+	Common::List<ObserverEntry> _observers;
+
+	void dispatchEvent(const Event &event);
+};
+
 class Keymapper;
 
 /**


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list