kodi
AddonClass.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
18 //#define LOG_LIFECYCLE_EVENTS
19 
30 //#define XBMC_ADDON_DEBUG_MEMORY
31 
32 #include "AddonString.h"
33 
34 #include <mutex>
35 #ifdef XBMC_ADDON_DEBUG_MEMORY
36 #include "utils/log.h"
37 #endif
38 #include "AddonUtils.h"
39 
40 #include <atomic>
41 #include <typeindex>
42 
43 namespace XBMCAddon
44 {
45  class LanguageHook;
46 
57  class AddonClass : public CCriticalSection
58  {
59  private:
60  mutable std::atomic<long> refs;
61  bool m_isDeallocating = false;
62 
63  // no copying
64  inline AddonClass(const AddonClass&) = delete;
65 
66 #ifdef XBMC_ADDON_DEBUG_MEMORY
67  bool isDeleted;
68 #endif
69 
70  protected:
71  LanguageHook* languageHook;
72 
82  virtual void deallocating()
83  {
84  std::unique_lock<CCriticalSection> lock(*this);
85  m_isDeallocating = true;
86  }
87 
92  static short getNextClassIndex();
93 
94  public:
95  AddonClass();
96  virtual ~AddonClass();
97 
98  inline const char* GetClassname() const { return typeid(*this).name(); }
99  inline LanguageHook* GetLanguageHook() { return languageHook; }
100 
106  bool isDeallocating() { XBMC_TRACE; return m_isDeallocating; }
107 
108  static short getNumAddonClasses();
109 
110 #ifdef XBMC_ADDON_DEBUG_MEMORY
111  virtual
112 #else
113  inline
114 #endif
115  void Release() const
116 #ifndef XBMC_ADDON_DEBUG_MEMORY
117  {
118  long ct = --refs;
119 #ifdef LOG_LIFECYCLE_EVENTS
120  CLog::Log(LOGDEBUG, "NEWADDON REFCNT decrementing to {} on {} 0x{:x}", ct, GetClassname(),
121  (long)(((void*)this)));
122 #endif
123  if(ct == 0)
124  delete this;
125  }
126 #else
127  ;
128 #endif
129 
130 
131 #ifdef XBMC_ADDON_DEBUG_MEMORY
132  virtual
133 #else
134  inline
135 #endif
136  void Acquire() const
137 #ifndef XBMC_ADDON_DEBUG_MEMORY
138  {
139 #ifdef LOG_LIFECYCLE_EVENTS
140  CLog::Log(LOGDEBUG, "NEWADDON REFCNT incrementing to {} on {} 0x{:x}", ++refs, GetClassname(),
141  (long)(((void*)this)));
142 #else
143  ++refs;
144 #endif
145  }
146 #else
147  ;
148 #endif
149 
150 #define refcheck
151 
154  template <class T> class Ref
155  {
156  T * ac;
157  public:
158  inline Ref() : ac(NULL) {}
159  inline Ref(const T* _ac) : ac(const_cast<T*>(_ac)) { if (ac) ac->Acquire(); refcheck; }
160 
161  // copy semantics
162  inline Ref(Ref<T> const & oref) : ac(const_cast<T*>(oref.get())) { if (ac) ac->Acquire(); refcheck; }
163  template<class O> inline Ref(Ref<O> const & oref) : ac(static_cast<T*>(oref.get())) { if (ac) ac->Acquire(); refcheck; }
164 
182  inline Ref<T>& operator=(Ref<T> const & oref)
183  { T* tmp = ac; ac = const_cast<T*>(oref.get()); if (ac) ac->Acquire(); if (tmp) tmp->Release(); refcheck; return *this; }
184 
185  inline T* operator->() const { refcheck; return ac; }
186 
190  inline operator T*() const { refcheck; return ac; }
191  inline T* get() const { refcheck; return ac; }
192  inline T& getRef() const { refcheck; return *ac; }
193 
194  inline ~Ref() { refcheck; if (ac) ac->Release(); }
195  inline bool isNull() const { refcheck; return ac == NULL; }
196  inline bool isNotNull() const { refcheck; return ac != NULL; }
197  inline bool isSet() const { refcheck; return ac != NULL; }
198  inline bool operator!() const { refcheck; return ac == NULL; }
199  inline bool operator==(const AddonClass::Ref<T>& oref) const { refcheck; return ac == oref.ac; }
200  inline bool operator<(const AddonClass::Ref<T>& oref) const { refcheck; return ac < oref.ac; } // std::set semantics
201 
202  // This is there only for boost compatibility
203  template<class O> inline void reset(Ref<O> const & oref) { refcheck; (*this) = static_cast<T*>(oref.get()); refcheck; }
204  template<class O> inline void reset(O * oref) { refcheck; (*this) = static_cast<T*>(oref); refcheck; }
205  inline void reset() { refcheck; if (ac) ac->Release(); ac = NULL; }
206  };
207 
208  };
209 }
This class is a smart pointer for a Referenced class.
Definition: AddonClass.h:154
Ref< T > & operator=(Ref< T > const &oref)
operator= should work with either another smart pointer or a pointer since it will be able to convert...
Definition: AddonClass.h:182
Defining LOG_LIFECYCLE_EVENTS will log all instantiations, deletions and also reference countings (in...
Definition: Addon.cpp:25
virtual void deallocating()
This method is meant to be called from the destructor of the lowest level class.
Definition: AddonClass.h:82
static short getNextClassIndex()
This is meant to be called during static initialization and so isn&#39;t synchronized.
Definition: LanguageHook.h:29
bool isDeallocating()
This method should be called while holding a Synchronize on the object.
Definition: AddonClass.h:106
This class is the superclass for all reference counted classes in the api.
Definition: AddonClass.h:57