ResourceFilesystem.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Resource/Common.h>
  7. #include <AnKi/Util/String.h>
  8. #include <AnKi/Util/StringList.h>
  9. #include <AnKi/Util/File.h>
  10. #include <AnKi/Util/Ptr.h>
  11. namespace anki {
  12. /// @addtogroup resource
  13. /// @{
  14. /// Resource filesystem file. An interface that abstracts the resource file.
  15. class ResourceFile
  16. {
  17. public:
  18. ResourceFile(HeapMemoryPool* pool)
  19. : m_pool(pool)
  20. {
  21. ANKI_ASSERT(pool);
  22. }
  23. ResourceFile(const ResourceFile&) = delete; // Non-copyable
  24. virtual ~ResourceFile()
  25. {
  26. }
  27. ResourceFile& operator=(const ResourceFile&) = delete; // Non-copyable
  28. /// Read data from the file
  29. virtual Error read(void* buff, PtrSize size) = 0;
  30. /// Read all the contents of a text file. If the file is not rewined it will probably fail
  31. virtual Error readAllText(StringRaii& out) = 0;
  32. /// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's
  33. virtual Error readU32(U32& u) = 0;
  34. /// Read 32bit float. Set the endianness if the file's endianness is different from the machine's
  35. virtual Error readF32(F32& f) = 0;
  36. /// Set the position indicator to a new position
  37. /// @param offset Number of bytes to offset from origin
  38. /// @param origin Position used as reference for the offset
  39. virtual Error seek(PtrSize offset, FileSeekOrigin origin) = 0;
  40. /// Get the size of the file.
  41. virtual PtrSize getSize() const = 0;
  42. void retain() const
  43. {
  44. m_refcount.fetchAdd(1);
  45. }
  46. I32 release() const
  47. {
  48. return m_refcount.fetchSub(1);
  49. }
  50. HeapMemoryPool& getMemoryPool() const
  51. {
  52. return *m_pool;
  53. }
  54. private:
  55. mutable HeapMemoryPool* m_pool = nullptr;
  56. mutable Atomic<I32> m_refcount = {0};
  57. };
  58. /// Resource file smart pointer.
  59. using ResourceFilePtr = IntrusivePtr<ResourceFile>;
  60. /// Resource filesystem.
  61. class ResourceFilesystem
  62. {
  63. public:
  64. ResourceFilesystem() = default;
  65. ResourceFilesystem(const ResourceFilesystem&) = delete; // Non-copyable
  66. ~ResourceFilesystem();
  67. ResourceFilesystem& operator=(const ResourceFilesystem&) = delete; // Non-copyable
  68. Error init(AllocAlignedCallback allocCallback, void* allocCallbackUserData);
  69. /// Search the path list to find the file. Then open the file for reading. It's thread-safe.
  70. Error openFile(const ResourceFilename& filename, ResourceFilePtr& file);
  71. /// Iterate all the filenames from all paths provided.
  72. template<typename TFunc>
  73. Error iterateAllFilenames(TFunc func) const
  74. {
  75. for(const Path& path : m_paths)
  76. {
  77. for(const String& fname : path.m_files)
  78. {
  79. ANKI_CHECK(func(fname.toCString()));
  80. }
  81. }
  82. return Error::kNone;
  83. }
  84. #if !ANKI_TESTS
  85. private:
  86. #endif
  87. class Path
  88. {
  89. public:
  90. StringList m_files; ///< Files inside the directory.
  91. String m_path; ///< A directory or an archive.
  92. Bool m_isArchive = false;
  93. Path() = default;
  94. Path(const Path&) = delete; // Non-copyable
  95. Path(Path&& b)
  96. {
  97. *this = std::move(b);
  98. }
  99. Path& operator=(const Path&) = delete; // Non-copyable
  100. Path& operator=(Path&& b)
  101. {
  102. m_files = std::move(b.m_files);
  103. m_path = std::move(b.m_path);
  104. m_isArchive = b.m_isArchive;
  105. return *this;
  106. }
  107. };
  108. HeapMemoryPool m_pool;
  109. List<Path> m_paths;
  110. String m_cacheDir;
  111. /// Add a filesystem path or an archive. The path is read-only.
  112. Error addNewPath(const CString& path, const StringListRaii& excludedStrings);
  113. Error openFileInternal(const ResourceFilename& filename, ResourceFile*& rfile);
  114. };
  115. /// @}
  116. } // end namespace anki