llhandle.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:5k
源码类别:

游戏引擎

开发平台:

C++ Builder

  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=viewergpl$
  7. * Copyright (c) 2001-2010, Linden Research, Inc.
  8. * Second Life Viewer Source Code
  9. * The source code in this file ("Source Code") is provided by Linden Lab
  10. * to you under the terms of the GNU General Public License, version 2.0
  11. * ("GPL"), unless you have obtained a separate licensing agreement
  12. * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15. * There are special exceptions to the terms and conditions of the GPL as
  16. * it is applied to this Source Code. View the full text of the exception
  17. * in the file doc/FLOSS-exception.txt in this software distribution, or
  18. * online at
  19. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  20. * By copying, modifying or distributing this software, you acknowledge
  21. * that you have read and understood your obligations described above,
  22. * and agree to abide by those obligations.
  23. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  24. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  25. * COMPLETENESS OR PERFORMANCE.
  26. * $/LicenseInfo$
  27. */
  28. #ifndef LLHANDLE_H
  29. #define LLHANDLE_H
  30. #include "llpointer.h"
  31. template <typename T>
  32. class LLTombStone : public LLRefCount
  33. {
  34. public:
  35. LLTombStone(T* target = NULL) : mTarget(target) {}
  36. void setTarget(T* target) { mTarget = target; }
  37. T* getTarget() const { return mTarget; }
  38. private:
  39. T* 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. public:
  53. LLHandle() : mTombStone(getDefaultTombStone()) {}
  54. const LLHandle<T>& operator =(const LLHandle<T>& other)  
  55. mTombStone = other.mTombStone;
  56. return *this; 
  57. }
  58. bool isDead() const 
  59. return mTombStone->getTarget() == NULL; 
  60. }
  61. void markDead() 
  62. mTombStone = getDefaultTombStone();
  63. }
  64. T* get() const
  65. {
  66. return mTombStone->getTarget();
  67. }
  68. friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  69. {
  70. return lhs.mTombStone == rhs.mTombStone;
  71. }
  72. friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  73. {
  74. return !(lhs == rhs);
  75. }
  76. friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  77. {
  78. return lhs.mTombStone < rhs.mTombStone;
  79. }
  80. friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
  81. {
  82. return lhs.mTombStone > rhs.mTombStone;
  83. }
  84. protected:
  85. protected:
  86. LLPointer<LLTombStone<T> > mTombStone;
  87. private:
  88. static LLPointer<LLTombStone<T> >& getDefaultTombStone()
  89. {
  90. static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
  91. return sDefaultTombStone;
  92. }
  93. };
  94. template <typename T>
  95. class LLRootHandle : public LLHandle<T>
  96. {
  97. public:
  98. LLRootHandle(T* object) { bind(object); }
  99. LLRootHandle() {};
  100. ~LLRootHandle() { unbind(); }
  101. // this is redundant, since a LLRootHandle *is* an LLHandle
  102. LLHandle<T> getHandle() { return LLHandle<T>(*this); }
  103. void bind(T* object) 
  104. // unbind existing tombstone
  105. if (LLHandle<T>::mTombStone.notNull())
  106. {
  107. if (LLHandle<T>::mTombStone->getTarget() == object) return;
  108. LLHandle<T>::mTombStone->setTarget(NULL);
  109. }
  110. // tombstone reference counted, so no paired delete
  111. LLHandle<T>::mTombStone = new LLTombStone<T>(object);
  112. }
  113. void unbind() 
  114. {
  115. LLHandle<T>::mTombStone->setTarget(NULL);
  116. }
  117. //don't allow copying of root handles, since there should only be one
  118. private:
  119. LLRootHandle(const LLRootHandle& other) {};
  120. };
  121. // Use this as a mixin for simple classes that need handles and when you don't
  122. // want handles at multiple points of the inheritance hierarchy
  123. template <typename T>
  124. class LLHandleProvider
  125. {
  126. protected:
  127. typedef LLHandle<T> handle_type_t;
  128. LLHandleProvider() 
  129. {
  130. // provided here to enforce T deriving from LLHandleProvider<T>
  131. LLHandle<T> getHandle() 
  132. // perform lazy binding to avoid small tombstone allocations for handle
  133. // providers whose handles are never referenced
  134. mHandle.bind(static_cast<T*>(this)); 
  135. return mHandle; 
  136. }
  137. private:
  138. LLRootHandle<T> mHandle;
  139. };
  140. #endif