117 | | template<class T> static void to_setting( const T &instance, Setting &root ) |
118 | | { |
119 | | const string &class_name = Particular_UI<T>::ui.class_name; |
120 | | |
121 | | // add attribute "class" |
122 | | Setting &type = root.add( "class", Setting::TypeString ); |
123 | | type = class_name; |
124 | | |
125 | | try |
126 | | { |
127 | | // instance disassembling |
128 | | instance.to_setting( root ); |
129 | | } |
130 | | catch(SettingException xcptn) |
131 | | { |
132 | | it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); |
133 | | } |
134 | | } |
135 | | |
136 | | template<class T> static T* from_setting( const Setting &element ) |
| 143 | static const Setting* pointer_to_child_setting( const Setting &element, const int index ); |
| 144 | |
| 145 | static const Setting* pointer_to_child_setting( const Setting &element, const string &name ); |
| 146 | |
| 147 | static const Setting& reference_to_child_setting( const Setting &element, const int index ); |
| 148 | |
| 149 | static const Setting& reference_to_child_setting( const Setting &element, const string &name ); |
| 150 | |
| 151 | |
| 152 | //! This methods tries to build a new double matrix |
| 153 | static void from_setting( mat& matrix, const Setting &element ); |
| 154 | //! This methods tries to build a new integer vector |
| 155 | static void from_setting( ivec &vec, const Setting &element ); |
| 156 | // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander.. |
| 157 | static void from_setting( string &str, const Setting &element ); |
| 158 | //! This methods tries to build a new templated array |
| 159 | |
| 160 | template<class T> static void from_setting( T* &instance, const Setting &element ) |
178 | | // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. |
179 | | // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny |
180 | | class Link_Expander |
181 | | { |
182 | | private: |
183 | | UI_File *file; |
184 | | const Setting *result; |
185 | | |
186 | | public: |
187 | | |
188 | | Link_Expander( const Setting &potential_link ) |
189 | | { |
190 | | file = NULL; |
191 | | result = &potential_link; |
192 | | |
193 | | if( potential_link.getType() != Setting::TypeString ) |
194 | | return; |
195 | | |
196 | | string link = (string) potential_link; |
197 | | size_t aerobase = link.find('@'); |
198 | | if( aerobase != string::npos ) |
199 | | { |
200 | | string file_name = link.substr( aerobase + 1, link.length() ); |
201 | | file = new UI_File( file_name ); |
202 | | file->load(); |
203 | | result = &(Setting&)(*file); |
204 | | link = link.substr( 0, aerobase ); |
205 | | } |
206 | | else |
207 | | while ( !result->isRoot() ) |
208 | | result = &result->getParent(); |
209 | | |
210 | | if( !result->exists( link ) ) |
211 | | ui_error( "linked Setting was not found", potential_link ); |
212 | | |
213 | | result = &(*result)[link]; |
214 | | } |
215 | | |
216 | | ~Link_Expander() |
217 | | { |
218 | | if( file ) delete file; |
219 | | } |
220 | | |
221 | | const Setting& root() const |
222 | | { |
223 | | return *result; |
224 | | } |
225 | | }; |
226 | | |
227 | | static const Setting* to_child_setting( const Setting &element, const int index ) |
228 | | { |
229 | | if( !element.isAggregate()) |
230 | | return NULL; |
231 | | |
232 | | if( element.getLength() <= index ) |
233 | | return NULL; |
234 | | |
235 | | return &element[index]; |
236 | | } |
237 | | |
238 | | static const Setting* to_child_setting( const Setting &element, const string &name ) |
239 | | { |
240 | | if( !element.isGroup() ) |
241 | | return NULL; |
242 | | |
243 | | if( !element.exists( name ) ) |
244 | | return NULL; |
245 | | |
246 | | return &element[name]; |
247 | | } |
248 | | |
249 | | static Setting& to_child_setting( Setting &element, const int index ) |
250 | | { |
251 | | if( !element.isAggregate()) |
252 | | ui_error( "it is not possible to index non-agregate element by integers", element ); |
253 | | |
254 | | if( element.getLength() <= index ) |
255 | | ui_error( "there is not any child with index " + index, element ); |
256 | | |
257 | | return element[index]; |
258 | | } |
259 | | |
260 | | static Setting& to_child_setting( Setting &element, const string &name ) |
261 | | { |
262 | | ASSERT_UITYPE(element,TypeGroup); |
263 | | if( !element.exists( name ) ) |
264 | | ui_error( "there is not any child named """ + name, element ); |
265 | | return element[name]; |
266 | | } |
267 | | |
268 | | //! This methods tries to build a new double matrix |
269 | | static void from_setting( mat& matrix, const Setting &element ) |
| 198 | //! This methods tries to build a new templated array , |
| 199 | // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme |
| 200 | template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element ) |
274 | | if( root.isNumber() ) |
275 | | { |
276 | | matrix.set_size( 1, 1 ); |
277 | | matrix(0,0) = root; |
278 | | return; |
279 | | } |
280 | | |
281 | | if( root.isList() ) |
282 | | { |
283 | | if( root.getLength() != 3 ) |
284 | | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
285 | | |
286 | | Setting &cols_setting = root[0]; |
287 | | Setting &rows_setting = root[1]; |
288 | | Setting &elements = root[2]; |
289 | | |
290 | | ASSERT_UITYPE(cols_setting,TypeInt); |
291 | | ASSERT_UITYPE(rows_setting,TypeInt); |
292 | | ASSERT_UITYPE(elements,TypeArray); |
293 | | |
294 | | int cols = cols_setting; |
295 | | int rows = rows_setting; |
296 | | |
297 | | if( cols < 0 | rows < 0 ) |
298 | | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
299 | | |
300 | | if( elements.getLength() != cols * rows ) |
301 | | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
302 | | |
303 | | matrix.set_size( rows, cols ); |
304 | | |
305 | | if( cols == 0 || rows == 0 ) |
306 | | return; |
307 | | |
308 | | if( !elements[0].isNumber() ) |
309 | | ui_error( "matrix elements have to be numbers", elements[0] ); |
310 | | |
311 | | // build matrix row-wise |
312 | | int k = 0; |
313 | | for( int i=0;i<rows;i++ ) |
314 | | for( int j=0; j<cols; j++) |
315 | | matrix(i,j) = elements[k++]; |
316 | | return; |
317 | | } |
318 | | |
319 | | ui_error( "only numeric types or TypeList are supported as matrix values", root ); |
320 | | } |
321 | | |
322 | | //! This methods tries to save a double matrix |
323 | | static void to_setting( const mat &matrix, Setting &root ) |
324 | | { |
325 | | Setting &cols = root.add( Setting::TypeInt ); |
326 | | cols = matrix.cols(); |
327 | | |
328 | | Setting &rows = root.add( Setting::TypeInt ); |
329 | | rows = matrix.rows(); |
330 | | |
331 | | Setting &elements = root.add( Setting::TypeArray ); |
332 | | |
333 | | // build matrix row-wise |
334 | | for( int i=0; i<matrix.rows(); i++ ) |
335 | | for( int j=0; j<matrix.cols(); j++) |
336 | | { |
337 | | Setting &newField = elements.add(Setting::TypeFloat); |
338 | | newField = matrix(i,j); |
339 | | } |
340 | | } |
341 | | |
342 | | //! This methods tries to build a new integer vector |
343 | | static void from_setting( ivec &vec, const Setting &element ) |
344 | | { |
345 | | const Link_Expander link_expander( element ); |
346 | | const Setting &root = link_expander.root(); |
347 | | |
348 | | if( root.isNumber() ) |
349 | | { |
350 | | ASSERT_UITYPE(root,TypeInt); |
351 | | vec.set_length( 1 ); |
352 | | vec(0) = root; |
353 | | return; |
354 | | } |
355 | | |
356 | | if( root.isList() ) |
357 | | { |
358 | | if( root.getLength() != 3 ) |
359 | | ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); |
360 | | |
361 | | Setting &cols_setting = root[0]; |
362 | | Setting &rows_setting = root[1]; |
363 | | Setting &elements = root[2]; |
364 | | |
365 | | ASSERT_UITYPE(cols_setting,TypeInt); |
366 | | ASSERT_UITYPE(rows_setting,TypeInt); |
367 | | ASSERT_UITYPE(elements,TypeArray); |
368 | | |
369 | | int cols = cols_setting; |
370 | | int rows = rows_setting; |
371 | | |
372 | | if( cols < 0 | rows < 0) |
373 | | ui_error( "the dimensions of a matrix has to be non-negative", root ); |
374 | | |
375 | | if( elements.getLength() != cols * rows ) |
376 | | ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); |
377 | | |
378 | | if( cols != 1 & rows !=1) |
379 | | ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); |
380 | | |
381 | | int len = rows * cols; |
382 | | vec.set_length ( len ); |
383 | | if( len == 0 ) return; |
384 | | |
385 | | ASSERT_UITYPE(elements[0],TypeInt); |
386 | | for( int i=0; i<len; i++ ) |
387 | | vec(i) = elements[i]; |
388 | | return; |
389 | | } |
390 | | |
391 | | if( root.isArray() ) |
392 | | { |
393 | | int len = root.getLength(); |
394 | | vec.set_length( len ); |
395 | | if( len == 0 ) return; |
396 | | |
397 | | ASSERT_UITYPE(root[0],TypeInt); |
398 | | for( int i=0; i < len; i++ ) |
399 | | vec(i) = root[i]; |
400 | | return; |
401 | | } |
402 | | |
403 | | ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); |
404 | | } |
405 | | |
406 | | //! This methods tries to save an integer vector |
407 | | static void to_setting( const ivec &vec, Setting &root ) |
408 | | { |
409 | | for( int i=0; i<vec.length(); i++ ) |
410 | | { |
411 | | Setting &newField = root.add(Setting::TypeInt); |
412 | | newField = vec(i); |
413 | | } |
414 | | } |
415 | | |
416 | | //! This methods tries to build a new array of strings |
417 | | static void from_setting( Array<string> &string_array, const Setting &element ) |
418 | | { |
419 | | const Link_Expander link_expander( element ); |
420 | | const Setting &root = link_expander.root(); |
421 | | |
422 | | if( root.getType() == Setting::TypeString ) |
423 | | { |
424 | | string_array.set_length( 1 ); |
425 | | string_array(0) = (string)root; |
426 | | return; |
427 | | } |
428 | | |
429 | | if( root.isArray() ) |
430 | | { |
431 | | int len = root.getLength(); |
432 | | string_array.set_length( len ); |
433 | | if( len == 0 ) return; |
434 | | |
435 | | ASSERT_UITYPE(root[0],TypeString); |
436 | | for( int i=0; i < len; i++ ) |
437 | | string_array(i) = (string)root[i]; |
438 | | return; |
439 | | } |
440 | | |
441 | | ui_error( "only TypeString or TypeArray are supported as vector of string values", root ); |
442 | | } |
443 | | |
444 | | //! This methods tries to save an array of strings |
445 | | static void to_setting( const Array<string> &string_array, Setting &root ) |
446 | | { |
447 | | for( int i=0; i<string_array.length(); i++ ) |
448 | | { |
449 | | Setting &newField = root.add(Setting::TypeString); |
450 | | newField = string_array(i); |
451 | | } |
| 205 | ASSERT_UITYPE(root,TypeList); |
| 206 | |
| 207 | int len = root.getLength(); |
| 208 | array_to_load.set_length( len ); |
| 209 | if( len == 0 ) return; |
| 210 | |
| 211 | for( int i=0; i < len; i++ ) |
| 212 | from_setting( array_to_load(i), root[i] ); |
486 | | return from_setting<T>( to_child_setting( element, name ) ); |
487 | | } |
488 | | |
489 | | //! This methods tries to save an instance of type T (or some of its descendant types) |
490 | | //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name |
491 | | //! and connecti it to the passed Setting as a new child node. |
492 | | template<class T> static void save( T &instance, Setting &element, const string &name = "") |
| 248 | T* instance; |
| 249 | from_setting<T>( instance, reference_to_child_setting( element, name ) ); |
| 250 | return instance; |
| 251 | } |
| 252 | |
| 253 | //! This methods tries to build a new double matrix |
| 254 | template<class T> static bool get( T &instance, const Setting &element, const string &name ) |
| 255 | { |
| 256 | const Setting *root = pointer_to_child_setting( element, name ); |
| 257 | if( !root ) return false; |
| 258 | from_setting( instance, *root ); |
| 259 | return true; |
| 260 | } |
| 261 | |
| 262 | //! This methods tries to build a new double matrix |
| 263 | template<class T> static bool get( T &instance, const Setting &element, const int index ) |
| 264 | { |
| 265 | const Setting *root = pointer_to_child_setting( element, index ); |
| 266 | if( !root ) return false; |
| 267 | from_setting( instance, *root ); |
| 268 | return true; |
| 269 | } |
| 270 | |
| 271 | //! This methods tries to build a new double matrix |
| 272 | template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const string &name ) |
| 273 | { |
| 274 | const Setting *root = pointer_to_child_setting( element, name ); |
| 275 | if( !root ) return false; |
| 276 | from_setting( array_to_load, *root ); |
| 277 | return true; |
| 278 | } |
| 279 | |
| 280 | //! This methods tries to build a new double matrix |
| 281 | template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const int index ) |
| 282 | { |
| 283 | const Setting *root = pointer_to_child_setting( element, index ); |
| 284 | if( !root ) return false; |
| 285 | from_setting( array_to_load, *root ); |
| 286 | return true; |
| 287 | } |
| 288 | |
| 289 | template< class T> static void save( const T * const instance, Setting &element, const string &name = "") |
496 | | to_setting( instance, root ); |
497 | | } |
498 | | |
499 | | //! This methods tries to build a new double matrix |
500 | | static bool get( mat& matrix, const Setting &element, const string &name ) |
501 | | { |
502 | | const Setting *root = to_child_setting( element, name ); |
503 | | if( !root ) return false; |
504 | | from_setting( matrix, *root ); |
505 | | return true; |
506 | | } |
507 | | |
508 | | //! This methods tries to build a new double matrix |
509 | | static bool get( mat& matrix, const Setting &element, const int index ) |
510 | | { |
511 | | const Setting *root = to_child_setting( element, index ); |
512 | | if( !root ) return false; |
513 | | from_setting( matrix, *root ); |
514 | | return true; |
515 | | } |
| 293 | |
| 294 | const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) ); |
| 295 | |
| 296 | // add attribute "class" |
| 297 | Setting &type = root.add( "class", Setting::TypeString ); |
| 298 | type = class_name; |
| 299 | |
| 300 | try |
| 301 | { |
| 302 | instance->to_setting( root ); |
| 303 | } |
| 304 | catch(SettingException xcptn) |
| 305 | { |
| 306 | it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | //! This methods tries to save a double vec |
| 311 | template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" ) |
| 312 | { |
| 313 | ASSERT_UITYPE(element,TypeGroup); |
| 314 | Setting &list = (name == "") ? element.add( Setting::TypeList ) |
| 315 | : element.add( name, Setting::TypeList ); |
| 316 | for( int i=0; i<array_to_save.length(); i++ ) |
| 317 | save( array_to_save(i), list ); |
| 318 | } |
| 319 | |
518 | | static void save( mat &matrix, Setting &element, const string &name = "" ) |
519 | | { |
520 | | Setting &root = (name == "") ? element.add( Setting::TypeList ) |
521 | | : element.add( name, Setting::TypeList ); |
522 | | to_setting( matrix, root ); |
523 | | } |
524 | | |
525 | | //! This methods tries to build a new double vec |
526 | | static bool get( ivec& vec, const Setting &element, const string &name ) |
527 | | { |
528 | | const Setting *root = to_child_setting( element, name ); |
529 | | if( !root ) return false; |
530 | | from_setting( vec, *root ); |
531 | | return true; |
532 | | } |
533 | | |
534 | | //! This methods tries to build a new double vec |
535 | | static bool get( ivec& vec, const Setting &element, const int index ) |
536 | | { |
537 | | const Setting *root = to_child_setting( element, index ); |
538 | | if( !root ) return false; |
539 | | from_setting( vec, *root ); |
540 | | return true; |
541 | | } |
| 322 | static void save( const mat &matrix, Setting &element, const string &name = "" ); |
544 | | static void save( ivec &vec, Setting &element, const string &name = "" ) |
545 | | { |
546 | | Setting &root = (name == "") ? element.add( Setting::TypeArray ) |
547 | | : element.add( name, Setting::TypeArray ); |
548 | | to_setting( vec, root ); |
549 | | } |
550 | | |
551 | | //! This methods tries to build a new double string_array |
552 | | static bool get( Array<string> &string_array, const Setting &element, const string &name ) |
553 | | { |
554 | | const Setting *root = to_child_setting( element, name ); |
555 | | if( !root ) return false; |
556 | | from_setting( string_array, *root ); |
557 | | return true; |
558 | | } |
559 | | |
560 | | //! This methods tries to build a new double string_array |
561 | | static bool get( Array<string> &string_array, const Setting &element, const int index ) |
562 | | { |
563 | | const Setting *root = to_child_setting( element, index ); |
564 | | if( !root ) return false; |
565 | | from_setting( string_array, *root ); |
566 | | return true; |
567 | | } |
568 | | |
569 | | //! This methods tries to save a double string_array |
570 | | static void save( Array<string> &string_array, Setting &element, const string &name = "" ) |
571 | | { |
572 | | Setting &root = (name == "") ? element.add( Setting::TypeArray ) |
573 | | : element.add( name, Setting::TypeArray ); |
574 | | to_setting( string_array, root ); |
575 | | } |
| 325 | static void save( const ivec &vec, Setting &element, const string &name = "" ); |
| 326 | |
| 327 | private: |
| 328 | //! This methods tries to save a double vec |
| 329 | static void save( const string &str, Setting &element); |
| 330 | |