UEventsManager.cpp
Go to the documentation of this file.
1 /*
2 * utilite is a cross-platform library with
3 * useful utilities for fast and small developing.
4 * Copyright (C) 2010 Mathieu Labbe
5 *
6 * utilite is free library: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * utilite is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
21 #include "rtabmap/utilite/UEvent.h"
22 #include <list>
23 #include "rtabmap/utilite/UStl.h"
24 
27 
29 {
30  if(!handler)
31  {
32  UERROR("Handler is null!");
33  return;
34  }
35  else
36  {
38  }
39 }
40 
42 {
43  if(!handler)
44  {
45  UERROR("Handler is null!");
46  return;
47  }
48  else
49  {
51  }
52 }
53 
54 void UEventsManager::post(UEvent * event, bool async, const UEventsSender * sender)
55 {
56  if(!event)
57  {
58  UERROR("Event is null!");
59  return;
60  }
61  else
62  {
63  UEventsManager::getInstance()->_postEvent(event, async, sender);
64  }
65 }
66 
68  const UEventsSender * sender,
69  const UEventsHandler * receiver,
70  const std::string & eventName)
71 {
72  if(!sender || !receiver)
73  {
74  UERROR("Sender and/or receiver is null!");
75  return;
76  }
77  else
78  {
79  UEventsManager::getInstance()->_createPipe(sender, receiver, eventName);
80  }
81 }
82 
84  const UEventsSender * sender,
85  const UEventsHandler * receiver,
86  const std::string & eventName)
87 {
88  if(!sender || !receiver)
89  {
90  UERROR("Sender and/or receiver is null!");
91  return;
92  }
93  else
94  {
95  UEventsManager::getInstance()->_removePipe(sender, receiver, eventName);
96  }
97 }
98 
100 {
101  if(!sender)
102  {
103  UERROR("Sender is null!");
104  return;
105  }
106  else
107  {
109  }
110 }
111 
113 {
114  if(!sender)
115  {
116  UERROR("Sender is null!");
117  return;
118  }
119  else
120  {
122  }
123 }
124 
126 {
127  if(!instance_)
128  {
129  instance_ = new UEventsManager();
131  instance_->start(); // Start the thread
132  }
133  return instance_;
134 }
135 
137 {
138 }
139 
141 {
142  join(true);
143 
144  // Free memory
145  for(std::list<std::pair<UEvent*, const UEventsSender*> >::iterator it=events_.begin(); it!=events_.end(); ++it)
146  {
147  delete it->first;
148  }
149  events_.clear();
150 
151  handlers_.clear();
152 
153  instance_ = 0;
154 }
155 
157 {
159  if(!this->isKilled())
160  {
161  dispatchEvents();
162  }
163 }
164 
166 {
168 }
169 
171 {
172  if(events_.size() == 0)
173  {
174  return;
175  }
176 
177  std::list<std::pair<UEvent*, const UEventsSender*> >::iterator it;
178  std::list<std::pair<UEvent*, const UEventsSender*> > eventsBuf;
179 
180  // Copy events in a buffer :
181  // Other threads can post events
182  // while events are handled.
183  eventsMutex_.lock();
184  {
185  eventsBuf = events_;
186  events_.clear();
187  }
189 
190  // Past events to handlers
191  for(it=eventsBuf.begin(); it!=eventsBuf.end(); ++it)
192  {
193  if(!dispatchEvent(it->first, it->second))
194  {
195  delete it->first;
196  }
197  }
198  eventsBuf.clear();
199 }
200 
202 {
203  std::list<UEventsHandler*> handlers;
204 
205  // Verify if there are pipes with the sender for his type of event
206  if(sender)
207  {
208  handlers = getPipes(sender, event->getClassName());
209  }
210 
212  if(handlers.size() == 0)
213  {
214  //No pipes, send to all handlers
215  handlers = handlers_;
216  }
217 
218  bool handled = false;
219 
220  for(std::list<UEventsHandler*>::iterator it=handlers.begin(); it!=handlers.end() && !handled; ++it)
221  {
222  // Check if the handler is still in the
223  // handlers_ list (may be changed if addHandler() or
224  // removeHandler() is called in EventsHandler::handleEvent())
225  if(std::find(handlers_.begin(), handlers_.end(), *it) != handlers_.end())
226  {
227  UEventsHandler * handler = *it;
229 
230  // Don't process event if the handler is the same as the sender
231  if(handler != sender)
232  {
233  // To be able to add/remove an handler in a handleEvent call (without a deadlock)
234  // @see _addHandler(), _removeHandler()
235  handled = handler->handleEvent(event);
236  }
237 
239  }
240  }
242  return handled;
243 }
244 
246 {
247  if(!this->isKilled())
248  {
250  {
251  //make sure it is not already in the list
252  bool handlerFound = false;
253  for(std::list<UEventsHandler*>::iterator it=handlers_.begin(); it!=handlers_.end(); ++it)
254  {
255  if(*it == handler)
256  {
257  handlerFound = true;
258  }
259  }
260  if(!handlerFound)
261  {
262  handlers_.push_back(handler);
263  }
264  }
266  }
267 }
268 
270 {
271  if(!this->isKilled())
272  {
274  {
275  for (std::list<UEventsHandler*>::iterator it = handlers_.begin(); it!=handlers_.end(); ++it)
276  {
277  if(*it == handler)
278  {
279  handlers_.erase(it);
280  break;
281  }
282  }
283  }
285 
286  pipesMutex_.lock();
287  {
288  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
289  {
290  if(iter->receiver_ == handler)
291  {
292  iter->receiver_ = 0; // set to null
293  }
294  }
295  }
297  }
298 }
299 
300 void UEventsManager::_postEvent(UEvent * event, bool async, const UEventsSender * sender)
301 {
302  if(!this->isKilled())
303  {
304  if(async)
305  {
306  eventsMutex_.lock();
307  {
308  events_.push_back(std::make_pair(event, sender));
309  }
311 
312  // Signal the EventsManager that an Event is added
314  }
315  else
316  {
317  if(!dispatchEvent(event, sender))
318  {
319  delete event;
320  }
321  }
322  }
323  else
324  {
325  delete event;
326  }
327 }
328 
329 std::list<UEventsHandler*> UEventsManager::getPipes(
330  const UEventsSender * sender,
331  const std::string & eventName)
332 {
333  std::list<UEventsHandler*> pipes;
334  pipesMutex_.lock();
335 
336  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end(); ++iter)
337  {
338  if(iter->sender_ == sender && iter->eventName_.compare(eventName) == 0)
339  {
340  bool added = false;
341  if(iter->receiver_)
342  {
344  for(std::list<UEventsHandler*>::iterator jter=handlers_.begin(); jter!=handlers_.end(); ++jter)
345  {
346  if(*jter == iter->receiver_)
347  {
348  pipes.push_back(*jter);
349  added = true;
350  break;
351  }
352  }
354  }
355  if(!added)
356  {
357  // Add nulls
358  pipes.push_back(0);
359  }
360  }
361  }
362 
364  return pipes;
365 }
366 
368  const UEventsSender * sender,
369  const UEventsHandler * receiver,
370  const std::string & eventName)
371 {
372  pipesMutex_.lock();
373  bool exist = false;
374  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();++iter)
375  {
376  if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
377  {
378  exist = true;
379  break;
380  }
381  }
382 
383  if(!exist)
384  {
385  bool handlerFound = false;
387  for(std::list<UEventsHandler*>::iterator iter=handlers_.begin(); iter!=handlers_.end(); ++iter)
388  {
389  if(*iter == receiver)
390  {
391  handlerFound = true;
392  break;
393  }
394  }
396  if(handlerFound)
397  {
398  pipes_.push_back(Pipe(sender, receiver, eventName));
399  }
400  else
401  {
402  UERROR("Cannot create the pipe because the receiver is not yet "
403  "added to UEventsManager's handlers list.");
404  }
405  }
406  else
407  {
408  UWARN("Pipe between sender %p and receiver %p with event %s was already created.",
409  sender, receiver, eventName.c_str());
410  }
412 }
413 
415  const UEventsSender * sender,
416  const UEventsHandler * receiver,
417  const std::string & eventName)
418 {
419  pipesMutex_.lock();
420 
421  bool removed = false;
422  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!= pipes_.end();)
423  {
424  if(iter->sender_ == sender && iter->receiver_ == receiver && iter->eventName_.compare(eventName) == 0)
425  {
426  iter = pipes_.erase(iter);
427  removed = true;
428  }
429  else
430  {
431  ++iter;
432  }
433  }
434 
435  if(!removed)
436  {
437  UWARN("Pipe between sender %p and receiver %p with event %s didn't exist.",
438  sender, receiver, eventName.c_str());
439  }
440 
442 }
443 
445 {
446  pipesMutex_.lock();
447  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
448  {
449  if(iter->sender_ == sender)
450  {
451  iter = pipes_.erase(iter);
452  }
453  else
454  {
455  ++iter;
456  }
457  }
459 }
460 
462 {
463  pipesMutex_.lock();
464  for(std::list<Pipe>::iterator iter=pipes_.begin(); iter!=pipes_.end();)
465  {
466  if(iter->receiver_ == 0)
467  {
468  iter = pipes_.erase(iter);
469  }
470  else
471  {
472  ++iter;
473  }
474  }
476 }
void release(int n=1)
Definition: USemaphore.h:168
static void createPipe(const UEventsSender *sender, const UEventsHandler *receiver, const std::string &eventName)
void start()
Definition: UThread.cpp:122
USemaphore postEventSem_
static void post(UEvent *event, bool async=true, const UEventsSender *sender=0)
Definition: UEvent.h:57
void _removeAllPipes(const UEventsSender *sender)
bool setDoomed(T *doomed)
Definition: UDestroyer.h:57
virtual ~UEventsManager()
std::list< Pipe > pipes_
void _removeNullPipes(const UEventsSender *sender)
std::list< UEventsHandler * > getPipes(const UEventsSender *sender, const std::string &eventName)
void _addHandler(UEventsHandler *handler)
void _postEvent(UEvent *event, bool async=true, const UEventsSender *sender=0)
void _createPipe(const UEventsSender *sender, const UEventsHandler *receiver, const std::string &eventName)
static void removeNullPipes(const UEventsSender *sender)
bool acquire(int n=1, int ms=0)
Definition: USemaphore.h:101
void _removeHandler(UEventsHandler *handler)
static UEventsManager * instance_
Wrappers of STL for convenient functions.
int lock() const
Definition: UMutex.h:87
virtual bool dispatchEvent(UEvent *event, const UEventsSender *sender)
virtual void mainLoop()
virtual std::string getClassName() const =0
int unlock() const
Definition: UMutex.h:113
virtual void dispatchEvents()
static void removePipe(const UEventsSender *sender, const UEventsHandler *receiver, const std::string &eventName)
virtual bool handleEvent(UEvent *event)=0
static UDestroyer< UEventsManager > destroyer_
static void addHandler(UEventsHandler *handler)
void _removePipe(const UEventsSender *sender, const UEventsHandler *receiver, const std::string &eventName)
#define UERROR(...)
std::list< UEventsHandler * > handlers_
#define UWARN(...)
static void removeHandler(UEventsHandler *handler)
virtual void mainLoopKill()
void join(bool killFirst=false)
Definition: UThread.cpp:85
std::list< std::pair< UEvent *, const UEventsSender *> > events_
static void removeAllPipes(const UEventsSender *sender)
bool isKilled() const
Definition: UThread.cpp:255
static UEventsManager * getInstance()


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Jan 23 2023 03:38:58