1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/3d/ps_located.h"
21 #include "nel/3d/particle_system.h"
24 #include "nel/misc/stream.h"
25 #include "nel/misc/mem_stream.h"
33 //=======================================================================
37 /** This can duplicate any serializable type by using a serialization policy (polymorphic, non polymorphic ..)
38 * The serialization policy must have a method to serial a pointer on the object (see example below)
39 * NB : of course this is slow (but convenient) way of performing a copy
40 * TODO maybe this could be used elsewhere ?
42 template <class TSerializePolicy
, typename T
>
43 static T
*DupSerializable(const T
*in
)
45 NLMISC::CMemStream ms
;
46 nlassert(!ms
.isReading());
47 T
*nonConstIn
= const_cast<T
*>(in
);
48 TSerializePolicy::serial(nonConstIn
, ms
);
49 std::vector
<uint8
> datas(ms
.length());
50 std::copy(ms
.buffer(), ms
.buffer() + ms
.length(), datas
.begin());
53 ms
.fill(&datas
[0], (uint32
)datas
.size());
54 nlassert(ms
.isReading());
56 TSerializePolicy::serial(newObj
, ms
);
60 /** A policy to duplicate a non-polymorphic type
65 static void serial(T
*&obj
, NLMISC::IStream
&dest
)
68 /*if (dest.isReading())
70 CUniquePtr<T> newObj(new T);
71 newObj->serialPtr(dest);
73 obj = newObj.release();
82 /** A policy to duplicate a polymorphic type
84 struct CDupPolymorphicObjPolicy
87 static void serial(T
*&obj
, NLMISC::IStream
&dest
)
89 dest
.serialPolyPtr(obj
);
95 //=======================================================================
96 /////////////////////////////////////////
97 // temp until there is a clone method //
98 /////////////////////////////////////////
99 NL3D::CParticleSystemProcess
*DupPSLocated(const CParticleSystemProcess
*in
)
101 if (!in
) return NULL
;
104 // if the located doesn't belon to a system, copy it direclty
105 if (in
->getOwner() == NULL
)
107 return DupSerializable
<CDupPolymorphicObjPolicy
>(in
);
111 uint index
= in
->getOwner()->getIndexOf(*in
);
112 /** Duplicate the system, and detach.
113 * We can't duplicate the object direclty (it may be referencing other objects in the system, so these objects will be copied too...)
115 CUniquePtr
<CParticleSystem
> newPS(DupSerializable
<CDupObjPolicy
>(in
->getOwner()));
116 // scene pointer is not serialised, but 'detach' may need the scene to be specified
117 newPS
->setScene(in
->getOwner()->getScene());
118 return newPS
->detach(index
);
121 catch (const NLMISC::EStream
&e
)
123 nlwarning (e
.what());
128 //=======================================================================
129 /////////////////////////////////////////
130 // temp until there is a clone method //
131 /////////////////////////////////////////
132 NL3D::CPSLocatedBindable
*DupPSLocatedBindable(CPSLocatedBindable
*in
)
134 if (!in
) return NULL
;
137 // if no owner, can copy the object directy
138 if (in
->getOwner() == NULL
)
140 return DupSerializable
<CDupPolymorphicObjPolicy
>(in
);
144 CParticleSystem
*srcPS
= in
->getOwner()->getOwner();
145 CUniquePtr
<CParticleSystem
> newPS(DupSerializable
<CDupObjPolicy
>(srcPS
));
146 // scene pointer is not serialised, but 'detach' may need the scene to be specified
147 newPS
->setScene(in
->getOwner()->getOwner()->getScene());
149 uint index
= srcPS
->getIndexOf(*(in
->getOwner()));
150 uint subIndex
= in
->getOwner()->getIndexOf(in
);
152 newPS
->setScene(in
->getOwner()->getScene()); // 'unbind' require the scene to be attached
153 CPSLocated
*loc
= NLMISC::safe_cast
<CPSLocated
*>(newPS
->getProcess(index
));
154 return loc
->unbind(subIndex
);
157 catch (const NLMISC::EStream
&e
)
159 nlwarning (e
.what());