StreamIn.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/NonCopyable.h>
  6. JPH_NAMESPACE_BEGIN
  7. /// Simple binary input stream
  8. class JPH_EXPORT StreamIn : public NonCopyable
  9. {
  10. public:
  11. /// Virtual destructor
  12. virtual ~StreamIn() = default;
  13. /// Read a string of bytes from the binary stream
  14. virtual void ReadBytes(void *outData, size_t inNumBytes) = 0;
  15. /// Returns true when an attempt has been made to read past the end of the file.
  16. /// Note that this follows the convention of std::basic_ios::eof which only returns true when an attempt is made to read past the end, not when the read pointer is at the end.
  17. virtual bool IsEOF() const = 0;
  18. /// Returns true if there was an IO failure
  19. virtual bool IsFailed() const = 0;
  20. /// Read a primitive (e.g. float, int, etc.) from the binary stream
  21. template <class T, std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true>
  22. void Read(T &outT)
  23. {
  24. ReadBytes(&outT, sizeof(outT));
  25. }
  26. /// Read a vector of primitives from the binary stream
  27. template <class T, class A, std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true>
  28. void Read(Array<T, A> &outT)
  29. {
  30. uint32 len = uint32(outT.size()); // Initialize to previous array size, this is used for validation in the StateRecorder class
  31. Read(len);
  32. if (!IsEOF() && !IsFailed())
  33. {
  34. outT.resize(len);
  35. if constexpr (std::is_same_v<T, Vec3> || std::is_same_v<T, DVec3> || std::is_same_v<T, DMat44>)
  36. {
  37. // These types have unused components that we don't want to read
  38. for (typename Array<T, A>::size_type i = 0; i < len; ++i)
  39. Read(outT[i]);
  40. }
  41. else
  42. {
  43. // Read all elements at once
  44. ReadBytes(outT.data(), len * sizeof(T));
  45. }
  46. }
  47. else
  48. outT.clear();
  49. }
  50. /// Read a string from the binary stream (reads the number of characters and then the characters)
  51. template <class Type, class Traits, class Allocator>
  52. void Read(std::basic_string<Type, Traits, Allocator> &outString)
  53. {
  54. uint32 len = 0;
  55. Read(len);
  56. if (!IsEOF() && !IsFailed())
  57. {
  58. outString.resize(len);
  59. ReadBytes(outString.data(), len * sizeof(Type));
  60. }
  61. else
  62. outString.clear();
  63. }
  64. /// Read a vector of primitives from the binary stream using a custom function to read the elements
  65. template <class T, class A, typename F>
  66. void Read(Array<T, A> &outT, const F &inReadElement)
  67. {
  68. uint32 len = uint32(outT.size()); // Initialize to previous array size, this is used for validation in the StateRecorder class
  69. Read(len);
  70. if (!IsEOF() && !IsFailed())
  71. {
  72. outT.resize(len);
  73. for (typename Array<T, A>::size_type i = 0; i < len; ++i)
  74. inReadElement(*this, outT[i]);
  75. }
  76. else
  77. outT.clear();
  78. }
  79. /// Read a Vec3 (don't read W)
  80. void Read(Vec3 &outVec)
  81. {
  82. ReadBytes(&outVec, 3 * sizeof(float));
  83. outVec = Vec3::sFixW(outVec.mValue);
  84. }
  85. /// Read a DVec3 (don't read W)
  86. void Read(DVec3 &outVec)
  87. {
  88. ReadBytes(&outVec, 3 * sizeof(double));
  89. outVec = DVec3::sFixW(outVec.mValue);
  90. }
  91. /// Read a DMat44 (don't read W component of translation)
  92. void Read(DMat44 &outVec)
  93. {
  94. Vec4 x, y, z;
  95. Read(x);
  96. Read(y);
  97. Read(z);
  98. DVec3 t;
  99. Read(t);
  100. outVec = DMat44(x, y, z, t);
  101. }
  102. };
  103. JPH_NAMESPACE_END