* ./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.
This commit is contained in:
Jean-Paul Chaput 2010-06-22 14:06:33 +00:00
parent 3968b339e6
commit 82fe4c2348
6 changed files with 275 additions and 91 deletions

View File

@ -132,15 +132,21 @@ namespace {
else if ( attrType == "enumerate" ) type = Parameter::Enumerate; else if ( attrType == "enumerate" ) type = Parameter::Enumerate;
_parameter = _configuration->getParameter ( attrId ); _parameter = _configuration->getParameter ( attrId );
if ( _parameter == NULL ) { if ( _parameter == NULL ) {
_parameter = _configuration->addParameter ( attrId _parameter = _configuration->addParameter ( attrId
, type , type
, _getAttributeValue("value") , _getAttributeValue("value")
); );
} else { } 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) if ( (type == Parameter::Enumerate)
@ -345,12 +351,26 @@ namespace Cfg {
{ return _layout.buildWidget(); } { return _layout.buildWidget(); }
Parameter* Configuration::getParameter ( const string& name ) const Parameter* Configuration::getParameter ( const string& name, Parameter::Type type ) const
{ {
map<const string,Parameter*>::const_iterator iparameter = _parameters.find(name); map<const string,Parameter*>::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;
} }

View File

@ -37,6 +37,7 @@ namespace Cfg {
string Parameter::typeToString ( Parameter::Type type ) string Parameter::typeToString ( Parameter::Type type )
{ {
switch ( type ) { switch ( type ) {
case Unknown: return "unknown";
case String: return "string"; case String: return "string";
case Int: return "int"; case Int: return "int";
case Double: return "double"; case Double: return "double";
@ -63,7 +64,114 @@ namespace Cfg {
if ( type == Percentage ) { if ( type == Percentage ) {
setPercentage ( asDouble() ); 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. } // End of Cfg namespace.

View File

@ -23,6 +23,7 @@
// x-----------------------------------------------------------------x // x-----------------------------------------------------------------x
#include "boost/bind.hpp"
#include <QLabel> #include <QLabel>
#include <QSpinBox> #include <QSpinBox>
#include <QCheckBox> #include <QCheckBox>
@ -161,6 +162,10 @@ namespace Cfg {
string valueId = _parameter->getId() + ".edit"; string valueId = _parameter->getId() + ".edit";
_valueWidget->setObjectName ( valueId.c_str() ); _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<QLineEdit*>(_valueWidget);
if ( _parameter->asString() != lineEdit->displayText().toStdString() ) return;
lineEdit->setText ( _parameter->asString().c_str() );
}
else if ( _parameter->getType() == Parameter::Bool )
{
QCheckBox* checkBox = qobject_cast<QCheckBox*>(_valueWidget);
if ( _parameter->asBool() == checkBox->isChecked() ) return;
checkBox->setCheckState ( Qt::Checked );
}
else if ( _parameter->getType() == Parameter::Int )
{
if ( hasFlags(UseSpinBox) ) {
QSpinBox* spinBox = qobject_cast<QSpinBox*>(_valueWidget);
if ( spinBox->value() == _parameter->asInt() ) return;
spinBox->setValue ( _parameter->asInt() );
} else {
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(_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<QLineEdit*>(_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<QLineEdit*>(_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<QComboBox*>(_valueWidget);
const vector<Parameter::EnumValue>& values = _parameter->getValues();
if ( values[comboBox->currentIndex()]._value == _parameter->asInt() ) return;
for ( size_t ivalue=0 ; ivalue<values.size() ; ++ivalue ) {
if ( values[ivalue]._value == _parameter->asInt() )
comboBox->setCurrentIndex ( ivalue );
}
}
}
void ParameterWidget::enableSlaves ( int state ) void ParameterWidget::enableSlaves ( int state )
{ {
ConfigurationWidget* cw = rparent<ConfigurationWidget*> ( this ); ConfigurationWidget* cw = rparent<ConfigurationWidget*> ( this );

View File

@ -48,7 +48,8 @@ namespace Cfg {
getParameters () const; getParameters () const;
inline const LayoutDescription& getLayout () const; inline const LayoutDescription& getLayout () const;
inline LayoutDescription& getLayout (); 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* addParameter ( const std::string& id
, Parameter::Type type , Parameter::Type type
, const std::string& value ); , const std::string& value );
@ -75,71 +76,65 @@ namespace Cfg {
inline Parameter* getParamString ( const std::string& id, const std::string& value="<undefined>" ) inline Parameter* getParamString ( const std::string& id, const std::string& value="<undefined>" )
{ {
Parameter* parameter = Configuration::get()->getParameter(id); Parameter* parameter = Configuration::get()->getParameter(id,Parameter::String);
if ( parameter == NULL ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::String, value ); parameter = Configuration::get()->addParameter ( id, Parameter::String, value );
} }
return parameter; return parameter;
} }
inline Parameter* getParamBool ( const std::string& id, bool value=false ) 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 ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::Bool, "false" ); parameter = Configuration::get()->addParameter ( id, Parameter::Bool, "false" );
parameter->setBool ( value ); parameter->setBool ( value );
} }
return parameter; return parameter;
} }
inline Parameter* getParamInt ( const std::string& id, int value=0 ) 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 ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::Int, "0" ); parameter = Configuration::get()->addParameter ( id, Parameter::Int, "0" );
parameter->setInt ( value ); parameter->setInt ( value );
} }
return parameter; return parameter;
} }
inline Parameter* getParamEnumerate ( const std::string& id, int value=0 ) 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 ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::Enumerate, "0" ); parameter = Configuration::get()->addParameter ( id, Parameter::Enumerate, "0" );
parameter->setInt ( value ); parameter->setInt ( value );
} }
return parameter; return parameter;
} }
inline Parameter* getParamDouble ( const std::string& id, double value=0.0 ) 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 ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::Double, "0.0" ); parameter = Configuration::get()->addParameter ( id, Parameter::Double, "0.0" );
parameter->setDouble ( value ); parameter->setDouble ( value );
} }
return parameter; return parameter;
} }
inline Parameter* getParamPercentage ( const std::string& id, double value=91.0 ) 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 ) { if ( parameter == NULL ) {
parameter = Configuration::get()->addParameter ( id, Parameter::Percentage, "0.91" ); parameter = Configuration::get()->addParameter ( id, Parameter::Percentage, "0.91" );
parameter->setPercentage ( value ); parameter->setPercentage ( value );
} }
return parameter; return parameter;
} }

View File

@ -30,6 +30,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <boost/function.hpp>
namespace Cfg { namespace Cfg {
@ -37,16 +38,18 @@ namespace Cfg {
class Parameter { class Parameter {
public: public:
enum Type { String = 1 enum Type { Unknown = 0
, Int = 2 , String = 1
, Double = 3 , Bool = 2
, Bool = 4 , Int = 3
, Percentage = 5 , Enumerate = 4
, Enumerate = 6 , Double = 5
, Percentage = 6
}; };
enum Flags { HasMin = 0x1 enum Flags { HasMin = 0x1
, HasMax = 0x2 , HasMax = 0x2
}; };
typedef boost::function< void(Parameter*) > ParameterChangedCb_t;
public: public:
class EnumValue { class EnumValue {
public: public:
@ -56,55 +59,59 @@ namespace Cfg {
int _value; int _value;
}; };
public: public:
static std::string typeToString ( Type ); static std::string typeToString ( Type );
public: public:
Parameter ( const std::string& id Parameter ( const std::string& id
, Type type , Type type
, const std::string& value ); , const std::string& value );
inline const std::string& getId () const; inline const std::string& getId () const;
inline const Type getType () const; inline const Type getType () const;
inline const std::vector<EnumValue>& inline const std::vector<EnumValue>&
getValues () const; getValues () const;
inline const std::vector<std::string>& inline const std::vector<std::string>&
getSlaves () const; getSlaves () const;
inline int getFlags () const; inline int getFlags () const;
inline bool hasFlags ( int mask ) const; inline bool hasFlags ( int mask ) const;
inline int getMinInt () const; inline int getMinInt () const;
inline int getMaxInt () const; inline int getMaxInt () const;
inline double getMinDouble () const; inline double getMinDouble () const;
inline double getMaxDouble () const; inline double getMaxDouble () const;
inline bool checkValue ( int ) const; inline bool checkValue ( int ) const;
inline bool checkValue ( double ) const; inline bool checkValue ( double ) const;
inline const std::string& asString () const; inline const std::string& asString () const;
inline bool asBool () const; bool asBool () const;
inline int asInt () const; int asInt () const;
inline double asDouble () const; double asDouble () const;
inline double asPercentage () const; double asPercentage () const;
inline void addValue ( const std::string&, int ); inline void addValue ( const std::string&, int );
inline void addSlave ( const std::string& ); inline void addSlave ( const std::string& );
inline void setString ( const std::string& ); void setString ( const std::string&, bool check=true );
inline void setFlags ( int mask ); inline void setFlags ( int mask );
inline void unsetFlags ( int mask ); inline void unsetFlags ( int mask );
inline void setInt ( int ); void setBool ( bool );
inline void setDouble ( double ); void setInt ( int );
inline void setBool ( bool ); void setDouble ( double );
inline void setPercentage ( double ); void setPercentage ( double );
inline void setMin ( int ); inline void setMin ( int );
inline void setMax ( int ); inline void setMax ( int );
inline void setMin ( double ); inline void setMin ( double );
inline void setMax ( double ); inline void setMax ( double );
inline void registerCb ( ParameterChangedCb_t );
private:
inline void _onValueChanged ();
private: private:
// Attributes. // Attributes.
std::string _id; std::string _id;
Type _type; Type _type;
std::string _value; std::string _value;
std::vector<EnumValue> _values; std::vector<EnumValue> _values;
int _flags; int _flags;
int _minInt; int _minInt;
int _maxInt; int _maxInt;
double _minDouble; double _minDouble;
double _maxDouble; double _maxDouble;
std::vector<std::string> _slaves; std::vector<std::string> _slaves;
std::vector<ParameterChangedCb_t> _callbacks;
}; };
@ -118,7 +125,6 @@ namespace Cfg {
inline double Parameter::getMinDouble () const { return _minDouble; } inline double Parameter::getMinDouble () const { return _minDouble; }
inline double Parameter::getMaxDouble () const { return _maxDouble; } inline double Parameter::getMaxDouble () const { return _maxDouble; }
inline const std::string& Parameter::asString () const { return _value; } 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 { inline bool Parameter::checkValue ( int value ) const {
bool ok = not ( ( (_flags&HasMin) and (value < _minInt) ) bool ok = not ( ( (_flags&HasMin) and (value < _minInt) )
@ -148,23 +154,6 @@ namespace Cfg {
_values.push_back ( EnumValue(label,value) ); _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::setFlags ( int mask ) { _flags |= mask; }
inline void Parameter::unsetFlags ( int mask ) { _flags &= ~mask; } inline void Parameter::unsetFlags ( int mask ) { _flags &= ~mask; }
inline void Parameter::setMin ( int min ) { _minInt = min; setFlags(HasMin); } 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 ) inline Parameter::EnumValue::EnumValue ( const std::string& label, int value )
: _label(label), _value(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. } // End of Cfg namespace.

View File

@ -54,6 +54,7 @@ namespace Cfg {
inline bool hasFlags ( int mask ) const; inline bool hasFlags ( int mask ) const;
inline void setFlags ( int mask ); inline void setFlags ( int mask );
inline void unsetFlags ( int mask ); inline void unsetFlags ( int mask );
void updateValueCb ( Parameter* );
public slots: public slots:
void updateValue (); void updateValue ();
void enableSlaves ( int ); void enableSlaves ( int );