#ifndef OSDEV_COMPONENTS_MQTT_ISTATECALLBACK_H #define OSDEV_COMPONENTS_MQTT_ISTATECALLBACK_H // std #include // boost #include namespace osdev { namespace components { namespace mqtt { /*! * \brief Struct introduces a typed client identifier. */ struct ClientIdentifier { /*! * \brief Construct a ClientIdentifier * \param id The client id. Default is empty. */ explicit ClientIdentifier(const std::string& id = "") : m_id(id) { } const std::string m_id; ///< Client identifier }; /*! * \brief Enumeration of state codes. * The states Unknown, CommunicationFailure, GeneralFailure, Good * and Shutdown are used to communicate state about the server * that is connected to. The states ConnectionFailure and Unregister * communicate state about the client. */ enum class StateEnum { Unknown, ///< State of underlying data source is unknown. CommunicationFailure, ///< No communication with underlying data source. GeneralFailure, ///< Some failure in the underlying data source. Good, ///< Underlying data source is available. Shutdown, ///< Underlying data source is shutting down. ConnectionFailure, ///< Client connection has failed. Unregister ///< Client is being unregistered. }; /*! * \brief Stream a StateEnum value */ std::ostream& operator<<(std::ostream& os, StateEnum rhs); /*! * \brief Type for identifying state change callbacks. */ using StateChangeCallbackHandle = std::uint32_t; class IStateCallback; /*! * \brief Create an id for an IStateCallback object. * \param idStatic - Static part of the id (name of the class). * \param clientId - Client identifier. Can contain information on how * the client is used for instance. If the id is empty * it is not used. * \param idDynamic - Dynamic part (object address). * \return identifier as string */ std::string createIdentifier(const std::string& idStatic, const ClientIdentifier& clientId, const IStateCallback* idDynamic); /*! * \brief State callback interface. * When a client implements this interface it can be registered on a * server in order to handle state changes from the underlying data source. * \note When the client is destroyed it is expected that it unregisters itself by calling * clearAllStateChangeCallbacks(). */ class IStateCallback { public: using SigStateChange = boost::signals2::signal; using SlotStateChange = SigStateChange::slot_type; virtual ~IStateCallback(); /*! * \brief Get a string that identifies this interface. */ virtual std::string clientId() const = 0; /*! * \brief Register a callback function that is called when the status changes. * \param cb - The callback function to register. * \return handle to the registered callback. * \note Make sure that the callback function lives longer than the IStateCallback object. * Otherwise unregister callback function before it is destroyed. */ virtual StateChangeCallbackHandle registerStateChangeCallback(const SlotStateChange& cb) = 0; /*! * \brief Unregister a previously registered callback function. * If the callback function was not registered nothing happens. * \param handle - Identifies the callback function to to unregister. */ virtual void unregisterStateChangeCallback(StateChangeCallbackHandle handle) = 0; /*! * \brief Remove all the registered callback functions. */ virtual void clearAllStateChangeCallbacks() = 0; /*! * \brief retuns the latest state received. */ virtual StateEnum state() const = 0; }; } // End namespace mqtt } // End namespace components } // End namespace osdev #endif // OSDEV_COMPONENTS_MQTT_ISTATECALLBACK_H