1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
11// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
12
13
14#ifndef PX_SERIALIZER_H
15#define PX_SERIALIZER_H
16/** \addtogroup extensions
17@{
18*/
19
20#include "PxSerialFramework.h"
21#include "PxCollection.h"
22#include "foundation/PxAssert.h"
23
24#ifndef PX_DOXYGEN
25namespace physx
26{
27#endif
28
29/**
30 \brief Serialization interface class.
31
32 PxSerializer is used to extend serializable PxBase classes with serialization functionality. The
33 interface is structured such that per-class adapter instances can be used as opposed to per-object
34 adapter instances, avoiding per object allocations. Hence the methods take a reference to PxBase as a parameter.
35
36 The PxSerializer interface needs to be implemented for binary or RepX serialization to work on custom
37 types. If only RepX serialization is needed, some methods can be left empty, as they are only needed
38 for binary serialization.
39
40 A default implementation is available as a template adapter (PxSerializerDefaultAdapter).
41
42 @see PxSerializerDefaultAdapter, PX_NEW_SERIALIZER_ADAPTER, PxSerializationRegistry::registerSerializer
43*/
44class PxSerializer
45{
46public:
47
48 /**********************************************************************************************************************/
49
50 /** @name Basics needed for Binary- and RepX-Serialization
51 */
52 //@{
53
54 /**
55 \brief Returns string name of dynamic type.
56
57 \return Class name of most derived type of this object.
58 */
59 virtual const char* getConcreteTypeName() const = 0;
60
61 /**
62 \brief Adds required objects to the collection.
63
64 This method does not add the required objects recursively, e.g. objects required by required objects.
65
66 @see PxCollection, PxSerialization::complete
67 */
68 virtual void requires(PxBase&, PxProcessPxBaseCallback&) const = 0;
69
70 /**
71 \brief Whether the object is subordinate.
72
73 A class is subordinate, if it can only be instantiated in the context of another class.
74
75 \return Whether the class is subordinate
76
77 @see PxSerialization::isSerializable
78 */
79 virtual bool isSubordinate() const = 0;
80
81 //@}
82 /**********************************************************************************************************************/
83
84 /**********************************************************************************************************************/
85
86 /** @name Functionality needed for Binary Serialization only
87 */
88 //@{
89
90 /**
91 \brief Exports object's extra data to stream.
92 */
93 virtual void exportExtraData(PxBase&, PxSerializationContext&) const = 0;
94
95 /**
96 \brief Exports object's data to stream.
97 */
98 virtual void exportData(PxBase&, PxSerializationContext&) const = 0;
99
100 /**
101 \brief Register references that the object maintains to other objects.
102 */
103 virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const = 0;
104
105 /**
106 \brief Returns size needed to create the class instance.
107
108 \return sizeof class instance.
109 */
110 virtual size_t getClassSize() const = 0;
111
112 /**
113 \brief Create object at a given address, resolve references and import extra data.
114
115 \param address Location at which object is created. Address is increased by the size of the created object.
116 \param context Context for reading external data and resolving references.
117 \return Created PxBase pointer (needs to be identical to address before increment).
118 */
119 virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const = 0;
120
121 //@}
122 /**********************************************************************************************************************/
123 virtual ~PxSerializer() {}
124};
125
126
127/**
128 \brief Default PxSerializer implementation.
129*/
130template<class T>
131class PxSerializerDefaultAdapter : public PxSerializer
132{
133public:
134
135 /************************************************************************************************/
136
137 /** @name Basics needed for Binary- and RepX-Serialization
138 */
139 //@{
140
141 PxSerializerDefaultAdapter(const char* name) : mTypeName(name){}
142
143 virtual const char* getConcreteTypeName() const
144 {
145 return mTypeName;
146 }
147
148 virtual void requires(PxBase& obj, PxProcessPxBaseCallback& c) const
149 {
150 T& t = static_cast<T&>(obj);
151 t.requires(c);
152 }
153
154 virtual bool isSubordinate() const
155 {
156 return false;
157 }
158
159 //@}
160 /************************************************************************************************/
161
162 /** @name Functionality needed for Binary Serialization only
163 */
164 //@{
165
166 // object methods
167
168 virtual void exportExtraData(PxBase& obj, PxSerializationContext& s) const
169 {
170 T& t = static_cast<T&>(obj);
171 t.exportExtraData(s);
172 }
173
174 virtual void exportData(PxBase& obj, PxSerializationContext& s) const
175 {
176 s.writeData(&obj, sizeof(T));
177 }
178
179 virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const
180 {
181 T& t = static_cast<T&>(obj);
182
183 s.registerReference(obj, PX_SERIAL_REF_KIND_PXBASE, size_t(&obj));
184
185 struct RequiresCallback : public PxProcessPxBaseCallback
186 {
187 RequiresCallback(PxSerializationContext& c) : context(c) {}
188 RequiresCallback& operator=(RequiresCallback&) { PX_ASSERT(0); return *this; }
189 void process(physx::PxBase& base)
190 {
191 context.registerReference(base, PX_SERIAL_REF_KIND_PXBASE, size_t(&base));
192 }
193 PxSerializationContext& context;
194 };
195
196 RequiresCallback callback(s);
197 t.requires(callback);
198 }
199
200 // class methods
201
202 virtual size_t getClassSize() const
203 {
204 return sizeof(T);
205 }
206
207 virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const
208 {
209 return T::createObject(address, context);
210 }
211
212
213 //@}
214 /************************************************************************************************/
215
216private:
217 const char* mTypeName;
218};
219
220/**
221 \brief Preprocessor Macro to simplify adapter creation.
222
223 Note: that the allocator used for creation needs to match with the one used in PX_DELETE_SERIALIZER_ADAPTER.
224*/
225#define PX_NEW_SERIALIZER_ADAPTER(x) \
226 *new( PxGetFoundation().getAllocatorCallback().allocate(sizeof(PxSerializerDefaultAdapter<x>), \
227 "PxSerializerDefaultAdapter", __FILE__, __LINE__ )) PxSerializerDefaultAdapter<x>(#x)
228
229/**
230 \brief Preprocessor Macro to simplify adapter deletion.
231*/
232#define PX_DELETE_SERIALIZER_ADAPTER(x) \
233 { PxSerializer* s = x; if (s) { s->~PxSerializer(); PxGetFoundation().getAllocatorCallback().deallocate(s); } }
234
235#ifndef PX_DOXYGEN
236} // namespace physx
237#endif
238
239/** @} */
240#endif
241