300 | | template<class T> class log_level_template : public log_level_base { |
301 | | //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger |
302 | | friend class logger; |
303 | | |
304 | | //! vector of log IDs - one element for each entry |
305 | | ivec ids; |
306 | | |
307 | | //! internal pointer to the logger to which this log_level is registered |
308 | | //! |
309 | | //! it is set to NULL at the beginning |
310 | | logger * registered_logger; |
311 | | |
312 | | public: |
313 | | //! default constructor |
314 | | log_level_template() { |
315 | | registered_logger = NULL; |
316 | | ids.set_size( T::log_level_names().length() ); |
| 300 | //! |
| 301 | //! This is only the first part of the whole declaration, which has to be however separated into |
| 302 | //! two different classes for allowing the compilation of source code. For more details |
| 303 | //! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const |
| 304 | //! method. For the reason the second one is templated, it was necessary to declare this whole class. |
| 305 | template<class T> class log_level_intermediate : public log_level_base { |
| 306 | public: |
| 307 | log_level_intermediate( ) { |
| 308 | ids.set_size( names().length() ); |
319 | | |
320 | | //! This method stores a vector to the proper place in registered logger |
321 | | void store( const enum T::log_level_enums log_level_enum, const vec &vect ) const |
322 | | { |
323 | | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); |
324 | | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); |
325 | | registered_logger->log_vector( ids( log_level_enum ), vect ); |
326 | | } |
327 | | |
328 | | //! This method stores a double to the proper place in registered logger |
329 | | void store( const enum T::log_level_enums log_level_enum, const double &dbl ) const |
330 | | { |
331 | | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); |
332 | | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); |
333 | | registered_logger->log_double( ids( log_level_enum ), dbl ); |
334 | | } |
335 | | |
336 | | //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger |
337 | | template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const |
338 | | { |
339 | | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); |
340 | | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); |
341 | | registered_logger->log_setting( ids( log_level_enum ), data); |
342 | | } |
343 | | |
367 | | |
368 | | /*! |
369 | | \def LOG_LEVEL(classname,...) |
370 | | \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class |
371 | | |
372 | | This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class. |
373 | | This macro defines a log_level instance which can be modified either directly or by the means of #UI class. |
374 | | |
375 | | One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through |
376 | | an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming |
377 | | any applications which are using this library. |
378 | | |
379 | | \todo Write a more detailed explanation including also examples |
380 | | |
381 | | \ref ui |
382 | | */ |
383 | | #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; } |
| 444 | |
| 445 | //! This class stores a details that will be logged to a logger |
| 446 | template<class T> class log_level_template : public log_level_intermediate<T> { |
| 447 | public: |
| 448 | //! This method stores a vector to the proper place in registered logger |
| 449 | void store( const enum T::log_level_enums log_level_enum, const vec &vect ) const |
| 450 | { |
| 451 | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); |
| 452 | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); |
| 453 | registered_logger->log_vector( ids( log_level_enum ), vect ); |
| 454 | } |
| 455 | |
| 456 | //! This method stores a double to the proper place in registered logger |
| 457 | void store( const enum T::log_level_enums log_level_enum, const double &dbl ) const |
| 458 | { |
| 459 | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); |
| 460 | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); |
| 461 | registered_logger->log_double( ids( log_level_enum ), dbl ); |
| 462 | } |
| 463 | |
| 464 | //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger |
| 465 | //! |
| 466 | //! If this method was not templated, we could store whole body of this class in cpp file without explicitly touching registered_logger->log_setting(...) here. |
| 467 | //! (it would not be straightforward, though, still there are some enums which had to be converted into integers but it could be done without loosing type control) |
| 468 | //! This way, it would not be necessary to declare log_level_intermediate<T> class and we could declare log_level_template<T> |
| 469 | //! before the log_level class itself with a mere foroward declaration of log_level. In our case, however, touching of registered_logger->log_setting |
| 470 | //! implies that friend declaration is not enough and we are lost in a circle. And just by cutting this circle we obtains log_level_intermediate<T> class. |
| 471 | //! Howg.) |
| 472 | template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const |
| 473 | { |
| 474 | bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); |
| 475 | bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); |
| 476 | registered_logger->log_setting( ids( log_level_enum ), data); |
| 477 | } |
| 478 | }; |
| 479 | |
| 480 | /*! |
| 481 | \def LOG_LEVEL(classname,...) |
| 482 | \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class |
| 483 | |
| 484 | This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class. |
| 485 | This macro defines a log_level instance which can be modified either directly or by the means of #UI class. |
| 486 | |
| 487 | One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through |
| 488 | an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming |
| 489 | any applications which are using this library. |
| 490 | |
| 491 | \todo Write a more detailed explanation including also examples |
| 492 | |
| 493 | \ref ui |
| 494 | */ |
| 495 | #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; } |
| 496 | |