C:/Users/Mike/Documents/Visual Studio Projects/GameEngine/src/EventManager.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 Copyright (C) 2006 Michael Harnetty
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 -----------------------------------------------------------------------------
00019 */
00020 
00021 #include "EventManager.h"
00022 #include "Timer.h"
00023 
00024 namespace GameEngine {
00025 
00026         EventManager::EventManager()
00027                 :       mActiveQueue(0)
00028         {
00029 
00030         }
00031 
00032 
00033         EventManager::~EventManager()
00034         {
00035                 mActiveQueue = 0;
00036         }
00037 
00038 
00039         bool EventManager::addListener(EventListenerPtr const & listener, EventType const & eventType)
00040         {
00041                 // Is this a valid EventType ?
00042                 if(!validateType(eventType))
00043                         return false;
00044 
00045                 // Check manager is aware of this type of event
00046                 EventTypeSet::iterator typeSetIt = mTypeList.find(eventType);
00047 
00048                 if(typeSetIt == mTypeList.end()){ // Not yet aware, register it now
00049                         mTypeList.insert(eventType);
00050                 }
00051 
00052 
00053                 // Check event type has entry in EventType - Listeners registry
00054                 EventListenerMap::iterator elmIt = mRegistry.find(eventType.getIdent());
00055 
00056                 if(elmIt == mRegistry.end()){  // No entry, create one now
00057                         EventListenerMapIRes elmIRes = mRegistry.insert( EventListenerMapEnt( eventType.getIdent(), EventListenerTable() ) );
00058                         
00059                         elmIt = elmIRes.first;
00060                 }
00061                 
00062 
00063                 // Get reference to table of listeners for this event type
00064                 EventListenerTable& evlTable = (*elmIt).second;
00065 
00066                 // Check if this listener is already registered to listen for events of this type
00067                 for(EventListenerTable::iterator it = evlTable.begin(),  itEnd = evlTable.end(); it != itEnd; it++){
00068                          bool bListenerMatch = (*it == listener);
00069 
00070                          if(bListenerMatch) // Already registered, can't register twice!
00071                                  return false;
00072                 }
00073 
00074                 // Register listener
00075                 evlTable.push_back( listener );
00076 
00077                 // Registered succesfully
00078                 return true;
00079         }
00080 
00081         
00082         bool EventManager::delListener(EventListenerPtr const & listener, EventType const & eventType)
00083         {
00084                 bool returnCode = false;
00085 
00086                 // Is this a valid EventType ?
00087                 if(!validateType(eventType))
00088                         return false;
00089 
00090 
00091                 // Iterate through EventListenerMap to find listeners
00092                 for(EventListenerMap::iterator it = mRegistry.begin(), itEnd = mRegistry.end(); it != itEnd; it++){
00093                         
00094                         int curEventType = it->first;
00095                         EventListenerTable table = it->second;
00096                         
00097                         if(curEventType == eventType.getIdent()){
00098                                 for(EventListenerTable::iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++){
00099                                         if(*it2 == listener){
00100                                                 table.erase( it2 );
00101                                                 returnCode = true;
00102                                                 break; // Can break for this inner for loop, as each listener can occur only once in an events listener table!
00103                                         }
00104                                 }
00105                         }
00106 
00107                 }
00108 
00109                 return returnCode;
00110         }
00111 
00112 
00113         bool EventManager::sendEvent(Event const & event) const
00114         {
00115                 if( !validateType(event.getEventType()) )
00116                         return false;
00117 
00118                 // Send event to all wildcardEventType listeners (those who want to listen to all events)
00119                 EventListenerMap::const_iterator itWc = mRegistry.find( 0 );
00120 
00121                 if(itWc != mRegistry.end()){
00122                         EventListenerTable const& table = itWc->second;
00123 
00124                         for(EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++){
00125                                 (*it2)->handleEvent( event );
00126                         }
00127                 }
00128 
00129 
00130 
00131                 // Now send event to listeners who only listen for this specific type of event
00132                 EventListenerMap::const_iterator it = mRegistry.find( event.getEventType().getIdent() );
00133                         
00134                 if( it == mRegistry.end() )
00135                         return false;
00136 
00137                 EventListenerTable const & table = it->second;
00138 
00139                 bool processed = false;
00140 
00141                 for(EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++){
00142                         if( (*it2)->handleEvent(event) ){ // Message eaten
00143                                 processed = true;
00144                         }
00145                 }
00146 
00147                 return processed;
00148         }
00149         
00150 
00151         bool EventManager::queueEvent(EventPtr const & event)
00152         {
00153                 assert( mActiveQueue >= 0 );
00154                 assert( mActiveQueue < NUM_QUEUES);
00155 
00156                 if( !validateType(event->getEventType()) )
00157                         return false;
00158 
00159                 EventListenerMap::const_iterator it = mRegistry.find( event->getEventType().getIdent() );
00160 
00161                 if( it == mRegistry.end() ) {
00162                         EventListenerMap::const_iterator itWc = mRegistry.find(0);
00163 
00164                         if( itWc == mRegistry.end() ){
00165                                 return false;
00166                         }
00167                 }
00168 
00169                 mQueues[mActiveQueue].push_back( event );
00170                 return true;
00171         }
00172 
00173 
00174         bool EventManager::tick(const double maxTime)
00175         {
00176                 Timer timer;
00177                 double timeLimit = timer.getMilliseconds() + maxTime; 
00178 
00179                 EventListenerMap::const_iterator itWc = mRegistry.find(0);
00180 
00181                 int queueToProcess = mActiveQueue;
00182                 mActiveQueue = (mActiveQueue + 1) % NUM_QUEUES; // Swap active queue around
00183                 mQueues[mActiveQueue].clear();
00184 
00185                 while(mQueues[queueToProcess].size() > 0){
00186                         EventPtr event = mQueues[queueToProcess].front();
00187                         mQueues[queueToProcess].pop_front();
00188                         EventType const& eventType = event->getEventType();
00189 
00190                         EventListenerMap::const_iterator itListeners = mRegistry.find( eventType.getIdent() );
00191 
00192                         if(itWc != mRegistry.end()){
00193                                 EventListenerTable const& table = itWc->second;
00194                                 bool processed = false;
00195 
00196                                 for( EventListenerTable::const_iterator it2 = table.begin(), it2End = table.end(); it2 != it2End; it2++){
00197                                         (*it2)->handleEvent(*event);
00198                                 }
00199                         }
00200 
00201                         if(itListeners == mRegistry.end())
00202                                 continue;
00203 
00204                         int const eventId = itListeners->first;
00205                         EventListenerTable const& table = itListeners->second;
00206 
00207                         for(EventListenerTable::const_iterator it = table.begin(), itEnd = table.end(); it != itEnd; it++){
00208                                 if( (*it)->handleEvent( *event ) ){ // Event consumed by handler
00209                                          break;
00210                                 }
00211                         }
00212 
00213 
00214                         if(timer.getMilliseconds() > timeLimit ){
00215                                 break; // Used all our alloted time, exit the loop!
00216                         }
00217                 }
00218 
00219 
00220 
00221                 bool queueFlushed = (mQueues[queueToProcess].size() < 1);
00222 
00223                 if( !queueFlushed){
00224                         while(mQueues[queueToProcess].size() > 0){
00225                                 EventPtr event = mQueues[queueToProcess].back();
00226                                 mQueues[queueToProcess].pop_back();
00227                                 mQueues[mActiveQueue].push_front( event );
00228                         }
00229                 }
00230 
00231                 return queueFlushed;
00232         }
00233 
00234 
00235 
00236         bool EventManager::validateType(EventType const & type) const
00237         {
00238                 if( type.getStr() == NULL) // Can't be NULL
00239                         return false;
00240 
00241                 if( (type.getIdent() == 0) && (strcmp(type.getStr(), wildcardEventType) != 0) ) // Hash value must be either non-zero or the wildcard
00242                         return false;
00243 
00244                 EventTypeSet::const_iterator evIt = mTypeList.find( type);
00245 
00246                 if(evIt != mTypeList.end()){
00247 
00248                         // Verify the text signature is the same as already known
00249                         EventType const& known = *evIt;
00250 
00251                         char const * const knownTag = known.getStr();
00252                         char const * const newTag = type.getStr();
00253 
00254                         int cv = stricmp( knownTag, newTag);
00255 
00256 
00257                         // Tag mismatch for ident value, not accepted
00258                         assert( cv == 0 && "You are horrible unlucky" );
00259 
00260                         if(cv != 0)
00261                                 return false;
00262                 }
00263 
00264                 return true;
00265         }
00266 
00267 }

Generated on Thu Apr 19 09:47:02 2007 for GameEngine by  doxygen 1.5.2