mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-14 11:19:07 +00:00
ab44d7e809
--HG-- branch : develop
162 lines
4.7 KiB
C++
162 lines
4.7 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
#include "std_afx.h"
|
|
|
|
#include "nel/3d/ps_located.h"
|
|
#include "nel/3d/particle_system.h"
|
|
|
|
|
|
#include "nel/misc/stream.h"
|
|
#include "nel/misc/mem_stream.h"
|
|
|
|
#include "dup_ps.h"
|
|
|
|
#include <memory>
|
|
|
|
using namespace NL3D;
|
|
|
|
//=======================================================================
|
|
|
|
|
|
|
|
/** This can duplicate any serializable type by using a serialization policy (polymorphic, non polymorphic ..)
|
|
* The serialization policy must have a method to serial a pointer on the object (see example below)
|
|
* NB : of course this is slow (but convenient) way of performing a copy
|
|
* TODO maybe this could be used elsewhere ?
|
|
*/
|
|
template <class TSerializePolicy, typename T>
|
|
static T *DupSerializable(const T *in) throw(NLMISC::EStream)
|
|
{
|
|
NLMISC::CMemStream ms;
|
|
nlassert(!ms.isReading());
|
|
T *nonConstIn = const_cast<T *>(in);
|
|
TSerializePolicy::serial(nonConstIn, ms);
|
|
std::vector<uint8> datas(ms.length());
|
|
std::copy(ms.buffer(), ms.buffer() + ms.length(), datas.begin());
|
|
ms.resetPtrTable();
|
|
ms.invert();
|
|
ms.fill(&datas[0], (uint32)datas.size());
|
|
nlassert(ms.isReading());
|
|
T *newObj = NULL;
|
|
TSerializePolicy::serial(newObj, ms);
|
|
return newObj;
|
|
}
|
|
|
|
/** A policy to duplicate a non-polymorphic type
|
|
*/
|
|
struct CDupObjPolicy
|
|
{
|
|
template <typename T>
|
|
static void serial(T *&obj, NLMISC::IStream &dest) throw(NLMISC::EStream)
|
|
{
|
|
dest.serialPtr(obj);
|
|
/*if (dest.isReading())
|
|
{
|
|
CUniquePtr<T> newObj(new T);
|
|
newObj->serialPtr(dest);
|
|
delete obj;
|
|
obj = newObj.release();
|
|
}
|
|
else
|
|
{
|
|
obj->serial(dest);
|
|
}*/
|
|
}
|
|
};
|
|
|
|
/** A policy to duplicate a polymorphic type
|
|
*/
|
|
struct CDupPolymorphicObjPolicy
|
|
{
|
|
template <typename T>
|
|
static void serial(T *&obj, NLMISC::IStream &dest) throw(NLMISC::EStream)
|
|
{
|
|
dest.serialPolyPtr(obj);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//=======================================================================
|
|
/////////////////////////////////////////
|
|
// temp until there is a clone method //
|
|
/////////////////////////////////////////
|
|
NL3D::CParticleSystemProcess *DupPSLocated(const CParticleSystemProcess *in)
|
|
{
|
|
if (!in) return NULL;
|
|
try
|
|
{
|
|
// if the located doesn't belon to a system, copy it direclty
|
|
if (in->getOwner() == NULL)
|
|
{
|
|
return DupSerializable<CDupPolymorphicObjPolicy>(in);
|
|
}
|
|
else
|
|
{
|
|
uint index = in->getOwner()->getIndexOf(*in);
|
|
/** Duplicate the system, and detach.
|
|
* We can't duplicate the object direclty (it may be referencing other objects in the system, so these objects will be copied too...)
|
|
*/
|
|
CUniquePtr<CParticleSystem> newPS(DupSerializable<CDupObjPolicy>(in->getOwner()));
|
|
// scene pointer is not serialised, but 'detach' may need the scene to be specified
|
|
newPS->setScene(in->getOwner()->getScene());
|
|
return newPS->detach(index);
|
|
}
|
|
}
|
|
catch (const NLMISC::EStream &e)
|
|
{
|
|
nlwarning (e.what());
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
/////////////////////////////////////////
|
|
// temp until there is a clone method //
|
|
/////////////////////////////////////////
|
|
NL3D::CPSLocatedBindable *DupPSLocatedBindable(CPSLocatedBindable *in)
|
|
{
|
|
if (!in) return NULL;
|
|
try
|
|
{
|
|
// if no owner, can copy the object directy
|
|
if (in->getOwner() == NULL)
|
|
{
|
|
return DupSerializable<CDupPolymorphicObjPolicy>(in);
|
|
}
|
|
else
|
|
{
|
|
CParticleSystem *srcPS = in->getOwner()->getOwner();
|
|
CUniquePtr<CParticleSystem> newPS(DupSerializable<CDupObjPolicy>(srcPS));
|
|
// scene pointer is not serialised, but 'detach' may need the scene to be specified
|
|
newPS->setScene(in->getOwner()->getOwner()->getScene());
|
|
//
|
|
uint index = srcPS->getIndexOf(*(in->getOwner()));
|
|
uint subIndex = in->getOwner()->getIndexOf(in);
|
|
//
|
|
newPS->setScene(in->getOwner()->getScene()); // 'unbind' require the scene to be attached
|
|
CPSLocated *loc = NLMISC::safe_cast<CPSLocated *>(newPS->getProcess(index));
|
|
return loc->unbind(subIndex);
|
|
}
|
|
}
|
|
catch (const NLMISC::EStream &e)
|
|
{
|
|
nlwarning (e.what());
|
|
return NULL;
|
|
}
|
|
}
|