Show bonus/malus timer text if available
[ryzomcore.git] / nel / src / misc / cdb_leaf.cpp
blobf5bc50ac3da4a00c3484dff1f68a11214d8a5595
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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>
7 //
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/>.
21 #include "stdmisc.h"
23 //#define TRACE_READ_DELTA
24 //#define TRACE_WRITE_DELTA
25 //#define TRACE_SET_VALUE
27 #define DELAYED_OBSERVERS
29 //////////////
30 // Includes //
31 //////////////
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>
37 ////////////////
38 // Namespaces //
39 ////////////////
40 using namespace std;
42 #ifdef DEBUG_NEW
43 #define new DEBUG_NEW
44 #endif
46 namespace NLMISC{
49 //-----------------------------------------------
50 // init
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'))
60 uint nbBit;
61 fromString((const char *) (type.getDatas() + 1), nbBit);
63 if(nbBit>=1 && nbBit<=64)
64 _Type=(ICDBNode::EPropType)nbBit;
65 else
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')
73 uint nbBit;
74 fromString((const char *) (type.getDatas() + 1), nbBit);
76 if(nbBit>=1 && nbBit<=64)
77 _Type = (ICDBNode::EPropType)(nbBit+64);
78 else
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;
84 // ELSE
85 else
87 // IF it is a TEXT.
88 if(!strcmp(type, "TEXT"))
89 _Type = ICDBNode::TEXT;
90 // ELSE type unknown.
91 else
93 nlwarning("CCDBNodeLeaf::init : type '%s' is unknown.", type.getDatas());
94 _Type = ICDBNode::UNKNOWN;
98 } // init //
101 //-----------------------------------------------
102 // getNode
104 //-----------------------------------------------
105 ICDBNode * CCDBNodeLeaf::getNode( uint16 /* idx */ )
107 return this;
108 } // getNode //
111 //-----------------------------------------------
112 // getNode
114 //-----------------------------------------------
115 ICDBNode * CCDBNodeLeaf::getNode (const CTextId& id, bool /* bCreate */)
117 if (_DBSM->localUnmap(_Name) == id.readNext())
119 if (id.size() == id.getCurrentIndex())
120 return this;
122 return NULL;
123 } // getNode //
125 //-----------------------------------------------
126 // write
128 //-----------------------------------------------
129 void CCDBNodeLeaf::write( CTextId& id, FILE * f)
131 fprintf(f,"%" NL_I64 "d\t%s\n",_Property,id.toString().c_str());
132 } // write //
134 //-----------------------------------------------
135 // readDelta
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.
143 uint64 recvd = 0;
144 uint bits;
145 if (_Type == TEXT)
146 bits = 32;
147 else if (_Type <= I64)
148 bits = _Type;
149 else
150 bits = _Type - 64;
151 f.serial(recvd, bits);
154 // if the DB update is older than last DB update, abort (but after the read!!)
155 if(gc<_LastChangeGC)
156 return;
158 // bkup _oldProperty
159 _oldProperty = _Property;
161 // setup new one
162 _Property = (sint64)recvd;
164 // if signed
165 if (! ((_Type == TEXT) || (_Type <= I64)))
167 // extend bit sign
168 sint64 mask = (((sint64)1)<<bits)-(sint64)1;
169 if( (_Property >> (bits-1))==1 )
171 _Property |= ~mask;
174 if ( verboseDatabase )
176 nlinfo( "CDB: Read value (%u bits) %" NL_I64 "d", bits, _Property );
179 // bkup the date of change
180 _LastChangeGC= gc;
182 notifyObservers();
185 else
186 nlwarning("CCDBNodeLeaf::readDelta : Property Type Unknown ('%d') -> not serialized.", (uint)_Type);
187 }// readDelta //
190 //-----------------------------------------------
191 // resetData
192 //-----------------------------------------------
193 void CCDBNodeLeaf::resetData(TGameCycle gc, bool forceReset)
195 if(forceReset)
197 _LastChangeGC = 0;
198 setValue64(0);
200 else if (gc>=_LastChangeGC) // apply only if happens after the DB change
202 _LastChangeGC = gc;
203 setValue64(0);
206 // Same version but without observer notification:
207 // if ((!forceReset) && (gc<_LastChangeGC)) // if !forceReset, apply only if happens after the DB change
208 // return;
210 // if (forceReset)
211 // gc = 0;
213 // _LastChangeGC = gc;
214 // _oldProperty = _Property;
215 // if (_Property != 0)
216 // _Changed = true;
217 // _Property = 0;
220 //-----------------------------------------------
221 // getProp
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.
230 return getValue64();
231 } // getProp //
235 //-----------------------------------------------
236 // setProp
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())
247 return false;
249 // Set the property value (and set "_Changed" flag with 'true');
250 CCDBNodeLeaf::setValue64(value);
252 // Done
253 return true;
254 }// setProp //
257 //-----------------------------------------------
258 // setPropCheckGC
259 //-----------------------------------------------
260 bool CCDBNodeLeaf::setPropCheckGC(TGameCycle gc, sint64 value)
262 // Apply only if happens after the DB change
263 if(gc>=_LastChangeGC)
265 // new recent date
266 _LastChangeGC= gc;
268 // Set the property value (and set "_Changed" flag with 'true');
269 CCDBNodeLeaf::setValue64(value);
271 return true;
273 else
274 return false;
277 //-----------------------------------------------
278 // clear
280 //-----------------------------------------------
281 void CCDBNodeLeaf::clear()
284 } // clear //
288 //-----------------------------------------------
289 //-----------------------------------------------
290 void CCDBNodeLeaf::setValue64(sint64 prop)
292 if (_Property != prop)
294 if (!_Changed)
296 _Changed = true;
299 _oldProperty = _Property;
300 _Property = prop;
301 // notify observer
302 notifyObservers();
306 void CCDBNodeLeaf::setValue32(sint32 prop)
308 sint64 newVal = (sint64)prop;
309 setValue64(newVal);
312 void CCDBNodeLeaf::setValue16(sint16 prop)
314 sint64 newVal = (sint64)prop;
315 setValue64(newVal);
319 void CCDBNodeLeaf::setValue8(sint8 prop)
321 sint64 newVal = (sint64)prop;
322 setValue64(newVal);
325 void CCDBNodeLeaf::setValueBool(bool prop)
327 sint64 newVal = (sint64)prop;
328 setValue64(newVal);
331 void CCDBNodeLeaf::setValueRGBA (const CRGBA &color)
333 sint64 newVal = (uint32)(color.R+(color.G<<8)+(color.B<<16)+(color.A<<24));
334 setValue64(newVal);
338 void CCDBNodeLeaf::display(const std::string &prefix)
340 nlinfo("%sL %s", prefix.c_str(), _DBSM->localUnmap(_Name).c_str());
343 //-----------------------------------------------
344 // addObserver
346 //-----------------------------------------------
347 bool CCDBNodeLeaf::addObserver(IPropertyObserver* observer,CTextId& /* id */)
349 _Observers.push_back(observer);
350 return true;
353 //-----------------------------------------------
354 // removeObserver
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());
362 return true;
365 //-----------------------------------------------
366 void CCDBNodeLeaf::notifyObservers()
368 std::vector<IPropertyObserver*> obs = _Observers;
369 // notify observer
370 for (std::vector<IPropertyObserver*>::const_iterator it = obs.begin(); it != obs.end(); it++)
372 (*it)->update(this);
374 // mark parent branchs
375 if (_Parent)
376 _Parent->onLeafChanged( _Name );
384 #ifdef TRACE_READ_DELTA
385 #undef TRACE_READ_DELTA
386 #endif
388 #ifdef TRACE_WRITE_DELTA
389 #undef TRACE_WRITE_DELTA
390 #endif
392 #ifdef TRACE_SET_VALUE
393 #undef TRACE_SET_VALUE
394 #endif
395 //#############################################################################################