Serializable.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. //
  2. // Copyright (c) 2008-2013 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "Precompiled.h"
  23. #include "Context.h"
  24. #include "Deserializer.h"
  25. #include "Log.h"
  26. #include "ReplicationState.h"
  27. #include "Serializable.h"
  28. #include "Serializer.h"
  29. #include "StringUtils.h"
  30. #include "XMLElement.h"
  31. #include "DebugNew.h"
  32. namespace Urho3D
  33. {
  34. Serializable::Serializable(Context* context) :
  35. Object(context),
  36. networkState_(0),
  37. instanceDefaultValues_(0)
  38. {
  39. }
  40. Serializable::~Serializable()
  41. {
  42. delete networkState_;
  43. networkState_ = 0;
  44. delete instanceDefaultValues_;
  45. instanceDefaultValues_ = 0;
  46. }
  47. void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
  48. {
  49. // Check for accessor function mode
  50. if (attr.accessor_)
  51. {
  52. attr.accessor_->Set(this, src);
  53. return;
  54. }
  55. // Calculate the destination address
  56. void* dest = attr.ptr_ ? attr.ptr_ : reinterpret_cast<unsigned char*>(this) + attr.offset_;
  57. switch (attr.type_)
  58. {
  59. case VAR_INT:
  60. // If enum type, use the low 8 bits only
  61. if (attr.enumNames_)
  62. *(reinterpret_cast<unsigned char*>(dest)) = src.GetInt();
  63. else
  64. *(reinterpret_cast<int*>(dest)) = src.GetInt();
  65. break;
  66. case VAR_BOOL:
  67. *(reinterpret_cast<bool*>(dest)) = src.GetBool();
  68. break;
  69. case VAR_FLOAT:
  70. *(reinterpret_cast<float*>(dest)) = src.GetFloat();
  71. break;
  72. case VAR_VECTOR2:
  73. *(reinterpret_cast<Vector2*>(dest)) = src.GetVector2();
  74. break;
  75. case VAR_VECTOR3:
  76. *(reinterpret_cast<Vector3*>(dest)) = src.GetVector3();
  77. break;
  78. case VAR_VECTOR4:
  79. *(reinterpret_cast<Vector4*>(dest)) = src.GetVector4();
  80. break;
  81. case VAR_QUATERNION:
  82. *(reinterpret_cast<Quaternion*>(dest)) = src.GetQuaternion();
  83. break;
  84. case VAR_COLOR:
  85. *(reinterpret_cast<Color*>(dest)) = src.GetColor();
  86. break;
  87. case VAR_STRING:
  88. *(reinterpret_cast<String*>(dest)) = src.GetString();
  89. break;
  90. case VAR_BUFFER:
  91. *(reinterpret_cast<PODVector<unsigned char>*>(dest)) = src.GetBuffer();
  92. break;
  93. case VAR_RESOURCEREF:
  94. *(reinterpret_cast<ResourceRef*>(dest)) = src.GetResourceRef();
  95. break;
  96. case VAR_RESOURCEREFLIST:
  97. *(reinterpret_cast<ResourceRefList*>(dest)) = src.GetResourceRefList();
  98. break;
  99. case VAR_VARIANTVECTOR:
  100. *(reinterpret_cast<VariantVector*>(dest)) = src.GetVariantVector();
  101. break;
  102. case VAR_VARIANTMAP:
  103. *(reinterpret_cast<VariantMap*>(dest)) = src.GetVariantMap();
  104. break;
  105. case VAR_INTRECT:
  106. *(reinterpret_cast<IntRect*>(dest)) = src.GetIntRect();
  107. break;
  108. case VAR_INTVECTOR2:
  109. *(reinterpret_cast<IntVector2*>(dest)) = src.GetIntVector2();
  110. break;
  111. default:
  112. LOGERROR("Unsupported attribute type for OnSetAttribute()");
  113. return;
  114. }
  115. }
  116. void Serializable::OnGetAttribute(const AttributeInfo& attr, Variant& dest) const
  117. {
  118. // Check for accessor function mode
  119. if (attr.accessor_)
  120. {
  121. attr.accessor_->Get(this, dest);
  122. return;
  123. }
  124. // Calculate the source address
  125. const void* src = attr.ptr_ ? attr.ptr_ : reinterpret_cast<const unsigned char*>(this) + attr.offset_;
  126. switch (attr.type_)
  127. {
  128. case VAR_INT:
  129. // If enum type, use the low 8 bits only
  130. if (attr.enumNames_)
  131. dest = *(reinterpret_cast<const unsigned char*>(src));
  132. else
  133. dest = *(reinterpret_cast<const int*>(src));
  134. break;
  135. case VAR_BOOL:
  136. dest = *(reinterpret_cast<const bool*>(src));
  137. break;
  138. case VAR_FLOAT:
  139. dest = *(reinterpret_cast<const float*>(src));
  140. break;
  141. case VAR_VECTOR2:
  142. dest = *(reinterpret_cast<const Vector2*>(src));
  143. break;
  144. case VAR_VECTOR3:
  145. dest = *(reinterpret_cast<const Vector3*>(src));
  146. break;
  147. case VAR_VECTOR4:
  148. dest = *(reinterpret_cast<const Vector4*>(src));
  149. break;
  150. case VAR_QUATERNION:
  151. dest = *(reinterpret_cast<const Quaternion*>(src));
  152. break;
  153. case VAR_COLOR:
  154. dest = *(reinterpret_cast<const Color*>(src));
  155. break;
  156. case VAR_STRING:
  157. dest = *(reinterpret_cast<const String*>(src));
  158. break;
  159. case VAR_BUFFER:
  160. dest = *(reinterpret_cast<const PODVector<unsigned char>*>(src));
  161. break;
  162. case VAR_RESOURCEREF:
  163. dest = *(reinterpret_cast<const ResourceRef*>(src));
  164. break;
  165. case VAR_RESOURCEREFLIST:
  166. dest = *(reinterpret_cast<const ResourceRefList*>(src));
  167. break;
  168. case VAR_VARIANTVECTOR:
  169. dest = *(reinterpret_cast<const VariantVector*>(src));
  170. break;
  171. case VAR_VARIANTMAP:
  172. dest = *(reinterpret_cast<const VariantMap*>(src));
  173. break;
  174. case VAR_INTRECT:
  175. dest = *(reinterpret_cast<const IntRect*>(src));
  176. break;
  177. case VAR_INTVECTOR2:
  178. dest = *(reinterpret_cast<const IntVector2*>(src));
  179. break;
  180. default:
  181. LOGERROR("Unsupported attribute type for OnGetAttribute()");
  182. return;
  183. }
  184. }
  185. const Vector<AttributeInfo>* Serializable::GetAttributes() const
  186. {
  187. return context_->GetAttributes(GetType());
  188. }
  189. const Vector<AttributeInfo>* Serializable::GetNetworkAttributes() const
  190. {
  191. return networkState_ ? networkState_->attributes_ : context_->GetNetworkAttributes(GetType());
  192. }
  193. bool Serializable::Load(Deserializer& source, bool setInstanceDefault)
  194. {
  195. const Vector<AttributeInfo>* attributes = GetAttributes();
  196. if (!attributes)
  197. return true;
  198. for (unsigned i = 0; i < attributes->Size(); ++i)
  199. {
  200. const AttributeInfo& attr = attributes->At(i);
  201. if (!(attr.mode_ & AM_FILE))
  202. continue;
  203. if (source.IsEof())
  204. {
  205. LOGERROR("Could not load " + GetTypeName() + ", stream not open or at end");
  206. return false;
  207. }
  208. Variant varValue = source.ReadVariant(attr.type_);
  209. OnSetAttribute(attr, varValue);
  210. if (setInstanceDefault)
  211. SetInstanceDefault(attr.name_, varValue);
  212. }
  213. return true;
  214. }
  215. bool Serializable::Save(Serializer& dest) const
  216. {
  217. const Vector<AttributeInfo>* attributes = GetAttributes();
  218. if (!attributes)
  219. return true;
  220. Variant value;
  221. for (unsigned i = 0; i < attributes->Size(); ++i)
  222. {
  223. const AttributeInfo& attr = attributes->At(i);
  224. if (!(attr.mode_ & AM_FILE))
  225. continue;
  226. OnGetAttribute(attr, value);
  227. if (!dest.WriteVariantData(value))
  228. {
  229. LOGERROR("Could not save " + GetTypeName() + ", writing to stream failed");
  230. return false;
  231. }
  232. }
  233. return true;
  234. }
  235. bool Serializable::LoadXML(const XMLElement& source, bool setInstanceDefault)
  236. {
  237. if (source.IsNull())
  238. {
  239. LOGERROR("Could not load " + GetTypeName() + ", null source element");
  240. return false;
  241. }
  242. const Vector<AttributeInfo>* attributes = GetAttributes();
  243. if (!attributes)
  244. return true;
  245. XMLElement attrElem = source.GetChild("attribute");
  246. unsigned startIndex = 0;
  247. while (attrElem)
  248. {
  249. String name = attrElem.GetAttribute("name");
  250. unsigned i = startIndex;
  251. unsigned attempts = attributes->Size();
  252. while (attempts)
  253. {
  254. const AttributeInfo& attr = attributes->At(i);
  255. if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
  256. {
  257. Variant varValue;
  258. // If enums specified, do enum lookup and int assignment. Otherwise assign the variant directly
  259. if (attr.enumNames_)
  260. {
  261. String value = attrElem.GetAttribute("value");
  262. bool enumFound = false;
  263. int enumValue = 0;
  264. const char** enumPtr = attr.enumNames_;
  265. while (*enumPtr)
  266. {
  267. if (!value.Compare(*enumPtr, false))
  268. {
  269. enumFound = true;
  270. break;
  271. }
  272. ++enumPtr;
  273. ++enumValue;
  274. }
  275. if (enumFound)
  276. varValue = enumValue;
  277. else
  278. LOGWARNING("Unknown enum value " + value + " in attribute " + attr.name_);
  279. }
  280. else
  281. varValue = attrElem.GetVariantValue(attr.type_);
  282. if (!varValue.IsEmpty())
  283. {
  284. OnSetAttribute(attr, varValue);
  285. if (setInstanceDefault)
  286. SetInstanceDefault(attr.name_, varValue);
  287. }
  288. startIndex = (i + 1) % attributes->Size();
  289. break;
  290. }
  291. else
  292. {
  293. i = (i + 1) % attributes->Size();
  294. --attempts;
  295. }
  296. }
  297. if (!attempts)
  298. LOGWARNING("Unknown attribute " + name + " in XML data");
  299. attrElem = attrElem.GetNext("attribute");
  300. }
  301. return true;
  302. }
  303. bool Serializable::SaveXML(XMLElement& dest) const
  304. {
  305. if (dest.IsNull())
  306. {
  307. LOGERROR("Could not save " + GetTypeName() + ", null destination element");
  308. return false;
  309. }
  310. const Vector<AttributeInfo>* attributes = GetAttributes();
  311. if (!attributes)
  312. return true;
  313. Variant value;
  314. for (unsigned i = 0; i < attributes->Size(); ++i)
  315. {
  316. const AttributeInfo& attr = attributes->At(i);
  317. if (!(attr.mode_ & AM_FILE))
  318. continue;
  319. OnGetAttribute(attr, value);
  320. Variant defaultValue(GetAttributeDefault(i));
  321. // In XML serialization default values can be skipped. This will make the file easier to read or edit manually
  322. if (value == defaultValue && !SaveDefaultAttributes())
  323. continue;
  324. XMLElement attrElem = dest.CreateChild("attribute");
  325. attrElem.SetAttribute("name", attr.name_);
  326. // If enums specified, set as an enum string. Otherwise set directly as a Variant
  327. if (attr.enumNames_)
  328. {
  329. int enumValue = value.GetInt();
  330. attrElem.SetAttribute("value", attr.enumNames_[enumValue]);
  331. }
  332. else
  333. attrElem.SetVariantValue(value);
  334. }
  335. return true;
  336. }
  337. bool Serializable::SetAttribute(unsigned index, const Variant& value)
  338. {
  339. const Vector<AttributeInfo>* attributes = GetAttributes();
  340. if (!attributes)
  341. {
  342. LOGERROR(GetTypeName() + " has no attributes");
  343. return false;
  344. }
  345. if (index >= attributes->Size())
  346. {
  347. LOGERROR("Attribute index out of bounds");
  348. return false;
  349. }
  350. const AttributeInfo& attr = attributes->At(index);
  351. // Check that the new value's type matches the attribute type
  352. if (value.GetType() == attr.type_)
  353. {
  354. OnSetAttribute(attr, value);
  355. return true;
  356. }
  357. else
  358. {
  359. LOGERROR("Could not set attribute " + attr.name_ + ": expected type " + Variant::GetTypeName(attr.type_) +
  360. " but got " + value.GetTypeName());
  361. return false;
  362. }
  363. }
  364. bool Serializable::SetAttribute(const String& name, const Variant& value)
  365. {
  366. const Vector<AttributeInfo>* attributes = GetAttributes();
  367. if (!attributes)
  368. {
  369. LOGERROR(GetTypeName() + " has no attributes");
  370. return false;
  371. }
  372. for (Vector<AttributeInfo>::ConstIterator i = attributes->Begin(); i != attributes->End(); ++i)
  373. {
  374. if (!i->name_.Compare(name, true))
  375. {
  376. // Check that the new value's type matches the attribute type
  377. if (value.GetType() == i->type_)
  378. {
  379. OnSetAttribute(*i, value);
  380. return true;
  381. }
  382. else
  383. {
  384. LOGERROR("Could not set attribute " + i->name_ + ": expected type " + Variant::GetTypeName(i->type_)
  385. + " but got " + value.GetTypeName());
  386. return false;
  387. }
  388. }
  389. }
  390. LOGERROR("Could not find attribute " + name + " in " + GetTypeName());
  391. return false;
  392. }
  393. void Serializable::ResetToDefault()
  394. {
  395. const Vector<AttributeInfo>* attributes = GetAttributes();
  396. if (!attributes)
  397. return;
  398. for (unsigned i = 0; i < attributes->Size(); ++i)
  399. {
  400. const AttributeInfo& attr = attributes->At(i);
  401. if (attr.mode_ & AM_NOEDIT || attr.mode_ & AM_NODEID || attr.mode_ & AM_COMPONENTID)
  402. continue;
  403. Variant defaultValue = GetInstanceDefault(attr.name_);
  404. if (defaultValue.IsEmpty())
  405. defaultValue = attr.defaultValue_;
  406. OnSetAttribute(attr, defaultValue);
  407. }
  408. }
  409. void Serializable::RemoveInstanceDefault()
  410. {
  411. delete instanceDefaultValues_;
  412. instanceDefaultValues_ = 0;
  413. }
  414. void Serializable::AllocateNetworkState()
  415. {
  416. if (!networkState_)
  417. {
  418. const Vector<AttributeInfo>* networkAttributes = GetNetworkAttributes();
  419. networkState_ = new NetworkState();
  420. networkState_->attributes_ = networkAttributes;
  421. }
  422. }
  423. void Serializable::WriteInitialDeltaUpdate(Serializer& dest)
  424. {
  425. if (!networkState_)
  426. {
  427. LOGERROR("WriteInitialDeltaUpdate called without allocated NetworkState");
  428. return;
  429. }
  430. const Vector<AttributeInfo>* attributes = networkState_->attributes_;
  431. if (!attributes)
  432. return;
  433. unsigned numAttributes = attributes->Size();
  434. DirtyBits attributeBits;
  435. // Compare against defaults
  436. for (unsigned i = 0; i < numAttributes; ++i)
  437. {
  438. const AttributeInfo& attr = attributes->At(i);
  439. if (networkState_->currentValues_[i] != attr.defaultValue_)
  440. attributeBits.Set(i);
  441. }
  442. // First write the change bitfield, then attribute data for non-default attributes
  443. dest.Write(attributeBits.data_, (numAttributes + 7) >> 3);
  444. for (unsigned i = 0; i < numAttributes; ++i)
  445. {
  446. if (attributeBits.IsSet(i))
  447. dest.WriteVariantData(networkState_->currentValues_[i]);
  448. }
  449. }
  450. void Serializable::WriteDeltaUpdate(Serializer& dest, const DirtyBits& attributeBits)
  451. {
  452. if (!networkState_)
  453. {
  454. LOGERROR("WriteDeltaUpdate called without allocated NetworkState");
  455. return;
  456. }
  457. const Vector<AttributeInfo>* attributes = networkState_->attributes_;
  458. if (!attributes)
  459. return;
  460. unsigned numAttributes = attributes->Size();
  461. // First write the change bitfield, then attribute data for changed attributes
  462. // Note: the attribute bits should not contain LATESTDATA attributes
  463. dest.Write(attributeBits.data_, (numAttributes + 7) >> 3);
  464. for (unsigned i = 0; i < numAttributes; ++i)
  465. {
  466. if (attributeBits.IsSet(i))
  467. dest.WriteVariantData(networkState_->currentValues_[i]);
  468. }
  469. }
  470. void Serializable::WriteLatestDataUpdate(Serializer& dest)
  471. {
  472. if (!networkState_)
  473. {
  474. LOGERROR("WriteLatestDataUpdate called without allocated NetworkState");
  475. return;
  476. }
  477. const Vector<AttributeInfo>* attributes = networkState_->attributes_;
  478. if (!attributes)
  479. return;
  480. unsigned numAttributes = attributes->Size();
  481. for (unsigned i = 0; i < numAttributes; ++i)
  482. {
  483. if (attributes->At(i).mode_ & AM_LATESTDATA)
  484. dest.WriteVariantData(networkState_->currentValues_[i]);
  485. }
  486. }
  487. void Serializable::ReadDeltaUpdate(Deserializer& source)
  488. {
  489. const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
  490. if (!attributes)
  491. return;
  492. unsigned numAttributes = attributes->Size();
  493. DirtyBits attributeBits;
  494. source.Read(attributeBits.data_, (numAttributes + 7) >> 3);
  495. for (unsigned i = 0; i < numAttributes && !source.IsEof(); ++i)
  496. {
  497. if (attributeBits.IsSet(i))
  498. {
  499. const AttributeInfo& attr = attributes->At(i);
  500. OnSetAttribute(attr, source.ReadVariant(attr.type_));
  501. }
  502. }
  503. }
  504. void Serializable::ReadLatestDataUpdate(Deserializer& source)
  505. {
  506. const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
  507. if (!attributes)
  508. return;
  509. unsigned numAttributes = attributes->Size();
  510. for (unsigned i = 0; i < numAttributes && !source.IsEof(); ++i)
  511. {
  512. const AttributeInfo& attr = attributes->At(i);
  513. if (attr.mode_ & AM_LATESTDATA)
  514. OnSetAttribute(attr, source.ReadVariant(attr.type_));
  515. }
  516. }
  517. Variant Serializable::GetAttribute(unsigned index) const
  518. {
  519. Variant ret;
  520. const Vector<AttributeInfo>* attributes = GetAttributes();
  521. if (!attributes)
  522. {
  523. LOGERROR(GetTypeName() + " has no attributes");
  524. return ret;
  525. }
  526. if (index >= attributes->Size())
  527. {
  528. LOGERROR("Attribute index out of bounds");
  529. return ret;
  530. }
  531. OnGetAttribute(attributes->At(index), ret);
  532. return ret;
  533. }
  534. Variant Serializable::GetAttribute(const String& name) const
  535. {
  536. Variant ret;
  537. const Vector<AttributeInfo>* attributes = GetAttributes();
  538. if (!attributes)
  539. {
  540. LOGERROR(GetTypeName() + " has no attributes");
  541. return ret;
  542. }
  543. for (Vector<AttributeInfo>::ConstIterator i = attributes->Begin(); i != attributes->End(); ++i)
  544. {
  545. if (!i->name_.Compare(name, true))
  546. {
  547. OnGetAttribute(*i, ret);
  548. return ret;
  549. }
  550. }
  551. LOGERROR("Could not find attribute " + name + " in " + GetTypeName());
  552. return ret;
  553. }
  554. Variant Serializable::GetAttributeDefault(unsigned index) const
  555. {
  556. const Vector<AttributeInfo>* attributes = GetAttributes();
  557. if (!attributes)
  558. {
  559. LOGERROR(GetTypeName() + " has no attributes");
  560. return Variant::EMPTY;
  561. }
  562. if (index >= attributes->Size())
  563. {
  564. LOGERROR("Attribute index out of bounds");
  565. return Variant::EMPTY;
  566. }
  567. AttributeInfo attr = attributes->At(index);
  568. Variant defaultValue = GetInstanceDefault(attr.name_);
  569. return defaultValue.IsEmpty() ? attr.defaultValue_ : defaultValue;
  570. }
  571. Variant Serializable::GetAttributeDefault(const String& name) const
  572. {
  573. Variant defaultValue = GetInstanceDefault(name);
  574. if (!defaultValue.IsEmpty())
  575. return defaultValue;
  576. const Vector<AttributeInfo>* attributes = GetAttributes();
  577. if (!attributes)
  578. {
  579. LOGERROR(GetTypeName() + " has no attributes");
  580. return Variant::EMPTY;
  581. }
  582. for (Vector<AttributeInfo>::ConstIterator i = attributes->Begin(); i != attributes->End(); ++i)
  583. {
  584. if (!i->name_.Compare(name, true))
  585. return i->defaultValue_;
  586. }
  587. LOGERROR("Could not find attribute " + name + " in " + GetTypeName());
  588. return Variant::EMPTY;
  589. }
  590. unsigned Serializable::GetNumAttributes() const
  591. {
  592. const Vector<AttributeInfo>* attributes = GetAttributes();
  593. return attributes ? attributes->Size() : 0;
  594. }
  595. unsigned Serializable::GetNumNetworkAttributes() const
  596. {
  597. const Vector<AttributeInfo>* attributes = networkState_ ? networkState_->attributes_ :
  598. context_->GetNetworkAttributes(GetType());
  599. return attributes ? attributes->Size() : 0;
  600. }
  601. void Serializable::SetInstanceDefault(const String& name, const Variant& defaultValue)
  602. {
  603. // Allocate the instance level default value
  604. if (!instanceDefaultValues_)
  605. instanceDefaultValues_ = new VariantMap();
  606. instanceDefaultValues_->operator[] (name) = defaultValue;
  607. }
  608. Variant Serializable::GetInstanceDefault(const String& name) const
  609. {
  610. if (instanceDefaultValues_)
  611. {
  612. VariantMap::ConstIterator i = instanceDefaultValues_->Find(name);
  613. if (i != instanceDefaultValues_->End())
  614. return i->second_;
  615. }
  616. return Variant::EMPTY;
  617. }
  618. }