SceneSerializer.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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/Scene/Common.h>
  7. #include <AnKi/Resource/ResourceManager.h>
  8. namespace anki {
  9. constexpr U32 kSceneBinaryVersion = 1;
  10. #define ANKI_SERIALIZE(var, version) \
  11. { \
  12. static_assert(version <= kSceneBinaryVersion); \
  13. ANKI_CHECK(serializer.serialize(#var, version, false, var)); \
  14. }
  15. #define ANKI_SERIALIZE_ALIAS(varName, var, version) \
  16. { \
  17. static_assert(version <= kSceneBinaryVersion); \
  18. ANKI_CHECK(serializer.serialize(varName, version, false, var)); \
  19. }
  20. #define ANKI_SERIALIZE_DEPRECATED(var, version) \
  21. { \
  22. static_assert(version <= kSceneBinaryVersion); \
  23. ANKI_CHECK(serializer.serialize(#var, version, true, var)); \
  24. }
  25. // Interface class for scene serialization
  26. class SceneSerializer
  27. {
  28. public:
  29. SceneSerializer(Bool writingMode)
  30. : m_writeMode(writingMode)
  31. {
  32. }
  33. virtual Error write(CString name, ConstWeakArray<U32> values) = 0;
  34. virtual Error read(CString name, WeakArray<U32> values) = 0;
  35. virtual Error write(CString name, ConstWeakArray<I32> values) = 0;
  36. virtual Error read(CString name, WeakArray<I32> values) = 0;
  37. virtual Error write(CString name, ConstWeakArray<F32> values) = 0;
  38. virtual Error read(CString name, WeakArray<F32> values) = 0;
  39. Error write(CString name, ConstWeakArray<F64> values);
  40. Error read(CString name, WeakArray<F64> values);
  41. virtual Error write(CString name, CString value) = 0;
  42. virtual Error read(CString name, SceneString& value) = 0;
  43. // For resources
  44. template<typename T>
  45. Error serialize(String varName, U32 varVersion, Bool varDeprecated, ResourcePtr<T>& rsrc)
  46. {
  47. SceneString filename;
  48. if(m_writeMode && rsrc)
  49. {
  50. filename = rsrc->getFilename();
  51. }
  52. ANKI_CHECK(serializeInternal(varName, varVersion, varDeprecated, filename));
  53. if(!m_writeMode && filename.getLength())
  54. {
  55. ANKI_CHECK(ResourceManager::getSingleton().loadResource(filename, rsrc));
  56. }
  57. return Error::kNone;
  58. }
  59. // For regular arithmetic
  60. template<typename T>
  61. Error serialize(String varName, U32 varVersion, Bool varDeprecated, T& varValue) requires(std::is_arithmetic_v<T>)
  62. {
  63. WeakArray<T> arr(&varValue, 1);
  64. return serializeInternal(varName, varVersion, varDeprecated, arr);
  65. }
  66. // SceneDynamicArray of numbers
  67. template<typename T>
  68. Error serialize(String varName, U32 varVersion, Bool varDeprecated, SceneDynamicArray<T>& array) requires(std::is_arithmetic_v<T>)
  69. {
  70. WeakArray<T> arr(array);
  71. return serializeInternal(varName, varVersion, varDeprecated, arr);
  72. }
  73. // Vector 3
  74. template<typename T>
  75. Error serialize(String varName, U32 varVersion, Bool varDeprecated, TVec<T, 3>& varValue)
  76. {
  77. WeakArray<T> arr(&varValue[0], 3);
  78. return serializeInternal(varName, varVersion, varDeprecated, arr);
  79. }
  80. // Vector 4
  81. template<typename T>
  82. Error serialize(String varName, U32 varVersion, Bool varDeprecated, TVec<T, 4>& varValue)
  83. {
  84. WeakArray<T> arr(&varValue[0], 4);
  85. return serializeInternal(varName, varVersion, varDeprecated, arr);
  86. }
  87. // Mat
  88. template<typename T, U kTRowCount, U kTColumnCount>
  89. Error serialize(String varName, U32 varVersion, Bool varDeprecated, TMat<T, kTRowCount, kTColumnCount>& varValue)
  90. {
  91. WeakArray<T> arr(&varValue[0], kTRowCount * kTColumnCount);
  92. return serializeInternal(varName, varVersion, varDeprecated, arr);
  93. }
  94. // Enums
  95. template<typename T>
  96. Error serialize(String varName, U32 varVersion, Bool varDeprecated, T& varValue) requires(std::is_enum_v<T>)
  97. {
  98. static_assert(sizeof(T) <= sizeof(U32));
  99. U32 val = U32(varValue);
  100. WeakArray<U32> arr(&val, 1);
  101. ANKI_CHECK(serializeInternal(varName, varVersion, varDeprecated, arr));
  102. varValue = T(val);
  103. return Error::kNone;
  104. }
  105. // Strings
  106. Error serialize(String varName, U32 varVersion, Bool varDeprecated, SceneString& varValue)
  107. {
  108. return serializeInternal(varName, varVersion, varDeprecated, varValue);
  109. }
  110. Bool isInWriteMode() const
  111. {
  112. return m_writeMode;
  113. }
  114. Bool isInReadMode() const
  115. {
  116. return !m_writeMode;
  117. }
  118. public:
  119. Bool m_writeMode = false;
  120. U32 m_crntBinaryVersion = kMaxU32;
  121. template<typename T>
  122. Error serializeInternal(CString varName, U32 varVersion, Bool varDeprecated, T& varValue)
  123. {
  124. ANKI_ASSERT(varVersion <= kSceneBinaryVersion);
  125. if(m_writeMode)
  126. {
  127. // Always writing in the latest version so skip deprecated vars
  128. const Bool skip = varDeprecated;
  129. if(!skip)
  130. {
  131. return write(varName, varValue);
  132. }
  133. }
  134. else
  135. {
  136. // Var is newer than the binary we are reading, skip it
  137. Bool skip = varVersion >= m_crntBinaryVersion;
  138. // Var is depracated and binary is newer, skip it
  139. skip = skip || (varDeprecated && m_crntBinaryVersion > varVersion);
  140. if(!skip)
  141. {
  142. return read(varName, varValue);
  143. }
  144. }
  145. return Error::kNone;
  146. }
  147. };
  148. // Serialize in a custom text format
  149. class TextSceneSerializer : public SceneSerializer
  150. {
  151. public:
  152. TextSceneSerializer(File* file, Bool writingMode)
  153. : SceneSerializer(writingMode)
  154. , m_file(*file)
  155. {
  156. }
  157. Error write(CString name, ConstWeakArray<U32> values) final
  158. {
  159. if(values.getSize() == 1)
  160. {
  161. ANKI_CHECK(m_file.writeTextf("%s %u\n", name.cstr(), values[0]));
  162. }
  163. else
  164. {
  165. ANKI_CHECK(m_file.writeTextf("%s %u ", name.cstr(), values[0]));
  166. for(U32 i = 1; i < values.getSize(); ++i)
  167. {
  168. ANKI_CHECK(m_file.writeTextf((i < values.getSize() - 1) ? "%u " : "%u\n", values[i]));
  169. }
  170. }
  171. return Error::kNone;
  172. }
  173. Error read([[maybe_unused]] CString name, [[maybe_unused]] WeakArray<U32> values) final
  174. {
  175. ANKI_ASSERT(!"TODO");
  176. return Error::kNone;
  177. }
  178. Error write(CString name, ConstWeakArray<I32> values) final
  179. {
  180. if(values.getSize() == 1)
  181. {
  182. ANKI_CHECK(m_file.writeTextf("%s %d\n", name.cstr(), values[0]));
  183. }
  184. else
  185. {
  186. ANKI_CHECK(m_file.writeTextf("%s %d ", name.cstr(), values[0]));
  187. for(U32 i = 1; i < values.getSize(); ++i)
  188. {
  189. ANKI_CHECK(m_file.writeTextf((i < values.getSize() - 1) ? "%d " : "%d\n", values[i]));
  190. }
  191. }
  192. return Error::kNone;
  193. }
  194. Error read([[maybe_unused]] CString name, [[maybe_unused]] WeakArray<I32> values) final
  195. {
  196. ANKI_ASSERT(!"TODO");
  197. return Error::kNone;
  198. }
  199. Error write(CString name, ConstWeakArray<F32> values) final
  200. {
  201. if(values.getSize() == 1)
  202. {
  203. ANKI_CHECK(m_file.writeTextf("%s %f\n", name.cstr(), values[0]));
  204. }
  205. else
  206. {
  207. ANKI_CHECK(m_file.writeTextf("%s %f ", name.cstr(), values[0]));
  208. for(U32 i = 1; i < values.getSize(); ++i)
  209. {
  210. ANKI_CHECK(m_file.writeTextf((i < values.getSize() - 1) ? "%f " : "%f\n", values[i]));
  211. }
  212. }
  213. return Error::kNone;
  214. }
  215. Error read([[maybe_unused]] CString name, [[maybe_unused]] WeakArray<F32> values)
  216. {
  217. ANKI_ASSERT(!"TODO");
  218. return Error::kNone;
  219. }
  220. Error write(CString name, CString value) final
  221. {
  222. return m_file.writeTextf("%s %s\n", name.cstr(), value.cstr());
  223. }
  224. Error read([[maybe_unused]] CString name, [[maybe_unused]] SceneString& value) final
  225. {
  226. ANKI_ASSERT(!"TODO");
  227. return Error::kNone;
  228. }
  229. private:
  230. File& m_file;
  231. };
  232. } // end namespace anki