include/common/PxSerializer.h
File members: include/common/PxSerializer.h
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PX_SERIALIZER_H
#define PX_SERIALIZER_H
#include "foundation/PxAssert.h"
#include "foundation/PxAllocatorCallback.h"
#include "foundation/PxFoundation.h"
#include "common/PxSerialFramework.h"
#include "common/PxCollection.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxSerializer
{
public:
/**********************************************************************************************************************/
virtual const char* getConcreteTypeName() const = 0;
virtual void requiresObjects(PxBase&, PxProcessPxBaseCallback&) const = 0;
virtual bool isSubordinate() const = 0;
/**********************************************************************************************************************/
/**********************************************************************************************************************/
virtual void exportExtraData(PxBase&, PxSerializationContext&) const = 0;
virtual void exportData(PxBase&, PxSerializationContext&) const = 0;
virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const = 0;
virtual size_t getClassSize() const = 0;
virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const = 0;
/**********************************************************************************************************************/
virtual ~PxSerializer() {}
};
template<class T>
class PxSerializerDefaultAdapter : public PxSerializer
{
public:
/************************************************************************************************/
PxSerializerDefaultAdapter(const char* name) : mTypeName(name){}
virtual const char* getConcreteTypeName() const
{
return mTypeName;
}
virtual void requiresObjects(PxBase& obj, PxProcessPxBaseCallback& c) const
{
T& t = static_cast<T&>(obj);
t.requiresObjects(c);
}
virtual bool isSubordinate() const
{
return false;
}
/************************************************************************************************/
// object methods
virtual void exportExtraData(PxBase& obj, PxSerializationContext& s) const
{
T& t = static_cast<T&>(obj);
t.exportExtraData(s);
}
virtual void exportData(PxBase& obj, PxSerializationContext& s) const
{
PxAllocatorCallback& allocator = *PxGetAllocatorCallback();
T* copy = reinterpret_cast<T*>(allocator.allocate(sizeof(T), "TmpAllocExportData", PX_FL));
PxMemCopy(copy, &obj, sizeof(T));
copy->preExportDataReset();
s.writeData(copy, sizeof(T));
allocator.deallocate(copy);
}
virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const
{
T& t = static_cast<T&>(obj);
s.registerReference(obj, PX_SERIAL_REF_KIND_PXBASE, size_t(&obj));
struct RequiresCallback : public PxProcessPxBaseCallback
{
RequiresCallback(PxSerializationContext& c) : context(c) {}
RequiresCallback& operator=(RequiresCallback&) { PX_ASSERT(0); return *this; }
void process(physx::PxBase& base)
{
context.registerReference(base, PX_SERIAL_REF_KIND_PXBASE, size_t(&base));
}
PxSerializationContext& context;
};
RequiresCallback callback(s);
t.requiresObjects(callback);
}
// class methods
virtual size_t getClassSize() const
{
return sizeof(T);
}
virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const
{
return T::createObject(address, context);
}
/************************************************************************************************/
private:
const char* mTypeName;
};
#define PX_NEW_SERIALIZER_ADAPTER(x) \
*new( PxGetAllocatorCallback()->allocate(sizeof(PxSerializerDefaultAdapter<x>), \
"PxSerializerDefaultAdapter", PX_FL)) PxSerializerDefaultAdapter<x>(#x)
#define PX_DELETE_SERIALIZER_ADAPTER(x) \
{ PxSerializer* s = x; if (s) { s->~PxSerializer(); PxGetAllocatorCallback()->deallocate(s); } }
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif