* ./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;
_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 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 )
{
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.

View File

@ -23,6 +23,7 @@
// x-----------------------------------------------------------------x
#include "boost/bind.hpp"
#include <QLabel>
#include <QSpinBox>
#include <QCheckBox>
@ -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<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 )
{
ConfigurationWidget* cw = rparent<ConfigurationWidget*> ( this );

View File

@ -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="<undefined>" )
{
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;
}

View File

@ -30,6 +30,7 @@
#include <string>
#include <sstream>
#include <iostream>
#include <boost/function.hpp>
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<EnumValue>&
getValues () const;
inline const std::vector<std::string>&
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<EnumValue>&
getValues () const;
inline const std::vector<std::string>&
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<EnumValue> _values;
int _flags;
int _minInt;
int _maxInt;
double _minDouble;
double _maxDouble;
std::vector<std::string> _slaves;
std::string _id;
Type _type;
std::string _value;
std::vector<EnumValue> _values;
int _flags;
int _minInt;
int _maxInt;
double _minDouble;
double _maxDouble;
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::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.

View File

@ -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 );