StreamIn.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. virtual bool IsEOF() const = 0;
  17. /// Returns true if there was an IO failure
  18. virtual bool IsFailed() const = 0;
  19. /// Read a primitive (e.g. float, int, etc.) from the binary stream
  20. template <class T, std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true>
  21. void Read(T &outT)
  22. {
  23. ReadBytes(&outT, sizeof(outT));
  24. }
  25. /// Read a vector of primitives from the binary stream
  26. template <class T, class A, std::enable_if_t<std::is_trivially_copyable_v<T>, bool> = true>
  27. void Read(Array<T, A> &outT)
  28. {
  29. uint32 len = uint32(outT.size()); // Initialize to previous array size, this is used for validation in the StateRecorder class
  30. Read(len);
  31. if (!IsEOF() && !IsFailed())
  32. {
  33. outT.resize(len);
  34. if constexpr (std::is_same_v<T, Vec3> || std::is_same_v<T, DVec3> || std::is_same_v<T, DMat44>)
  35. {
  36. // These types have unused components that we don't want to read
  37. for (typename Array<T, A>::size_type i = 0; i < len; ++i)
  38. Read(outT[i]);
  39. }
  40. else
  41. {
  42. // Read all elements at once
  43. ReadBytes(outT.data(), len * sizeof(T));
  44. }
  45. }
  46. else
  47. outT.clear();
  48. }
  49. /// Read a string from the binary stream (reads the number of characters and then the characters)
  50. template <class Type, class Traits, class Allocator>
  51. void Read(std::basic_string<Type, Traits, Allocator> &outString)
  52. {
  53. uint32 len = 0;
  54. Read(len);
  55. if (!IsEOF() && !IsFailed())
  56. {
  57. outString.resize(len);
  58. ReadBytes(outString.data(), len * sizeof(Type));
  59. }
  60. else
  61. outString.clear();
  62. }
  63. /// Read a vector of primitives from the binary stream using a custom function to read the elements
  64. template <class T, class A, typename F>
  65. void Read(Array<T, A> &outT, const F &inReadElement)
  66. {
  67. uint32 len = uint32(outT.size()); // Initialize to previous array size, this is used for validation in the StateRecorder class
  68. Read(len);
  69. if (!IsEOF() && !IsFailed())
  70. {
  71. outT.resize(len);
  72. for (typename Array<T, A>::size_type i = 0; i < len; ++i)
  73. inReadElement(*this, outT[i]);
  74. }
  75. else
  76. outT.clear();
  77. }
  78. /// Read a Vec3 (don't read W)
  79. void Read(Vec3 &outVec)
  80. {
  81. ReadBytes(&outVec, 3 * sizeof(float));
  82. outVec = Vec3::sFixW(outVec.mValue);
  83. }
  84. /// Read a DVec3 (don't read W)
  85. void Read(DVec3 &outVec)
  86. {
  87. ReadBytes(&outVec, 3 * sizeof(double));
  88. outVec = DVec3::sFixW(outVec.mValue);
  89. }
  90. /// Read a DMat44 (don't read W component of translation)
  91. void Read(DMat44 &outVec)
  92. {
  93. Vec4 x, y, z;
  94. Read(x);
  95. Read(y);
  96. Read(z);
  97. DVec3 t;
  98. Read(t);
  99. outVec = DMat44(x, y, z, t);
  100. }
  101. };
  102. JPH_NAMESPACE_END