// %pacpus:license{ // This file is part of the PACPUS framework distributed under the // CECILL-C License, Version 1.0. // %pacpus:license} /// @file /// @author Gerald Dhermobez /// @author Marek Kurdej /// @author Samuel Gosselin /// @author Julien Moras /// @date February, 2006 /// @version $Id: ComponentBase.h 76 2013-01-10 17:05:10Z kurdejma $ /// @copyright Copyright (c) UTC/CNRS Heudiasyc 2006 - 2013. All rights reserved. /// @brief Generic ComponentBase class. This is an abstract class. /// /// Detailed description. /// @todo - see if some methods can be private with ComponentManager /// friendship /// - include the copy of Xml node in param here /// - see if there is a possibility to avoid the constraint /// on parameters in the constructor of derived class #ifndef DEF_PACPUS_COMPONENTBASE_H #define DEF_PACPUS_COMPONENTBASE_H #include #include // InputOutputInterface.h must be included, otherwise we could not use addInput, addOutput template methods #include #include #include #include #include #include #include #include class QWidget; namespace boost { namespace program_options { class options_description_easy_init; } } namespace pacpus { class ComponentManager; class InputInterfaceBase; class OutputInterfaceBase; template class InputInterface; template class OutputInterface; using ::boost::program_options::value; /// @brief Base class of a Pacpus component. class PACPUSLIB_API ComponentBase { friend class ComponentManager; public: /// Enumeration of the state that can take a component, the three last states suppose /// that the component is started. enum COMPONENT_STATE { STOPPED, NOT_MONITORED, MONITOR_OK, MONITOR_NOK }; /// Resulting state of a component after its configuration. enum COMPONENT_CONFIGURATION { CONFIGURED_OK, NOT_CONFIGURED, CONFIGURATION_DELAYED, CONFIGURED_FAILED }; /// Ctor of ComponentBase. /// @param name Name of your component. ComponentBase(const QString & name); /// Dtor of ComponentBase. virtual ~ComponentBase(); /// Returns the state of the component. /// @return Value of the current state. COMPONENT_STATE getState(); /// Checks whether the component if configurer or not. /// @return @b true if the component is configured, otherwise @b false. bool isConfigured() const; /// Returns the name of the component. /// @return Name of the component. QString getName() const; /// @returns @b true if the component has been started and is active (working) bool isActive() const; protected: /// Changes the state of the component. /// @param state New component state. void setState(COMPONENT_STATE state); /// Called when the component starts, you must override this function. virtual void startActivity() = 0; /// Called when the component stops, you must override this function. virtual void stopActivity() = 0; /// Called by the ComponentManager, it configure the component thanks a XML node. /// @param config Component's XML node. /// @return State of the configuration. /// @todo FIXME: 'config' should be const, but it will be a breaking change /// old stuff. virtual COMPONENT_CONFIGURATION configureComponent(XmlComponentConfig config) = 0; // virtual QString getType() = 0; /// @todo FIXME: should be pure virtual, but it will be a breaking change virtual void addInputs() {} virtual void addOutputs() {} /// Returns an object permitting to add component parameters. ::boost::program_options::options_description_easy_init addParameters(); protected: typedef QMap InputsMap; typedef QMap OutputsMap; // TODO: use std::function // TODO: use std::mem_fun template void addInput(const char * name, Function function) { typedef InputInterface InputType; InputType * connection = new InputType(name, dynamic_cast(this), function); inputs().insert(name, connection); } template void addOutput(const char * name) { typedef OutputInterface OutputType; OutputType * connection = new OutputType(name, dynamic_cast(this)); outputs().insert(name, connection); } /// @todo DOC InputInterfaceBase * getInput(QString name) const; /// @todo DOC OutputInterfaceBase * getOutput(QString name) const; template InputInterface * getTypedInput(const char * name) const { return dynamic_cast *>(getInput(name)); } template OutputInterface * getTypedOutput(const char * name) const { return dynamic_cast *>(getOutput(name)); } void setActive(bool isActive); bool isRecording() const; void setRecording(bool isRecording); InputsMap & inputs(); const InputsMap & inputs() const; OutputsMap & outputs(); const OutputsMap & outputs() const; COMPONENT_CONFIGURATION configurationState() const; void setConfigurationState(COMPONENT_CONFIGURATION state); const XmlComponentConfig xmlParameters() const; protected: std::string mName; std::string mTypeName; /// Whether to display or not the graphical interface (GUI) bool hasGui() const; bool isOutputVerbose() const; int getVerbosityLevel() const; private: /// Called by ComponentManager to handle parameters /// @throws void parseParameters(const XmlComponentConfig & cfg); /// called by the ComponentManager to start the component int startComponent(); /// called by the ComponentManager to stop the component int stopComponent(); private: bool mHasGui; bool mVerbose; int mVerbosityLevel; boost::program_options::options_description mOptionsDescription; /// The XML node that is got in the configureComponent method XmlComponentConfig param; /// the name of the component. It is this one in the XML config file QString m_componentName; /// is the component active? volatile bool m_isActive; /// is the component is recording data? bool mIsRecording; /// a pointer to the manager of components ComponentManager * m_manager; InputsMap m_inputs; OutputsMap m_outputs; /// a pointer to an optional widget QWidget * m_ui; /// store the state of the component COMPONENT_STATE m_componentState; /// is the component configured (ie configureComponent method was called) COMPONENT_CONFIGURATION m_configurationState; }; } // pacpus #endif // DEF_PACPUS_COMPONENTBASE_H