ResourcePointer.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #ifndef ANKI_RESOURCE_RESOURCE_POINTER_H
  6. #define ANKI_RESOURCE_RESOURCE_POINTER_H
  7. #include "anki/resource/Common.h"
  8. #include "anki/util/Assert.h"
  9. #include "anki/util/Atomic.h"
  10. #include <cstring>
  11. namespace anki {
  12. // Forward
  13. class ResourceManager;
  14. /// @addtogroup resource
  15. /// @{
  16. /// Special smart pointer that points to resource classes.
  17. ///
  18. /// It looks like auto_ptr but the main difference is that when its out of scope
  19. /// it tries to unload the resource.
  20. template<typename Type, typename TResourceManager>
  21. class ResourcePointer
  22. {
  23. public:
  24. using Value = Type; ///< Resource type
  25. /// Default constructor
  26. ResourcePointer()
  27. {}
  28. /// Copy constructor
  29. ResourcePointer(const ResourcePointer& b)
  30. {
  31. copy(b);
  32. }
  33. ~ResourcePointer()
  34. {
  35. reset();
  36. }
  37. const Value& operator*() const
  38. {
  39. ANKI_ASSERT(m_cb != nullptr);
  40. return m_cb->m_resource;
  41. }
  42. Value& operator*()
  43. {
  44. ANKI_ASSERT(m_cb != nullptr);
  45. return m_cb->m_resource;
  46. }
  47. const Value* operator->() const
  48. {
  49. ANKI_ASSERT(m_cb != nullptr);
  50. return &m_cb->m_resource;
  51. }
  52. Value* operator->()
  53. {
  54. ANKI_ASSERT(m_cb != nullptr);
  55. return &m_cb->m_resource;
  56. }
  57. const Value* get() const
  58. {
  59. ANKI_ASSERT(m_cb != nullptr);
  60. return &m_cb->m_resource;
  61. }
  62. Value* get()
  63. {
  64. ANKI_ASSERT(m_cb != nullptr);
  65. return &m_cb->m_resource;
  66. }
  67. CString getResourceName() const
  68. {
  69. ANKI_ASSERT(m_cb != nullptr);
  70. return &m_cb->m_uuid[0];
  71. }
  72. U32 getReferenceCount() const
  73. {
  74. ANKI_ASSERT(m_cb != nullptr);
  75. return m_cb->m_refcount.load();
  76. }
  77. /// Copy
  78. ResourcePointer& operator=(const ResourcePointer& b)
  79. {
  80. copy(b);
  81. return *this;
  82. }
  83. Bool operator==(const ResourcePointer& b) const
  84. {
  85. ANKI_ASSERT(m_cb != nullptr);
  86. ANKI_ASSERT(b.m_cb != nullptr);
  87. return std::strcmp(&m_cb->m_uuid[0], &b.m_cb->m_uuid[0]) == 0;
  88. }
  89. /// Load the resource using the resource manager
  90. ANKI_USE_RESULT Error load(
  91. const CString& filename, TResourceManager* resources);
  92. template<typename... TArgs>
  93. ANKI_USE_RESULT Error loadToCache(
  94. TResourceManager* resources, TArgs&&... args);
  95. Bool isLoaded() const
  96. {
  97. return m_cb != nullptr;
  98. }
  99. private:
  100. /// Control block
  101. class ControlBlock
  102. {
  103. public:
  104. ControlBlock(ResourceAllocator<U8>& alloc)
  105. : m_resource(alloc)
  106. {}
  107. Type m_resource;
  108. Atomic<U32> m_refcount = {1};
  109. TResourceManager* m_resources = nullptr;
  110. char m_uuid[1]; ///< This is part of the UUID
  111. };
  112. ControlBlock* m_cb = nullptr;
  113. void reset();
  114. /// If this empty and @a b empty then unload. If @a b has something then
  115. /// unload this and load exactly what @b has. In everything else do nothing
  116. void copy(const ResourcePointer& b);
  117. };
  118. /// @}
  119. } // end namespace anki
  120. #include "anki/resource/ResourcePointer.inl.h"
  121. #endif