00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef SO_REF_COUNTER_H
00025 #define SO_REF_COUNTER_H
00026
00027 #include <stdio.h>
00028 #include <Inventor/SbBase.h>
00029 #include <Inventor/threads/SbThreadSpinlock.h>
00030 #include <Inventor/errors/SoDebugError.h>
00031 #include <functional>
00032
00033 class SoRefCounter;
00034
00035
00036 typedef void SoBaseRefCountCB(void *userData, const SoRefCounter *base);
00037
00038
00070 class SoRefCounter
00071 {
00072 public:
00077 void ref() const;
00078
00085 void unref() const;
00086
00094 void unrefNoDelete() const;
00095
00099 inline int getRefCount() const
00100 { return m_refcount; }
00101
00105 inline void lock() const
00106 { m_refMutex.lock(); }
00107
00111 inline void unlock() const
00112 { m_refMutex.unlock(); }
00113
00114
00115 private:
00117 static void initClass();
00118
00120 static void exitClass();
00121
00122 struct OnDeleteCB{
00123 SoRefCounter* context;
00124 std::function<void(SoRefCounter* caller, SoRefCounter* context)> callback;
00125 bool isValid;
00126 OnDeleteCB(SoRefCounter* ptr, const std::function<void(SoRefCounter* caller, SoRefCounter* context)> &cb): context(ptr), callback(cb), isValid(true){}
00127 };
00128
00137 static void setRefCountCallback(SoBaseRefCountCB *f)
00138 { s_refCountCBFunc = f; }
00139
00152 void setRefCountCallbackData(void *userData = NULL)
00153 { m_refCountCBData = userData; }
00154
00158 void invokeRefCountCB() const;
00159
00161 static inline void setTraceRefs(const bool enable)
00162 { s_traceRefs = enable; }
00163
00165 static inline SbBool getTraceRefs()
00166 { return s_traceRefs; }
00167
00172 void setRefCount(const int count);
00173
00174
00175 void addOnDeleteCB(SoRefCounter *context, const std::function<void()> &callBackFunction);
00176 void addOnDeleteCB(SoRefCounter *context, const std::function<void(SoRefCounter* caller)> &callBackFunction);
00177 void addOnDeleteCB(SoRefCounter *context, const std::function<void(SoRefCounter* caller, SoRefCounter* context)> &callBackFunction);
00178 void addOnDeleteCB(const std::function<void()> &callBackFunction);
00179 void addOnDeleteCB(const std::function<void(SoRefCounter* caller)> &callBackFunction);
00180
00181
00182 private:
00184 SoRefCounter();
00185
00187 SoRefCounter(const SoRefCounter &);
00188
00190 SoRefCounter & operator=(const SoRefCounter &)
00191 { return *this; }
00192
00194 virtual ~SoRefCounter();
00195
00196
00203 virtual bool notifyDelete() const
00204 { return true; }
00205
00210 virtual void destroy()
00211 { delete this; }
00212
00213 private:
00215 static bool s_traceRefs;
00216
00218 static SoBaseRefCountCB* s_refCountCBFunc;
00219 void* m_refCountCBData;
00220
00222 mutable int m_refcount;
00223 mutable SbThreadSpinlock m_refMutex;
00224
00225
00226 std::vector<OnDeleteCB> *m_onDeleteCBVec;
00227 std::vector<SoRefCounter*> *m_contextVec;
00228 void cleanUpContextsCB();
00229 void cleanUpContextsLists();
00230
00231 };
00232
00234 #define SO_UNREF_RESET(object)\
00235 {\
00236 if ( object )\
00237 {\
00238 object->unref();\
00239 object=NULL;\
00240 }\
00241 }
00242
00243
00244
00245 #include <Inventor/misc/SoAutoRef.h>
00246
00247 #endif // SO_REF_COUNTER_H
00248
00249
00250