PageRenderTime 30ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llui/llhandle.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 181 lines | 113 code | 24 blank | 44 comment | 6 complexity | 7ee5cf18df404087e3eef6a0cc61528e MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llhandle.h
  3. * @brief "Handle" to an object (usually a floater) whose lifetime you don't
  4. * control.
  5. *
  6. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #ifndef LLHANDLE_H
  28. #define LLHANDLE_H
  29. #include "llpointer.h"
  30. #include <boost/type_traits/is_convertible.hpp>
  31. #include <boost/utility/enable_if.hpp>
  32. class LLTombStone : public LLRefCount
  33. {
  34. public:
  35. LLTombStone(void* target = NULL) : mTarget(target) {}
  36. void setTarget(void* target) { mTarget = target; }
  37. void* getTarget() const { return mTarget; }
  38. private:
  39. mutable void* mTarget;
  40. };
  41. // LLHandles are used to refer to objects whose lifetime you do not control or influence.
  42. // Calling get() on a handle will return a pointer to the referenced object or NULL,
  43. // if the object no longer exists. Note that during the lifetime of the returned pointer,
  44. // you are assuming that the object will not be deleted by any action you perform,
  45. // or any other thread, as normal when using pointers, so avoid using that pointer outside of
  46. // the local code block.
  47. //
  48. // https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
  49. template <typename T>
  50. class LLHandle
  51. {
  52. template <typename U> friend class LLHandle;
  53. template <typename U> friend class LLHandleProvider;
  54. public:
  55. LLHandle() : mTombStone(getDefaultTombStone()) {}
  56. template<typename U>
  57. LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
  58. : mTombStone(other.mTombStone)
  59. {}
  60. bool isDead() const
  61. {
  62. return mTombStone->getTarget() == NULL;
  63. }
  64. void markDead()
  65. {
  66. mTombStone = getDefaultTombStone();
  67. }
  68. T* get() const
  69. {
  70. return reinterpret_cast<T*>(mTombStone->getTarget());
  71. }
  72. friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  73. {
  74. return lhs.mTombStone == rhs.mTombStone;
  75. }
  76. friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  77. {
  78. return !(lhs == rhs);
  79. }
  80. friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  81. {
  82. return lhs.mTombStone < rhs.mTombStone;
  83. }
  84. friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  85. {
  86. return lhs.mTombStone > rhs.mTombStone;
  87. }
  88. protected:
  89. LLPointer<LLTombStone> mTombStone;
  90. private:
  91. typedef T* pointer_t;
  92. static LLPointer<LLTombStone>& getDefaultTombStone()
  93. {
  94. static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
  95. return sDefaultTombStone;
  96. }
  97. };
  98. template <typename T>
  99. class LLRootHandle : public LLHandle<T>
  100. {
  101. public:
  102. typedef LLRootHandle<T> self_t;
  103. typedef LLHandle<T> base_t;
  104. LLRootHandle(T* object) { bind(object); }
  105. LLRootHandle() {};
  106. ~LLRootHandle() { unbind(); }
  107. // this is redundant, since an LLRootHandle *is* an LLHandle
  108. //LLHandle<T> getHandle() { return LLHandle<T>(*this); }
  109. void bind(T* object)
  110. {
  111. // unbind existing tombstone
  112. if (LLHandle<T>::mTombStone.notNull())
  113. {
  114. if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
  115. LLHandle<T>::mTombStone->setTarget(NULL);
  116. }
  117. // tombstone reference counted, so no paired delete
  118. LLHandle<T>::mTombStone = new LLTombStone((void*)object);
  119. }
  120. void unbind()
  121. {
  122. LLHandle<T>::mTombStone->setTarget(NULL);
  123. }
  124. //don't allow copying of root handles, since there should only be one
  125. private:
  126. LLRootHandle(const LLRootHandle& other) {};
  127. };
  128. // Use this as a mixin for simple classes that need handles and when you don't
  129. // want handles at multiple points of the inheritance hierarchy
  130. template <typename T>
  131. class LLHandleProvider
  132. {
  133. public:
  134. LLHandle<T> getHandle() const
  135. {
  136. // perform lazy binding to avoid small tombstone allocations for handle
  137. // providers whose handles are never referenced
  138. mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
  139. return mHandle;
  140. }
  141. protected:
  142. typedef LLHandle<T> handle_type_t;
  143. LLHandleProvider()
  144. {
  145. // provided here to enforce T deriving from LLHandleProvider<T>
  146. }
  147. template <typename U>
  148. LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
  149. {
  150. LLHandle<U> downcast_handle;
  151. downcast_handle.mTombStone = getHandle().mTombStone;
  152. return downcast_handle;
  153. }
  154. private:
  155. mutable LLRootHandle<T> mHandle;
  156. };
  157. #endif