hydrogen 1.2.6
Object.h
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#ifndef H2C_OBJECT_H
24#define H2C_OBJECT_H
25
26#include "core/Logger.h"
27#include <core/config.h>
28#include "core/Globals.h"
29
30#ifndef _WIN32
31#include <sys/time.h>
32#endif
33#include <unistd.h>
34#include <iostream>
35#include <atomic>
36#include <map>
37#include <QtCore>
38#include <QDebug>
39
40namespace H2Core {
41
43typedef struct atomic_obj_cpt_t {
44 std::atomic<int> constructed;
45 std::atomic<int> destructed;
48
49typedef struct {
52} obj_cpt_t;
53
55typedef std::map<const char*, obj_cpt_t> object_map_t;
56typedef std::map<const char*, const atomic_obj_cpt_t*> object_internal_map_t;
57
62class Base {
63 public:
64 Base() {
65#ifdef H2CORE_HAVE_DEBUG
66 if ( __count ) {
68 }
69#endif
70 }
71 Base(const Base &other) {
72#ifdef H2CORE_HAVE_DEBUG
73 if ( __count ) {
75 }
76#endif
77 }
78 static const char *_class_name() { return "Object"; }
79 virtual const char* class_name() const { return _class_name(); }
84 static void set_count( bool flag );
85 static bool count_active() { return __count; }
86 static int objects_count() { return __objects_count; }
87
94 static void write_objects_map_to( std::ostream& out, object_map_t* map = nullptr );
96
102 static int bootstrap( Logger* logger, bool count=false );
103 static Logger* logger() { return __logger; }
104
111 static QString base_clock( const QString& sMsg );
112 static QString base_clock_in( const QString& sMsg );
113
115 static int getAliveObjectCount();
117
118 static object_map_t getObjectMap();
124 static void printObjectMapDiff( object_map_t map );
127 static QString sPrintIndention;
128
137 virtual QString toQString( const QString& sPrefix = "", bool bShort = true ) const;
143 void Print( bool bShort = true ) const;
144
146 void logBacktrace() const;
147 protected:
149#ifdef H2CORE_HAVE_DEBUG
150 if ( __count ) {
152 }
153#endif
154 }
155 static bool __count;
156 static Logger * __logger;
157 static bool bLogColors;
158 static void registerClass(const char *name, const atomic_obj_cpt_t *counters);
159 static timeval __last_clock;
160
161 private:
162 static std::atomic<int> __objects_count;
164 static pthread_mutex_t __mutex;
165};
166
167std::ostream& operator<<( std::ostream& os, const Base& object );
168std::ostream& operator<<( std::ostream& os, const Base* object );
169
170
171inline QDebug operator<<( QDebug d, Base *o ) {
172 d << ( o ? o->toQString( "", true ) : "(nullptr)" );
173 return d;
174}
175
176inline QDebug operator<<( QDebug d, std::shared_ptr<Base> o ) {
177 d << ( o ? o->toQString( "", true ) : "(nullptr)" );
178 return d;
179}
180
181template<typename T> class Object: public Base {
182 public:
184#ifdef H2CORE_HAVE_DEBUG
185 if ( __logger && __logger->should_log( Logger::Constructors ) ) {
186 __logger->log( Logger::Debug, nullptr, T::_class_name(), "Constructor" );
187 }
188 if ( __count ) {
189 if ( ! counters.constructed ) {
190 registerClass(T::_class_name(), &counters);
191 }
192 ++counters.constructed;
193 }
194#endif
195 }
196 Object(const Object<T> &other) {
197#ifdef H2CORE_HAVE_DEBUG
198 if( __logger && __logger->should_log( Logger::Constructors ) ) {
199 __logger->log( Logger::Debug, nullptr, T::_class_name(), "Copy Constructor" );
200 }
201 if ( __count ) {
202 if ( ! counters.constructed ) {
203 registerClass(T::_class_name(), &counters);
204 }
205 ++counters.constructed;
206 }
207#endif
208 }
209 protected:
211#ifdef H2CORE_HAVE_DEBUG
212 if( __logger && __logger->should_log( Logger::Constructors ) ) {
213 __logger->log( Logger::Debug, nullptr, T::_class_name(), "Destructor" );
214 }
215 if ( __count ) {
216 ++counters.destructed;
217 }
218#endif
219 }
220 private:
222};
224
225
226// Object inherited class declaration macro
227#define H2_OBJECT(name) \
228 public: static const char* _class_name() { return #name; } \
229 const char* class_name() const override { return _class_name(); }
230
231// LOG MACROS
232#define __LOG_METHOD( lvl, msg ) if( __logger->should_log( (lvl) ) ) { __logger->log( (lvl), _class_name(), __FUNCTION__, QString( "%1" ).arg( msg ) ); }
233#define __LOG_CLASS( lvl, msg ) if( logger()->should_log( (lvl) ) ) { logger()->log( (lvl), _class_name(), __FUNCTION__, QString( "%1" ).arg( msg ) ); }
234#define __LOG_OBJ( lvl, msg ) if( __object->logger()->should_log( (lvl) ) ) { __object->logger()->log( (lvl), 0, __PRETTY_FUNCTION__, QString( "%1" ).arg( msg ) ); }
235#define __LOG_STATIC( lvl, msg ) if( H2Core::Logger::get_instance()->should_log( (lvl) ) ) { H2Core::Logger::get_instance()->log( (lvl), 0, __PRETTY_FUNCTION__, QString( "%1" ).arg( msg ) ); }
236#define __LOG( logger, lvl, msg ) if( (logger)->should_log( (lvl) ) ) { (logger)->log( (lvl), 0, 0, QString( "%1" ).arg( msg ) ); }
237
238// Object instance method logging macros
239#define DEBUGLOG(x) __LOG_METHOD( H2Core::Logger::Debug, (x) );
240#define INFOLOG(x) __LOG_METHOD( H2Core::Logger::Info, (x) );
241#define WARNINGLOG(x) __LOG_METHOD( H2Core::Logger::Warning, (x) );
242#define ERRORLOG(x) __LOG_METHOD( H2Core::Logger::Error, (x) );
243
244// Object class method logging macros
245#define _DEBUGLOG(x) __LOG_CLASS( H2Core::Logger::Debug, (x) );
246#define _INFOLOG(x) __LOG_CLASS( H2Core::Logger::Info, (x) );
247#define _WARNINGLOG(x) __LOG_CLASS( H2Core::Logger::Warning, (x) );
248#define _ERRORLOG(x) __LOG_CLASS( H2Core::Logger::Error, (x) );
249
250// logging macros using an Base *__object ( thread : Base * __object = ( Base * )param; )
251#define __DEBUGLOG(x) __LOG_OBJ( H2Core::Logger::Debug, (x) );
252#define __INFOLOG(x) __LOG_OBJ( H2Core::Logger::Info, (x) );
253#define __WARNINGLOG(x) __LOG_OBJ( H2Core::Logger::Warning, (x) );
254#define __ERRORLOG(x) __LOG_OBJ( H2Core::Logger::Error, (x) );
255
256// logging macros using ( thread : Base * __object = ( Base * )param; )
257#define ___DEBUGLOG(x) __LOG_STATIC( H2Core::Logger::Debug, (x) );
258#define ___INFOLOG(x) __LOG_STATIC( H2Core::Logger::Info, (x) );
259#define ___WARNINGLOG(x) __LOG_STATIC(H2Core::Logger::Warning, (x) );
260#define ___ERRORLOG(x) __LOG_STATIC( H2Core::Logger::Error, (x) );
261
262// Can be called without or with a single argument
263#define CLOCK(...) __LOG_METHOD( H2Core::Logger::Debug, base_clock( QString( "%1" ).arg( #__VA_ARGS__ ) ) );
264#define CLOCKIN(...) __LOG_METHOD( H2Core::Logger::Debug, base_clock_in( QString( "%1" ).arg( #__VA_ARGS__ ) ) );
265
266};
267
268#endif // H2C_OBJECT_H
269
270/* vim: set softtabstop=4 noexpandtab: */
Base class.
Definition Object.h:62
static std::atomic< int > __objects_count
total objects count
Definition Object.h:162
static void write_objects_map_to_cerr()
output objects map to stderr
Definition Object.h:95
static void registerClass(const char *name, const atomic_obj_cpt_t *counters)
Definition Object.cpp:255
static Logger * logger()
return the logger instance
Definition Object.h:103
virtual QString toQString(const QString &sPrefix="", bool bShort=true) const
Formatted string version for debugging purposes.
Definition Object.cpp:186
Base(const Base &other)
Definition Object.h:71
static QString base_clock_in(const QString &sMsg)
Definition Object.cpp:209
static object_map_t getObjectMap()
Definition Object.cpp:154
static pthread_mutex_t __mutex
yeah this has to be thread safe
Definition Object.h:164
static bool count_active()
Definition Object.h:85
static QString base_clock(const QString &sMsg)
Measures the current time and stores it in __last_clock.
Definition Object.cpp:223
static int getAliveObjectCount()
Definition Object.cpp:139
void Print(bool bShort=true) const
Prints content of toQString() via DEBUGLOG.
Definition Object.cpp:191
void logBacktrace() const
Print the current stack at point into the debug log.
Definition Object.cpp:195
static bool __count
should we count class instances
Definition Object.h:155
static bool bLogColors
Definition Object.h:157
static int objects_count()
Definition Object.h:86
static void set_count(bool flag)
enable/disable class instances counting
Definition Object.cpp:79
static int bootstrap(Logger *logger, bool count=false)
must be called before any Object instantiation !
Definition Object.cpp:66
static timeval __last_clock
Definition Object.h:159
static object_internal_map_t __objects_map
objects classes and instances count structure
Definition Object.h:163
static QString sPrintIndention
String used to format the debugging string output of some core classes.
Definition Object.h:127
static void write_objects_map_to(std::ostream &out, object_map_t *map=nullptr)
output the full objects map to a given ostream
Definition Object.cpp:89
virtual const char * class_name() const
Definition Object.h:79
static Logger * __logger
Definition Object.h:156
static void printObjectMapDiff(object_map_t map)
Creates the difference between a snapshot of the object map and its current state and prints it to st...
Definition Object.cpp:167
static const char * _class_name()
return the class name
Definition Object.h:78
Class for writing logs to the console.
Definition Logger.h:41
Object(const Object< T > &other)
Definition Object.h:196
static atomic_obj_cpt_t counters
Definition Object.h:221
std::map< const char *, const atomic_obj_cpt_t * > object_internal_map_t
Definition Object.h:56
struct H2Core::atomic_obj_cpt_t atomic_obj_cpt_t
an objects class map item type
std::ostream & operator<<(std::ostream &os, const Base &object)
Definition Object.cpp:247
std::map< const char *, obj_cpt_t > object_map_t
the objects class map types
Definition Object.h:55
atomic_obj_cpt_t Object< T >::counters
Definition Object.h:223
an objects class map item type
Definition Object.h:43
std::atomic< int > constructed
Definition Object.h:44
std::atomic< int > destructed
Definition Object.h:45