Files
XCEngine/engine/third_party/physx/source/physxextensions/src/serialization/SnSerializationRegistry.cpp

271 lines
8.4 KiB
C++
Raw Normal View History

// 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-2025 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#include "common/PxSerializer.h"
#include "foundation/PxString.h"
#include "PxPhysics.h"
#include "PxPhysicsSerialization.h"
#include "PxArticulationLink.h"
#include "SnSerializationRegistry.h"
#include "ExtSerialization.h"
#include "CmCollection.h"
using namespace physx;
namespace
{
class CollectionSorter : public PxProcessPxBaseCallback
{
typedef PxPair<PxBase*, PxSerialObjectId> Object;
class Element
{
public:
Object object;
PxArray<PxU32> children;
bool isFinished;
Element(PxBase* obj = NULL) : object(obj, PX_SERIAL_OBJECT_ID_INVALID), isFinished(false) {}
};
public:
CollectionSorter(Cm::Collection& collection, Sn::SerializationRegistry& sr, bool isRepx) : mCollection(collection), mSr(sr), mIsRepx(isRepx) {}
virtual ~CollectionSorter(){}
void process(PxBase& base)
{
addChild(&base);
//ArticulationLink is not a repx serializer, so should require Articulation here
if( mIsRepx && PxConcreteType::eARTICULATION_LINK == base.getConcreteType() )
{
PxArticulationLink* link = static_cast<PxArticulationLink*>(&base);
PxBase* a = reinterpret_cast<PxBase*>(&link->getArticulation());
if(mCurElement->object.first != a ) //don't require itself
addChild(a);
}
}
void sort()
{
Element element;
PxU32 i;
PxU32 nbObject = mCollection.internalGetNbObjects();
const Cm::Collection::ObjectToIdMap::Entry* objectdatas = mCollection.internalGetObjects();
for( i = 0; i < nbObject; ++i )
{
element.object.first = objectdatas[i].first;
element.object.second = objectdatas[i].second;
mObjToIdMap.insert(objectdatas[i].first, mElements.size());
mElements.pushBack(element);
}
for( i = 0; i < nbObject; ++i )
{
mCurElement = &mElements[i];
const PxSerializer* serializer = mSr.getSerializer(mCurElement->object.first->getConcreteType());
PX_ASSERT(serializer);
serializer->requiresObjects(*mCurElement->object.first, *this);
}
for( i = 0; i < nbObject; ++i )
{
if( mElements[i].isFinished )
continue;
AddElement(mElements[i]);
}
mCollection.mObjects.clear();
for(PxArray<Object>::Iterator o = mSorted.begin(); o != mSorted.end(); ++o )
{
mCollection.internalAdd(o->first, o->second);
}
}
void AddElement(Element& e)
{
if( !e.isFinished )
{
for( PxArray<PxU32>::Iterator child = e.children.begin(); child != e.children.end(); ++child )
{
AddElement(mElements[*child]);
}
mSorted.pushBack(e.object);
e.isFinished = true;
}
}
private:
PX_INLINE void addChild(PxBase* base)
{
PX_ASSERT(mCurElement);
const PxHashMap<PxBase*, PxU32>::Entry* entry = mObjToIdMap.find(base);
if(entry)
mCurElement->children.pushBack(entry->second);
}
CollectionSorter& operator=(const CollectionSorter&);
PxHashMap<PxBase*, PxU32> mObjToIdMap;
PxArray<Element> mElements;
Cm::Collection& mCollection;
Sn::SerializationRegistry& mSr;
PxArray<Object> mSorted;
Element* mCurElement;
bool mIsRepx;
};
}
namespace physx { namespace Sn {
SerializationRegistry::SerializationRegistry(PxPhysics& physics)
: mPhysics(physics)
{
PxRegisterPhysicsSerializers(*this);
Ext::RegisterExtensionsSerializers(*this);
}
SerializationRegistry::~SerializationRegistry()
{
PxUnregisterPhysicsSerializers(*this);
Ext::UnregisterExtensionsSerializers(*this);
if(mSerializers.size() > 0)
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::release(): some registered PxSerializer instances were not unregistered");
}
if(mRepXSerializers.size() > 0)
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::release(): some registered PxRepXSerializer instances were not unregistered");
}
}
void SerializationRegistry::registerSerializer(PxType type, PxSerializer& serializer)
{
if(mSerializers.find(type))
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::registerSerializer: Type %d has already been registered", type);
}
mSerializers.insert(type, &serializer);
}
PxSerializer* SerializationRegistry::unregisterSerializer(PxType type)
{
const SerializerMap::Entry* e = mSerializers.find(type);
PxSerializer* s = e ? e->second : NULL;
if(!mSerializers.erase(type))
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::unregisterSerializer: failed to find PxSerializer instance for type %d", type);
}
return s;
}
const PxSerializer* SerializationRegistry::getSerializer(PxType type) const
{
const SerializerMap::Entry* e = mSerializers.find(type);
#if PX_CHECKED
if (!e)
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::getSerializer: failed to find PxSerializer instance for type %d", type);
}
#endif
return e ? e->second : NULL;
}
PxType SerializationRegistry::getSerializerType(PxU32 index) const
{
PX_ASSERT(index < mSerializers.size());
return mSerializers.getEntries()[index].first;
}
const char* SerializationRegistry::getSerializerName(PxU32 index) const
{
PX_ASSERT(index < mSerializers.size());
return mSerializers.getEntries()[index].second->getConcreteTypeName();
}
void SerializationRegistry::registerRepXSerializer(PxType type, PxRepXSerializer& serializer)
{
if(mRepXSerializers.find(type))
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::registerRepXSerializer: Type %d has already been registered", type);
}
mRepXSerializers.insert(type, &serializer);
}
PxRepXSerializer* SerializationRegistry::getRepXSerializer(const char* typeName) const
{
SerializationRegistry* sr = const_cast<SerializationRegistry*>(this);
for( RepXSerializerMap::Iterator iter = sr->mRepXSerializers.getIterator(); !iter.done(); ++iter)
{
if ( physx::Pxstricmp( iter->second->getTypeName(), typeName ) == 0 )
return iter->second;
}
return NULL;
}
PxRepXSerializer* SerializationRegistry::unregisterRepXSerializer(PxType type)
{
const RepXSerializerMap::Entry* e = mRepXSerializers.find(type);
PxRepXSerializer* s = e ? e->second : NULL;
if(!mRepXSerializers.erase(type))
{
PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL,
"PxSerializationRegistry::unregisterRepXSerializer: failed to find PxRepXSerializer instance for type %d", type);
}
return s;
}
void sortCollection(Cm::Collection& collection, SerializationRegistry& sr, bool isRepx)
{
CollectionSorter sorter(collection, sr, isRepx);
sorter.sort();
}
} // Sn
PxSerializationRegistry* PxSerialization::createSerializationRegistry(PxPhysics& physics)
{
return PX_NEW(Sn::SerializationRegistry)(physics);
}
} // physx