BVB Source Codes

CRYENGINE Show FlashUI.cpp Source code

Return Download CRYENGINE: download FlashUI.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "FlashUI.h"
  5. #include "FlashUIElement.h"
  6. #include "FlashUIAction.h"
  7. #include "FlashUIElementNodes.h"
  8. #include "FlashUIEventNodes.h"
  9. #include "FlashUIActionEvents.h"
  10.  
  11. #include <IPlayerProfiles.h>
  12. #include <CryString/StringUtils.h>
  13. #include <CrySystem/VR/IHMDManager.h>
  14. #include <CryRenderer/IStereoRenderer.h>
  15. #include <CrySystem/Scaleform/IScaleformHelper.h>
  16.  
  17. #define FLASH_UIELEMENTS_FOLDER "UIElements"
  18. #define FLASH_UIACTION_FOLDER   "UIActions"
  19. #define FLASH_PRELOAD_XML       "TexturePreload.xml"
  20.  
  21. AllocateConstIntCVar(CFlashUI, CV_gfx_draw);
  22. AllocateConstIntCVar(CFlashUI, CV_gfx_debugdraw);
  23. AllocateConstIntCVar(CFlashUI, CV_gfx_uiaction_enable);
  24. AllocateConstIntCVar(CFlashUI, CV_gfx_uiaction_log);
  25. AllocateConstIntCVar(CFlashUI, CV_gfx_loadtimethread);
  26. AllocateConstIntCVar(CFlashUI, CV_gfx_reloadonlanguagechange);
  27. AllocateConstIntCVar(CFlashUI, CV_gfx_uievents_editorenabled);
  28. AllocateConstIntCVar(CFlashUI, CV_gfx_ampserver);
  29. int CFlashUI::CV_gfx_enabled;
  30. float CFlashUI::CV_gfx_inputevents_triggerstart;
  31. float CFlashUI::CV_gfx_inputevents_triggerrepeat;
  32.  
  33. ICVar* CFlashUI::CV_gfx_uiaction_log_filter;
  34. ICVar* CFlashUI::CV_gfx_uiaction_folder;
  35.  
  36. //------------------------------------------------------------------------------------
  37. string CreateDisplayName(const char* format, ...)
  38. {
  39.         va_list args;
  40.         va_start(args, format);
  41.         char result[1024];
  42.         cry_vsprintf(result, format, args);
  43.         va_end(args);
  44.         return result;
  45. }
  46.  
  47. #if !defined (_RELEASE) || defined(ENABLE_UISTACK_DEBUGGING)
  48. void RenderDebugInfo();
  49. #endif
  50. #ifdef ENABLE_UISTACK_DEBUGGING
  51. void RenderStackDebugInfo(bool, const char*, int);
  52. #endif
  53. //-------------------------------------------------------------------
  54. CRYREGISTER_SINGLETON_CLASS(CFlashUI)
  55.  
  56. CFlashUI::CFlashUI()
  57.         : m_pUIActionManager(new CUIActionManager())
  58.         , m_iWidth(1)
  59.         , m_iHeight(1)
  60.         , m_bLoadtimeThread(false)
  61.         , m_bSortedElementsInvalidated(true)
  62.         , m_ScreenSizeCB(NULL)
  63.         , m_LogCallback(NULL)
  64.         , m_plattformCallback(NULL)
  65.         , m_pFlashUIActionEvents(NULL)
  66.         , m_systemState(eSS_NoLevel)
  67.         , m_fLastAdvance(0)
  68.         , m_modules(8)
  69.         , m_lastTimeTriggered(0)
  70.         , m_bHudVisible(true)
  71. {
  72.         DefineConstIntCVarName("gfx_draw", CV_gfx_draw, 1, VF_NULL, "Draw UI Elements");
  73.         DefineConstIntCVarName("gfx_debugdraw", CV_gfx_debugdraw, 0, VF_NULL, "Display UI Elements debug info.\n" \
  74.           "0=Disabled"                                                                                            \
  75.           "1=UIElements"                                                                                          \
  76.           "2=UIActions"                                                                                           \
  77.           "4=UIActions"                                                                                           \
  78.           "12=UIStack per UI FG");
  79.         DefineConstIntCVarName("gfx_uiaction_log", CV_gfx_uiaction_log, 0, VF_NULL, "Log UI Actions");
  80.         DefineConstIntCVarName("gfx_uiaction_enable", CV_gfx_uiaction_enable, 1, VF_NULL, "Enables UI Actions");
  81.         DefineConstIntCVarName("gfx_loadtimethread", CV_gfx_loadtimethread, 1, VF_NULL, "Enables threaded rendering while loading");
  82.         DefineConstIntCVarName("gfx_reloadonlanguagechange", CV_gfx_reloadonlanguagechange, 1, VF_NULL, "Automatically reloads all UIElements on language change");
  83.         DefineConstIntCVarName("gfx_uievents_editorenabled", CV_gfx_uievents_editorenabled, 1, VF_NULL, "Enabled UI->System events in editor (Disabled per default! handle with care!)");
  84.         DefineConstIntCVarName("gfx_ampserver", CV_gfx_ampserver, 0, VF_NULL, "Enables AMP flash profiling");
  85.  
  86.         REGISTER_CVAR3("gfx_enabled", CV_gfx_enabled, 1, VF_NULL, "Enables the general FlashUI.");
  87.  
  88.         REGISTER_CVAR2("gfx_inputevents_triggerstart", &CV_gfx_inputevents_triggerstart, 0.3f, VF_NULL, "Time in seconds to wait until input key triggering starts");
  89.         REGISTER_CVAR2("gfx_inputevents_triggerrepeat", &CV_gfx_inputevents_triggerrepeat, 0.05f, VF_NULL, "Time in seconds to wait between each input key trigger");
  90.  
  91.         CV_gfx_uiaction_log_filter = REGISTER_STRING("gfx_uiaction_log_filter", "", VF_NULL, "Filter for logging\n" \
  92.           "<string> only log messages\n"                                                                            \
  93.           "-<string> don't log message\n"                                                                           \
  94.           "<filter1>|<filter2> to use more filters");
  95.         CV_gfx_uiaction_folder = REGISTER_STRING("gfx_uiaction_folder", "Libs/UI/", VF_NULL, "Default folder for UIActions");
  96.  
  97.         REGISTER_COMMAND("gfx_reload_all", CFlashUI::ReloadAllElements, VF_NULL, "Reloads all UI Elements");
  98. }
  99.  
  100. //-------------------------------------------------------------------
  101. void CFlashUI::Init()
  102. {
  103.         LOADING_TIME_PROFILE_SECTION;
  104.         if (CV_gfx_enabled)
  105.         {
  106.                 m_pFlashUIActionEvents = new CFlashUIActionEvents();
  107.  
  108.                 LoadElements();
  109.                 CreateNodes();
  110.         }
  111. }
  112.  
  113. //-------------------------------------------------------------------
  114. bool CFlashUI::PostInit()
  115. {
  116.         LOADING_TIME_PROFILE_SECTION;
  117.         bool res = true;
  118.  
  119.         if (CV_gfx_enabled)
  120.         {
  121.                 LoadActions();
  122.  
  123.                 for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  124.                 {
  125.                         res &= (*iter)->Init(false);
  126.                 }
  127.                 for (TUIActionsLookup::iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  128.                 {
  129.                         res &= (*iter)->Init();
  130.                 }
  131.  
  132.                 RegisterListeners();
  133.  
  134.                 for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  135.                         notifier->Init();
  136.  
  137.                 PreloadTextures();
  138.                 gEnv->pRenderer->InitSystemResources(FRR_SYSTEM_RESOURCES);
  139.         }
  140.         return res;
  141. }
  142.  
  143. //-------------------------------------------------------------------
  144. void CFlashUI::Shutdown()
  145. {
  146.         StopRenderThread();
  147.  
  148.         for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  149.                 notifier->Shutdown();
  150.  
  151.         if (gEnv->pHardwareMouse && gEnv->pInput)
  152.         {
  153.                 gEnv->pHardwareMouse->RemoveListener(this);
  154.                 gEnv->pInput->RemoveEventListener(this);
  155.         }
  156.         ClearNodes();
  157.         ClearActions();
  158.         ClearElements();
  159.         UnregisterListeners();
  160.  
  161.         for (TUIEventSystemMap::const_iterator iter = m_eventSystemsUiToSys.begin(); iter != m_eventSystemsUiToSys.end(); ++iter)
  162.                 delete iter->second;
  163.  
  164.         for (TUIEventSystemMap::const_iterator iter = m_eventSystemsSysToUi.begin(); iter != m_eventSystemsSysToUi.end(); ++iter)
  165.                 delete iter->second;
  166.  
  167.         SAFE_DELETE(m_pUIActionManager);
  168.         SAFE_DELETE(m_pFlashUIActionEvents);
  169. }
  170.  
  171. //------------------------------------------------------------------------------------
  172. void CFlashUI::RegisterListeners()
  173. {
  174.         CRY_ASSERT_MESSAGE(gEnv->pHardwareMouse && gEnv->pInput, "Unable to register as input listener!");
  175.         if (gEnv->pHardwareMouse && gEnv->pInput)
  176.         {
  177.                 gEnv->pHardwareMouse->AddListener(this);
  178.                 gEnv->pInput->AddEventListener(this);
  179.         }
  180.  
  181.         CRY_ASSERT_MESSAGE(gEnv->pGameFramework, "Unable to register as Framework listener!");
  182.         if (gEnv->pGameFramework)
  183.         {
  184.                 gEnv->pGameFramework->RegisterListener(this, "FlashUI", FRAMEWORKLISTENERPRIORITY_HUD);
  185.                 CRY_ASSERT_MESSAGE(gEnv->pGameFramework->GetILevelSystem(), "Unable to register as levelsystem listener!");
  186.                 if (gEnv->pGameFramework->GetILevelSystem())
  187.                 {
  188.                         gEnv->pGameFramework->GetILevelSystem()->AddListener(this);
  189.                 }
  190.         }
  191.  
  192.         CRY_ASSERT_MESSAGE(gEnv->pSystem, "Unable to register as system listener!");
  193.         if (gEnv->pSystem)
  194.         {
  195.                 gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(this);
  196.         }
  197. }
  198.  
  199. //------------------------------------------------------------------------------------
  200. void CFlashUI::UnregisterListeners()
  201. {
  202.         if (gEnv->pGameFramework)
  203.         {
  204.                 gEnv->pGameFramework->UnregisterListener(this);
  205.                 if (gEnv->pGameFramework->GetILevelSystem())
  206.                         gEnv->pGameFramework->GetILevelSystem()->RemoveListener(this);
  207.         }
  208.  
  209.         if (gEnv->pSystem)
  210.         {
  211.                 gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(this);
  212.         }
  213.  
  214.         if (gEnv->pHardwareMouse && gEnv->pInput)
  215.         {
  216.                 gEnv->pHardwareMouse->RemoveListener(this);
  217.                 gEnv->pInput->RemoveEventListener(this);
  218.         }
  219. }
  220.  
  221. //------------------------------------------------------------------------------------
  222. void CFlashUI::Reload()
  223. {
  224.         LOADING_TIME_PROFILE_SECTION;
  225.         UIACTION_LOG("FlashUI reload start");
  226.  
  227.         ReloadAllBootStrapper();
  228.         ResetActions();
  229.         ReloadScripts();
  230.  
  231.         for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  232.                 notifier->Reload();
  233.  
  234.         gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_FRONTEND_RELOADED, 0, 0);
  235.  
  236.         UIACTION_LOG("FlashUI reload end");
  237. }
  238.  
  239. //-------------------------------------------------------------------
  240. void CFlashUI::ReloadAll()
  241. {
  242.         if (gEnv->IsEditor())
  243.         {
  244.                 for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  245.                         if (!notifier->EditorAllowReload())
  246.                                 return;
  247.  
  248.                 LoadElements();
  249.                 CreateNodes();
  250.                 gEnv->pFlowSystem->ReloadAllNodeTypes();
  251.                 LoadActions();
  252.                 Reload();
  253.  
  254.                 for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  255.                         notifier->EditorReload();
  256.  
  257.                 return;
  258.         }
  259.  
  260.         Reload();
  261. }
  262.  
  263. //-------------------------------------------------------------------
  264. void CFlashUI::Update(float fDeltaTime)
  265. {
  266.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  267.  
  268.         if (m_bLoadtimeThread)
  269.                 return;
  270.  
  271.         const bool isEditor = gEnv->IsEditor();
  272.  
  273.         if (!isEditor || gEnv->pGameFramework->IsGameStarted())
  274.         {
  275.  
  276.                 if (CV_gfx_reloadonlanguagechange == 1)
  277.                         CheckLanguageChanged();
  278.  
  279.                 CheckResolutionChange();
  280.         }
  281.  
  282.         for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  283.                 notifier->UpdateModule(fDeltaTime);
  284.  
  285.         const TSortedElementList& sortedElements = GetSortedElements();
  286.  
  287.         for (TSortedElementList::const_iterator iter = sortedElements.begin(); iter != sortedElements.end(); ++iter)
  288.         {
  289.                 // UIElements with eFUI_NO_AUTO_UPDATE flag are advanced & rendered manually.
  290.                 if (iter->second->HasFlag(IUIElement::eFUI_NO_AUTO_UPDATE))
  291.                         continue;
  292.  
  293.                 iter->second->Update(fDeltaTime);
  294.                 if (CV_gfx_draw == 1)
  295.                 {
  296.                         if (!m_bHudVisible && iter->second->HasFlag(IUIElement::eFUI_IS_HUD))
  297.                                 continue;
  298.  
  299.                         iter->second->Render();
  300.                 }
  301.         }
  302.  
  303.         ResetDirtyFlags();
  304.  
  305. #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD)
  306.         // amp server support
  307.         if (gEnv && gEnv->pScaleformHelper)
  308.         {
  309.                 static bool ampEnabled = false;
  310.                 if (CV_gfx_ampserver == 1)
  311.                 {
  312.                         if (!ampEnabled)
  313.                         {
  314.                                 gEnv->pScaleformHelper->SetAmpEnabled(true);
  315.                                 ampEnabled = true;
  316.                         }
  317.                 }
  318.                 else if (ampEnabled)
  319.                 {
  320.                         gEnv->pScaleformHelper->SetAmpEnabled(false);
  321.                         ampEnabled = false;
  322.                 }
  323.  
  324.                 // always tick amp if we compiled support in, else memory will accumulate and never be freed
  325.                 gEnv->pScaleformHelper->AmpAdvanceFrame();
  326.         }
  327.  
  328. #endif
  329.  
  330. #if !defined (_RELEASE) || defined(ENABLE_UISTACK_DEBUGGING)
  331.         // debug info
  332.         if (CV_gfx_debugdraw > 0)
  333.         {
  334.                 RenderDebugInfo();
  335.         }
  336. #endif
  337. }
  338.  
  339. //------------------------------------------------------------------------------------
  340. void CFlashUI::InvalidateSortedElements()
  341. {
  342.         m_bSortedElementsInvalidated = true;
  343. }
  344.  
  345. //------------------------------------------------------------------------------------
  346. const CFlashUI::TSortedElementList& CFlashUI::GetSortedElements()
  347. {
  348.         if (m_bSortedElementsInvalidated)
  349.                 UpdateSortedElements();
  350.         return m_sortedElements;
  351. }
  352.  
  353. //------------------------------------------------------------------------------------
  354. void CFlashUI::UpdateSortedElements()
  355. {
  356.         m_sortedElements.clear();
  357.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  358.         {
  359.                 IUIElementIteratorPtr instances = (*iter)->GetInstances();
  360.                 while (IUIElement* pInstance = instances->Next())
  361.                 {
  362.                         if (pInstance->IsVisible())
  363.                         {
  364.                                 m_sortedElements.insert(std::make_pair(pInstance->GetLayer(), pInstance));
  365.                         }
  366.                 }
  367.         }
  368.         m_bSortedElementsInvalidated = false;
  369. }
  370.  
  371. //------------------------------------------------------------------------------------
  372. void CFlashUI::OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
  373. {
  374.         LOADING_TIME_PROFILE_SECTION;
  375.         switch (event)
  376.         {
  377.         case ESYSTEM_EVENT_GAME_POST_INIT_DONE:
  378.                 {
  379.                         m_pFlashUIActionEvents->OnSystemStart();
  380.                         UpdateFG();
  381.                         m_systemState = eSS_NoLevel;
  382.                 }
  383.                 break;
  384.  
  385.         case ESYSTEM_EVENT_FAST_SHUTDOWN:
  386.                 {
  387.                         StopRenderThread();
  388.                         ReleasePreloadedTextures(true);
  389.                         m_pFlashUIActionEvents->OnSystemShutdown();
  390.                         UpdateFG();
  391.                         m_systemState = eSS_NoLevel;
  392.                 }
  393.                 break;
  394.  
  395.         case ESYSTEM_EVENT_GAME_PAUSED:
  396.                 {
  397.                         if (m_systemState == eSS_GameStarted)
  398.                         {
  399.                                 m_pFlashUIActionEvents->OnGameplayPaused();
  400.                         }
  401.                 }
  402.                 break;
  403.  
  404.         case ESYSTEM_EVENT_GAME_RESUMED:
  405.                 {
  406.                         if (m_systemState == eSS_GameStarted)
  407.                         {
  408.                                 m_pFlashUIActionEvents->OnGameplayResumed();
  409.                         }
  410.                 }
  411.                 break;
  412.  
  413.         case ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN:
  414.                 {
  415.                         m_fLastAdvance = gEnv->pTimer->GetAsyncCurTime();
  416.                         if (m_systemState == eSS_NoLevel)
  417.                         {
  418.                                 m_pFlashUIActionEvents->OnLoadingStart((ILevelInfo*)wparam);
  419.                                 UpdateFG();
  420.                                 StartRenderThread();
  421.                         }
  422.  
  423.                         m_systemState = eSS_Loading;
  424.                 }
  425.                 break;
  426.  
  427.         case ESYSTEM_EVENT_LEVEL_GAMEPLAY_START:
  428.                 {
  429.                         if (m_systemState == eSS_LoadingDone)
  430.                         {
  431.                                 m_pFlashUIActionEvents->OnGameplayStarted();
  432.                         }
  433.                         m_systemState = eSS_GameStarted;
  434.                 }
  435.                 break;
  436.  
  437.         case ESYSTEM_EVENT_LEVEL_UNLOAD:
  438.                 {
  439.                         if (m_systemState == eSS_GameStarted)
  440.                         {
  441.                                 m_pFlashUIActionEvents->OnLevelUnload();
  442.                                 UpdateFG();
  443.                                 Update(0.1f);
  444.                                 StartRenderThread();
  445.  
  446.                                 UIACTION_LOG("FlashUI unload start");
  447.                                 for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  448.                                 {
  449.                                         CFlashUIElement* pElement = (CFlashUIElement*)*iter;
  450.                                         if (pElement->HasFlag(IUIElement::eFUI_FORCE_NO_UNLOAD))
  451.                                                 continue;
  452.                                         pElement->Unload(true);
  453.                                 }
  454.                                 for (TUIModules::Notifier notifier(m_modules); notifier.IsValid(); notifier.Next())
  455.                                         notifier->Reset();
  456.  
  457.                                 ResetActions();
  458.                                 ReleasePreloadedTextures();
  459.  
  460.                                 UIACTION_LOG("FlashUI unload end");
  461.                         }
  462.                         m_systemState = eSS_Unloading;
  463.                 }
  464.                 break;
  465.  
  466.         case ESYSTEM_EVENT_LEVEL_POST_UNLOAD:
  467.                 {
  468.                         if (m_systemState == eSS_Unloading)
  469.                         {
  470.                                 StopRenderThread();
  471.                                 gEnv->pRenderer->InitSystemResources(FRR_SYSTEM_RESOURCES);
  472.                                 PreloadTextures();
  473.  
  474.                                 m_pFlashUIActionEvents->OnUnloadComplete();
  475.                                 UpdateFG();
  476.  
  477.                         }
  478.                         m_systemState = eSS_NoLevel;
  479.                 }
  480.                 break;
  481.  
  482.         case ESYSTEM_EVENT_LEVEL_LOAD_END:
  483.                 {
  484.                         StopRenderThread();
  485.  
  486.                         if (m_systemState == eSS_Loading)
  487.                         {
  488.                                 m_pFlashUIActionEvents->OnLoadingComplete();
  489.                                 UpdateFG();
  490.                         }
  491.  
  492.                         ILevelInfo* pLevel = gEnv->pGameFramework->GetILevelSystem()->GetCurrentLevel();
  493.                         PreloadTextures(pLevel ? pLevel->GetName() : "");
  494.  
  495.                         m_systemState = eSS_LoadingDone;
  496.  
  497.                         gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_GAMEPLAY_START, 0, 0);
  498.                 }
  499.                 break;
  500.  
  501.         case ESYSTEM_EVENT_FRONTEND_RELOADED:
  502.                 {
  503.                         m_pFlashUIActionEvents->OnReload();
  504.                 }
  505.                 break;
  506.         }
  507. }
  508.  
  509. //------------------------------------------------------------------------------------
  510. void CFlashUI::OnActionEvent(const SActionEvent& event)
  511. {
  512.         switch (event.m_event)
  513.         {
  514.         case eAE_disconnected:
  515.                 {
  516.                         m_pFlashUIActionEvents->OnDisconnect(event.m_description);
  517.                         if (m_systemState == eSS_GameStarted)
  518.                                 m_pFlashUIActionEvents->OnGameplayEnded();
  519.  
  520.                         UpdateFG();
  521.                 }
  522.                 break;
  523.  
  524.         case eAE_connected:
  525.                 {
  526.                         m_pFlashUIActionEvents->OnConnect(event.m_description);
  527.                         UpdateFG();
  528.                 }
  529.                 break;
  530.         }
  531. }
  532.  
  533. //------------------------------------------------------------------------------------
  534. void CFlashUI::OnLevelNotFound(const char* levelName)
  535. {
  536.         StopRenderThread();
  537.  
  538.         if (m_systemState == eSS_Loading)
  539.         {
  540.                 string msg;
  541.                 msg.Format("Level %s not found", levelName);
  542.                 m_pFlashUIActionEvents->OnLoadingError(NULL, msg.c_str());
  543.                 UpdateFG();
  544.         }
  545.         m_systemState = eSS_NoLevel;
  546. }
  547.  
  548. //------------------------------------------------------------------------------------
  549. void CFlashUI::OnLoadingError(ILevelInfo* pLevel, const char* error)
  550. {
  551.         StopRenderThread();
  552.  
  553.         if (m_systemState == eSS_Loading)
  554.         {
  555.                 m_pFlashUIActionEvents->OnLoadingError(pLevel, error);
  556.                 UpdateFG();
  557.         }
  558.         m_systemState = eSS_NoLevel;
  559. }
  560.  
  561. //------------------------------------------------------------------------------------
  562. void CFlashUI::OnLoadingProgress(ILevelInfo* pLevel, int progressAmount)
  563. {
  564.         if (m_systemState == eSS_Loading)
  565.         {
  566.                 if (CV_gfx_loadtimethread == 0 && m_bLoadtimeThread == false)
  567.                 {
  568.                         uint32 nRecursionLevel = 0;
  569.                         gEnv->pRenderer->EF_Query(EFQ_RecurseLevel, nRecursionLevel);
  570.                         const bool bStandAlone = (nRecursionLevel <= 0);
  571.                         if (bStandAlone)
  572.                                 gEnv->pSystem->RenderBegin();
  573.  
  574.                         const float currTime = gEnv->pTimer->GetAsyncCurTime();
  575.                         OnPostUpdate(currTime - m_fLastAdvance);
  576.                         m_fLastAdvance = currTime;
  577.  
  578.                         if (bStandAlone)
  579.                                 gEnv->pSystem->RenderEnd();
  580.                 }
  581.                 m_pFlashUIActionEvents->OnLoadingProgress(pLevel, progressAmount);
  582.                 UpdateFG();
  583.         }
  584. }
  585.  
  586. //------------------------------------------------------------------------------------
  587. void CFlashUI::LoadtimeUpdate(float fDeltaTime)
  588. {
  589.         LOADING_TIME_PROFILE_SECTION
  590.  
  591.         if (m_bSortedElementsInvalidated)
  592.         {
  593.                 for (TPlayerList::const_iterator it = m_loadtimePlayerList.begin(); it != m_loadtimePlayerList.end(); ++it)
  594.                 {
  595.                         IFlashPlayer* pPlayer = *it;
  596.                         pPlayer->Release();
  597.                 }
  598.                 m_loadtimePlayerList.clear();
  599.  
  600.                 for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  601.                 {
  602.                         IUIElementIteratorPtr instances = (*iter)->GetInstances();
  603.                         while (IUIElement* pInstance = instances->Next())
  604.                         {
  605.                                 if (pInstance->IsVisible())
  606.                                 {
  607.                                         IFlashPlayer* pPlayer = pInstance->GetFlashPlayer();
  608.                                         pPlayer->AddRef();
  609.                                         m_loadtimePlayerList.push_back(pPlayer);
  610.                                 }
  611.                         }
  612.                 }
  613.  
  614.                 m_bSortedElementsInvalidated = false;
  615.         }
  616.  
  617.         for (TPlayerList::const_iterator it = m_loadtimePlayerList.begin(); it != m_loadtimePlayerList.end(); ++it)
  618.         {
  619.                 (*it)->Advance(fDeltaTime);
  620.         }
  621.  
  622.         if (IHmdManager* pHmdManager = gEnv->pSystem->GetHmdManager())
  623.         {
  624.                 pHmdManager->UpdateTracking(eVRComponent_Hmd);
  625.         }
  626. }
  627.  
  628. //------------------------------------------------------------------------------------
  629. void CFlashUI::LoadtimeRender()
  630. {
  631.         LOADING_TIME_PROFILE_SECTION
  632.  
  633.         gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR);
  634.  
  635.         if (CV_gfx_draw == 1)
  636.         {
  637.                 if (IStereoRenderer* pStereoRenderer = gEnv->pRenderer->GetIStereoRenderer())
  638.                 {
  639.                         if (IHmdRenderer* pHmdRender = pStereoRenderer->GetIHmdRenderer())
  640.                         {
  641.                                 pHmdRender->PrepareFrame();
  642.                         }
  643.                 }
  644.  
  645.                 for (TPlayerList::const_iterator it = m_loadtimePlayerList.begin(); it != m_loadtimePlayerList.end(); ++it)
  646.                 {
  647.                         (*it)->Render(gEnv->pRenderer->IsStereoEnabled());
  648.                 }
  649.         }
  650. }
  651.  
  652. //------------------------------------------------------------------------------------
  653. #ifdef ENABLE_UISTACK_DEBUGGING
  654.         #define DEBUG_FLUSH_STACK(loop)      RenderStackDebugInfo(true, "Finished", loop);
  655.         #define DEBUG_ADD_STACK(label, loop) RenderStackDebugInfo(false, label, loop);
  656. #else
  657.         #define DEBUG_FLUSH_STACK
  658.         #define DEBUG_ADD_STACK(label, loop)
  659. #endif
  660. void CFlashUI::UpdateFG()
  661. {
  662.         LOADING_TIME_PROFILE_SECTION;
  663.  
  664.         static bool isUpdating = false;
  665.         CRY_ASSERT_MESSAGE(!isUpdating, "Recursive loop: trying to update UIAction FlowGraphs within update loop!");
  666.         if (!isUpdating)
  667.         {
  668.                 isUpdating = true;
  669.                 int loops = 0;
  670.                 do
  671.                 {
  672.                         m_pUIActionManager->Update();// preupdate
  673.                         DEBUG_ADD_STACK("Events and Actions", loops);
  674.  
  675.                         int i = 0;
  676.                         while (CFlashUIAction* pAction = (CFlashUIAction*)GetUIAction(i++))
  677.                         {
  678.                                 pAction->Update();
  679.                                 if (CV_gfx_debugdraw & 8)
  680.                                 {
  681.                                         DEBUG_ADD_STACK(string().Format("FG %s", pAction->GetName()), loops);
  682.                                 }
  683.                         }
  684.                         if (!(CV_gfx_debugdraw & 8))
  685.                         {
  686.                                 DEBUG_ADD_STACK("Flowgraphs", loops);
  687.                         }
  688.  
  689.                         m_pUIActionManager->Update();// post update
  690.                         DEBUG_ADD_STACK("PostUpdate", loops);
  691.  
  692.                         if (++loops > 255)
  693.                         {
  694.                                 CRY_ASSERT_MESSAGE(false, "stack constantly gets new events within this update loop, should not happen!");
  695.                                 UIACTION_ERROR("Some UIActions are causing infinitive loop!");
  696.                                 break;
  697.                         }
  698.                 }
  699.                 while (CUIFGStackMan::GetTotalStackSize() > 0);
  700.                 DEBUG_FLUSH_STACK(loops);
  701.                 isUpdating = false;
  702.         }
  703. }
  704.  
  705. //------------------------------------------------------------------------------------
  706. void CFlashUI::EnableEventStack(bool bEnable)
  707. {
  708.         CRY_ASSERT_MESSAGE(gEnv->IsEditor(), "Only allowed for editor!");
  709.         if (gEnv->IsEditor())
  710.         {
  711.                 CUIFGStackMan::SetEnabled(bEnable);
  712.         }
  713. }
  714.  
  715. //------------------------------------------------------------------------------------
  716. void CFlashUI::RegisterModule(IUIModule* pModule, const char* name)
  717. {
  718.         const bool ok = m_modules.Add(pModule, name);
  719.         CRY_ASSERT_MESSAGE(ok, "Module already registered!");
  720. }
  721.  
  722. //------------------------------------------------------------------------------------
  723. void CFlashUI::UnregisterModule(IUIModule* pModule)
  724. {
  725.         CRY_ASSERT_MESSAGE(m_modules.Contains(pModule), "Module was never registered or already unregistered!");
  726.         m_modules.Remove(pModule);
  727. }
  728.  
  729. void CFlashUI::SetHudElementsVisible(bool bVisible)
  730. {
  731.         ICVar* pHudHidden = gEnv->pConsole->GetCVar("hud_hide");
  732.         if (!pHudHidden)
  733.         {
  734.                 m_bHudVisible = bVisible;
  735.         }
  736.         else
  737.         {
  738.                 bool bHudHideOverride = pHudHidden->GetIVal() > 0;
  739.                 if (bHudHideOverride)
  740.                 {
  741.                         m_bHudVisible = false;
  742.                 }
  743.                 else
  744.                 {
  745.                         m_bHudVisible = bVisible;
  746.                 }
  747.         }
  748. }
  749.  
  750. //-------------------------------------------------------------------
  751. void CFlashUI::OnHardwareMouseEvent(int iX, int iY, EHARDWAREMOUSEEVENT eHardwareMouseEvent, int wheelDelta)
  752. {
  753.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  754.  
  755.         if (gEnv->pConsole->GetStatus())   // disable UI inputs when console is open
  756.                 return;
  757.         int iButton = 0;
  758.         SFlashCursorEvent::ECursorState evt;
  759.         switch (eHardwareMouseEvent)
  760.         {
  761.         case HARDWAREMOUSEEVENT_RBUTTONDOWN:
  762.                 iButton = 1;
  763.         case HARDWAREMOUSEEVENT_LBUTTONDOWN:
  764.                 evt = SFlashCursorEvent::eCursorPressed;
  765.                 break;
  766.         case HARDWAREMOUSEEVENT_RBUTTONUP:
  767.         case HARDWAREMOUSEEVENT_RBUTTONDOUBLECLICK: // IFlashPlayer does not support double click atm
  768.                 iButton = 1;
  769.         case HARDWAREMOUSEEVENT_LBUTTONUP:
  770.         case HARDWAREMOUSEEVENT_LBUTTONDOUBLECLICK: // IFlashPlayer does not support double click atm
  771.                 evt = SFlashCursorEvent::eCursorReleased;
  772.                 break;
  773.         case HARDWAREMOUSEEVENT_MOVE:
  774.                 evt = SFlashCursorEvent::eCursorMoved;
  775.                 break;
  776.         case HARDWAREMOUSEEVENT_WHEEL:
  777.                 evt = SFlashCursorEvent::eWheel;
  778.                 break;
  779.         default:
  780.                 return;
  781.         }
  782.         SendFlashMouseEvent(evt, iX, iY, iButton, wheelDelta / 120.0f);
  783. }
  784.  
  785. //-------------------------------------------------------------------
  786. bool CFlashUI::OnInputEvent(const SInputEvent& event)
  787. {
  788.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  789.  
  790.         if (gEnv->pConsole->GetStatus())   // disable UI inputs when console is open
  791.                 return false;
  792.  
  793.         if (event.state == eIS_Down)
  794.         {
  795.                 switch (event.keyId)
  796.                 {
  797.                 case eKI_LShift:
  798.                 case eKI_RShift:
  799.                 case eKI_LAlt:
  800.                 case eKI_RAlt:
  801.                 case eKI_LCtrl:
  802.                 case eKI_RCtrl:
  803.                         break;
  804.                 default:
  805.                         TriggerEvent(event);
  806.                 }
  807.                 return false;
  808.         }
  809.  
  810.         if (event.state == eIS_Pressed || event.state == eIS_Released)
  811.         {
  812.                 m_lastTimeTriggered = gEnv->pTimer->GetAsyncCurTime() + CV_gfx_inputevents_triggerstart;
  813.  
  814.                 SFlashKeyEvent evt = MapToFlashKeyEvent(event);
  815.  
  816.                 const TSortedElementList& sortedElements = GetSortedElements();
  817.  
  818.                 for (TSortedElementList::const_reverse_iterator iter = sortedElements.rbegin(); iter != sortedElements.rend(); ++iter)
  819.                 {
  820.                         if (iter->second->HasFlag(IUIElement::eFUI_KEYEVENTS))
  821.                         {
  822.                                 iter->second->SendKeyEvent(evt);
  823.                                 if (iter->second->HasFlag(IUIElement::eFUI_EVENTS_EXCLUSIVE))
  824.                                         return false;
  825.                         }
  826.                 }
  827.         }
  828.         return false;
  829. }
  830.  
  831. //------------------------------------------------------------------------------------
  832. bool CFlashUI::OnInputEventUI(const SUnicodeEvent& event)
  833. {
  834.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  835.  
  836.         if (gEnv->pConsole->GetStatus())   // disable UI inputs when console is open
  837.                 return false;
  838.  
  839.         SFlashCharEvent charEvent(event.inputChar);
  840.         const TSortedElementList& sortedElements = GetSortedElements();
  841.  
  842.         for (TSortedElementList::const_reverse_iterator iter = sortedElements.rbegin(); iter != sortedElements.rend(); ++iter)
  843.         {
  844.                 if (iter->second->HasFlag(IUIElement::eFUI_KEYEVENTS))
  845.                 {
  846.                         iter->second->SendCharEvent(charEvent);
  847.                         if (iter->second->HasFlag(IUIElement::eFUI_EVENTS_EXCLUSIVE))
  848.                                 return false;
  849.                 }
  850.         }
  851.         return false;
  852. }
  853.  
  854. //-------------------------------------------------------------------
  855. void CFlashUI::TriggerEvent(const SInputEvent& event)
  856. {
  857.         const float currtime = gEnv->pTimer->GetAsyncCurTime();
  858.         if (currtime > m_lastTimeTriggered + CV_gfx_inputevents_triggerrepeat)
  859.         {
  860.                 SInputEvent evt = event;
  861.                 evt.state = eIS_Released;
  862.                 OnInputEvent(evt);
  863.                 evt.state = eIS_Pressed;
  864.                 OnInputEvent(evt);
  865.                 m_lastTimeTriggered = currtime;
  866.         }
  867. }
  868.  
  869. //-------------------------------------------------------------------
  870. void CFlashUI::DispatchControllerEvent(IUIElement::EControllerInputEvent event, IUIElement::EControllerInputState state, float value)
  871. {
  872.         if (IsVirtualKeyboardRunning()) return;
  873.  
  874.         if (event == IUIElement::eCIE_Action)
  875.         {
  876.                 CreateMouseClick(state);
  877.         }
  878.  
  879.         const TSortedElementList& sortedElements = GetSortedElements();
  880.  
  881.         for (TSortedElementList::const_reverse_iterator iter = sortedElements.rbegin(); iter != sortedElements.rend(); ++iter)
  882.         {
  883.                 if (iter->second->HasFlag(IUIElement::eFUI_CONTROLLER_INPUT) && !iter->second->IsHiding())
  884.                 {
  885.                         iter->second->SendControllerEvent(event, state, value);
  886.                         if (iter->second->HasFlag(IUIElement::eFUI_EVENTS_EXCLUSIVE))
  887.                                 return;
  888.                 }
  889.         }
  890. }
  891.  
  892. //-------------------------------------------------------------------
  893. void CFlashUI::CreateMouseClick(IUIElement::EControllerInputState state)
  894. {
  895.         SFlashCursorEvent::ECursorState evt;
  896.  
  897.         switch (state)
  898.         {
  899.         case IUIElement::eCIS_OnPress:
  900.                 evt = SFlashCursorEvent::eCursorPressed;
  901.                 break;
  902.         case IUIElement::eCIS_OnRelease:
  903.                 evt = SFlashCursorEvent::eCursorReleased;
  904.                 break;
  905.         default:
  906.                 return;
  907.         }
  908.  
  909.         float fX, fY;
  910.         gEnv->pHardwareMouse->GetHardwareMouseClientPosition(&fX, &fY);
  911.         SendFlashMouseEvent(evt, (int) fX, (int) fY, 0, 0.f, true);
  912. }
  913.  
  914. //-------------------------------------------------------------------
  915. void CFlashUI::SendFlashMouseEvent(SFlashCursorEvent::ECursorState evt, int iX, int iY, int iButton /*= 0*/, float fWheel /*= 0.f*/, bool bFromController /*= false*/)
  916. {
  917.         const TSortedElementList& sortedElements = GetSortedElements();
  918.  
  919.         for (TSortedElementList::const_reverse_iterator iter = sortedElements.rbegin(); iter != sortedElements.rend(); ++iter)
  920.         {
  921.                 if (iter->second->HasFlag(IUIElement::eFUI_MOUSEEVENTS) && (!bFromController || !iter->second->HasFlag(IUIElement::eFUI_CONTROLLER_INPUT))
  922. #if !CRY_PLATFORM_DESKTOP
  923.                     && iter->second->HasFlag(IUIElement::eFUI_CONSOLE_MOUSE)
  924. #elif !defined(_RELEASE)
  925.                     && (!gEnv->IsEditor() || GetCurrentPlatform() == IFlashUI::ePUI_PC || iter->second->HasFlag(IUIElement::eFUI_CONSOLE_MOUSE))
  926. #endif
  927.                     && !iter->second->IsHiding())
  928.                 {
  929.                         iter->second->SendCursorEvent(evt, iX, iY, iButton, fWheel);
  930.                         if (iter->second->HasFlag(IUIElement::eFUI_EVENTS_EXCLUSIVE))
  931.                                 return;
  932.                 }
  933.         }
  934. }
  935.  
  936. //-------------------------------------------------------------------
  937. bool CFlashUI::DisplayVirtualKeyboard(unsigned int flags, const char* title, const char* initialInput, int maxInputLength, IVirtualKeyboardEvents* pInCallback)
  938. {
  939.         IPlatformOS* pPlatformOS = gEnv->pSystem->GetPlatformOS();
  940.         if (pPlatformOS && gEnv->pGameFramework)
  941.         {
  942.                 unsigned int controllerIdx = gEnv->pGameFramework->GetIPlayerProfileManager()->GetExclusiveControllerDeviceIndex();
  943.                 if (controllerIdx != INVALID_CONTROLLER_INDEX)
  944.                         return pPlatformOS->KeyboardStart(controllerIdx, flags, title, initialInput, maxInputLength, pInCallback);
  945.         }
  946.         return false;
  947. }
  948.  
  949. //-------------------------------------------------------------------
  950. bool CFlashUI::IsVirtualKeyboardRunning()
  951. {
  952.         IPlatformOS* pPlatformOS = gEnv->pSystem->GetPlatformOS();
  953.         if (pPlatformOS)
  954.         {
  955.                 return pPlatformOS->KeyboardIsRunning();
  956.         }
  957.         return false;
  958. }
  959.  
  960. //-------------------------------------------------------------------
  961. bool CFlashUI::CancelVirtualKeyboard()
  962. {
  963.         IPlatformOS* pPlatformOS = gEnv->pSystem->GetPlatformOS();
  964.         if (pPlatformOS)
  965.         {
  966.                 return pPlatformOS->KeyboardCancel();
  967.         }
  968.         return false;
  969. }
  970.  
  971. //-------------------------------------------------------------------
  972. IUIActionManager* CFlashUI::GetUIActionManager() const
  973. {
  974.         return m_pUIActionManager;
  975. }
  976.  
  977. //-------------------------------------------------------------------
  978. void CFlashUI::LoadElements()
  979. {
  980.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  981.                 ((CFlashUIElement*)*iter)->SetValid(false);
  982.  
  983.         string folder;
  984.         folder.Format("%s/%s", CV_gfx_uiaction_folder->GetString(), FLASH_UIELEMENTS_FOLDER);
  985.         LoadFromFile(folder.c_str(), "*.xml", &CFlashUI::LoadElementsFromFile);
  986.         InvalidateSortedElements();
  987.  
  988.         //Reset the dirty flags so we don't
  989.         //unload what we are about to load
  990.         ResetDirtyFlags();
  991. }
  992.  
  993. //-------------------------------------------------------------------
  994. void CFlashUI::LoadActions()
  995. {
  996.         for (TUIActionsLookup::iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  997.                 ((CFlashUIAction*)*iter)->SetValid(false);
  998.  
  999.         string folder;
  1000.         folder.Format("%s/%s", CV_gfx_uiaction_folder->GetString(), FLASH_UIACTION_FOLDER);
  1001.         LoadFromFile(folder.c_str(), "*.xml", &CFlashUI::LoadFGActionFromFile);
  1002.         LoadFromFile(folder.c_str(), "*.lua", &CFlashUI::LoadLuaActionFromFile);
  1003. }
  1004.  
  1005. //-------------------------------------------------------------------
  1006. template<EUIObjectType T> bool IsTemplate()                     { return false; }
  1007. template<> bool                IsTemplate<eUOT_MovieClipTmpl>() { return true; }
  1008.  
  1009. template<EUIObjectType Type, class Item>
  1010. void CreateMCFunctionNodes(CFlashUI::TUIFlowNodes& nodelist, IUIElement* pElement, Item* pItem, const string& path, bool fill = false)
  1011. {
  1012.         // prevent to fill "first row"
  1013.         if (fill)
  1014.         {
  1015.                 const int fctcount = SUIGetDesc<eUOT_Functions, Item, int>::GetCount(pItem);
  1016.                 for (int i = 0; i < fctcount; ++i)
  1017.                 {
  1018.                         const SUIEventDesc* pDesc = SUIGetDesc<eUOT_Functions, Item, int>::GetDesc(pItem, i);
  1019.  
  1020.                         string category = path;
  1021.                         category += ":";
  1022.                         category += pDesc->sDisplayName;
  1023.  
  1024.                         CFlashUIFunctionNode* pNode = new CFlashUIFunctionNode(pElement, category, pDesc, IsTemplate<Type>());
  1025.                         CAutoRegUIFlowNode* pFlowNode = new CAutoRegUIFlowNode(pNode->GetCategory(), pNode);
  1026.                         nodelist.push_back(pFlowNode);
  1027.                 }
  1028.         }
  1029.  
  1030.         const int subcount = SUIGetDesc<Type, Item, int>::GetCount(pItem);
  1031.         for (int i = 0; i < subcount; ++i)
  1032.         {
  1033.                 const SUIMovieClipDesc* pDesc = SUIGetDesc<Type, Item, int>::GetDesc(pItem, i);
  1034.                 string newpath = path;
  1035.                 newpath += ":";
  1036.                 newpath += pDesc->sDisplayName;
  1037.                 CreateMCFunctionNodes<eUOT_MovieClip>(nodelist, pElement, pDesc, newpath, true);
  1038.         }
  1039. }
  1040.  
  1041. //-------------------------------------------------------------------
  1042. void CFlashUI::CreateNodes()
  1043. {
  1044.         // create element nodes
  1045.         ClearNodes();
  1046.  
  1047.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  1048.         {
  1049.                 if (!(*iter)->IsValid()) continue;
  1050.  
  1051.                 int i = 0;
  1052.                 while (const SUIEventDesc* pDesc = (*iter)->GetEventDesc(i++))
  1053.                 {
  1054.                         CFlashUIEventNode* pNode = new CFlashUIEventNode(*iter, CreateDisplayName("UI:Events:%s:%s", (*iter)->GetName(), pDesc->sDisplayName), pDesc);
  1055.                         CAutoRegUIFlowNode* pFlowNode = new CAutoRegUIFlowNode(pNode->GetCategory(), pNode);
  1056.                         m_UINodes.push_back(pFlowNode);
  1057.                 }
  1058.                 i = 0;
  1059.                 while (const SUIEventDesc* pDesc = (*iter)->GetFunctionDesc(i++))
  1060.                 {
  1061.                         CFlashUIFunctionNode* pNode = new CFlashUIFunctionNode(*iter, CreateDisplayName("UI:Functions:%s:%s", (*iter)->GetName(), pDesc->sDisplayName), pDesc, false);
  1062.                         CAutoRegUIFlowNode* pFlowNode = new CAutoRegUIFlowNode(pNode->GetCategory(), pNode);
  1063.                         m_UINodes.push_back(pFlowNode);
  1064.                 }
  1065.  
  1066.                 CreateMCFunctionNodes<eUOT_MovieClip>(m_UINodes, *iter, *iter, CreateDisplayName("UI:Functions:%s", (*iter)->GetName()));
  1067.                 CreateMCFunctionNodes<eUOT_MovieClipTmpl>(m_UINodes, *iter, *iter, CreateDisplayName("UI:Template:Functions:%s", (*iter)->GetName()));
  1068.         }
  1069.  
  1070.         // create event system nodes for eEST_SYSTEM_TO_UI
  1071.         IUIEventSystemIteratorPtr eventIter = CreateEventSystemIterator(IUIEventSystem::eEST_SYSTEM_TO_UI);
  1072.         string name;
  1073.         while (IUIEventSystem* pEventSystem = eventIter->Next(name))
  1074.         {
  1075.                 int i = 0;
  1076.                 while (const SUIEventDesc* pDesc = pEventSystem->GetEventDesc(i++))
  1077.                 {
  1078.                         CFlashUIBaseNodeCategory* pNode = new CFlashUIEventSystemEventNode(pEventSystem, CreateDisplayName("UI:Events:%s:%s", name.c_str(), pDesc->sDisplayName), pDesc);
  1079.                         CAutoRegUIFlowNode* pFlowNode = new CAutoRegUIFlowNode(pNode->GetCategory(), pNode);
  1080.                         m_UINodes.push_back(pFlowNode);
  1081.                 }
  1082.         }
  1083.  
  1084.         // create event system nodes for eEST_UI_TO_SYSTEM
  1085.         eventIter = CreateEventSystemIterator(IUIEventSystem::eEST_UI_TO_SYSTEM);
  1086.         while (IUIEventSystem* pEventSystem = eventIter->Next(name))
  1087.         {
  1088.                 int i = 0;
  1089.                 while (const SUIEventDesc* pDesc = pEventSystem->GetEventDesc(i++))
  1090.                 {
  1091.                         CFlashUIBaseNodeCategory* pNode = new CFlashUIEventSystemFunctionNode(pEventSystem, CreateDisplayName("UI:Functions:%s:%s", name.c_str(), pDesc->sDisplayName), pDesc);
  1092.                         CAutoRegUIFlowNode* pFlowNode = new CAutoRegUIFlowNode(pNode->GetCategory(), pNode);
  1093.                         m_UINodes.push_back(pFlowNode);
  1094.                 }
  1095.         }
  1096. }
  1097.  
  1098. //-------------------------------------------------------------------
  1099. bool CFlashUI::LoadElementsFromFile(const char* sFileName)
  1100. {
  1101.         UIACTION_LOG("FlashUI parse element XML file %s", sFileName);
  1102.         XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(sFileName);
  1103.         if (xmlNode)
  1104.         {
  1105.                 const char* groupname = xmlNode->getAttr("name");
  1106.  
  1107.                 for (int i = 0; i < xmlNode->getChildCount(); ++i)
  1108.                 {
  1109.                         XmlNodeRef element = xmlNode->getChild(i);
  1110.  
  1111.                         const char* name = element->getAttr("name");
  1112.                         if (name == NULL) continue;
  1113.  
  1114.                         IUIElement* pElement = GetUIElement(name);
  1115.                         if (!pElement)
  1116.                         {
  1117.                                 UIACTION_LOG("FlashUI create UIElement %s", name);
  1118.                                 pElement = new CFlashUIElement(this);
  1119.                                 pElement->SetName(name);
  1120.                                 m_elements.push_back(pElement);
  1121.                         }
  1122.                         UIACTION_LOG("FlashUI read UIElement %s from xml %s", name, sFileName);
  1123.                         if (!pElement->Serialize(element, true))
  1124.                         {
  1125.                                 UIACTION_ERROR("FlashUI failed to load UIElement %s from xml %s", name, sFileName);
  1126.                                 return false;
  1127.                         }
  1128.  
  1129.                         pElement->SetGroupName(groupname ? groupname : "");
  1130.                 }
  1131.                 return true;
  1132.         }
  1133.  
  1134.         UIACTION_ERROR("Error in element xml file %s", sFileName);
  1135.         return false;
  1136. }
  1137.  
  1138. //-------------------------------------------------------------------
  1139. bool CFlashUI::LoadActionFromFile(const char* sFileName, IUIAction::EUIActionType type)
  1140. {
  1141.         switch (type)
  1142.         {
  1143.         case IUIAction::eUIAT_FlowGraph:
  1144.                 return LoadFGActionFromFile(sFileName);
  1145.         case IUIAction::eUIAT_LuaScript:
  1146.                 return LoadLuaActionFromFile(sFileName);
  1147.         }
  1148.         return false;
  1149. }
  1150. //-------------------------------------------------------------------
  1151. bool CFlashUI::LoadFGActionFromFile(const char* sFileName)
  1152. {
  1153.         XmlNodeRef root = GetISystem()->LoadXmlFromFile(sFileName);
  1154.         if (root)
  1155.         {
  1156.                 IUIAction* pAction = GetUIAction(PathUtil::GetFileName(sFileName));
  1157.                 if (!pAction)
  1158.                 {
  1159.                         UIACTION_LOG("FlashUI create FG UIAction from xml %s", sFileName);
  1160.                         pAction = new CFlashUIAction(IUIAction::eUIAT_FlowGraph);
  1161.                         pAction->SetName(PathUtil::GetFileName(sFileName));
  1162.                         m_actions.push_back(pAction);
  1163.                 }
  1164.                 if (pAction->GetType() == IUIAction::eUIAT_FlowGraph)
  1165.                 {
  1166.                         UIACTION_LOG("FlashUI read FG UIAction from xml %s", sFileName);
  1167.                         if (!pAction->Serialize(root, true))
  1168.                         {
  1169.                                 UIACTION_ERROR("FlashUI failed to load FG UIAction from xml %s", sFileName);
  1170.                                 return false;
  1171.                         }
  1172.                 }
  1173.                 else
  1174.                 {
  1175.                         UIACTION_ERROR("FlashUI try to load UIAction FlowGraph from xml %s but Lua UI Action already exist with same name!", sFileName);
  1176.                         return false;
  1177.                 }
  1178.                 return true;
  1179.         }
  1180.         UIACTION_ERROR("Error in ui action xml file %s", sFileName);
  1181.         return false;
  1182. }
  1183.  
  1184. //-------------------------------------------------------------------
  1185. bool CFlashUI::LoadLuaActionFromFile(const char* sFileName)
  1186. {
  1187.         IUIAction* pAction = GetUIAction(PathUtil::GetFileName(sFileName));
  1188.         if (!pAction)
  1189.         {
  1190.                 UIACTION_LOG("FlashUI create Lua UIAction from lau %s", sFileName);
  1191.                 pAction = new CFlashUIAction(IUIAction::eUIAT_LuaScript);
  1192.                 pAction->SetName(PathUtil::GetFileName(sFileName));
  1193.                 m_actions.push_back(pAction);
  1194.         }
  1195.         if (pAction->GetType() == IUIAction::eUIAT_LuaScript)
  1196.         {
  1197.                 UIACTION_LOG("FlashUI read Lua UIAction from xml %s", sFileName);
  1198.                 if (!pAction->Serialize(sFileName, true))
  1199.                 {
  1200.                         UIACTION_ERROR("FlashUI failed to load Lua UIAction from script %s", sFileName);
  1201.                         return false;
  1202.                 }
  1203.         }
  1204.         else
  1205.         {
  1206.                 UIACTION_ERROR("FlashUI try to load UIAction Lua script %s but Flowgraph UI Action already exist with same name!", sFileName);
  1207.                 return false;
  1208.         }
  1209.         return true;
  1210. }
  1211.  
  1212. //-------------------------------------------------------------------
  1213. void CFlashUI::ClearElements()
  1214. {
  1215.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  1216.                 delete *iter;
  1217.  
  1218.         m_elements.clear();
  1219. }
  1220.  
  1221. //-------------------------------------------------------------------
  1222. void CFlashUI::ClearActions()
  1223. {
  1224.         m_pUIActionManager->Init();
  1225.  
  1226.         for (TUIActionsLookup::iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  1227.                 delete *iter;
  1228.  
  1229.         m_actions.clear();
  1230. }
  1231.  
  1232. //-------------------------------------------------------------------
  1233. void CFlashUI::ResetActions()
  1234. {
  1235.         m_pUIActionManager->Init();
  1236.         for (TUIActionsLookup::iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  1237.         {
  1238.                 (*iter)->Init();
  1239.         }
  1240. }
  1241.  
  1242. //-------------------------------------------------------------------
  1243. void CFlashUI::ReloadScripts()
  1244. {
  1245.         for (TUIActionsLookup::iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  1246.         {
  1247.                 CFlashUIAction* pAction = (CFlashUIAction*)*iter;
  1248.                 pAction->ReloadScript();
  1249.         }
  1250. }
  1251.  
  1252. //-------------------------------------------------------------------
  1253. void CFlashUI::ClearNodes()
  1254. {
  1255.         for (TUIFlowNodes::iterator iter = m_UINodes.begin(); iter != m_UINodes.end(); ++iter)
  1256.                 SAFE_RELEASE(*iter);
  1257.  
  1258.         m_UINodes.clear();
  1259. }
  1260.  
  1261. //-------------------------------------------------------------------
  1262. void CFlashUI::LoadFromFile(const char* pFolderName, const char* pSearch, bool (CFlashUI::* fhFileLoader)(const char*))
  1263. {
  1264.         ICryPak* pCryPak = gEnv->pCryPak;
  1265.         _finddata_t fd;
  1266.         char filename[_MAX_PATH];
  1267.  
  1268.         string search = string(pFolderName) + "/";
  1269.         search += pSearch;
  1270.         intptr_t handle = pCryPak->FindFirst(search.c_str(), &fd);
  1271.         if (handle != -1)
  1272.         {
  1273.                 int res = 0;
  1274.                 do
  1275.                 {
  1276.                         cry_strcpy(filename, pFolderName);
  1277.                         cry_strcat(filename, "/");
  1278.                         cry_strcat(filename, fd.name);
  1279.  
  1280.                         (this->*fhFileLoader)(filename);
  1281.  
  1282.                         res = pCryPak->FindNext(handle, &fd);
  1283.                 }
  1284.                 while (res >= 0);
  1285.                 pCryPak->FindClose(handle);
  1286.         }
  1287. }
  1288.  
  1289. //-------------------------------------------------------------------
  1290. void CFlashUI::PreloadTextures(const char* pLevelName)
  1291. {
  1292.         LOADING_TIME_PROFILE_SECTION;
  1293.  
  1294.         ReleasePreloadedTextures(false);
  1295.  
  1296.         string file;
  1297.         file.Format("%s/%s", CV_gfx_uiaction_folder->GetString(), FLASH_PRELOAD_XML);
  1298.         if (!gEnv->pCryPak->IsFileExist(file))
  1299.                 return;
  1300.  
  1301.         XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(file.c_str());
  1302.  
  1303.         string XMLLevelName(pLevelName);
  1304.         XMLLevelName.replace("/", "_");
  1305.  
  1306.         if (xmlNode)
  1307.         {
  1308.                 XmlNodeRef commonNode = xmlNode->findChild("common");
  1309.                 PreloadTexturesFromNode(commonNode);
  1310.                 if (pLevelName)
  1311.                 {
  1312.                         XmlNodeRef levels = xmlNode->findChild("levels");
  1313.                         if (levels)
  1314.                         {
  1315.                                 XmlNodeRef commonLevelNode = levels->findChild("common");
  1316.                                 PreloadTexturesFromNode(commonLevelNode);
  1317.                                 XmlNodeRef levelNode = levels->findChild(XMLLevelName.c_str());
  1318.                                 PreloadTexturesFromNode(levelNode);
  1319.                         }
  1320.                 }
  1321.                 else
  1322.                 {
  1323.                         XmlNodeRef levelNode = xmlNode->findChild("nolevel");
  1324.                         PreloadTexturesFromNode(levelNode);
  1325.                 }
  1326.         }
  1327. }
  1328.  
  1329. void CFlashUI::PreloadTexturesFromNode(const XmlNodeRef& node)
  1330. {
  1331.         if (node)
  1332.         {
  1333.                 for (int i = 0; i < node->getChildCount(); ++i)
  1334.                 {
  1335.                         const char* pFile = node->getChild(i)->getAttr("file");
  1336.                         if (pFile)
  1337.                         {
  1338.                                 string path = PathUtil::GetPathWithoutFilename(pFile);
  1339.                                 string file = PathUtil::GetFile(pFile);
  1340.                                 LoadFromFile(path, file, &CFlashUI::PreloadTexture);
  1341.                         }
  1342.                 }
  1343.         }
  1344. }
  1345.  
  1346. bool CFlashUI::PreloadTexture(const char* pFileName)
  1347. {
  1348.         gEnv->pLog->UpdateLoadingScreen(0); // CFlashUI::PreloadTextures() might take a long time
  1349.                                             // poll system events here
  1350.  
  1351.         stack_string sFile = pFileName;
  1352.  
  1353.         //#if !CRY_PLATFORM_DESKTOP
  1354.         if (sFile.find(".0") != string::npos)
  1355.                 sFile = sFile.substr(0, sFile.find(".0"));
  1356.         //#endif
  1357.  
  1358.         if (sFile.find(".dds") == sFile.length() - 4
  1359.             || sFile.find(".tif") == sFile.length() - 4)
  1360.         {
  1361.                 if (gEnv && gEnv->pRenderer)
  1362.                 {
  1363.                         PathUtil::ToUnixPath(sFile);
  1364.                         while (sFile.find("//") != stack_string::npos)
  1365.                                 sFile.replace("//", "/");
  1366.  
  1367.                         ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(sFile.c_str(), FT_DONT_STREAM | FT_NOMIPS);
  1368.                         m_preloadedTextures[pTexture] = sFile.c_str();
  1369.                         UIACTION_LOG("Preload Texture: %s %s", sFile.c_str(), pTexture ? "done!" : "failed!");
  1370.                 }
  1371.         }
  1372.         return true;
  1373. }
  1374.  
  1375. //-------------------------------------------------------------------
  1376. void CFlashUI::ReleasePreloadedTextures(bool bReleaseTextures /*= true*/)
  1377. {
  1378.         if (bReleaseTextures)
  1379.         {
  1380.                 for (TTextureMap::iterator it = m_preloadedTextures.begin(); it != m_preloadedTextures.end(); ++it)
  1381.                 {
  1382.                         it->first->Release();
  1383.                 }
  1384.         }
  1385.         m_preloadedTextures.clear();
  1386.         UIACTION_LOG("Released preloaded texture");
  1387. }
  1388.  
  1389. //-------------------------------------------------------------------
  1390. bool CFlashUI::UseSharedRT(const char* instanceStr, bool defVal) const
  1391. {
  1392.         IUIElement* pElement = GetUIElementByInstanceStr(instanceStr);
  1393.         return pElement ? pElement->HasFlag(IUIElement::eFUI_SHARED_RT) : defVal;
  1394. }
  1395.  
  1396. //-------------------------------------------------------------------
  1397. void CFlashUI::CheckPreloadedTexture(ITexture* pTexture) const
  1398. {
  1399. #if defined(UIACTION_LOGGING)
  1400.         TTextureMap::const_iterator it = m_preloadedTextures.find(pTexture);
  1401.         if (it != m_preloadedTextures.end())
  1402.         {
  1403.                 UIACTION_LOG("Using preloaded texture: \"%s\"", it->second.c_str());
  1404.         }
  1405.         else
  1406.         {
  1407.                 UIACTION_WARNING("Using not preloaded Texture \"%s\"", pTexture->GetName());
  1408.         }
  1409. #endif
  1410. }
  1411.  
  1412. //-------------------------------------------------------------------
  1413. void CFlashUI::GetMemoryStatistics(ICrySizer* s) const
  1414. {
  1415.         SIZER_SUBCOMPONENT_NAME(s, "FlashUI");
  1416.         s->AddObject(this, sizeof(*this));
  1417.         s->AddContainer(m_preloadedTextures);
  1418.         s->AddContainer(m_UINodes);
  1419.  
  1420.         {
  1421.                 SIZER_SUBCOMPONENT_NAME(s, "Elements");
  1422.                 s->AddContainer(m_elements);
  1423.                 for (TUIElementsLookup::const_iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  1424.                 {
  1425.                         s->AddObject(*iter);
  1426.                 }
  1427.         }
  1428.  
  1429.         {
  1430.                 SIZER_SUBCOMPONENT_NAME(s, "Actions");
  1431.                 s->AddContainer(m_actions);
  1432.                 for (TUIActionsLookup::const_iterator iter = m_actions.begin(); iter != m_actions.end(); ++iter)
  1433.                 {
  1434.                         s->AddObject(*iter);
  1435.                 }
  1436.         }
  1437.  
  1438.         {
  1439.                 SIZER_SUBCOMPONENT_NAME(s, "EventSystems");
  1440.                 s->AddContainer(m_eventSystemsUiToSys);
  1441.                 s->AddContainer(m_eventSystemsSysToUi);
  1442.  
  1443.                 for (TUIEventSystemMap::const_iterator iter = m_eventSystemsUiToSys.begin(); iter != m_eventSystemsUiToSys.end(); ++iter)
  1444.                 {
  1445.                         s->AddObject(iter->second);
  1446.                 }
  1447.                 for (TUIEventSystemMap::const_iterator iter = m_eventSystemsSysToUi.begin(); iter != m_eventSystemsSysToUi.end(); ++iter)
  1448.                 {
  1449.                         s->AddObject(iter->second);
  1450.                 }
  1451.         }
  1452.  
  1453.         s->Add(*m_pUIActionManager);
  1454.         s->Add(*m_pFlashUIActionEvents);
  1455. }
  1456.  
  1457. //-------------------------------------------------------------------
  1458. IUIEventSystem* CFlashUI::CreateEventSystem(const char* sName, IUIEventSystem::EEventSystemType eType)
  1459. {
  1460.         IUIEventSystem* pResult = GetEventSystem(sName, eType);
  1461.         if (pResult)
  1462.                 return pResult;
  1463.  
  1464.         TUIEventSystemMap* pMap = GetEventSystemMap(eType);
  1465.         CFlashUIEventSystem* pEventSystem = new CFlashUIEventSystem(sName, eType);
  1466.         pMap->insert(std::make_pair(sName, pEventSystem));
  1467.         return pEventSystem;
  1468. }
  1469.  
  1470. //------------------------------------------------------------------------------------
  1471. IUIEventSystem* CFlashUI::GetEventSystem(const char* name, IUIEventSystem::EEventSystemType eType)
  1472. {
  1473.         TUIEventSystemMap* pMap = GetEventSystemMap(eType);
  1474.         TUIEventSystemMap::iterator it = pMap->find(name);
  1475.         if (it != pMap->end())
  1476.                 return it->second;
  1477.  
  1478.         return 0;
  1479. }
  1480.  
  1481. //------------------------------------------------------------------------------------
  1482. TUIEventSystemMap* CFlashUI::GetEventSystemMap(IUIEventSystem::EEventSystemType eType)
  1483. {
  1484.         TUIEventSystemMap* pMap = &m_eventSystemsSysToUi;
  1485.         ;
  1486.         switch (eType)
  1487.         {
  1488.         case IUIEventSystem::eEST_SYSTEM_TO_UI:
  1489.                 pMap = &m_eventSystemsSysToUi;
  1490.                 break;
  1491.         case IUIEventSystem::eEST_UI_TO_SYSTEM:
  1492.                 pMap = &m_eventSystemsUiToSys;
  1493.                 break;
  1494.         default:
  1495.                 CRY_ASSERT_MESSAGE(false, "Invalid IUIEventSystem::EEventSystemType type");
  1496.         }
  1497.         return pMap;
  1498. }
  1499.  
  1500. //------------------------------------------------------------------------------------
  1501. void CFlashUI::StartRenderThread()
  1502. {
  1503. #if defined(_RELEASE) && !CRY_PLATFORM_DESKTOP
  1504.         const bool bMultiThreaded = true;
  1505. #else
  1506.         static ICVar* pMT = gEnv->pConsole->GetCVar("r_MultiThreaded");
  1507.         const bool bMultiThreaded = pMT && pMT->GetIVal() > 0;
  1508. #endif
  1509.         static ICVar* pAsyncLoad = gEnv->pConsole->GetCVar("g_asynclevelload");
  1510.         const bool bAsyncLoad = pAsyncLoad && pAsyncLoad->GetIVal() > 0;
  1511.         if (CV_gfx_loadtimethread == 1 && !gEnv->IsEditor() && m_bLoadtimeThread == false && bMultiThreaded && !bAsyncLoad)
  1512.         {
  1513.                 const TSortedElementList& activeElements = GetSortedElements();
  1514.                 for (TSortedElementList::const_iterator it = activeElements.begin(); it != activeElements.end(); ++it)
  1515.                 {
  1516.                         IFlashPlayer* pPlayer = it->second->GetFlashPlayer();
  1517.                         pPlayer->AddRef();
  1518.                         m_loadtimePlayerList.push_back(pPlayer);
  1519.                 }
  1520.                 m_bLoadtimeThread = true;
  1521.                 gEnv->pCryPak->LockReadIO(true);
  1522.                 gEnv->pRenderer->InitSystemResources(FRR_SYSTEM_RESOURCES);
  1523.                 gEnv->pRenderer->StartLoadtimeFlashPlayback(this);
  1524.                 UIACTION_LOG("Loadtime Render Thread: Started");
  1525.         }
  1526. }
  1527.  
  1528. //------------------------------------------------------------------------------------
  1529. void CFlashUI::StopRenderThread()
  1530. {
  1531.         if (m_bLoadtimeThread == true)
  1532.         {
  1533.                 gEnv->pRenderer->StopLoadtimeFlashPlayback();
  1534.                 for (TPlayerList::const_iterator it = m_loadtimePlayerList.begin(); it != m_loadtimePlayerList.end(); ++it)
  1535.                 {
  1536.                         IFlashPlayer* pPlayer = *it;
  1537.                         pPlayer->Release();
  1538.                 }
  1539.                 m_loadtimePlayerList.clear();
  1540.                 gEnv->pCryPak->LockReadIO(false);
  1541.                 m_bLoadtimeThread = false;
  1542.                 UIACTION_LOG("Loadtime Render Thread: Stopped");
  1543.         }
  1544. }
  1545.  
  1546. //------------------------------------------------------------------------------------
  1547. IUIEventSystemIteratorPtr CFlashUI::CreateEventSystemIterator(IUIEventSystem::EEventSystemType eType)
  1548. {
  1549.         TUIEventSystemMap* pMap = GetEventSystemMap(eType);
  1550.         IUIEventSystemIteratorPtr iter = new CUIEventSystemIterator(pMap);
  1551.         iter->Release();
  1552.         return iter;
  1553. }
  1554.  
  1555. //-------------------------------------------------------------------
  1556. IUIElement* CFlashUI::GetUIElementByInstanceStr(const char* sUIInstanceStr) const
  1557. {
  1558.         assert(sUIInstanceStr != NULL);
  1559.         if (sUIInstanceStr == NULL)
  1560.                 return NULL;
  1561.  
  1562.         string tmpName(sUIInstanceStr);
  1563.         PathUtil::RemoveExtension(tmpName);
  1564.  
  1565.         char name[_MAX_PATH];
  1566.         cry_strcpy(name, tmpName.c_str());
  1567.  
  1568.         const char* pExt = PathUtil::GetExt(sUIInstanceStr);
  1569.         if (*pExt != '\0' && strcmpi(pExt, "ui"))
  1570.                 return NULL;
  1571.  
  1572.         uint instanceId = 0;
  1573.  
  1574.         int str_length = strlen(name);
  1575.         int index = 0;
  1576.         int id_index = -1;
  1577.         while (name[index] != '\0')
  1578.         {
  1579.                 if (name[index] == '@')
  1580.                 {
  1581.                         name[index] = '\0';
  1582.                         id_index = index + 1;
  1583.                 }
  1584.                 index++;
  1585.         }
  1586.         if (id_index != -1 && id_index < str_length)
  1587.         {
  1588.                 instanceId = atoi(name + id_index);
  1589.         }
  1590.  
  1591.         IUIElement* pElement = GetUIElement(name);
  1592.         if (pElement)
  1593.         {
  1594.                 pElement = pElement->GetInstance(instanceId);
  1595.         }
  1596.         return pElement;
  1597. }
  1598.  
  1599. //-------------------------------------------------------------------
  1600. SFlashKeyEvent CFlashUI::MapToFlashKeyEvent(const SInputEvent& inputEvent)
  1601. {
  1602.         SFlashKeyEvent::EKeyCode keyCode(SFlashKeyEvent::VoidSymbol);
  1603.  
  1604.         EKeyId keyId(inputEvent.keyId);
  1605.         switch (keyId)
  1606.         {
  1607.         case eKI_Backspace:
  1608.                 keyCode = SFlashKeyEvent::Backspace;
  1609.                 break;
  1610.         case eKI_Tab:
  1611.                 keyCode = SFlashKeyEvent::Tab;
  1612.                 break;
  1613.         case eKI_Enter:
  1614.                 keyCode = SFlashKeyEvent::Return;
  1615.                 break;
  1616.         case eKI_LShift:
  1617.         case eKI_RShift:
  1618.                 keyCode = SFlashKeyEvent::Shift;
  1619.                 break;
  1620.         case eKI_LCtrl:
  1621.         case eKI_RCtrl:
  1622.                 keyCode = SFlashKeyEvent::Control;
  1623.                 break;
  1624.         case eKI_LAlt:
  1625.         case eKI_RAlt:
  1626.                 keyCode = SFlashKeyEvent::Alt;
  1627.                 break;
  1628.         case eKI_Escape:
  1629.                 keyCode = SFlashKeyEvent::Escape;
  1630.                 break;
  1631.         case eKI_PgUp:
  1632.                 keyCode = SFlashKeyEvent::PageUp;
  1633.                 break;
  1634.         case eKI_PgDn:
  1635.                 keyCode = SFlashKeyEvent::PageDown;
  1636.                 break;
  1637.         case eKI_End:
  1638.                 keyCode = SFlashKeyEvent::End;
  1639.                 break;
  1640.         case eKI_Home:
  1641.                 keyCode = SFlashKeyEvent::Home;
  1642.                 break;
  1643.         case eKI_Left:
  1644.                 keyCode = SFlashKeyEvent::Left;
  1645.                 break;
  1646.         case eKI_Up:
  1647.                 keyCode = SFlashKeyEvent::Up;
  1648.                 break;
  1649.         case eKI_Right:
  1650.                 keyCode = SFlashKeyEvent::Right;
  1651.                 break;
  1652.         case eKI_Down:
  1653.                 keyCode = SFlashKeyEvent::Down;
  1654.                 break;
  1655.         case eKI_Insert:
  1656.                 keyCode = SFlashKeyEvent::Insert;
  1657.                 break;
  1658.         case eKI_Delete:
  1659.                 keyCode = SFlashKeyEvent::Delete;
  1660.                 break;
  1661.         }
  1662.  
  1663.         unsigned char specialKeyState(0);
  1664.         specialKeyState |= ((inputEvent.modifiers & (eMM_LShift | eMM_RShift)) != 0) ? SFlashKeyEvent::eShiftPressed : 0;
  1665.         specialKeyState |= ((inputEvent.modifiers & (eMM_LCtrl | eMM_RCtrl)) != 0) ? SFlashKeyEvent::eCtrlPressed : 0;
  1666.         specialKeyState |= ((inputEvent.modifiers & (eMM_LAlt | eMM_RAlt)) != 0) ? SFlashKeyEvent::eAltPressed : 0;
  1667.         specialKeyState |= ((inputEvent.modifiers & eMM_CapsLock) != 0) ? SFlashKeyEvent::eCapsToggled : 0;
  1668.         specialKeyState |= ((inputEvent.modifiers & eMM_NumLock) != 0) ? SFlashKeyEvent::eNumToggled : 0;
  1669.         specialKeyState |= ((inputEvent.modifiers & eMM_ScrollLock) != 0) ? SFlashKeyEvent::eScrollToggled : 0;
  1670.  
  1671.         return SFlashKeyEvent(inputEvent.state == eIS_Pressed ? SFlashKeyEvent::eKeyDown : SFlashKeyEvent::eKeyUp, keyCode, specialKeyState, 0, 0);
  1672. }
  1673.  
  1674. //------------------------------------------------------------------------------------
  1675. void CFlashUI::CheckLanguageChanged()
  1676. {
  1677.         static ICVar* pLanguage = gEnv->pConsole->GetCVar("g_language");
  1678.         if (pLanguage)
  1679.         {
  1680.                 static string sLanguage = pLanguage->GetString();
  1681.                 if (sLanguage != pLanguage->GetString())
  1682.                 {
  1683.                         ReloadAll();
  1684.                         sLanguage = pLanguage->GetString();
  1685.                 }
  1686.         }
  1687. }
  1688.  
  1689. //------------------------------------------------------------------------------------
  1690. void CFlashUI::CheckResolutionChange()
  1691. {
  1692.         int width, height, x, y;
  1693.         if (!gEnv->IsEditor())
  1694.         {
  1695.                 gEnv->pRenderer->GetViewport(&x, &y, &width, &height);
  1696.         }
  1697.         else
  1698.         {
  1699.                 GetScreenSize(width, height);
  1700.         }
  1701.  
  1702.         const bool bResChanged = width != m_iWidth || height != m_iHeight;
  1703.         m_iWidth = width;
  1704.         m_iHeight = height;
  1705.  
  1706.         if (bResChanged)
  1707.         {
  1708.                 const TSortedElementList& sortedElements = GetSortedElements();
  1709.  
  1710.                 for (TSortedElementList::const_iterator iter = sortedElements.begin(); iter != sortedElements.end(); ++iter)
  1711.                         iter->second->UpdateViewPort();
  1712.  
  1713.                 // fix for mouse cursor trapped in old resolution on switch to FS
  1714.                 std::map<IUIElement*, bool> bCursorMap;
  1715.                 for (TSortedElementList::const_iterator iter = sortedElements.begin(); iter != sortedElements.end(); ++iter)
  1716.                 {
  1717.                         bCursorMap[iter->second] = iter->second->HasFlag(IUIElement::eFUI_HARDWARECURSOR);
  1718.                         iter->second->SetFlag(IUIElement::eFUI_HARDWARECURSOR, false);
  1719.                 }
  1720.                 for (TSortedElementList::const_iterator iter = sortedElements.begin(); iter != sortedElements.end(); ++iter)
  1721.                 {
  1722.                         iter->second->SetFlag(IUIElement::eFUI_HARDWARECURSOR, bCursorMap[iter->second]);
  1723.                 }
  1724.         }
  1725. }
  1726.  
  1727. //------------------------------------------------------------------------------------
  1728. void CFlashUI::GetScreenSize(int& width, int& height)
  1729. {
  1730.         CRY_ASSERT_MESSAGE(gEnv->IsEditor(), "Only allowed for editor!");
  1731.         if (m_ScreenSizeCB)
  1732.         {
  1733.                 m_ScreenSizeCB(width, height);
  1734.         }
  1735.         else
  1736.         {
  1737.                 int x, y;
  1738.                 gEnv->pRenderer->GetViewport(&x, &y, &width, &height);
  1739.         }
  1740. }
  1741.  
  1742. //------------------------------------------------------------------------------------
  1743. void CFlashUI::SetEditorScreenSizeCallback(TEditorScreenSizeCallback& cb)
  1744. {
  1745.         m_ScreenSizeCB = cb;
  1746. }
  1747.  
  1748. //------------------------------------------------------------------------------------
  1749. void CFlashUI::RemoveEditorScreenSizeCallback()
  1750. {
  1751.         m_ScreenSizeCB = NULL;
  1752. }
  1753.  
  1754. //------------------------------------------------------------------------------------
  1755. void CFlashUI::SetEditorUILogEventCallback(TEditorUILogEventCallback& cb)
  1756. {
  1757.         m_LogCallback = cb;
  1758. }
  1759.  
  1760. void CFlashUI::RemoveEditorUILogEventCallback()
  1761. {
  1762.         m_LogCallback = NULL;
  1763. }
  1764.  
  1765. //------------------------------------------------------------------------------------
  1766. IFlashUI::EPlatformUI CFlashUI::GetCurrentPlatform()
  1767. {
  1768.         CRY_ASSERT_MESSAGE(gEnv->IsEditor(), "Only allowed for editor!");
  1769.  
  1770.         if (m_plattformCallback)
  1771.         {
  1772.                 return m_plattformCallback();
  1773.         }
  1774.  
  1775.         return IFlashUI::ePUI_PC;
  1776. }
  1777.  
  1778. //------------------------------------------------------------------------------------
  1779. void CFlashUI::SetEditorPlatformCallback(TEditorPlatformCallback& cb)
  1780. {
  1781.         m_plattformCallback = cb;
  1782. }
  1783.  
  1784. //------------------------------------------------------------------------------------
  1785. void CFlashUI::RemoveEditorPlatformCallback()
  1786. {
  1787.         m_plattformCallback = NULL;
  1788. }
  1789.  
  1790. //------------------------------------------------------------------------------------
  1791. void CFlashUI::ReloadAllBootStrapper()
  1792. {
  1793.         std::map<IUIElement*, std::pair<bool, bool>> visMap;
  1794.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  1795.         {
  1796.                 IUIElementIteratorPtr instances = (*iter)->GetInstances();
  1797.                 while (IUIElement* pInstance = instances->Next())
  1798.                 {
  1799.                         visMap[pInstance].first = pInstance->IsInit();
  1800.                         visMap[pInstance].second = pInstance->IsVisible();
  1801.                         pInstance->UnloadBootStrapper();
  1802.                 }
  1803.         }
  1804.         for (TUIElementsLookup::iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
  1805.         {
  1806.                 IUIElementIteratorPtr instances = (*iter)->GetInstances();
  1807.                 while (IUIElement* pInstance = instances->Next())
  1808.                 {
  1809.                         pInstance->Init(visMap[pInstance].first);
  1810.                         pInstance->SetVisible(visMap[pInstance].second);
  1811.                 }
  1812.         }
  1813. }
  1814.  
  1815. //------------------------------------------------------------------------------------
  1816. void CFlashUI::ReloadAllElements(IConsoleCmdArgs* /* pArgs */)
  1817. {
  1818.         if (gEnv->pFlashUI)
  1819.         {
  1820.                 ((CFlashUI*)gEnv->pFlashUI)->ReloadAll();
  1821.         }
  1822. }
  1823.  
  1824. //------------------------------------------------------------------------------------
  1825. void CFlashUI::LogUIAction(ELogEventLevel level, const char* format, ...)
  1826. {
  1827. #if defined(UIACTION_LOGGING)
  1828.         if (!CV_gfx_uiaction_log)
  1829.                 return;
  1830.  
  1831.         va_list args;
  1832.         va_start(args, format);
  1833.         char tmp[1024];
  1834.         cry_vsprintf(tmp, format, args);
  1835.         va_end(args);
  1836.  
  1837.         if (gEnv->IsEditor())
  1838.         {
  1839.                 if (((CFlashUI*)gEnv->pFlashUI)->m_LogCallback && (CheckFilter(tmp) || level != IFlashUI::eLEL_Log))
  1840.                 {
  1841.                         IFlashUI::SUILogEvent evt;
  1842.                         evt.Message = tmp;
  1843.                         evt.Level = level;
  1844.                         ((CFlashUI*)gEnv->pFlashUI)->m_LogCallback(evt);
  1845.                 }
  1846.         }
  1847.  
  1848.         if (level == IFlashUI::eLEL_Warning)
  1849.         {
  1850.                 gEnv->pLog->LogWarning("$7[UIAction] $6%s", tmp);
  1851.         }
  1852.         else if (level == IFlashUI::eLEL_Error)
  1853.         {
  1854.                 gEnv->pLog->LogError("$7[UIAction] $4%s", tmp);
  1855.         }
  1856.         else
  1857.         {
  1858.                 if (CheckFilter(tmp))
  1859.                 {
  1860.                         CryLogAlways("$7[UIAction] $1%s", tmp);
  1861.                 }
  1862.         }
  1863. #endif
  1864. }
  1865.  
  1866. //------------------------------------------------------------------------------------
  1867. bool CFlashUI::CheckFilter(const string& str)
  1868. {
  1869.         string msg = str;
  1870.         msg.MakeUpper();
  1871.         if (CV_gfx_uiaction_log_filter)
  1872.         {
  1873.                 string filter = CV_gfx_uiaction_log_filter->GetString();
  1874.                 filter.MakeUpper();
  1875.                 SUIArguments filterlist;
  1876.                 filterlist.SetDelimiter("|");
  1877.                 filterlist.SetArguments(filter.c_str());
  1878.  
  1879.                 const int filter_count = filterlist.GetArgCount();
  1880.                 for (int i = 0; i < filter_count; ++i)
  1881.                 {
  1882.                         string filterEntry;
  1883.                         filterlist.GetArg(i, filterEntry);
  1884.                         if (filterEntry.substr(0, 1) == "-")
  1885.                         {
  1886.                                 if (msg.find(filterEntry.substr(1)) != string::npos)
  1887.                                         return false;
  1888.                         }
  1889.                 }
  1890.  
  1891.                 bool bHasFilter = false;
  1892.                 for (int i = 0; i < filter_count; ++i)
  1893.                 {
  1894.                         string filterEntry;
  1895.                         filterlist.GetArg(i, filterEntry);
  1896.                         if (filterEntry.substr(0, 1) != "-")
  1897.                         {
  1898.                                 if (msg.find(filterEntry) != string::npos)
  1899.                                 {
  1900.                                         return true;
  1901.                                 }
  1902.                                 else
  1903.                                 {
  1904.                                         bHasFilter = true;
  1905.                                 }
  1906.                         }
  1907.                 }
  1908.                 return !bHasFilter;
  1909.         }
  1910.         return true;
  1911. }
  1912.  
  1913. //------------------------------------------------------------------------------------
  1914. void CFlashUI::ResetDirtyFlags()
  1915. {
  1916.         if (m_elements.size() > 0)
  1917.         {
  1918.                 IFlashPlayer* flash_player = m_elements[0]->GetFlashPlayer();
  1919.                 if (flash_player)
  1920.                 {
  1921.                         flash_player->ResetDirtyFlags();
  1922.                 }
  1923.         }
  1924. }
  1925.  
  1926. //------------------------------------------------------------------------------------
  1927. #if !defined (_RELEASE) || defined(ENABLE_UISTACK_DEBUGGING)
  1928. void Draw2dLabel(float x, float y, float fontSize, const float* pColor, const char* pText)
  1929. {
  1930.         IRenderAuxText::DrawText(Vec3(x, y, 0.5f), fontSize, pColor, eDrawText_2D | eDrawText_800x600 | eDrawText_FixedSize | eDrawText_Monospace, pText);
  1931. }
  1932.  
  1933. void DrawTextLabelEx(float x, float y, float size, const float* pColor, const char* pFormat, ...) PRINTF_PARAMS(5, 6);
  1934. void DrawTextLabelEx(float x, float y, float size, const float* pColor, const char* pFormat, ...)
  1935. {
  1936.         char buffer[512];
  1937.  
  1938.         va_list args;
  1939.         va_start(args, pFormat);
  1940.         cry_vsprintf(buffer, pFormat, args);
  1941.         va_end(args);
  1942.  
  1943.         Draw2dLabel(x, y, size, pColor, buffer);
  1944. }
  1945.  
  1946.         #define DrawTextLabel(x, y, pColor, ...) DrawTextLabelEx(x, y, 1.4f, pColor, __VA_ARGS__)
  1947.  
  1948. void RenderDebugInfo()
  1949. {
  1950.         if (gEnv->pFlashUI && gEnv->pSystem)
  1951.         {
  1952.                 const float dy = 15;
  1953.                 const float dy_space = 5;
  1954.                 static const float colorWhite[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
  1955.                 static const float colorBlue[4] = { 0.3f, 0.8f, 1.0f, 1.0f };
  1956.                 static const float colorDarkBlue[4] = { 0.3f, 0.4f, 0.5f, 1.0f };
  1957.                 static const float colorGray[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
  1958.                 static const float colorGreen[4] = { 0.3f, 1.0f, 0.8f, 1.0f };
  1959.                 static const float colorRed[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
  1960.  
  1961.                 static ICVar* pFlashInfo = gEnv->pConsole->GetCVar("sys_flash_info");
  1962.                 float py = 20 + (pFlashInfo ? pFlashInfo->GetIVal() > 0 ? 400.f : 0 : 0);
  1963.  
  1964.                 if (CFlashUI::CV_gfx_debugdraw & 1)
  1965.                 {
  1966.                         const float col1 = 10;
  1967.                         const float col2 = 420;
  1968.                         const float col3 = 480;
  1969.                         const float col4 = 600;
  1970.                         const float col5 = 700;
  1971.                         const float col6 = 800;
  1972.  
  1973.                         DrawTextLabel(col1, py, colorWhite, "UIElement");
  1974.                         DrawTextLabel(col2, py, colorWhite, "Refs");
  1975.                         DrawTextLabel(col3, py, colorWhite, "Instance");
  1976.                         DrawTextLabel(col4, py, colorWhite, "Init");
  1977.                         DrawTextLabel(col5, py, colorWhite, "Visible");
  1978.                         DrawTextLabel(col6, py, colorWhite, "Memory/Textures");
  1979.                         py += dy + dy_space;
  1980.  
  1981.                         std::map<IUIElement*, bool> m_collectedMap;
  1982.  
  1983.                         // display normal elements
  1984.                         for (int i = 0; i < gEnv->pFlashUI->GetUIElementCount(); ++i)
  1985.                         {
  1986.                                 ICrySizer* pSizer = gEnv->pSystem->CreateSizer();
  1987.                                 IUIElement* pElement = gEnv->pFlashUI->GetUIElement(i);
  1988.                                 pElement->GetMemoryUsage(pSizer);
  1989.                                 IUIElementIteratorPtr instances = pElement->GetInstances();
  1990.                                 const float* color = pElement->IsValid() ? colorGreen : colorRed;
  1991.                                 DrawTextLabel(col1, py, color, "%s%s (%s)", pElement->IsValid() ? "" : "INVALID! ", pElement->GetName(), pElement->GetFlashFile());
  1992.                                 DrawTextLabel(col3, py, color, "Count: %i", instances->GetCount());
  1993.                                 DrawTextLabel(col6, py, color, "%4d KB", static_cast<uint32>(pSizer->GetTotalSize() >> 10));
  1994.                                 pSizer->Release();
  1995.                                 py += dy;
  1996.  
  1997.                                 while (IUIElement* pInstance = instances->Next())
  1998.                                 {
  1999.                                         color = pInstance->IsValid() ? pInstance->IsInit() ? pInstance->IsVisible() ? colorBlue : colorDarkBlue : colorGray : colorRed;
  2000.                                         DrawTextLabel(col1, py, color, "%s%s@%i", pInstance->IsValid() ? "" : "INVALID! ", pInstance->GetName(), pInstance->GetInstanceID());
  2001.                                         DrawTextLabel(col2, py, color, "%i", ((CFlashUIElement*)pInstance)->m_refCount);
  2002.                                         DrawTextLabel(col3, py, color, "ID: %i", pInstance->GetInstanceID());
  2003.                                         DrawTextLabel(col4, py, color, "%s ", pInstance->IsInit() ? "true" : "false");
  2004.                                         DrawTextLabel(col5, py, color, "%s ", pInstance->IsVisible() ? "true" : "false");
  2005.                                         DrawTextLabel(col6, py, color, "DynTex: %i ", pInstance->GetNumExtTextures());
  2006.                                         py += dy;
  2007.                                         m_collectedMap[pInstance] = true;
  2008.                                 }
  2009.                                 py += dy_space;
  2010.                         }
  2011.                         py += dy;
  2012.  
  2013.                         // display leaking elements
  2014.                         for (CFlashUIElement::TElementInstanceList::const_iterator it = CFlashUIElement::s_ElementDebugList.begin(); it != CFlashUIElement::s_ElementDebugList.end(); ++it)
  2015.                         {
  2016.                                 CFlashUIElement* pElement = *it;
  2017.                                 if (m_collectedMap[pElement])
  2018.                                         continue;
  2019.  
  2020.                                 DrawTextLabel(col1, py, colorRed, "%s@%i", pElement->GetName(), pElement->GetInstanceID());
  2021.                                 DrawTextLabel(col2, py, colorRed, "%i", pElement->m_refCount);
  2022.                                 DrawTextLabel(col3, py, colorRed, "ID: %i", pElement->GetInstanceID());
  2023.                                 DrawTextLabel(col4, py, colorRed, "LEAKING!!!");
  2024.                                 DrawTextLabel(col6, py, colorRed, "DynTex: %i ", pElement->GetNumExtTextures());
  2025.                                 py += dy;
  2026.                         }
  2027.                         py += dy;
  2028.                 }
  2029.                 if (CFlashUI::CV_gfx_debugdraw & 2)
  2030.                 {
  2031.                         const float col1 = 10;
  2032.                         const float col2 = 480;
  2033.                         const float col3 = 600;
  2034.                         const float col4 = 700;
  2035.  
  2036.                         DrawTextLabel(col1, py, colorWhite, "UIAction");
  2037.                         DrawTextLabel(col2, py, colorWhite, "Enabled");
  2038.                         DrawTextLabel(col3, py, colorWhite, "Type");
  2039.                         DrawTextLabel(col4, py, colorWhite, "Memory");
  2040.                         py += dy + dy_space;
  2041.  
  2042.                         std::list<IUIAction*> actions[2];
  2043.  
  2044.                         for (int i = 0; i < gEnv->pFlashUI->GetUIActionCount(); ++i)
  2045.                         {
  2046.                                 IUIAction* pAction = gEnv->pFlashUI->GetUIAction(i);
  2047.                                 if (pAction->IsEnabled())
  2048.                                         actions[0].push_back(pAction);
  2049.                                 else
  2050.                                         actions[1].push_back(pAction);
  2051.                         }
  2052.  
  2053.                         for (int i = 0; i < 2; ++i)
  2054.                         {
  2055.                                 for (std::list<IUIAction*>::iterator it = actions[i].begin(); it != actions[i].end(); ++it)
  2056.                                 {
  2057.                                         ICrySizer* pSizer = gEnv->pSystem->CreateSizer();
  2058.                                         IUIAction* pAction = *it;
  2059.                                         const float* color = pAction->IsValid() ? i == 0 ? colorBlue : colorDarkBlue : colorRed;
  2060.                                         pAction->GetMemoryUsage(pSizer);
  2061.                                         DrawTextLabel(col1, py, color, "%s", pAction->GetName());
  2062.                                         DrawTextLabel(col2, py, color, "%s", pAction->IsValid() ? pAction->IsEnabled() ? "true" : "false" : "INVALID!");
  2063.                                         DrawTextLabel(col3, py, color, "%s", pAction->GetType() == IUIAction::eUIAT_FlowGraph ? "FlowGraph" : "Lua Script");
  2064.                                         DrawTextLabel(col4, py, color, "%4d KB", static_cast<uint32>(pSizer->GetTotalSize() >> 10));
  2065.                                         pSizer->Release();
  2066.                                         py += dy;
  2067.                                 }
  2068.                                 py += dy_space;
  2069.                         }
  2070.                         py += dy;
  2071.                 }
  2072.  
  2073.                 // Force post effect active
  2074.                 gEnv->p3DEngine->SetPostEffectParam("Post3DRenderer_Active", 1.0f, true);
  2075.  
  2076.                 // Get post3DRenderer texture
  2077.                 static ITexture* pPost3DRendererTexture = NULL;
  2078.                 if (pPost3DRendererTexture == NULL)
  2079.                 {
  2080.                         pPost3DRendererTexture = gEnv->pRenderer->EF_LoadTexture("$BackBuffer");
  2081.                 }
  2082.  
  2083.                 // Render debug view
  2084.                 if (pPost3DRendererTexture != NULL)
  2085.                 {
  2086.                         gEnv->pRenderer->Draw2dImage(0, 0, 200, 200, pPost3DRendererTexture->GetTextureID());
  2087.                 }
  2088.                 /////////////////
  2089.         }
  2090. }
  2091. #endif
  2092.  
  2093. #ifdef ENABLE_UISTACK_DEBUGGING
  2094.  
  2095. struct SStackInfo
  2096. {
  2097.         enum EType
  2098.         {
  2099.                 eDefault = 0,
  2100.                 eAdded,
  2101.                 eStack,
  2102.                 eRemoved,
  2103.         };
  2104.         SStackInfo(float t = 0) : time(t), index(-1), type(eDefault), id(-1) {}
  2105.         SStackInfo(const char* str, float t) : info(str), time(t), index(-1), type(eDefault), id(-1) {}
  2106.         SStackInfo(const char* str, float t, int i, EType tp, int idx) : info(str), time(t), index(i), type(tp), id(idx) {}
  2107.         string info;
  2108.         float  time;
  2109.         int    index;
  2110.         EType  type;
  2111.         int    id;
  2112. };
  2113.  
  2114. void RenderStackDebugInfo(bool render, const char* label, int loop)
  2115. {
  2116.         if (CFlashUI::CV_gfx_debugdraw & 4)
  2117.         {
  2118.                 static bool empty = true;
  2119.                 static std::deque<SStackInfo> stacklist;
  2120.                 static std::vector<int> currStack;
  2121.                 static std::map<int, const char*> lastStack;
  2122.  
  2123.                 const float time = gEnv->pTimer->GetAsyncCurTime();
  2124.  
  2125.                 const std::map<int, const char*>& stack = CUIFGStackMan::GetStack();
  2126.                 if (lastStack != stack)
  2127.                 {
  2128.                         lastStack = stack;
  2129.  
  2130.                         if (!stack.empty() || !currStack.empty())
  2131.                         {
  2132.                                 empty = false;
  2133.                                 stacklist.push_front(SStackInfo(time));
  2134.                                 stacklist.push_front(SStackInfo(string().Format("%i: %s", loop, label), time));
  2135.  
  2136.                                 int removed = 0;
  2137.                                 for (std::vector<int>::iterator it = currStack.begin(); it != currStack.end(); )
  2138.                                 {
  2139.                                         if (stack.find(*it) == stack.end())
  2140.                                         {
  2141.                                                 for (std::deque<SStackInfo>::const_iterator it2 = stacklist.begin(), end2 = stacklist.end(); it2 != end2; ++it2)
  2142.                                                 {
  2143.                                                         if (it2->id == *it)
  2144.                                                         {
  2145.                                                                 stacklist.push_front(SStackInfo(it2->info.c_str(), time, removed++, SStackInfo::eRemoved, it2->id));
  2146.                                                                 break;
  2147.                                                         }
  2148.                                                 }
  2149.                                                 it = currStack.erase(it);
  2150.                                         }
  2151.                                         else
  2152.                                                 ++it;
  2153.                                 }
  2154.  
  2155.                                 int stackNum = 0;
  2156.                                 for (std::map<int, const char*>::const_iterator it = stack.begin(), end = stack.end(); it != end; ++it)
  2157.                                 {
  2158.                                         SStackInfo::EType type = SStackInfo::eStack;
  2159.                                         if (!stl::find(currStack, it->first))
  2160.                                         {
  2161.                                                 currStack.push_back(it->first);
  2162.                                                 type = SStackInfo::eAdded;
  2163.                                         }
  2164.                                         stacklist.push_front(SStackInfo(it->second, time, stackNum++, type, it->first));
  2165.                                 }
  2166.                         }
  2167.                 }
  2168.  
  2169.                 if (!render)
  2170.                         return;
  2171.  
  2172.                 if (!empty)
  2173.                 {
  2174.                         stacklist.push_front(SStackInfo("-------------------------------------------------------", time));
  2175.                         empty = true;
  2176.                 }
  2177.  
  2178.                 const float displayTime = 20;
  2179.                 const int itemsPerRow = 140;
  2180.  
  2181.                 const float dy = 8;
  2182.                 const float dy_space = 5;
  2183.                 const float dx = 400;
  2184.                 float colorWhite[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
  2185.                 float colorBlue[4] = { 0.3f, 0.8f, 1.0f, 1.0f };
  2186.                 float colorGreen[4] = { 0.3f, 1.0f, 0.8f, 1.0f };
  2187.                 float colorRed[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
  2188.  
  2189.                 const float col1 = 10;
  2190.                 const float col2 = 40;
  2191.                 const float col3 = 50;
  2192.  
  2193.                 float py = 0;
  2194.                 float px = 0;
  2195.                 const int count = stacklist.size();
  2196.                 int round = 0;
  2197.  
  2198.                 colorWhite[3] = 1.f;
  2199.                 for (int i = 0; i <= count / itemsPerRow; ++i)
  2200.                 {
  2201.                         DrawTextLabelEx(col1 + i * dx, py, 1.1f, colorWhite, "   Id");
  2202.                         DrawTextLabelEx(col3 + i * dx, py, 1.1f, colorWhite, "Stack");
  2203.                 }
  2204.                 py += dy + dy_space;
  2205.  
  2206.                 for (int i = 0; i < count; ++i)
  2207.                 {
  2208.                         float alpha = (displayTime + stacklist[i].time - time) / displayTime;
  2209.                         if (alpha <= 0.05)
  2210.                         {
  2211.                                 stacklist.resize(i);
  2212.                                 break;
  2213.                         }
  2214.                         colorWhite[3] = colorBlue[3] = colorGreen[3] = colorRed[3] = alpha;
  2215.  
  2216.                         float* color = stacklist[i].type == SStackInfo::eAdded ? colorGreen : stacklist[i].type == SStackInfo::eRemoved ? colorRed : colorBlue;
  2217.  
  2218.                         if (stacklist[i].index >= 0)
  2219.                         {
  2220.                                 DrawTextLabelEx(col1 + px, py, 0.9f, color, "%4i", stacklist[i].id & 511);
  2221.                                 DrawTextLabelEx(col2 + px, py, 0.9f, color, "%s", stacklist[i].type == SStackInfo::eAdded ? "+" : stacklist[i].type == SStackInfo::eRemoved ? "-" : "");
  2222.                                 DrawTextLabelEx(col3 + px, py, 0.9f, color, "%s", stacklist[i].info.c_str());
  2223.                         }
  2224.                         else
  2225.                         {
  2226.                                 DrawTextLabelEx(col1 + px, py, 0.9f, colorWhite, "%s", stacklist[i].info.c_str());
  2227.                         }
  2228.  
  2229.                         if (stacklist[i].info == "")
  2230.                                 py += dy_space;
  2231.                         else
  2232.                                 py += dy;
  2233.  
  2234.                         if ((i + 1) % itemsPerRow == 0)
  2235.                         {
  2236.                                 px += dx;
  2237.                                 py = dy + dy_space;
  2238.                         }
  2239.                 }
  2240.         }
  2241. }
  2242. #endif
  2243. //------------------------------------------------------------------------------------
  2244.  
downloadFlashUI.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