From 82fe4c2348caa91cc5370475a3fc6efd165bc75e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 22 Jun 2010 14:06:33 +0000 Subject: [PATCH] * ./vlsisapd/configuration: - New: More thorough type checking of parameter's type while setting/ getting. - New: In Parameter, callback mechanism (trimmed down Observer pattern) to uses whenever Qt signal/slots are not used. This is needed to maintain data coherency througout the software. --- .../src/configuration/src/Configuration.cpp | 34 ++++- vlsisapd/src/configuration/src/Parameter.cpp | 108 ++++++++++++++ .../src/configuration/src/ParameterWidget.cpp | 66 +++++++++ .../vlsisapd/configuration/Configuration.h | 21 ++- .../src/vlsisapd/configuration/Parameter.h | 136 +++++++++--------- .../vlsisapd/configuration/ParameterWidget.h | 1 + 6 files changed, 275 insertions(+), 91 deletions(-) diff --git a/vlsisapd/src/configuration/src/Configuration.cpp b/vlsisapd/src/configuration/src/Configuration.cpp index 9028899a..1c33b236 100644 --- a/vlsisapd/src/configuration/src/Configuration.cpp +++ b/vlsisapd/src/configuration/src/Configuration.cpp @@ -132,15 +132,21 @@ namespace { else if ( attrType == "enumerate" ) type = Parameter::Enumerate; _parameter = _configuration->getParameter ( attrId ); - if ( _parameter == NULL ) { - _parameter = _configuration->addParameter ( attrId + _parameter = _configuration->addParameter ( attrId , type , _getAttributeValue("value") ); - } else { - _parameter->setString ( _getAttributeValue("value") ); + _parameter->setString ( _getAttributeValue("value"), false ); + } + + if ( type == Parameter::Percentage ) { + istringstream s ( _getAttributeValue("value") ); + double ratio; + s >> ratio; + + _parameter->setPercentage ( ratio ); } if ( (type == Parameter::Enumerate) @@ -345,12 +351,26 @@ namespace Cfg { { return _layout.buildWidget(); } - Parameter* Configuration::getParameter ( const string& name ) const + Parameter* Configuration::getParameter ( const string& name, Parameter::Type type ) const { map::const_iterator iparameter = _parameters.find(name); - if ( iparameter != _parameters.end() ) return iparameter->second; + if ( iparameter == _parameters.end() ) return NULL; - return NULL; + if ( type != Parameter::Unknown ) { + Parameter::Type t1 = (*iparameter).second->getType(); + Parameter::Type t2 = type; + + if ( t1 > t2 ) swap ( t1, t2 ); + + if ( (t1 != t2) + and not ( (t1 == Parameter::Double) and (t2 == Parameter::Percentage) ) + and not ( (t1 == Parameter::Int ) and (t2 == Parameter::Enumerate ) ) ) + cerr << "[ERROR] Accessing " << Parameter::typeToString((*iparameter).second->getType()) + << " parameter <" << (*iparameter).second->getId() + << "> as " << Parameter::typeToString(type)<< " (type mismatch)." << endl; + } + + return (*iparameter).second; } diff --git a/vlsisapd/src/configuration/src/Parameter.cpp b/vlsisapd/src/configuration/src/Parameter.cpp index 80c65f1e..eed82c7a 100644 --- a/vlsisapd/src/configuration/src/Parameter.cpp +++ b/vlsisapd/src/configuration/src/Parameter.cpp @@ -37,6 +37,7 @@ namespace Cfg { string Parameter::typeToString ( Parameter::Type type ) { switch ( type ) { + case Unknown: return "unknown"; case String: return "string"; case Int: return "int"; case Double: return "double"; @@ -63,7 +64,114 @@ namespace Cfg { if ( type == Percentage ) { setPercentage ( asDouble() ); } + + //cerr << "New " << typeToString(_type) << " parameter " << _id << " value:" << _value << endl; } + bool Parameter::asBool () const + { + if ( _type != Bool ) + cerr << "[ERROR] Accessing " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Bool)<< " (type mismatch)." << endl; + + std::istringstream s ( _value ); bool b; s >> std::boolalpha >> b; return b; + } + + + int Parameter::asInt () const + { + if ( (_type != Int) and (_type != Enumerate) ) + cerr << "[ERROR] Accessing " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Int)<< " (type mismatch)." << endl; + + std::istringstream s ( _value ); int i; s >> i; return i; + } + + + double Parameter::asDouble () const + { + if ( (_type != Double) and (_type != Percentage) ) + cerr << "[ERROR] Accessing " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Double)<< " (type mismatch)." << endl; + + std::istringstream s ( _value ); double d; s >> d; return d; + } + + + double Parameter::asPercentage () const + { + if ( (_type != Double) and (_type != Percentage) ) + cerr << "[ERROR] Accessing " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Percentage)<< " (type mismatch)." << endl; + + std::istringstream s ( _value ); double r; s >> r; return r*100.0; + } + + + void Parameter::setString ( const std::string& s, bool check ) + { + if ( check and (_type != String) ) + cerr << "[ERROR] Parameter::setString(): Setting " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(String)<< " (type mismatch)." << endl; + + _value = s; + _onValueChanged(); + } + + + void Parameter::setBool ( bool b ) + { + if ( _type != Bool ) + cerr << "[ERROR] Parameter::setBool(): Setting " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Bool)<< " (type mismatch)." << endl; + + std::ostringstream s; s << std::boolalpha << b; _value = s.str(); + + _onValueChanged(); + } + + + void Parameter::setInt ( int i ) + { + if ( (_type != Int) and (_type != Enumerate) ) + cerr << "[ERROR] Parameter::setInt(): Setting " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Int)<< " (type mismatch)." << endl; + + std::ostringstream s; s << i; _value = s.str(); + _onValueChanged(); + } + + + void Parameter::setDouble ( double d ) + { + if ( (_type != Double) and (_type != Percentage) ) + cerr << "[ERROR] Parameter::setDouble(): Setting " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Double)<< " (type mismatch)." << endl; + + std::ostringstream s; s << d; _value = s.str(); + _onValueChanged(); + } + + + void Parameter::setPercentage ( double d ) + { + if ( (_type != Double) and (_type != Percentage) ) + cerr << "[ERROR] Parameter::setPercentage(): Setting " << Parameter::typeToString(_type) + << " parameter <" << _id + << "> as " << Parameter::typeToString(Double)<< " (type mismatch)." << endl; + + std::ostringstream s; s << (d/100.0); _value = s.str(); + _onValueChanged(); + } + + } // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/ParameterWidget.cpp b/vlsisapd/src/configuration/src/ParameterWidget.cpp index c7e39a0f..3c6a56f8 100644 --- a/vlsisapd/src/configuration/src/ParameterWidget.cpp +++ b/vlsisapd/src/configuration/src/ParameterWidget.cpp @@ -23,6 +23,7 @@ // x-----------------------------------------------------------------x +#include "boost/bind.hpp" #include #include #include @@ -161,6 +162,10 @@ namespace Cfg { string valueId = _parameter->getId() + ".edit"; _valueWidget->setObjectName ( valueId.c_str() ); + + //Parameter::ParameterChangedCb_t cb = boost::bind(&ParameterWidget::updateValueCb,this); + + _parameter->registerCb ( boost::bind(&ParameterWidget::updateValueCb,this,_1) ); } @@ -224,6 +229,67 @@ namespace Cfg { } + void ParameterWidget::updateValueCb ( Parameter* p ) + { + if ( _parameter->getType() == Parameter::String ) + { + QLineEdit* lineEdit = qobject_cast(_valueWidget); + if ( _parameter->asString() != lineEdit->displayText().toStdString() ) return; + + lineEdit->setText ( _parameter->asString().c_str() ); + } + else if ( _parameter->getType() == Parameter::Bool ) + { + QCheckBox* checkBox = qobject_cast(_valueWidget); + if ( _parameter->asBool() == checkBox->isChecked() ) return; + + checkBox->setCheckState ( Qt::Checked ); + } + else if ( _parameter->getType() == Parameter::Int ) + { + if ( hasFlags(UseSpinBox) ) { + QSpinBox* spinBox = qobject_cast(_valueWidget); + if ( spinBox->value() == _parameter->asInt() ) return; + + spinBox->setValue ( _parameter->asInt() ); + } else { + QLineEdit* lineEdit = qobject_cast(_valueWidget); + if ( _parameter->asString() == lineEdit->displayText().toStdString() ) return; + + lineEdit->setText ( _parameter->asString().c_str() ); + } + } + else if ( _parameter->getType() == Parameter::Double ) + { + bool success; + QLineEdit* lineEdit = qobject_cast(_valueWidget); + if ( _parameter->asDouble() == lineEdit->displayText().toFloat(&success) ) return; + + lineEdit->setText ( _parameter->asString().c_str() ); + } + else if ( _parameter->getType() == Parameter::Percentage ) + { + bool success; + QLineEdit* lineEdit = qobject_cast(_valueWidget); + double value = lineEdit->displayText().toFloat ( &success ); + + if ( value == _parameter->asPercentage() ) return; + lineEdit->setText ( QString("%1").arg(_parameter->asPercentage()) ); + } + else if ( _parameter->getType() == Parameter::Enumerate ) + { + QComboBox* comboBox = qobject_cast(_valueWidget); + const vector& values = _parameter->getValues(); + + if ( values[comboBox->currentIndex()]._value == _parameter->asInt() ) return; + for ( size_t ivalue=0 ; ivalueasInt() ) + comboBox->setCurrentIndex ( ivalue ); + } + } + } + + void ParameterWidget::enableSlaves ( int state ) { ConfigurationWidget* cw = rparent ( this ); diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h index 4ab9cafd..1a73b4d3 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h @@ -48,7 +48,8 @@ namespace Cfg { getParameters () const; inline const LayoutDescription& getLayout () const; inline LayoutDescription& getLayout (); - Parameter* getParameter ( const std::string& id ) const; + Parameter* getParameter ( const std::string& id + , Parameter::Type type=Parameter::Unknown ) const; Parameter* addParameter ( const std::string& id , Parameter::Type type , const std::string& value ); @@ -75,71 +76,65 @@ namespace Cfg { inline Parameter* getParamString ( const std::string& id, const std::string& value="" ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::String); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::String, value ); } - return parameter; } inline Parameter* getParamBool ( const std::string& id, bool value=false ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::Bool); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::Bool, "false" ); parameter->setBool ( value ); } - return parameter; } inline Parameter* getParamInt ( const std::string& id, int value=0 ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::Int); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::Int, "0" ); parameter->setInt ( value ); } - return parameter; } inline Parameter* getParamEnumerate ( const std::string& id, int value=0 ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::Enumerate); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::Enumerate, "0" ); parameter->setInt ( value ); } - return parameter; } inline Parameter* getParamDouble ( const std::string& id, double value=0.0 ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::Double); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::Double, "0.0" ); parameter->setDouble ( value ); } - return parameter; } inline Parameter* getParamPercentage ( const std::string& id, double value=91.0 ) { - Parameter* parameter = Configuration::get()->getParameter(id); + Parameter* parameter = Configuration::get()->getParameter(id,Parameter::Percentage); if ( parameter == NULL ) { parameter = Configuration::get()->addParameter ( id, Parameter::Percentage, "0.91" ); parameter->setPercentage ( value ); } - return parameter; } diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h index 2d41feba..2d3a0363 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace Cfg { @@ -37,16 +38,18 @@ namespace Cfg { class Parameter { public: - enum Type { String = 1 - , Int = 2 - , Double = 3 - , Bool = 4 - , Percentage = 5 - , Enumerate = 6 + enum Type { Unknown = 0 + , String = 1 + , Bool = 2 + , Int = 3 + , Enumerate = 4 + , Double = 5 + , Percentage = 6 }; enum Flags { HasMin = 0x1 , HasMax = 0x2 }; + typedef boost::function< void(Parameter*) > ParameterChangedCb_t; public: class EnumValue { public: @@ -56,55 +59,59 @@ namespace Cfg { int _value; }; public: - static std::string typeToString ( Type ); - public: - Parameter ( const std::string& id - , Type type - , const std::string& value ); - inline const std::string& getId () const; - inline const Type getType () const; - inline const std::vector& - getValues () const; - inline const std::vector& - getSlaves () const; - inline int getFlags () const; - inline bool hasFlags ( int mask ) const; - inline int getMinInt () const; - inline int getMaxInt () const; - inline double getMinDouble () const; - inline double getMaxDouble () const; - inline bool checkValue ( int ) const; - inline bool checkValue ( double ) const; - inline const std::string& asString () const; - inline bool asBool () const; - inline int asInt () const; - inline double asDouble () const; - inline double asPercentage () const; - inline void addValue ( const std::string&, int ); - inline void addSlave ( const std::string& ); - inline void setString ( const std::string& ); - inline void setFlags ( int mask ); - inline void unsetFlags ( int mask ); - inline void setInt ( int ); - inline void setDouble ( double ); - inline void setBool ( bool ); - inline void setPercentage ( double ); - inline void setMin ( int ); - inline void setMax ( int ); - inline void setMin ( double ); - inline void setMax ( double ); + static std::string typeToString ( Type ); + public: + Parameter ( const std::string& id + , Type type + , const std::string& value ); + inline const std::string& getId () const; + inline const Type getType () const; + inline const std::vector& + getValues () const; + inline const std::vector& + getSlaves () const; + inline int getFlags () const; + inline bool hasFlags ( int mask ) const; + inline int getMinInt () const; + inline int getMaxInt () const; + inline double getMinDouble () const; + inline double getMaxDouble () const; + inline bool checkValue ( int ) const; + inline bool checkValue ( double ) const; + inline const std::string& asString () const; + bool asBool () const; + int asInt () const; + double asDouble () const; + double asPercentage () const; + inline void addValue ( const std::string&, int ); + inline void addSlave ( const std::string& ); + void setString ( const std::string&, bool check=true ); + inline void setFlags ( int mask ); + inline void unsetFlags ( int mask ); + void setBool ( bool ); + void setInt ( int ); + void setDouble ( double ); + void setPercentage ( double ); + inline void setMin ( int ); + inline void setMax ( int ); + inline void setMin ( double ); + inline void setMax ( double ); + inline void registerCb ( ParameterChangedCb_t ); + private: + inline void _onValueChanged (); private: // Attributes. - std::string _id; - Type _type; - std::string _value; - std::vector _values; - int _flags; - int _minInt; - int _maxInt; - double _minDouble; - double _maxDouble; - std::vector _slaves; + std::string _id; + Type _type; + std::string _value; + std::vector _values; + int _flags; + int _minInt; + int _maxInt; + double _minDouble; + double _maxDouble; + std::vector _slaves; + std::vector _callbacks; }; @@ -118,7 +125,6 @@ namespace Cfg { inline double Parameter::getMinDouble () const { return _minDouble; } inline double Parameter::getMaxDouble () const { return _maxDouble; } inline const std::string& Parameter::asString () const { return _value; } - inline void Parameter::setString ( const std::string& s ) { _value = s; } inline bool Parameter::checkValue ( int value ) const { bool ok = not ( ( (_flags&HasMin) and (value < _minInt) ) @@ -148,23 +154,6 @@ namespace Cfg { _values.push_back ( EnumValue(label,value) ); } - - inline bool Parameter::asBool () const - { std::istringstream s ( _value ); bool b; s >> std::boolalpha >> b; return b; } - - inline int Parameter::asInt () const - { std::istringstream s ( _value ); int i; s >> i; return i; } - - inline double Parameter::asDouble () const - { std::istringstream s ( _value ); double d; s >> d; return d; } - - inline double Parameter::asPercentage () const - { std::istringstream s ( _value ); double r; s >> r; return r*100.0; } - - inline void Parameter::setInt ( int i ) { std::ostringstream s; s << i; _value = s.str(); } - inline void Parameter::setDouble ( double d ) { std::ostringstream s; s << d; _value = s.str(); } - inline void Parameter::setBool ( bool b ) { std::ostringstream s; s << std::boolalpha << b; _value = s.str(); } - inline void Parameter::setPercentage ( double d ) { std::ostringstream s; s << (d/100.0); _value = s.str(); } inline void Parameter::setFlags ( int mask ) { _flags |= mask; } inline void Parameter::unsetFlags ( int mask ) { _flags &= ~mask; } inline void Parameter::setMin ( int min ) { _minInt = min; setFlags(HasMin); } @@ -179,6 +168,11 @@ namespace Cfg { inline Parameter::EnumValue::EnumValue ( const std::string& label, int value ) : _label(label), _value(value) { } + inline void Parameter::registerCb ( ParameterChangedCb_t cb ) { _callbacks.push_back(cb); } + + inline void Parameter::_onValueChanged () + { for ( size_t icb=0 ; icb<_callbacks.size() ; ++icb ) _callbacks[icb]( this ); } + } // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h index 0a1ae878..3f2514bf 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h @@ -54,6 +54,7 @@ namespace Cfg { inline bool hasFlags ( int mask ) const; inline void setFlags ( int mask ); inline void unsetFlags ( int mask ); + void updateValueCb ( Parameter* ); public slots: void updateValue (); void enableSlaves ( int );