BVB Source Codes

CRYENGINE Show FlashUIElement.cpp Source code

Return Download CRYENGINE: download FlashUIElement.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   FlashUIElement.cpp
  5. //  Version:     v1.00
  6. //  Created:     10/9/2010 by Paul Reindell.
  7. //  Description:
  8. // -------------------------------------------------------------------------
  9. //  History:
  10. //
  11. ////////////////////////////////////////////////////////////////////////////
  12. #include "StdAfx.h"
  13. #include "FlashUIElement.h"
  14. #include <CryString/UnicodeFunctions.h>
  15. #include <CryInput/IHardwareMouse.h>
  16. #include <CrySystem/Scaleform/IFlashUI.h>
  17. #include <CrySystem/Scaleform/IScaleformHelper.h>
  18. #include <CrySystem/File/ICryPak.h>
  19. #include "FlashUI.h"
  20.  
  21. #define FLASH_PLATFORM_PC      0
  22. #define FLASH_PLATFORM_DURANGO 1
  23. #define FLASH_PLATFORM_ORBIS   2
  24. #define FLASH_PLATFORM_ANDROID 1
  25.  
  26. #if !defined (_RELEASE)
  27. CFlashUIElement::TElementInstanceList CFlashUIElement::s_ElementDebugList;
  28. #endif
  29.  
  30. //------------------------------------------------------------------------------------
  31. struct SUIElementSerializer
  32. {
  33.         static bool Serialize(CFlashUIElement* pElement, XmlNodeRef& xmlNode, bool bIsLoading)
  34.         {
  35.                 CRY_ASSERT_MESSAGE(pElement, "NULL pointer passed!");
  36.                 CRY_ASSERT_MESSAGE(xmlNode != 0, "XmlNode is invalid");
  37.  
  38.                 if (!pElement || !xmlNode) return false;
  39.  
  40.                 if (bIsLoading)
  41.                 {
  42.                         pElement->m_baseInfo = xmlNode;
  43.  
  44.                         DeleteContainer(pElement->m_variables);
  45.                         DeleteContainer(pElement->m_arrays);
  46.                         DeleteContainer(pElement->m_displayObjects);
  47.                         DeleteContainer(pElement->m_displayObjectsTmpl);
  48.                         DeleteContainer(pElement->m_events);
  49.                         DeleteContainer(pElement->m_functions);
  50.                         pElement->m_StringBufferSet.clear();
  51.                         pElement->m_sName = xmlNode->getAttr("name");
  52.  
  53.                         SUIMovieClipDesc* pRoot = new SUIMovieClipDesc("_root", "Root", "Root MC");
  54.                         pElement->m_displayObjects.push_back(pRoot);
  55.                         pElement->m_pRoot = pRoot;
  56.  
  57.                         ReadElementFlag(xmlNode, pElement, "mouseevents", IUIElement::eFUI_MOUSEEVENTS);
  58.                         ReadElementFlag(xmlNode, pElement, "keyevents", IUIElement::eFUI_KEYEVENTS);
  59.                         ReadElementFlag(xmlNode, pElement, "cursor", IUIElement::eFUI_HARDWARECURSOR);
  60.                         ReadElementFlag(xmlNode, pElement, "console_mouse", IUIElement::eFUI_CONSOLE_MOUSE);
  61.                         ReadElementFlag(xmlNode, pElement, "console_cursor", IUIElement::eFUI_CONSOLE_CURSOR);
  62.                         ReadElementFlag(xmlNode, pElement, "controller_input", IUIElement::eFUI_CONTROLLER_INPUT);
  63.                         ReadElementFlag(xmlNode, pElement, "events_exclusive", IUIElement::eFUI_EVENTS_EXCLUSIVE);
  64.                         ReadElementFlag(xmlNode, pElement, "render_lockless", IUIElement::eFUI_RENDER_LOCKLESS);
  65.                         ReadElementFlag(xmlNode, pElement, "force_no_unload", IUIElement::eFUI_FORCE_NO_UNLOAD);
  66.                         ReadElementFlag(xmlNode, pElement, "fixed_proj_depth", IUIElement::eFUI_FIXED_PROJ_DEPTH);
  67.                         ReadElementFlag(xmlNode, pElement, "lazy_update", IUIElement::eFUI_LAZY_UPDATE);
  68.                         ReadElementFlag(xmlNode, pElement, "is_Hud", IUIElement::eFUI_IS_HUD);
  69.                         ReadElementFlag(xmlNode, pElement, "shared_rt", IUIElement::eFUI_SHARED_RT);
  70.  
  71.                         ReadGFxNode(xmlNode->findChild("GFx"), pElement);
  72.                         ReadParamNodes<SUIParameterDesc>(xmlNode->findChild("variables"), pElement->m_variables, "varname", true, pElement->m_pRoot);
  73.                         ReadParamNodes<SUIParameterDesc>(xmlNode->findChild("arrays"), pElement->m_arrays, "varname", true, pElement->m_pRoot);
  74.                         ReadParamNodes<SUIMovieClipDesc>(xmlNode->findChild("movieclips"), pElement->m_displayObjects, "instancename", true, pElement->m_pRoot);
  75.                         ReadParamNodes<SUIMovieClipDesc>(xmlNode->findChild("templates"), pElement->m_displayObjectsTmpl, "template", false);
  76.                         ReadEventNodes(xmlNode->findChild("events"), pElement->m_events, "fscommand");
  77.                         ReadEventNodes(xmlNode->findChild("functions"), pElement->m_functions, "funcname", pElement->m_pRoot);
  78.  
  79.                         pElement->m_firstDynamicDisplObjIndex = pElement->m_displayObjects.size();
  80.                 }
  81.                 else
  82.                 {
  83.                         // save - not needed atm
  84.                         // maybe we need it to serialize dynamic created stuff?
  85.                         assert(false);
  86.                 }
  87.                 return true;
  88.         }
  89.  
  90.         static void ReadElementFlag(const XmlNodeRef& node, CFlashUIElement* pElement, const char* sFlag, IUIElement::EFlashUIFlags eFlag)
  91.         {
  92.                 bool xmlflag = false;
  93.                 node->getAttr(sFlag, xmlflag);
  94.                 pElement->SetFlagInt(eFlag, xmlflag);
  95.         }
  96.  
  97.         static void ReadGFxNode(const XmlNodeRef& node, CFlashUIElement* pElement)
  98.         {
  99.                 if (node)
  100.                 {
  101.                         node->getAttr("alpha", pElement->m_fAlpha);
  102.                         node->getAttr("layer", pElement->m_iLayer);
  103.                         pElement->m_sFlashFile = node->getAttr("file");
  104.  
  105.                         const XmlNodeRef& constraintsnode = node->findChild("Constraints");
  106.                         if (constraintsnode)
  107.                         {
  108.                                 const XmlNodeRef& alignnode = constraintsnode->findChild("Align");
  109.                                 if (alignnode)
  110.                                 {
  111.                                         pElement->m_constraints.eType = GetPositionType(alignnode->getAttr("mode"));
  112.                                         pElement->m_constraints.eHAlign = GetAlignType(alignnode->getAttr("halign"));
  113.                                         pElement->m_constraints.eVAlign = GetAlignType(alignnode->getAttr("valign"));
  114.                                         pElement->m_constraints.bScale = false;
  115.                                         alignnode->getAttr("scale", pElement->m_constraints.bScale);
  116.                                         pElement->m_constraints.bMax = false;
  117.                                         alignnode->getAttr("max", pElement->m_constraints.bMax);
  118.                                 }
  119.  
  120.                                 const XmlNodeRef& posnode = constraintsnode->findChild("Position");
  121.                                 if (posnode)
  122.                                 {
  123.                                         posnode->getAttr("top", pElement->m_constraints.iTop);
  124.                                         posnode->getAttr("left", pElement->m_constraints.iLeft);
  125.                                         posnode->getAttr("width", pElement->m_constraints.iWidth);
  126.                                         posnode->getAttr("height", pElement->m_constraints.iHeight);
  127.                                 }
  128.                         }
  129.                 }
  130.         }
  131.  
  132.         static IUIElement::SUIConstraints::EPositionType GetPositionType(const char* mode)
  133.         {
  134.                 if (mode != NULL)
  135.                 {
  136.                         if (!strcmpi("fixed", mode))
  137.                                 return IUIElement::SUIConstraints::ePT_Fixed;
  138.                         else if (!strcmpi("dynamic", mode))
  139.                                 return IUIElement::SUIConstraints::ePT_Dynamic;
  140.                         else if (!strcmpi("fullscreen", mode))
  141.                                 return IUIElement::SUIConstraints::ePT_Fullscreen;
  142.                         else if (!strcmpi("fixdyntexsize", mode))
  143.                                 return IUIElement::SUIConstraints::ePT_FixedDynTexSize;
  144.                 }
  145.                 return IUIElement::SUIConstraints::ePT_Dynamic;
  146.         }
  147.  
  148.         static IUIElement::SUIConstraints::EPositionAlign GetAlignType(const char* type)
  149.         {
  150.                 if (type != NULL)
  151.                 {
  152.                         if (!strcmpi("left", type) || !strcmpi("top", type))
  153.                                 return IUIElement::SUIConstraints::ePA_Lower;
  154.                         else if (!strcmpi("mid", type))
  155.                                 return IUIElement::SUIConstraints::ePA_Mid;
  156.                         else if (!strcmpi("right", type) || !strcmpi("bottom", type))
  157.                                 return IUIElement::SUIConstraints::ePA_Upper;
  158.                 }
  159.                 return IUIElement::SUIConstraints::ePA_Mid;
  160.         }
  161.  
  162.         static SUIParameterDesc::EUIParameterType GetParamType(const char* type)
  163.         {
  164.                 if (type != NULL)
  165.                 {
  166.                         if (!strcmpi("bool", type))
  167.                                 return SUIParameterDesc::eUIPT_Bool;
  168.                         else if (!strcmpi("int", type))
  169.                                 return SUIParameterDesc::eUIPT_Int;
  170.                         else if (!strcmpi("float", type))
  171.                                 return SUIParameterDesc::eUIPT_Float;
  172.                         else if (!strcmpi("string", type))
  173.                                 return SUIParameterDesc::eUIPT_String;
  174.                 }
  175.                 return SUIParameterDesc::eUIPT_Any;
  176.         }
  177.  
  178.         template<class T>
  179.         static void DeleteContainer(T& container)
  180.         {
  181.                 for (typename T::iterator it = container.begin(); it != container.end(); ++it)
  182.                         delete *it;
  183.                 container.clear();
  184.         }
  185.  
  186.         static void DeleteContainer(TUIMovieClipLookup& container)
  187.         {
  188.                 for (TUIMovieClipLookup::iterator it = container.begin(); it != container.end(); ++it)
  189.                 {
  190.                         DeleteContainer((*it)->m_variables);
  191.                         DeleteContainer((*it)->m_arrays);
  192.                         DeleteContainer((*it)->m_displayObjects);
  193.                         DeleteContainer((*it)->m_functions);
  194.                         delete *it;
  195.                 }
  196.                 container.clear();
  197.         }
  198.  
  199.         template<class D>
  200.         static void ReadSubnodes(const XmlNodeRef& node, D* item, bool bSetParent)
  201.         {
  202.         }
  203.  
  204.         template<class D, class T>
  205.         static D* AddToList(T& list, const char* name, const char* displname, const char* desc, SUIParameterDesc::EUIParameterType eType, const SUIParameterDesc* pParent)
  206.         {
  207.                 D* newItem = new D(name, displname, desc, eType, pParent);
  208.                 list.push_back(newItem);
  209.                 return newItem;
  210.         }
  211.  
  212.         template<class D, class T>
  213.         static void ReadParamNodes(const XmlNodeRef& node, T& list, const char* sParamName, bool bSetParent = true, const SUIParameterDesc* pParent = NULL, const char* nodename = NULL)
  214.         {
  215.                 if (node)
  216.                 {
  217.                         for (int i = 0; i < node->getChildCount(); ++i)
  218.                         {
  219.                                 const XmlNodeRef& paramNode = node->getChild(i);
  220.  
  221.                                 if (nodename && strcmpi(paramNode->getTag(), nodename) != 0) continue;
  222.  
  223.                                 const char* displName = paramNode->getAttr("name");
  224.                                 const char* varName = paramNode->getAttr(sParamName);
  225.                                 varName = strcmp(varName, "") ? varName : displName;
  226.                                 const char* root = strstr(varName, "_root.");
  227.                                 if (root) varName = root + 6;
  228.                                 const char* desc = paramNode->getAttr("desc");
  229.                                 const char* type = paramNode->getAttr("type");
  230.                                 SUIParameterDesc::EUIParameterType eType = GetParamType(type);
  231.  
  232.                                 if (IsUnique(list, displName, varName))
  233.                                 {
  234.                                         ReadSubnodes(paramNode, AddToList<D>(list, varName, displName, desc, eType, pParent), bSetParent);
  235.                                 }
  236.                                 else
  237.                                         gEnv->pLog->LogError("%s (%s) is not unique!", varName, displName);
  238.                         }
  239.                 }
  240.         }
  241.  
  242.         template<class T>
  243.         static void ReadEventNodes(const XmlNodeRef& node, T& list, const char* sEventName, const SUIParameterDesc* pParent = NULL, const char* nodename = NULL)
  244.         {
  245.                 if (node)
  246.                 {
  247.                         for (int i = 0; i < node->getChildCount(); ++i)
  248.                         {
  249.                                 const XmlNodeRef& eventNode = node->getChild(i);
  250.                                 if (nodename && strcmpi(eventNode->getTag(), nodename) != 0) continue;
  251.  
  252.                                 const char* displName = eventNode->getAttr("name");
  253.                                 const char* eventName = eventNode->getAttr(sEventName);
  254.                                 eventName = strcmp(eventName, "") ? eventName : displName;
  255.                                 const char* root = strstr(eventName, "_root.");
  256.                                 if (root) eventName = root + 6;
  257.                                 const char* desc = eventNode->getAttr("desc");
  258.                                 bool IsDyn = false;
  259.                                 eventNode->getAttr("dynamic", IsDyn);
  260.                                 const char* dynName = eventNode->getAttr("dynName");
  261.                                 const char* dynDesc = eventNode->getAttr("dynDesc");
  262.                                 dynName = strcmp(dynName, "") ? dynName : "Array";
  263.  
  264.                                 if (IsUnique(list, displName, eventName))
  265.                                 {
  266.                                         SUIEventDesc* pNewEvent = new SUIEventDesc(eventName, displName, desc, SUIEventDesc::SEvtParamsDesc(IsDyn, dynName, dynDesc), SUIEventDesc::SEvtParamsDesc(), pParent);
  267.                                         list.push_back(pNewEvent);
  268.                                         ReadParamNodes<SUIParameterDesc>(eventNode, pNewEvent->InputParams.Params, "name", true, pParent);
  269.                                 }
  270.                                 else
  271.                                         gEnv->pLog->LogError("%s (%s) is not unique!", displName, eventName);
  272.                         }
  273.                 }
  274.         }
  275.  
  276.         template<class T>
  277.         static bool IsUnique(const T& list, const char* displayName, const char* flashName)
  278.         {
  279.                 for (typename T::const_iterator it = list.begin(); it != list.end(); ++it)
  280.                 {
  281.                         if (strcmpi((*it)->sDisplayName, displayName) == 0 || strcmpi((*it)->sName, flashName) == 0)
  282.                                 return false;
  283.                 }
  284.                 return true;
  285.         }
  286.  
  287.         template<class T>
  288.         static size_t GetMemUsage(const T& container)
  289.         {
  290.                 return container.get_alloc_size();
  291.         }
  292.  
  293.         static size_t GetMemUsage(TUIMovieClipLookup& container)
  294.         {
  295.                 size_t res = container.get_alloc_size();
  296.                 for (TUIMovieClipLookup::iterator it = container.begin(); it != container.end(); ++it)
  297.                 {
  298.                         res += GetMemUsage((*it)->m_variables);
  299.                         res += GetMemUsage((*it)->m_arrays);
  300.                         res += GetMemUsage((*it)->m_displayObjects);
  301.                         res += GetMemUsage((*it)->m_functions);
  302.                 }
  303.                 return res;
  304.         }
  305. };
  306.  
  307. template<>
  308. SUIParameterDesc* SUIElementSerializer::AddToList<SUIParameterDesc, TUIParams>(TUIParams& list, const char* name, const char* displname, const char* desc, SUIParameterDesc::EUIParameterType eType, const SUIParameterDesc* pParent)
  309. {
  310.         list.push_back(SUIParameterDesc(name, displname, desc, eType, pParent));
  311.         return &(*list.rbegin());
  312. }
  313.  
  314. template<>
  315. bool SUIElementSerializer::IsUnique<TUIParams>(const TUIParams& list, const char* displayName, const char* flashName)
  316. {
  317.         for (TUIParams::const_iterator it = list.begin(); it != list.end(); ++it)
  318.         {
  319.                 if (strcmpi(it->sDisplayName, displayName) == 0 || strcmpi(it->sName, flashName) == 0)
  320.                         return false;
  321.         }
  322.         return true;
  323. }
  324.  
  325. template<>
  326. void SUIElementSerializer::ReadSubnodes<SUIMovieClipDesc>(const XmlNodeRef& node, SUIMovieClipDesc* item, bool bSetParent)
  327. {
  328.         ReadParamNodes<SUIParameterDesc>(node, item->m_variables, "varname", true, bSetParent ? item : NULL, "Variable");
  329.         ReadParamNodes<SUIParameterDesc>(node, item->m_arrays, "varname", true, bSetParent ? item : NULL, "Array");
  330.         ReadParamNodes<SUIMovieClipDesc>(node, item->m_displayObjects, "instancename", true, bSetParent ? item : NULL, "MovieClip");
  331.         ReadEventNodes(node, item->m_functions, "funcname", bSetParent ? true, item : NULL, "Function");
  332. }
  333.  
  334. //------------------------------------------------------------------------------------
  335. CFlashUIElement::CFlashUIElement(CFlashUI* pFlashUI, CFlashUIElement* pBaseInstance, uint instanceId)
  336.         : m_refCount(1)
  337.         , m_pFlashUI(pFlashUI)
  338.         , m_bVisible(false)
  339.         , m_pFlashplayer(NULL)
  340.         , m_bCursorVisible(false)
  341.         , m_iFlags(0)
  342.         , m_fAlpha(0)
  343.         , m_iLayer(0)
  344.         , m_bIsValid(false)
  345.         , m_pBaseInstance(pBaseInstance)
  346.         , m_iInstanceID(instanceId)
  347.         , m_pBootStrapper(NULL)
  348.         , m_eventListener(4)
  349.         , m_bNeedLazyUpdate(false)
  350.         , m_bNeedLazyRender(false)
  351.         , m_firstDynamicDisplObjIndex(0)
  352.         , m_bIsHideRequest(false)
  353.         , m_bUnloadRequest(false)
  354.         , m_bUnloadAll(false)
  355. {
  356.         if (pBaseInstance == NULL)
  357.                 m_instances.push_back(this);
  358.  
  359. #if !defined (_RELEASE)
  360.         s_ElementDebugList.push_back(this);
  361. #endif
  362. }
  363.  
  364. //------------------------------------------------------------------------------------
  365. CFlashUIElement::~CFlashUIElement()
  366. {
  367.         if (m_pBaseInstance == NULL)
  368.                 DestroyBootStrapper();
  369.         else
  370.                 Unload();
  371.  
  372.         TUIElements instances = m_instances;
  373.         m_instances.clear();
  374.         for (TUIElements::iterator it = instances.begin(); it != instances.end(); ++it)
  375.         {
  376.                 if (*it != this)
  377.                 {
  378.                         SAFE_RELEASE(*it);
  379.                 }
  380.         }
  381.  
  382.         CRY_ASSERT_MESSAGE(m_variableObjects.empty(), "Variable objects not cleared!");
  383.         CRY_ASSERT_MESSAGE(m_pFlashplayer == NULL, "Flash player not correct unloaded!");
  384.         CRY_ASSERT_MESSAGE(m_pBootStrapper == NULL, "Flash bootstrapper not correct unloaded!");
  385.  
  386. #if !defined (_RELEASE)
  387.         bool ok = stl::find_and_erase(s_ElementDebugList, this);
  388.         CRY_ASSERT_MESSAGE(ok, "UIElement was not registered to debug list!!");
  389. #endif
  390.  
  391.         SUIElementSerializer::DeleteContainer(m_variables);
  392.         SUIElementSerializer::DeleteContainer(m_arrays);
  393.         SUIElementSerializer::DeleteContainer(m_displayObjects);
  394.         SUIElementSerializer::DeleteContainer(m_displayObjectsTmpl);
  395.         SUIElementSerializer::DeleteContainer(m_events);
  396.         SUIElementSerializer::DeleteContainer(m_functions);
  397. }
  398.  
  399. void CFlashUIElement::AddRef()
  400. {
  401.         CryInterlockedIncrement(&m_refCount);
  402. }
  403.  
  404. void CFlashUIElement::Release()
  405. {
  406.         long refCnt = CryInterlockedDecrement(&m_refCount);
  407.         if (refCnt <= 0)
  408.                 delete this;
  409. }
  410.  
  411. //------------------------------------------------------------------------------------
  412. IUIElement* CFlashUIElement::GetInstance(uint instanceID)
  413. {
  414.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  415.  
  416.         if (m_pBaseInstance)
  417.                 return m_pBaseInstance->GetInstance(instanceID);
  418.  
  419.         for (TUIElements::iterator it = m_instances.begin(); it != m_instances.end(); ++it)
  420.         {
  421.                 if ((*it)->GetInstanceID() == instanceID)
  422.                         return *it;
  423.         }
  424.  
  425.         CFlashUIElement* pNewElement = new CFlashUIElement(m_pFlashUI, this, instanceID);
  426.  
  427.         if (!SUIElementSerializer::Serialize(pNewElement, m_baseInfo, true))
  428.         {
  429.                 SAFE_RELEASE(pNewElement);
  430.                 return NULL;
  431.         }
  432.  
  433.         m_instances.push_back(pNewElement);
  434.  
  435.         TUIEventListenerUnique listeners;
  436.         GetAllListeners(listeners);
  437.         for (TUIEventListenerUnique::iterator listener = listeners.begin(); listener != listeners.end(); ++listener)
  438.                 (*listener)->OnInstanceCreated(this, pNewElement);
  439.  
  440.         UIACTION_LOG("%s (%i): Created UIElement instance", GetName(), instanceID);
  441.  
  442.         return pNewElement;
  443. }
  444.  
  445. //------------------------------------------------------------------------------------
  446. bool CFlashUIElement::DestroyInstance(uint instanceID)
  447. {
  448.         if (m_pBaseInstance)
  449.                 return m_pBaseInstance->DestroyInstance(instanceID);
  450.  
  451.         if (instanceID > 0)
  452.         {
  453.                 TUIEventListenerUnique listeners;
  454.                 TUIElements::iterator instanceToDelete = GetAllListeners(listeners, instanceID);
  455.  
  456.                 if (instanceToDelete != m_instances.end())
  457.                 {
  458.                         for (TUIEventListenerUnique::iterator listener = listeners.begin(); listener != listeners.end(); ++listener)
  459.                                 (*listener)->OnInstanceDestroyed(this, *instanceToDelete);
  460.  
  461.                         SAFE_RELEASE(*instanceToDelete);
  462.                         m_instances.erase(instanceToDelete);
  463.  
  464.                         UIACTION_LOG("%s (%i): UIElement instance destroyed", GetName(), instanceID);
  465.                         return true;
  466.                 }
  467.  
  468.                 UIACTION_WARNING("%s (%i): UIElement can't destroy instance, instance not found", GetName(), instanceID);
  469.                 return false;
  470.         }
  471.  
  472.         UIACTION_WARNING("%s (%i): UIElement can't destroy base instance", GetName(), instanceID);
  473.         return false;
  474. }
  475.  
  476. //------------------------------------------------------------------------------------
  477. CFlashUIElement::TUIElements::iterator CFlashUIElement::GetAllListeners(TUIEventListenerUnique& listeners, uint instanceID)
  478. {
  479.         TUIElements::iterator result = m_instances.end();
  480.         for (TUIElements::iterator instance = m_instances.begin(); instance != m_instances.end(); ++instance)
  481.         {
  482.                 CFlashUIElement* pInstance = (CFlashUIElement*)*instance;
  483.                 if (pInstance->m_iInstanceID == instanceID)
  484.                         result = instance;
  485.                 for (TUIEventListener::Notifier notifier(pInstance->m_eventListener); notifier.IsValid(); notifier.Next())
  486.                         listeners.insert(*notifier);
  487.         }
  488.         return result;
  489. }
  490.  
  491. //------------------------------------------------------------------------------------
  492. IUIElementIteratorPtr CFlashUIElement::GetInstances() const
  493. {
  494.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  495.  
  496.         if (m_pBaseInstance)
  497.                 return m_pBaseInstance->GetInstances();
  498.  
  499.         CUIElementIterator* pIter = new CUIElementIterator(this);
  500.         IUIElementIteratorPtr iter = pIter;
  501.         iter->Release();
  502.         return iter;
  503. }
  504.  
  505. //------------------------------------------------------------------------------------
  506. bool CFlashUIElement::LazyInit()
  507. {
  508.         if (!m_pFlashplayer)
  509.         {
  510.                 Init();
  511.                 return m_pFlashplayer != NULL;
  512.         }
  513.         return m_pFlashplayer != NULL;
  514. }
  515.  
  516. //------------------------------------------------------------------------------------
  517. void CFlashUIElement::ShowCursor()
  518. {
  519.         if (!m_bCursorVisible)
  520.         {
  521.                 m_bCursorVisible = true;
  522.                 gEnv->pHardwareMouse->IncrementCounter();
  523.         }
  524. }
  525.  
  526. //------------------------------------------------------------------------------------
  527. void CFlashUIElement::HideCursor()
  528. {
  529.         if (m_bCursorVisible)
  530.         {
  531.                 m_bCursorVisible = false;
  532.                 gEnv->pHardwareMouse->DecrementCounter();
  533.         }
  534. }
  535.  
  536. //------------------------------------------------------------------------------------
  537. const char* CFlashUIElement::GetStringBuffer(const char* str)
  538. {
  539.         if (m_pBaseInstance)
  540.                 return m_pBaseInstance->GetStringBuffer(str);
  541.         return m_StringBufferSet.insert(string(str)).first->c_str();
  542. }
  543.  
  544. //------------------------------------------------------------------------------------
  545. void CFlashUIElement::SetFlashFile(const char* sFlashFile)
  546. {
  547.         if (m_sFlashFile != sFlashFile)
  548.         {
  549.                 m_sFlashFile = sFlashFile;
  550.                 UIACTION_LOG("%s (%i): UIElement set new flash file", GetName(), m_iInstanceID);
  551.                 ReloadBootStrapper();
  552.         }
  553. }
  554.  
  555. //------------------------------------------------------------------------------------
  556. bool CFlashUIElement::Init(bool bLoadAsset)
  557. {
  558.         if (!IsValid())
  559.         {
  560.                 UIACTION_WARNING("%s: Element is marked as not valid! Instance was not created!", GetName());
  561.                 return false;
  562.         }
  563.  
  564.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  565.  
  566.         IFlashPlayerBootStrapper* pBootStrapper = InitBootStrapper();
  567.  
  568.         if (!bLoadAsset || !pBootStrapper)
  569.                 return pBootStrapper != NULL;
  570.  
  571.         // UIElements that needs to be advanced & rendered manually must
  572.         // have CE_NoAutoUpdate in the metadata section of their flash assets. (e.g. 3DHUD)
  573.         bool bNoAutoUpdate = pBootStrapper->HasMetadata("CE_NoAutoUpdate");
  574.         SetFlagInt(IUIElement::eFUI_NO_AUTO_UPDATE, bNoAutoUpdate);
  575.  
  576.         if (!CFlashUI::CV_gfx_uiaction_enable)
  577.                 return false;
  578.  
  579.         if (!m_pFlashplayer)
  580.         {
  581.                 m_pFlashplayer = pBootStrapper->CreatePlayerInstance();
  582.                 m_pFlashplayer->SetViewport(-1, -1, 1, 1);
  583.                 UpdateFlags();
  584.         }
  585.         else
  586.         {
  587.                 return true;
  588.         }
  589.  
  590.         if (!m_pFlashplayer)
  591.         {
  592.                 UIACTION_ERROR("%s (%i): Failed to created flash instance: \"%s\"", GetName(), m_iInstanceID, m_sFlashFile.c_str());
  593.                 return false;
  594.         }
  595.  
  596.         UIACTION_LOG("%s (%i): Created flash instance: \"%s\"", GetName(), m_iInstanceID, m_sFlashFile.c_str());
  597.  
  598.         m_pFlashplayer->SetBackgroundAlpha(m_fAlpha);
  599.         m_pFlashplayer->SetFSCommandHandler(this);
  600.         IFlashVariableObject* pRoot = NULL;
  601.         m_pFlashplayer->GetVariable(m_pRoot->sName, pRoot);
  602.         assert(pRoot);
  603.         m_variableObjects[CCryName(m_pRoot->sName)].pObj = pRoot;
  604.         m_variableObjects[CCryName(m_pRoot->sName)].pParent = NULL;
  605.         m_variableObjectsLookup[(const SUIParameterDesc*)NULL][m_pRoot] = &m_variableObjects[CCryName(m_pRoot->sName)];
  606.         if (!HasExtTexture())
  607.         {
  608.                 UpdateViewPort();
  609.         }
  610.  
  611.         UIACTION_LOG("%s (%i): UIElement invoke \"cry_onSetup\"", GetName(), m_iInstanceID);
  612.         if (m_pFlashplayer->IsAvailable("cry_onSetup"))
  613.         {
  614.                 if (gEnv->IsEditor())
  615.                 {
  616.                         switch (m_pFlashUI->GetCurrentPlatform())
  617.                         {
  618.                         case IFlashUI::ePUI_Durango:
  619.                                 m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_DURANGO);
  620.                                 break;
  621.                         case IFlashUI::ePUI_Orbis:
  622.                                 m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_ORBIS);
  623.                                 break;
  624.                         case IFlashUI::ePUI_Android:
  625.                                 m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_ANDROID);
  626.                                 break;
  627.                         default:
  628.                                 m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_PC);
  629.                         }
  630.                 }
  631.                 else
  632.                 {
  633. #if CRY_PLATFORM_DURANGO
  634.                         m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_DURANGO);
  635. #elif CRY_PLATFORM_ORBIS
  636.                         m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_ORBIS);
  637. #elif CRY_PLATFORM_ANDROID
  638.                         m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_ANDROID);
  639. #else
  640.                         m_pFlashplayer->Invoke1("cry_onSetup", FLASH_PLATFORM_PC);
  641. #endif
  642.                 }
  643.         }
  644.  
  645.         for (TUIEventListener::Notifier notifier(m_eventListener); notifier.IsValid(); notifier.Next())
  646.                 notifier->OnInit(this, m_pFlashplayer);
  647.  
  648.         if (HasExtTexture())
  649.         {
  650.                 m_pFlashplayer->SetViewScaleMode(IFlashPlayer::eSM_ExactFit);
  651.                 m_pFlashplayer->SetViewport(0, 0, m_pFlashplayer->GetWidth(), m_pFlashplayer->GetHeight(), 1.f);
  652.                 m_pFlashplayer->SetScissorRect(0, 0, m_pFlashplayer->GetWidth(), m_pFlashplayer->GetHeight());
  653.                 SetVisible(true);
  654.         }
  655.  
  656.         return true;
  657. }
  658.  
  659. void CFlashUIElement::Unload(bool bAllInstances)
  660. {
  661.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  662.  
  663.         if (!CFlashUI::CV_gfx_uiaction_enable)
  664.                 return;
  665.  
  666.         if (bAllInstances)
  667.         {
  668.                 if (m_pBaseInstance)
  669.                 {
  670.                         m_pBaseInstance->Unload(true);
  671.                 }
  672.                 else
  673.                 {
  674.                         TUIElements instances = m_instances;
  675.                         for (TUIElements::iterator iter = instances.begin(); iter != instances.end(); ++iter)
  676.                         {
  677.                                 uint instanceId = (*iter)->GetInstanceID();
  678.                                 if (instanceId == 0)
  679.                                         (*iter)->Unload();
  680.                                 else
  681.                                         DestroyInstance(instanceId);
  682.                         }
  683.                 }
  684.                 return;
  685.         }
  686.  
  687.         if (m_pFlashplayer)
  688.         {
  689.                 SetVisible(false);
  690.                 FreeVarObjects();
  691.                 // reset all pParent pointers on dynamically created MCs
  692.                 for (int i = m_firstDynamicDisplObjIndex; i < m_displayObjects.size(); ++i)
  693.                         m_displayObjects[i]->pParent = NULL;
  694.  
  695.                 UIACTION_LOG("%s (%i): Unload flash instance", GetName(), m_iInstanceID);
  696.  
  697.                 for (TUIEventListener::Notifier notifier(m_eventListener); notifier.IsValid(); notifier.Next())
  698.                         notifier->OnUnload(this);
  699.  
  700.                 SAFE_RELEASE(m_pFlashplayer);
  701.         }
  702. }
  703.  
  704. void CFlashUIElement::RequestUnload(bool bAllInstances)
  705. {
  706.         m_bUnloadRequest = true;
  707.         m_bUnloadAll = bAllInstances;
  708. }
  709.  
  710. void CFlashUIElement::Reload(bool bAllInstances)
  711. {
  712.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  713.  
  714.         if (!CFlashUI::CV_gfx_uiaction_enable)
  715.                 return;
  716.  
  717.         if (bAllInstances)
  718.         {
  719.                 if (m_pBaseInstance)
  720.                 {
  721.                         m_pBaseInstance->Reload(true);
  722.                 }
  723.                 else
  724.                 {
  725.                         for (TUIElements::iterator iter = m_instances.begin(); iter != m_instances.end(); ++iter)
  726.                                 (*iter)->Reload(false);
  727.                 }
  728.                 return;
  729.         }
  730.  
  731.         const bool bVisible = IsVisible();
  732.         Unload();
  733.         Init();
  734.         SetVisible(bVisible);
  735. }
  736.  
  737. void CFlashUIElement::UnloadBootStrapper()
  738. {
  739.         DestroyBootStrapper();
  740. }
  741.  
  742. void CFlashUIElement::ReloadBootStrapper()
  743. {
  744.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  745.  
  746.         if (!CFlashUI::CV_gfx_uiaction_enable)
  747.                 return;
  748.  
  749.         if (m_pBaseInstance)
  750.         {
  751.                 m_pBaseInstance->ReloadBootStrapper();
  752.                 return;
  753.         }
  754.  
  755.         std::map<IUIElement*, std::pair<bool, bool>> visMap;
  756.         for (TUIElements::iterator iter = m_instances.begin(); iter != m_instances.end(); ++iter)
  757.         {
  758.                 visMap[*iter].first = (*iter)->IsInit();
  759.                 visMap[*iter].second = (*iter)->IsVisible();
  760.                 (*iter)->UnloadBootStrapper();
  761.         }
  762.  
  763.         for (TUIElements::iterator iter = m_instances.begin(); iter != m_instances.end(); ++iter)
  764.         {
  765.                 (*iter)->Init(visMap[*iter].first);
  766.                 (*iter)->SetVisible(visMap[*iter].second);
  767.         }
  768. }
  769.  
  770. IFlashPlayerBootStrapper* CFlashUIElement::InitBootStrapper()
  771. {
  772.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  773.  
  774.         if (!CFlashUI::CV_gfx_uiaction_enable)
  775.                 return NULL;
  776.  
  777.         if (!m_pBaseInstance)
  778.         {
  779.                 if (!m_pBootStrapper)
  780.                 {
  781.                         m_pBootStrapper = gEnv->pScaleformHelper ? gEnv->pScaleformHelper->CreateFlashPlayerBootStrapper() : nullptr;
  782.                         if (m_pBootStrapper)
  783.                         {
  784.                                 string filename;
  785.                                 filename.Format("%s%s", CFlashUI::CV_gfx_uiaction_folder->GetString(), m_sFlashFile.c_str());
  786.                                 if (!gEnv->pCryPak->IsFileExist(filename.c_str()))
  787.                                         filename = m_sFlashFile;
  788.  
  789.                                 if (!m_pBootStrapper->Load(filename.c_str()))
  790.                                 {
  791.                                         UIACTION_ERROR("%s: Can't find flash file: \"%s\"", GetName(), m_sFlashFile.c_str());
  792.                                         SAFE_RELEASE(m_pBootStrapper);
  793.                                 }
  794.                                 else
  795.                                 {
  796.                                         UIACTION_LOG("%s: Created BootStrapper for flash file: \"%s\"", GetName(), filename.c_str());
  797.                                 }
  798.                         }
  799.                 }
  800.                 return m_pBootStrapper;
  801.         }
  802.         return m_pBaseInstance->InitBootStrapper();
  803. }
  804.  
  805. void CFlashUIElement::DestroyBootStrapper()
  806. {
  807.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  808.  
  809.         if (!CFlashUI::CV_gfx_uiaction_enable)
  810.                 return;
  811.  
  812.         if (m_pBaseInstance)
  813.         {
  814.                 m_pBaseInstance->DestroyBootStrapper();
  815.                 return;
  816.         }
  817.  
  818.         // deactivate dyn textures as they have to release all IFlashPlayer instances to be able to delete the bootstrapper
  819.         TDynTextures::TVec texVex = m_textures.GetCopy();
  820.         for (TDynTextures::TVec::iterator it = texVex.begin(); it != texVex.end(); ++it)
  821.                 (*it)->Activate(false);
  822.  
  823.         Unload(true);
  824.  
  825.         // reactivate dyn textures!
  826.         for (TDynTextures::TVec::iterator it = texVex.begin(); it != texVex.end(); ++it)
  827.                 (*it)->Activate(true);
  828.  
  829.         CRY_ASSERT_MESSAGE(!HasExtTexture(), "Can't destory Bootstrapper while still used by dynamic textures");
  830.         SAFE_RELEASE(m_pBootStrapper);
  831.         UIACTION_LOG("%s: BootStrapper destroyed for flash file: \"%s\"", GetName(), m_sFlashFile.c_str());
  832. }
  833. //------------------------------------------------------------------------------------
  834. bool CFlashUIElement::Serialize(XmlNodeRef& xmlNode, bool bIsLoading)
  835. {
  836.         CRY_ASSERT_MESSAGE(bIsLoading, "only loading supported!");
  837.  
  838.         bool res = true;
  839.         for (TUIElements::iterator iter = m_instances.begin(); iter != m_instances.end(); ++iter)
  840.                 res &= SUIElementSerializer::Serialize((CFlashUIElement*)*iter, xmlNode, bIsLoading);
  841.         SetValid(res);
  842.         return res;
  843. }
  844.  
  845. //------------------------------------------------------------------------------------
  846. void CFlashUIElement::Update(float fDeltaTime)
  847. {
  848.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  849.         if (m_pFlashplayer == NULL || ((m_iFlags & (uint64) eFUI_LAZY_UPDATE) != 0 && !m_bNeedLazyUpdate)) return;
  850.  
  851.         m_pFlashplayer->Advance(fDeltaTime);
  852.         m_bNeedLazyUpdate = false;
  853.  
  854.         if (m_bUnloadRequest)
  855.         {
  856.                 Unload(m_bUnloadAll);
  857.                 m_bUnloadRequest = false;
  858.         }
  859.         else
  860.         {
  861.                 m_bNeedLazyRender = true;
  862.         }
  863. }
  864.  
  865. //------------------------------------------------------------------------------------
  866. void CFlashUIElement::Render()
  867. {
  868.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  869.         if (m_pFlashplayer == NULL) return;
  870.  
  871.         if (!HasExtTexture())
  872.         {
  873.                 m_pFlashplayer->Render(gEnv->pRenderer->IsStereoEnabled());
  874.         }
  875. }
  876.  
  877. //------------------------------------------------------------------------------------
  878. void CFlashUIElement::RenderLockless()
  879. {
  880.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  881.         if (m_pFlashplayer == NULL) return;
  882.  
  883.         if (!HasExtTexture())
  884.         {
  885.                 m_pFlashplayer->Render(gEnv->pRenderer->IsStereoEnabled());
  886.         }
  887. }
  888.  
  889. //------------------------------------------------------------------------------------
  890. void CFlashUIElement::RequestHide()
  891. {
  892.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  893.  
  894.         if (!CFlashUI::CV_gfx_uiaction_enable)
  895.                 return;
  896.  
  897.         UIACTION_LOG("%s (%i): Hide requested", GetName(), m_iInstanceID);
  898.  
  899.         if (!LazyInit())
  900.                 return;
  901.  
  902.         if (m_pFlashplayer && m_pFlashplayer->IsAvailable("cry_requestHide"))
  903.         {
  904.                 UIACTION_LOG("%s (%i): UIElement invoke \"cry_requestHide\"", GetName(), m_iInstanceID);
  905.                 m_pFlashplayer->Invoke0("cry_requestHide");
  906.         }
  907.  
  908.         m_bIsHideRequest = true;
  909.         UpdateFlags();
  910. }
  911.  
  912. //------------------------------------------------------------------------------------
  913. void CFlashUIElement::SetVisible(bool bVisible)
  914. {
  915.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  916.  
  917.         if (!CFlashUI::CV_gfx_uiaction_enable)
  918.                 return;
  919.  
  920.         if (m_bVisible == bVisible && !m_bIsHideRequest)
  921.                 return;
  922.  
  923.         if (bVisible && !LazyInit())
  924.                 return;
  925.  
  926.         m_bVisible = bVisible;
  927.         m_bIsHideRequest = false;
  928.  
  929.         UIACTION_LOG("%s (%i): Set visible: %s", GetName(), m_iInstanceID, bVisible ? "true" : "false");
  930.  
  931.         if (m_pFlashplayer)
  932.         {
  933.                 if (m_bVisible && m_pFlashplayer->IsAvailable("cry_onShow"))
  934.                 {
  935.                         UIACTION_LOG("%s (%i): UIElement invoke \"cry_onShow\"", GetName(), m_iInstanceID);
  936.                         m_pFlashplayer->Invoke0("cry_onShow");
  937.                 }
  938.                 else if (m_pFlashplayer->IsAvailable("cry_onHide"))
  939.                 {
  940.                         UIACTION_LOG("%s (%i): UIElement invoke \"cry_onHide\"", GetName(), m_iInstanceID);
  941.                         m_pFlashplayer->Invoke0("cry_onHide");
  942.                 }
  943.                 m_pFlashplayer->Advance(0);
  944.         }
  945.  
  946.         for (TUIEventListener::Notifier notifier(m_eventListener); notifier.IsValid(); notifier.Next())
  947.                 notifier->OnSetVisible(this, m_bVisible);
  948.  
  949.         m_pFlashUI->InvalidateSortedElements();
  950.  
  951.         UpdateFlags();
  952.         if (m_bVisible)
  953.                 UpdateViewPort();
  954. }
  955.  
  956. //------------------------------------------------------------------------------------
  957. IFlashPlayer* CFlashUIElement::GetFlashPlayer()
  958. {
  959.         LazyInit();
  960.         return m_pFlashplayer;
  961. }
  962.  
  963. //------------------------------------------------------------------------------------
  964. void CFlashUIElement::SetLayer(int iLayer)
  965. {
  966.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  967.  
  968.         if (!CFlashUI::CV_gfx_uiaction_enable)
  969.                 return;
  970.  
  971.         UIACTION_LOG("%s (%i): UIElement set layer %i", GetName(), m_iInstanceID, iLayer);
  972.  
  973.         if (m_iLayer != iLayer)
  974.                 m_pFlashUI->InvalidateSortedElements();
  975.         m_iLayer = iLayer;
  976. }
  977.  
  978. //------------------------------------------------------------------------------------
  979. void CFlashUIElement::SetConstraints(const SUIConstraints& newConstraints)
  980. {
  981.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  982.  
  983.         if (!CFlashUI::CV_gfx_uiaction_enable)
  984.                 return;
  985.  
  986.         UIACTION_LOG("%s (%i): UIElement set new constraints", GetName(), m_iInstanceID);
  987.         m_constraints = newConstraints;
  988.         UpdateViewPort();
  989. }
  990.  
  991. //------------------------------------------------------------------------------------
  992. void CFlashUIElement::SetAlpha(float fAlpha)
  993. {
  994.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  995.  
  996.         if (!CFlashUI::CV_gfx_uiaction_enable)
  997.                 return;
  998.  
  999.         if (!LazyInit())
  1000.                 return;
  1001.  
  1002.         UIACTION_LOG("%s (%i): Set background alpha: %f", GetName(), m_iInstanceID, m_fAlpha);
  1003.  
  1004.         m_fAlpha = clamp_tpl(fAlpha, 0.0f, 1.f);
  1005.         if (m_pFlashplayer != NULL)
  1006.                 m_pFlashplayer->SetBackgroundAlpha(m_fAlpha);
  1007.         ForceLazyUpdateInl();
  1008. }
  1009.  
  1010. //------------------------------------------------------------------------------------
  1011. void CFlashUIElement::UpdateFlags()
  1012. {
  1013. #if CRY_PLATFORM_DESKTOP
  1014.         if (HasFlag(eFUI_HARDWARECURSOR) && m_bVisible && !m_bIsHideRequest)
  1015. #else
  1016.         if (HasFlag(eFUI_HARDWARECURSOR) && HasFlag(eFUI_CONSOLE_CURSOR) && m_bVisible && !m_bIsHideRequest)
  1017. #endif
  1018.                 ShowCursor();
  1019.         else
  1020.                 HideCursor();
  1021.  
  1022.         if (m_pFlashplayer)
  1023.                 m_pFlashplayer->StereoEnforceFixedProjectionDepth(HasFlag(eFUI_FIXED_PROJ_DEPTH));
  1024.         ForceLazyUpdateInl();
  1025. }
  1026.  
  1027. //------------------------------------------------------------------------------------
  1028. void CFlashUIElement::SetFlag(EFlashUIFlags flag, bool bSet)
  1029. {
  1030.         CRY_ASSERT_MESSAGE((flag & eFUI_NOT_CHANGEABLE) == 0, "Not allowed to set non changeable flag during runtime!");
  1031.         if ((flag & eFUI_NOT_CHANGEABLE) == 0)
  1032.                 SetFlagInt(flag, bSet);
  1033. }
  1034.  
  1035. void CFlashUIElement::SetFlagInt(EFlashUIFlags flag, bool bSet)
  1036. {
  1037.         if (HasFlag(flag) == bSet) return;
  1038.  
  1039.         if ((flag & eFUI_MASK_PER_ELEMENT) && m_pBaseInstance)
  1040.         {
  1041.                 m_pBaseInstance->SetFlag(flag, bSet);
  1042.         }
  1043.         else
  1044.         {
  1045.                 UIACTION_LOG("%s (%i): UIElement set flag %i to %s", GetName(), m_iInstanceID, flag, bSet ? "1" : "0");
  1046.                 if (bSet)
  1047.                         m_iFlags |= (uint64) flag;
  1048.                 else
  1049.                         m_iFlags &= ~(uint64) flag;
  1050.         }
  1051.  
  1052.         UpdateFlags();
  1053. }
  1054.  
  1055. //------------------------------------------------------------------------------------
  1056. bool CFlashUIElement::HasFlag(EFlashUIFlags flag) const
  1057. {
  1058.         if ((flag & eFUI_MASK_PER_ELEMENT) && m_pBaseInstance)
  1059.                 return m_pBaseInstance->HasFlag(flag);
  1060.  
  1061.         return (m_iFlags & (uint64) flag) != 0;
  1062. }
  1063.  
  1064. //------------------------------------------------------------------------------------
  1065. bool CFlashUIElement::DefaultInfoCheck(SFlashObjectInfo*& pInfo, const SUIParameterDesc* pDesc, const SUIMovieClipDesc* pTmplDesc)
  1066. {
  1067.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1068.                 return false;
  1069.  
  1070.         if (!LazyInit())
  1071.                 return false;
  1072.  
  1073.         CRY_ASSERT_MESSAGE(pDesc, "NULL pointer passed!");
  1074.         if (!pDesc)
  1075.                 return false;
  1076.  
  1077.         const SUIMovieClipDesc* pParentDesc = pTmplDesc ? pTmplDesc : m_pRoot;
  1078.         CRY_ASSERT_MESSAGE(pParentDesc, "Invalid parent passed!");
  1079.         if (!pParentDesc)
  1080.                 return false;
  1081.  
  1082.         pInfo = GetFlashVarObj(pDesc, pParentDesc);
  1083.         if (!pInfo)
  1084.         {
  1085. #if defined(UIACTION_LOGGING)
  1086.                 string sInstance;
  1087.                 pDesc->GetInstanceString(sInstance, pParentDesc);
  1088.                 UIACTION_ERROR("%s (%i): UIElement does not have object %s", GetName(), m_iInstanceID, sInstance.c_str());
  1089. #endif
  1090.                 return false;
  1091.         }
  1092.  
  1093.         return true;
  1094. }
  1095.  
  1096. //------------------------------------------------------------------------------------
  1097. bool CFlashUIElement::CallFunction(const char* pFctName, const SUIArguments& args, TUIData* pDataRes, const char* pTmplName)
  1098. {
  1099.         const SUIEventDesc* pEventDesc = GetOrCreateFunctionDesc(pFctName);
  1100.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1101.         return CallFunction(pEventDesc, args, pDataRes, pTmplDesc);
  1102. }
  1103.  
  1104. //------------------------------------------------------------------------------------
  1105. bool CFlashUIElement::CallFunction(const SUIEventDesc* pFctDesc, const SUIArguments& args, TUIData* pDataRes, const SUIMovieClipDesc* pTmplDesc)
  1106. {
  1107.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1108.  
  1109.         SFlashObjectInfo* pInfo = NULL;
  1110.         if (!DefaultInfoCheck(pInfo, pFctDesc, pTmplDesc))
  1111.                 return false;
  1112.  
  1113. #if defined(UIACTION_LOGGING)
  1114.         string sInstance;
  1115.         pFctDesc->GetInstanceString(sInstance, pTmplDesc);
  1116.  
  1117.         if (args.GetArgCount() != pFctDesc->InputParams.Params.size() && !pFctDesc->InputParams.IsDynamic)
  1118.         {
  1119.                 UIACTION_WARNING("%s (%i): Called function %s (%s) with wrong number of arguments. Expected %i args, got %i args", GetName(), m_iInstanceID, pFctDesc->sDisplayName, sInstance.c_str(), pFctDesc->InputParams.Params.size(), args.GetArgCount());
  1120.         }
  1121. #endif
  1122.  
  1123.         if (!pInfo->pParent)
  1124.         {
  1125.                 UIACTION_WARNING("%s (%i): Root movie clip missing", GetName(), m_iInstanceID);
  1126.                 return false;
  1127.         }
  1128.  
  1129.         SFlashVarValue pRes(0);
  1130.         if (pInfo->pParent->Invoke(pInfo->sMember.c_str(), args.GetAsList(), args.GetArgCount(), &pRes))
  1131.         {
  1132.                 if (pDataRes)
  1133.                 {
  1134.                         SUIArguments tmp(&pRes, 1);
  1135.                         *pDataRes = tmp.GetArg(0);
  1136.                 }
  1137.  
  1138. #if defined(UIACTION_LOGGING)
  1139.                 {
  1140.                         string res;
  1141.                         if (pDataRes)
  1142.                         {
  1143.                                 pDataRes->GetValueWithConversion(res);
  1144.                                 res = string(" - Res: ") + res;
  1145.                         }
  1146.                         UIACTION_LOG("%s (%i): Function invoked: %s (%s) - Args: %s%s", GetName(), m_iInstanceID, pFctDesc->sDisplayName, sInstance.c_str(), args.GetAsString(), res.c_str());
  1147.                 }
  1148. #endif
  1149.  
  1150.                 ForceLazyUpdateInl();
  1151.                 RemoveFlashVarObj(pFctDesc);
  1152.                 return true;
  1153.         }
  1154. #if defined(UIACTION_LOGGING)
  1155.         UIACTION_ERROR("%s (%i): Try to call undefined function %s (%s)", GetName(), m_iInstanceID, pFctDesc->sDisplayName, sInstance.c_str());
  1156. #endif
  1157.         RemoveFlashVarObj(pFctDesc);
  1158.         return false;
  1159. }
  1160.  
  1161. //------------------------------------------------------------------------------------
  1162. IFlashVariableObject* CFlashUIElement::GetMovieClip(const char* movieClipName, const char* pTmplName)
  1163. {
  1164.         const SUIMovieClipDesc* pMCDesc = GetOrCreateMovieClipDesc(movieClipName);
  1165.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1166.         return GetMovieClip(pMCDesc, pTmplDesc);
  1167. }
  1168.  
  1169. //------------------------------------------------------------------------------------
  1170. IFlashVariableObject* CFlashUIElement::GetMovieClip(const SUIMovieClipDesc* pMovieClipDesc, const SUIMovieClipDesc* pTmplDesc)
  1171. {
  1172.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1173.  
  1174.         SFlashObjectInfo* pInfo = NULL;
  1175.         if (!DefaultInfoCheck(pInfo, pMovieClipDesc, pTmplDesc))
  1176.                 return NULL;
  1177.  
  1178.         if (pInfo->pObj->IsDisplayObject())
  1179.         {
  1180.                 return pInfo->pObj;
  1181.         }
  1182.         return NULL;
  1183. }
  1184.  
  1185. //------------------------------------------------------------------------------------
  1186. IFlashVariableObject* CFlashUIElement::CreateMovieClip(const SUIMovieClipDesc*& pNewInstanceDesc, const char* movieClipTemplate, const char* mcParentName, const char* mcInstanceName)
  1187. {
  1188.         const SUIMovieClipDesc* pMCTmplDesc = GetOrCreateMovieClipTmplDesc(movieClipTemplate);
  1189.         const SUIMovieClipDesc* pParentDesc = mcParentName ? GetMovieClipDesc(mcParentName) : NULL;
  1190.         return CreateMovieClip(pNewInstanceDesc, pMCTmplDesc, pParentDesc, mcInstanceName);
  1191. }
  1192.  
  1193. //------------------------------------------------------------------------------------
  1194. IFlashVariableObject* CFlashUIElement::CreateMovieClip(const SUIMovieClipDesc*& pNewInstanceDesc, const SUIMovieClipDesc* pMovieClipTemplateDesc, const SUIMovieClipDesc* pParentMC, const char* mcInstanceName)
  1195. {
  1196.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1197.  
  1198.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1199.                 return NULL;
  1200.  
  1201.         if (!LazyInit())
  1202.                 return NULL;
  1203.  
  1204.         const SUIMovieClipDesc* pParentDesc = pParentMC ? pParentMC : m_pRoot;
  1205.         CRY_ASSERT_MESSAGE(pParentDesc, "Invalid parent passed!");
  1206.         if (!pParentDesc)
  1207.                 return NULL;
  1208.  
  1209.         string newName;
  1210.         if (mcInstanceName)
  1211.         {
  1212.                 if (const SUIMovieClipDesc* pDesc = GetMovieClipDesc(mcInstanceName))
  1213.                 {
  1214.                         if (pDesc->pParent)
  1215.                         {
  1216.                                 IFlashVariableObject* pVar = GetMovieClip(pDesc, pParentDesc);
  1217.                                 UIACTION_WARNING("%s (%i): Try to create new movieclip %s that already exist!", GetName(), m_iInstanceID, mcInstanceName);
  1218.                                 pNewInstanceDesc = pDesc;
  1219.                                 return pVar;
  1220.                         }
  1221.                 }
  1222.                 newName = mcInstanceName;
  1223.         }
  1224.         else
  1225.         {
  1226.                 int i = 0;
  1227.                 while (true)
  1228.                 {
  1229.                         newName.Format("%s_%i", pMovieClipTemplateDesc->sDisplayName, i++);
  1230.                         if (const SUIMovieClipDesc* pDesc = GetMovieClipDesc(newName.c_str()))
  1231.                         {
  1232.                                 if (pDesc->pParent == NULL)
  1233.                                         break;
  1234.                         }
  1235.                         else
  1236.                                 break;
  1237.                 }
  1238.         }
  1239.  
  1240.         IFlashVariableObject* pNewMc = NULL;
  1241.         SFlashObjectInfo* pParent = GetFlashVarObj(pParentDesc);
  1242.         if (pParent)
  1243.         {
  1244.                 string instanceName;
  1245.                 pParentDesc->GetInstanceString(instanceName);
  1246.                 instanceName += ".";
  1247.                 instanceName += newName.c_str();
  1248.                 pParent->pObj->AttachMovie(pNewMc, pMovieClipTemplateDesc->sName, instanceName.c_str());
  1249.                 if (pNewMc)
  1250.                 {
  1251.                         pParent->pObj->SetMember(newName.c_str(), pNewMc); // we have to set this member otherwise GetMember will return NULL even if it exists!
  1252.                         SUIMovieClipDesc* pMCDesc = const_cast<SUIMovieClipDesc*>(GetOrCreateMovieClipDesc(newName.c_str()));
  1253.                         pMCDesc->pParent = pParentDesc;
  1254.                         SFlashObjectInfo* pNewInfo = &m_variableObjects[CCryName(instanceName.c_str())];
  1255.                         pNewInfo->pObj = pNewMc;
  1256.                         pNewInfo->pParent = pParent->pObj;
  1257.                         pNewInfo->sMember = newName;
  1258.                         m_variableObjectsLookup[pParentDesc][pMCDesc] = pNewInfo;
  1259.                         pNewInstanceDesc = pMCDesc;
  1260.                         m_pFlashplayer->Advance(0);
  1261.                         UIACTION_LOG("%s (%i): Created Movieclip from template %s - Instancename %s", GetName(), m_iInstanceID, pMovieClipTemplateDesc->sDisplayName, instanceName.c_str());
  1262.                 }
  1263.         }
  1264.         ForceLazyUpdateInl();
  1265.         return pNewMc;
  1266. }
  1267.  
  1268. //------------------------------------------------------------------------------------
  1269. void CFlashUIElement::RemoveMovieClip(const char* movieClipName)
  1270. {
  1271.         RemoveMovieClip(GetMovieClipDesc(movieClipName));
  1272. }
  1273.  
  1274. //------------------------------------------------------------------------------------
  1275. void CFlashUIElement::RemoveMovieClip(const SUIParameterDesc* pMovieClipDesc)
  1276. {
  1277.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1278.  
  1279.         SFlashObjectInfo* pInfo = NULL;
  1280.         if (!DefaultInfoCheck(pInfo, pMovieClipDesc, NULL))
  1281.                 return;
  1282.  
  1283.         if (pInfo->pParent == NULL)
  1284.         {
  1285.                 UIACTION_ERROR("%s (%i): Not allowed to remove _root MC!", GetName(), m_iInstanceID);
  1286.                 return;
  1287.         }
  1288.         SUIParameterDesc* pMC = const_cast<SUIParameterDesc*>(pMovieClipDesc);
  1289.         pInfo->pObj->Invoke0("removeMovieClip");
  1290.         pInfo->pParent->SetMember(pInfo->sMember.c_str(), NULL);
  1291.         RemoveFlashVarObj(pMC);
  1292.         UIACTION_LOG("%s (%i): Removed Movieclip %s", GetName(), m_iInstanceID, pMovieClipDesc->sDisplayName);
  1293.         pMC->pParent = NULL;
  1294. }
  1295.  
  1296. //------------------------------------------------------------------------------------
  1297. void CFlashUIElement::RemoveMovieClip(IFlashVariableObject* flashVarObj)
  1298. {
  1299.         for (TVarMap::iterator it = m_variableObjects.begin(); it != m_variableObjects.end(); ++it)
  1300.         {
  1301.                 if (flashVarObj == it->second.pObj)
  1302.                 {
  1303.                         if (const SUIParameterDesc* pDesc = GetDescForInfo(&it->second))
  1304.                         {
  1305.                                 RemoveMovieClip(pDesc);
  1306.                                 return;
  1307.                         }
  1308.                 }
  1309.         }
  1310.         CRY_ASSERT_MESSAGE(false, "The given IFlashVariableObject was not created thru the UISystem!");
  1311. }
  1312.  
  1313. //------------------------------------------------------------------------------------
  1314. bool CFlashUIElement::SetVariable(const char* pVarName, const TUIData& value, const char* pTmplName)
  1315. {
  1316.         const SUIParameterDesc* pVarDesc = GetOrCreateVariableDesc(pVarName);
  1317.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1318.         return SetVariableInt(pVarDesc, value, pTmplDesc);
  1319. }
  1320.  
  1321. //------------------------------------------------------------------------------------
  1322. bool CFlashUIElement::SetVariable(const SUIParameterDesc* pVarDesc, const TUIData& value, const SUIMovieClipDesc* pTmplDesc)
  1323. {
  1324.         return SetVariableInt(pVarDesc, value, pTmplDesc);
  1325. }
  1326.  
  1327. //------------------------------------------------------------------------------------
  1328. bool CFlashUIElement::SetVariableInt(const SUIParameterDesc* pVarDesc, const TUIData& value, const SUIMovieClipDesc* pTmplDesc, bool bCreate /*= false*/)
  1329. {
  1330.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1331.  
  1332.         SFlashObjectInfo* pInfo = NULL;
  1333.         if (!DefaultInfoCheck(pInfo, pVarDesc, pTmplDesc))
  1334.                 return false;
  1335.  
  1336.         SUIArguments tmp;
  1337.         tmp.AddArgument(value);
  1338.         if (pInfo->pParent->SetMember(pInfo->sMember.c_str(), *tmp.GetAsList()))
  1339.         {
  1340.  
  1341. #if defined(UIACTION_LOGGING)
  1342.                 string sInstance;
  1343.                 pVarDesc->GetInstanceString(sInstance, pTmplDesc);
  1344.                 {
  1345.                         string sVal;
  1346.                         value.GetValueWithConversion(sVal);
  1347.                         UIACTION_LOG("%s (%i): Variable set %s (%s) - Value: %s", GetName(), m_iInstanceID, pVarDesc->sDisplayName, sInstance.c_str(), sVal.c_str());
  1348.                 }
  1349. #endif
  1350.  
  1351.                 ForceLazyUpdateInl();
  1352.                 return true;
  1353.         }
  1354. #if defined(UIACTION_LOGGING)
  1355.         string sInstance;
  1356.         pVarDesc->GetInstanceString(sInstance, pTmplDesc);
  1357.         UIACTION_ERROR("%s (%i): Try to access undefined variable %s (%s)", GetName(), m_iInstanceID, pVarDesc->sDisplayName, sInstance.c_str());
  1358. #endif
  1359.         return false;
  1360. }
  1361.  
  1362. //------------------------------------------------------------------------------------
  1363. bool CFlashUIElement::GetVariable(const char* pVarName, TUIData& valueOut, const char* pTmplName)
  1364. {
  1365.         const SUIParameterDesc* pVarDesc = GetOrCreateVariableDesc(pVarName);
  1366.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1367.         return GetVariable(pVarDesc, valueOut, pTmplDesc);
  1368. }
  1369.  
  1370. //------------------------------------------------------------------------------------
  1371. bool CFlashUIElement::GetVariable(const SUIParameterDesc* pVarDesc, TUIData& valueOut, const SUIMovieClipDesc* pTmplDesc)
  1372. {
  1373.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1374.  
  1375.         SFlashObjectInfo* pInfo = NULL;
  1376.         if (!DefaultInfoCheck(pInfo, pVarDesc, pTmplDesc))
  1377.                 return false;
  1378.  
  1379.         SFlashVarValue val = SFlashVarValue::CreateUndefined();
  1380.         if (pInfo->pParent->GetMember(pInfo->sMember.c_str(), val))
  1381.         {
  1382.                 SUIArguments tmp(&val, 1);
  1383.                 valueOut = tmp.GetArg(0);
  1384.  
  1385. #if defined(UIACTION_LOGGING)
  1386.                 string sInstance;
  1387.                 pVarDesc->GetInstanceString(sInstance, pTmplDesc);
  1388.                 UIACTION_LOG("%s (%i): Variable get %s (%s) - Value: %s", GetName(), m_iInstanceID, pVarDesc->sDisplayName, sInstance.c_str(), tmp.GetAsString());
  1389. #endif
  1390.                 return true;
  1391.         }
  1392. #if defined(UIACTION_LOGGING)
  1393.         string sInstance;
  1394.         pVarDesc->GetInstanceString(sInstance, pTmplDesc);
  1395.         UIACTION_ERROR("%s (%i): Try to access undefined variable %s (%s)", GetName(), m_iInstanceID, pVarDesc->sDisplayName, sInstance.c_str());
  1396. #endif
  1397.         return false;
  1398. }
  1399.  
  1400. //------------------------------------------------------------------------------------
  1401. bool CFlashUIElement::CreateVariable(const SUIParameterDesc*& pNewDesc, const char* varName, const TUIData& value, const char* pTmplName)
  1402. {
  1403.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1404.         return CreateVariable(pNewDesc, varName, value, pTmplDesc);
  1405. }
  1406.  
  1407. //------------------------------------------------------------------------------------
  1408. bool CFlashUIElement::CreateVariable(const SUIParameterDesc*& pNewDesc, const char* varName, const TUIData& value, const SUIMovieClipDesc* pTmplDesc)
  1409. {
  1410.         bool bExist;
  1411.         pNewDesc = GetOrCreateVariableDesc(varName, &bExist);
  1412.         if (bExist)
  1413.         {
  1414.                 UIACTION_ERROR("%s (%i): Try to create variable %s that already exists!", GetName(), m_iInstanceID, pNewDesc->sDisplayName);
  1415.         }
  1416.         ForceLazyUpdateInl();
  1417.         return SetVariableInt(pNewDesc, value, pTmplDesc, true);
  1418. }
  1419.  
  1420. //------------------------------------------------------------------------------------
  1421. bool CFlashUIElement::SetArray(const char* pArrayName, const SUIArguments& values, const char* pTmplName)
  1422. {
  1423.         const SUIParameterDesc* pArrayDesc = GetOrCreateArrayDesc(pArrayName);
  1424.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1425.         return SetArray(pArrayDesc, values, pTmplDesc);
  1426. }
  1427.  
  1428. //------------------------------------------------------------------------------------
  1429. bool CFlashUIElement::SetArray(const SUIParameterDesc* pArrayDesc, const SUIArguments& values, const SUIMovieClipDesc* pTmplDesc)
  1430. {
  1431.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1432.  
  1433.         SFlashObjectInfo* pInfo = NULL;
  1434.         if (!DefaultInfoCheck(pInfo, pArrayDesc, pTmplDesc))
  1435.                 return false;
  1436.  
  1437.         if (pInfo->pObj->IsArray())
  1438.         {
  1439.                 const int valueCount = values.GetArgCount();
  1440.                 pInfo->pObj->SetArraySize(valueCount);
  1441.                 const SFlashVarValue* pValueList = values.GetAsList();
  1442.                 for (int i = 0; i < valueCount; ++i)
  1443.                 {
  1444.                         pInfo->pObj->SetElement(i, pValueList[i]);
  1445.                 }
  1446.  
  1447.                 ForceLazyUpdateInl();
  1448. #if defined(UIACTION_LOGGING)
  1449.                 string sInstance;
  1450.                 pArrayDesc->GetInstanceString(sInstance, pTmplDesc);
  1451.                 UIACTION_LOG("%s (%i): Array set %s (%s) - Values: %s", GetName(), m_iInstanceID, pArrayDesc->sDisplayName, sInstance.c_str(), values.GetAsString());
  1452. #endif
  1453.                 return true;
  1454.         }
  1455. #if defined(UIACTION_LOGGING)
  1456.         string sInstance;
  1457.         pArrayDesc->GetInstanceString(sInstance, pTmplDesc);
  1458.         UIACTION_ERROR("%s (%i): Try to access undefined array %s (%s)", GetName(), m_iInstanceID, pArrayDesc->sDisplayName, sInstance.c_str());
  1459. #endif
  1460.         return false;
  1461. }
  1462.  
  1463. //------------------------------------------------------------------------------------
  1464. bool CFlashUIElement::GetArray(const char* pArrayName, SUIArguments& valuesOut, const char* pTmplName)
  1465. {
  1466.         const SUIParameterDesc* pArrayDesc = GetOrCreateArrayDesc(pArrayName);
  1467.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1468.         return GetArray(pArrayDesc, valuesOut, pTmplDesc);
  1469. }
  1470.  
  1471. //------------------------------------------------------------------------------------
  1472. bool CFlashUIElement::GetArray(const SUIParameterDesc* pArrayDesc, SUIArguments& valuesOut, const SUIMovieClipDesc* pTmplDesc)
  1473. {
  1474.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1475.  
  1476.         SFlashObjectInfo* pInfo = NULL;
  1477.         if (!DefaultInfoCheck(pInfo, pArrayDesc, pTmplDesc))
  1478.                 return false;
  1479.  
  1480.         if (pInfo->pObj->IsArray())
  1481.         {
  1482.                 const int size = pInfo->pObj->GetArraySize();
  1483.                 SFlashVarValue val = SFlashVarValue::CreateUndefined();
  1484.  
  1485.                 for (int i = 0; i < size; ++i)
  1486.                 {
  1487.                         pInfo->pObj->GetElement(i, val);
  1488.                         valuesOut.AddArguments(&val, 1);
  1489.                 }
  1490.  
  1491. #if defined(UIACTION_LOGGING)
  1492.                 string sInstance;
  1493.                 pArrayDesc->GetInstanceString(sInstance, pTmplDesc);
  1494.                 UIACTION_LOG("%s (%i): Array get %s (%s) - Values: %s", GetName(), m_iInstanceID, pArrayDesc->sDisplayName, sInstance.c_str(), valuesOut.GetAsString());
  1495. #endif
  1496.                 return true;
  1497.         }
  1498. #if defined(UIACTION_LOGGING)
  1499.         string sInstance;
  1500.         pArrayDesc->GetInstanceString(sInstance, pTmplDesc);
  1501.         UIACTION_ERROR("%s (%i): Try to access undefined array %s (%s)", GetName(), m_iInstanceID, pArrayDesc->sDisplayName, sInstance.c_str());
  1502. #endif
  1503.         return false;
  1504. }
  1505.  
  1506. //------------------------------------------------------------------------------------
  1507. bool CFlashUIElement::CreateArray(const SUIParameterDesc*& pNewDesc, const char* arrayName, const SUIArguments& values, const char* pTmplName)
  1508. {
  1509.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1510.         return CreateArray(pNewDesc, arrayName, values, pTmplDesc);
  1511. }
  1512.  
  1513. //------------------------------------------------------------------------------------
  1514. bool CFlashUIElement::CreateArray(const SUIParameterDesc*& pNewDesc, const char* arrayName, const SUIArguments& values, const SUIMovieClipDesc* pTmplDesc)
  1515. {
  1516.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1517.  
  1518.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1519.                 return false;
  1520.  
  1521.         if (!LazyInit())
  1522.                 return false;
  1523.  
  1524.         const SUIMovieClipDesc* pParentDesc = pTmplDesc ? pTmplDesc : m_pRoot;
  1525.         CRY_ASSERT_MESSAGE(pParentDesc && arrayName, "Invalid parent passed!");
  1526.         if (!pParentDesc)
  1527.                 return false;
  1528.  
  1529.         const SUIParameterDesc* pDesc = GetOrCreateArrayDesc(arrayName);
  1530.         if (pDesc->pParent)
  1531.         {
  1532.                 SFlashObjectInfo* pInfo = GetFlashVarObj(pDesc, pParentDesc);
  1533.                 if (pInfo)
  1534.                 {
  1535.                         UIACTION_WARNING("%s (%i): Try to create new array %s that already exist!", GetName(), m_iInstanceID, arrayName);
  1536.                         return SetArray(pDesc, values);
  1537.                         ;
  1538.                 }
  1539.         }
  1540.  
  1541.         IFlashVariableObject* pNewArray = NULL;
  1542.         SFlashObjectInfo* pParent = GetFlashVarObj(pParentDesc);
  1543.         if (pParent)
  1544.         {
  1545.                 bool ok = m_pFlashplayer->CreateArray(pNewArray);
  1546.                 CRY_ASSERT_MESSAGE(ok, "Failed to create new flash array!");
  1547.                 pParent->pObj->SetMember(arrayName, pNewArray);
  1548.  
  1549.                 const_cast<SUIParameterDesc*>(pDesc)->pParent = pParentDesc;
  1550.                 string instanceName;
  1551.                 pDesc->GetInstanceString(instanceName, pParentDesc);
  1552.                 SFlashObjectInfo* pNewInfo = &m_variableObjects[CCryName(instanceName.c_str())];
  1553.                 pNewInfo->pObj = pNewArray;
  1554.                 pNewInfo->pParent = pParent->pObj;
  1555.                 pNewInfo->sMember = arrayName;
  1556.                 m_variableObjectsLookup[pParentDesc][pDesc] = pNewInfo;
  1557.                 m_pFlashplayer->Advance(0);
  1558.                 pNewDesc = pDesc;
  1559.                 ForceLazyUpdateInl();
  1560.                 return SetArray(pDesc, values);
  1561.         }
  1562.         UIACTION_ERROR("%s (%i): Try to create new array %s on invalid parent!", GetName(), m_iInstanceID, arrayName);
  1563.         return false;
  1564. }
  1565.  
  1566. //------------------------------------------------------------------------------------
  1567. void CFlashUIElement::LoadTexIntoMc(const char* movieClip, ITexture* pTexture, const char* pTmplName)
  1568. {
  1569.         const SUIParameterDesc* pMovieClipDesc = GetOrCreateMovieClipDesc(movieClip);
  1570.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1571.         LoadTexIntoMc(pMovieClipDesc, pTexture, pTmplDesc);
  1572. }
  1573.  
  1574. //------------------------------------------------------------------------------------
  1575. void CFlashUIElement::LoadTexIntoMc(const SUIParameterDesc* pMovieClipDesc, ITexture* pTexture, const SUIMovieClipDesc* pTmplDesc)
  1576. {
  1577.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1578.  
  1579.         SFlashObjectInfo* pInfo = NULL;
  1580.         if (!DefaultInfoCheck(pInfo, pMovieClipDesc, pTmplDesc))
  1581.                 return;
  1582.  
  1583.         if (pInfo->pObj->IsDisplayObject())
  1584.         {
  1585.                 string texStr;
  1586.                 texStr.Format("img://TEXID:%i", pTexture->GetTextureID());
  1587.                 pInfo->pObj->Invoke1("loadMovie", texStr.c_str());
  1588.                 ForceLazyUpdateInl();
  1589. #if defined(UIACTION_LOGGING)
  1590.                 string sInstance;
  1591.                 pMovieClipDesc->GetInstanceString(sInstance, pTmplDesc);
  1592.                 UIACTION_LOG("%s (%i): Loaded texture %s into movieclip %s (%s)", GetName(), m_iInstanceID, pTexture->GetName(), pMovieClipDesc->sDisplayName, sInstance.c_str());
  1593. #endif
  1594.         }
  1595.         else
  1596.         {
  1597. #if defined(UIACTION_LOGGING)
  1598.                 string sInstance;
  1599.                 pMovieClipDesc->GetInstanceString(sInstance, pTmplDesc);
  1600.                 UIACTION_ERROR("%s (%i): Try to access non-existing movieclip %s", GetName(), m_iInstanceID, pMovieClipDesc->sDisplayName);
  1601. #endif
  1602.         }
  1603. }
  1604.  
  1605. //------------------------------------------------------------------------------------
  1606. void CFlashUIElement::UnloadTexFromMc(const char* movieClip, ITexture* pTexture, const char* pTmplName)
  1607. {
  1608.         const SUIParameterDesc* pMovieClipDesc = GetOrCreateMovieClipDesc(movieClip);
  1609.         const SUIMovieClipDesc* pTmplDesc = pTmplName ? GetMovieClipDesc(pTmplName) : NULL;
  1610.         UnloadTexFromMc(pMovieClipDesc, pTexture, pTmplDesc);
  1611. }
  1612.  
  1613. //------------------------------------------------------------------------------------
  1614. void CFlashUIElement::UnloadTexFromMc(const SUIParameterDesc* pMovieClipDesc, ITexture* pTexture, const SUIMovieClipDesc* pTmplDesc)
  1615. {
  1616.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1617.  
  1618.         SFlashObjectInfo* pInfo = NULL;
  1619.         if (!DefaultInfoCheck(pInfo, pMovieClipDesc, pTmplDesc))
  1620.                 return;
  1621.  
  1622.         if (pInfo->pObj->IsDisplayObject())
  1623.         {
  1624.                 string texStr;
  1625.                 texStr.Format("img://TEXID:%i", pTexture->GetTextureID());
  1626.                 pInfo->pObj->Invoke1("unloadMovie", texStr.c_str());
  1627.                 ForceLazyUpdateInl();
  1628. #if defined(UIACTION_LOGGING)
  1629.                 string sInstance;
  1630.                 pMovieClipDesc->GetInstanceString(sInstance, pTmplDesc);
  1631.                 UIACTION_LOG("%s (%i): Unloaded texture %s from movieclip %s (%s)", GetName(), m_iInstanceID, pTexture->GetName(), pMovieClipDesc->sDisplayName, sInstance.c_str());
  1632. #endif
  1633.         }
  1634.         else
  1635.         {
  1636. #if defined(UIACTION_LOGGING)
  1637.                 string sInstance;
  1638.                 pMovieClipDesc->GetInstanceString(sInstance, pTmplDesc);
  1639.                 UIACTION_ERROR("%s (%i): Try to access non-existing movieclip %s", GetName(), m_iInstanceID, pMovieClipDesc->sDisplayName);
  1640. #endif
  1641.         }
  1642. }
  1643.  
  1644. //------------------------------------------------------------------------------------
  1645. void CFlashUIElement::ScreenToFlash(const float& px, const float& py, float& rx, float& ry, bool bStageScaleMode) const
  1646. {
  1647.         if (m_pFlashplayer)
  1648.         {
  1649.                 const float flashWidth = (float) m_pFlashplayer->GetWidth();
  1650.                 const float flashHeigth = (float) m_pFlashplayer->GetHeight();
  1651.                 float flashVPX, flashVPY, flashVPWidth, flashVPHeight;
  1652.                 {
  1653.                         int x, y, width, height;
  1654.                         float aspect;
  1655.                         m_pFlashplayer->GetViewport(x, y, width, height, aspect);
  1656.                         flashVPX = (float) x;
  1657.                         flashVPY = (float) y;
  1658.                         flashVPWidth = (float) width;
  1659.                         flashVPHeight = (float) height;
  1660.                 }
  1661.  
  1662.                 if (!m_constraints.bScale && !bStageScaleMode)
  1663.                 {
  1664.                         const float oAspect = flashWidth / flashHeigth;
  1665.                         const float nAspect = flashVPWidth / flashVPHeight;
  1666.                         if (oAspect < nAspect) flashVPWidth = flashVPHeight * oAspect;
  1667.                         else flashVPHeight = flashVPWidth / oAspect;
  1668.                 }
  1669.  
  1670.                 const float screenWidth = (float)gEnv->pRenderer->GetWidth();
  1671.                 const float screenHeigth = (float)gEnv->pRenderer->GetHeight();
  1672.  
  1673.                 const float screenX = px * screenWidth;
  1674.                 const float screenY = py * screenHeigth;
  1675.  
  1676.                 const float flashX = (screenX - flashVPX) / flashVPWidth;
  1677.                 const float flashY = (screenY - flashVPY) / flashVPHeight;
  1678.  
  1679.                 rx = flashX * flashWidth;
  1680.                 ry = flashY * flashHeigth;
  1681.  
  1682.                 if (bStageScaleMode)
  1683.                 {
  1684.                         float factorX = screenWidth / flashWidth;
  1685.                         float factorY = screenHeigth / flashHeigth;
  1686.  
  1687.                         rx *= factorX;
  1688.                         ry *= factorY;
  1689.  
  1690.                         rx -= (screenWidth - flashWidth) / 2.f;
  1691.                         ry -= (screenHeigth - flashHeigth) / 2.f;
  1692.                 }
  1693.         }
  1694. }
  1695.  
  1696. //------------------------------------------------------------------------------------
  1697. void CFlashUIElement::WorldToFlash(const Matrix34& camMat, const Vec3& worldpos, Vec3& flashpos, Vec2& borders, float& scale, bool bStageScaleMode) const
  1698. {
  1699.         // calculate scale
  1700.         const float distance = (camMat.GetTranslation() - worldpos).GetLength();
  1701.         Matrix44 projMat;
  1702.         gEnv->pRenderer->GetProjectionMatrix(projMat.GetData());
  1703.         scale = MatMulVec3(projMat, Vec3(-1.f, -1.f, distance)).x;
  1704.  
  1705.         // calculate screen x,y coordinates
  1706.         CCamera cam = gEnv->pRenderer->GetCamera();
  1707.         cam.SetMatrix(camMat);
  1708.         cam.Project(worldpos, flashpos);
  1709.         flashpos.x = flashpos.x / (f32)gEnv->pRenderer->GetWidth();
  1710.         flashpos.y = flashpos.y / (f32)gEnv->pRenderer->GetHeight();
  1711.  
  1712.         // overflow
  1713.         borders.x = flashpos.x<0 ? -1.f : flashpos.x> 1.f ? 1.f : flashpos.z < 1.f ? 0 : -1.f;
  1714.         borders.y = flashpos.y<0 ? -1.f : flashpos.y> 1.f ? 1.f : flashpos.z < 1.f ? 0 : -1.f;
  1715.  
  1716.         // store screen pos in x/y and depth in z (clamp to borders if not on screen)
  1717.         flashpos.x = borders.x == 0 ? flashpos.x : borders.x < 0 ? 0 : 1.f;
  1718.         flashpos.y = borders.y == 0 ? flashpos.y : borders.y < 0 ? 0 : 1.f;
  1719.         ;
  1720.         flashpos.z = distance;
  1721.  
  1722.         // finally transform into flash coordinates
  1723.         ScreenToFlash(flashpos.x, flashpos.y, flashpos.x, flashpos.y, bStageScaleMode);
  1724. }
  1725.  
  1726. //------------------------------------------------------------------------------------
  1727. Vec3 CFlashUIElement::MatMulVec3(const Matrix44& m, const Vec3& v) const
  1728. {
  1729.         Vec3 r;
  1730.         const float fInvW = 1.0f / (m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33);
  1731.         r.x = (m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03) * fInvW;
  1732.         r.y = (m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13) * fInvW;
  1733.         r.z = (m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23) * fInvW;
  1734.         return r;
  1735. }
  1736.  
  1737. //------------------------------------------------------------------------------------
  1738. void CFlashUIElement::AddTexture(IDynTextureSource* pDynTexture)
  1739. {
  1740.         CRY_ASSERT_MESSAGE(pDynTexture, "NULL pointer passed!");
  1741.         if (pDynTexture)
  1742.         {
  1743.                 UIACTION_LOG("%s (%i): UIElement registered by texture \"%p\"", GetName(), m_iInstanceID, pDynTexture);
  1744.                 const bool ok = m_textures.PushBackUnique(pDynTexture);
  1745.                 CRY_ASSERT_MESSAGE(ok, "Texture already registered!");
  1746.  
  1747.                 SetVisible(true);
  1748.  
  1749.                 if (m_pFlashplayer)
  1750.                 {
  1751.                         m_pFlashplayer->SetViewScaleMode(IFlashPlayer::eSM_ExactFit);
  1752.                         m_pFlashplayer->SetViewport(0, 0, m_pFlashplayer->GetWidth(), m_pFlashplayer->GetHeight(), 1.f);
  1753.                         m_pFlashplayer->SetScissorRect(0, 0, m_pFlashplayer->GetWidth(), m_pFlashplayer->GetHeight());
  1754.                 }
  1755.         }
  1756. }
  1757.  
  1758. //------------------------------------------------------------------------------------
  1759. void CFlashUIElement::RemoveTexture(IDynTextureSource* pDynTexture)
  1760. {
  1761.         CRY_ASSERT_MESSAGE(pDynTexture, "NULL pointer passed!");
  1762.         if (pDynTexture)
  1763.         {
  1764.                 UIACTION_LOG("%s (%i): UIElement unregistered by texture \"%p\"", GetName(), m_iInstanceID, pDynTexture);
  1765.                 const bool ok = m_textures.FindAndErase(pDynTexture);
  1766.                 CRY_ASSERT_MESSAGE(ok, "Texture was never registered or already unregistered!");
  1767.         }
  1768. }
  1769.  
  1770. //------------------------------------------------------------------------------------
  1771. void CFlashUIElement::SendCursorEvent(SFlashCursorEvent::ECursorState evt, int iX, int iY, int iButton /*= 0*/, float fWheel /*= 0.f*/)
  1772. {
  1773.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1774.  
  1775.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1776.                 return;
  1777.  
  1778.         if (!m_pFlashplayer || m_bIsHideRequest)
  1779.                 return;
  1780.  
  1781.         UpdateFlags();
  1782.  
  1783.         if (HasExtTexture())
  1784.         {
  1785.                 int x, y, width, height;
  1786.                 gEnv->pRenderer->GetViewport(&x, &y, &width, &height);
  1787.                 float fX = (float) iX / (float) width;
  1788.                 float fY = (float) iY / (float) height;
  1789.                 float aspect;
  1790.                 m_pFlashplayer->GetViewport(x, y, width, height, aspect);
  1791.                 iX = (int) (fX * (float)width);
  1792.                 iY = (int) (fY * (float)height);
  1793.         }
  1794.  
  1795.         m_pFlashplayer->ScreenToClient(iX, iY);
  1796.         m_pFlashplayer->SendCursorEvent(SFlashCursorEvent(evt, iX, iY, iButton, fWheel));
  1797.         m_pFlashplayer->Advance(0);
  1798.         ForceLazyUpdateInl();
  1799. }
  1800.  
  1801. void CFlashUIElement::SendKeyEvent(const SFlashKeyEvent& evt)
  1802. {
  1803.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1804.  
  1805.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1806.                 return;
  1807.  
  1808.         if (!m_pFlashplayer || m_bIsHideRequest)
  1809.                 return;
  1810.  
  1811.         m_pFlashplayer->SendKeyEvent(evt);
  1812.         m_pFlashplayer->Advance(0);
  1813.         ForceLazyUpdateInl();
  1814. }
  1815.  
  1816. void CFlashUIElement::SendCharEvent(const SFlashCharEvent& charEvent)
  1817. {
  1818.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1819.  
  1820.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1821.                 return;
  1822.  
  1823.         if (!m_pFlashplayer || m_bIsHideRequest)
  1824.                 return;
  1825.  
  1826.         m_pFlashplayer->SendCharEvent(charEvent);
  1827.         m_pFlashplayer->Advance(0);
  1828.         ForceLazyUpdateInl();
  1829. }
  1830.  
  1831. void CFlashUIElement::SendControllerEvent(EControllerInputEvent event, EControllerInputState state, float value)
  1832. {
  1833.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1834.  
  1835.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1836.                 return;
  1837.  
  1838.         if (!m_pFlashplayer || m_bIsHideRequest)
  1839.                 return;
  1840.  
  1841.         if (m_pFlashplayer->IsAvailable("cry_onController"))
  1842.         {
  1843.                 HideCursor();
  1844.  
  1845.                 SFlashVarValue args[] = { SFlashVarValue((int) event), SFlashVarValue(state == eCIS_OnRelease), SFlashVarValue(value) };
  1846.                 m_pFlashplayer->Invoke("cry_onController", args, 3);
  1847.                 m_pFlashplayer->Advance(0);
  1848.         }
  1849.         ForceLazyUpdateInl();
  1850. }
  1851.  
  1852. //-------------------------------------------------------------------
  1853. void CFlashUIElement::GetMemoryUsage(ICrySizer* s) const
  1854. {
  1855.         SIZER_SUBCOMPONENT_NAME(s, "UIElement");
  1856.         s->AddObject(this, sizeof(*this));
  1857.         s->Add(&m_variables, SUIElementSerializer::GetMemUsage(m_variables));
  1858.         s->Add(&m_arrays, SUIElementSerializer::GetMemUsage(m_arrays));
  1859.         s->Add(&m_displayObjects, SUIElementSerializer::GetMemUsage(m_displayObjects));
  1860.         s->Add(&m_displayObjectsTmpl, SUIElementSerializer::GetMemUsage(m_displayObjectsTmpl));
  1861.         s->Add(&m_functions, SUIElementSerializer::GetMemUsage(m_functions));
  1862.         s->Add(&m_events, SUIElementSerializer::GetMemUsage(m_events));
  1863.  
  1864.         s->AddContainer(m_variableObjects);
  1865.         s->Add(&m_eventListener, m_eventListener.MemSize());
  1866.         TDynTextures::TVec dynTex = m_textures.GetCopy();
  1867.         s->AddContainer(dynTex);
  1868.  
  1869.         {
  1870.                 SIZER_SUBCOMPONENT_NAME(s, "Instances");
  1871.                 s->AddContainer(m_instances);
  1872.                 for (TUIElements::const_iterator iter = m_instances.begin(); iter != m_instances.end(); ++iter)
  1873.                 {
  1874.                         if (*iter != this)
  1875.                                 (*iter)->GetMemoryUsage(s);
  1876.                 }
  1877.         }
  1878. }
  1879.  
  1880. //------------------------------------------------------------------------------------
  1881. void CFlashUIElement::HandleFSCommand(const char* sCommand, const char* sArgs, void* pUserData)
  1882. {
  1883.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1884.  
  1885.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1886.                 return;
  1887.  
  1888.         SUIArguments args;
  1889.         args.SetDelimiter(",");
  1890.         args.SetArguments(sArgs);
  1891.         args.SetDelimiter(UIARGS_DEFAULT_DELIMITER);
  1892.  
  1893.         if (HandleInternalCommand(sCommand, args))
  1894.         {
  1895.                 UIACTION_LOG("%s (%i): Internal command received %s (args: %s)", GetName(), m_iInstanceID, sCommand, sArgs);
  1896.         }
  1897.         else
  1898.         {
  1899.                 SUIEventDesc* pEventDesc = NULL;
  1900.                 for (TUIEventsLookup::iterator iter = m_events.begin(); iter != m_events.end(); ++iter)
  1901.                 {
  1902.                         if (!strcmp((*iter)->sName, sCommand))
  1903.                         {
  1904.                                 pEventDesc = *iter;
  1905.                                 break;
  1906.                         }
  1907.                 }
  1908.  
  1909.                 if (pEventDesc)
  1910.                 {
  1911.                         UIACTION_LOG("%s (%i): Event %s (%s) sended (args: %s)", GetName(), m_iInstanceID, pEventDesc->sDisplayName, pEventDesc->sName, args.GetAsString());
  1912.  
  1913.                         for (TUIEventListener::Notifier notifier(m_eventListener); notifier.IsValid(); notifier.Next())
  1914.                                 notifier->OnUIEvent(this, *pEventDesc, args);
  1915.                 }
  1916.                 else
  1917.                 {
  1918.                         UIACTION_LOG("%s (%i): Fscommand %s sended (args: %s)", GetName(), m_iInstanceID, sCommand, args.GetAsString());
  1919.  
  1920.                         for (TUIEventListener::Notifier notifier(m_eventListener); notifier.IsValid(); notifier.Next())
  1921.                                 notifier->OnUIEventEx(this, sCommand, args, pUserData);
  1922.                 }
  1923.         }
  1924. }
  1925.  
  1926. //------------------------------------------------------------------------------------
  1927. bool CFlashUIElement::HandleInternalCommand(const char* sCommand, const SUIArguments& args)
  1928. {
  1929.         if (strcmp(sCommand, "cry_hideElement") == 0)
  1930.         {
  1931.                 UIACTION_LOG("%s (%i): UIElement received \"cry_hideElement\" from ActionScript", GetName(), m_iInstanceID);
  1932.                 SetVisible(false);
  1933.                 return true;
  1934.         }
  1935.         if (strcmp(sCommand, "cry_virtualKeyboard") == 0)
  1936.         {
  1937.                 UIACTION_LOG("%s (%i): UIElement received \"cry_virtualKeyboard\" from ActionScript with args %s", GetName(), m_iInstanceID, args.GetAsString());
  1938.                 string mode;
  1939.                 string utf8Title;
  1940.                 string utf8InitialInput;
  1941.                 int maxchars;
  1942.  
  1943.                 bool ok = args.GetArg(0, mode);
  1944.                 ok &= args.GetArg(1, utf8Title);
  1945.                 ok &= args.GetArg(2, utf8InitialInput);
  1946.                 ok &= args.GetArg(3, maxchars);
  1947.  
  1948.                 if (ok && utf8Title[0] == '@') // this is a localization label (label name stored in utf8Title)
  1949.                 {
  1950.                         string utf8Localized;
  1951.                         if (gEnv->pSystem->GetLocalizationManager()->LocalizeLabel(utf8Title.c_str(), utf8Localized))
  1952.                         {
  1953.                                 utf8Title.swap(utf8Localized);
  1954.                         }
  1955.                 }
  1956.  
  1957.                 CRY_ASSERT_MESSAGE(ok, "cry_virtualKeyboard received with wrong arguments!");
  1958.                 if (ok)
  1959.                 {
  1960.                         unsigned int flags = IPlatformOS::KbdFlag_Default;
  1961.                         if (strcmpi(mode.c_str(), "GamerTag") == 0)
  1962.                                 flags &= IPlatformOS::KbdFlag_GamerTag;
  1963.                         else if (strcmpi(mode.c_str(), "Password") == 0)
  1964.                                 flags &= IPlatformOS::KbdFlag_Password;
  1965.                         else if (strcmpi(mode.c_str(), "Email") == 0)
  1966.                                 flags &= IPlatformOS::KbdFlag_Email;
  1967.  
  1968.                         m_pFlashUI->DisplayVirtualKeyboard(flags, utf8Title, utf8InitialInput, maxchars, this);
  1969.                 }
  1970.                 else
  1971.                 {
  1972.                         UIACTION_ERROR("%s (%i): cry_virtualKeyboard received with wrong arguments! Args: %s", GetName(), m_iInstanceID, args.GetAsString());
  1973.                 }
  1974.                 return true;
  1975.         }
  1976.         if (strcmp(sCommand, "cry_imeFocus") == 0)
  1977.         {
  1978.                 UIACTION_LOG("%s (%i): UIElement received \"cry_imeFocus\" from ActionScript", GetName(), m_iInstanceID);
  1979.                 IFlashPlayer* pPlayer = GetFlashPlayer();
  1980.                 if (pPlayer) pPlayer->SetImeFocus();
  1981.                 return true;
  1982.         }
  1983.         return false;
  1984. }
  1985.  
  1986. //------------------------------------------------------------------------------------
  1987. void CFlashUIElement::KeyboardCancelled()
  1988. {
  1989.         if (!m_pFlashplayer)
  1990.                 return;
  1991.  
  1992.         if (!CFlashUI::CV_gfx_uiaction_enable)
  1993.                 return;
  1994.  
  1995.         if (m_pFlashplayer->IsAvailable("cry_onVirtualKeyboard"))
  1996.         {
  1997.                 SUIArguments args;
  1998.                 args.AddArgument(false);
  1999.                 args.AddArgument("");
  2000.                 m_pFlashplayer->Invoke("cry_onVirtualKeyboard", args.GetAsList(), args.GetArgCount());
  2001.         }
  2002. }
  2003.  
  2004. //------------------------------------------------------------------------------------
  2005. void CFlashUIElement::KeyboardFinished(const char* pInString)
  2006. {
  2007.         if (!m_pFlashplayer)
  2008.                 return;
  2009.  
  2010.         if (!CFlashUI::CV_gfx_uiaction_enable)
  2011.                 return;
  2012.  
  2013.         if (m_pFlashplayer->IsAvailable("cry_onVirtualKeyboard"))
  2014.         {
  2015.                 SUIArguments args;
  2016.                 args.AddArgument(true);
  2017.                 args.AddArgument(pInString);
  2018.                 m_pFlashplayer->Invoke("cry_onVirtualKeyboard", args.GetAsList(), args.GetArgCount());
  2019.         }
  2020. }
  2021.  
  2022. //------------------------------------------------------------------------------------
  2023. const SUIParameterDesc* CFlashUIElement::GetOrCreateVariableDesc(const char* pVarName, bool* bExist /*= NULL*/)
  2024. {
  2025.         const SUIParameterDesc* pVarDesc = GetVariableDesc(pVarName);
  2026.         if (bExist) *bExist = pVarDesc != NULL;
  2027.         if (!pVarDesc)
  2028.         {
  2029.                 pVarName = GetStringBuffer(pVarName);
  2030.                 SUIParameterDesc* pNewVarDesc = new SUIParameterDesc(pVarName, pVarName, "New dynamic created var");
  2031.                 m_variables.push_back(pNewVarDesc);
  2032.                 pVarDesc = pNewVarDesc;
  2033.                 UIACTION_LOG("%s (%i): Created new dynamic variable definition %s", GetName(), m_iInstanceID, pVarName);
  2034.         }
  2035.         return pVarDesc;
  2036. }
  2037.  
  2038. //------------------------------------------------------------------------------------
  2039. const SUIParameterDesc* CFlashUIElement::GetOrCreateArrayDesc(const char* pArrayName, bool* bExist /*= NULL*/)
  2040. {
  2041.         const SUIParameterDesc* pArrayDesc = GetArrayDesc(pArrayName);
  2042.         if (bExist) *bExist = pArrayDesc != NULL;
  2043.         if (!pArrayDesc)
  2044.         {
  2045.                 pArrayName = GetStringBuffer(pArrayName);
  2046.                 SUIParameterDesc* pNewArrayDesc = new SUIParameterDesc(pArrayName, pArrayName, "New dynamic created array");
  2047.                 m_arrays.push_back(pNewArrayDesc);
  2048.                 pArrayDesc = pNewArrayDesc;
  2049.                 UIACTION_LOG("%s (%i): Created new dynamic array definition %s", GetName(), m_iInstanceID, pArrayName);
  2050.         }
  2051.         return pArrayDesc;
  2052. }
  2053.  
  2054. //------------------------------------------------------------------------------------
  2055. const SUIMovieClipDesc* CFlashUIElement::GetOrCreateMovieClipDesc(const char* pMovieClipName, bool* bExist /*= NULL*/)
  2056. {
  2057.         const SUIMovieClipDesc* pMCDesc = GetMovieClipDesc(pMovieClipName);
  2058.         if (bExist) *bExist = pMCDesc != NULL;
  2059.         if (!pMCDesc)
  2060.         {
  2061.                 pMovieClipName = GetStringBuffer(pMovieClipName);
  2062.                 SUIMovieClipDesc* pNewMCDesc = new SUIMovieClipDesc(pMovieClipName, pMovieClipName, "New dynamic created MC");
  2063.                 m_displayObjects.push_back(pNewMCDesc);
  2064.                 pMCDesc = pNewMCDesc;
  2065.                 UIACTION_LOG("%s (%i): Created new dynamic movieclip definition %s", GetName(), m_iInstanceID, pMovieClipName);
  2066.         }
  2067.         return pMCDesc;
  2068. }
  2069.  
  2070. //------------------------------------------------------------------------------------
  2071. const SUIMovieClipDesc* CFlashUIElement::GetOrCreateMovieClipTmplDesc(const char* pMovieClipTmplName)
  2072. {
  2073.         const SUIMovieClipDesc* pMCTmplDesc = GetMovieClipTmplDesc(pMovieClipTmplName);
  2074.         if (!pMCTmplDesc)
  2075.         {
  2076.                 pMovieClipTmplName = GetStringBuffer(pMovieClipTmplName);
  2077.                 SUIMovieClipDesc* pNewMCTmplDesc = new SUIMovieClipDesc(pMovieClipTmplName, pMovieClipTmplName, "New dynamic created MC Template");
  2078.                 m_displayObjectsTmpl.push_back(pNewMCTmplDesc);
  2079.                 pMCTmplDesc = pNewMCTmplDesc;
  2080.                 UIACTION_LOG("%s (%i): Created new dynamic movieclip template %s", GetName(), m_iInstanceID, pMovieClipTmplName);
  2081.         }
  2082.         return pMCTmplDesc;
  2083. }
  2084.  
  2085. //------------------------------------------------------------------------------------
  2086. const SUIEventDesc* CFlashUIElement::GetOrCreateFunctionDesc(const char* pFunctionName)
  2087. {
  2088.         const SUIEventDesc* pEventDesc = GetFunctionDesc(pFunctionName);
  2089.         if (!pEventDesc)
  2090.         {
  2091.                 pFunctionName = GetStringBuffer(pFunctionName);
  2092.                 SUIEventDesc* pNewEventDesc = new SUIEventDesc(pFunctionName, pFunctionName, "Dynamic Created Fct", true);
  2093.                 m_functions.push_back(pNewEventDesc);
  2094.                 pEventDesc = pNewEventDesc;
  2095.                 UIACTION_LOG("%s (%i): Created new dynamic function definition %s", GetName(), m_iInstanceID, pFunctionName);
  2096.         }
  2097.         return pEventDesc;
  2098. }
  2099.  
  2100. //------------------------------------------------------------------------------------
  2101. CFlashUIElement::SFlashObjectInfo* CFlashUIElement::GetFlashVarObj(const SUIParameterDesc* pDesc, const SUIMovieClipDesc* pTmplDesc)
  2102. {
  2103.         CRY_ASSERT_MESSAGE(pDesc, "NULL pointer passed!");
  2104.         SFlashObjectInfo* pVarInfo = NULL;
  2105.         const SUIMovieClipDesc* pRootDesc = pDesc != m_pRoot ? pTmplDesc ? pTmplDesc : m_pRoot : NULL;
  2106.  
  2107.         TVarMapLookup& map = m_variableObjectsLookup[pRootDesc];
  2108.         TVarMapLookup::iterator iter = map.find(pDesc);
  2109.         if (iter != map.end())
  2110.                 pVarInfo = iter->second;
  2111.  
  2112.         if (pDesc && !pVarInfo)
  2113.         {
  2114.                 string sInstance;
  2115.                 pDesc->GetInstanceString(sInstance, pRootDesc);
  2116.                 TVarMap::iterator it = m_variableObjects.find(CCryName(sInstance.c_str()));
  2117.                 if (it != m_variableObjects.end())
  2118.                 {
  2119.                         pVarInfo = &it->second;
  2120.                         map[pDesc] = pVarInfo;
  2121.                 }
  2122.                 else
  2123.                 {
  2124.                         // since accessing thru path foo.bar.mc does not work in dynamic created MCs we have to go thru the path manually
  2125.                         // we will collect all members on the way and store them in the m_variableObjects list for easy release on unload
  2126.                         string currPathToObj = "_root";
  2127.                         SUIArguments path;
  2128.                         path.SetDelimiter(".");
  2129.                         path.SetArguments(sInstance.c_str());
  2130.                         const int count = path.GetArgCount();
  2131.                         IFlashVariableObject* pParent = m_variableObjects[CCryName(m_pRoot->sName)].pObj;
  2132.                         IFlashVariableObject* pVar = NULL;
  2133.                         for (int i = 1; i < count && pParent; ++i)
  2134.                         {
  2135.                                 string member;
  2136.                                 path.GetArg(i, member);
  2137.                                 currPathToObj += ".";
  2138.                                 currPathToObj += member;
  2139.                                 SFlashObjectInfo* pCurrVarInfo = NULL;
  2140.                                 it = m_variableObjects.find(CCryName(currPathToObj.c_str()));
  2141.                                 if (it != m_variableObjects.end())
  2142.                                 {
  2143.                                         pCurrVarInfo = &it->second;
  2144.                                         pVar = pCurrVarInfo->pObj;
  2145.                                 }
  2146.                                 else
  2147.                                 {
  2148.                                         pParent->GetMember(member.c_str(), pVar);
  2149.                                         if (pVar)
  2150.                                         {
  2151.                                                 pCurrVarInfo = &m_variableObjects[CCryName(currPathToObj.c_str())];
  2152.                                                 pCurrVarInfo->pObj = pVar;
  2153.                                                 pCurrVarInfo->pParent = pParent;
  2154.                                                 pCurrVarInfo->sMember = member;
  2155.                                         }
  2156.                                 }
  2157.                                 if (i == count - 1)
  2158.                                 {
  2159.                                         pVarInfo = pCurrVarInfo;
  2160.                                         map[pDesc] = pVarInfo;
  2161.                                 }
  2162.                                 pParent = pVar;
  2163.                         }
  2164.                 }
  2165.         }
  2166.         return pVarInfo;
  2167. }
  2168.  
  2169. //------------------------------------------------------------------------------------
  2170. void CFlashUIElement::RemoveFlashVarObj(const SUIParameterDesc* pDesc)
  2171. {
  2172.         typedef std::vector<std::pair<TVarMap::iterator, std::pair<const SUIParameterDesc*, const SUIParameterDesc*>>> TDelList;
  2173.         TDelList iterToDelete;
  2174.         string instance;
  2175.         pDesc->GetInstanceString(instance);
  2176.         const char* sInstanceStr = instance.c_str();
  2177.         int lenInstance = instance.length();
  2178.         for (TVarMap::iterator it = m_variableObjects.begin(); it != m_variableObjects.end(); ++it)
  2179.         {
  2180.                 const char* instStr = it->first.c_str();
  2181.                 int len = it->first.length();
  2182.                 if (strstr(instStr, sInstanceStr) && (len == lenInstance || (len > lenInstance && instStr[lenInstance] == '.')))
  2183.                 {
  2184.                         const SUIParameterDesc* pParentDescToDel = NULL;
  2185.                         const SUIParameterDesc* pDescToDel = GetDescForInfo(&it->second, &pParentDescToDel);
  2186.                         UIACTION_LOG("%s (%i): Release FlashVarObject %s (%s)", GetName(), m_iInstanceID, pDescToDel ? pDescToDel->sDisplayName : "", it->first.c_str());
  2187.                         iterToDelete.push_back(std::make_pair(it, std::make_pair(pDescToDel, pParentDescToDel)));
  2188.                 }
  2189.         }
  2190.         CRY_ASSERT_MESSAGE(!iterToDelete.empty(), "The given ParameterDescription is not valid!");
  2191.         for (TDelList::iterator it = iterToDelete.begin(); it != iterToDelete.end(); ++it)
  2192.         {
  2193.                 it->first->second.pObj->Release();
  2194.                 if (it->second.first)
  2195.                 {
  2196.                         TVarMapLookup& map = m_variableObjectsLookup[it->second.second];
  2197.                         const bool ok = stl::member_find_and_erase(map, it->second.first);
  2198.                         CRY_ASSERT_MESSAGE(ok, "no lookup for this object!");
  2199.                 }
  2200.                 m_variableObjects.erase(it->first);
  2201.         }
  2202. }
  2203.  
  2204. const SUIParameterDesc* CFlashUIElement::GetDescForInfo(SFlashObjectInfo* pInfo, const SUIParameterDesc** pParent) const
  2205. {
  2206.         for (TTmplMapLookup::const_iterator it = m_variableObjectsLookup.begin(); it != m_variableObjectsLookup.end(); ++it)
  2207.         {
  2208.                 for (TVarMapLookup::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
  2209.                         if (it2->second == pInfo)
  2210.                         {
  2211.                                 if (pParent) *pParent = it->first;
  2212.                                 return it2->first;
  2213.                         }
  2214.         }
  2215.         return NULL;
  2216. }
  2217.  
  2218. //------------------------------------------------------------------------------------
  2219. void CFlashUIElement::FreeVarObjects()
  2220. {
  2221.         for (TVarMap::iterator it = m_variableObjects.begin(); it != m_variableObjects.end(); ++it)
  2222.         {
  2223.                 SAFE_RELEASE(it->second.pObj);
  2224.         }
  2225.         m_variableObjects.clear();
  2226.         m_variableObjectsLookup.clear();
  2227. }
  2228.  
  2229. //------------------------------------------------------------------------------------
  2230. void CFlashUIElement::AddEventListener(IUIElementEventListener* pListener, const char* name)
  2231. {
  2232.         const bool ok = m_eventListener.Add(pListener, name);
  2233.         CRY_ASSERT_MESSAGE(ok, "Listener already registered!");
  2234. }
  2235.  
  2236. //------------------------------------------------------------------------------------
  2237. void CFlashUIElement::RemoveEventListener(IUIElementEventListener* pListener)
  2238. {
  2239.         // Since flow nodes will unregister at all living instances to make sure they only re-register at elements of interest
  2240.         // this check is disabled
  2241.         // assert( m_eventListener.Contains(pListener) );
  2242.         m_eventListener.Remove(pListener);
  2243. }
  2244.  
  2245. //------------------------------------------------------------------------------------
  2246. void CFlashUIElement::UpdateViewPort()
  2247. {
  2248.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  2249.  
  2250.         if (!CFlashUI::CV_gfx_uiaction_enable)
  2251.                 return;
  2252.  
  2253.         if (!m_pFlashplayer || HasExtTexture() || m_constraints.eType == SUIConstraints::ePT_FixedDynTexSize)
  2254.                 return;
  2255.  
  2256.         int posX, posY, width, height, dx, dy;
  2257.  
  2258.         if (!gEnv->IsEditor())
  2259.         {
  2260.                 dx = gEnv->pRenderer->GetOverlayWidth();
  2261.                 dy = gEnv->pRenderer->GetOverlayHeight();
  2262.         }
  2263.         else
  2264.         {
  2265.                 m_pFlashUI->GetScreenSize(dx, dy);
  2266.         }
  2267.  
  2268.         if (m_constraints.eType == SUIConstraints::ePT_Fixed)
  2269.         {
  2270.                 posX = m_constraints.iLeft;
  2271.                 posY = m_constraints.iTop;
  2272.                 width = m_constraints.iWidth;
  2273.                 height = m_constraints.iHeight;
  2274.                 if (m_constraints.bScale)
  2275.                 {
  2276.                         m_pFlashplayer->SetViewScaleMode(IFlashPlayer::eSM_ExactFit);
  2277.                 }
  2278.         }
  2279.         else if (m_constraints.eType == SUIConstraints::ePT_Dynamic)
  2280.         {
  2281.                 if (m_constraints.bScale)
  2282.                 {
  2283.                         float screenAspectRatio = (float) dx / dy;
  2284.                         float hudAspectRatio = (float) m_pFlashplayer->GetWidth() / m_pFlashplayer->GetHeight();
  2285.  
  2286.                         const bool fitToHeight = m_constraints.bMax ? screenAspectRatio<hudAspectRatio : screenAspectRatio> hudAspectRatio;
  2287.  
  2288.                         width = fitToHeight ? (int) (dy * hudAspectRatio) : dx;
  2289.                         height = !fitToHeight ? (int) (dx / hudAspectRatio) : dy;
  2290.                         ;
  2291.  
  2292.                         switch (m_constraints.eHAlign)
  2293.                         {
  2294.                         default:
  2295.                         case SUIConstraints::ePA_Lower:
  2296.                                 posX = 0;
  2297.                                 break;
  2298.                         case SUIConstraints::ePA_Mid:
  2299.                                 posX = fitToHeight ? (int) ((dx - dy * hudAspectRatio) / 2.f) : 0;
  2300.                                 break;
  2301.                         case SUIConstraints::ePA_Upper:
  2302.                                 posX = fitToHeight ? (int) (dx - dy * hudAspectRatio) : 0;
  2303.                                 break;
  2304.                         }
  2305.                         switch (m_constraints.eVAlign)
  2306.                         {
  2307.                         default:
  2308.                         case SUIConstraints::ePA_Lower:
  2309.                                 posY = 0;
  2310.                                 break;
  2311.                         case SUIConstraints::ePA_Mid:
  2312.                                 posY = !fitToHeight ? (int) ((dy - dx / hudAspectRatio) / 2.f) : 0;
  2313.                                 break;
  2314.                         case SUIConstraints::ePA_Upper:
  2315.                                 posY = !fitToHeight ? (int) (dy - dx / hudAspectRatio) : 0;
  2316.                                 break;
  2317.                         }
  2318.  
  2319.                 }
  2320.                 else
  2321.                 {
  2322.                         width = m_pFlashplayer->GetWidth();
  2323.                         height = m_pFlashplayer->GetHeight();
  2324.  
  2325.                         switch (m_constraints.eHAlign)
  2326.                         {
  2327.                         default:
  2328.                         case SUIConstraints::ePA_Lower:
  2329.                                 posX = 0;
  2330.                                 break;
  2331.                         case SUIConstraints::ePA_Mid:
  2332.                                 posX = (dx - width) / 2;
  2333.                                 break;
  2334.                         case SUIConstraints::ePA_Upper:
  2335.                                 posX = dx - width;
  2336.                                 break;
  2337.                         }
  2338.                         switch (m_constraints.eVAlign)
  2339.                         {
  2340.                         default:
  2341.                         case SUIConstraints::ePA_Lower:
  2342.                                 posY = 0;
  2343.                                 break;
  2344.                         case SUIConstraints::ePA_Mid:
  2345.                                 posY = (dy - height) / 2;
  2346.                                 break;
  2347.                         case SUIConstraints::ePA_Upper:
  2348.                                 posY = dy - height;
  2349.                                 break;
  2350.                         }
  2351.  
  2352.                 }
  2353.         }
  2354.         else /*if ( m_constraints.eType == SUIConstraints::ePT_Fullscreen )*/
  2355.         {
  2356.                 posX = 0;
  2357.                 posY = 0;
  2358.                 width = dx;
  2359.                 height = dy;
  2360.  
  2361.                 if (m_constraints.bScale)
  2362.                 {
  2363.                         m_pFlashplayer->SetViewScaleMode(IFlashPlayer::eSM_ExactFit);
  2364.                 }
  2365.                 m_pFlashplayer->SetViewAlignment(IFlashPlayer::eAT_TopLeft);
  2366.         }
  2367.  
  2368.         // set viewport
  2369.         m_pFlashplayer->SetViewport(posX, posY, width, height, 1.f);
  2370.         if (m_pFlashplayer->IsAvailable("cry_onResize"))
  2371.         {
  2372.                 SFlashVarValue args[] = { SFlashVarValue(width), SFlashVarValue(height), SFlashVarValue(dx), SFlashVarValue(dy) };
  2373.                 m_pFlashplayer->Invoke("cry_onResize", args, 4);
  2374.                 m_pFlashplayer->Advance(0);
  2375.         }
  2376.         ForceLazyUpdateInl();
  2377.         UIACTION_LOG("%s (%i): Changed Viewport: %d, %d, %d, %d", GetName(), m_iInstanceID, posX, posY, width, height);
  2378. }
  2379.  
  2380. //------------------------------------------------------------------------------------
  2381. void CFlashUIElement::GetViewPort(int& x, int& y, int& width, int& height, float& aspectRatio)
  2382. {
  2383.         if (m_pFlashplayer)
  2384.         {
  2385.                 m_pFlashplayer->GetViewport(x, y, width, height, aspectRatio);
  2386.         }
  2387. }
  2388.  
  2389. //------------------------------------------------------------------------------------
  2390.  
  2391. CUIElementIterator::CUIElementIterator(const CFlashUIElement* pElement)
  2392.         : m_pElement(pElement)
  2393. {
  2394.         m_iRefs = 1;
  2395.         m_currIter = pElement->m_instances.begin();
  2396. }
  2397.  
  2398. //------------------------------------------------------------------------------------
  2399. void CUIElementIterator::AddRef()
  2400. {
  2401.         m_iRefs++;
  2402. }
  2403.  
  2404. //------------------------------------------------------------------------------------
  2405. void CUIElementIterator::Release()
  2406. {
  2407.         if (--m_iRefs == 0)
  2408.                 delete this;
  2409. }
  2410.  
  2411. //------------------------------------------------------------------------------------
  2412. IUIElement* CUIElementIterator::Next()
  2413. {
  2414.         IUIElement* pNext = NULL;
  2415.         if (m_currIter != m_pElement->m_instances.end())
  2416.         {
  2417.                 pNext = *m_currIter;
  2418.                 ++m_currIter;
  2419.         }
  2420.         return pNext;
  2421. }
  2422.  
  2423. //------------------------------------------------------------------------------------
  2424. #undef SHOW_CURSOR
  2425. #undef HIDE_CURSOR
  2426.  
downloadFlashUIElement.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top