Variant.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. #include "../../Include/RmlUi/Core/Variant.h"
  2. #include "../../Include/RmlUi/Core/DecorationTypes.h"
  3. #include <string.h>
  4. namespace Rml {
  5. Variant::Variant()
  6. {
  7. // Make sure our object size assumptions fit inside the static buffer
  8. static_assert(sizeof(Colourb) <= LOCAL_DATA_SIZE, "Local data too small for Colourb");
  9. static_assert(sizeof(Colourf) <= LOCAL_DATA_SIZE, "Local data too small for Colourf");
  10. static_assert(sizeof(Vector4f) <= LOCAL_DATA_SIZE, "Local data too small for Vector4f");
  11. static_assert(sizeof(String) <= LOCAL_DATA_SIZE, "Local data too small for String");
  12. static_assert(sizeof(TransformPtr) <= LOCAL_DATA_SIZE, "Local data too small for TransformPtr");
  13. static_assert(sizeof(TransitionList) <= LOCAL_DATA_SIZE, "Local data too small for TransitionList");
  14. static_assert(sizeof(AnimationList) <= LOCAL_DATA_SIZE, "Local data too small for AnimationList");
  15. static_assert(sizeof(DecoratorsPtr) <= LOCAL_DATA_SIZE, "Local data too small for DecoratorsPtr");
  16. static_assert(sizeof(FiltersPtr) <= LOCAL_DATA_SIZE, "Local data too small for FiltersPtr");
  17. static_assert(sizeof(FontEffectsPtr) <= LOCAL_DATA_SIZE, "Local data too small for FontEffectsPtr");
  18. static_assert(sizeof(ColorStopList) <= LOCAL_DATA_SIZE, "Local data too small for ColorStopList");
  19. static_assert(sizeof(BoxShadowList) <= LOCAL_DATA_SIZE, "Local data too small for BoxShadowList");
  20. }
  21. Variant::Variant(const Variant& copy)
  22. {
  23. Set(copy);
  24. }
  25. Variant::Variant(Variant&& other) noexcept
  26. {
  27. Set(std::move(other));
  28. }
  29. Variant::~Variant()
  30. {
  31. Clear();
  32. }
  33. void Variant::Clear()
  34. {
  35. // Free any allocated types.
  36. switch (type)
  37. {
  38. case STRING:
  39. {
  40. // Clean up the string.
  41. String* string = (String*)data;
  42. string->~String();
  43. }
  44. break;
  45. case TRANSFORMPTR:
  46. {
  47. // Clean up the transform.
  48. TransformPtr* transform = (TransformPtr*)data;
  49. transform->~TransformPtr();
  50. }
  51. break;
  52. case TRANSITIONLIST:
  53. {
  54. // Clean up the transition list.
  55. TransitionList* transition_list = (TransitionList*)data;
  56. transition_list->~TransitionList();
  57. }
  58. break;
  59. case ANIMATIONLIST:
  60. {
  61. // Clean up the transition list.
  62. AnimationList* animation_list = (AnimationList*)data;
  63. animation_list->~AnimationList();
  64. }
  65. break;
  66. case DECORATORSPTR:
  67. {
  68. DecoratorsPtr* decorators = (DecoratorsPtr*)data;
  69. decorators->~DecoratorsPtr();
  70. }
  71. break;
  72. case FILTERSPTR:
  73. {
  74. FiltersPtr* decorators = (FiltersPtr*)data;
  75. decorators->~FiltersPtr();
  76. }
  77. break;
  78. case FONTEFFECTSPTR:
  79. {
  80. FontEffectsPtr* font_effects = (FontEffectsPtr*)data;
  81. font_effects->~shared_ptr();
  82. }
  83. break;
  84. case COLORSTOPLIST:
  85. {
  86. ColorStopList* value = (ColorStopList*)data;
  87. value->~ColorStopList();
  88. }
  89. break;
  90. case BOXSHADOWLIST:
  91. {
  92. BoxShadowList* value = (BoxShadowList*)data;
  93. value->~BoxShadowList();
  94. }
  95. break;
  96. default: break;
  97. }
  98. type = NONE;
  99. }
  100. #define SET_VARIANT(type) *((type*)data) = value;
  101. void Variant::Set(const Variant& copy)
  102. {
  103. switch (copy.type)
  104. {
  105. case STRING: Set(*reinterpret_cast<const String*>(copy.data)); break;
  106. case TRANSFORMPTR: Set(*reinterpret_cast<const TransformPtr*>(copy.data)); break;
  107. case TRANSITIONLIST: Set(*reinterpret_cast<const TransitionList*>(copy.data)); break;
  108. case ANIMATIONLIST: Set(*reinterpret_cast<const AnimationList*>(copy.data)); break;
  109. case DECORATORSPTR: Set(*reinterpret_cast<const DecoratorsPtr*>(copy.data)); break;
  110. case FILTERSPTR: Set(*reinterpret_cast<const FiltersPtr*>(copy.data)); break;
  111. case FONTEFFECTSPTR: Set(*reinterpret_cast<const FontEffectsPtr*>(copy.data)); break;
  112. case COLORSTOPLIST: Set(*reinterpret_cast<const ColorStopList*>(copy.data)); break;
  113. case BOXSHADOWLIST: Set(*reinterpret_cast<const BoxShadowList*>(copy.data)); break;
  114. default:
  115. memcpy(data, copy.data, LOCAL_DATA_SIZE);
  116. type = copy.type;
  117. break;
  118. }
  119. RMLUI_ASSERT(type == copy.type);
  120. }
  121. void Variant::Set(Variant&& other)
  122. {
  123. switch (other.type)
  124. {
  125. case STRING: Set(std::move(*reinterpret_cast<String*>(other.data))); break;
  126. case TRANSFORMPTR: Set(std::move(*reinterpret_cast<TransformPtr*>(other.data))); break;
  127. case TRANSITIONLIST: Set(std::move(*reinterpret_cast<TransitionList*>(other.data))); break;
  128. case ANIMATIONLIST: Set(std::move(*reinterpret_cast<AnimationList*>(other.data))); break;
  129. case DECORATORSPTR: Set(std::move(*reinterpret_cast<DecoratorsPtr*>(other.data))); break;
  130. case FILTERSPTR: Set(std::move(*reinterpret_cast<FiltersPtr*>(other.data))); break;
  131. case FONTEFFECTSPTR: Set(std::move(*reinterpret_cast<FontEffectsPtr*>(other.data))); break;
  132. case COLORSTOPLIST: Set(std::move(*reinterpret_cast<ColorStopList*>(other.data))); break;
  133. case BOXSHADOWLIST: Set(std::move(*reinterpret_cast<BoxShadowList*>(other.data))); break;
  134. default:
  135. memcpy(data, other.data, LOCAL_DATA_SIZE);
  136. type = other.type;
  137. break;
  138. }
  139. RMLUI_ASSERT(type == other.type);
  140. }
  141. void Variant::Set(const bool value)
  142. {
  143. type = BOOL;
  144. SET_VARIANT(bool);
  145. }
  146. void Variant::Set(const byte value)
  147. {
  148. type = BYTE;
  149. SET_VARIANT(byte);
  150. }
  151. void Variant::Set(const char value)
  152. {
  153. type = CHAR;
  154. SET_VARIANT(char);
  155. }
  156. void Variant::Set(const float value)
  157. {
  158. type = FLOAT;
  159. SET_VARIANT(float);
  160. }
  161. void Variant::Set(const double value)
  162. {
  163. type = DOUBLE;
  164. SET_VARIANT(double);
  165. }
  166. void Variant::Set(const int value)
  167. {
  168. type = INT;
  169. SET_VARIANT(int);
  170. }
  171. void Variant::Set(const int64_t value)
  172. {
  173. type = INT64;
  174. SET_VARIANT(int64_t);
  175. }
  176. void Variant::Set(const unsigned int value)
  177. {
  178. type = UINT;
  179. SET_VARIANT(unsigned int);
  180. }
  181. void Variant::Set(const uint64_t value)
  182. {
  183. type = UINT64;
  184. SET_VARIANT(uint64_t);
  185. }
  186. void Variant::Set(const char* value)
  187. {
  188. Set(String(value));
  189. }
  190. void Variant::Set(void* voidptr)
  191. {
  192. type = VOIDPTR;
  193. memcpy(data, &voidptr, sizeof(void*));
  194. }
  195. void Variant::Set(const Vector2f value)
  196. {
  197. type = VECTOR2;
  198. SET_VARIANT(Vector2f);
  199. }
  200. void Variant::Set(const Vector3f value)
  201. {
  202. type = VECTOR3;
  203. SET_VARIANT(Vector3f);
  204. }
  205. void Variant::Set(const Vector4f value)
  206. {
  207. type = VECTOR4;
  208. SET_VARIANT(Vector4f);
  209. }
  210. void Variant::Set(const Colourf value)
  211. {
  212. type = COLOURF;
  213. SET_VARIANT(Colourf);
  214. }
  215. void Variant::Set(const Colourb value)
  216. {
  217. type = COLOURB;
  218. SET_VARIANT(Colourb);
  219. }
  220. void Variant::Set(ScriptInterface* value)
  221. {
  222. type = SCRIPTINTERFACE;
  223. memcpy(data, &value, sizeof(ScriptInterface*));
  224. }
  225. void Variant::Set(const String& value)
  226. {
  227. if (type == STRING)
  228. {
  229. (*(String*)data) = value;
  230. }
  231. else
  232. {
  233. type = STRING;
  234. new (data) String(value);
  235. }
  236. }
  237. void Variant::Set(String&& value)
  238. {
  239. if (type == STRING)
  240. {
  241. (*(String*)data) = std::move(value);
  242. }
  243. else
  244. {
  245. type = STRING;
  246. new (data) String(std::move(value));
  247. }
  248. }
  249. void Variant::Set(const TransformPtr& value)
  250. {
  251. if (type == TRANSFORMPTR)
  252. {
  253. SET_VARIANT(TransformPtr);
  254. }
  255. else
  256. {
  257. type = TRANSFORMPTR;
  258. new (data) TransformPtr(value);
  259. }
  260. }
  261. void Variant::Set(TransformPtr&& value)
  262. {
  263. if (type == TRANSFORMPTR)
  264. {
  265. (*(TransformPtr*)data) = std::move(value);
  266. }
  267. else
  268. {
  269. type = TRANSFORMPTR;
  270. new (data) TransformPtr(std::move(value));
  271. }
  272. }
  273. void Variant::Set(const TransitionList& value)
  274. {
  275. if (type == TRANSITIONLIST)
  276. {
  277. *(TransitionList*)data = value;
  278. }
  279. else
  280. {
  281. type = TRANSITIONLIST;
  282. new (data) TransitionList(value);
  283. }
  284. }
  285. void Variant::Set(TransitionList&& value)
  286. {
  287. if (type == TRANSITIONLIST)
  288. {
  289. (*(TransitionList*)data) = std::move(value);
  290. }
  291. else
  292. {
  293. type = TRANSITIONLIST;
  294. new (data) TransitionList(std::move(value));
  295. }
  296. }
  297. void Variant::Set(const AnimationList& value)
  298. {
  299. if (type == ANIMATIONLIST)
  300. {
  301. *(AnimationList*)data = value;
  302. }
  303. else
  304. {
  305. type = ANIMATIONLIST;
  306. new (data) AnimationList(value);
  307. }
  308. }
  309. void Variant::Set(AnimationList&& value)
  310. {
  311. if (type == ANIMATIONLIST)
  312. {
  313. (*(AnimationList*)data) = std::move(value);
  314. }
  315. else
  316. {
  317. type = ANIMATIONLIST;
  318. new (data) AnimationList(std::move(value));
  319. }
  320. }
  321. void Variant::Set(const DecoratorsPtr& value)
  322. {
  323. if (type == DECORATORSPTR)
  324. {
  325. *(DecoratorsPtr*)data = value;
  326. }
  327. else
  328. {
  329. type = DECORATORSPTR;
  330. new (data) DecoratorsPtr(value);
  331. }
  332. }
  333. void Variant::Set(DecoratorsPtr&& value)
  334. {
  335. if (type == DECORATORSPTR)
  336. {
  337. (*(DecoratorsPtr*)data) = std::move(value);
  338. }
  339. else
  340. {
  341. type = DECORATORSPTR;
  342. new (data) DecoratorsPtr(std::move(value));
  343. }
  344. }
  345. void Variant::Set(const FiltersPtr& value)
  346. {
  347. if (type == FILTERSPTR)
  348. {
  349. *(FiltersPtr*)data = value;
  350. }
  351. else
  352. {
  353. type = FILTERSPTR;
  354. new (data) FiltersPtr(value);
  355. }
  356. }
  357. void Variant::Set(FiltersPtr&& value)
  358. {
  359. if (type == FILTERSPTR)
  360. {
  361. (*(FiltersPtr*)data) = std::move(value);
  362. }
  363. else
  364. {
  365. type = FILTERSPTR;
  366. new (data) FiltersPtr(std::move(value));
  367. }
  368. }
  369. void Variant::Set(const FontEffectsPtr& value)
  370. {
  371. if (type == FONTEFFECTSPTR)
  372. {
  373. *(FontEffectsPtr*)data = value;
  374. }
  375. else
  376. {
  377. type = FONTEFFECTSPTR;
  378. new (data) FontEffectsPtr(value);
  379. }
  380. }
  381. void Variant::Set(FontEffectsPtr&& value)
  382. {
  383. if (type == FONTEFFECTSPTR)
  384. {
  385. (*(FontEffectsPtr*)data) = std::move(value);
  386. }
  387. else
  388. {
  389. type = FONTEFFECTSPTR;
  390. new (data) FontEffectsPtr(std::move(value));
  391. }
  392. }
  393. void Variant::Set(const ColorStopList& value)
  394. {
  395. if (type == COLORSTOPLIST)
  396. {
  397. *(ColorStopList*)data = value;
  398. }
  399. else
  400. {
  401. type = COLORSTOPLIST;
  402. new (data) ColorStopList(value);
  403. }
  404. }
  405. void Variant::Set(ColorStopList&& value)
  406. {
  407. if (type == COLORSTOPLIST)
  408. {
  409. (*(ColorStopList*)data) = std::move(value);
  410. }
  411. else
  412. {
  413. type = COLORSTOPLIST;
  414. new (data) ColorStopList(std::move(value));
  415. }
  416. }
  417. void Variant::Set(const BoxShadowList& value)
  418. {
  419. if (type == BOXSHADOWLIST)
  420. {
  421. *(BoxShadowList*)data = value;
  422. }
  423. else
  424. {
  425. type = BOXSHADOWLIST;
  426. new (data) BoxShadowList(value);
  427. }
  428. }
  429. void Variant::Set(BoxShadowList&& value)
  430. {
  431. if (type == BOXSHADOWLIST)
  432. {
  433. (*(BoxShadowList*)data) = std::move(value);
  434. }
  435. else
  436. {
  437. type = BOXSHADOWLIST;
  438. new (data) BoxShadowList(std::move(value));
  439. }
  440. }
  441. Variant& Variant::operator=(const Variant& copy)
  442. {
  443. if (this == &copy)
  444. return *this;
  445. if (copy.type != type)
  446. Clear();
  447. Set(copy);
  448. return *this;
  449. }
  450. Variant& Variant::operator=(Variant&& other) noexcept
  451. {
  452. if (this == &other)
  453. return *this;
  454. if (other.type != type)
  455. Clear();
  456. Set(std::move(other));
  457. return *this;
  458. }
  459. #define DEFAULT_VARIANT_COMPARE(TYPE) static_cast<TYPE>(*(TYPE*)data) == static_cast<TYPE>(*(TYPE*)other.data)
  460. bool Variant::operator==(const Variant& other) const
  461. {
  462. if (type != other.type)
  463. return false;
  464. switch (type)
  465. {
  466. case BOOL: return DEFAULT_VARIANT_COMPARE(bool);
  467. case BYTE: return DEFAULT_VARIANT_COMPARE(byte);
  468. case CHAR: return DEFAULT_VARIANT_COMPARE(char);
  469. case FLOAT: return DEFAULT_VARIANT_COMPARE(float);
  470. case DOUBLE: return DEFAULT_VARIANT_COMPARE(double);
  471. case INT: return DEFAULT_VARIANT_COMPARE(int);
  472. case INT64: return DEFAULT_VARIANT_COMPARE(int64_t);
  473. case UINT: return DEFAULT_VARIANT_COMPARE(unsigned int);
  474. case UINT64: return DEFAULT_VARIANT_COMPARE(uint64_t);
  475. case STRING: return DEFAULT_VARIANT_COMPARE(String);
  476. case VECTOR2: return DEFAULT_VARIANT_COMPARE(Vector2f);
  477. case VECTOR3: return DEFAULT_VARIANT_COMPARE(Vector3f);
  478. case VECTOR4: return DEFAULT_VARIANT_COMPARE(Vector4f);
  479. case COLOURF: return DEFAULT_VARIANT_COMPARE(Colourf);
  480. case COLOURB: return DEFAULT_VARIANT_COMPARE(Colourb);
  481. case SCRIPTINTERFACE: return DEFAULT_VARIANT_COMPARE(ScriptInterface*);
  482. case VOIDPTR: return DEFAULT_VARIANT_COMPARE(void*);
  483. case TRANSFORMPTR: return DEFAULT_VARIANT_COMPARE(TransformPtr);
  484. case TRANSITIONLIST: return DEFAULT_VARIANT_COMPARE(TransitionList);
  485. case ANIMATIONLIST: return DEFAULT_VARIANT_COMPARE(AnimationList);
  486. case DECORATORSPTR: return DEFAULT_VARIANT_COMPARE(DecoratorsPtr);
  487. case FILTERSPTR: return DEFAULT_VARIANT_COMPARE(FiltersPtr);
  488. case FONTEFFECTSPTR: return DEFAULT_VARIANT_COMPARE(FontEffectsPtr);
  489. case COLORSTOPLIST: return DEFAULT_VARIANT_COMPARE(ColorStopList);
  490. case BOXSHADOWLIST: return DEFAULT_VARIANT_COMPARE(BoxShadowList);
  491. case NONE: return true;
  492. }
  493. RMLUI_ERRORMSG("Variant comparison not implemented for this type.");
  494. return false;
  495. }
  496. } // namespace Rml