| 104 | | file = NULL; |
| 105 | | result = &potential_link; |
| 106 | | |
| 107 | | if( potential_link.getType() != Setting::TypeString ) |
| 108 | | return; |
| 109 | | |
| 110 | | string link = (string) potential_link; |
| 111 | | size_t aerobase = link.find('@'); |
| 112 | | if( aerobase != string::npos ) |
| 113 | | { |
| 114 | | string file_name = link.substr( aerobase + 1, link.length() ); |
| 115 | | file = new UI_File( file_name ); |
| 116 | | file->load(); |
| 117 | | result = &(Setting&)(*file); |
| 118 | | link = link.substr( 0, aerobase ); |
| 119 | | } |
| 120 | | else |
| 121 | | while ( !result->isRoot() ) |
| 122 | | result = &result->getParent(); |
| 123 | | |
| 124 | | if( !result->exists( link ) ) |
| 125 | | ui_error( "linked Setting was not found", potential_link ); |
| 126 | | |
| 127 | | result = &(*result)[link]; |
| | 106 | file = NULL; |
| | 107 | result = &potential_link; |
| | 108 | |
| | 109 | if ( potential_link.getType() != Setting::TypeString ) |
| | 110 | return; |
| | 111 | |
| | 112 | string link = (string) potential_link; |
| | 113 | size_t aerobase = link.find('@'); |
| | 114 | if ( aerobase != string::npos ) |
| | 115 | { |
| | 116 | string file_name = link.substr( aerobase + 1, link.length() ); |
| | 117 | file = new UI_File( file_name ); |
| | 118 | result = &(Setting&)(*file); |
| | 119 | link = link.substr( 0, aerobase ); |
| | 120 | } |
| | 121 | else |
| | 122 | while ( !result->isRoot() ) |
| | 123 | result = &result->getParent(); |
| | 124 | |
| | 125 | if ( !result->exists( link ) ) |
| | 126 | ui_error( "linked Setting was not found", potential_link ); |
| | 127 | |
| | 128 | result = &(*result)[link]; |
| 153 | | |
| 154 | | Setting &root = (name == "") ? element.add( Setting::TypeList ) |
| 155 | | : element.add( name, Setting::TypeList ); |
| 156 | | |
| 157 | | Setting &cols = root.add( Setting::TypeInt ); |
| 158 | | cols = matrix.cols(); |
| 159 | | |
| 160 | | Setting &rows = root.add( Setting::TypeInt ); |
| 161 | | rows = matrix.rows(); |
| 162 | | |
| 163 | | Setting &elements = root.add( Setting::TypeArray ); |
| 164 | | |
| 165 | | // build matrix row-wise |
| 166 | | for( int i=0; i<matrix.rows(); i++ ) |
| 167 | | for( int j=0; j<matrix.cols(); j++) |
| 168 | | { |
| 169 | | Setting &new_field = elements.add(Setting::TypeFloat); |
| 170 | | new_field = matrix(i,j); |
| 171 | | } |
| 172 | | } |
| 173 | | |
| 174 | | |
| 175 | | //! This methods tries to save a double vec |
| 176 | | void UI::save( const ivec &vec, Setting &element, const string &name) |
| 177 | | { |
| 178 | | |
| 179 | | Setting &root = (name == "") ? element.add( Setting::TypeArray ) |
| 180 | | : element.add( name, Setting::TypeArray ); |
| 181 | | for( int i=0; i<vec.length(); i++ ) |
| 182 | | { |
| 183 | | Setting &new_field = root.add(Setting::TypeInt); |
| 184 | | new_field = vec(i); |
| 185 | | } |
| 186 | | } |
| 187 | | |
| 188 | | |
| 189 | | //! This methods tries to build a new double matrix |
| | 159 | |
| | 160 | Setting &root = (name == "") ? element.add( Setting::TypeList ) |
| | 161 | : element.add( name, Setting::TypeList ); |
| | 162 | |
| | 163 | Setting &cols = root.add( Setting::TypeInt ); |
| | 164 | cols = matrix.cols(); |
| | 165 | |
| | 166 | Setting &rows = root.add( Setting::TypeInt ); |
| | 167 | rows = matrix.rows(); |
| | 168 | |
| | 169 | Setting &elements = root.add( Setting::TypeArray ); |
| | 170 | |
| | 171 | // build matrix row-wise |
| | 172 | for ( int i=0; i<matrix.rows(); i++ ) |
| | 173 | for ( int j=0; j<matrix.cols(); j++) |
| | 174 | { |
| | 175 | Setting &new_field = elements.add(Setting::TypeFloat); |
| | 176 | new_field = matrix(i,j); |
| | 177 | } |
| | 178 | } |
| | 179 | |
| | 180 | |
| | 181 | //! This methods tries to save a integer vector |
| | 182 | void UI::save( const ivec &vector, Setting &element, const string &name) |
| | 183 | { |
| | 184 | |
| | 185 | Setting &root = (name == "") ? element.add( Setting::TypeArray ) |
| | 186 | : element.add( name, Setting::TypeArray ); |
| | 187 | for ( int i=0; i<vector.length(); i++ ) |
| | 188 | { |
| | 189 | Setting &new_field = root.add(Setting::TypeInt); |
| | 190 | new_field = vector(i); |
| | 191 | } |
| | 192 | } |
| | 193 | |
| | 194 | |
| | 195 | //! This methods tries to save a double vector |
| | 196 | void UI::save( const vec &vector, Setting &element, const string &name) |
| | 197 | { |
| | 198 | |
| | 199 | Setting &root = (name == "") ? element.add( Setting::TypeArray ) |
| | 200 | : element.add( name, Setting::TypeArray ); |
| | 201 | for ( int i=0; i<vector.length(); i++ ) |
| | 202 | { |
| | 203 | Setting &new_field = root.add(Setting::TypeFloat); |
| | 204 | new_field = vector(i); |
| | 205 | } |
| | 206 | } |
| | 207 | |
| | 208 | |
| | 209 | //! This methods tries to build a new double matrix |
| 193 | | const Link_Expander link_expander( element ); |
| 194 | | const Setting &root = link_expander.root(); |
| 195 | | |
| 196 | | if( root.isNumber() ) |
| 197 | | { |
| 198 | | matrix.set_size( 1, 1 ); |
| 199 | | matrix(0,0) = root; |
| 200 | | return; |
| 201 | | } |
| 202 | | |
| 203 | | if( root.isList() ) |
| 204 | | { |
| 205 | | if( root.getLength() != 3 ) |
| 206 | | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
| 207 | | |
| 208 | | Setting &cols_setting = root[0]; |
| 209 | | Setting &rows_setting = root[1]; |
| 210 | | Setting &elements = root[2]; |
| 211 | | |
| 212 | | ASSERT_UITYPE(cols_setting,TypeInt); |
| 213 | | ASSERT_UITYPE(rows_setting,TypeInt); |
| 214 | | ASSERT_UITYPE(elements,TypeArray); |
| 215 | | |
| 216 | | int cols = cols_setting; |
| 217 | | int rows = rows_setting; |
| 218 | | |
| 219 | | if( cols < 0 | rows < 0 ) |
| 220 | | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
| 221 | | |
| 222 | | if( elements.getLength() != cols * rows ) |
| 223 | | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
| 224 | | |
| 225 | | matrix.set_size( rows, cols ); |
| 226 | | |
| 227 | | if( cols == 0 || rows == 0 ) |
| 228 | | return; |
| 229 | | |
| 230 | | if( !elements[0].isNumber() ) |
| 231 | | ui_error( "matrix elements have to be numbers", elements[0] ); |
| 232 | | |
| 233 | | // build matrix row-wise |
| 234 | | int k = 0; |
| 235 | | for( int i=0;i<rows;i++ ) |
| 236 | | for( int j=0; j<cols; j++) |
| 237 | | matrix(i,j) = elements[k++]; |
| 238 | | return; |
| 239 | | } |
| 240 | | |
| 241 | | ui_error( "only numeric types or TypeList are supported as matrix values", root ); |
| | 213 | const Link_Expander link_expander( element ); |
| | 214 | const Setting &root = link_expander.root(); |
| | 215 | |
| | 216 | if ( root.isNumber() ) |
| | 217 | { |
| | 218 | matrix.set_size( 1, 1 ); |
| | 219 | matrix(0,0) = root; |
| | 220 | return; |
| | 221 | } |
| | 222 | |
| | 223 | if ( root.isList() ) |
| | 224 | { |
| | 225 | if ( root.getLength() != 3 ) |
| | 226 | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
| | 227 | |
| | 228 | Setting &rows_setting = root[0]; |
| | 229 | Setting &cols_setting = root[1]; |
| | 230 | Setting &elements = root[2]; |
| | 231 | |
| | 232 | ASSERT_UITYPE(cols_setting,TypeInt); |
| | 233 | ASSERT_UITYPE(rows_setting,TypeInt); |
| | 234 | ASSERT_UITYPE(elements,TypeArray); |
| | 235 | |
| | 236 | int cols = cols_setting; |
| | 237 | int rows = rows_setting; |
| | 238 | |
| | 239 | if ( cols < 0 | rows < 0 ) |
| | 240 | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
| | 241 | |
| | 242 | if ( elements.getLength() != cols * rows ) |
| | 243 | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
| | 244 | |
| | 245 | matrix.set_size( rows, cols ); |
| | 246 | |
| | 247 | if ( cols == 0 || rows == 0 ) |
| | 248 | return; |
| | 249 | |
| | 250 | if ( !elements[0].isNumber() ) |
| | 251 | ui_error( "matrix elements have to be numbers", elements[0] ); |
| | 252 | |
| | 253 | // build matrix row-wise |
| | 254 | int k = 0; |
| | 255 | for ( int i=0; i<rows; i++ ) |
| | 256 | for ( int j=0; j<cols; j++) |
| | 257 | matrix(i,j) = elements[k++]; |
| | 258 | return; |
| | 259 | } |
| | 260 | |
| | 261 | ui_error( "only numeric types or TypeList are supported as matrix values", root ); |
| 245 | | void UI::from_setting( ivec &vec, const Setting &element ) |
| 246 | | { |
| 247 | | const Link_Expander link_expander( element ); |
| 248 | | const Setting &root = link_expander.root(); |
| 249 | | |
| 250 | | if( root.isNumber() ) |
| 251 | | { |
| 252 | | ASSERT_UITYPE(root,TypeInt); |
| 253 | | vec.set_length( 1 ); |
| 254 | | vec(0) = root; |
| 255 | | return; |
| 256 | | } |
| 257 | | |
| 258 | | if( root.isList() ) |
| 259 | | { |
| 260 | | if( root.getLength() != 3 ) |
| 261 | | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
| 262 | | |
| 263 | | Setting &cols_setting = root[0]; |
| 264 | | Setting &rows_setting = root[1]; |
| 265 | | Setting &elements = root[2]; |
| 266 | | |
| 267 | | ASSERT_UITYPE(cols_setting,TypeInt); |
| 268 | | ASSERT_UITYPE(rows_setting,TypeInt); |
| 269 | | ASSERT_UITYPE(elements,TypeArray); |
| 270 | | |
| 271 | | int cols = cols_setting; |
| 272 | | int rows = rows_setting; |
| 273 | | |
| 274 | | if( cols < 0 | rows < 0) |
| 275 | | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
| 276 | | |
| 277 | | if( elements.getLength() != cols * rows ) |
| 278 | | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
| 279 | | |
| 280 | | if( cols != 1 & rows !=1) |
| 281 | | ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); |
| 282 | | |
| 283 | | int len = rows * cols; |
| 284 | | vec.set_length ( len ); |
| 285 | | if( len == 0 ) return; |
| 286 | | |
| 287 | | ASSERT_UITYPE(elements[0],TypeInt); |
| 288 | | for( int i=0; i<len; i++ ) |
| 289 | | vec(i) = elements[i]; |
| 290 | | return; |
| 291 | | } |
| 292 | | |
| 293 | | if( root.isArray() ) |
| 294 | | { |
| 295 | | int len = root.getLength(); |
| 296 | | vec.set_length( len ); |
| 297 | | if( len == 0 ) return; |
| 298 | | |
| 299 | | ASSERT_UITYPE(root[0],TypeInt); |
| 300 | | for( int i=0; i < len; i++ ) |
| 301 | | vec(i) = root[i]; |
| 302 | | return; |
| 303 | | } |
| 304 | | |
| 305 | | ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); |
| | 265 | void UI::from_setting( ivec &vector, const Setting &element ) |
| | 266 | { |
| | 267 | const Link_Expander link_expander( element ); |
| | 268 | const Setting &root = link_expander.root(); |
| | 269 | |
| | 270 | if ( root.isNumber() ) |
| | 271 | { |
| | 272 | ASSERT_UITYPE(root,TypeInt); |
| | 273 | vector.set_length( 1 ); |
| | 274 | vector(0) = root; |
| | 275 | return; |
| | 276 | } |
| | 277 | |
| | 278 | if ( root.isList() ) |
| | 279 | { |
| | 280 | if ( root.getLength() != 3 ) |
| | 281 | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
| | 282 | |
| | 283 | Setting &cols_setting = root[0]; |
| | 284 | Setting &rows_setting = root[1]; |
| | 285 | Setting &elements = root[2]; |
| | 286 | |
| | 287 | ASSERT_UITYPE(cols_setting,TypeInt); |
| | 288 | ASSERT_UITYPE(rows_setting,TypeInt); |
| | 289 | ASSERT_UITYPE(elements,TypeArray); |
| | 290 | |
| | 291 | int cols = cols_setting; |
| | 292 | int rows = rows_setting; |
| | 293 | |
| | 294 | if ( cols < 0 | rows < 0) |
| | 295 | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
| | 296 | |
| | 297 | if ( elements.getLength() != cols * rows ) |
| | 298 | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
| | 299 | |
| | 300 | if ( cols != 1 & rows !=1) |
| | 301 | ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); |
| | 302 | |
| | 303 | int len = rows * cols; |
| | 304 | vector.set_length ( len ); |
| | 305 | if ( len == 0 ) return; |
| | 306 | |
| | 307 | ASSERT_UITYPE(elements[0],TypeInt); |
| | 308 | for ( int i=0; i<len; i++ ) |
| | 309 | vector(i) = elements[i]; |
| | 310 | return; |
| | 311 | } |
| | 312 | |
| | 313 | if ( root.isArray() ) |
| | 314 | { |
| | 315 | int len = root.getLength(); |
| | 316 | vector.set_length( len ); |
| | 317 | if ( len == 0 ) return; |
| | 318 | |
| | 319 | ASSERT_UITYPE(root[0],TypeInt); |
| | 320 | for ( int i=0; i < len; i++ ) |
| | 321 | vector(i) = root[i]; |
| | 322 | return; |
| | 323 | } |
| | 324 | |
| | 325 | ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); |
| | 326 | } |
| | 327 | |
| | 328 | //! This methods tries to build a new double vector |
| | 329 | void UI::from_setting( vec &vector, const Setting &element ) |
| | 330 | { |
| | 331 | const Link_Expander link_expander( element ); |
| | 332 | const Setting &root = link_expander.root(); |
| | 333 | |
| | 334 | if ( root.isNumber() ) |
| | 335 | { |
| | 336 | vector.set_length( 1 ); |
| | 337 | vector(0) = root; |
| | 338 | return; |
| | 339 | } |
| | 340 | |
| | 341 | if ( root.isList() ) |
| | 342 | { |
| | 343 | if ( root.getLength() != 3 ) |
| | 344 | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
| | 345 | |
| | 346 | Setting &cols_setting = root[0]; |
| | 347 | Setting &rows_setting = root[1]; |
| | 348 | Setting &elements = root[2]; |
| | 349 | |
| | 350 | ASSERT_UITYPE(cols_setting,TypeInt); |
| | 351 | ASSERT_UITYPE(rows_setting,TypeInt); |
| | 352 | ASSERT_UITYPE(elements,TypeArray); |
| | 353 | |
| | 354 | int cols = cols_setting; |
| | 355 | int rows = rows_setting; |
| | 356 | |
| | 357 | if ( cols < 0 | rows < 0) |
| | 358 | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
| | 359 | |
| | 360 | if ( elements.getLength() != cols * rows ) |
| | 361 | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
| | 362 | |
| | 363 | if ( cols != 1 & rows !=1) |
| | 364 | ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); |
| | 365 | |
| | 366 | int len = rows * cols; |
| | 367 | vector.set_length ( len ); |
| | 368 | if ( len == 0 ) return; |
| | 369 | |
| | 370 | if ( !elements[0].isNumber()) |
| | 371 | ui_error("a vector element has to be a number", elements[0]); |
| | 372 | |
| | 373 | for ( int i=0; i<len; i++ ) |
| | 374 | vector(i) = elements[i]; |
| | 375 | return; |
| | 376 | } |
| | 377 | |
| | 378 | if ( root.isArray() ) |
| | 379 | { |
| | 380 | int len = root.getLength(); |
| | 381 | vector.set_length( len ); |
| | 382 | if ( len == 0 ) return; |
| | 383 | |
| | 384 | if ( !root[0].isNumber()) |
| | 385 | ui_error("a vector element has to be a number", root[0]); |
| | 386 | |
| | 387 | for ( int i=0; i < len; i++ ) |
| | 388 | vector(i) = root[i]; |
| | 389 | return; |
| | 390 | } |
| | 391 | |
| | 392 | ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); |
| 317 | | //! This methods tries to save an instance of type T (or some of its descendant types) |
| 318 | | //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name |
| 319 | | //! and connecti it to the passed Setting as a new child node. |
| 320 | | const Setting* UI::pointer_to_child_setting( const Setting &element, const int index ) |
| 321 | | { |
| 322 | | if( !element.isList()) |
| 323 | | return NULL; |
| 324 | | |
| 325 | | if( element.getLength() <= index ) |
| 326 | | return NULL; |
| 327 | | |
| 328 | | return &element[index]; |
| 329 | | } |
| 330 | | |
| 331 | | const Setting* UI::pointer_to_child_setting( const Setting &element, const string &name ) |
| 332 | | { |
| 333 | | if( !element.isGroup() ) |
| 334 | | return NULL; |
| 335 | | |
| 336 | | if( !element.exists( name ) ) |
| 337 | | return NULL; |
| 338 | | |
| 339 | | return &element[name]; |
| 340 | | } |
| 341 | | |
| 342 | | const Setting& UI::reference_to_child_setting( const Setting &element, const int index ) |
| 343 | | { |
| 344 | | if( !element.isList()) |
| 345 | | ui_error( "only TypeList elements could be indexed by integers", element ); |
| 346 | | |
| 347 | | if( element.getLength() <= index ) |
| 348 | | ui_error( "there is not any child with index " + index, element ); |
| 349 | | |
| 350 | | return element[index]; |
| 351 | | } |
| 352 | | |
| 353 | | const Setting& UI::reference_to_child_setting( const Setting &element, const string &name ) |
| 354 | | { |
| 355 | | ASSERT_UITYPE(element,TypeGroup); |
| 356 | | if( !element.exists( name ) ) |
| 357 | | ui_error( "there is not any child named """ + name, element ); |
| 358 | | return element[name]; |
| 359 | | } |
| 360 | | |
| 361 | | |
| 362 | | } |
| 363 | | |
| | 404 | //! This methods tries to save an instance of type T (or some of its descendant types) |
| | 405 | //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name |
| | 406 | //! and connecti it to the passed Setting as a new child node. |
| | 407 | const Setting& UI::to_child_setting( const Setting &element, const int index ) |
| | 408 | { |
| | 409 | if ( !element.isList()) |
| | 410 | ui_error( "only TypeList elements could be indexed by integers", element ); |
| | 411 | |
| | 412 | if ( element.getLength() <= index ) |
| | 413 | ui_error( "there is not any child with index " + index, element ); |
| | 414 | |
| | 415 | return element[index]; |
| | 416 | } |
| | 417 | |
| | 418 | const Setting& UI::to_child_setting( const Setting &element, const string &name ) |
| | 419 | { |
| | 420 | ASSERT_UITYPE(element,TypeGroup); |
| | 421 | if ( !element.exists( name ) ) |
| | 422 | ui_error( "there is not any child named """ + name, element ); |
| | 423 | return element[name]; |
| | 424 | } |
| | 425 | |
| | 426 | |
| | 427 | } |
| | 428 | |