// // C++ Implementation: itpp_ext // // Description: // // // Author: smidl , (C) 2008 // // Copyright: See COPYING file that comes with this distribution // // #include "user_info.h" namespace bdm { ///////////////////////////// Class UIFile ///////////////////////////////////////////// UIFile::UIFile() { } UIFile::UIFile ( const string &file_name ) { try { readFile( file_name.c_str() ); // this flag has to be set AFTER each file load, that is why it is right here setAutoConvert( true ); } catch ( FileIOException f ) { it_error ( "UI error: file " + file_name + " not found." ); } catch ( ParseException& P ) { stringstream msg; msg << "UI error: parsing error """ << P.getError() << """ in file " << file_name << " on line " << P.getLine() << "."; it_error ( msg.str() ); } } void UIFile::save(const string &file_name ) { try { writeFile ( file_name.c_str() ); } catch ( FileIOException f ) { it_error( "UI error: file " + file_name + " is inacessible." ); } } UIFile::operator Setting&() { return getRoot(); } ///////////////////////////// Class UI::MappedUI ///////////////////////////////////////////// UI::MappedUI::StringToUIMap& UI::MappedUI::mapped_strings() { // this way it is ensured that there is only one instance of StringTpUIMap, and // what is more, this declaration leaves its allocation/deallocation on the compiler static StringToUIMap var; return var; } UI::MappedUI::TypeInfoToStringMap& UI::MappedUI::mapped_type_infos() { // this way it is ensured that there is only one instance of TypeInfoToStringMap, and // what is more, this declaration leaves its allocation/deallocation on the compiler static TypeInfoToStringMap var; return var; } void UI::MappedUI::add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ) { pair< const string, const UI* const > new_pair = make_pair( class_name, ui ); mapped_strings().insert( new_pair ); mapped_type_infos().insert( make_pair( class_type_info, new_pair.first ) ); } void UI::MappedUI::unregistered_class_error( const string &unregistered_class_name ) { stringstream msg; msg << "UI error: class " + unregistered_class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." << endl; if( mapped_strings().size() ) { StringToUIMap::const_iterator iter = mapped_strings().begin(); msg << "These classes are already registered: " << iter->first; for(; iter != mapped_strings().end(); iter++) msg << ", " << iter->first; msg << "." << endl; } else msg << "There is not any registered class yet!" << endl; it_error ( msg.str() ); } const UI& UI::MappedUI::retrieve_ui( const string &class_name ) { StringToUIMap::const_iterator iter = mapped_strings().find( class_name ); if ( iter == mapped_strings().end()) unregistered_class_error( class_name ); return *iter->second; } const string& UI::MappedUI::retrieve_class_name( const type_info * const class_type_info ) { TypeInfoToStringMap::const_iterator iter = mapped_type_infos().find( class_type_info ); if ( iter == mapped_type_infos().end()) unregistered_class_error( "with RTTI name " + string(class_type_info->name()) ); return iter->second; } ///////////////////////////// Class UI::SettingResolver ///////////////////////////////////////////// UI::SettingResolver::SettingResolver( const Setting &potential_link ) : result( initialize_reference( file, potential_link ) ) { } const Setting& UI::SettingResolver::initialize_reference(UIFile *&file, const Setting &potential_link) { file = NULL; if ( potential_link.getType() != Setting::TypeString ) return potential_link; string link = (const char*) potential_link; size_t aerobase = link.find('@'); const Setting *result; if ( aerobase != string::npos ) { string file_name = link.substr( aerobase + 1, link.length() ); file = new UIFile( file_name ); result = &(Setting&)(*file); link = link.substr( 0, aerobase ); } else { result = &potential_link; while ( !result->isRoot() ) result = &result->getParent(); } if ( !result->exists( link ) ) ui_error( "linked setting was not found", potential_link ); return (*result)[link]; } UI::SettingResolver::~SettingResolver() { if ( file ) delete file; } ///////////////////////////// Class UI ///////////////////////////////////////////// void UI::ui_error( string message, const Setting &element ) { stringstream error_message; error_message << "UI error: " << message << "! Check path """ << element.getPath() << """, source line " << element.getSourceLine() << "."; it_error ( error_message.str() ); } const Setting& UI::to_child_setting( const Setting &element, const int index ) { if ( !element.isList()) ui_error( "only TypeList elements could be indexed by integers", element ); if ( element.getLength() <= index ) ui_error( "there is not any child with index " + index, element ); return element[index]; } const Setting& UI::to_child_setting( const Setting &element, const string &name ) { if ( !element.isGroup()) ui_error( "only TypeGroup elements could be indexed by strings", element ); if ( !element.exists( name ) ) ui_error( "there is not any child named """ + name, element ); return element[name]; } void UI::save( const int &integer, Setting &element, const string &name) { Setting &set = (name == "") ? element.add( Setting::TypeInt ) : element.add( name, Setting::TypeInt ); set = integer; } void UI::save( const double &real, Setting &element, const string &name) { Setting &set = (name == "") ? element.add( Setting::TypeFloat ) : element.add( name, Setting::TypeFloat ); set = real; } void UI::save( const string &str, Setting &element, const string &name) { Setting &set = (name == "") ? element.add( Setting::TypeString ) : element.add( name, Setting::TypeString ); set = str; } void UI::save( const mat &matrix, Setting &element, const string &name) { Setting &set = (name == "") ? element.add( Setting::TypeList ) : element.add( name, Setting::TypeList ); Setting &cols = set.add( Setting::TypeInt ); cols = matrix.cols(); Setting &rows = set.add( Setting::TypeInt ); rows = matrix.rows(); Setting &elements = set.add( Setting::TypeArray ); // build matrix row-wise for ( int i=0; i