aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Documentation/PhysXGuide/Manual/ExtendingSerialization.html
blob: d8372ea5026b88666b43240f39f075c9125f3a4e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Extending Serialization &mdash; NVIDIA PhysX SDK 3.4.2 Documentation</title>
    
    <link rel="stylesheet" href="../_static/nvidia.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/breathe.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '3.4.2',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="top" title="NVIDIA PhysX SDK 3.4.2 Documentation" href="../index.html" />
    <link rel="up" title="User&#39;s Guide" href="Index.html" />
    <link rel="next" title="Best Practices Guide" href="BestPractices.html" />
    <link rel="prev" title="Serialization" href="Serialization.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="BestPractices.html" title="Best Practices Guide"
             accesskey="N">next</a></li>
        <li class="right" >
          <a href="Serialization.html" title="Serialization"
             accesskey="P">previous</a> |</li>
        <li><a href="../Index.html">NVIDIA PhysX SDK 3.4.2 Documentation</a> &raquo;</li>
          <li><a href="Index.html" accesskey="U">User's Guide</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="extending-serialization">
<span id="extendedserialization"></span><h1>Extending Serialization<a class="headerlink" href="#extending-serialization" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>The PhysX serialization system (<a class="reference internal" href="Serialization.html#serialization"><em>Serialization</em></a>) is extendable to custom types.  If an application were to require a new joint type, for example, the serialization system could be extended to add support for serialization of that new joint type.</p>
<p>The following document contains some recipes and example code that show how PhysX serialization may be extended to custom types. It doesn't cover all aspects of the extension mechanisms. It is therefore advisable to look into the following implementation example for more details:</p>
<ul class="simple">
<li>PhysXVehicle library (PhysXVehicle/src)</li>
</ul>
</div>
<div class="section" id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p>Both binary and RepX serialization can be extended for custom types.  To prepare the custom type for serialization it must first inherit from <em>PxBase</em>.  This allows instances of the custom type to be added to a <em>PxCollection</em>, which is a pre-requisite for serialization.  The core serialization functionality needs to be provided by implementing the <em>PxSerializer</em> interface.  The template <em>PxSerializerDefaultAdapter</em> provides a default implementation and can be specialized for the custom type as required.  In order to support RepX serialization an additional <em>PxRepXSerializer</em> interface needs to be implemented. RepX serialization relies on automatic code generation using clang. Scripts to run the code generation for the examples can be found in (Tools/PhysXMetaDataGenerator).</p>
</div>
<div class="section" id="binary-serialization-of-custom-classes">
<span id="binaryserializationofcustomclasses"></span><h2>Binary Serialization of Custom Classes<a class="headerlink" href="#binary-serialization-of-custom-classes" title="Permalink to this headline"></a></h2>
<p>Serialization and deserialization of a custom class can be achieved with the following steps:</p>
<ol class="arabic simple">
<li>Define a <em>PxConcreteType</em> and type info for the custom class. Make sure its type value is unique.</li>
<li>The custom class needs to inherit from <em>PxBase</em> and implement its interface.</li>
<li>Instance PxSerializerDefaultAdapter&lt;T&gt; and implement specialized methods where necessary.</li>
<li>If retargeting to other platforms is needed, implement <em>getBinaryMetaData()</em>.</li>
<li>Register the adapter and metadata, see <em>PX_NEW_SERIALIZER_ADAPTER</em> , <em>PxSerializationRegistry::registerSerializer</em> and <em>PxSerializationRegistry::registerBinaryMetaDataCallback</em>. Note that serializers also need to be unregistered before <em>PxSerializationRegistry::release</em> is called. The application is responsible for custom type serializer allocation and deallocation.</li>
</ol>
<p>For pointer members the following needs to be done (Note that reference members are currently not supported):</p>
<ol class="arabic simple" start="6">
<li>Implement <em>PxSerializer::requires</em>. It should enumerate <em>PxBase</em> objects on which the object depends for deserialization. See <a class="reference internal" href="Serialization.html#requires"><em>Requires</em></a>.</li>
<li>For a member pointer to another <em>PxBase</em> object, register the reference in the implementation of <em>PxSerializer::registerReferences</em>. The implementation of <em>PxSerializer::requires</em> may be used to help with this.</li>
<li>Resolve references in the implementation of <em>PxSerializer::createObject</em> using <em>PxDeserializationContext::resolveReference, translatePxBase</em>.</li>
<li>Make sure that <em>PxSerializer::isSubordinate</em> returns whether the object can only be serialized along with an owner object. See <a class="reference internal" href="Serialization.html#subordinate"><em>Subordinate</em></a>.</li>
<li>Export non <em>PxBase</em> data by implementing <em>PxSerializer::exportExtraData</em> using <em>PxSerializationContext::writeData, alignData</em>.</li>
<li>Import non <em>PxBase</em> data in the implementation of <em>PxSerializer::createObject</em> using <em>PxDeserializationContext::readExtraData, alignExtraData</em>.</li>
</ol>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In checked builds (PX_CHECKED defined as 1) metadata definitions are verified against serialized data. If metadata definitions are missing warnings are output on the error stream during re-targeting (<em>PxBinaryConverter::convert</em>). To avoid false warnings, all unused memory in custom serialized class instances should be marked with a 0xcd pattern. This can be done with <em>Cm::markSerializedMem</em> from CmUtils.h.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The memory of a deserialized class instance should not be deallocated. The memory is embedded in the memory buffer containing the serialized data. The flag PxBaseFlag::eOWNS_MEMORY can used to decide whether the object memory needs be deallocated or not.</p>
</div>
<p>Example for a custom class:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include &quot;extensions/PxSerialization.h&quot;</span>
<span class="cp">#include &quot;common/PxTypeInfo.h&quot;</span>
<span class="cp">#include &quot;common/PxMetaData.h&quot;</span>
<span class="cp">#include &quot;common/PxSerializer.h&quot;</span>
<span class="cp">#include &quot;common/PxSerialFramework.h</span>

<span class="k">using</span> <span class="k">namespace</span> <span class="n">physx</span><span class="p">;</span>

<span class="k">const</span> <span class="n">PxType</span> <span class="n">customClassType</span> <span class="o">=</span> <span class="n">PxConcreteType</span><span class="o">::</span><span class="n">eFIRST_USER_EXTENSION</span><span class="p">;</span>
<span class="n">PX_DEFINE_TYPEINFO</span><span class="p">(</span><span class="n">CustomClass</span><span class="p">,</span> <span class="n">customClassType</span><span class="p">);</span>

<span class="k">class</span> <span class="nc">CustomClass</span> <span class="o">:</span> <span class="k">public</span> <span class="n">PxBase</span>
<span class="p">{</span>
    <span class="k">friend</span> <span class="k">class</span> <span class="nc">PxSerializerDefaultAdapter</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span><span class="p">;</span>
<span class="nl">public:</span>

    <span class="c1">// constructor setting up PxBase object</span>
    <span class="n">CustomClass</span><span class="p">()</span>
    <span class="o">:</span> <span class="n">PxBase</span><span class="p">(</span><span class="n">customClassType</span><span class="p">,</span> <span class="n">PxBaseFlag</span><span class="o">::</span><span class="n">eOWNS_MEMORY</span> <span class="o">|</span> <span class="n">PxBaseFlag</span><span class="o">::</span><span class="n">eIS_RELEASABLE</span><span class="p">)</span>
    <span class="p">{}</span>

    <span class="c1">// constructor called on deserialization</span>
    <span class="n">CustomClass</span><span class="p">(</span><span class="n">PxBaseFlags</span> <span class="n">baseFlags</span><span class="p">)</span> <span class="o">:</span> <span class="n">PxBase</span><span class="p">(</span><span class="n">baseFlags</span><span class="p">)</span> <span class="p">{}</span>

    <span class="k">virtual</span> <span class="o">~</span><span class="n">CustomClass</span><span class="p">()</span> <span class="p">{}</span>


    <span class="c1">//PxBase</span>
    <span class="k">virtual</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">getConcreteTypeName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;CustomClass&quot;</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">virtual</span> <span class="kt">bool</span> <span class="n">isKindOf</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">name</span><span class="p">)</span> <span class="k">const</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="o">!</span><span class="n">strcmp</span><span class="p">(</span><span class="s">&quot;CustomClass&quot;</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">||</span> <span class="n">PxBase</span><span class="o">::</span><span class="n">isKindOf</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">//~PxBase</span>

    <span class="c1">//PxSerializationRegistry::registerBinaryMetaDataCallback</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="n">getBinaryMetaData</span><span class="p">(</span><span class="n">PxOutputStream</span><span class="o">&amp;</span> <span class="n">stream</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">PX_DEF_BIN_METADATA_VCLASS</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">)</span>
        <span class="n">PX_DEF_BIN_METADATA_BASE_CLASS</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">,</span> <span class="n">PxBase</span><span class="p">)</span>

        <span class="n">PX_DEF_BIN_METADATA_ITEM</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">,</span> <span class="n">PxRigidDynamic</span><span class="p">,</span> <span class="n">mActor</span><span class="p">,</span>
            <span class="n">PxMetaDataFlag</span><span class="o">::</span><span class="n">ePTR</span><span class="p">)</span>
        <span class="n">PX_DEF_BIN_METADATA_ITEM</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">,</span> <span class="kt">char</span><span class="p">,</span> <span class="n">mBuf</span><span class="p">,</span> <span class="n">PxMetaDataFlag</span><span class="o">::</span><span class="n">ePTR</span><span class="p">)</span>
        <span class="n">PX_DEF_BIN_METADATA_ITEM</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">,</span> <span class="n">PxU32</span><span class="p">,</span> <span class="n">mSize</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>

        <span class="n">PX_DEF_BIN_METADATA_EXTRA_ITEMS</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">CustomClass</span><span class="p">,</span> <span class="kt">char</span><span class="p">,</span> <span class="n">mBuf</span><span class="p">,</span> <span class="n">mSize</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="c1">//~PxSerializationRegistry::registerBinaryMetaDataCallback</span>

<span class="nl">private:</span>
    <span class="n">PxRigidDynamic</span><span class="o">*</span> <span class="n">mActor</span><span class="p">;</span>    <span class="c1">//add in requires</span>
    <span class="kt">char</span><span class="o">*</span> <span class="n">mBuf</span><span class="p">;</span>                <span class="c1">//extra data</span>
    <span class="n">PxU32</span> <span class="n">mSize</span><span class="p">;</span>               <span class="c1">//size of mBuf</span>
<span class="p">};</span>

<span class="c1">//PxSerializerDefaultAdapter</span>
<span class="k">template</span><span class="o">&lt;&gt;</span>
<span class="kt">void</span> <span class="n">PxSerializerDefaultAdapter</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;::</span><span class="n">requires</span><span class="p">(</span><span class="n">PxBase</span><span class="o">&amp;</span> <span class="n">obj</span><span class="p">,</span>
                                                       <span class="n">PxProcessPxBaseCallback</span><span class="o">&amp;</span> <span class="n">c</span><span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="n">CustomClass</span><span class="o">*</span> <span class="n">custom</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="n">is</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span><span class="p">();</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">custom</span><span class="p">);</span>
    <span class="n">c</span><span class="p">.</span><span class="n">process</span><span class="p">(</span><span class="o">*</span><span class="n">custom</span><span class="o">-&gt;</span><span class="n">mActor</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;&gt;</span>
<span class="kt">void</span> <span class="n">PxSerializerDefaultAdapter</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;::</span><span class="n">registerReferences</span><span class="p">(</span><span class="n">PxBase</span><span class="o">&amp;</span> <span class="n">obj</span><span class="p">,</span>
                                                                 <span class="n">PxSerializationContext</span><span class="o">&amp;</span> <span class="n">s</span><span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="n">CustomClass</span><span class="o">*</span> <span class="n">custom</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="n">is</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span><span class="p">();</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">custom</span><span class="p">);</span>

    <span class="n">s</span><span class="p">.</span><span class="n">registerReference</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">PX_SERIAL_REF_KIND_PXBASE</span><span class="p">,</span> <span class="kt">size_t</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj</span><span class="p">));</span>
    <span class="n">s</span><span class="p">.</span><span class="n">registerReference</span><span class="p">(</span><span class="o">*</span><span class="n">custom</span><span class="o">-&gt;</span><span class="n">mActor</span><span class="p">,</span> <span class="n">PX_SERIAL_REF_KIND_PXBASE</span><span class="p">,</span> <span class="kt">size_t</span><span class="p">(</span><span class="n">custom</span><span class="o">-&gt;</span><span class="n">mActor</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;&gt;</span>
<span class="kt">void</span> <span class="n">PxSerializerDefaultAdapter</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;::</span><span class="n">exportExtraData</span><span class="p">(</span><span class="n">PxBase</span><span class="o">&amp;</span> <span class="n">obj</span><span class="p">,</span>
                                                              <span class="n">PxSerializationContext</span><span class="o">&amp;</span> <span class="n">s</span><span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="n">CustomClass</span><span class="o">*</span> <span class="n">custom</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="n">is</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span><span class="p">();</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">custom</span><span class="p">);</span>
    <span class="n">s</span><span class="p">.</span><span class="n">alignData</span><span class="p">(</span><span class="n">PX_SERIAL_ALIGN</span><span class="p">);</span>
    <span class="n">s</span><span class="p">.</span><span class="n">writeData</span><span class="p">(</span><span class="n">custom</span><span class="o">-&gt;</span><span class="n">mBuf</span><span class="p">,</span> <span class="n">custom</span><span class="o">-&gt;</span><span class="n">mSize</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;&gt;</span>
<span class="n">PxBase</span><span class="o">*</span> <span class="n">PxSerializerDefaultAdapter</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;::</span><span class="n">createObject</span><span class="p">(</span><span class="n">PxU8</span><span class="o">*&amp;</span> <span class="n">address</span><span class="p">,</span>
                                                              <span class="n">PxDeserializationContext</span><span class="o">&amp;</span> <span class="n">context</span><span class="p">)</span>
                                                              <span class="k">const</span>
<span class="p">{</span>
    <span class="n">CustomClass</span><span class="o">*</span> <span class="n">custom</span> <span class="o">=</span> <span class="k">new</span> <span class="p">(</span><span class="n">address</span><span class="p">)</span> <span class="n">CustomClass</span><span class="p">(</span><span class="n">PxBaseFlag</span><span class="o">::</span><span class="n">eIS_RELEASABLE</span><span class="p">);</span>
    <span class="n">address</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">CustomClass</span><span class="p">);</span>

    <span class="c1">// resolve references</span>
    <span class="n">context</span><span class="p">.</span><span class="n">translatePtr</span><span class="p">(</span><span class="n">custom</span><span class="o">-&gt;</span><span class="n">mActor</span><span class="p">);</span>

    <span class="c1">// import extra data</span>
    <span class="n">custom</span><span class="o">-&gt;</span><span class="n">mBuf</span> <span class="o">=</span> <span class="n">context</span><span class="p">.</span><span class="n">readExtraData</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">*</span><span class="p">,</span> <span class="n">PX_SERIAL_ALIGN</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="c1">// return deserialized object</span>
    <span class="k">return</span> <span class="n">custom</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">//~PxSerializerDefaultAdapter</span>

<span class="kt">void</span> <span class="n">registerCustomClassBinarySerializer</span><span class="p">(</span><span class="n">PxSerializationRegistry</span><span class="o">&amp;</span> <span class="n">registry</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">registry</span><span class="p">.</span><span class="n">registerSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">,</span> <span class="n">PX_NEW_SERIALIZER_ADAPTER</span><span class="p">(</span><span class="n">CustomClass</span><span class="p">));</span>
    <span class="n">registry</span><span class="p">.</span><span class="n">registerBinaryMetaDataCallback</span><span class="p">(</span><span class="n">CustomClass</span><span class="o">::</span><span class="n">getBinaryMetaData</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="n">unregisterCustomClassBinarySerializer</span><span class="p">(</span><span class="n">PxSerializationRegistry</span><span class="o">&amp;</span> <span class="n">registry</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">PX_DELETE_SERIALIZER_ADAPTER</span><span class="p">(</span><span class="n">registry</span><span class="p">.</span><span class="n">unregisterSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="repx-serialization-of-custom-classes">
<h2>RepX Serialization of Custom Classes<a class="headerlink" href="#repx-serialization-of-custom-classes" title="Permalink to this headline"></a></h2>
<p>Serialization and deserialization of a custom class can be achieved with the following steps:</p>
<ol class="arabic simple">
<li>Perform the first three steps from <a class="reference internal" href="#binaryserializationofcustomclasses"><em>Binary Serialization of Custom Classes</em></a>. Methods in <em>PxSerializer</em> and <em>PxSerializerDefaultAdapter&lt;T&gt;</em> required exclusively for binary serialization may be left empty.</li>
<li>Create a custom RepX serializer that implements the <em>PxRepXSerializer</em> interface. <em>PxRepXSerializer</em> is used to create an object from the xml file and write an object to the xml file. The class <em>RepXSerializerImpl</em> can be used to inherit default implementations of some methods.</li>
<li>Register the general serializer adapter and the RepX serializer. Note that custom type serializers also need to be unregistered and deallocated.</li>
<li>RepX supports automatic reading and writing of class properties. To achieve this, clang has to be used to generate corresponding metadata: <a class="reference internal" href="#physxmetadata"><em>PhysX API Metadata System</em></a>.</li>
</ol>
<p>Example for a custom class:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include &quot;SnRepXSerializerImpl.h&quot;</span>

<span class="k">const</span> <span class="n">PxType</span> <span class="n">customClassType</span> <span class="o">=</span> <span class="n">PxConcreteType</span><span class="o">::</span><span class="n">eFIRST_USER_EXTENSION</span><span class="p">;</span>
<span class="n">PX_DEFINE_TYPEINFO</span><span class="p">(</span><span class="n">CustomClass</span><span class="p">,</span> <span class="n">customClassType</span><span class="p">);</span>

<span class="k">struct</span> <span class="n">CustomClassRepXSerializer</span> <span class="o">:</span> <span class="k">public</span> <span class="n">RepXSerializerImpl</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="n">CustomClassRepXSerializer</span><span class="p">(</span><span class="n">PxAllocatorCallback</span><span class="o">&amp;</span> <span class="n">inCallback</span><span class="p">)</span>
    <span class="o">:</span> <span class="n">RepXSerializerImpl</span><span class="o">&lt;</span><span class="n">CustomClass</span><span class="o">&gt;</span><span class="p">(</span><span class="n">inCallback</span><span class="p">)</span>
    <span class="p">{}</span>

    <span class="k">virtual</span> <span class="n">PxRepXObject</span> <span class="n">fileToObject</span><span class="p">(</span><span class="n">XmlReader</span><span class="o">&amp;</span> <span class="n">inReader</span><span class="p">,</span> <span class="n">XmlMemoryAllocator</span><span class="o">&amp;</span> <span class="n">inAllocator</span><span class="p">,</span>
        <span class="n">PxRepXInstantiationArgs</span><span class="o">&amp;</span> <span class="n">inArgs</span><span class="p">,</span> <span class="n">PxCollection</span><span class="o">*</span> <span class="n">inCollection</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// factory for CustomClass instance provided by application</span>
        <span class="n">CustomClass</span><span class="o">*</span> <span class="n">object</span> <span class="o">=</span> <span class="n">createCustomClass</span><span class="p">();</span>

        <span class="c1">// when using the PhysX API metadata system readAllProperties(...) can be used to read</span>
        <span class="c1">// all properties automatically</span>
        <span class="n">readAllProperties</span><span class="p">(</span><span class="n">inArgs</span><span class="p">,</span> <span class="n">inReader</span><span class="p">,</span> <span class="n">object</span><span class="p">,</span> <span class="n">inAllocator</span><span class="p">,</span> <span class="o">*</span><span class="n">inCollection</span><span class="p">);</span>

        <span class="k">return</span> <span class="nf">PxCreateRepXObject</span><span class="p">(</span><span class="n">object</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">objectToFileImpl</span><span class="p">(</span><span class="k">const</span> <span class="n">CustomClass</span><span class="o">*</span> <span class="n">obj</span><span class="p">,</span> <span class="n">PxCollection</span><span class="o">*</span> <span class="n">inCollection</span><span class="p">,</span>
                                  <span class="n">XmlWriter</span><span class="o">&amp;</span> <span class="n">inWriter</span><span class="p">,</span> <span class="n">MemoryBuffer</span><span class="o">&amp;</span> <span class="n">inTempBuffer</span><span class="p">,</span>
                                  <span class="n">PxRepXInstantiationArgs</span><span class="o">&amp;</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// when using the PhysX API metadata system writeAllProperties(...) can be used to save</span>
        <span class="c1">// all properties automatically</span>
        <span class="n">writeAllProperties</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">inWriter</span><span class="p">,</span> <span class="n">inTempBuffer</span><span class="p">,</span> <span class="o">*</span><span class="n">inCollection</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="c1">// this can return NULL if fileToObject(...) is overwritten with a custom implementation.</span>
    <span class="k">virtual</span> <span class="n">CustomClass</span><span class="o">*</span> <span class="n">allocateObject</span><span class="p">(</span><span class="n">PxRepXInstantiationArgs</span><span class="o">&amp;</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>

<span class="kt">void</span> <span class="nf">registerCustomClassRepXSerializer</span><span class="p">(</span><span class="n">PxSerializationRegistry</span><span class="o">&amp;</span> <span class="n">registry</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">registry</span><span class="p">.</span><span class="n">registerSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">,</span>
                                <span class="n">PX_NEW_SERIALIZER_ADAPTER</span><span class="p">(</span><span class="n">CustomClass</span><span class="p">));</span>

    <span class="n">registry</span><span class="p">.</span><span class="n">registerRepXSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">,</span>
                                    <span class="n">PX_NEW_REPX_SERIALIZER</span><span class="o">&lt;</span><span class="n">CustomClassRepXSerializer</span><span class="o">&gt;</span><span class="p">));</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">unregisterCustomClassRepXSerializer</span><span class="p">(</span><span class="n">PxSerializationRegistry</span><span class="o">&amp;</span> <span class="n">registry</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">PX_DELETE_SERIALIZER_ADAPTER</span><span class="p">(</span><span class="n">registry</span><span class="p">.</span><span class="n">unregisterSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">));</span>
    <span class="n">PX_DELETE_REPX_SERIALIZER</span><span class="p">(</span><span class="n">registry</span><span class="p">.</span><span class="n">unregisterRepXSerializer</span><span class="p">(</span><span class="n">customClassType</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Implementing a PxRepXSerializer is currently not practical without including the internal PhysXExtension header &quot;SnRepXSerializerImpl.h&quot;.</p>
</div>
<div class="section" id="physx-api-metadata-system">
<span id="physxmetadata"></span><h3>PhysX API Metadata System<a class="headerlink" href="#physx-api-metadata-system" title="Permalink to this headline"></a></h3>
<p>This system produces a set of objects that are analogues of the interfaces and of descriptors in the PhysX system, all based on the public interface. The generator heuristically finds functions that start with get/set and, through a series of cascading rules, combines those into several types of properties.</p>
<p>Currently the generator supports the following property types:</p>
<ul class="simple">
<li>Basic property<ul>
<li>{ptype} get{pname}() const;</li>
<li>void set{pname}( const ptype&amp; prop ); //plus variations</li>
<li>read-only, write-only variants of above.</li>
</ul>
</li>
<li>Range property<ul>
<li>void get{pname}( {ptype}&amp; lowEnd, {ptype}&amp; highEnd );</li>
<li>void set{pname}( {ptype} lowEnd, {ptype} highEnd );</li>
</ul>
</li>
<li>Indexed property<ul>
<li>{ptype} get{pname}( enumType idx );</li>
<li>void set{pname}( enumType idx, const {ptype}&amp; prop );</li>
</ul>
</li>
<li>Dual indexed property (like above, but with two enumeration indexes).</li>
<li>Collection<ul>
<li>PxU32 getNb() const;</li>
<li>PxU32 get( {ptype}* buffer, PxU32 count );</li>
<li>void set({ptype}* buffer, PxU32 count);</li>
</ul>
</li>
</ul>
<p>In order to make use of the generator the following files need to be created with the following recipe:</p>
<ul>
<li><p class="first">CustomTypeExtensionAPI.h</p>
<ul class="simple">
<li>Add all the types that should be exported to gUserPhysXTypes to this file.</li>
<li>Add the unnecessary types to gAvoidedPhysXTypes. It will not generate metadata information for these types.</li>
<li>Be sure to append the included files for these types.</li>
</ul>
</li>
<li><p class="first">runClang_[windows|osx|linux].[bat|sh] (e.g. runClang_windows.bat)</p>
<ul>
<li><p class="first">Set definition folder for these autogenerated files and set the source file in here.</p>
</li>
<li><p class="first">Specify the filename of autogenerated files. Then it will generate the following files:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">include</span><span class="o">/</span><span class="n">CustomTypeAutoGeneratedMetaDataObjectNames</span><span class="p">.</span><span class="n">h</span>
<span class="n">include</span><span class="o">/</span><span class="n">CustomTypeAutoGeneratedMetaDataObjects</span><span class="p">.</span><span class="n">h</span>
<span class="n">src</span><span class="o">/</span><span class="n">CustomTypeAutoGeneratedMetaDataObjects</span><span class="p">.</span><span class="n">cpp</span>
</pre></div>
</div>
</li>
</ul>
</li>
<li><p class="first">CustomTypeMetaDataObjects.h</p>
<ul class="simple">
<li>CustomTypePropertyInfoName has to be defined and CustomTypeAutoGeneratedMetaDataObjects.h has to be included in this file. The file will then export the properties of the custom class and can be included for implementing the custom RepX serializer.</li>
</ul>
</li>
<li><p class="first">CustomTypeMetaDataObjects.cpp</p>
<ul class="simple">
<li>This file is optional. It is only required when custom properties are needed.</li>
</ul>
</li>
</ul>
<p>PxVehicle serialization is a useful example.  With Source/PhysXVehicle as the root folder the structure of the files is as follows:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">src</span><span class="o">/</span><span class="n">PhysXMetaData</span><span class="o">/</span><span class="n">include</span><span class="o">/</span><span class="n">PxVehicleMetaDataObjects</span><span class="p">.</span><span class="n">h</span>
<span class="n">src</span><span class="o">/</span><span class="n">PhysXMetaData</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">PxVehicleMetaDataObjects</span><span class="p">.</span><span class="n">cpp</span>
<span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="n">Tools</span><span class="o">/</span><span class="n">PhysXMetaDataGenerator</span><span class="o">/</span><span class="n">PxVehicleExtensionAPI</span><span class="p">.</span><span class="n">h</span>
<span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="n">Tools</span><span class="o">/</span><span class="n">PhysXMetaDataGenerator</span><span class="o">/</span><span class="n">generateMetaData</span><span class="p">.</span><span class="n">py</span>
</pre></div>
</div>
<p>Running the script will auto-generate the following files:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">src</span><span class="o">/</span><span class="n">PhysXMetaData</span><span class="o">/</span><span class="n">include</span><span class="o">/</span><span class="n">PxVehicleAutoGeneratedMetaDataObjectNames</span><span class="p">.</span><span class="n">h</span>
<span class="n">src</span><span class="o">/</span><span class="n">PhysXMetaData</span><span class="o">/</span><span class="n">include</span><span class="o">/</span><span class="n">PxVehicleAutoGeneratedMetaDataObjects</span><span class="p">.</span><span class="n">h</span>
<span class="n">src</span><span class="o">/</span><span class="n">PhysXMetaData</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">PxVehicleAutoGeneratedMetaDataObjects</span><span class="p">.</span><span class="n">cpp</span>
</pre></div>
</div>
<ol class="arabic simple">
<li>PxVehicleExtensionAPI.h: The type DisabledPropertyEntry is used to mark properties which do not require export. CustomProperty is for properties that need to be customized and gUserPhysXTypes is for general properties that need to be exported.</li>
<li>runClang_[windows|osx|linux].[bat|sh]: The target directory is set to src/PhysXMetaData, and the target name is PxVehicle.</li>
<li>PxVehicleMetaDataObjects.h: It defines the custom properties and includes PxVehicleAutoGeneratedMetaDataObjects.h</li>
<li>PxVehicleMetaDataObjects.cpp: It implements the custom properties.</li>
</ol>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The properties defined in PxVehicleAutoGeneratedMetaDataObjects.h are written to the RepX file automatically if PxVehicleMetaDataObjects.h is included for the custom RepX serializer.</p>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../Index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Extending Serialization</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#overview">Overview</a></li>
<li><a class="reference internal" href="#binary-serialization-of-custom-classes">Binary Serialization of Custom Classes</a></li>
<li><a class="reference internal" href="#repx-serialization-of-custom-classes">RepX Serialization of Custom Classes</a><ul>
<li><a class="reference internal" href="#physx-api-metadata-system">PhysX API Metadata System</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="Serialization.html"
                        title="previous chapter">Serialization</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="BestPractices.html"
                        title="next chapter">Best Practices Guide</a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="BestPractices.html" title="Best Practices Guide"
             >next</a></li>
        <li class="right" >
          <a href="Serialization.html" title="Serialization"
             >previous</a> |</li>
        <li><a href="../Index.html">NVIDIA PhysX SDK 3.4.2 Documentation</a> &raquo;</li>
          <li><a href="Index.html" >User's Guide</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2008-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved.
    </div>
  </body>
</html>