/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2022, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#pragma once

#include <mrpt/system/mrptEvent.h>

#include <set>

namespace mrpt::system
{
class CObservable;

/** Inherit from this class to get notified about events from any CObservable
 * object after subscribing to it.
 *
 *  The main methods in this class are:
 *   - observeBegin(): To be called to start listening at a given object.
 *   - OnEvent(): Virtual functions to be implemented in your child class to
 * receive all the notifications.
 *
 *  Note that if custom (child) mrptEvent classes are used, you can tell
 * between them in runtime with "dynamic_cast<>()".
 *
 * \note The pairs CObservable / CObserver automatically notify each other the
 * destruction of any of them, effectively ending the subscription of events.
 * \ingroup mrpt_system_grp
 *  \sa CObservable, mrptEvent
 */
class CObserver
{
	friend class CObservable;

   public:
	CObserver();
	virtual ~CObserver();

	/** Starts the subscription of this observer to the given object.  \sa
	 * observeEnd  */
	void observeBegin(CObservable& obj);

	/** Ends the subscription of this observer to the given object (note that
	   there is no need to call this method, since the destruction of the first
	   of observer/observed will put an end to the process
		\sa observeBegin  */
	void observeEnd(CObservable& obj);

   private:
	std::set<CObservable*> m_subscribed;
	void internal_on_event(const mrptEvent& e);

   protected:
	/** This virtual function will be called upon receive of any event after
	 * starting listening at any CObservable object.
	 */
	virtual void OnEvent(const mrptEvent& e) = 0;

};	// End of class def.

}  // namespace mrpt::system
