UEventsManager.cpp
Go to the documentation of this file.
00001 /*
00002 *  utilite is a cross-platform library with
00003 *  useful utilities for fast and small developing.
00004 *  Copyright (C) 2010  Mathieu Labbe
00005 *
00006 *  utilite is free library: you can redistribute it and/or modify
00007 *  it under the terms of the GNU Lesser General Public License as published by
00008 *  the Free Software Foundation, either version 3 of the License, or
00009 *  (at your option) any later version.
00010 *
00011 *  utilite is distributed in the hope that it will be useful,
00012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *  GNU Lesser General Public License for more details.
00015 *
00016 *  You should have received a copy of the GNU Lesser General Public License
00017 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 #include "rtabmap/utilite/UEventsManager.h"
00021 #include "rtabmap/utilite/UEvent.h"
00022 #include <list>
00023 #include "rtabmap/utilite/UStl.h"
00024 
00025 UEventsManager* UEventsManager::instance_ = 0;
00026 UDestroyer<UEventsManager> UEventsManager::destroyer_;
00027 
00028 void UEventsManager::addHandler(UEventsHandler* handler)
00029 {
00030         if(!handler)
00031         {
00032                 UERROR("Handler is null!");
00033                 return;
00034         }
00035         else
00036         {
00037                 UEventsManager::getInstance()->_addHandler(handler);
00038         }
00039 }
00040 
00041 void UEventsManager::removeHandler(UEventsHandler* handler)
00042 {
00043         if(!handler)
00044         {
00045                 UERROR("Handler is null!");
00046                 return;
00047         }
00048         else
00049         {
00050                 UEventsManager::getInstance()->_removeHandler(handler);
00051         }
00052 }
00053 
00054 void UEventsManager::post(UEvent * event, bool async, const UEventsSender * sender)
00055 {
00056         if(!event)
00057         {
00058                 UERROR("Event is null!");
00059                 return;
00060         }
00061         else
00062         {
00063                 UEventsManager::getInstance()->_postEvent(event, async, sender);
00064         }
00065 }
00066 
00067 void UEventsManager::createPipe(
00068                 const UEventsSender * sender,
00069                 const UEventsHandler * receiver,
00070                 const std::string & eventName)
00071 {
00072         if(!sender || !receiver)
00073         {
00074                 UERROR("Sender and/or receiver is null!");
00075                 return;
00076         }
00077         else
00078         {
00079                 UEventsManager::getInstance()->_createPipe(sender, receiver, eventName);
00080         }
00081 }
00082 
00083 void UEventsManager::removePipe(
00084                 const UEventsSender * sender,
00085                 const UEventsHandler * receiver,
00086                 const std::string & eventName)
00087 {
00088         if(!sender || !receiver)
00089         {
00090                 UERROR("Sender and/or receiver is null!");
00091                 return;
00092         }
00093         else
00094         {
00095                 UEventsManager::getInstance()->_removePipe(sender, receiver, eventName);
00096         }
00097 }
00098 
00099 void UEventsManager::removeAllPipes(const UEventsSender * sender)
00100 {
00101         if(!sender)
00102         {
00103                 UERROR("Sender is null!");
00104                 return;
00105         }
00106         else
00107         {
00108                 UEventsManager::getInstance()->_removeAllPipes(sender);
00109         }
00110 }
00111 
00112 void UEventsManager::removeNullPipes(const UEventsSender * sender)
00113 {
00114         if(!sender)
00115         {
00116                 UERROR("Sender is null!");
00117                 return;
00118         }
00119         else
00120         {
00121                 UEventsManager::getInstance()->_removeNullPipes(sender);
00122         }
00123 }
00124 
00125 UEventsManager* UEventsManager::getInstance()
00126 {
00127     if(!instance_)
00128     {
00129         instance_ = new UEventsManager();
00130         destroyer_.setDoomed(instance_);
00131         instance_->start(); // Start the thread
00132     }
00133     return instance_;
00134 }
00135 
00136 UEventsManager::UEventsManager()
00137 {
00138 }
00139 
00140 UEventsManager::~UEventsManager()
00141 {
00142         join(true);
00143 
00144     // Free memory
00145     for(std::list<std::pair<UEvent*, const UEventsSender*> >::iterator it=events_.begin(); it!=events_.end(); ++it)
00146     {
00147         delete it->first;
00148     }
00149     events_.clear();
00150 
00151     handlers_.clear();
00152 
00153     instance_ = 0;
00154 }
00155 
00156 void UEventsManager::mainLoop()
00157 {
00158     postEventSem_.acquire();
00159     if(!this->isKilled())
00160     {
00161                 dispatchEvents();
00162     }
00163 }
00164 
00165 void UEventsManager::mainLoopKill()
00166 {
00167     postEventSem_.release();
00168 }
00169 
00170 void UEventsManager::dispatchEvents()
00171 {
00172     if(events_.size() == 0)
00173     {
00174         return;
00175     }
00176 
00177     std::list<std::pair<UEvent*, const UEventsSender*> >::iterator it;
00178     std::list<std::pair<UEvent*, const UEventsSender*> > eventsBuf;
00179 
00180     // Copy events in a buffer :
00181     // Other threads can post events 
00182     // while events are handled.
00183     eventsMutex_.lock();
00184     {
00185         eventsBuf = events_;
00186         events_.clear();
00187     }
00188     eventsMutex_.unlock();
00189 
00190         // Past events to handlers
00191         for(it=eventsBuf.begin(); it!=eventsBuf.end(); ++it)
00192         {
00193                 dispatchEvent(it->first, it->second);
00194                 delete it->first;
00195         }
00196     eventsBuf.clear();
00197 }
00198 
00199 void UEventsManager::dispatchEvent(UEvent * event, const UEventsSender * sender)
00200 {
00201         std::list<UEventsHandler*> handlers;
00202 
00203         // Verify if there are pipes with the sender for his type of event
00204         if(sender)
00205         {
00206                 handlers = getPipes(sender, event->getClassName());
00207         }
00208 
00209         handlersMutex_.lock();
00210         if(handlers.size() == 0)
00211         {
00212                 //No pipes, send to all handlers
00213                 handlers = handlers_;
00214         }
00215 
00216         for(std::list<UEventsHandler*>::iterator it=handlers.begin(); it!=handlers.end(); ++it)
00217         {
00218                 // Check if the handler is still in the
00219                 // handlers_ list (may be changed if addHandler() or
00220                 // removeHandler() is called in EventsHandler::handleEvent())
00221                 if(std::find(handlers_.begin(), handlers_.end(), *it) != handlers_.end())
00222                 {
00223                         UEventsHandler * handler = *it;
00224                         handlersMutex_.unlock();
00225 
00226                         // Don't process event if the handler is the same as the sender
00227                         if(handler != sender)
00228                         {
00229                                 // To be able to add/remove an handler in a handleEvent call (without a deadlock)
00230                                 // @see _addHandler(), _removeHandler()
00231                                 handler->handleEvent(event);
00232                         }
00233 
00234                         handlersMutex_.lock();
00235                 }
00236         }
00237         handlersMutex_.unlock();
00238 }
00239 
00240 void UEventsManager::_addHandler(UEventsHandler* handler)
00241 {
00242     if(!this->isKilled())
00243     {
00244         handlersMutex_.lock();
00245         {
00246                 //make sure it is not already in the list
00247                 bool handlerFound = false;
00248                 for(std::list<UEventsHandler*>::iterator it=handlers_.begin(); it!=handlers_.end(); ++it)
00249                 {
00250                         if(*it == handler)
00251                         {
00252                                 handlerFound = true;
00253                         }
00254                 }
00255                 if(!handlerFound)
00256                 {
00257                         handlers_.push_back(handler);
00258                 }
00259         }
00260         handlersMutex_.unlock();
00261     }
00262 }
00263 
00264 void UEventsManager::_removeHandler(UEventsHandler* handler)
00265 {
00266     if(!this->isKilled())
00267     {
00268         handlersMutex_.lock();
00269         {
00270             for (std::list<UEventsHandler*>::iterator it = handlers_.begin(); it!=handlers_.end(); ++it)
00271             {
00272                 if(*it == handler)
00273                 {
00274                     handlers_.erase(it);
00275                     break;
00276                 }
00277             }
00278         }
00279         handlersMutex_.unlock();
00280 
00281         pipesMutex_.lock();
00282         {
00283                 for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
00284                         {
00285                                 if(iter->receiver_ == handler)
00286                                 {
00287                                         iter->receiver_ = 0; // set to null
00288                                 }
00289                         }
00290         }
00291         pipesMutex_.unlock();
00292     }
00293 }
00294 
00295 void UEventsManager::_postEvent(UEvent * event, bool async, const UEventsSender * sender)
00296 {
00297     if(!this->isKilled())
00298     {
00299         if(async)
00300         {
00301                         eventsMutex_.lock();
00302                         {
00303                                 events_.push_back(std::make_pair(event, sender));
00304                         }
00305                         eventsMutex_.unlock();
00306 
00307                         // Signal the EventsManager that an Event is added
00308                         postEventSem_.release();
00309         }
00310         else
00311         {
00312                 dispatchEvent(event, sender);
00313                 delete event;
00314         }
00315     }
00316     else
00317     {
00318         delete event;
00319     }
00320 }
00321 
00322 std::list<UEventsHandler*> UEventsManager::getPipes(
00323                 const UEventsSender * sender,
00324                 const std::string & eventName)
00325 {
00326         std::list<UEventsHandler*> pipes;
00327         pipesMutex_.lock();
00328 
00329         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
00330         {
00331                 if(iter->sender_ == sender && iter->eventName_.compare(eventName) == 0)
00332                 {
00333                         bool added = false;
00334                         if(iter->receiver_)
00335                         {
00336                                 handlersMutex_.lock();
00337                                 for(std::list<UEventsHandler*>::iterator jter=handlers_.begin(); jter!=handlers_.end(); ++jter)
00338                                 {
00339                                         if(*jter == iter->receiver_)
00340                                         {
00341                                                 pipes.push_back(*jter);
00342                                                 added = true;
00343                                                 break;
00344                                         }
00345                                 }
00346                                 handlersMutex_.unlock();
00347                         }
00348                         if(!added)
00349                         {
00350                                 // Add nulls
00351                                 pipes.push_back(0);
00352                         }
00353                 }
00354         }
00355 
00356         pipesMutex_.unlock();
00357         return pipes;
00358 }
00359 
00360 void UEventsManager::_createPipe(
00361                 const UEventsSender * sender,
00362                 const UEventsHandler * receiver,
00363                 const std::string & eventName)
00364 {
00365         pipesMutex_.lock();
00366         bool exist = false;
00367         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();++iter)
00368         {
00369                 if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
00370                 {
00371                         exist = true;
00372                         break;
00373                 }
00374         }
00375 
00376         if(!exist)
00377         {
00378                 bool handlerFound = false;
00379                 handlersMutex_.lock();
00380                 for(std::list<UEventsHandler*>::iterator iter=handlers_.begin(); iter!=handlers_.end(); ++iter)
00381                 {
00382                         if(*iter == receiver)
00383                         {
00384                                 handlerFound = true;
00385                                 break;
00386                         }
00387                 }
00388                 handlersMutex_.unlock();
00389                 if(handlerFound)
00390                 {
00391                         pipes_.push_back(Pipe(sender, receiver, eventName));
00392                 }
00393                 else
00394                 {
00395                         UERROR("Cannot create the pipe because the receiver is not yet "
00396                                    "added to UEventsManager's handlers list.");
00397                 }
00398         }
00399         else
00400         {
00401                 UWARN("Pipe between sender %p and receiver %p with event %s was already created.",
00402                                 sender, receiver, eventName.c_str());
00403         }
00404         pipesMutex_.unlock();
00405 }
00406 
00407 void UEventsManager::_removePipe(
00408                 const UEventsSender * sender,
00409                 const UEventsHandler * receiver,
00410                 const std::string & eventName)
00411 {
00412         pipesMutex_.lock();
00413 
00414         bool removed = false;
00415         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();)
00416         {
00417                 if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
00418                 {
00419                         iter = pipes_.erase(iter);
00420                         removed = true;
00421                 }
00422                 else
00423                 {
00424                         ++iter;
00425                 }
00426         }
00427 
00428         if(!removed)
00429         {
00430                 UWARN("Pipe between sender %p and receiver %p with event %s didn't exist.",
00431                                 sender, receiver, eventName.c_str());
00432         }
00433 
00434         pipesMutex_.unlock();
00435 }
00436 
00437 void UEventsManager::_removeAllPipes(const UEventsSender * sender)
00438 {
00439         pipesMutex_.lock();
00440         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
00441         {
00442                 if(iter->sender_ == sender)
00443                 {
00444                         iter = pipes_.erase(iter);
00445                 }
00446                 else
00447                 {
00448                         ++iter;
00449                 }
00450         }
00451         pipesMutex_.unlock();
00452 }
00453 
00454 void UEventsManager::_removeNullPipes(const UEventsSender * sender)
00455 {
00456         pipesMutex_.lock();
00457         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
00458         {
00459                 if(iter->receiver_ == 0)
00460                 {
00461                         iter = pipes_.erase(iter);
00462                 }
00463                 else
00464                 {
00465                         ++iter;
00466                 }
00467         }
00468         pipesMutex_.unlock();
00469 }


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:28