aboutsummaryrefslogtreecommitdiff
path: root/PxShared/src/pvd/src/PxPvdObjectModel.h
blob: 427989a15177eb8abe160e08516ed2a1aaa896a5 (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
431
432
433
434
435
436
437
// This code contains NVIDIA Confidential Information and is disclosed to you
// under a form of NVIDIA software license agreement provided separately to you.
//
// Notice
// NVIDIA Corporation and its licensors retain all intellectual property and
// proprietary rights in and to this software and related documentation and
// any modifications thereto. Any use, reproduction, disclosure, or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA Corporation is strictly prohibited.
//
// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Information and code furnished is believed to be accurate and reliable.
// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
// information or for any infringement of patents or other rights of third parties that may
// result from its use. No license is granted by implication or otherwise under any patent
// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
// This code supersedes and replaces all information previously supplied.
// NVIDIA Corporation products are not authorized for use as critical
// components in life support devices or systems without express written approval of
// NVIDIA Corporation.
//
// Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.

#ifndef PXPVDSDK_PXPVDOBJECTMODEL_H
#define PXPVDSDK_PXPVDOBJECTMODEL_H

#include "PsBasicTemplates.h"
#include "PxPvdObjectModelMetaData.h"

namespace physx
{
namespace pvdsdk
{

#if PX_VC == 11 || PX_VC == 12 || PX_VC == 14
#pragma warning(push)
#pragma warning(disable : 4435) // 'class1' : Object layout under /vd2 will change due to virtual base 'class2'
#endif

class PvdInputStream;
class PvdOutputStream;

struct InstanceDescription
{
	int32_t mId;
	int32_t mClassId;
	void* mInstPtr;
	bool mAlive;

	InstanceDescription(int32_t id, int32_t classId, void* inst, bool alive)
	: mId(id), mClassId(classId), mInstPtr(inst), mAlive(alive)
	{
	}
	InstanceDescription() : mId(-1), mClassId(-1), mInstPtr(NULL), mAlive(false)
	{
	}
	operator void*()
	{
		PX_ASSERT(mAlive);
		if(mAlive)
			return mInstPtr;
		return NULL;
	}
	operator int32_t()
	{
		return mId;
	}
};

typedef physx::shdfnd::Pair<int32_t, int32_t> InstancePropertyPair;

class PvdObjectModelBase
{
  protected:
	virtual ~PvdObjectModelBase()
	{
	}

  public:
	virtual void addRef() = 0;
	virtual void release() = 0;
	virtual void* idToPtr(int32_t instId) const = 0;
	virtual int32_t ptrToId(void* instPtr) const = 0;
	virtual InstanceDescription idToDescriptor(int32_t instId) const = 0;
	virtual InstanceDescription ptrToDescriptor(void* instPtr) const = 0;
	virtual Option<ClassDescription> getClassOf(void* instId) const = 0;
	virtual const PvdObjectModelMetaData& getMetaData() const = 0;
};

class PvdObjectModelMutator : public virtual PvdObjectModelBase
{
  protected:
	virtual ~PvdObjectModelMutator()
	{
	}

  public:
	// if the instance is alive, this destroyes any arrays and sets the instance back to its initial state.
	virtual InstanceDescription createInstance(int32_t clsId, int32_t instId) = 0;
	virtual InstanceDescription createInstance(int32_t clsId) = 0;
	// Instances that are pinned are not removed from the system, ever.
	// This means that createInstance, pinInstance, deleteInstance
	// can be called in this order and you can still call getClassOf, etc. on the instances.
	// The instances will never be removed from memory if they are pinned, so use at your
	// careful discretion.
	virtual void pinInstance(void* instId) = 0;
	virtual void unPinInstance(void* instId) = 0;
	// when doing capture, should update all events in a section at once, otherwis there possible parse data
	// incompltely.
	virtual void recordCompletedInstances() = 0;

	virtual void destroyInstance(void* instId) = 0;
	virtual int32_t getNextInstanceHandleValue() const = 0;
	// reserve a set of instance handle values by getting the current, adding an amount to it
	// and setting the value.  You can never set the value lower than it already is, it only climbs.
	virtual void setNextInstanceHandleValue(int32_t hdlValue) = 0;
	// If incoming type is provided, then we may be able to marshal simple types
	// This works for arrays, it just completely replaces the entire array.
	// Because if this, it is an error of the property identifier
	virtual bool setPropertyValue(void* instId, int32_t propId, const uint8_t* data, uint32_t dataLen,
	                              int32_t incomingType) = 0;
	// Set a set of properties defined by a property message
	virtual bool setPropertyMessage(void* instId, int32_t msgId, const uint8_t* data, uint32_t dataLen) = 0;
	// insert an element(s) into array index.  If index > numElements, element(s) is(are) appended.
	virtual bool insertArrayElement(void* instId, int32_t propId, int32_t index, const uint8_t* data, uint32_t dataLen,
	                                int32_t incomingType = -1) = 0;
	virtual bool removeArrayElement(void* instId, int32_t propId, int32_t index) = 0;
	// Add this array element to end end if it doesn't already exist in the array.
	// The option is false if there was an error with the function call.
	// The integer has no value if nothing was added, else it tells you the index
	// where the item was added.  Comparison is done using memcmp.
	virtual Option<int32_t> pushBackArrayElementIf(void* instId, int32_t propId, const uint8_t* data, uint32_t dataLen,
	                                               int32_t incomingType = -1) = 0;
	// Remove an array element if it exists in the array.
	// The option is false if there was an error with the function call.
	// the integer has no value if the item wasn't found, else it tells you the index where
	// the item resided.  Comparison is memcmp.
	virtual Option<int32_t> removeArrayElementIf(void* instId, int32_t propId, const uint8_t* data, uint32_t dataLen,
	                                             int32_t incomingType = -1) = 0;
	virtual bool setArrayElementValue(void* instId, int32_t propId, int32_t propIdx, const uint8_t* data,
	                                  uint32_t dataLen, int32_t incomingType) = 0;

	virtual void originShift(void* instId, PxVec3 shift) = 0;

	InstanceDescription createInstance(const NamespacedName& name)
	{
		return createInstance(getMetaData().findClass(name)->mClassId);
	}
	template <typename TDataType>
	bool setPropertyValue(void* instId, const char* propName, const TDataType* dtype, uint32_t count)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return false;
		}
		const PropertyDescription& prop(descOpt);
		Option<ClassDescription> incomingCls(getMetaData().findClass(getPvdNamespacedNameForType<TDataType>()));
		if(incomingCls.hasValue())
			return setPropertyValue(instId, prop.mPropertyId, reinterpret_cast<const uint8_t*>(dtype),
			                        sizeof(*dtype) * count, incomingCls.getValue().mClassId);
		return false;
	}

	// Simplest possible setPropertyValue
	template <typename TDataType>
	bool setPropertyValue(void* instId, const char* propName, const TDataType& dtype)
	{
		return setPropertyValue(instId, propName, &dtype, 1);
	}

	template <typename TDataType>
	bool setPropertyMessage(void* instId, const TDataType& msg)
	{
		Option<PropertyMessageDescription> msgId =
		    getMetaData().findPropertyMessage(getPvdNamespacedNameForType<TDataType>());
		if(msgId.hasValue() == false)
			return false;
		return setPropertyMessage(instId, msgId.getValue().mMessageId, reinterpret_cast<const uint8_t*>(&msg),
		                          sizeof(msg));
	}
	template <typename TDataType>
	bool insertArrayElement(void* instId, const char* propName, int32_t idx, const TDataType& dtype)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return false;
		}
		const PropertyDescription& prop(descOpt);
		Option<ClassDescription> incomingCls(getMetaData().findClass(getPvdNamespacedNameForType<TDataType>()));
		if(incomingCls.hasValue())
		{
			return insertArrayElement(instId, prop.mPropertyId, idx, reinterpret_cast<const uint8_t*>(&dtype),
			                          sizeof(dtype), incomingCls.getValue().mClassId);
		}
		return false;
	}

	bool removeArrayElement(void* instId, const char* propName, int32_t idx)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return false;
		}
		const PropertyDescription& prop(descOpt);
		return removeArrayElement(instId, prop.mPropertyId, idx);
	}
	template <typename TDataType>
	Option<int32_t> pushBackArrayElementIf(void* instId, const char* pname, const TDataType& item)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, pname));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return None();
		}
		const PropertyDescription& prop(descOpt);
		Option<ClassDescription> incomingCls(getMetaData().findClass(getPvdNamespacedNameForType<TDataType>()));
		if(incomingCls.hasValue() && (incomingCls.getValue().mClassId == prop.mDatatype))
		{
			return pushBackArrayElementIf(instId, prop.mPropertyId, reinterpret_cast<const uint8_t*>(&item),
			                              sizeof(item), incomingCls.getValue().mClassId);
		}
		return None();
	}
	template <typename TDataType>
	Option<int32_t> removeArrayElementIf(void* instId, const char* propId, const TDataType& item)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propId));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return None();
		}
		const PropertyDescription& prop(descOpt);
		Option<ClassDescription> incomingCls(getMetaData().findClass(getPvdNamespacedNameForType<TDataType>()));
		if(incomingCls.hasValue() && (incomingCls.getValue().mClassId == prop.mDatatype))
		{
			return removeArrayElementIf(instId, prop.mPropertyId, reinterpret_cast<const uint8_t*>(&item), sizeof(item),
			                            incomingCls.getValue().mClassId);
		}
		return None();
	}
	template <typename TDataType>
	bool setArrayElementValue(void* instId, const char* propName, int32_t propIdx, TDataType& item)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return false;
		}
		const PropertyDescription& prop(descOpt);
		Option<ClassDescription> incomingCls(getMetaData().findClass(getPvdNamespacedNameForType<TDataType>()));
		if(incomingCls.hasValue() && (incomingCls.getValue().mClassId == prop.mDatatype))
			return setArrayElementValue(instId, prop.mPropertyId, propIdx, reinterpret_cast<const uint8_t*>(&item),
			                            sizeof(item), incomingCls.getValue().mClassId);
		PX_ASSERT(false);
		return false;
	}
};

class PvdObjectModelReader : public virtual PvdObjectModelBase
{
  protected:
	virtual ~PvdObjectModelReader()
	{
	}

  public:
	// Return the byte size of a possible nested property
	virtual uint32_t getPropertyByteSize(void* instId, int32_t propId) = 0;
	uint32_t getPropertyByteSize(void* instId, String propName)
	{
		int32_t propId = getMetaData().findProperty(getClassOf(instId)->mClassId, propName)->mPropertyId;
		return getPropertyByteSize(instId, propId);
	}
	// Return the value of a possible nested property
	virtual uint32_t getPropertyValue(void* instId, int32_t propId, uint8_t* outData, uint32_t outDataLen) = 0;
	// Get the actual raw database memory.  This is subject to change drastically if the object gets deleted.
	virtual DataRef<uint8_t> getRawPropertyValue(void* instId, int32_t propId) = 0;

	DataRef<uint8_t> getRawPropertyValue(void* instId, const char* propName)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return 0;
		}
		return getRawPropertyValue(instId, descOpt->mPropertyId);
	}

	template <typename TDataType>
	DataRef<TDataType> getTypedRawPropertyValue(void* instId, int32_t propId)
	{
		DataRef<uint8_t> propVal = getRawPropertyValue(instId, propId);
		return DataRef<TDataType>(reinterpret_cast<const TDataType*>(propVal.begin()),
		                          propVal.size() / sizeof(TDataType));
	}

	template <typename TDataType>
	DataRef<TDataType> getTypedRawPropertyValue(void* instId, const char* propName)
	{
		DataRef<uint8_t> propVal = getRawPropertyValue(instId, propName);
		return DataRef<TDataType>(reinterpret_cast<const TDataType*>(propVal.begin()),
		                          propVal.size() / sizeof(TDataType));
	}

	template <typename TDataType>
	uint32_t getPropertyValue(void* instId, const char* propName, TDataType* outBuffer, uint32_t outNumBufferItems)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return 0;
		}
		const PropertyDescription& prop(descOpt);
		uint32_t desired = outNumBufferItems * sizeof(TDataType);
		return getPropertyValue(instId, prop.mPropertyId, reinterpret_cast<uint8_t*>(outBuffer), desired) /
		       sizeof(TDataType);
	}

	template <typename TDataType>
	Option<TDataType> getPropertyValue(void* instId, const char* propName)
	{
		TDataType retval;
		if(getPropertyValue(instId, propName, &retval, 1) == 1)
			return retval;
		return None();
	}

	// Get this one item out of the array
	// return array[idx]
	virtual uint32_t getPropertyValue(void* instId, int32_t propId, int inArrayIndex, uint8_t* outData,
	                                  uint32_t outDataLen) = 0;
	// Get this sub element of one item out of the array
	// return array[idx].a
	virtual uint32_t getPropertyValue(void* instId, int32_t propId, int inArrayIndex, int nestedProperty,
	                                  uint8_t* outData, uint32_t outDataLen) = 0;

	// Get a set of properties defined by a property message
	virtual bool getPropertyMessage(void* instId, int32_t msgId, uint8_t* data, uint32_t dataLen) const = 0;

	template <typename TDataType>
	bool getPropertyMessage(void* instId, TDataType& msg)
	{
		Option<PropertyMessageDescription> msgId(
		    getMetaData().findPropertyMessage(getPvdNamespacedNameForType<TDataType>()));
		if(msgId.hasValue() == false)
			return false;
		return getPropertyMessage(instId, msgId.getValue().mMessageId, reinterpret_cast<uint8_t*>(&msg), sizeof(msg));
	}

	// clearing the array is performed with a set property value call with no data.
	virtual uint32_t getNbArrayElements(void* instId, int32_t propId) = 0;
	uint32_t getNbArrayElements(void* instId, const char* propName)
	{
		ClassDescription cls(getClassOf(instId));
		Option<PropertyDescription> descOpt(getMetaData().findProperty(cls.mClassId, propName));
		if(!descOpt.hasValue())
		{
			PX_ASSERT(false);
			return false;
		}
		const PropertyDescription& prop(descOpt);
		return getNbArrayElements(instId, prop.mPropertyId);
	}

	// Write this instance out.  Offset is set as the instances last write offset.
	// This offset is cleared if the object is changed.
	// If offset doesn't have a value, then the instance isn't changed.
	virtual void writeInstance(void* instId, PvdOutputStream& stream) = 0;

	virtual uint32_t getNbInstances() const = 0;
	virtual uint32_t getInstances(InstanceDescription* outBuffer, uint32_t count, uint32_t startIndex = 0) const = 0;

	// Get the list of updated objects since the last time someone cleared the updated instance list.
	virtual uint32_t getNbUpdatedInstances() const = 0;
	virtual uint32_t getUpdatedInstances(InstanceDescription* outBuffer, uint32_t count, uint32_t startIndex = 0) = 0;
	// Must be called for instances to be released.  Only instances that aren't live nor are they updated
	// are valid.
	virtual void clearUpdatedInstances() = 0;
};

class PvdObjectModel : public PvdObjectModelMutator, public PvdObjectModelReader
{
  protected:
	virtual ~PvdObjectModel()
	{
	}

  public:
	virtual void destroyAllInstances() = 0;
	virtual bool setPropertyValueToDefault(void* instId, int32_t propId) = 0;
	// Read an instance data and put a copy of the data in the output stream.
	static bool readInstance(PvdInputStream& inStream, PvdOutputStream& outStream);
	virtual InstanceDescription readInstance(DataRef<const uint8_t> writtenData) = 0;
	// Set just this property from this serialized instance.
	// Expects the instance to be alive, just like setPropertyValue
	virtual bool readInstanceProperty(DataRef<const uint8_t> writtenData, int32_t propId) = 0;

	virtual void recordCompletedInstances() = 0;

	// OriginShift seekback support
	virtual uint32_t getNbShifted() = 0;
	virtual void getShiftedPair(InstancePropertyPair* outData, uint32_t count) = 0;
	virtual void clearShiftedPair() = 0;
	virtual void shiftObject(void* instId, int32_t propId, PxVec3 shift) = 0;
	static PvdObjectModel& create(physx::PxAllocatorCallback& callback, PvdObjectModelMetaData& metaData,
	                              bool isCapture = false);
};

#if PX_VC == 11 || PX_VC == 12 || PX_VC == 14
#pragma warning(pop)
#endif
}
}
#endif // PXPVDSDK_PXPVDOBJECTMODEL_H