1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //#define TRACE_READ_DELTA
24 //#define TRACE_WRITE_DELTA
25 //#define TRACE_SET_VALUE
27 #define DELAYED_OBSERVERS
32 #include "nel/misc/cdb_leaf.h"
33 #include "nel/misc/xml_auto_ptr.h"
34 #include "nel/misc/bit_mem_stream.h"
35 //#include <iostream.h>
49 //-----------------------------------------------
51 //-----------------------------------------------
52 void CCDBNodeLeaf::init( xmlNodePtr node
, IProgressCallback
&/* progressCallBack */, bool /* mapBanks */, CCDBBankHandler
* /* bankHandler */ )
54 CXMLAutoPtr
type((const char*)xmlGetProp (node
, (xmlChar
*)"type"));
55 nlassert((const char *) type
!= NULL
);
57 // IF type is an INT with n bits [1,64].
58 if ((type
.getDatas()[0] == 'I') || (type
.getDatas()[0] == 'U'))
61 fromString((const char *) (type
.getDatas() + 1), nbBit
);
63 if(nbBit
>=1 && nbBit
<=64)
64 _Type
=(ICDBNode::EPropType
)nbBit
;
67 nlwarning("CCDBNodeLeaf::init : property is an INT and should be between [1,64] but it is %d bit(s).", nbBit
);
68 _Type
= ICDBNode::UNKNOWN
;
71 else if (type
.getDatas()[0] == 'S')
74 fromString((const char *) (type
.getDatas() + 1), nbBit
);
76 if(nbBit
>=1 && nbBit
<=64)
77 _Type
= (ICDBNode::EPropType
)(nbBit
+64);
80 nlwarning("CCDBNodeLeaf::init : property is an SINT and should be between [1,64] but it is %d bit(s).", nbBit
);
81 _Type
= ICDBNode::UNKNOWN
;
88 if(!strcmp(type
, "TEXT"))
89 _Type
= ICDBNode::TEXT
;
93 nlwarning("CCDBNodeLeaf::init : type '%s' is unknown.", type
.getDatas());
94 _Type
= ICDBNode::UNKNOWN
;
101 //-----------------------------------------------
104 //-----------------------------------------------
105 ICDBNode
* CCDBNodeLeaf::getNode( uint16
/* idx */ )
111 //-----------------------------------------------
114 //-----------------------------------------------
115 ICDBNode
* CCDBNodeLeaf::getNode (const CTextId
& id
, bool /* bCreate */)
117 if (_DBSM
->localUnmap(_Name
) == id
.readNext())
119 if (id
.size() == id
.getCurrentIndex())
125 //-----------------------------------------------
128 //-----------------------------------------------
129 void CCDBNodeLeaf::write( CTextId
& id
, FILE * f
)
131 fprintf(f
,"%" NL_I64
"d\t%s\n",_Property
,id
.toString().c_str());
134 //-----------------------------------------------
136 //-----------------------------------------------
137 void CCDBNodeLeaf::readDelta(TGameCycle gc
, CBitMemStream
& f
)
139 // If the property Type is valid.
140 if(_Type
> UNKNOWN
&& _Type
< Nb_Prop_Type
)
142 // Read the Property Value according to the Property Type.
147 else if (_Type
<= I64
)
151 f
.serial(recvd
, bits
);
154 // if the DB update is older than last DB update, abort (but after the read!!)
159 _oldProperty
= _Property
;
162 _Property
= (sint64
)recvd
;
165 if (! ((_Type
== TEXT
) || (_Type
<= I64
)))
168 sint64 mask
= (((sint64
)1)<<bits
)-(sint64
)1;
169 if( (_Property
>> (bits
-1))==1 )
174 if ( verboseDatabase
)
176 nlinfo( "CDB: Read value (%u bits) %" NL_I64
"d", bits
, _Property
);
179 // bkup the date of change
186 nlwarning("CCDBNodeLeaf::readDelta : Property Type Unknown ('%d') -> not serialized.", (uint
)_Type
);
190 //-----------------------------------------------
192 //-----------------------------------------------
193 void CCDBNodeLeaf::resetData(TGameCycle gc
, bool forceReset
)
200 else if (gc
>=_LastChangeGC
) // apply only if happens after the DB change
206 // Same version but without observer notification:
207 // if ((!forceReset) && (gc<_LastChangeGC)) // if !forceReset, apply only if happens after the DB change
213 // _LastChangeGC = gc;
214 // _oldProperty = _Property;
215 // if (_Property != 0)
220 //-----------------------------------------------
223 //-----------------------------------------------
224 sint64
CCDBNodeLeaf::getProp( CTextId
& id
)
226 // assert that there are no lines left in the textid
227 nlassert( id
.getCurrentIndex() == id
.size() );
229 // Return the property value.
235 //-----------------------------------------------
237 // Set the value of a property (the update flag is set to true)
238 // \param id is the text id of the property/grp
239 // \param name is the name of the property
240 // \param value is the value of the property
241 // \return bool : 'false' if id is too long.
242 //-----------------------------------------------
243 bool CCDBNodeLeaf::setProp( CTextId
& id
, sint64 value
)
245 // assert that there are no lines left in the textid
246 if(id
.getCurrentIndex() != id
.size())
249 // Set the property value (and set "_Changed" flag with 'true');
250 CCDBNodeLeaf::setValue64(value
);
257 //-----------------------------------------------
259 //-----------------------------------------------
260 bool CCDBNodeLeaf::setPropCheckGC(TGameCycle gc
, sint64 value
)
262 // Apply only if happens after the DB change
263 if(gc
>=_LastChangeGC
)
268 // Set the property value (and set "_Changed" flag with 'true');
269 CCDBNodeLeaf::setValue64(value
);
277 //-----------------------------------------------
280 //-----------------------------------------------
281 void CCDBNodeLeaf::clear()
288 //-----------------------------------------------
289 //-----------------------------------------------
290 void CCDBNodeLeaf::setValue64(sint64 prop
)
292 if (_Property
!= prop
)
299 _oldProperty
= _Property
;
306 void CCDBNodeLeaf::setValue32(sint32 prop
)
308 sint64 newVal
= (sint64
)prop
;
312 void CCDBNodeLeaf::setValue16(sint16 prop
)
314 sint64 newVal
= (sint64
)prop
;
319 void CCDBNodeLeaf::setValue8(sint8 prop
)
321 sint64 newVal
= (sint64
)prop
;
325 void CCDBNodeLeaf::setValueBool(bool prop
)
327 sint64 newVal
= (sint64
)prop
;
331 void CCDBNodeLeaf::setValueRGBA (const CRGBA
&color
)
333 sint64 newVal
= (uint32
)(color
.R
+(color
.G
<<8)+(color
.B
<<16)+(color
.A
<<24));
338 void CCDBNodeLeaf::display(const std::string
&prefix
)
340 nlinfo("%sL %s", prefix
.c_str(), _DBSM
->localUnmap(_Name
).c_str());
343 //-----------------------------------------------
346 //-----------------------------------------------
347 bool CCDBNodeLeaf::addObserver(IPropertyObserver
* observer
,CTextId
& /* id */)
349 _Observers
.push_back(observer
);
353 //-----------------------------------------------
356 //-----------------------------------------------
357 bool CCDBNodeLeaf::removeObserver(IPropertyObserver
* observer
, CTextId
& /* id */)
359 std::vector
<IPropertyObserver
*>::iterator endIt
= std::remove(_Observers
.begin(), _Observers
.end(), observer
);
360 if (endIt
== _Observers
.end()) return false; // no observer has been removed..
361 _Observers
.erase(endIt
, _Observers
.end());
365 //-----------------------------------------------
366 void CCDBNodeLeaf::notifyObservers()
368 std::vector
<IPropertyObserver
*> obs
= _Observers
;
370 for (std::vector
<IPropertyObserver
*>::const_iterator it
= obs
.begin(); it
!= obs
.end(); it
++)
374 // mark parent branchs
376 _Parent
->onLeafChanged( _Name
);
384 #ifdef TRACE_READ_DELTA
385 #undef TRACE_READ_DELTA
388 #ifdef TRACE_WRITE_DELTA
389 #undef TRACE_WRITE_DELTA
392 #ifdef TRACE_SET_VALUE
393 #undef TRACE_SET_VALUE
395 //#############################################################################################