Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
StreamUtils.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <Jolt/Core/Result.h>
11#include <Jolt/Core/Factory.h>
12
14
15namespace StreamUtils {
16
17template <class Type>
19
20template <class Type>
22
23// Restore a single object by reading the hash of the type, constructing it and then calling the restore function
24template <class Type>
25Result<Ref<Type>> RestoreObject(StreamIn &inStream, void (Type::*inRestoreBinaryStateFunction)(StreamIn &))
26{
27 Result<Ref<Type>> result;
28
29 // Read the hash of the type
30 uint32 hash;
31 inStream.Read(hash);
32 if (inStream.IsEOF() || inStream.IsFailed())
33 {
34 result.SetError("Failed to read type hash");
35 return result;
36 }
37
38 // Get the RTTI for the type
39 const RTTI *rtti = Factory::sInstance->Find(hash);
40 if (rtti == nullptr)
41 {
42 result.SetError("Failed to create instance of type");
43 return result;
44 }
45
46 // Construct and read the data of the type
47 Ref<Type> object = reinterpret_cast<Type *>(rtti->CreateObject());
48 (object->*inRestoreBinaryStateFunction)(inStream);
49 if (inStream.IsEOF() || inStream.IsFailed())
50 {
51 result.SetError("Failed to restore object");
52 return result;
53 }
54
55 result.Set(object);
56 return result;
57}
58
60template <class Type>
61void SaveObjectReference(StreamOut &inStream, const Type *inObject, ObjectToIDMap<Type> *ioObjectToIDMap)
62{
63 if (ioObjectToIDMap == nullptr || inObject == nullptr)
64 {
65 // Write null ID
66 inStream.Write(~uint32(0));
67 }
68 else
69 {
70 typename ObjectToIDMap<Type>::const_iterator id = ioObjectToIDMap->find(inObject);
71 if (id != ioObjectToIDMap->end())
72 {
73 // Existing object, write ID
74 inStream.Write(id->second);
75 }
76 else
77 {
78 // New object, write the ID
79 uint32 new_id = uint32(ioObjectToIDMap->size());
80 (*ioObjectToIDMap)[inObject] = new_id;
81 inStream.Write(new_id);
82
83 // Write the object
84 inObject->SaveBinaryState(inStream);
85 }
86 }
87}
88
90template <class Type>
92{
93 Result<Ref<Type>> result;
94
95 // Read id
96 uint32 id = ~uint32(0);
97 inStream.Read(id);
98
99 // Check null
100 if (id == ~uint32(0))
101 {
102 result.Set(nullptr);
103 return result;
104 }
105
106 // Check if it already exists
107 if (id >= ioIDToObjectMap.size())
108 {
109 // New object, restore it
110 result = Type::sRestoreFromBinaryState(inStream);
111 if (result.HasError())
112 return result;
113 JPH_ASSERT(id == ioIDToObjectMap.size());
114 ioIDToObjectMap.push_back(result.Get());
115 }
116 else
117 {
118 // Existing object filter
119 result.Set(ioIDToObjectMap[id].GetPtr());
120 }
121
122 return result;
123}
124
125// Save an array of objects to a stream.
126template <class ArrayType, class ValueType>
127void SaveObjectArray(StreamOut &inStream, const ArrayType &inArray, ObjectToIDMap<ValueType> *ioObjectToIDMap)
128{
129 uint32 len = uint32(inArray.size());
130 inStream.Write(len);
131 for (const ValueType *value: inArray)
132 SaveObjectReference(inStream, value, ioObjectToIDMap);
133}
134
135// Restore an array of objects from a stream.
136template <class ArrayType, class ValueType>
138{
139 Result<ArrayType> result;
140
141 uint32 len;
142 inStream.Read(len);
143 if (inStream.IsEOF() || inStream.IsFailed())
144 {
145 result.SetError("Failed to read stream");
146 return result;
147 }
148
149 ArrayType values;
150 values.reserve(len);
151 for (size_t i = 0; i < len; ++i)
152 {
153 Result value = RestoreObjectReference(inStream, ioIDToObjectMap);
154 if (value.HasError())
155 {
156 result.SetError(value.GetError());
157 return result;
158 }
159 values.push_back(std::move(value.Get()));
160 }
161
162 result.Set(values);
163 return result;
164}
165
166} // StreamUtils
167
#define JPH_NAMESPACE_END
Definition: Core.h:378
std::uint32_t uint32
Definition: Core.h:455
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
std::unordered_map< Key, T, Hash, KeyEqual, STLAllocator< pair< const Key, T > > > UnorderedMap
Definition: UnorderedMap.h:13
Definition: Array.h:36
size_type size() const
Returns amount of elements in the array.
Definition: Array.h:318
void push_back(const T &inValue)
Add element to the back of the array.
Definition: Array.h:275
const RTTI * Find(const char *inName)
Find type info for a specific class by name.
Definition: Factory.cpp:19
static Factory * sInstance
Singleton factory instance.
Definition: Factory.h:40
Definition: RTTI.h:122
void * CreateObject() const
Create an object of this type (returns nullptr if the object is abstract)
Definition: RTTI.cpp:53
Definition: Reference.h:107
Helper class that either contains a valid result or an error.
Definition: Result.h:12
void SetError(const char *inError)
Set an error value.
Definition: Result.h:152
void Set(const Type &inResult)
Set the result value.
Definition: Result.h:140
bool HasError() const
Check if we had an error.
Definition: Result.h:146
const String & GetError() const
Get the error value.
Definition: Result.h:149
const Type & Get() const
Get the result value.
Definition: Result.h:137
Simple binary input stream.
Definition: StreamIn.h:13
void Read(T &outT)
Read a primitive (e.g. float, int, etc.) from the binary stream.
Definition: StreamIn.h:29
virtual bool IsEOF() const =0
Returns true when an attempt has been made to read past the end of the file.
virtual bool IsFailed() const =0
Returns true if there was an IO failure.
Simple binary output stream.
Definition: StreamOut.h:13
void Write(const T &inT)
Write a primitive (e.g. float, int, etc.) to the binary stream.
Definition: StreamOut.h:26
Definition: StreamUtils.h:15
Result< ArrayType > RestoreObjectArray(StreamIn &inStream, IDToObjectMap< ValueType > &ioIDToObjectMap)
Definition: StreamUtils.h:137
Result< Ref< Type > > RestoreObject(StreamIn &inStream, void(Type::*inRestoreBinaryStateFunction)(StreamIn &))
Definition: StreamUtils.h:25
Result< Ref< Type > > RestoreObjectReference(StreamIn &inStream, IDToObjectMap< Type > &ioIDToObjectMap)
Restore an object reference from stream.
Definition: StreamUtils.h:91
void SaveObjectArray(StreamOut &inStream, const ArrayType &inArray, ObjectToIDMap< ValueType > *ioObjectToIDMap)
Definition: StreamUtils.h:127
UnorderedMap< const Type *, uint32 > ObjectToIDMap
Definition: StreamUtils.h:18
void SaveObjectReference(StreamOut &inStream, const Type *inObject, ObjectToIDMap< Type > *ioObjectToIDMap)
Save an object reference to a stream. Uses a map to map objects to IDs which is also used to prevent ...
Definition: StreamUtils.h:61