CmResourceHandle.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #pragma once
  2. #include "CmIReflectable.h"
  3. namespace CamelotEngine
  4. {
  5. template <typename T>
  6. class ResourceHandle;
  7. struct CM_EXPORT ResourceHandleData : public IReflectable
  8. {
  9. ResourceHandleData()
  10. :mIsCreated(false)
  11. { }
  12. std::shared_ptr<Resource> mPtr;
  13. String mUUID;
  14. bool mIsCreated;
  15. /************************************************************************/
  16. /* RTTI */
  17. /************************************************************************/
  18. public:
  19. friend class ResourceHandleDataRTTI;
  20. static RTTITypeBase* getRTTIStatic();
  21. virtual RTTITypeBase* getRTTI() const;
  22. };
  23. class CM_EXPORT ResourceHandleBase : public IReflectable
  24. {
  25. public:
  26. /**
  27. * @brief Checks if the resource is loaded
  28. */
  29. bool isLoaded() const;
  30. /**
  31. * @brief Blocks the current thread until the resource is fully loaded.
  32. *
  33. * @note Careful not to call this on the thread that does the loading.
  34. */
  35. void waitUntilLoaded() const;
  36. /**
  37. * @brief Returns the UUID of the resource the handle is referring to.
  38. */
  39. const String& getUUID() const { return mData->mUUID; }
  40. protected:
  41. ResourceHandleBase();
  42. std::shared_ptr<ResourceHandleData> mData;
  43. void init(Resource* ptr);
  44. void init(std::shared_ptr<Resource> ptr);
  45. template <typename T1>
  46. void init(const ResourceHandle<T1>& ptr)
  47. {
  48. mData = ptr.mData;
  49. }
  50. private:
  51. friend class Resources;
  52. CM_STATIC_THREAD_SYNCHRONISER(mResourceCreatedCondition)
  53. CM_STATIC_MUTEX(mResourceCreatedMutex)
  54. /**
  55. * @brief Sets the created flag to true. Should only be called
  56. * by Resources class after loading of the resource is fully done.
  57. */
  58. void resolve(std::shared_ptr<Resource> ptr);
  59. /**
  60. * @brief Sets an uuid of the ResourceHandle. Should only be called by
  61. * Resources class.
  62. */
  63. void ResourceHandleBase::setUUID(const String& uuid);
  64. protected:
  65. inline void throwIfNotLoaded() const;
  66. /************************************************************************/
  67. /* RTTI */
  68. /************************************************************************/
  69. public:
  70. friend class ResourceHandleRTTI;
  71. static RTTITypeBase* getRTTIStatic();
  72. virtual RTTITypeBase* getRTTI() const;
  73. };
  74. template <typename T>
  75. class ResourceHandle : public ResourceHandleBase
  76. {
  77. public:
  78. ResourceHandle()
  79. :ResourceHandleBase()
  80. { }
  81. explicit ResourceHandle(T* ptr)
  82. :ResourceHandleBase()
  83. {
  84. init(ptr);
  85. }
  86. ResourceHandle(std::shared_ptr<T> ptr)
  87. :ResourceHandleBase()
  88. {
  89. init(ptr);
  90. }
  91. template <typename T1>
  92. ResourceHandle(const ResourceHandle<T1>& ptr)
  93. :ResourceHandleBase()
  94. {
  95. init(ptr);
  96. }
  97. operator ResourceHandle<Resource>()
  98. {
  99. return ResourceHandle<Resource>(mData->mPtr);
  100. }
  101. // TODO Low priority - User can currently try to access these even if resource ptr is not resolved
  102. T* get() const
  103. {
  104. throwIfNotLoaded();
  105. return static_cast<T*>(mData->mPtr.get());
  106. }
  107. T* operator->() const { return get(); }
  108. T& operator*() const { return *get(); }
  109. std::shared_ptr<T> getInternalPtr()
  110. {
  111. throwIfNotLoaded();
  112. return std::static_pointer_cast<T>(mData->mPtr);
  113. }
  114. template<class _Ty>
  115. struct CM_Bool_struct
  116. {
  117. int _Member;
  118. };
  119. // Conversion to bool
  120. // (Why not just directly convert to bool? Because then we can assign pointer to bool and that's weird)
  121. operator int CM_Bool_struct<T>::*() const
  122. {
  123. return (((mData->mPtr != nullptr)) ? &CM_Bool_struct<T>::_Member : 0);
  124. }
  125. };
  126. template<class _Ty1, class _Ty2>
  127. ResourceHandle<_Ty1> static_resource_cast(const ResourceHandle<_Ty2>& other)
  128. {
  129. return ResourceHandle<_Ty1>(other);
  130. }
  131. template<class _Ty1, class _Ty2>
  132. bool operator==(const ResourceHandle<_Ty1>& _Left, const ResourceHandle<_Ty2>& _Right)
  133. {
  134. return (_Left.get() == _Right.get());
  135. }
  136. template<class _Ty1, class _Ty2>
  137. bool operator!=(const ResourceHandle<_Ty1>& _Left, const ResourceHandle<_Ty2>& _Right)
  138. {
  139. return (!(_Left == _Right));
  140. }
  141. }