mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-04 00:37:46 +08:00
189 lines
6.5 KiB
C++
189 lines
6.5 KiB
C++
/*
|
|
* utilite is a cross-platform library with
|
|
* useful utilities for fast and small developing.
|
|
* Copyright (C) 2010 Mathieu Labbe
|
|
*
|
|
* utilite is free library: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* utilite 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef UEVENTSHANDLER_H
|
|
#define UEVENTSHANDLER_H
|
|
|
|
#include "rtabmap/utilite/UtiLiteExp.h" // DLL export/import defines
|
|
|
|
#include "rtabmap/utilite/UEventsSender.h"
|
|
class UEvent;
|
|
|
|
/**
|
|
* The class UEventsHandler is an abstract class for
|
|
* handling events.
|
|
*
|
|
* Inherited classes must implement handleEvent() function, which
|
|
* is called by the UEventsManager when an event is dispatched. Once the handler is
|
|
* created, it must be added to events manager with UEventsManager::addHandler() function.
|
|
* Note that it is not safe to automatically add the handler to UEventsManager in the handler's constructor.
|
|
*
|
|
* Note for multi-threading: the handleEvent() method is called
|
|
* inside the UEventsManager thread. If the inherited class also inherits
|
|
* from UThreadNode, handleEvent() is done as well outside the thread's main loop, so
|
|
* be careful to protect private data of the thread used in its main loop.
|
|
*
|
|
* Example for a useful combination of an UEventsHandler and a UThreadNode, with safe data
|
|
* modification while not blocking the handleEvent() call on a mutex:
|
|
* @code
|
|
* #include "utilite/UThreadNode.h"
|
|
* #include "utilite/UEventsHandler.h"
|
|
* #include "utilite/UEventsManager.h"
|
|
* #include "utilite/UEvent.h"
|
|
*
|
|
* // Implement a simple event
|
|
* class ResetEvent : public UEvent {
|
|
* public:
|
|
* ResetEvent() {}
|
|
* virtual ~ResetEvent() {}
|
|
* virtual std::string getClassName() const {return "ResetEvent";} // Must be implemented
|
|
* };
|
|
*
|
|
* // There is the thread counting indefinitely, the count can be reseted by sending a ResetEvent.
|
|
* class CounterThread : public UThreadNode, public UEventsHandler {
|
|
* public:
|
|
* CounterThread() : state_(0), count_(0) {}
|
|
* virtual ~CounterThread() {this->join(true);}
|
|
*
|
|
* protected:
|
|
* virtual void mainLoop() {
|
|
* if(state_ == 1) {
|
|
* state_ = 0;
|
|
* // Do a long initialization, reset memory or other special long works... here
|
|
* // we reset the count. This could be done in the handleEvent() but
|
|
* // with many objects, it is more safe to do it here (in the thread's loop). A safe
|
|
* // way could be also to use a UMutex to protect this initialization in
|
|
* // the handleEvent(), but it is not recommended to do long works in handleEvent()
|
|
* // because this will add latency in the UEventsManager dispatching events loop.
|
|
* count_ = 0; // Reset the count
|
|
* printf("Reset!\n");
|
|
* }
|
|
*
|
|
* // Do some works...
|
|
* printf("count=%d\n", count_++);
|
|
* uSleep(100); // wait 100 ms
|
|
* }
|
|
* virtual void handleEvent(UEvent * event) {
|
|
* if(event->getClassName().compare("ResetEvent") == 0) {
|
|
* state_ = 1;
|
|
* }
|
|
* }
|
|
* private:
|
|
* int state_;
|
|
* int count_;
|
|
* };
|
|
*
|
|
* int main(int argc, char * argv[])
|
|
* {
|
|
* CounterThread counter;
|
|
* counter.start();
|
|
* UEventsManager::addHandler(&counter);
|
|
*
|
|
* uSleep(500); // wait 500 ms before sending a reset event
|
|
* UEventsManager::post(new ResetEvent());
|
|
* uSleep(500); // wait 500 ms before termination
|
|
*
|
|
* UEventsManager::removeHandler(&counter);
|
|
* counter.join(true); // Kill and wait to finish
|
|
* return 0;
|
|
* }
|
|
* @endcode
|
|
*
|
|
* The output is:
|
|
* @code
|
|
* count=0
|
|
* count=1
|
|
* count=2
|
|
* count=3
|
|
* count=4
|
|
* Reset!
|
|
* count=0
|
|
* count=1
|
|
* count=2
|
|
* count=3
|
|
* count=4
|
|
* @endcode
|
|
*
|
|
* @see UEventsManager
|
|
* @see UEvent
|
|
* @see UThreadNode
|
|
*
|
|
*/
|
|
class UTILITE_EXP UEventsHandler : public UEventsSender {
|
|
public:
|
|
|
|
void registerToEventsManager();
|
|
void unregisterFromEventsManager();
|
|
|
|
|
|
protected:
|
|
/**
|
|
* Only the UEventsManager has access
|
|
* to the handleEvent() method.
|
|
*/
|
|
friend class UEventsManager;
|
|
|
|
/**
|
|
* Method called by the UEventsManager
|
|
* to handle an event. Important : this method
|
|
* must do a minimum of work because the faster
|
|
* the dispatching loop is done; the faster the
|
|
* events are received. If a handling function
|
|
* takes too much time, the events list can grow
|
|
* faster than it is emptied. The event can be
|
|
* modified.
|
|
* @return "true" to notify UEventsManager that this handler took ownership of the
|
|
* event (meaning it must delete it). The event will
|
|
* not be dispatched to next handlers.
|
|
* @return "false" to let event be dispatched to next handlers (default behavior). UEventsManager
|
|
* will take care of deleting the event.
|
|
*
|
|
*/
|
|
virtual bool handleEvent(UEvent * event) = 0;
|
|
|
|
protected:
|
|
/**
|
|
* UEventsHandler constructor.
|
|
*
|
|
* Note : You can call EventsManager::addHandler(this) at
|
|
* the end of the constructor of the inherited class where the virtual
|
|
* method handleEvent(...) is defined. If so, the UEventsHandler doesn't
|
|
* need to be manually added to the EventsManager where the handler
|
|
* is instantiated. We decided to not include UEventsManager::addHandler(this)
|
|
* in this abstract class constructor because an event can be handled (calling
|
|
* the pure virtual method) while the concrete class is constructed.
|
|
*/
|
|
UEventsHandler() {}
|
|
|
|
/**
|
|
* UEventsHandler destructor.
|
|
*
|
|
* By default, it removes the handler reference from the UEventsManager. To be thread-safe,
|
|
* the inherited class must remove itself from the UEventsManager before it is deleted because
|
|
* an event can be handled (calling the pure virtual method handleEvent()) after the concrete class
|
|
* is deleted.
|
|
*/
|
|
virtual ~UEventsHandler();
|
|
|
|
private:
|
|
|
|
};
|
|
|
|
#endif // UEVENTSHANDLER_H
|