RefCounted.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
  2. #ifndef NV_CORE_REFCOUNTED_H
  3. #define NV_CORE_REFCOUNTED_H
  4. #include "nvcore.h"
  5. #include "Debug.h"
  6. #define NV_DECLARE_PTR(Class) \
  7. template <class T> class SmartPtr; \
  8. typedef SmartPtr<class Class> Class ## Ptr; \
  9. typedef SmartPtr<const class Class> Class ## ConstPtr
  10. namespace nv
  11. {
  12. /// Weak proxy.
  13. class WeakProxy
  14. {
  15. NV_FORBID_COPY(WeakProxy);
  16. public:
  17. /// Ctor.
  18. WeakProxy(void * ptr) : m_count(0), m_ptr(ptr) { }
  19. /// Dtor.
  20. ~WeakProxy()
  21. {
  22. nvCheck( m_count == 0 );
  23. }
  24. /// Increase reference count.
  25. uint addRef() const
  26. {
  27. m_count++;
  28. return m_count;
  29. }
  30. /// Decrease reference count and remove when 0.
  31. uint release() const
  32. {
  33. nvCheck( m_count > 0 );
  34. m_count--;
  35. if( m_count == 0 ) {
  36. delete this;
  37. return 0;
  38. }
  39. return m_count;
  40. }
  41. /// WeakPtr's call this to determine if their pointer is valid or not.
  42. bool isAlive() const {
  43. return m_ptr != NULL;
  44. }
  45. /// Only the actual object should call this.
  46. void notifyObjectDied() {
  47. m_ptr = NULL;
  48. }
  49. /// Return proxy pointer.
  50. void * ptr() const {
  51. return m_ptr;
  52. }
  53. private:
  54. mutable int m_count;
  55. void * m_ptr;
  56. };
  57. /// Reference counted base class to be used with SmartPtr and WeakPtr.
  58. class RefCounted
  59. {
  60. NV_FORBID_COPY(RefCounted);
  61. public:
  62. /// Ctor.
  63. RefCounted() : m_count(0), m_weak_proxy(NULL)
  64. {
  65. }
  66. /// Virtual dtor.
  67. virtual ~RefCounted()
  68. {
  69. nvCheck( m_count == 0 );
  70. releaseWeakProxy();
  71. }
  72. /// Increase reference count.
  73. uint addRef() const
  74. {
  75. m_count++;
  76. return m_count;
  77. }
  78. /// Decrease reference count and remove when 0.
  79. uint release() const
  80. {
  81. nvCheck( m_count > 0 );
  82. m_count--;
  83. if( m_count == 0 ) {
  84. delete this;
  85. return 0;
  86. }
  87. return m_count;
  88. }
  89. /// Get weak proxy.
  90. WeakProxy * getWeakProxy() const
  91. {
  92. if (m_weak_proxy == NULL) {
  93. m_weak_proxy = new WeakProxy((void *)this);
  94. m_weak_proxy->addRef();
  95. }
  96. return m_weak_proxy;
  97. }
  98. /// Release the weak proxy.
  99. void releaseWeakProxy() const
  100. {
  101. if (m_weak_proxy != NULL) {
  102. m_weak_proxy->notifyObjectDied();
  103. m_weak_proxy->release();
  104. m_weak_proxy = NULL;
  105. }
  106. }
  107. /// Get reference count.
  108. int refCount() const
  109. {
  110. return m_count;
  111. }
  112. private:
  113. mutable int m_count;
  114. mutable WeakProxy * m_weak_proxy;
  115. };
  116. } // nv namespace
  117. #endif // NV_CORE_REFCOUNTED_H