BVB Source Codes

CRYENGINE Show FlowInspectorDefault.cpp Source code

Return Download CRYENGINE: download FlowInspectorDefault.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.  
  5. #include "FlowInspectorDefault.h"
  6. #include <FlowSystem/FlowSystem.h>
  7. #include <FlowSystem/FlowGraph.h>
  8. #include <FlowSystem/FlowData.h>
  9. #include <CryAISystem/IAIAction.h>
  10.  
  11. #include <CryEntitySystem/IEntitySystem.h>
  12. #include <CryRenderer/IRenderer.h>
  13.  
  14. // TODO: find a better place for them
  15.  
  16. // Address equality operator
  17. inline bool operator==(const SFlowAddress& lhs, const SFlowAddress& rhs)
  18. {
  19.         return lhs.node == rhs.node && lhs.port == rhs.port && lhs.isOutput == rhs.isOutput;
  20. }
  21.  
  22. namespace
  23. {
  24. static const int MAX_ROWS = 23;             // max number of one-time-flow lines
  25. static const int MAX_ROWS_CONT = 12;        // max number of rows for continuous flows
  26.  
  27. static const float MAX_AGE = 10.0f;         // max age of one-time-flows updates before fade out
  28. static const float MAX_AGE_CONT = 2.5f;     // max age of continuous updates before fade out
  29.  
  30. // visuals
  31. static const float BASE_Y = 50.0f;
  32. static const float ROW_SIZE = 9.5f;
  33. static const float COL_SIZE = 5.0f;
  34.  
  35. static const ColorF DRAW_COLORS[CFlowInspectorDefault::eRTLast] = {
  36.         ColorF(0.5f, 0.5f, 1.0f, 1.0f),     // eRTUnknown blue-ish
  37.         ColorF(1.0f, 1.0f, 1.0f, 1.0f),     // eRTEntity white
  38.         ColorF(1.0f, 0.9f, 0.3f, 1.0f),     // eRTAction yellow-ish
  39. };
  40.  
  41. float smoothstep(float t)   // it's graphics after all ;-)
  42. {
  43.         return t * t * (3.0f - 2.0f * t);
  44. }
  45.  
  46. // TODO: better description (currently it's more debug...)
  47. void GetGraphNameAndType(IFlowGraph* pGraph, string& name, CFlowInspectorDefault::ERecType& type)
  48. {
  49.         name = "<noname>";
  50.         type = CFlowInspectorDefault::eRTUnknown;
  51.  
  52.         IAIAction* pAction = pGraph->GetAIAction();
  53.         EntityId id = pGraph->GetGraphEntity(0);
  54.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(id);
  55.         if (pEntity != 0)
  56.         {
  57.                 name = pEntity->GetName();
  58.                 type = CFlowInspectorDefault::eRTEntity;
  59.         }
  60.         else
  61.         {
  62.                 id = pGraph->GetGraphEntity(1);
  63.                 pEntity = gEnv->pEntitySystem->GetEntity(id);
  64.                 if (pEntity != 0)
  65.                 {
  66.                         name = pEntity->GetName();
  67.                         type = CFlowInspectorDefault::eRTEntity;
  68.                 }
  69.         }
  70.         if (pAction != 0)
  71.         {
  72.                 type = CFlowInspectorDefault::eRTAction;
  73.                 name = pAction->GetName();
  74.                 if (!name.empty())
  75.                         name += " ";
  76.                 name += "User=";
  77.                 pEntity = pAction->GetUserEntity();
  78.                 if (pEntity)
  79.                 {
  80.                         name += pEntity->GetName();
  81.                 }
  82.                 else name += "<none>";
  83.  
  84.                 name += " Obj=";
  85.                 pEntity = pAction->GetObjectEntity();
  86.                 if (pEntity)
  87.                 {
  88.                         name += pEntity->GetName();
  89.                 }
  90.                 else name += "<none>";
  91.         }
  92. }
  93.  
  94. const char* GetPortName(IFlowGraph* pGraph, const SFlowAddress addr)
  95. {
  96.         CFlowData* data = static_cast<CFlowData*>(pGraph->GetNodeData(addr.node));
  97.         return data->GetPortName(addr.port, addr.isOutput);
  98. }
  99.  
  100. string GetNodeName(IFlowGraph* pGraph, const SFlowAddress addr)
  101. {
  102.         const char* typeName = pGraph->GetNodeTypeName(addr.node);
  103.         const char* nodeName = pGraph->GetNodeName(addr.node);
  104.         string human;
  105.         human += typeName;
  106.         human += " Node:";
  107.  
  108.         if (nodeName == 0)
  109.         {
  110.                 IEntity* pEntity = ((CFlowGraph*)pGraph)->GetIEntityForNode(addr.node);
  111.                 if (pEntity)
  112.                         human += pEntity->GetName();
  113.         }
  114.         else
  115.                 human += nodeName;
  116.         return human;
  117. }
  118. };
  119.  
  120. CFlowInspectorDefault::CFlowInspectorDefault(IFlowSystem* pFlowSystem)
  121.         : m_pRenderer(gEnv->pRenderer)
  122.         , m_pFlowSystem(pFlowSystem)
  123.         , m_refs(0)
  124.         , m_newOneTime(0)
  125.         , m_newCont(0)
  126.         , m_bProcessing(false)
  127.         , m_bPaused(false)
  128. {
  129. }
  130.  
  131. CFlowInspectorDefault::~CFlowInspectorDefault()
  132. {
  133. }
  134.  
  135. void
  136. CFlowInspectorDefault::AddRef()
  137. {
  138.         ++m_refs;
  139. }
  140.  
  141. void
  142. CFlowInspectorDefault::Release()
  143. {
  144.         if (--m_refs <= 0)
  145.                 delete this;
  146. }
  147.  
  148. /* virtual */ void
  149. CFlowInspectorDefault::PreUpdate(IFlowGraph* pGraph)
  150. {
  151.         m_bProcessing = true;
  152.         m_currentTime = gEnv->pTimer->GetFrameStartTime();
  153. }
  154.  
  155. /* virtual */ void
  156. CFlowInspectorDefault::PostUpdate(IFlowGraph* pGraph)
  157. {
  158.         ColorF headColor(1.0f, 0.5f, 0.5f, 1.0f);
  159.         ColorF filterColor(1.0f, 0.1f, 0.1f, 1.0f);
  160.         if (!m_bPaused)
  161.         {
  162.                 UpdateRecords();
  163.         }
  164.  
  165. #if 1
  166.         if (m_newCont <= MAX_ROWS_CONT)
  167.                 DrawLabel(2, 0, headColor, 0.2f, "Continuous Flows:");
  168.         else
  169.                 DrawLabel(2, 0, headColor, 0.2f, "Continuous Flows [truncated]:");
  170.  
  171.         DrawRecords(m_contRecords, 1, m_bPaused ? 0.0f : MAX_AGE_CONT);
  172.         if (m_newOneTime <= MAX_ROWS)
  173.                 DrawLabel(2, 1 + MAX_ROWS_CONT, headColor, 0.2f, "Flows:");
  174.         else
  175.                 DrawLabel(2, 1 + MAX_ROWS_CONT, headColor, 0.2f, "Flows [truncated]:");
  176.  
  177.         if (m_bPaused)
  178.                 DrawLabel(2, -1, headColor, 0.5f, "Paused:");
  179.  
  180.         if (m_filters.empty() == false)
  181.                 DrawLabel(11, -1, filterColor, 0.0, "Filter Active");
  182.  
  183.         DrawRecords(m_oneTimeRecords, 1 + 1 + MAX_ROWS_CONT, m_bPaused ? 0.0f : MAX_AGE);
  184. #endif
  185.  
  186.         m_bProcessing = true; // FIXME: actually we should set it to 'false' now, but then we don't get EntityEvents, which occur not during the FG update phase
  187.         m_curRecords.resize(0);
  188.  
  189.         if (gEnv->pInput)
  190.         {
  191.                 static TKeyName scrollKey("scrolllock");
  192.                 if (gEnv->pInput->InputState(scrollKey, eIS_Pressed))
  193.                         m_bPaused = !m_bPaused;
  194.         }
  195. }
  196.  
  197. bool
  198. CFlowInspectorDefault::RunFilters(IFlowGraph* pGraph, const SFlowAddress from, const SFlowAddress to)
  199. {
  200.         if (m_filters.empty())
  201.                 return true;
  202.  
  203.         bool gotBlock = false;
  204.         bool gotPass = false;
  205.         IFilter::EFilterResult res;
  206.         IFilter_AutoArray::iterator iter(m_filters.begin());
  207.         IFilter_AutoArray::iterator end(m_filters.end());
  208.  
  209.         while (iter != end)
  210.         {
  211.                 res = (*iter)->Apply(pGraph, from, to);
  212.                 gotBlock |= res == IFilter::eFR_Block;
  213.                 gotPass |= res == IFilter::eFR_Pass;
  214.                 ++iter;
  215.         }
  216.  
  217.         return (!gotBlock || gotPass);
  218.         /*
  219.            if (gotBlock && !gotPass)
  220.            return false;
  221.            return true;
  222.          */
  223. }
  224.  
  225. /* virtual */ void
  226. CFlowInspectorDefault::NotifyFlow(IFlowGraph* pGraph, const SFlowAddress from, const SFlowAddress to)
  227. {
  228.         static char msg[256];
  229.  
  230.         if (!m_bProcessing)
  231.                 return;
  232.         if (m_bPaused)
  233.                 return;
  234.  
  235.         if (RunFilters(pGraph, from, to) == false)
  236.                 return;
  237.  
  238.         string name;
  239.         TFlowRecord rec;
  240.         GetGraphNameAndType(pGraph, name, rec.m_type);
  241.         rec.m_from = from;
  242.         rec.m_to = to;
  243.         rec.m_pGraph = pGraph;
  244.         rec.m_tstamp = m_currentTime;
  245.  
  246.         const TFlowInputData* data = pGraph->GetInputValue(to.node, to.port);
  247.         if (0 != data)
  248.         {
  249.                 rec.m_data = *data;
  250.         }
  251.         string val;
  252.         rec.m_data.GetValueWithConversion(val);
  253.  
  254.         cry_sprintf(msg, "0x%p %s [%s:%s] -> [%s:%s] Val=%s",
  255.                     (const IFlowGraph*) rec.m_pGraph,
  256.                     name.c_str(),
  257.                     GetNodeName(rec.m_pGraph, rec.m_from).c_str(),
  258.                     GetPortName(rec.m_pGraph, rec.m_from),
  259.                     GetNodeName(rec.m_pGraph, rec.m_to).c_str(),
  260.                     GetPortName(rec.m_pGraph, rec.m_to), val.c_str());
  261.         rec.m_message = msg;
  262.  
  263.         if (CFlowSystemCVars::Get().m_inspectorLog != 0)
  264.         {
  265.                 CryLogAlways("[fgi] %s", msg);
  266.         }
  267.  
  268.         m_curRecords.push_back(rec);
  269. }
  270.  
  271. /* virtual */ void
  272. CFlowInspectorDefault::NotifyProcessEvent(IFlowNode::EFlowEvent event, IFlowNode::SActivationInfo* pActInfo, IFlowNode* pImpl)
  273. {
  274. }
  275.  
  276. /* virtual */ void
  277. CFlowInspectorDefault::UpdateRecords()
  278. {
  279.         m_newOneTime = 0;
  280.         m_newCont = 0;
  281.  
  282.         // if we find a record equal to one in the m_oneTimeRecords, we put it into the m_contRecords instead (replacing one which is already there)
  283.         std::vector<TFlowRecord>::const_iterator iter(m_curRecords.begin());
  284.  
  285.         while (iter != m_curRecords.end())
  286.         {
  287.                 const TFlowRecord& rec(*iter);
  288.                 std::deque<TFlowRecord>::const_iterator iterInOneTimeRecords = std::find(m_oneTimeRecords.begin(), m_oneTimeRecords.end(), rec);
  289.                 std::deque<TFlowRecord>::iterator iterInContRecords = std::find(m_contRecords.begin(), m_contRecords.end(), rec);
  290.  
  291.                 if (iterInOneTimeRecords != m_oneTimeRecords.end())
  292.                 {
  293.                         // if found in oneTimeRecords put it into the contList or replace copy
  294.                         if (iterInContRecords != m_contRecords.end())
  295.                                 *iterInContRecords = rec;
  296.                         else
  297.                         {
  298.                                 m_contRecords.push_back(rec);
  299.                                 ++m_newCont;
  300.                         }
  301.                 }
  302.                 else
  303.                 {
  304.                         // not found oneTimeRecords. replace copy in cont if it's there, otherwise put it into oneTimeRecords
  305.                         if (iterInContRecords != m_contRecords.end())
  306.                                 *iterInContRecords = rec;
  307.                         else
  308.                         {
  309.                                 m_oneTimeRecords.push_back(rec);
  310.                                 ++m_newOneTime;
  311.                         }
  312.                 }
  313.                 ++iter;
  314.         }
  315.  
  316.         // clear outdated
  317.         while (!m_oneTimeRecords.empty())
  318.         {
  319.                 float age = (m_currentTime - m_oneTimeRecords.front().m_tstamp).GetSeconds();
  320.                 if (age <= MAX_AGE) break;
  321.                 m_oneTimeRecords.pop_front();
  322.         }
  323.  
  324.         // erase too old ones
  325.         while (m_oneTimeRecords.size() > MAX_ROWS)
  326.         {
  327.                 m_oneTimeRecords.pop_front();
  328.         }
  329.  
  330.         // clear outdated in cont
  331.         while (!m_contRecords.empty())
  332.         {
  333.                 float age = (m_currentTime - m_contRecords.front().m_tstamp).GetSeconds();
  334.                 if (age <= MAX_AGE_CONT) break;
  335.                 m_contRecords.pop_front();
  336.         }
  337.  
  338.         // erase too old ones in cont
  339.         while (m_contRecords.size() > MAX_ROWS_CONT)
  340.         {
  341.                 m_contRecords.pop_front();
  342.         }
  343.  
  344. }
  345.  
  346. void
  347. CFlowInspectorDefault::DrawLabel(float col, float row, const ColorF& color, float glow, const char* szText, float fScale) const
  348. {
  349.         const float ColumnSize = COL_SIZE;
  350.         const float RowSize = ROW_SIZE;
  351.  
  352.         CryFixedStringT<128> msg;
  353.         msg.Format("%s", szText ? szText : "No message");
  354.  
  355.         if (glow > 0.1f)
  356.         {
  357.                 ColorF glowColor(color[0], color[1], color[2], glow);
  358.                 IRenderAuxText::Draw2dLabel((float)(ColumnSize * col + 1), (float)(BASE_Y + RowSize * row + 1), fScale * 1.2f, &glowColor[0], false, "%s", msg.c_str());
  359.         }
  360.         ColorF tmp(color);
  361.         IRenderAuxText::Draw2dLabel((float)(ColumnSize * col), (float)(BASE_Y + RowSize * row), fScale * 1.2f, &tmp[0], false, "%s", msg.c_str());
  362. }
  363.  
  364. /* virtual */ void
  365. CFlowInspectorDefault::DrawRecords(const std::deque<TFlowRecord>& inRecords, int inBaseRow, float inMaxAge) const
  366. {
  367.         // records are pushed back, but we want to draw new records on top
  368.         // so we draw from bottom to top, ensuring linear mem access
  369.         int row = inRecords.size() - 1 + inBaseRow;
  370.         string val;
  371.         ColorF color;
  372.  
  373.         std::deque<TFlowRecord>::const_iterator iter(inRecords.begin());
  374.         while (iter != inRecords.end())
  375.         {
  376.                 const TFlowRecord& rec(*iter);
  377.                 float age = (m_currentTime - rec.m_tstamp).GetSeconds() - 0.5f;  // -0.5 grace time
  378.                 float ageFactor = inMaxAge > 0 ? age / inMaxAge : 0;
  379.                 if (ageFactor < 0) ageFactor = 0;
  380.                 if (ageFactor > 1) ageFactor = 1;
  381.                 ageFactor = smoothstep(1.0f - ageFactor);
  382.                 color = DRAW_COLORS[rec.m_type];
  383.                 color.a *= ageFactor;
  384.                 DrawLabel(2.f, (float)row, color, 0.0f, rec.m_message.c_str());
  385.                 --row;
  386.                 ++iter;
  387.         }
  388. }
  389.  
  390. /* virtual */ void
  391. CFlowInspectorDefault::AddFilter(IFlowGraphInspector::IFilterPtr pFilter)
  392. {
  393.         stl::push_back_unique(m_filters, pFilter);
  394. }
  395.  
  396. /* virtual */ void
  397. CFlowInspectorDefault::RemoveFilter(IFlowGraphInspector::IFilterPtr pFilter)
  398. {
  399.         stl::find_and_erase(m_filters, pFilter);
  400. }
  401.  
  402. template<class T>
  403. static void AddFlowRecordsTo(const T& cont, ICrySizer* s)
  404. {
  405.         s->AddObject(cont);
  406.         for (typename T::const_iterator it = cont.begin(); it != cont.end(); ++it)
  407.         {
  408.                 it->m_data.GetMemoryStatistics(s);
  409.                 s->Add(it->m_message);
  410.         }
  411. }
  412.  
  413. void CFlowInspectorDefault::GetMemoryUsage(ICrySizer* s) const
  414. {
  415.         s->Add(*this);
  416.         AddFlowRecordsTo(m_curRecords, s);
  417.         AddFlowRecordsTo(m_oneTimeRecords, s);
  418.         AddFlowRecordsTo(m_contRecords, s);
  419. }
  420.  
downloadFlowInspectorDefault.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