/* * 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 . */ #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