logobject.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /******************************************************************************
  2. *
  3. * package: Log4Qt
  4. * file: logobject.h
  5. * created: September 2007
  6. * author: Martin Heinrich
  7. *
  8. *
  9. * changes: Sep 2008, Martin Heinrich:
  10. * - Replaced usage of q_atomic_increment and q_atomic_decrement
  11. * with QAtomicInt.
  12. * Feb 2009, Martin Heinrich
  13. * - Fixed a problem where the pParent parameter of the constructor
  14. * was not passed on to the QObject constructor
  15. *
  16. *
  17. * Copyright 2007 - 2009 Martin Heinrich
  18. *
  19. * Licensed under the Apache License, Version 2.0 (the "License");
  20. * you may not use this file except in compliance with the License.
  21. * You may obtain a copy of the License at
  22. *
  23. * http://www.apache.org/licenses/LICENSE-2.0
  24. *
  25. * Unless required by applicable law or agreed to in writing, software
  26. * distributed under the License is distributed on an "AS IS" BASIS,
  27. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  28. * See the License for the specific language governing permissions and
  29. * limitations under the License.
  30. *
  31. ******************************************************************************/
  32. #ifndef LOG4QT_LOGOBJECT_H
  33. #define LOG4QT_LOGOBJECT_H
  34. /******************************************************************************
  35. * Dependencies
  36. ******************************************************************************/
  37. #include <QtCore/QObject>
  38. #include "log4qt/helpers/classlogger.h"
  39. #if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
  40. # include <QtCore/QAtomicInt>
  41. # ifndef Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
  42. # warning "QAtomicInt reference counting is not native. The class Log4Qt::LogObject is not thread-safe."
  43. # endif
  44. #endif
  45. namespace Log4Qt
  46. {
  47. class Logger;
  48. /*!
  49. * \brief The class LogObject is the common base class for many classes
  50. * in the package.
  51. *
  52. * The class inherits QObject to allow its subclass to be accessed using
  53. * the Qt property system.
  54. *
  55. * LogObject objects provide a reference counter. A reference to the
  56. * object is established by calling retain() and freed by calling
  57. * release(). The object will delete itself when the reference counter
  58. * is decremented to 0.
  59. *
  60. * A class specific logger can be accessed over logger().
  61. *
  62. * The class also implements generic streaming to QDebug. Streaming an
  63. * object to QDebug will invoke debug() to create class specific output.
  64. *
  65. * \note All the functions declared in this class are thread-safe.
  66. *
  67. * \sa \ref Ownership "Object ownership",
  68. * LOG4QT_DECLARE_QCLASS_LOGGER
  69. */
  70. class LogObject : public QObject
  71. {
  72. Q_OBJECT
  73. public:
  74. /*!
  75. * Creates a LogObject which is a child of \a pObject.
  76. */
  77. LogObject(QObject *pObject = 0);
  78. /*!
  79. * Destroys the LogObject.
  80. */
  81. virtual ~LogObject();
  82. private:
  83. LogObject(const LogObject &rOther); // Not implemented
  84. LogObject &operator=(const LogObject &rOther); // Not implemented
  85. public:
  86. /*!
  87. * Returns the value of the reference counter.
  88. */
  89. int referenceCount() const;
  90. /*!
  91. * Decrements the reference count of the object. If the reference count
  92. * count reaches zero and the object does not have a parent the object
  93. * is deleted.
  94. */
  95. void release();
  96. /*!
  97. * Increments the reference count of the object.
  98. */
  99. void retain();
  100. protected:
  101. #ifndef QT_NO_DEBUG_STREAM
  102. /*!
  103. * Writes all object member variables to the given debug stream
  104. * \a rDebug and returns the stream.
  105. *
  106. * The member function is used by
  107. * QDebug operator<<(QDebug debug, const LogObject &rLogObject) to
  108. * generate class specific output.
  109. *
  110. * \sa QDebug operator<<(QDebug debug, const LogObject &rLogObject)
  111. */
  112. virtual QDebug debug(QDebug &rDebug) const = 0;
  113. // Needs to be friend to access internal data
  114. friend QDebug operator<<(QDebug debug,
  115. const LogObject &rLogObject);
  116. #endif // QT_NO_DEBUG_STREAM
  117. /*!
  118. * Returns a pointer to a Logger named after of the object.
  119. *
  120. * \sa Logger::logger(const char *pName)
  121. */
  122. Logger* logger() const;
  123. private:
  124. #if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
  125. volatile int mReferenceCount;
  126. #else
  127. mutable QAtomicInt mReferenceCount;
  128. #endif
  129. mutable ClassLogger mLog4QtClassLogger;
  130. };
  131. /**************************************************************************
  132. * Operators, Helper
  133. **************************************************************************/
  134. #ifndef QT_NO_DEBUG_STREAM
  135. /*!
  136. * \relates LogObject
  137. *
  138. * Writes all object member variables to the given debug stream \a debug
  139. * and returns the stream.
  140. *
  141. * To handle sub-classing the function uses the virtual member function
  142. * debug(). This allows each class to generate its own output.
  143. *
  144. * \sa QDebug, debug()
  145. */
  146. QDebug operator<<(QDebug debug,
  147. const LogObject &rLogObject);
  148. #endif
  149. /**************************************************************************
  150. * Inline
  151. **************************************************************************/
  152. inline LogObject::LogObject(QObject *pParent) :
  153. QObject(pParent),
  154. mReferenceCount()
  155. {}
  156. inline LogObject::~LogObject()
  157. {}
  158. inline int LogObject::referenceCount() const
  159. #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
  160. { return mReferenceCount; }
  161. #else
  162. { return mReferenceCount.loadAcquire(); }
  163. #endif
  164. inline void LogObject::release()
  165. #if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
  166. { if ((q_atomic_decrement(&mReferenceCount) == 0) && !parent())
  167. delete(this); }
  168. #else
  169. { if (!mReferenceCount.deref())
  170. delete(this); }
  171. #endif
  172. inline void LogObject::retain()
  173. #if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
  174. { q_atomic_increment(&mReferenceCount); }
  175. #else
  176. { mReferenceCount.ref(); }
  177. #endif
  178. inline Logger *LogObject::logger() const
  179. { return mLog4QtClassLogger.logger(this); }
  180. } // namespace Log4Qt
  181. // Q_DECLARE_TYPEINFO(Log4Qt::LogObject, Q_COMPLEX_TYPE); // Use default
  182. #endif // LOG4QT_LOGOBJECT_H