3
0

UiSerialize.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "UiSerialize.h"
  9. #include <LyShine/UiAssetTypes.h>
  10. #include <LyShine/IDraw2d.h>
  11. #include <LyShine/UiBase.h>
  12. #include "UiInteractableComponent.h"
  13. #include <LyShine/UiSerializeHelpers.h>
  14. #include <LyShine/Bus/UiParticleEmitterBus.h>
  15. #include <LyShine/Bus/UiImageBus.h>
  16. #include <LyShine/Bus/UiTransform2dBus.h>
  17. #include <UiElementComponent.h>
  18. #include <UiCanvasComponent.h>
  19. #include <UiLayoutGridComponent.h>
  20. #include <AzCore/Serialization/SerializeContext.h>
  21. #include <AzCore/RTTI/BehaviorContext.h>
  22. #include <AzCore/Script/ScriptContext.h>
  23. #include <AzCore/Slice/SliceComponent.h>
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////
  25. // NAMESPACE FUNCTIONS
  26. ////////////////////////////////////////////////////////////////////////////////////////////////////
  27. namespace UiSerialize
  28. {
  29. //////////////////////////////////////////////////////////////////////////
  30. void UiOffsetsScriptConstructor(UiTransform2dInterface::Offsets* thisPtr, AZ::ScriptDataContext& dc)
  31. {
  32. int numArgs = dc.GetNumArguments();
  33. const int noArgsGiven = 0;
  34. const int allArgsGiven = 4;
  35. switch (numArgs)
  36. {
  37. case noArgsGiven:
  38. {
  39. *thisPtr = UiTransform2dInterface::Offsets();
  40. }
  41. break;
  42. case allArgsGiven:
  43. {
  44. if (dc.IsNumber(0) && dc.IsNumber(1) && dc.IsNumber(2) && dc.IsNumber(3))
  45. {
  46. float left = 0;
  47. float top = 0;
  48. float right = 0;
  49. float bottom = 0;
  50. dc.ReadArg(0, left);
  51. dc.ReadArg(1, top);
  52. dc.ReadArg(2, right);
  53. dc.ReadArg(3, bottom);
  54. *thisPtr = UiTransform2dInterface::Offsets(left, top, right, bottom);
  55. }
  56. else
  57. {
  58. dc.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, "When providing 4 arguments to UiOffsets(), all must be numbers!");
  59. }
  60. }
  61. break;
  62. default:
  63. {
  64. dc.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, "UiOffsets() accepts only 0 or 4 arguments, not %d!", numArgs);
  65. }
  66. break;
  67. }
  68. }
  69. //////////////////////////////////////////////////////////////////////////
  70. void UiAnchorsScriptConstructor(UiTransform2dInterface::Anchors* thisPtr, AZ::ScriptDataContext& dc)
  71. {
  72. int numArgs = dc.GetNumArguments();
  73. const int noArgsGiven = 0;
  74. const int allArgsGiven = 4;
  75. switch (numArgs)
  76. {
  77. case noArgsGiven:
  78. {
  79. *thisPtr = UiTransform2dInterface::Anchors();
  80. }
  81. break;
  82. case allArgsGiven:
  83. {
  84. if (dc.IsNumber(0) && dc.IsNumber(1) && dc.IsNumber(2) && dc.IsNumber(3))
  85. {
  86. float left = 0;
  87. float top = 0;
  88. float right = 0;
  89. float bottom = 0;
  90. dc.ReadArg(0, left);
  91. dc.ReadArg(1, top);
  92. dc.ReadArg(2, right);
  93. dc.ReadArg(3, bottom);
  94. *thisPtr = UiTransform2dInterface::Anchors(left, top, right, bottom);
  95. }
  96. else
  97. {
  98. dc.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, "When providing 4 arguments to UiAnchors(), all must be numbers!");
  99. }
  100. }
  101. break;
  102. default:
  103. {
  104. dc.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, "UiAnchors() accepts only 0 or 4 arguments, not %d!", numArgs);
  105. }
  106. break;
  107. }
  108. }
  109. ////////////////////////////////////////////////////////////////////////////////////////////////////
  110. void SetAnchorLeft(UiTransform2dInterface::Anchors* anchor, float left)
  111. {
  112. if (anchor)
  113. {
  114. anchor->m_left = left;
  115. }
  116. else
  117. {
  118. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set left on null anchor.")
  119. }
  120. }
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////
  122. void SetAnchorTop(UiTransform2dInterface::Anchors* anchor, float top)
  123. {
  124. if (anchor)
  125. {
  126. anchor->m_top = top;
  127. }
  128. else
  129. {
  130. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set top on null anchor.")
  131. }
  132. }
  133. ////////////////////////////////////////////////////////////////////////////////////////////////////
  134. void SetAnchorRight(UiTransform2dInterface::Anchors* anchor, float right)
  135. {
  136. if (anchor)
  137. {
  138. anchor->m_right = right;
  139. }
  140. else
  141. {
  142. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set right on null anchor.")
  143. }
  144. }
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////
  146. void SetAnchorBottom(UiTransform2dInterface::Anchors* anchor, float bottom)
  147. {
  148. if (anchor)
  149. {
  150. anchor->m_bottom = bottom;
  151. }
  152. else
  153. {
  154. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set bottom on null anchor.")
  155. }
  156. }
  157. ////////////////////////////////////////////////////////////////////////////////////////////////////
  158. void SetAnchors(UiTransform2dInterface::Anchors* anchor, float left, float top, float right, float bottom)
  159. {
  160. if (anchor)
  161. {
  162. anchor->m_left = left;
  163. anchor->m_top = top;
  164. anchor->m_right = right;
  165. anchor->m_bottom = bottom;
  166. }
  167. else
  168. {
  169. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set values on null anchor.")
  170. }
  171. }
  172. ////////////////////////////////////////////////////////////////////////////////////////////////////
  173. void SetOffsetLeft(UiTransform2dInterface::Offsets* offset, float left)
  174. {
  175. if (offset)
  176. {
  177. offset->m_left = left;
  178. }
  179. else
  180. {
  181. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set left on null offset.")
  182. }
  183. }
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////
  185. void SetOffsetTop(UiTransform2dInterface::Offsets* offset, float top)
  186. {
  187. if (offset)
  188. {
  189. offset->m_top = top;
  190. }
  191. else
  192. {
  193. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set top on null offset.")
  194. }
  195. }
  196. ////////////////////////////////////////////////////////////////////////////////////////////////////
  197. void SetOffsetRight(UiTransform2dInterface::Offsets* offset, float right)
  198. {
  199. if (offset)
  200. {
  201. offset->m_right = right;
  202. }
  203. else
  204. {
  205. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set right on null offset.")
  206. }
  207. }
  208. ////////////////////////////////////////////////////////////////////////////////////////////////////
  209. void SetOffsetBottom(UiTransform2dInterface::Offsets* offset, float bottom)
  210. {
  211. if (offset)
  212. {
  213. offset->m_bottom = bottom;
  214. }
  215. else
  216. {
  217. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set bottom on null offset.")
  218. }
  219. }
  220. ////////////////////////////////////////////////////////////////////////////////////////////////////
  221. void SetOffsets(UiTransform2dInterface::Offsets* offset, float left, float top, float right, float bottom)
  222. {
  223. if (offset)
  224. {
  225. offset->m_left = left;
  226. offset->m_top = top;
  227. offset->m_right = right;
  228. offset->m_bottom = bottom;
  229. }
  230. else
  231. {
  232. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set values on null offset.")
  233. }
  234. }
  235. ////////////////////////////////////////////////////////////////////////////////////////////////////
  236. void SetPaddingLeft(UiLayoutInterface::Padding* padding, int left)
  237. {
  238. if (padding)
  239. {
  240. padding->m_left = left;
  241. }
  242. else
  243. {
  244. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set left on null padding.")
  245. }
  246. }
  247. ////////////////////////////////////////////////////////////////////////////////////////////////////
  248. void SetPaddingTop(UiLayoutInterface::Padding* padding, int top)
  249. {
  250. if (padding)
  251. {
  252. padding->m_top = top;
  253. }
  254. else
  255. {
  256. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set top on null padding.")
  257. }
  258. }
  259. ////////////////////////////////////////////////////////////////////////////////////////////////////
  260. void SetPaddingRight(UiLayoutInterface::Padding* padding, int right)
  261. {
  262. if (padding)
  263. {
  264. padding->m_right = right;
  265. }
  266. else
  267. {
  268. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set right on null padding.")
  269. }
  270. }
  271. ////////////////////////////////////////////////////////////////////////////////////////////////////
  272. void SetPaddingBottom(UiLayoutInterface::Padding* padding, int bottom)
  273. {
  274. if (padding)
  275. {
  276. padding->m_bottom = bottom;
  277. }
  278. else
  279. {
  280. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set bottom on null padding.")
  281. }
  282. }
  283. ////////////////////////////////////////////////////////////////////////////////////////////////////
  284. void SetPadding(UiLayoutInterface::Padding* padding, int left, int top, int right, int bottom)
  285. {
  286. if (padding)
  287. {
  288. padding->m_left = left;
  289. padding->m_top = top;
  290. padding->m_right = right;
  291. padding->m_bottom = bottom;
  292. }
  293. else
  294. {
  295. AZ_ErrorOnce("Script Canvas", false, "UI Script tried to set values on null padding.")
  296. }
  297. }
  298. ////////////////////////////////////////////////////////////////////////////////////////////////////
  299. void ReflectUiTypes(AZ::ReflectContext* context)
  300. {
  301. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  302. AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
  303. if (serializeContext)
  304. {
  305. serializeContext->Class<ColorF>()->
  306. Field("r", &ColorF::r)->
  307. Field("g", &ColorF::g)->
  308. Field("b", &ColorF::b)->
  309. Field("a", &ColorF::a);
  310. serializeContext->Class<ColorB>()->
  311. Field("r", &ColorB::r)->
  312. Field("g", &ColorB::g)->
  313. Field("b", &ColorB::b)->
  314. Field("a", &ColorB::a);
  315. }
  316. // Vec2 (still used in UI Animation sequence splines)
  317. {
  318. if (serializeContext)
  319. {
  320. serializeContext->Class<Vec2>()->
  321. Field("x", &Vec2::x)->
  322. Field("y", &Vec2::y);
  323. }
  324. }
  325. // Vec3 (possibly no longer used)
  326. {
  327. if (serializeContext)
  328. {
  329. serializeContext->Class<Vec3>()->
  330. Field("x", &Vec3::x)->
  331. Field("y", &Vec3::y)->
  332. Field("z", &Vec3::z);
  333. }
  334. }
  335. // Anchors
  336. {
  337. if (serializeContext)
  338. {
  339. serializeContext->Class<UiTransform2dInterface::Anchors>()->
  340. Field("left", &UiTransform2dInterface::Anchors::m_left)->
  341. Field("top", &UiTransform2dInterface::Anchors::m_top)->
  342. Field("right", &UiTransform2dInterface::Anchors::m_right)->
  343. Field("bottom", &UiTransform2dInterface::Anchors::m_bottom);
  344. }
  345. if (behaviorContext)
  346. {
  347. behaviorContext->Class<UiTransform2dInterface::Anchors>("UiAnchors")
  348. ->Constructor<>()
  349. ->Constructor<float, float, float, float>()
  350. ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
  351. ->Attribute(AZ::Script::Attributes::ConstructorOverride, &UiAnchorsScriptConstructor)
  352. ->Property("left", BehaviorValueProperty(&UiTransform2dInterface::Anchors::m_left))
  353. ->Property("top", BehaviorValueProperty(&UiTransform2dInterface::Anchors::m_top))
  354. ->Property("right", BehaviorValueProperty(&UiTransform2dInterface::Anchors::m_right))
  355. ->Property("bottom", BehaviorValueProperty(&UiTransform2dInterface::Anchors::m_bottom))
  356. ->Method("SetLeft", SetAnchorLeft)
  357. ->Method("SetTop", SetAnchorTop)
  358. ->Method("SetRight", SetAnchorRight)
  359. ->Method("SetBottom", SetAnchorBottom)
  360. ->Method("SetAnchors", SetAnchors);
  361. }
  362. }
  363. // ParticleColorKeyframe
  364. {
  365. if (serializeContext)
  366. {
  367. serializeContext->Class<UiParticleEmitterInterface::ParticleColorKeyframe>()
  368. ->Field("Time", &UiParticleEmitterInterface::ParticleColorKeyframe::time)
  369. ->Field("Color", &UiParticleEmitterInterface::ParticleColorKeyframe::color)
  370. ->Field("InTangent", &UiParticleEmitterInterface::ParticleColorKeyframe::inTangent)
  371. ->Field("OutTangent", &UiParticleEmitterInterface::ParticleColorKeyframe::outTangent);
  372. }
  373. }
  374. // ParticleFloatKeyframe
  375. {
  376. if (serializeContext)
  377. {
  378. serializeContext->Class<UiParticleEmitterInterface::ParticleFloatKeyframe>()
  379. ->Field("Time", &UiParticleEmitterInterface::ParticleFloatKeyframe::time)
  380. ->Field("Multiplier", &UiParticleEmitterInterface::ParticleFloatKeyframe::multiplier)
  381. ->Field("InTangent", &UiParticleEmitterInterface::ParticleFloatKeyframe::inTangent)
  382. ->Field("OutTangent", &UiParticleEmitterInterface::ParticleFloatKeyframe::outTangent);
  383. }
  384. }
  385. // Offsets
  386. {
  387. if (serializeContext)
  388. {
  389. serializeContext->Class<UiTransform2dInterface::Offsets>()->
  390. Field("left", &UiTransform2dInterface::Offsets::m_left)->
  391. Field("top", &UiTransform2dInterface::Offsets::m_top)->
  392. Field("right", &UiTransform2dInterface::Offsets::m_right)->
  393. Field("bottom", &UiTransform2dInterface::Offsets::m_bottom);
  394. }
  395. if (behaviorContext)
  396. {
  397. behaviorContext->Class<UiTransform2dInterface::Offsets>("UiOffsets")
  398. ->Constructor<>()
  399. ->Constructor<float, float, float, float>()
  400. ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
  401. ->Attribute(AZ::Script::Attributes::ConstructorOverride, &UiOffsetsScriptConstructor)
  402. ->Property("left", BehaviorValueProperty(&UiTransform2dInterface::Offsets::m_left))
  403. ->Property("top", BehaviorValueProperty(&UiTransform2dInterface::Offsets::m_top))
  404. ->Property("right", BehaviorValueProperty(&UiTransform2dInterface::Offsets::m_right))
  405. ->Property("bottom", BehaviorValueProperty(&UiTransform2dInterface::Offsets::m_bottom))
  406. ->Method("SetLeft", SetOffsetLeft)
  407. ->Method("SetTop", SetOffsetTop)
  408. ->Method("SetRight", SetOffsetRight)
  409. ->Method("SetBottom", SetOffsetBottom)
  410. ->Method("SetOffsets", SetOffsets);
  411. }
  412. }
  413. // Padding
  414. {
  415. if (serializeContext)
  416. {
  417. serializeContext->Class<UiLayoutInterface::Padding>()->
  418. Field("left", &UiLayoutInterface::Padding::m_left)->
  419. Field("top", &UiLayoutInterface::Padding::m_top)->
  420. Field("right", &UiLayoutInterface::Padding::m_right)->
  421. Field("bottom", &UiLayoutInterface::Padding::m_bottom);
  422. }
  423. if (behaviorContext)
  424. {
  425. behaviorContext->Class<UiLayoutInterface::Padding>("UiPadding")
  426. ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
  427. ->Property("left", BehaviorValueProperty(&UiLayoutInterface::Padding::m_left))
  428. ->Property("right", BehaviorValueProperty(&UiLayoutInterface::Padding::m_right))
  429. ->Property("top", BehaviorValueProperty(&UiLayoutInterface::Padding::m_top))
  430. ->Property("bottom", BehaviorValueProperty(&UiLayoutInterface::Padding::m_bottom))
  431. ->Method("SetLeft", SetPaddingLeft)
  432. ->Method("SetTop", SetPaddingTop)
  433. ->Method("SetRight", SetPaddingRight)
  434. ->Method("SetBottom", SetPaddingBottom)
  435. ->Method("SetPadding", SetPadding);
  436. }
  437. }
  438. // UiLayout enums
  439. {
  440. if (behaviorContext)
  441. {
  442. behaviorContext->Enum<(int)UiLayoutInterface::HorizontalOrder::LeftToRight>("eUiHorizontalOrder_LeftToRight")
  443. ->Enum<(int)UiLayoutInterface::HorizontalOrder::RightToLeft>("eUiHorizontalOrder_RightToLeft")
  444. ->Enum<(int)UiLayoutInterface::VerticalOrder::TopToBottom>("eUiVerticalOrder_TopToBottom")
  445. ->Enum<(int)UiLayoutInterface::VerticalOrder::BottomToTop>("eUiVerticalOrder_BottomToTop");
  446. }
  447. }
  448. // IDraw2d enums
  449. {
  450. if (behaviorContext)
  451. {
  452. behaviorContext->Enum<(int)IDraw2d::HAlign::Left>("eUiHAlign_Left")
  453. ->Enum<(int)IDraw2d::HAlign::Center>("eUiHAlign_Center")
  454. ->Enum<(int)IDraw2d::HAlign::Right>("eUiHAlign_Right")
  455. ->Enum<(int)IDraw2d::VAlign::Top>("eUiVAlign_Top")
  456. ->Enum<(int)IDraw2d::VAlign::Center>("eUiVAlign_Center")
  457. ->Enum<(int)IDraw2d::VAlign::Bottom>("eUiVAlign_Bottom");
  458. }
  459. }
  460. if (serializeContext)
  461. {
  462. serializeContext->Class<AnimationData>()
  463. ->Version(1)
  464. ->Field("SerializeString", &AnimationData::m_serializeData);
  465. // deprecate old classes that no longer exist
  466. serializeContext->ClassDeprecate("UiCanvasEditor", AZ::Uuid("{65682E87-B573-435B-88CB-B4C12B71EEEE}"));
  467. serializeContext->ClassDeprecate("ImageAsset", AZ::Uuid("{138E471A-F3AE-404A-9075-EDC7488C97FC}"));
  468. // Allow loading FontAssets and CanvasAssets with previous Uuid specializations of AZ_TYPE_INFO_SPECIALIZE
  469. serializeContext->ClassDeprecate("SimpleAssetReference_FontAsset", AZ::Uuid("{D6342379-A5FA-4B18-B890-702C2FE99A5A}"),
  470. [](AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootElement)
  471. {
  472. AZStd::vector<AZ::SerializeContext::DataElementNode> childNodeElements;
  473. for (int index = 0; index < rootElement.GetNumSubElements(); ++index)
  474. {
  475. childNodeElements.push_back(rootElement.GetSubElement(index));
  476. }
  477. // Convert the rootElement now, the existing child DataElmentNodes are now removed
  478. rootElement.Convert<AzFramework::SimpleAssetReference<LyShine::FontAsset>>(context);
  479. for (AZ::SerializeContext::DataElementNode& childNodeElement : childNodeElements)
  480. {
  481. rootElement.AddElement(AZStd::move(childNodeElement));
  482. }
  483. return true;
  484. });
  485. AzFramework::SimpleAssetReference<LyShine::FontAsset>::Register(*serializeContext);
  486. AzFramework::SimpleAssetReference<LyShine::CanvasAsset>::Register(*serializeContext);
  487. UiInteractableComponent::Reflect(serializeContext);
  488. }
  489. if (behaviorContext)
  490. {
  491. UiInteractableComponent::Reflect(behaviorContext);
  492. behaviorContext->EBus<UiLayoutBus>("UiLayoutBus")
  493. ->Event("GetHorizontalChildAlignment", &UiLayoutBus::Events::GetHorizontalChildAlignment)
  494. ->Event("SetHorizontalChildAlignment", &UiLayoutBus::Events::SetHorizontalChildAlignment)
  495. ->Event("GetVerticalChildAlignment", &UiLayoutBus::Events::GetVerticalChildAlignment)
  496. ->Event("SetVerticalChildAlignment", &UiLayoutBus::Events::SetVerticalChildAlignment)
  497. ->Event("GetIgnoreDefaultLayoutCells", &UiLayoutBus::Events::GetIgnoreDefaultLayoutCells)
  498. ->Event("SetIgnoreDefaultLayoutCells", &UiLayoutBus::Events::SetIgnoreDefaultLayoutCells);
  499. }
  500. }
  501. ////////////////////////////////////////////////////////////////////////////////////////////////
  502. // Helper function to VersionConverter to move three state actions from the derived interactable
  503. // to the interactable base class
  504. bool MoveToInteractableStateActions(
  505. AZ::SerializeContext& context,
  506. AZ::SerializeContext::DataElementNode& srcClassElement,
  507. const char* stateActionsElementName,
  508. const char* colorElementName,
  509. const char* alphaElementName,
  510. const char* spriteElementName)
  511. {
  512. // Note, we can assume that srcClassElement will stay in the same place in memory during this function
  513. // But the base class (and everything in it) will move around in memory as we remove elements from
  514. // srcClassElement. So it is improtant not to hold only any indicies or references to the base class.
  515. int interactableBaseClassIndex = srcClassElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
  516. // Add a new element for the state actions.
  517. int stateActionsIndex = srcClassElement.GetSubElement(interactableBaseClassIndex)
  518. .AddElement<AZStd::vector<UiInteractableStateAction*> >(context, stateActionsElementName);
  519. if (stateActionsIndex == -1)
  520. {
  521. // Error adding the new sub element
  522. AZ_Error("Serialization", false, "AddElement failed for %s", stateActionsElementName);
  523. return false;
  524. }
  525. {
  526. interactableBaseClassIndex = srcClassElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
  527. AZ::SerializeContext::DataElementNode& dstClassElement = srcClassElement.GetSubElement(interactableBaseClassIndex);
  528. stateActionsIndex = dstClassElement.FindElement(AZ_CRC(stateActionsElementName));
  529. AZ::SerializeContext::DataElementNode& stateActionsNode = dstClassElement.GetSubElement(stateActionsIndex);
  530. int colorIndex = stateActionsNode.AddElement<UiInteractableStateColor*>(context, "element");
  531. AZ::SerializeContext::DataElementNode& colorNode = stateActionsNode.GetSubElement(colorIndex);
  532. if (!LyShine::MoveElement(context, srcClassElement, colorNode, colorElementName, "Color"))
  533. {
  534. return false;
  535. }
  536. {
  537. // In the latest version of UiInteractableStateColor the color is an AZ::Color but in the
  538. // version we are converting from (before UiInteractableStateColor existed) colors were stored
  539. // as Vector3. Since the UiInteractableStateColor we just created will be at the latest version
  540. // we need to convert the color to an AZ::Color now.
  541. // Note that indices will have changed since MoveElement was called.
  542. interactableBaseClassIndex = srcClassElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
  543. AZ::SerializeContext::DataElementNode& dstBaseClassElement = srcClassElement.GetSubElement(interactableBaseClassIndex);
  544. stateActionsIndex = dstBaseClassElement.FindElement(AZ_CRC(stateActionsElementName));
  545. AZ::SerializeContext::DataElementNode& dstStateActionsNode = dstBaseClassElement.GetSubElement(stateActionsIndex);
  546. colorIndex = dstStateActionsNode.FindElement(AZ_CRC("element"));
  547. AZ::SerializeContext::DataElementNode& dstColorNode = dstStateActionsNode.GetSubElement(colorIndex);
  548. if (!LyShine::ConvertSubElementFromVector3ToAzColor(context, dstColorNode, "Color"))
  549. {
  550. return false;
  551. }
  552. }
  553. }
  554. {
  555. interactableBaseClassIndex = srcClassElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
  556. AZ::SerializeContext::DataElementNode& dstClassElement = srcClassElement.GetSubElement(interactableBaseClassIndex);
  557. stateActionsIndex = dstClassElement.FindElement(AZ_CRC(stateActionsElementName));
  558. AZ::SerializeContext::DataElementNode& stateActionsNode = dstClassElement.GetSubElement(stateActionsIndex);
  559. int alphaIndex = stateActionsNode.AddElement<UiInteractableStateAlpha*>(context, "element");
  560. AZ::SerializeContext::DataElementNode& alphaNode = stateActionsNode.GetSubElement(alphaIndex);
  561. if (!LyShine::MoveElement(context, srcClassElement, alphaNode, alphaElementName, "Alpha"))
  562. {
  563. return false;
  564. }
  565. }
  566. {
  567. interactableBaseClassIndex = srcClassElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
  568. AZ::SerializeContext::DataElementNode& dstClassElement = srcClassElement.GetSubElement(interactableBaseClassIndex);
  569. stateActionsIndex = dstClassElement.FindElement(AZ_CRC(stateActionsElementName));
  570. AZ::SerializeContext::DataElementNode& stateActionsNode = dstClassElement.GetSubElement(stateActionsIndex);
  571. int spriteIndex = stateActionsNode.AddElement<UiInteractableStateSprite*>(context, "element");
  572. AZ::SerializeContext::DataElementNode& spriteNode = stateActionsNode.GetSubElement(spriteIndex);
  573. if (!LyShine::MoveElement(context, srcClassElement, spriteNode, spriteElementName, "Sprite"))
  574. {
  575. return false;
  576. }
  577. }
  578. // if the field did not exist then we do not report an error
  579. return true;
  580. }
  581. }