1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #ifndef H2C_OBJECT_H
24 #define H2C_OBJECT_H
25 
26 #include "hydrogen/logger.h"
27 #include "hydrogen/config.h"
28 #include "hydrogen/globals.h"
29 
30 #include <unistd.h>
31 #include <iostream>
32 #include <QtCore>
33 
34 namespace H2Core {
35 
36 /**
37  * Base class.
38  */
39 class Object {
40 	public:
41 		/** destructor */
42 		~Object();
43 		/** copy constructor */
44 		Object( const Object& obj );
45 		/** constructor */
46 		Object( const char* class_name );
47 
class_name()48 		const char* class_name( ) const         { return __class_name; }        ///< return the class name
49 		/**
50 		 * enable/disable class instances counting
51 		 * \param flag the counting status to set
52 		 */
53 		static void set_count( bool flag );
count_active()54 		static bool count_active()              { return __count; }             ///< return true if class instances counting is enabled
objects_count()55 		static unsigned objects_count()         { return __objects_count; }     ///< return the number of objects
56 
57 		/**
58 		 * output the full objects map to a given ostream
59 		 * \param out the ostream to write to
60 		 */
61 		static void write_objects_map_to( std::ostream& out );
write_objects_map_to_cerr()62 		static void write_objects_map_to_cerr() { Object::write_objects_map_to( std::cerr ); }  ///< output objects map to stderr
63 
64 		/**
65 		 * must be called before any Object instantiation !
66 		 * \param logger the logger instance used to send messages to
67 		 * \param count should we count objects instances or not
68 		 */
69 		static int bootstrap( Logger* logger, bool count=false );
logger()70 		static Logger* logger()                 { return __logger; }            ///< return the logger instance
71 
72 	private:
73 		/**
74 		 * search for the class name within __objects_map, decrease class and global counts
75 		 * \param obj the object to be taken into account
76 		 */
77 		static void del_object( const Object* obj );
78 		/**
79 		 * search for the class name within __objects_map, create it if doesn't exists, increase class and global counts
80 		 * \param obj the object to be taken into account
81 		 * \param copy is it called from a copy constructor
82 		 */
83 		static void add_object( const Object* obj, bool copy );
84 
85 		/** an objects class map item type */
86 		typedef struct {
87 			unsigned constructed;
88 			unsigned destructed;
89 		} obj_cpt_t;
90 		/** the objects class map type */
91 		typedef std::map<const char*, obj_cpt_t> object_map_t;
92 
93 		const char* __class_name;               ///< the object class name
94 		static bool __count;                    ///< should we count class instances
95 		static unsigned __objects_count;        ///< total objects count
96 		static object_map_t __objects_map;      ///< objects classes and instances count structure
97 		static pthread_mutex_t __mutex;         ///< yeah this has to be thread safe
98 
99 	protected:
100 		static Logger* __logger;                ///< logger instance pointer
101 };
102 
103 // Object inherited class declaration macro
104 #define H2_OBJECT                                                       \
105 	public: static const char* class_name() { return __class_name; }    \
106 	private: static const char* __class_name;                           \
107 
108 // LOG MACROS
109 #define __LOG_METHOD(   lvl, msg )  if( __logger->should_log( (lvl) ) )                 { __logger->log( (lvl), class_name(), __FUNCTION__, msg ); }
110 #define __LOG_CLASS(    lvl, msg )  if( logger()->should_log( (lvl) ) )                 { logger()->log( (lvl), class_name(), __FUNCTION__, msg ); }
111 #define __LOG_OBJ(      lvl, msg )  if( __object->logger()->should_log( (lvl) ) )       { __object->logger()->log( (lvl), 0, __PRETTY_FUNCTION__, msg ); }
112 #define __LOG_STATIC(   lvl, msg )  if( H2Core::Logger::get_instance()->should_log( (lvl) ) )   { H2Core::Logger::get_instance()->log( (lvl), 0, __PRETTY_FUNCTION__, msg ); }
113 #define __LOG( logger,  lvl, msg )  if( (logger)->should_log( (lvl) ) )                 { (logger)->log( (lvl), 0, 0, msg ); }
114 
115 // Object instance method logging macros
116 #define DEBUGLOG(x)     __LOG_METHOD( H2Core::Logger::Debug,   (x) );
117 #define INFOLOG(x)      __LOG_METHOD( H2Core::Logger::Info,    (x) );
118 #define WARNINGLOG(x)   __LOG_METHOD( H2Core::Logger::Warning, (x) );
119 #define ERRORLOG(x)     __LOG_METHOD( H2Core::Logger::Error,   (x) );
120 
121 // Object class method logging macros
122 #define _DEBUGLOG(x)    __LOG_CLASS( H2Core::Logger::Debug,   (x) );
123 #define _INFOLOG(x)     __LOG_CLASS( H2Core::Logger::Info,    (x) );
124 #define _WARNINGLOG(x)  __LOG_CLASS( H2Core::Logger::Warning, (x) );
125 #define _ERRORLOG(x)    __LOG_CLASS( H2Core::Logger::Error,   (x) );
126 
127 // logging macros using an Object *__object ( thread :  Object* __object = ( Object* )param; )
128 #define __DEBUGLOG(x)   __LOG_OBJ( H2Core::Logger::Debug,      (x) );
129 #define __INFOLOG(x)    __LOG_OBJ( H2Core::Logger::Info,       (x) );
130 #define __WARNINGLOG(x) __LOG_OBJ( H2Core::Logger::Warning,    (x) );
131 #define __ERRORLOG(x)   __LOG_OBJ( H2Core::Logger::Error,      (x) );
132 
133 // logging macros using  ( thread :  Object* __object = ( Object* )param; )
134 #define ___DEBUGLOG(x)  __LOG_STATIC( H2Core::Logger::Debug,    (x) );
135 #define ___INFOLOG(x)   __LOG_STATIC( H2Core::Logger::Info,     (x) );
136 #define ___WARNINGLOG(x) __LOG_STATIC(H2Core::Logger::Warning,  (x) );
137 #define ___ERRORLOG(x)  __LOG_STATIC( H2Core::Logger::Error,    (x) );
138 
139 };
140 
141 #endif // H2C_OBJECT_H
142 
143 /* vim: set softtabstop=4 noexpandtab: */
144