Changeset 176 in pacpusframework


Ignore:
Timestamp:
Oct 11, 2013, 2:10:06 PM (11 years ago)
Author:
Marek Kurdej
Message:

Added: addParameters() method in ComponentBase using Boost.Program_Options.
Each component can declare its parameters and they will be read automatically before configureComponent() method.
See example ProducerConsumerExample constructors.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/examples/ProducerConsumerExample/ConsumerExample.cpp

    r165 r176  
    2020    LOG_INFO("Thread " << thread.currentThread());
    2121    LOG_INFO("Current Thread " << QThread::currentThread());
     22
     23    namespace po = boost::program_options;
     24   
     25    addParameters()
     26        ("output-path", po::value<std::string>(&mOutputFileName)->default_value("consumer.txt"), "set output file path")
     27    ;
    2228}
    2329
     
    4046ConsumerExample::configureComponent(XmlComponentConfig /*config*/)
    4147{
    42     LOG_TRACE(Q_FUNC_INFO);
     48    PACPUS_LOG_FUNCTION();
    4349
    44     // load XML parameters
     50    // load XML parameters -- NOT NEEDED - loaded by boost::program_options (used addParameters())
    4551
    46     LOG_INFO("component '" << name() << "' configured");
     52    LOG_INFO("component '" << getName() << "' configured");
    4753    return ComponentBase::CONFIGURED_OK;
    4854}
     
    5460    m_counter = 0;
    5561   
    56     static const char * outputFileName = "consumer.txt";
    57     m_file.open(outputFileName, std::ios_base::out | std::ios_base::app);
     62    m_file.open(mOutputFileName.c_str(), std::ios_base::out | std::ios_base::app);
    5863    if (!m_file.is_open()) {
    59         LOG_ERROR("file '" << outputFileName << "'cannot be opened");
     64        LOG_ERROR("file '" << mOutputFileName << "' cannot be opened");
    6065    }
    6166
    6267    thread.start();
    6368    setState(MONITOR_OK);
    64     LOG_INFO("started component '" << name() << "'");
     69    LOG_INFO("started component '" << getName() << "'");
    6570}
    6671
     
    7277    m_file.close();
    7378    setState(STOPPED);
    74     LOG_INFO("stopped component '" << name() << "'");
     79    LOG_INFO("stopped component '" << getName() << "'");
    7580}
    7681
  • trunk/examples/ProducerConsumerExample/ConsumerExample.h

    r163 r176  
    88#include <QImage>
    99#include <QThread>
     10#include <string>
    1011
    1112namespace pacpus {
     
    3536    int m_counter;
    3637    std::ofstream m_file;
     38
     39    std::string mOutputFileName;
    3740};
    3841
  • trunk/examples/ProducerConsumerExample/ProducerExample.cpp

    r165 r176  
    2222{
    2323    LOG_TRACE("constructor(" << name << ")");
     24
     25    namespace po = boost::program_options;
     26   
     27    addParameters()
     28        ("output-path", po::value<std::string>(&mOutputFileName)->default_value("producer.txt"), "set output file path")
     29    ;
    2430}
    2531
     
    3238ProducerExample::configureComponent(XmlComponentConfig /*config*/)
    3339{
    34     LOG_TRACE(Q_FUNC_INFO);
     40    PACPUS_LOG_FUNCTION();
    3541
    36     LOG_INFO("component '" << name() << "' configured");
     42    LOG_INFO("component '" << getName() << "' configured");
    3743    return ComponentBase::CONFIGURED_OK;
    3844}
     
    5763    setActive(true);
    5864    setState(MONITOR_OK);
    59     LOG_INFO("started component '" << name() << "'");
     65    LOG_INFO("started component '" << getName() << "'");
    6066}
    6167
     
    6672    setActive(false);
    6773    setState(STOPPED);
    68     LOG_INFO("stopped component '" << name() << "'");
     74    LOG_INFO("stopped component '" << getName() << "'");
    6975}
    7076
  • trunk/examples/ProducerConsumerExample/ProducerExample.h

    r163 r176  
    4747
    4848private:
     49    std::string mOutputFileName;
    4950    //QThread thread;
    5051};
  • trunk/include/Pacpus/kernel/ComponentBase.h

    r161 r176  
    3131#include <QMap>
    3232
     33#include <boost/program_options/options_description.hpp>
     34#include <boost/program_options/value_semantic.hpp>
     35#include <string>
     36
    3337class QWidget;
     38
     39namespace boost {
     40namespace program_options {
     41    class options_description_easy_init;
     42}
     43}
    3444
    3545namespace pacpus {
     
    94104     * @return Name of the component.
    95105     */
    96     QString name() const;
    97106    QString getName() const;
    98107
     
    127136    virtual void addOutputs() {}
    128137
     138    boost::program_options::options_description_easy_init addParameters();
     139
    129140protected:
    130141    typedef QMap<QString, InputInterfaceBase *> InputsMap;
     
    177188
    178189    const XmlComponentConfig xmlParameters() const;
     190
     191protected:
     192    std::string mName;
     193    std::string mTypeName;
     194    bool mHasGui;
     195    bool mVerbose;
     196    int mVerbosityLevel;
    179197   
    180198private:
     199    /// Called by ComponentManager to handle parameters
     200    /// @throws
     201    void parseParameters(const XmlComponentConfig & cfg);
     202
    181203    /// called by the ComponentManager to start the component
    182204    int startComponent();
     
    186208
    187209private:
     210    boost::program_options::options_description mOptionsDescription;
     211
    188212    /// The XML node that is got in the configureComponent method
    189213    XmlComponentConfig param;
  • trunk/include/Pacpus/kernel/Log.h

    r143 r176  
    3535
    3636#if defined(PACPUS_USE_LOG)
     37#   include <boost/log/attributes/named_scope.hpp>
     38#   include <boost/log/trivial.hpp>
     39#   include <iosfwd>
    3740
    38 #include <boost/log/trivial.hpp>
    39 #include <iosfwd>
    4041class QString;
    41 
    4242template< typename CharT, typename TraitsT >
    4343PACPUSLIB_API std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, QString const& s);
    4444
    45 #define DECLARE_STATIC_LOGGER(name)
    46 
    47 #define LOG(level, message)         BOOST_LOG_TRIVIAL(level) << message
    48 #define LOG_TRACE(message)          LOG(trace, message)
    49 #define LOG_DEBUG(message)          LOG(debug, message)
    50 #define LOG_INFO(message)           LOG(info, message)
    51 #define LOG_WARN(message)           LOG(warning, message)
    52 #define LOG_ERROR(message)          LOG(error, message)
    53 #define LOG_FATAL(message)          LOG(fatal, message)
    54 
     45#   define DECLARE_STATIC_LOGGER(name)        //BOOST_LOG_NAMED_SCOPE(name)
     46#   define PACPUS_LOG_FUNCTION()              BOOST_LOG_FUNCTION()
     47#   define PACPUS_LOG_NAMED_SCOPE(name)       BOOST_LOG_NAMED_SCOPE(name)
     48#   define PACPUS_LOG(level, message)         BOOST_LOG_TRIVIAL(level) << message
    5549#else
    56 
    5750/// @param name Name of the logger, displayed when logging a message.
    58 #define DECLARE_STATIC_LOGGER(name)
    59 /// Logs a message at TRACE level using default logger
    60 #define LOG_TRACE(message)
    61 /// Logs a message at DEBUG level using default logger
    62 #define LOG_DEBUG(message)
    63 /// Logs a message at INFO level using default logger
    64 #define LOG_INFO(message)
    65 /// Logs a message at WARN level using default logger
    66 #define LOG_WARN(message)
    67 /// Logs a message at ERROR level using default logger
    68 #define LOG_ERROR(message)
    69 /// Logs a message at FATAL level using default logger
    70 #define LOG_FATAL(message)
    71 
     51#   define DECLARE_STATIC_LOGGER(name)
     52#   define PACPUS_LOG_FUNCTION()              ((void) 0)
     53#   define PACPUS_LOG_NAMED_SCOPE(name)       ((void) 0)
     54#   define PACPUS_LOG(level, message)         ((void) 0)
    7255#endif // PACPUS_USE_LOG
    7356
     57/// Logs a message at TRACE level using default logger
     58#define LOG_TRACE(message)          PACPUS_LOG(trace, message)
     59/// Logs a message at DEBUG level using default logger
     60#define LOG_DEBUG(message)          PACPUS_LOG(debug, message)
     61/// Logs a message at INFO level using default logger
     62#define LOG_INFO(message)           PACPUS_LOG(info, message)
     63/// Logs a message at WARN level using default logger
     64#define LOG_WARN(message)           PACPUS_LOG(warning, message)
     65/// Logs a message at ERROR level using default logger
     66#define LOG_ERROR(message)          PACPUS_LOG(error, message)
     67/// Logs a message at FATAL level using default logger
     68#define LOG_FATAL(message)          PACPUS_LOG(fatal, message)
     69
    7470#endif // DEF_PACPUS_LOG_H
  • trunk/include/Pacpus/kernel/XmlComponentConfig.h

    r89 r176  
    2222namespace pacpus {
    2323   
     24//class QDomNamedNodeMap;
    2425class XmlConfigFile;
    2526
     
    3839    /** Dtor of XmlComponentConfig. */
    3940    ~XmlComponentConfig();
     41
     42    QDomNamedNodeMap getProperties() const;
    4043
    4144    /** Add the property @em name to the XML and set its value to @em 0 if it does not exist.
     
    9497
    9598    // Copy internally the node in the internal QDomElement.
    96     void localCopy(const QDomElement& elementToCopy);
     99    void localCopy(const QDomElement & elementToCopy);
    97100
    98101    QString const getComponentName() const;
    99102    QString const getComponentType() const;
    100 
    101103
    102104    QString const getConnectionType() const;
  • trunk/src/DBITEPlayerLib/DbtPlyEngine.cpp

    r152 r176  
    162162             << dataDir_ << "\"");
    163163    if (dataDir_.isNull()) {
    164         LOG_FATAL("The data directory '" << name() << "' is invalid or unavailable!");
     164        LOG_FATAL("The data directory '" << getName() << "' is invalid or unavailable!");
    165165    }
    166166
  • trunk/src/DBITEPlayerLib/DbtPlyFileManager.cpp

    r152 r176  
    181181void DbtPlyFileManager::displayUI()
    182182{
    183     LOG_WARN("component '" << name() << "' has no user interface. Please set ui property to 0 in your XML configuration");
     183    LOG_WARN("component '" << getName() << "' has no user interface. Please set ui property to 0 in your XML configuration");
    184184}
    185185
     
    301301    deltaTDbtTab_[(deltaTDbtTabLoop_++)%1000] = deltaT;
    302302    if (deltaT > kMaxPendingTimeFromEngineMicrosecs) {
    303         LOG_WARN(name() << ": data not replayed: elapsed time since engine notification too big:" << deltaT << "us");
     303        LOG_WARN(getName() << ": data not replayed: elapsed time since engine notification too big:" << deltaT << "us");
    304304        return;
    305305    }
  • trunk/src/PacpusLib/ComponentBase.cpp

    r152 r176  
    99#include <Pacpus/kernel/Log.h>
    1010
     11#include <boost/program_options/parsers.hpp>
     12#include <boost/program_options/variables_map.hpp>
     13#include <string>
     14#include <vector>
     15
     16namespace po = boost::program_options;
    1117using namespace pacpus;
     18using namespace std;
     19
     20std::vector<std::string> convertAttributesToArgumentVector(const QDomNamedNodeMap & attributes);
     21void logVariablesMap(boost::program_options::variables_map vm);
    1222
    1323DECLARE_STATIC_LOGGER("pacpus.core.ComponentBase");
     
    2030  , m_ui(NULL)
    2131  , m_componentState(NOT_MONITORED)
     32  , mOptionsDescription("Component parameters")
    2233{
    2334    LOG_TRACE("constructor");
    2435    // Get a pointer on the instance of ComponentManager.
    2536    m_manager = ComponentManager::getInstance();
    26     LOG_INFO("component " << name() << " was created");
     37    LOG_INFO("component " << getName() << " was created");
     38
     39    addParameters()
     40        ("name", po::value<string>(&mName)->required(), "component name")
     41        ("type", po::value<string>(&mTypeName)->required(), "component type")
     42        ("ui", po::value<bool>(&mHasGui)->default_value(false), "whether to show GUI")
     43        ("verbose", po::value<bool>(&mVerbose)->default_value(false), "set output verbose")
     44        ("verbosity-level", po::value<int>(&mVerbosityLevel)->default_value(0), "set verbosity level")
     45        ("recording", po::value<bool>(&m_isRecording)->default_value(false), "whether to record data")
     46    ;
    2747}
    2848
     
    113133}
    114134
    115 QString ComponentBase::name() const
    116 {
    117     return m_componentName;
    118 }
    119 
    120135QString ComponentBase::getName() const
    121136{
     
    148163        return inputs()[inputName];
    149164    }
    150     LOG_WARN("Component " << name() << " does not contain input " << inputName);
     165    LOG_WARN("Component " << getName() << " does not contain input " << inputName);
    151166    return NULL;
    152167}
     
    161176        return outputs()[outputName];
    162177    }
    163     LOG_WARN("Component " << name() << " does not containt output " << outputName);
     178    LOG_WARN("Component " << getName() << " does not containt output " << outputName);
    164179    return NULL;
    165180}
     181
     182po::options_description_easy_init ComponentBase::addParameters()
     183{
     184    return mOptionsDescription.add_options();
     185}
     186
     187void ComponentBase::parseParameters(const XmlComponentConfig & cfg)
     188{
     189    LOG_INFO("Parsing parameters...");
     190    LOG_INFO(mOptionsDescription);
     191   
     192    vector<string> xargs = convertAttributesToArgumentVector(cfg.getProperties());
     193   
     194    boost::program_options::variables_map vm;
     195    try {
     196        po::store(
     197            po::command_line_parser(xargs)
     198                .options(mOptionsDescription)
     199                //.allow_unregistered()
     200                .run()
     201        , vm);
     202        po::notify(vm);
     203    } catch (po::error & e) {
     204        LOG_ERROR(e.what());
     205        throw;
     206    }
     207
     208    logVariablesMap(vm);
     209}
     210
     211void logVariablesMap(boost::program_options::variables_map vm)
     212{
     213    for (po::variables_map::iterator i = vm.begin(); i != vm.end(); ++i) {
     214        const po::variable_value& v = i->second;
     215        if (v.empty()) {
     216            continue;
     217        }
     218        const type_info & type = v.value().type();
     219        if (type == typeid(string)) {
     220            const string & val = v.as<string>();
     221            LOG_INFO(i->first << "=" << val);
     222        } else if (type == typeid(int)) {
     223            int val = v.as<int>();
     224            LOG_INFO(i->first << "=" << val);
     225        } else if (type == typeid(bool)) {
     226            int val = v.as<bool>();
     227            LOG_INFO(i->first << "=" << val);
     228        }
     229    }
     230}
     231
     232vector<string> convertAttributesToArgumentVector(const QDomNamedNodeMap & attributes)
     233{
     234    vector<string> xargs;
     235    xargs.reserve(attributes.size());
     236
     237    for (int i = 0; i < attributes.size(); ++i) {
     238        QDomAttr parameter = attributes.item(i).toAttr();
     239        if (parameter.isNull()) {
     240            LOG_WARN("node is not a parameter");
     241            continue;
     242        }
     243       
     244        QString arg = QString("--") + parameter.name() + "=";
     245       
     246        bool shouldAddQuotes = parameter.value().contains(' ');
     247        if (shouldAddQuotes) {
     248            arg += '\"';
     249            arg += parameter.value();
     250            arg += '\"';
     251        } else {
     252            arg += parameter.value();
     253        }
     254       
     255        LOG_DEBUG("parameter: " << arg);
     256        xargs.push_back(arg.toStdString());
     257    }
     258
     259    return xargs;
     260}
  • trunk/src/PacpusLib/ComponentManager.cpp

    r162 r176  
    255255        } else {
    256256            component->param.localCopy(cfg.qDomElement());
     257            component->parseParameters(cfg);
    257258            component->setConfigurationState(component->configureComponent(cfg));
    258259        }
  • trunk/src/PacpusLib/Log.cpp

    r146 r176  
    7171   
    7272    logging::add_common_attributes();
     73    logging::core::get()->add_global_attribute(
     74        "ProcessID",
     75        attrs::current_process_id());
     76    logging::core::get()->add_global_attribute(
     77        "ThreadID",
     78        attrs::current_thread_id());
     79
    7380    logging::core::get()->set_filter
    7481    (
     
    93100            expr::stream
    94101                << std::setfill('0') << std::setw(6) << expr::attr< unsigned int >("LineID")
    95                 //<< " [" << expr::format_date_time< posix_time::ptime >("TimeStamp", date_time::iso_extended_format) << "] "
    96                 << " [" << expr::format_date_time< posix_time::ptime >("TimeStamp", "%Y-%m-%d %T.%f") << "] "
    97                 << "<" << logging::trivial::severity << ">"
    98                 << " "
    99                 << expr::smessage
     102                //<< " [" << expr::format_date_time< posix_time::ptime >("TimeStamp", date_time::iso_extended_format) << "]"
     103                << " [" << expr::format_date_time< posix_time::ptime >("TimeStamp", "%Y-%m-%d %T.%f") << "]"
     104                << " <" << logging::trivial::severity << ">"
     105                << " <" << expr::attr< attrs::current_process_id::value_type >("ProcessID")
     106                << ":" << expr::attr< attrs::current_thread_id::value_type >("ThreadID") << ">"
     107                << " " << expr::smessage
    100108        )
    101109    );
  • trunk/src/PacpusLib/XmlComponentConfig.cpp

    r165 r176  
    88#include <Pacpus/kernel/Log.h>
    99#include <Pacpus/kernel/XmlConfigFile.h>
     10#include <QDomNamedNodeMap>
    1011
    1112using namespace pacpus;
     
    3738}
    3839
     40QDomNamedNodeMap XmlComponentConfig::getProperties() const
     41{
     42    return component_.attributes();
     43}
     44
    3945void XmlComponentConfig::addProperty(const QString& name)
    4046{
    41     if (hasProperty(name))
    42     {
     47    if (hasProperty(name)) {
    4348        LOG_ERROR("cannot add component property:"
    4449                  << " component '" << component_.attribute(kPropertyComponentName) << "'"
Note: See TracChangeset for help on using the changeset viewer.