ResourceFilesystem.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (C) 2009-present, 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. #include <AnKi/Util/CVarSet.h>
  12. namespace anki {
  13. // Forward
  14. extern StringCVar g_dataPathsCVar;
  15. /// @addtogroup resource
  16. /// @{
  17. /// Resource filesystem file. An interface that abstracts the resource file.
  18. class ResourceFile
  19. {
  20. public:
  21. ResourceFile() = default;
  22. ResourceFile(const ResourceFile&) = delete; // Non-copyable
  23. virtual ~ResourceFile()
  24. {
  25. }
  26. ResourceFile& operator=(const ResourceFile&) = delete; // Non-copyable
  27. /// Read data from the file
  28. virtual Error read(void* buff, PtrSize size) = 0;
  29. /// Read all the contents of a text file. If the file is not rewined it will probably fail
  30. virtual Error readAllText(ResourceString& out) = 0;
  31. /// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's
  32. virtual Error readU32(U32& u) = 0;
  33. /// Read 32bit float. Set the endianness if the file's endianness is different from the machine's
  34. virtual Error readF32(F32& f) = 0;
  35. /// Set the position indicator to a new position
  36. /// @param offset Number of bytes to offset from origin
  37. /// @param origin Position used as reference for the offset
  38. virtual Error seek(PtrSize offset, FileSeekOrigin origin) = 0;
  39. /// Get the size of the file.
  40. virtual PtrSize getSize() const = 0;
  41. void retain() const
  42. {
  43. m_refcount.fetchAdd(1);
  44. }
  45. I32 release() const
  46. {
  47. return m_refcount.fetchSub(1);
  48. }
  49. private:
  50. mutable Atomic<I32> m_refcount = {0};
  51. };
  52. /// Resource file smart pointer.
  53. class ResourceFileDeleter
  54. {
  55. public:
  56. void operator()(ResourceFile* x)
  57. {
  58. deleteInstance(ResourceMemoryPool::getSingleton(), x);
  59. }
  60. };
  61. using ResourceFilePtr = IntrusivePtr<ResourceFile, ResourceFileDeleter>;
  62. /// Resource filesystem.
  63. class ResourceFilesystem
  64. {
  65. public:
  66. ResourceFilesystem() = default;
  67. ResourceFilesystem(const ResourceFilesystem&) = delete; // Non-copyable
  68. ~ResourceFilesystem();
  69. ResourceFilesystem& operator=(const ResourceFilesystem&) = delete; // Non-copyable
  70. Error init();
  71. /// Search the path list to find the file. Then open the file for reading.
  72. /// @note Thread-safe.
  73. Error openFile(const ResourceFilename& filename, ResourceFilePtr& file) const;
  74. /// Iterate all the filenames from all paths provided.
  75. template<typename TFunc>
  76. Error iterateAllFilenames(TFunc func) const
  77. {
  78. for(const Path& path : m_paths)
  79. {
  80. for(const ResourceString& fname : path.m_files)
  81. {
  82. ANKI_CHECK(func(fname.toCString()));
  83. }
  84. }
  85. return Error::kNone;
  86. }
  87. #if !ANKI_TESTS
  88. private:
  89. #endif
  90. class Path
  91. {
  92. public:
  93. ResourceStringList m_files; ///< Files inside the directory.
  94. ResourceString m_path; ///< A directory or an archive.
  95. Bool m_isArchive = false;
  96. Path() = default;
  97. Path(const Path&) = delete; // Non-copyable
  98. Path(Path&& b)
  99. {
  100. *this = std::move(b);
  101. }
  102. Path& operator=(const Path&) = delete; // Non-copyable
  103. Path& operator=(Path&& b)
  104. {
  105. m_files = std::move(b.m_files);
  106. m_path = std::move(b.m_path);
  107. m_isArchive = b.m_isArchive;
  108. return *this;
  109. }
  110. };
  111. ResourceList<Path> m_paths;
  112. ResourceString m_cacheDir;
  113. /// Add a filesystem path or an archive. The path is read-only.
  114. Error addNewPath(CString path, const ResourceStringList& includeStrings, const ResourceStringList& excludedStrings);
  115. Error openFileInternal(const ResourceFilename& filename, ResourceFile*& rfile) const;
  116. };
  117. /// @}
  118. } // end namespace anki