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                 if(!dispatchEvent(it->first, it->second))
00194                 {
00195                         delete it->first;
00196                 }
00197         }
00198     eventsBuf.clear();
00199 }
00200 
00201 bool UEventsManager::dispatchEvent(UEvent * event, const UEventsSender * sender)
00202 {
00203         std::list<UEventsHandler*> handlers;
00204 
00205         // Verify if there are pipes with the sender for his type of event
00206         if(sender)
00207         {
00208                 handlers = getPipes(sender, event->getClassName());
00209         }
00210 
00211         handlersMutex_.lock();
00212         if(handlers.size() == 0)
00213         {
00214                 //No pipes, send to all handlers
00215                 handlers = handlers_;
00216         }
00217 
00218         bool handled = false;
00219 
00220         for(std::list<UEventsHandler*>::iterator it=handlers.begin(); it!=handlers.end() && !handled; ++it)
00221         {
00222                 // Check if the handler is still in the
00223                 // handlers_ list (may be changed if addHandler() or
00224                 // removeHandler() is called in EventsHandler::handleEvent())
00225                 if(std::find(handlers_.begin(), handlers_.end(), *it) != handlers_.end())
00226                 {
00227                         UEventsHandler * handler = *it;
00228                         handlersMutex_.unlock();
00229 
00230                         // Don't process event if the handler is the same as the sender
00231                         if(handler != sender)
00232                         {
00233                                 // To be able to add/remove an handler in a handleEvent call (without a deadlock)
00234                                 // @see _addHandler(), _removeHandler()
00235                                 handled = handler->handleEvent(event);
00236                         }
00237 
00238                         handlersMutex_.lock();
00239                 }
00240         }
00241         handlersMutex_.unlock();
00242         return handled;
00243 }
00244 
00245 void UEventsManager::_addHandler(UEventsHandler* handler)
00246 {
00247     if(!this->isKilled())
00248     {
00249         handlersMutex_.lock();
00250         {
00251                 //make sure it is not already in the list
00252                 bool handlerFound = false;
00253                 for(std::list<UEventsHandler*>::iterator it=handlers_.begin(); it!=handlers_.end(); ++it)
00254                 {
00255                         if(*it == handler)
00256                         {
00257                                 handlerFound = true;
00258                         }
00259                 }
00260                 if(!handlerFound)
00261                 {
00262                         handlers_.push_back(handler);
00263                 }
00264         }
00265         handlersMutex_.unlock();
00266     }
00267 }
00268 
00269 void UEventsManager::_removeHandler(UEventsHandler* handler)
00270 {
00271     if(!this->isKilled())
00272     {
00273         handlersMutex_.lock();
00274         {
00275             for (std::list<UEventsHandler*>::iterator it = handlers_.begin(); it!=handlers_.end(); ++it)
00276             {
00277                 if(*it == handler)
00278                 {
00279                     handlers_.erase(it);
00280                     break;
00281                 }
00282             }
00283         }
00284         handlersMutex_.unlock();
00285 
00286         pipesMutex_.lock();
00287         {
00288                 for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
00289                         {
00290                                 if(iter->receiver_ == handler)
00291                                 {
00292                                         iter->receiver_ = 0; // set to null
00293                                 }
00294                         }
00295         }
00296         pipesMutex_.unlock();
00297     }
00298 }
00299 
00300 void UEventsManager::_postEvent(UEvent * event, bool async, const UEventsSender * sender)
00301 {
00302     if(!this->isKilled())
00303     {
00304         if(async)
00305         {
00306                         eventsMutex_.lock();
00307                         {
00308                                 events_.push_back(std::make_pair(event, sender));
00309                         }
00310                         eventsMutex_.unlock();
00311 
00312                         // Signal the EventsManager that an Event is added
00313                         postEventSem_.release();
00314         }
00315         else
00316         {
00317                 if(!dispatchEvent(event, sender))
00318                 {
00319                         delete event;
00320                 }
00321         }
00322     }
00323     else
00324     {
00325         delete event;
00326     }
00327 }
00328 
00329 std::list<UEventsHandler*> UEventsManager::getPipes(
00330                 const UEventsSender * sender,
00331                 const std::string & eventName)
00332 {
00333         std::list<UEventsHandler*> pipes;
00334         pipesMutex_.lock();
00335 
00336         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
00337         {
00338                 if(iter->sender_ == sender && iter->eventName_.compare(eventName) == 0)
00339                 {
00340                         bool added = false;
00341                         if(iter->receiver_)
00342                         {
00343                                 handlersMutex_.lock();
00344                                 for(std::list<UEventsHandler*>::iterator jter=handlers_.begin(); jter!=handlers_.end(); ++jter)
00345                                 {
00346                                         if(*jter == iter->receiver_)
00347                                         {
00348                                                 pipes.push_back(*jter);
00349                                                 added = true;
00350                                                 break;
00351                                         }
00352                                 }
00353                                 handlersMutex_.unlock();
00354                         }
00355                         if(!added)
00356                         {
00357                                 // Add nulls
00358                                 pipes.push_back(0);
00359                         }
00360                 }
00361         }
00362 
00363         pipesMutex_.unlock();
00364         return pipes;
00365 }
00366 
00367 void UEventsManager::_createPipe(
00368                 const UEventsSender * sender,
00369                 const UEventsHandler * receiver,
00370                 const std::string & eventName)
00371 {
00372         pipesMutex_.lock();
00373         bool exist = false;
00374         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();++iter)
00375         {
00376                 if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
00377                 {
00378                         exist = true;
00379                         break;
00380                 }
00381         }
00382 
00383         if(!exist)
00384         {
00385                 bool handlerFound = false;
00386                 handlersMutex_.lock();
00387                 for(std::list<UEventsHandler*>::iterator iter=handlers_.begin(); iter!=handlers_.end(); ++iter)
00388                 {
00389                         if(*iter == receiver)
00390                         {
00391                                 handlerFound = true;
00392                                 break;
00393                         }
00394                 }
00395                 handlersMutex_.unlock();
00396                 if(handlerFound)
00397                 {
00398                         pipes_.push_back(Pipe(sender, receiver, eventName));
00399                 }
00400                 else
00401                 {
00402                         UERROR("Cannot create the pipe because the receiver is not yet "
00403                                    "added to UEventsManager's handlers list.");
00404                 }
00405         }
00406         else
00407         {
00408                 UWARN("Pipe between sender %p and receiver %p with event %s was already created.",
00409                                 sender, receiver, eventName.c_str());
00410         }
00411         pipesMutex_.unlock();
00412 }
00413 
00414 void UEventsManager::_removePipe(
00415                 const UEventsSender * sender,
00416                 const UEventsHandler * receiver,
00417                 const std::string & eventName)
00418 {
00419         pipesMutex_.lock();
00420 
00421         bool removed = false;
00422         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();)
00423         {
00424                 if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
00425                 {
00426                         iter = pipes_.erase(iter);
00427                         removed = true;
00428                 }
00429                 else
00430                 {
00431                         ++iter;
00432                 }
00433         }
00434 
00435         if(!removed)
00436         {
00437                 UWARN("Pipe between sender %p and receiver %p with event %s didn't exist.",
00438                                 sender, receiver, eventName.c_str());
00439         }
00440 
00441         pipesMutex_.unlock();
00442 }
00443 
00444 void UEventsManager::_removeAllPipes(const UEventsSender * sender)
00445 {
00446         pipesMutex_.lock();
00447         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
00448         {
00449                 if(iter->sender_ == sender)
00450                 {
00451                         iter = pipes_.erase(iter);
00452                 }
00453                 else
00454                 {
00455                         ++iter;
00456                 }
00457         }
00458         pipesMutex_.unlock();
00459 }
00460 
00461 void UEventsManager::_removeNullPipes(const UEventsSender * sender)
00462 {
00463         pipesMutex_.lock();
00464         for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
00465         {
00466                 if(iter->receiver_ == 0)
00467                 {
00468                         iter = pipes_.erase(iter);
00469                 }
00470                 else
00471                 {
00472                         ++iter;
00473                 }
00474         }
00475         pipesMutex_.unlock();
00476 }


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:32