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>
12#include <Jolt/Core/Factory.h>
13
15
16namespace StreamUtils {
17
18// Restore a single object by reading the hash of the type, constructing it and then calling the restore function
19template <class Type>
20Result<Ref<Type>> RestoreObject(StreamIn &inStream, void (Type::*inRestoreBinaryStateFunction)(StreamIn &))
21{
22 Result<Ref<Type>> result;
23
24 // Read the hash of the type
25 uint32 hash;
26 inStream.Read(hash);
27 if (inStream.IsEOF() || inStream.IsFailed())
28 {
29 result.SetError("Failed to read type hash");
30 return result;
31 }
32
33 // Get the RTTI for the type
34 const RTTI *rtti = Factory::sInstance->Find(hash);
35 if (rtti == nullptr)
36 {
37 result.SetError("Failed to create instance of type");
38 return result;
39 }
40
41 // Construct and read the data of the type
42 Ref<Type> object = reinterpret_cast<Type *>(rtti->CreateObject());
43 (object->*inRestoreBinaryStateFunction)(inStream);
44 if (inStream.IsEOF() || inStream.IsFailed())
45 {
46 result.SetError("Failed to restore object");
47 return result;
48 }
49
50 result.Set(object);
51 return result;
52}
53
55template <class Type>
56void SaveObjectReference(StreamOut &inStream, const Type *inObject, ObjectToIDMap<Type> *ioObjectToIDMap)
57{
58 if (ioObjectToIDMap == nullptr || inObject == nullptr)
59 {
60 // Write null ID
61 inStream.Write(~uint32(0));
62 }
63 else
64 {
65 typename ObjectToIDMap<Type>::const_iterator id = ioObjectToIDMap->find(inObject);
66 if (id != ioObjectToIDMap->end())
67 {
68 // Existing object, write ID
69 inStream.Write(id->second);
70 }
71 else
72 {
73 // New object, write the ID
74 uint32 new_id = uint32(ioObjectToIDMap->size());
75 (*ioObjectToIDMap)[inObject] = new_id;
76 inStream.Write(new_id);
77
78 // Write the object
79 inObject->SaveBinaryState(inStream);
80 }
81 }
82}
83
85template <class Type>
87{
88 Result<Ref<Type>> result;
89
90 // Read id
91 uint32 id = ~uint32(0);
92 inStream.Read(id);
93
94 // Check null
95 if (id == ~uint32(0))
96 {
97 result.Set(nullptr);
98 return result;
99 }
100
101 // Check if it already exists
102 if (id >= ioIDToObjectMap.size())
103 {
104 // New object, restore it
105 result = Type::sRestoreFromBinaryState(inStream);
106 if (result.HasError())
107 return result;
108 JPH_ASSERT(id == ioIDToObjectMap.size());
109 ioIDToObjectMap.push_back(result.Get());
110 }
111 else
112 {
113 // Existing object filter
114 result.Set(ioIDToObjectMap[id].GetPtr());
115 }
116
117 return result;
118}
119
120// Save an array of objects to a stream.
121template <class ArrayType, class ValueType>
122void SaveObjectArray(StreamOut &inStream, const ArrayType &inArray, ObjectToIDMap<ValueType> *ioObjectToIDMap)
123{
124 uint32 len = uint32(inArray.size());
125 inStream.Write(len);
126 for (const ValueType *value: inArray)
127 SaveObjectReference(inStream, value, ioObjectToIDMap);
128}
129
130// Restore an array of objects from a stream.
131template <class ArrayType, class ValueType>
133{
134 Result<ArrayType> result;
135
136 uint32 len;
137 inStream.Read(len);
138 if (inStream.IsEOF() || inStream.IsFailed())
139 {
140 result.SetError("Failed to read stream");
141 return result;
142 }
143
144 ArrayType values;
145 values.reserve(len);
146 for (size_t i = 0; i < len; ++i)
147 {
148 Result value = RestoreObjectReference(inStream, ioIDToObjectMap);
149 if (value.HasError())
150 {
151 result.SetError(value.GetError());
152 return result;
153 }
154 values.push_back(std::move(value.Get()));
155 }
156
157 result.Set(values);
158 return result;
159}
160
161} // StreamUtils
162
#define JPH_NAMESPACE_END
Definition Core.h:425
std::uint32_t uint32
Definition Core.h:503
#define JPH_NAMESPACE_BEGIN
Definition Core.h:419
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
Definition Array.h:36
size_type size() const
Returns amount of elements in the array.
Definition Array.h:397
void push_back(const T &inValue)
Add element to the back of the array.
Definition Array.h:354
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
iterator end()
Iterator to one beyond last element.
Definition HashTable.h:555
size_type size() const
Number of elements in the table.
Definition HashTable.h:603
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:30
virtual bool IsEOF() const =0
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 UnorderedMap.h:31
typename Base::const_iterator const_iterator
Definition UnorderedMap.h:37
iterator find(const Key &inKey)
Non-const version of find.
Definition UnorderedMap.h:74
Definition ObjectToIDMap.h:11
Result< ArrayType > RestoreObjectArray(StreamIn &inStream, IDToObjectMap< ValueType > &ioIDToObjectMap)
Definition StreamUtils.h:132
Result< Ref< Type > > RestoreObject(StreamIn &inStream, void(Type::*inRestoreBinaryStateFunction)(StreamIn &))
Definition StreamUtils.h:20
Result< Ref< Type > > RestoreObjectReference(StreamIn &inStream, IDToObjectMap< Type > &ioIDToObjectMap)
Restore an object reference from stream.
Definition StreamUtils.h:86
void SaveObjectArray(StreamOut &inStream, const ArrayType &inArray, ObjectToIDMap< ValueType > *ioObjectToIDMap)
Definition StreamUtils.h:122
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:56