Variant.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. //
  2. // Copyright (c) 2008-2017 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 "../Core/StringUtils.h"
  24. #include "../IO/VectorBuffer.h"
  25. #include <cstring>
  26. namespace Urho3D
  27. {
  28. const Variant Variant::EMPTY;
  29. const PODVector<unsigned char> Variant::emptyBuffer;
  30. const ResourceRef Variant::emptyResourceRef;
  31. const ResourceRefList Variant::emptyResourceRefList;
  32. const VariantMap Variant::emptyVariantMap;
  33. const VariantVector Variant::emptyVariantVector;
  34. const StringVector Variant::emptyStringVector;
  35. static const char* typeNames[] =
  36. {
  37. "None",
  38. "Int",
  39. "Bool",
  40. "Float",
  41. "Vector2",
  42. "Vector3",
  43. "Vector4",
  44. "Quaternion",
  45. "Color",
  46. "String",
  47. "Buffer",
  48. "VoidPtr",
  49. "ResourceRef",
  50. "ResourceRefList",
  51. "VariantVector",
  52. "VariantMap",
  53. "IntRect",
  54. "IntVector2",
  55. "Ptr",
  56. "Matrix3",
  57. "Matrix3x4",
  58. "Matrix4",
  59. "Double",
  60. "StringVector",
  61. "Rect",
  62. "IntVector3",
  63. "Int64",
  64. "CustomPtr",
  65. "Custom",
  66. nullptr
  67. };
  68. static_assert(sizeof(typeNames) / sizeof(const char*) == MAX_VAR_TYPES + 1, "Variant type name array is out-of-date");
  69. Variant& Variant::operator =(const Variant& rhs)
  70. {
  71. // Handle custom types separately
  72. if (rhs.IsCustom())
  73. {
  74. SetCustomVariantValue(*rhs.GetCustomVariantValuePtr());
  75. return *this;
  76. }
  77. // Assign other types here
  78. SetType(rhs.GetType());
  79. switch (type_)
  80. {
  81. case VAR_STRING:
  82. value_.string_ = rhs.value_.string_;
  83. break;
  84. case VAR_BUFFER:
  85. value_.buffer_ = rhs.value_.buffer_;
  86. break;
  87. case VAR_RESOURCEREF:
  88. value_.resourceRef_ = rhs.value_.resourceRef_;
  89. break;
  90. case VAR_RESOURCEREFLIST:
  91. value_.resourceRefList_ = rhs.value_.resourceRefList_;
  92. break;
  93. case VAR_VARIANTVECTOR:
  94. value_.variantVector_ = rhs.value_.variantVector_;
  95. break;
  96. case VAR_STRINGVECTOR:
  97. value_.stringVector_ = rhs.value_.stringVector_;
  98. break;
  99. case VAR_VARIANTMAP:
  100. value_.variantMap_ = rhs.value_.variantMap_;
  101. break;
  102. case VAR_PTR:
  103. value_.weakPtr_ = rhs.value_.weakPtr_;
  104. break;
  105. case VAR_MATRIX3:
  106. *value_.matrix3_ = *rhs.value_.matrix3_;
  107. break;
  108. case VAR_MATRIX3X4:
  109. *value_.matrix3x4_ = *rhs.value_.matrix3x4_;
  110. break;
  111. case VAR_MATRIX4:
  112. *value_.matrix4_ = *rhs.value_.matrix4_;
  113. break;
  114. default:
  115. memcpy(&value_, &rhs.value_, sizeof(VariantValue));
  116. break;
  117. }
  118. return *this;
  119. }
  120. Variant& Variant::operator =(const VectorBuffer& rhs)
  121. {
  122. SetType(VAR_BUFFER);
  123. value_.buffer_ = rhs.GetBuffer();
  124. return *this;
  125. }
  126. bool Variant::operator ==(const Variant& rhs) const
  127. {
  128. if (type_ == VAR_VOIDPTR || type_ == VAR_PTR)
  129. return GetVoidPtr() == rhs.GetVoidPtr();
  130. else if (IsCustom() && rhs.IsCustom())
  131. return GetCustomVariantValuePtr()->Compare(*rhs.GetCustomVariantValuePtr());
  132. else if (type_ != rhs.type_)
  133. return false;
  134. switch (type_)
  135. {
  136. case VAR_INT:
  137. return value_.int_ == rhs.value_.int_;
  138. case VAR_INT64:
  139. return value_.int64_ == rhs.value_.int64_;
  140. case VAR_BOOL:
  141. return value_.bool_ == rhs.value_.bool_;
  142. case VAR_FLOAT:
  143. return value_.float_ == rhs.value_.float_;
  144. case VAR_VECTOR2:
  145. return value_.vector2_ == rhs.value_.vector2_;
  146. case VAR_VECTOR3:
  147. return value_.vector3_ == rhs.value_.vector3_;
  148. case VAR_VECTOR4:
  149. return value_.vector4_ == rhs.value_.vector4_;
  150. case VAR_QUATERNION:
  151. return value_.quaternion_ == rhs.value_.quaternion_;
  152. case VAR_COLOR:
  153. return value_.color_ == rhs.value_.color_;
  154. case VAR_STRING:
  155. return value_.string_ == rhs.value_.string_;
  156. case VAR_BUFFER:
  157. return value_.buffer_ == rhs.value_.buffer_;
  158. case VAR_RESOURCEREF:
  159. return value_.resourceRef_ == rhs.value_.resourceRef_;
  160. case VAR_RESOURCEREFLIST:
  161. return value_.resourceRefList_ == rhs.value_.resourceRefList_;
  162. case VAR_VARIANTVECTOR:
  163. return value_.variantVector_ == rhs.value_.variantVector_;
  164. case VAR_STRINGVECTOR:
  165. return value_.stringVector_ == rhs.value_.stringVector_;
  166. case VAR_VARIANTMAP:
  167. return value_.variantMap_ == rhs.value_.variantMap_;
  168. case VAR_INTRECT:
  169. return value_.intRect_ == rhs.value_.intRect_;
  170. case VAR_INTVECTOR2:
  171. return value_.intVector2_ == rhs.value_.intVector2_;
  172. case VAR_INTVECTOR3:
  173. return value_.intVector3_ == rhs.value_.intVector3_;
  174. case VAR_MATRIX3:
  175. return *value_.matrix3_ == *rhs.value_.matrix3_;
  176. case VAR_MATRIX3X4:
  177. return *value_.matrix3x4_ == *rhs.value_.matrix3x4_;
  178. case VAR_MATRIX4:
  179. return *value_.matrix4_ == *rhs.value_.matrix4_;
  180. case VAR_DOUBLE:
  181. return value_.double_ == rhs.value_.double_;
  182. case VAR_RECT:
  183. return value_.rect_ == rhs.value_.rect_;
  184. default:
  185. return true;
  186. }
  187. }
  188. bool Variant::operator ==(const PODVector<unsigned char>& rhs) const
  189. {
  190. // Use strncmp() instead of PODVector<unsigned char>::operator ==()
  191. const PODVector<unsigned char>& buffer = value_.buffer_;
  192. return type_ == VAR_BUFFER && buffer.Size() == rhs.Size() ?
  193. strncmp(reinterpret_cast<const char*>(&buffer[0]), reinterpret_cast<const char*>(&rhs[0]), buffer.Size()) == 0 :
  194. false;
  195. }
  196. bool Variant::operator ==(const VectorBuffer& rhs) const
  197. {
  198. const PODVector<unsigned char>& buffer = value_.buffer_;
  199. return type_ == VAR_BUFFER && buffer.Size() == rhs.GetSize() ?
  200. strncmp(reinterpret_cast<const char*>(&buffer[0]), reinterpret_cast<const char*>(rhs.GetData()), buffer.Size()) == 0 :
  201. false;
  202. }
  203. void Variant::FromString(const String& type, const String& value)
  204. {
  205. return FromString(GetTypeFromName(type), value.CString());
  206. }
  207. void Variant::FromString(const char* type, const char* value)
  208. {
  209. return FromString(GetTypeFromName(type), value);
  210. }
  211. void Variant::FromString(VariantType type, const String& value)
  212. {
  213. return FromString(type, value.CString());
  214. }
  215. void Variant::FromString(VariantType type, const char* value)
  216. {
  217. switch (type)
  218. {
  219. case VAR_INT:
  220. *this = ToInt(value);
  221. break;
  222. case VAR_INT64:
  223. *this = ToInt64(value);
  224. break;
  225. case VAR_BOOL:
  226. *this = ToBool(value);
  227. break;
  228. case VAR_FLOAT:
  229. *this = ToFloat(value);
  230. break;
  231. case VAR_VECTOR2:
  232. *this = ToVector2(value);
  233. break;
  234. case VAR_VECTOR3:
  235. *this = ToVector3(value);
  236. break;
  237. case VAR_VECTOR4:
  238. *this = ToVector4(value);
  239. break;
  240. case VAR_QUATERNION:
  241. *this = ToQuaternion(value);
  242. break;
  243. case VAR_COLOR:
  244. *this = ToColor(value);
  245. break;
  246. case VAR_STRING:
  247. *this = value;
  248. break;
  249. case VAR_BUFFER:
  250. SetType(VAR_BUFFER);
  251. StringToBuffer(value_.buffer_, value);
  252. break;
  253. case VAR_VOIDPTR:
  254. // From string to void pointer not supported, set to null
  255. *this = (void*)nullptr;
  256. break;
  257. case VAR_RESOURCEREF:
  258. {
  259. StringVector values = String::Split(value, ';');
  260. if (values.Size() == 2)
  261. {
  262. SetType(VAR_RESOURCEREF);
  263. value_.resourceRef_.type_ = values[0];
  264. value_.resourceRef_.name_ = values[1];
  265. }
  266. break;
  267. }
  268. case VAR_RESOURCEREFLIST:
  269. {
  270. StringVector values = String::Split(value, ';', true);
  271. if (values.Size() >= 1)
  272. {
  273. SetType(VAR_RESOURCEREFLIST);
  274. value_.resourceRefList_.type_ = values[0];
  275. value_.resourceRefList_.names_.Resize(values.Size() - 1);
  276. for (unsigned i = 1; i < values.Size(); ++i)
  277. value_.resourceRefList_.names_[i - 1] = values[i];
  278. }
  279. break;
  280. }
  281. case VAR_INTRECT:
  282. *this = ToIntRect(value);
  283. break;
  284. case VAR_INTVECTOR2:
  285. *this = ToIntVector2(value);
  286. break;
  287. case VAR_INTVECTOR3:
  288. *this = ToIntVector3(value);
  289. break;
  290. case VAR_PTR:
  291. // From string to RefCounted pointer not supported, set to null
  292. *this = (RefCounted*)nullptr;
  293. break;
  294. case VAR_MATRIX3:
  295. *this = ToMatrix3(value);
  296. break;
  297. case VAR_MATRIX3X4:
  298. *this = ToMatrix3x4(value);
  299. break;
  300. case VAR_MATRIX4:
  301. *this = ToMatrix4(value);
  302. break;
  303. case VAR_DOUBLE:
  304. *this = ToDouble(value);
  305. break;
  306. case VAR_RECT:
  307. *this = ToRect(value);
  308. break;
  309. default:
  310. SetType(VAR_NONE);
  311. }
  312. }
  313. void Variant::SetBuffer(const void* data, unsigned size)
  314. {
  315. if (size && !data)
  316. size = 0;
  317. SetType(VAR_BUFFER);
  318. PODVector<unsigned char>& buffer = value_.buffer_;
  319. buffer.Resize(size);
  320. if (size)
  321. memcpy(&buffer[0], data, size);
  322. }
  323. void Variant::SetCustomVariantValue(const CustomVariantValue& value)
  324. {
  325. // Assign value if destination is already initialized
  326. if (CustomVariantValue* custom = GetCustomVariantValuePtr())
  327. {
  328. if (custom->GetTypeInfo() == value.GetTypeInfo())
  329. {
  330. custom->Assign(value);
  331. return;
  332. }
  333. }
  334. if (value.GetSize() <= VARIANT_VALUE_SIZE)
  335. {
  336. SetType(VAR_CUSTOM_STACK);
  337. value_.customValueStack_.~CustomVariantValue();
  338. value.Clone(&value_.customValueStack_);
  339. }
  340. else
  341. {
  342. SetType(VAR_CUSTOM_HEAP);
  343. delete value_.customValueHeap_;
  344. value_.customValueHeap_ = value.Clone();
  345. }
  346. }
  347. VectorBuffer Variant::GetVectorBuffer() const
  348. {
  349. return VectorBuffer(type_ == VAR_BUFFER ? value_.buffer_ : emptyBuffer);
  350. }
  351. String Variant::GetTypeName() const
  352. {
  353. return typeNames[type_];
  354. }
  355. String Variant::ToString() const
  356. {
  357. switch (type_)
  358. {
  359. case VAR_INT:
  360. return String(value_.int_);
  361. case VAR_INT64:
  362. return String(value_.int64_);
  363. case VAR_BOOL:
  364. return String(value_.bool_);
  365. case VAR_FLOAT:
  366. return String(value_.float_);
  367. case VAR_VECTOR2:
  368. return value_.vector2_.ToString();
  369. case VAR_VECTOR3:
  370. return value_.vector3_.ToString();
  371. case VAR_VECTOR4:
  372. return value_.vector4_.ToString();
  373. case VAR_QUATERNION:
  374. return value_.quaternion_.ToString();
  375. case VAR_COLOR:
  376. return value_.color_.ToString();
  377. case VAR_STRING:
  378. return value_.string_;
  379. case VAR_BUFFER:
  380. {
  381. const PODVector<unsigned char>& buffer = value_.buffer_;
  382. String ret;
  383. BufferToString(ret, buffer.Begin().ptr_, buffer.Size());
  384. return ret;
  385. }
  386. case VAR_VOIDPTR:
  387. case VAR_PTR:
  388. // Pointer serialization not supported (convert to null)
  389. return String(0);
  390. case VAR_INTRECT:
  391. return value_.intRect_.ToString();
  392. case VAR_INTVECTOR2:
  393. return value_.intVector2_.ToString();
  394. case VAR_INTVECTOR3:
  395. return value_.intVector3_.ToString();
  396. case VAR_MATRIX3:
  397. return value_.matrix3_->ToString();
  398. case VAR_MATRIX3X4:
  399. return value_.matrix3x4_->ToString();
  400. case VAR_MATRIX4:
  401. return value_.matrix4_->ToString();
  402. case VAR_DOUBLE:
  403. return String(value_.double_);
  404. case VAR_RECT:
  405. return value_.rect_.ToString();
  406. case VAR_CUSTOM_HEAP:
  407. case VAR_CUSTOM_STACK:
  408. return GetCustomVariantValuePtr()->ToString();
  409. default:
  410. // VAR_RESOURCEREF, VAR_RESOURCEREFLIST, VAR_VARIANTVECTOR, VAR_STRINGVECTOR, VAR_VARIANTMAP
  411. // Reference string serialization requires typehash-to-name mapping from the context. Can not support here
  412. // Also variant map or vector string serialization is not supported. XML or binary save should be used instead
  413. return String::EMPTY;
  414. }
  415. }
  416. bool Variant::IsZero() const
  417. {
  418. switch (type_)
  419. {
  420. case VAR_INT:
  421. return value_.int_ == 0;
  422. case VAR_INT64:
  423. return value_.int64_ == 0;
  424. case VAR_BOOL:
  425. return value_.bool_ == false;
  426. case VAR_FLOAT:
  427. return value_.float_ == 0.0f;
  428. case VAR_VECTOR2:
  429. return value_.vector2_ == Vector2::ZERO;
  430. case VAR_VECTOR3:
  431. return value_.vector3_ == Vector3::ZERO;
  432. case VAR_VECTOR4:
  433. return value_.vector4_ == Vector4::ZERO;
  434. case VAR_QUATERNION:
  435. return value_.quaternion_ == Quaternion::IDENTITY;
  436. case VAR_COLOR:
  437. // WHITE is considered empty (i.e. default) color in the Color class definition
  438. return value_.color_ == Color::WHITE;
  439. case VAR_STRING:
  440. return value_.string_.Empty();
  441. case VAR_BUFFER:
  442. return value_.buffer_.Empty();
  443. case VAR_VOIDPTR:
  444. return value_.voidPtr_ == nullptr;
  445. case VAR_RESOURCEREF:
  446. return value_.resourceRef_.name_.Empty();
  447. case VAR_RESOURCEREFLIST:
  448. {
  449. const StringVector& names = value_.resourceRefList_.names_;
  450. for (StringVector::ConstIterator i = names.Begin(); i != names.End(); ++i)
  451. {
  452. if (!i->Empty())
  453. return false;
  454. }
  455. return true;
  456. }
  457. case VAR_VARIANTVECTOR:
  458. return value_.variantVector_.Empty();
  459. case VAR_STRINGVECTOR:
  460. return value_.stringVector_.Empty();
  461. case VAR_VARIANTMAP:
  462. return value_.variantMap_.Empty();
  463. case VAR_INTRECT:
  464. return value_.intRect_ == IntRect::ZERO;
  465. case VAR_INTVECTOR2:
  466. return value_.intVector2_ == IntVector2::ZERO;
  467. case VAR_INTVECTOR3:
  468. return value_.intVector3_ == IntVector3::ZERO;
  469. case VAR_PTR:
  470. return value_.weakPtr_ == (RefCounted*)nullptr;
  471. case VAR_MATRIX3:
  472. return *value_.matrix3_ == Matrix3::IDENTITY;
  473. case VAR_MATRIX3X4:
  474. return *value_.matrix3x4_ == Matrix3x4::IDENTITY;
  475. case VAR_MATRIX4:
  476. return *value_.matrix4_ == Matrix4::IDENTITY;
  477. case VAR_DOUBLE:
  478. return value_.double_ == 0.0;
  479. case VAR_RECT:
  480. return value_.rect_ == Rect::ZERO;
  481. case VAR_CUSTOM_HEAP:
  482. case VAR_CUSTOM_STACK:
  483. return GetCustomVariantValuePtr()->IsZero();
  484. default:
  485. return true;
  486. }
  487. }
  488. void Variant::SetType(VariantType newType)
  489. {
  490. if (type_ == newType)
  491. return;
  492. switch (type_)
  493. {
  494. case VAR_STRING:
  495. value_.string_.~String();
  496. break;
  497. case VAR_BUFFER:
  498. value_.buffer_.~PODVector<unsigned char>();
  499. break;
  500. case VAR_RESOURCEREF:
  501. value_.resourceRef_.~ResourceRef();
  502. break;
  503. case VAR_RESOURCEREFLIST:
  504. value_.resourceRefList_.~ResourceRefList();
  505. break;
  506. case VAR_VARIANTVECTOR:
  507. value_.variantVector_.~VariantVector();
  508. break;
  509. case VAR_STRINGVECTOR:
  510. value_.stringVector_.~StringVector();
  511. break;
  512. case VAR_VARIANTMAP:
  513. value_.variantMap_.~VariantMap();
  514. break;
  515. case VAR_PTR:
  516. value_.weakPtr_.~WeakPtr<RefCounted>();
  517. break;
  518. case VAR_MATRIX3:
  519. delete value_.matrix3_;
  520. break;
  521. case VAR_MATRIX3X4:
  522. delete value_.matrix3x4_;
  523. break;
  524. case VAR_MATRIX4:
  525. delete value_.matrix4_;
  526. break;
  527. case VAR_CUSTOM_HEAP:
  528. delete value_.customValueHeap_;
  529. break;
  530. case VAR_CUSTOM_STACK:
  531. value_.customValueStack_.~CustomVariantValue();
  532. break;
  533. default:
  534. break;
  535. }
  536. type_ = newType;
  537. switch (type_)
  538. {
  539. case VAR_STRING:
  540. new(&value_.string_) String();
  541. break;
  542. case VAR_BUFFER:
  543. new(&value_.buffer_) PODVector<unsigned char>();
  544. break;
  545. case VAR_RESOURCEREF:
  546. new(&value_.resourceRef_) ResourceRef();
  547. break;
  548. case VAR_RESOURCEREFLIST:
  549. new(&value_.resourceRefList_) ResourceRefList();
  550. break;
  551. case VAR_VARIANTVECTOR:
  552. new(&value_.variantVector_) VariantVector();
  553. break;
  554. case VAR_STRINGVECTOR:
  555. new(&value_.stringVector_) StringVector();
  556. break;
  557. case VAR_VARIANTMAP:
  558. new(&value_.variantMap_) VariantMap();
  559. break;
  560. case VAR_PTR:
  561. new(&value_.weakPtr_) WeakPtr<RefCounted>();
  562. break;
  563. case VAR_MATRIX3:
  564. value_.matrix3_ = new Matrix3();
  565. break;
  566. case VAR_MATRIX3X4:
  567. value_.matrix3x4_ = new Matrix3x4();
  568. break;
  569. case VAR_MATRIX4:
  570. value_.matrix4_ = new Matrix4();
  571. break;
  572. case VAR_CUSTOM_HEAP:
  573. // Must be initialized later
  574. value_.customValueHeap_ = nullptr;
  575. break;
  576. case VAR_CUSTOM_STACK:
  577. // Initialize virtual table with void custom object
  578. new (&value_.customValueStack_) CustomVariantValue();
  579. break;
  580. default:
  581. break;
  582. }
  583. }
  584. template <> int Variant::Get<int>() const
  585. {
  586. return GetInt();
  587. }
  588. template <> unsigned Variant::Get<unsigned>() const
  589. {
  590. return GetUInt();
  591. }
  592. template <> long long Variant::Get<long long>() const
  593. {
  594. return GetInt64();
  595. }
  596. template <> unsigned long long Variant::Get<unsigned long long>() const
  597. {
  598. return GetUInt64();
  599. }
  600. template <> StringHash Variant::Get<StringHash>() const
  601. {
  602. return GetStringHash();
  603. }
  604. template <> bool Variant::Get<bool>() const
  605. {
  606. return GetBool();
  607. }
  608. template <> float Variant::Get<float>() const
  609. {
  610. return GetFloat();
  611. }
  612. template <> double Variant::Get<double>() const
  613. {
  614. return GetDouble();
  615. }
  616. template <> const Vector2& Variant::Get<const Vector2&>() const
  617. {
  618. return GetVector2();
  619. }
  620. template <> const Vector3& Variant::Get<const Vector3&>() const
  621. {
  622. return GetVector3();
  623. }
  624. template <> const Vector4& Variant::Get<const Vector4&>() const
  625. {
  626. return GetVector4();
  627. }
  628. template <> const Quaternion& Variant::Get<const Quaternion&>() const
  629. {
  630. return GetQuaternion();
  631. }
  632. template <> const Color& Variant::Get<const Color&>() const
  633. {
  634. return GetColor();
  635. }
  636. template <> const String& Variant::Get<const String&>() const
  637. {
  638. return GetString();
  639. }
  640. template <> const Rect& Variant::Get<const Rect&>() const
  641. {
  642. return GetRect();
  643. }
  644. template <> const IntRect& Variant::Get<const IntRect&>() const
  645. {
  646. return GetIntRect();
  647. }
  648. template <> const IntVector2& Variant::Get<const IntVector2&>() const
  649. {
  650. return GetIntVector2();
  651. }
  652. template <> const IntVector3& Variant::Get<const IntVector3&>() const
  653. {
  654. return GetIntVector3();
  655. }
  656. template <> const PODVector<unsigned char>& Variant::Get<const PODVector<unsigned char>&>() const
  657. {
  658. return GetBuffer();
  659. }
  660. template <> void* Variant::Get<void*>() const
  661. {
  662. return GetVoidPtr();
  663. }
  664. template <> RefCounted* Variant::Get<RefCounted*>() const
  665. {
  666. return GetPtr();
  667. }
  668. template <> const Matrix3& Variant::Get<const Matrix3&>() const
  669. {
  670. return GetMatrix3();
  671. }
  672. template <> const Matrix3x4& Variant::Get<const Matrix3x4&>() const
  673. {
  674. return GetMatrix3x4();
  675. }
  676. template <> const Matrix4& Variant::Get<const Matrix4&>() const
  677. {
  678. return GetMatrix4();
  679. }
  680. template <> ResourceRef Variant::Get<ResourceRef>() const
  681. {
  682. return GetResourceRef();
  683. }
  684. template <> ResourceRefList Variant::Get<ResourceRefList>() const
  685. {
  686. return GetResourceRefList();
  687. }
  688. template <> VariantVector Variant::Get<VariantVector>() const
  689. {
  690. return GetVariantVector();
  691. }
  692. template <> StringVector Variant::Get<StringVector >() const
  693. {
  694. return GetStringVector();
  695. }
  696. template <> VariantMap Variant::Get<VariantMap>() const
  697. {
  698. return GetVariantMap();
  699. }
  700. template <> Vector2 Variant::Get<Vector2>() const
  701. {
  702. return GetVector2();
  703. }
  704. template <> Vector3 Variant::Get<Vector3>() const
  705. {
  706. return GetVector3();
  707. }
  708. template <> Vector4 Variant::Get<Vector4>() const
  709. {
  710. return GetVector4();
  711. }
  712. template <> Quaternion Variant::Get<Quaternion>() const
  713. {
  714. return GetQuaternion();
  715. }
  716. template <> Color Variant::Get<Color>() const
  717. {
  718. return GetColor();
  719. }
  720. template <> String Variant::Get<String>() const
  721. {
  722. return GetString();
  723. }
  724. template <> Rect Variant::Get<Rect>() const
  725. {
  726. return GetRect();
  727. }
  728. template <> IntRect Variant::Get<IntRect>() const
  729. {
  730. return GetIntRect();
  731. }
  732. template <> IntVector2 Variant::Get<IntVector2>() const
  733. {
  734. return GetIntVector2();
  735. }
  736. template <> IntVector3 Variant::Get<IntVector3>() const
  737. {
  738. return GetIntVector3();
  739. }
  740. template <> PODVector<unsigned char> Variant::Get<PODVector<unsigned char> >() const
  741. {
  742. return GetBuffer();
  743. }
  744. template <> Matrix3 Variant::Get<Matrix3>() const
  745. {
  746. return GetMatrix3();
  747. }
  748. template <> Matrix3x4 Variant::Get<Matrix3x4>() const
  749. {
  750. return GetMatrix3x4();
  751. }
  752. template <> Matrix4 Variant::Get<Matrix4>() const
  753. {
  754. return GetMatrix4();
  755. }
  756. String Variant::GetTypeName(VariantType type)
  757. {
  758. return typeNames[type];
  759. }
  760. VariantType Variant::GetTypeFromName(const String& typeName)
  761. {
  762. return GetTypeFromName(typeName.CString());
  763. }
  764. VariantType Variant::GetTypeFromName(const char* typeName)
  765. {
  766. return (VariantType)GetStringListIndex(typeName, typeNames, VAR_NONE);
  767. }
  768. }