diff --git a/vlsisapd/src/configuration/src/CMakeLists.txt b/vlsisapd/src/configuration/src/CMakeLists.txt index 6bdf7438..c10a50bb 100644 --- a/vlsisapd/src/configuration/src/CMakeLists.txt +++ b/vlsisapd/src/configuration/src/CMakeLists.txt @@ -2,50 +2,68 @@ include ( ${QT_USE_FILE} ) include_directories ( ${VLSISAPD_SOURCE_DIR}/src/configuration/src + ${VLSISAPD_SOURCE_DIR}/src/openChams/src ${Boost_INCLUDE_DIRS} + ${PYTHON_INCLUDE_PATH} ${LIBXML2_INCLUDE_DIR} ) - set ( mocIncludes vlsisapd/configuration/FilePathEdit.h - vlsisapd/configuration/ConfigurationDialog.h - vlsisapd/configuration/ParameterWidget.h - vlsisapd/configuration/ConfTabWidget.h - vlsisapd/configuration/LogWidget.h - vlsisapd/configuration/ConfigurationWidget.h - vlsisapd/configuration/ConfEditorWidget.h + set ( mocIncludes vlsisapd/configuration/FilePathEdit.h + vlsisapd/configuration/ConfigurationDialog.h + vlsisapd/configuration/ParameterWidget.h + vlsisapd/configuration/ConfTabWidget.h + vlsisapd/configuration/LogWidget.h + vlsisapd/configuration/ConfigurationWidget.h + vlsisapd/configuration/ConfEditorWidget.h + ) + set ( includes vlsisapd/configuration/Parameter.h + vlsisapd/configuration/LayoutDescription.h + vlsisapd/configuration/Configuration.h + ) + set ( cpps Parameter.cpp + LayoutDescription.cpp + Configuration.cpp + FilePathEdit.cpp + ParameterWidget.cpp + ConfTabWidget.cpp + LogWidget.cpp + ConfigurationWidget.cpp + ConfigurationDialog.cpp + ConfEditorWidget.cpp + ) + set ( pycpps PyConfiguration.cpp ) + set ( editorcpp ConfEditorMain.cpp ) + + qt4_wrap_cpp ( mocCpps ${mocIncludes} ) + qt4_add_resources ( RCC_SRCS Configuration.qrc ) + + add_library ( configuration ${cpps} ${mocCpps} ${RCC_SRCS} ) + set_target_properties ( configuration PROPERTIES VERSION 1.0 SOVERSION 1 ) + target_link_libraries ( configuration ${QT_LIBRARIES} + ${PYTHON_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${Boost_LIBRARIES} ) - set ( includes vlsisapd/configuration/Parameter.h - vlsisapd/configuration/LayoutDescription.h - vlsisapd/configuration/Configuration.h - ) - set ( cpps Parameter.cpp - LayoutDescription.cpp - Configuration.cpp - FilePathEdit.cpp - ParameterWidget.cpp - ConfTabWidget.cpp - LogWidget.cpp - ConfigurationWidget.cpp - ConfigurationDialog.cpp - ConfEditorWidget.cpp - ) - set ( editorcpp ConfEditorMain.cpp ) - qt4_wrap_cpp ( mocCpps ${mocIncludes} ) - qt4_add_resources ( RCC_SRCS Configuration.qrc ) - - add_library ( configuration ${cpps} ${mocCpps} ${RCC_SRCS} ) - set_target_properties ( configuration PROPERTIES VERSION 1.0 SOVERSION 1 ) - target_link_libraries ( configuration ${QT_LIBRARIES} - ${PYTHON_LIBRARIES} - ${LIBXML2_LIBRARIES} - ${Boost_LIBRARIES} + if (Boost_FOUND) + add_library ( pyConfiguration MODULE ${pycpps}) + set_target_properties ( pyConfiguration PROPERTIES + OUTPUT_NAME "Cfg" + PREFIX "" ) + target_link_libraries ( pyConfiguration configuration + ${PYTHON_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${Boost_LIBRARIES} + ) + install ( TARGETS pyConfiguration DESTINATION ${PYTHON_SITE_PACKAGES} ) + endif(Boost_FOUND) + add_executable ( vlsisapd-conf-editor ${editorcpp} ) target_link_libraries ( vlsisapd-conf-editor configuration ${Boost_LIBRARIES} ) - install ( TARGETS configuration DESTINATION lib${LIB_SUFFIX} ) - install ( TARGETS vlsisapd-conf-editor DESTINATION bin ) - install ( FILES ${includes} ${mocIncludes} - DESTINATION include/vlsisapd/configuration ) + install ( TARGETS configuration DESTINATION lib${LIB_SUFFIX} ) + install ( TARGETS vlsisapd-conf-editor DESTINATION bin ) + install ( FILES ${includes} ${mocIncludes} + DESTINATION include/vlsisapd/configuration ) diff --git a/vlsisapd/src/configuration/src/ConfEditorMain.cpp b/vlsisapd/src/configuration/src/ConfEditorMain.cpp index e5d18249..73209091 100644 --- a/vlsisapd/src/configuration/src/ConfEditorMain.cpp +++ b/vlsisapd/src/configuration/src/ConfEditorMain.cpp @@ -2,34 +2,33 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x -// | | // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./ConfEditorMain.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | // x-----------------------------------------------------------------x +#include +#include +#include + #include namespace boptions = boost::program_options; #include namespace bfs = boost::filesystem; -#include #include #if (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) and not defined (__APPLE__) # include @@ -92,6 +91,23 @@ int main ( int argc, char* argv[] ) conf->readFromFile ( dotConfPath.string() ); } + cout << "misc.catchCore: " << conf->getParameter("misc.catchCore" )->asBool() << endl; + cout << "kite.eventsLimit: " << conf->getParameter("kite.eventsLimit")->asInt () << endl; + + bfs::path pyDotConfPath ( "./.coriolis2.init.py" ); + if ( bfs::exists(pyDotConfPath) ) { + cout << "Reading python dot configuration: <" << pyDotConfPath.string() << ">." << endl; + Py_Initialize (); + FILE* fd = fopen ( pyDotConfPath.string().c_str(), "r" ); + if ( fd ) { + PyRun_SimpleFile ( fd, pyDotConfPath.string().c_str() ); + fclose ( fd ); + } else { + cout << "Cannot open Python configuration file: <" << pyDotConfPath.string() << ">." << endl; + } + Py_Finalize (); + } + ConfEditorWidget* editor = new ConfEditorWidget (); editor->show (); //editor->getConfigurationWidget()->selectTab ( "Kite" ); diff --git a/vlsisapd/src/configuration/src/ConfEditorWidget.cpp b/vlsisapd/src/configuration/src/ConfEditorWidget.cpp index c6f67881..1baf0e7e 100644 --- a/vlsisapd/src/configuration/src/ConfEditorWidget.cpp +++ b/vlsisapd/src/configuration/src/ConfEditorWidget.cpp @@ -2,14 +2,13 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | @@ -17,10 +16,7 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./ConfEditorWidget.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include @@ -91,7 +87,8 @@ namespace Cfg { cout << "Saving configuration file: <" << dotConfigFile << ">."<< endl; //Configuration::get()->writeToStream ( file, 0, ";misc;kite;;mauka;;" ); - Configuration::get()->writeToStream ( file, 0 ); + Configuration::get()->writeToStream ( file, Configuration::DriveValues|Configuration::DriveLayout, "misc" ); + //Configuration::get()->writeToStream ( file, 0 ); //Configuration::get()->writeToStream ( file, Configuration::DriveValues|Configuration::DriveLayout ); file.close (); } diff --git a/vlsisapd/src/configuration/src/Configuration.cpp b/vlsisapd/src/configuration/src/Configuration.cpp index c8c16467..cd74d916 100644 --- a/vlsisapd/src/configuration/src/Configuration.cpp +++ b/vlsisapd/src/configuration/src/Configuration.cpp @@ -2,25 +2,21 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./Configuration.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include @@ -39,24 +35,6 @@ namespace { using namespace std; using namespace Cfg; - - - void tokenize ( set& tokens, const string& line ) - { - static std::string separators = " ;"; - size_t iBegin = 0; - size_t iEnd = 0; - - for ( ; iEnd < line.size() ; ++iEnd ) { - if ( separators.find(line[iEnd]) != std::string::npos ) { - if ( iBegin < iEnd ) - tokens.insert ( line.substr(iBegin,iEnd-iBegin) ); - iBegin = iEnd+1; - } - } - if ( iBegin < iEnd ) - tokens.insert ( line.substr(iBegin,iEnd-iBegin) ); - } class XmlParser { @@ -99,6 +77,8 @@ namespace { { LIBXML_TEST_VERSION; + Configuration::pushDefaultPriority ( Parameter::ConfigurationFile ); + _reader = xmlReaderForFile ( _fileName.c_str(), NULL, 0 ); if ( _reader != NULL ) { _status = xmlTextReaderRead ( _reader ); @@ -116,6 +96,8 @@ namespace { // xmlCleanupParser (); // CF libxml2 documentation if libxml2 parser is use by the application any other time : DO NOT CALL xmlCleanupParser (at least on mac osx) } + Configuration::popDefaultPriority (); + return (_status == 0); } @@ -162,7 +144,6 @@ namespace { _parameter = _configuration->addParameter ( attrId , type , _getAttributeValue("value") - , Parameter::ConfigurationFile ); } else { _parameter->setString ( _getAttributeValue("value") @@ -288,8 +269,9 @@ namespace { void XmlParser::_tabNode () { string attrName = _getAttributeValue("name"); + string attrId = _getAttributeValue("id"); - _configuration->getLayout().addTab ( attrName ); + _configuration->getLayout().addTab ( attrName, attrId ); _status = xmlTextReaderRead ( _reader ); while ( _status == 1 ) { @@ -376,6 +358,24 @@ namespace Cfg { using std::ofstream; using std::setw; using std::vector; + + + void Configuration::_tokenize ( set& tokens, const string& line ) + { + static std::string separators = " ;"; + size_t iBegin = 0; + size_t iEnd = 0; + + for ( ; iEnd < line.size() ; ++iEnd ) { + if ( separators.find(line[iEnd]) != std::string::npos ) { + if ( iBegin < iEnd ) + tokens.insert ( line.substr(iBegin,iEnd-iBegin) ); + iBegin = iEnd+1; + } + } + if ( iBegin < iEnd ) + tokens.insert ( line.substr(iBegin,iEnd-iBegin) ); + } Configuration* Configuration::_singleton = NULL; @@ -388,6 +388,18 @@ namespace Cfg { } + Parameter::Priority Configuration::pushDefaultPriority ( Parameter::Priority priority ) + { return Parameter::pushDefaultPriority(priority); } + + + Parameter::Priority Configuration::popDefaultPriority () + { return Parameter::popDefaultPriority(); } + + + Parameter::Priority Configuration::getDefaultPriority () + { return Parameter::getDefaultPriority(); } + + Configuration::Configuration () : _parameters() , _layout (this) @@ -426,10 +438,10 @@ namespace Cfg { } - Parameter* Configuration::addParameter ( const string& id - , Parameter::Type type - , const string& value - , int priority ) + Parameter* Configuration::addParameter ( const string& id + , Parameter::Type type + , const string& value + , Parameter::Priority priority ) { Parameter* p = getParameter ( id ); if ( p != NULL ) { @@ -520,7 +532,7 @@ namespace Cfg { void Configuration::writeToStream ( ostream& out, unsigned int flags, const string& tabs ) const { set tabset; - tokenize ( tabset, tabs ); + _tokenize ( tabset, tabs ); out << "" << endl; @@ -585,6 +597,16 @@ namespace Cfg { const vector& slaves = p->getSlaves(); if ( slaves.empty() ) continue; + if ( not tabset.empty() ) { + set::iterator itab = tabset.begin(); + for ( ; itab != tabset.end() ; ++itab ) { + if ( p->getId().compare(0,(*itab).size(),*itab) == 0 ) { + break; + } + } + if ( itab == tabset.end() ) continue; + } + out << " " << endl; out << " getId() << "\"/>" << endl; @@ -595,7 +617,7 @@ namespace Cfg { } } - if ( flags & DriveLayout ) _layout.writeToStream ( out ); + if ( flags & DriveLayout ) _layout.writeToStream ( out, tabs ); out << "" << endl; } diff --git a/vlsisapd/src/configuration/src/LayoutDescription.cpp b/vlsisapd/src/configuration/src/LayoutDescription.cpp index bf1e8ff4..63dd2d09 100644 --- a/vlsisapd/src/configuration/src/LayoutDescription.cpp +++ b/vlsisapd/src/configuration/src/LayoutDescription.cpp @@ -2,14 +2,13 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | @@ -17,10 +16,7 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./LayoutDescription.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "vlsisapd/configuration/LayoutDescription.h" @@ -35,6 +31,7 @@ namespace Cfg { using std::endl; using std::string; using std::vector; + using std::set; using std::map; using std::make_pair; using std::ostream; @@ -62,13 +59,13 @@ namespace Cfg { } - TabDescription* LayoutDescription::getTab ( const string& tabName ) + TabDescription* LayoutDescription::getTab ( const string& tabName, const string& id ) { for ( size_t itab=0 ; itab<_tabs.size() ; ++itab ) { if ( _tabs[itab]->getName() == tabName ) return _tabs[itab]; } - addTab ( new TabDescription(this,tabName) ); + addTab ( new TabDescription(this,tabName,id) ); return getBackTab(); } @@ -131,12 +128,17 @@ namespace Cfg { break; case WidgetDescription::Parameter: Parameter* parameter = _configuration->getParameter ( widgets[iwidget]->getId() ); - cw->addParameter ( _tabs[itab]->getName() - , parameter - , widgets[iwidget]->getLabel() - , widgets[iwidget]->getColumn() - , widgets[iwidget]->getSpan() - , widgets[iwidget]->getFlags() ); + if ( parameter ) { + cw->addParameter ( _tabs[itab]->getName() + , parameter + , widgets[iwidget]->getLabel() + , widgets[iwidget]->getColumn() + , widgets[iwidget]->getSpan() + , widgets[iwidget]->getFlags() ); + } else { + cerr << "[ERROR] LayoutDescription::buildWidget(): reference to non-existent parameter id=\"" + << widgets[iwidget]->getId() << "\"." << endl; + } break; } } @@ -148,12 +150,27 @@ namespace Cfg { } - void LayoutDescription::writeToStream ( ostream& out ) const + void LayoutDescription::writeToStream ( ostream& out, const string& tabs ) const { + set tabset; + Configuration::_tokenize ( tabset, tabs ); + out << " " << endl; for ( size_t itab=0 ; itab<_tabs.size() ; ++itab ) { - out << " getName() << "\">" << endl; + if ( not tabset.empty() ) { + set::iterator isavetab = tabset.begin(); + for ( ; isavetab != tabset.end() ; ++isavetab ) { + if ( _tabs[itab]->getId().compare(0,(*isavetab).size(),*isavetab) == 0 ) { + break; + } + } + if ( isavetab == tabset.end() ) continue; + } + + out << " getName() + << "\" id=\"" << _tabs[itab]->getId() + << "\">" << endl; const vector& widgets = _tabs[itab]->getWidgets(); for ( size_t iwidget=0 ; iwidget @@ -39,6 +35,31 @@ namespace Cfg { using std::ostringstream; using std::boolalpha; using std::hex; + using std::vector; + + + vector Parameter::_defaultPriorities (1,Parameter::ApplicationBuiltin); + + + Parameter::Priority Parameter::pushDefaultPriority ( Parameter::Priority priority ) + { + Priority previous = _defaultPriorities.back (); + _defaultPriorities.push_back ( priority ); + return previous; + } + + + Parameter::Priority Parameter::popDefaultPriority () + { + Priority previous = _defaultPriorities.back (); + if ( _defaultPriorities.size() > 1 ) + _defaultPriorities.pop_back (); + return previous; + } + + + Parameter::Priority Parameter::getDefaultPriority () + { return _defaultPriorities.back(); } string Parameter::typeToString ( Parameter::Type type ) @@ -59,7 +80,7 @@ namespace Cfg { Parameter::Parameter ( const std::string& id , Type type , const std::string& value - , int priority + , Priority priority ) : _id (id) , _type (type) @@ -77,6 +98,7 @@ namespace Cfg { if ( type == Percentage ) { setPercentage ( asDouble() ); } + if ( priority == UseDefault ) _priority = getDefaultPriority(); //cerr << "New " << typeToString(_type) << " parameter " << _id << " value:" << _value << endl; } @@ -140,10 +162,9 @@ namespace Cfg { } - bool Parameter::setString ( const std::string& s, unsigned int flags, int priority ) + bool Parameter::setString ( const std::string& s, unsigned int flags, Priority priority ) { - if ( priority < _priority ) return false; - _priority = priority; + if ( not _updatePriority(priority) ) return false; if ( (flags & TypeCheck) and (_type != String) ) cerr << "[ERROR] Parameter::setString(): Setting " << Parameter::typeToString(_type) @@ -154,10 +175,9 @@ namespace Cfg { } - bool Parameter::setBool ( bool b, int priority ) + bool Parameter::setBool ( bool b, Priority priority ) { - if ( priority < _priority ) return false; - _priority = priority; + if ( not _updatePriority(priority) ) return false; if ( _type != Bool ) cerr << "[ERROR] Parameter::setBool(): Setting " << Parameter::typeToString(_type) @@ -168,10 +188,9 @@ namespace Cfg { } - bool Parameter::setInt ( int i, int priority ) + bool Parameter::setInt ( int i, Priority priority ) { - if ( priority < _priority ) return false; - _priority = priority; + if ( not _updatePriority(priority) ) return false; if ( (_type != Int) and (_type != Enumerate) ) cerr << "[ERROR] Parameter::setInt(): Setting " << Parameter::typeToString(_type) @@ -182,10 +201,9 @@ namespace Cfg { } - bool Parameter::setDouble ( double d, int priority ) + bool Parameter::setDouble ( double d, Priority priority ) { - if ( priority < _priority ) return false; - _priority = priority; + if ( not _updatePriority(priority) ) return false; if ( (_type != Double) and (_type != Percentage) ) cerr << "[ERROR] Parameter::setDouble(): Setting " << Parameter::typeToString(_type) @@ -196,8 +214,10 @@ namespace Cfg { } - bool Parameter::setPercentage ( double d, int priority ) + bool Parameter::setPercentage ( double d, Priority priority ) { + if ( not _updatePriority(priority) ) return false; + if ( (_type != Double) and (_type != Percentage) ) cerr << "[ERROR] Parameter::setPercentage(): Setting " << Parameter::typeToString(_type) << " parameter <" << _id @@ -207,6 +227,32 @@ namespace Cfg { } + void Parameter::setMin ( int min, Parameter::Priority priority ) + { if (_updatePriority(priority)) { _minInt = min; setFlags(HasMin); } } + + + void Parameter::setMax ( int max, Parameter::Priority priority ) + { if (_updatePriority(priority)) { _maxInt = max; setFlags(HasMax); } } + + + void Parameter::setMin ( double min, Parameter::Priority priority ) + { if (_updatePriority(priority)) { + _minDouble = min; + setFlags ( HasMin ); + if (_type==Percentage) _minDouble/=100.0; + } + } + + + void Parameter::setMax ( double max, Parameter::Priority priority ) + { if (_updatePriority(priority)) { + _maxDouble = max; + setFlags ( HasMax ); + if (_type==Percentage) _maxDouble/=100.0; + } + } + + bool Parameter::_doChange ( unsigned int flags, const string& s, bool b, int i, double d ) { //cerr << "_doChange: " << _id << ":" << _value << " -> \"" << s << "\"|" << b << "|" << i << "|" << d; diff --git a/vlsisapd/src/configuration/src/PyConfiguration.cpp b/vlsisapd/src/configuration/src/PyConfiguration.cpp new file mode 100644 index 00000000..eef7b5f5 --- /dev/null +++ b/vlsisapd/src/configuration/src/PyConfiguration.cpp @@ -0,0 +1,321 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyConfiguration.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +using namespace boost::python; + +#include "vlsisapd/openChams/PySTLMapWrapper.h" +using OpenChams::map_item; + +#include "vlsisapd/configuration/Configuration.h" + + +namespace { + + using namespace Cfg; + + + template + struct EnumToInt { + static PyObject* convert ( EnumType& type ) + { return incref ( object((int)type).ptr() ); } + }; + + +// Thin wrappers for function members overloads. + void parameterSetMinInt1 ( Parameter& self, int min ) { self.setMin(min); } + void parameterSetMinDouble1 ( Parameter& self, double min ) { self.setMin(min); } + void parameterSetMaxInt1 ( Parameter& self, int max ) { self.setMax(max); } + void parameterSetMaxDouble1 ( Parameter& self, double max ) { self.setMax(max); } + +// STL map wrapper for boost::python. + template + class MapWrapper { + public: + typedef typename Map::key_type Key; + typedef typename Map::mapped_type Value; + public: + static Value& get ( Map&, const Key& ); + static void set ( Map&, const Key&, const Value& ); + static void del ( Map&, const Key& ); + static bool in ( Map&, const Key& ); + static list keys ( Map& ); + static list values ( Map& ); + static list items ( Map& ); + }; + + + inline void KeyError () { PyErr_SetString(PyExc_KeyError, "Key not found"); } + + + template + typename MapWrapper::Value& MapWrapper::get ( Map& m, const typename MapWrapper::Key& k ) + { + static Value notFound; + if( m.find(k) != m.end() ) return m[k]; + KeyError (); + return notFound; + } + + template + void MapWrapper::set ( Map& m, const MapWrapper::Key& k, const typename MapWrapper::Value& v ) + { m[k] = v; } + + template + void MapWrapper::del ( Map& m, const typename MapWrapper::Key& k) + { + if( m.find(k) != m.end() ) m.erase(k); + else KeyError (); + } + + template + bool MapWrapper::in ( Map& m, const typename MapWrapper::Key& k ) + { return m.find(k) != m.end(); } + + template + list MapWrapper::keys ( Map& m ) + { + list l; + for(typename Map::iterator it = m.begin() ; it != m.end() ; ++it ) + l.append ( it->first ); + return l; + } + + template + list MapWrapper::values ( Map& m) + { + list l; + for( typename Map::iterator it=m.begin(); it != m.end() ; ++it ) + l.append ( it->second ); + return l; + } + + template + list MapWrapper::items ( Map& m ) { + list l; + for( typename Map::iterator it=m.begin(); it!=m.end(); ++it ) + l.append( make_tuple(it->first,it->second) ); + return l; + } + + +} // End of anonymous namespace. + + +namespace Cfg { + + + BOOST_PYTHON_MODULE(Cfg) { + + typedef void (Parameter::* VoidIntPrioritySign )(int ,Parameter::Priority) ; + typedef void (Parameter::* VoidDoublePrioritySign )(double,Parameter::Priority) ; + typedef void (Parameter::* VoidIntSign )(int ); + typedef void (Parameter::* VoidDoubleSign )(double); + typedef bool (Parameter::* BoolIntConstSign )(int ) const; + typedef bool (Parameter::* BoolDoubleConstSign )(double) const; + typedef bool (Parameter::* BoolBoolSign )(bool ); + typedef bool (Parameter::* BoolIntSign )(int ); + typedef bool (Parameter::* BoolDoubleSign )(double); + typedef bool (Parameter::* BoolStringSign )(std::string); + typedef bool (Parameter::* BoolStringFlagsSign )(std::string,unsigned int); + + // Parameter overloaded function members. + BoolIntConstSign paramCheckValueInt = (BoolIntConstSign) &Parameter::checkValue; + BoolDoubleConstSign paramCheckValueDouble = (BoolDoubleConstSign)&Parameter::checkValue; + BoolStringSign paramSetString1 = (BoolStringSign) &Parameter::setString; + BoolStringFlagsSign paramSetString2 = (BoolStringFlagsSign)&Parameter::setString; + BoolBoolSign paramSetBool1 = (BoolBoolSign) &Parameter::setBool; + BoolIntSign paramSetInt1 = (BoolIntSign) &Parameter::setInt; + BoolDoubleSign paramSetDouble1 = (BoolDoubleSign) &Parameter::setDouble; + BoolDoubleSign paramSetPercentage1 = (BoolDoubleSign) &Parameter::setPercentage; + + implicitly_convertible(); + implicitly_convertible(); + implicitly_convertible(); + + //to_python_converter >(); + + { + scope paramScope + ( class_("Parameter", init >()) + .def("isFile" , &Parameter::isFile) + .def("isPath" , &Parameter::isPath) + .def("hasMin" , &Parameter::hasMin) + .def("hasMax" , &Parameter::hasMax) + .def("hasNeedRestart" , &Parameter::hasNeedRestart) + .def("hasMustExist" , &Parameter::hasMustExist) + //.def("hasFlags" , &Parameter::hasFlags) + .def("getId" , &Parameter::getId, return_value_policy()) + .def("getMinInt" , &Parameter::getMinInt) + .def("getMaxInt" , &Parameter::getMaxInt) + .def("getMinDouble" , &Parameter::getMinDouble) + .def("getMaxDouble" , &Parameter::getMaxDouble) + .def("checkValue" , paramCheckValueInt) + .def("checkValue" , paramCheckValueDouble) + .def("asString" , &Parameter::asString, return_value_policy()) + .def("asPercentageString", &Parameter::asPercentageString) + .def("asBool" , &Parameter::asBool) + .def("asInt" , &Parameter::asInt) + .def("asPercentage" , &Parameter::asPercentage) + .def("addValue" , &Parameter::addValue) + .def("addSlave" , &Parameter::addSlave) + .def("setPriority" , &Parameter::setPriority) + .def("setString" , &Parameter::setString) + .def("setString" , paramSetString1) + .def("setString" , paramSetString2) + .def("setBool" , &Parameter::setBool) + .def("setBool" , paramSetBool1) + .def("setInt" , &Parameter::setInt) + .def("setInt" , paramSetInt1) + .def("setDouble" , &Parameter::setDouble) + .def("setDouble" , paramSetDouble1) + .def("setPercentage" , &Parameter::setPercentage) + .def("setPercentage" , paramSetPercentage1) + .def("setMin" , ¶meterSetMinInt1) + .def("setMin" , ¶meterSetMinDouble1) + .def("setMax" , ¶meterSetMaxInt1) + .def("setMax" , ¶meterSetMaxDouble1) + + //.add_property("flags", &Parameter::getFlags, &Parameter::setFlags) + .add_property("type" , &Parameter::getType) + ); + + enum_("Type") + .value("Unknown" ,Parameter::Unknown) + .value("String" ,Parameter::String) + .value("Bool" ,Parameter::Bool) + .value("Int" ,Parameter::Int) + .value("Enumerate" ,Parameter::Enumerate) + .value("Double" ,Parameter::Double) + .value("Percentage",Parameter::Percentage) + ; + + enum_("Priority") + .value("UseDefault" ,Parameter::UseDefault) + .value("ApplicationBuiltin",Parameter::ApplicationBuiltin) + .value("ConfigurationFile" ,Parameter::ConfigurationFile) + .value("CommandLine" ,Parameter::CommandLine) + .value("Interactive" ,Parameter::Interactive) + ; + + enum_("Flags") + .value("HasMin" , Parameter::HasMin) + .value("HasMax" , Parameter::HasMax) + .value("IsFile" , Parameter::IsFile) + .value("IsPath" , Parameter::IsPath) + .value("NeedRestart" , Parameter::NeedRestart) + .value("MustExist" , Parameter::MustExist) + .value("TypeCheck" , Parameter::TypeCheck) + .value("FromString" , Parameter::FromString) + .value("AllRequirements", Parameter::AllRequirements) + ; + } + + typedef std::map ParametersMap; + typedef std::pair ParametersPair; + + class_("ParametersPair") + .def_readonly ("key" , &ParametersPair::first ) + .def_readwrite("value", &ParametersPair::second) + ; + class_("ParametersMap") + .def("__len__" , &ParametersMap::size) + .def("clear" , &ParametersMap::clear) + .def("__getitem__" , &MapWrapper::get, return_value_policy()) + .def("__setitem__" , &MapWrapper::set, return_value_policy()) + .def("__delitem__" , &MapWrapper::del) + .def("__contains__" , &MapWrapper::in ) + .def("has_key" , &MapWrapper::in ) + .def("keys" , &MapWrapper::keys ) + .def("values" , &MapWrapper::values ) + .def("items" , &MapWrapper::items ) + ; + + // Configuration overloaded function members. + Parameter* (Configuration::*CfgGetParameter1) ( const std::string& ) const = (Parameter* (Configuration:: *)(const std::string&) const) &Configuration::getParameter; + Parameter* (Configuration::*CfgGetParameter2) ( const std::string&, Parameter::Type ) const = (Parameter* (Configuration:: *)(const std::string&,Parameter::Type) const)&Configuration::getParameter; + + { + scope confScope + ( class_("Configuration", no_init) + .def("get" , &Configuration::get , return_value_policy()) + .def("getParameter" , CfgGetParameter1 , return_value_policy()) + .def("getParameter" , CfgGetParameter2 , return_value_policy()) + .def("pushDefaultPriority", &Configuration::pushDefaultPriority) + .def("popDefaultPriority" , &Configuration::popDefaultPriority ) + .def("getDefaultPriority" , &Configuration::getDefaultPriority ) + .def("getParameters" , &Configuration::getParameters , return_value_policy()) + .staticmethod("get") + .staticmethod("pushDefaultPriority") + .staticmethod("popDefaultPriority") + .staticmethod("getDefaultPriority") + .add_property("flags", &Configuration::getFlags, &Configuration::setFlags) + ); + + implicitly_convertible(); + + enum_("Flags") + .value("DriveValues",Configuration::DriveValues) + .value("DriveLayout",Configuration::DriveLayout) + ; + } + + + // Configuration overloaded functions. + typedef Parameter* (*ParamStringSign )(const std::string&); + typedef Parameter* (*ParamStringBoolSign )(const std::string&, bool); + typedef Parameter* (*ParamStringIntSign )(const std::string&, int); + typedef Parameter* (*ParamStringDoubleSign)(const std::string&, double); + typedef Parameter* (*ParamStringStringSign)(const std::string&, const std::string&); + + ParamStringSign getParamString1 = (ParamStringSign )getParamString; + ParamStringStringSign getParamString2 = (ParamStringStringSign)getParamString; + ParamStringSign getParamBool1 = (ParamStringSign )getParamBool; + ParamStringBoolSign getParamBool2 = (ParamStringBoolSign )getParamBool; + ParamStringSign getParamInt1 = (ParamStringSign )getParamInt; + ParamStringIntSign getParamInt2 = (ParamStringIntSign )getParamInt; + ParamStringSign getParamEnumerate1 = (ParamStringSign )getParamEnumerate; + ParamStringIntSign getParamEnumerate2 = (ParamStringIntSign )getParamEnumerate; + ParamStringSign getParamDouble1 = (ParamStringSign )getParamDouble; + ParamStringDoubleSign getParamDouble2 = (ParamStringDoubleSign)getParamDouble; + ParamStringSign getParamPercentage1 = (ParamStringSign )getParamPercentage; + ParamStringDoubleSign getParamPercentage2 = (ParamStringDoubleSign)getParamPercentage; + + def("getParamString" , getParamString1 , return_value_policy()); + def("getParamString" , getParamString2 , return_value_policy()); + def("getParamBool" , getParamBool1 , return_value_policy()); + def("getParamBool" , getParamBool2 , return_value_policy()); + def("getParamInt" , getParamInt1 , return_value_policy()); + def("getParamInt" , getParamInt2 , return_value_policy()); + def("getParamEnumerate" , getParamEnumerate1 , return_value_policy()); + def("getParamEnumerate" , getParamEnumerate2 , return_value_policy()); + def("getParamDouble" , getParamDouble1 , return_value_policy()); + def("getParamDouble" , getParamDouble2 , return_value_policy()); + def("getParamPercentage", getParamPercentage1, return_value_policy()); + def("getParamPercentage", getParamPercentage2, return_value_policy()); + + } // End of Configuration BOOST_PYTHON_MODULE. + + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h index f122b302..226ff820 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h @@ -2,24 +2,20 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x -// | | // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./Configuration.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | // x-----------------------------------------------------------------x @@ -58,6 +54,10 @@ namespace Cfg { public: static Configuration* get (); + static Parameter::Priority pushDefaultPriority ( Parameter::Priority ); + static Parameter::Priority popDefaultPriority (); + static Parameter::Priority getDefaultPriority (); + static void _tokenize ( std::set& tokens, const std::string& line ); public: // Methods. ConfigurationWidget* buildWidget ( unsigned int flags ); @@ -68,12 +68,12 @@ namespace Cfg { inline unsigned int getFlags () const; inline const LayoutDescription& getLayout () const; inline LayoutDescription& getLayout (); - 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 - , int priority=0 ); + 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 + , Parameter::Priority priority=Parameter::UseDefault ); inline void setFlags ( unsigned int mask ); inline bool hasLogs ( unsigned int mask ) const; void addLog ( unsigned int mask, const std::string& id ); diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h index 9f616e24..08448f30 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h @@ -2,14 +2,13 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | @@ -17,10 +16,7 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./LayoutDescription.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ @@ -122,25 +118,30 @@ namespace Cfg { class TabDescription { public: - inline TabDescription ( LayoutDescription*, const std::string& name ); + inline TabDescription ( LayoutDescription*, const std::string& name, const std::string& id ); void addWidget ( WidgetDescription* ); inline const std::string& getName () const; + inline const std::string& getId () const; inline const std::vector& getWidgets () const; private: LayoutDescription* _layout; std::string _name; + std::string _id; std::vector _widgets; }; // Inline Methods. - inline TabDescription::TabDescription ( LayoutDescription* layout, const std::string& name ) - : _layout(layout), _name(name), _widgets() + inline TabDescription::TabDescription ( LayoutDescription* layout, const std::string& name, const std::string& id ) + : _layout(layout), _name(name), _id(id), _widgets() { } inline const std::string& TabDescription::getName () const { return _name; } + inline const std::string& TabDescription::getId () const + { return _id; } + inline const std::vector& TabDescription::getWidgets () const { return _widgets; } @@ -155,9 +156,9 @@ namespace Cfg { WidgetDescription* getWidget ( const std::string& id ); void addWidgetLookup ( WidgetDescription* ); inline void addTab ( TabDescription* ); - inline void addTab ( const std::string& tabName ); + inline void addTab ( const std::string& tabName, const std::string& id ); inline TabDescription* getBackTab (); - TabDescription* getTab ( const std::string& tabName ); + TabDescription* getTab ( const std::string& tabName, const std::string& id="no_id" ); inline const std::vector& getTabs () const; void addRule ( const std::string& tabName ); void addTitle ( const std::string& tabName @@ -172,7 +173,7 @@ namespace Cfg { , int span =1 , unsigned int flags =0 ); ConfigurationWidget* buildWidget ( unsigned int flags ); - void writeToStream ( std::ostream& ) const; + void writeToStream ( std::ostream&, const std::string& ) const; private: Configuration* _configuration; std::vector _tabs; @@ -188,8 +189,8 @@ namespace Cfg { inline void LayoutDescription::addTab ( TabDescription* tab ) { _tabs.push_back(tab); } - inline void LayoutDescription::addTab ( const std::string& tabName ) - { addTab ( new TabDescription(this,tabName) ); } + inline void LayoutDescription::addTab ( const std::string& tabName, const std::string& id ) + { addTab ( new TabDescription(this,tabName,id) ); } inline TabDescription* LayoutDescription::getBackTab () { return _tabs.back(); } diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h index 68aefd1b..7065a684 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h @@ -2,25 +2,21 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | C o n f i g u r a t i o n D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./Parameter.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./vlsisapd/configuration/Parameter.h" | +// +-----------------------------------------------------------------+ #ifndef __CFG_CONFIGURATION_PARAMETER__ @@ -56,7 +52,8 @@ namespace Cfg { , FromString = 0x80 , AllRequirements = HasMin|HasMax|IsFile|IsPath|NeedRestart|MustExist|TypeCheck }; - enum Priority { ApplicationBuiltin = 1 + enum Priority { UseDefault = 0 + , ApplicationBuiltin = 1 , ConfigurationFile = 2 , CommandLine = 3 , Interactive = 4 @@ -71,61 +68,66 @@ namespace Cfg { int _value; }; public: - static std::string typeToString ( Type ); + static std::string typeToString ( Type ); + static Priority pushDefaultPriority ( Priority ); + static Priority popDefaultPriority (); + static Priority getDefaultPriority (); public: - Parameter ( const std::string& id - , Type type - , const std::string& value - , int priority=0 ); - inline bool isFile () const; - inline bool isPath () const; - inline bool hasMin () const; - inline bool hasMax () const; - inline bool hasNeedRestart () const; - inline bool hasMustExist () const; - inline bool hasFlags ( int mask ) const; - 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 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; - std::string asPercentageString () 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& ); - inline void setPriority ( int ); - inline void setFlags ( int mask ); - inline void unsetFlags ( int mask ); - bool setString ( const std::string& - , unsigned int flags=AllRequirements - , int priority=ApplicationBuiltin - ); - bool setBool ( bool , int priority=ApplicationBuiltin ); - bool setInt ( int , int priority=ApplicationBuiltin ); - bool setDouble ( double, int priority=ApplicationBuiltin ); - bool setPercentage ( double, int priority=ApplicationBuiltin ); - inline void setMin ( int , int priority=ApplicationBuiltin ); - inline void setMax ( int , int priority=ApplicationBuiltin ); - inline void setMin ( double, int priority=ApplicationBuiltin ); - inline void setMax ( double, int priority=ApplicationBuiltin ); - inline void registerCb ( ParameterChangedCb_t ); - private: - inline void _onValueChanged (); - bool _doChange ( unsigned int flags, const std::string&, bool, int, double ); + Parameter ( const std::string& id + , Type type + , const std::string& value + , Priority priority=UseDefault ); + inline bool isFile () const; + inline bool isPath () const; + inline bool hasMin () const; + inline bool hasMax () const; + inline bool hasNeedRestart () const; + inline bool hasMustExist () const; + inline bool hasFlags ( int mask ) const; + 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 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; + std::string asPercentageString () 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& ); + inline void setPriority ( Priority ); + inline void setFlags ( int mask ); + inline void unsetFlags ( int mask ); + bool setString ( const std::string& + , unsigned int flags =AllRequirements + , Priority priority=UseDefault + ); + bool setBool ( bool , Priority priority=UseDefault ); + bool setInt ( int , Priority priority=UseDefault ); + bool setDouble ( double, Priority priority=UseDefault ); + bool setPercentage ( double, Priority priority=UseDefault ); + void setMin ( int , Priority priority=UseDefault ); + void setMax ( int , Priority priority=UseDefault ); + void setMin ( double, Priority priority=UseDefault ); + void setMax ( double, Priority priority=UseDefault ); + inline void registerCb ( ParameterChangedCb_t ); + private: + inline void _onValueChanged (); + inline bool _updatePriority ( Priority ); + bool _doChange ( unsigned int flags, const std::string&, bool, int, double ); private: // Attributes. + static std::vector _defaultPriorities; std::string _id; Type _type; std::string _value; @@ -159,7 +161,7 @@ namespace Cfg { inline const std::string& Parameter::asString () const { return _value; } inline void Parameter::setFlags ( int mask ) { _flags |= mask; } inline void Parameter::unsetFlags ( int mask ) { _flags &= ~mask; } - inline void Parameter::setPriority ( int priority ) { _priority = priority; } + inline void Parameter::setPriority ( Priority priority ) { _priority = priority; } inline bool Parameter::checkValue ( int value ) const { bool ok = not ( ( (_flags&HasMin) and (value < _minInt) ) @@ -192,35 +194,20 @@ namespace Cfg { _values.push_back ( EnumValue(label,value) ); } - inline void Parameter::setMin ( int min, int priority ) - { if (priority >= _priority) { _priority=priority; _minInt = min; setFlags(HasMin); } } - - inline void Parameter::setMax ( int max, int priority ) - { if (priority >= _priority) { _priority=priority; _maxInt = max; setFlags(HasMax); } } - - inline void Parameter::setMin ( double min, int priority ) - { if (priority >= _priority) { - _priority = priority; - _minDouble = min; - setFlags ( HasMin ); - if (_type==Percentage) _minDouble/=100.0; - } - } - - inline void Parameter::setMax ( double max, int priority ) - { if (priority >= _priority) { - _priority = priority; - _maxDouble = max; - setFlags ( HasMax ); - if (_type==Percentage) _maxDouble/=100.0; - } - } - 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 bool Parameter::_updatePriority ( Priority priority ) + { + if ( priority == UseDefault ) priority = getDefaultPriority(); + if ( priority < _priority ) return false; + _priority = priority; + return true; + } + inline void Parameter::_onValueChanged () { for ( size_t icb=0 ; icb<_callbacks.size() ; ++icb ) _callbacks[icb]( this ); }