BVB Source Codes

CRYENGINE Show NetDebug.cpp Source code

Return Download CRYENGINE: download NetDebug.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.    Description:  network debugging helpers for CryAction code
  8.    -------------------------------------------------------------------------
  9.    History:
  10.    - 01/06/2000   11:28 : Created by Sergii Rustamov
  11. *************************************************************************/
  12. #include "StdAfx.h"
  13. #include "NetDebug.h"
  14.  
  15. #if ENABLE_NETDEBUG
  16.  
  17.         #include <CrySystem/ITextModeConsole.h>
  18.  
  19. CNetDebug::CNetDebug()
  20. {
  21.         m_fLastTime = 0;
  22.         m_varDebug = 0;
  23.         m_varDebugRMI = 0;
  24.         m_trapValue = 0;
  25.         m_trapValueCount = 1;
  26.  
  27.         REGISTER_CVAR2("g_debugAspectChanges", &m_varDebug, 0, 0, "Start debugging network aspect changes");
  28.         REGISTER_CVAR2("g_debugRMI", &m_varDebugRMI, 0, 0, "Start debugging RMI network traffic");
  29.         REGISTER_STRING("g_debugAspectFilterClass", "*", 0, "Filter entities per class name");
  30.         REGISTER_STRING("g_debugAspectFilterEntity", "*", 0, "Filter entities per entity name");
  31.         REGISTER_CVAR2("g_debugAspectTrap", &m_trapValue, 0, 0, "Catch aspect change rate greater than trap value");
  32.         REGISTER_CVAR2("g_debugAspectTrapCount", &m_trapValueCount, 1, 0, "How much time trace aspect change rate");
  33. }
  34.  
  35. CNetDebug::~CNetDebug()
  36. {
  37.         gEnv->pConsole->UnregisterVariable("g_debugAspectChanges");
  38.         gEnv->pConsole->UnregisterVariable("g_debugRMI");
  39.         gEnv->pConsole->UnregisterVariable("g_debugAspectFilterClass");
  40.         gEnv->pConsole->UnregisterVariable("g_debugAspectFilterEntity");
  41.         gEnv->pConsole->UnregisterVariable("g_debugAspectTrap");
  42.         gEnv->pConsole->UnregisterVariable("g_debugAspectTrapCount");
  43.         m_aspects.clear();
  44. }
  45.  
  46. void CNetDebug::DebugAspectsChange(IEntity* pEntity, uint8 aspects)
  47. {
  48.         if (!m_varDebug || !pEntity)
  49.                 return;
  50.  
  51.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  52.  
  53.         const char* sClassName = pEntity->GetClass()->GetName();
  54.         const char* sEntityName = pEntity->GetName();
  55.  
  56.         TDebugAspects::iterator it = m_aspects.find(CONST_TEMP_STRING(sClassName));
  57.         if (m_aspects.end() == it)
  58.         {
  59.                 DebugAspectsContext ctx;
  60.                 DebugAspectsEntity ent;
  61.  
  62.                 ctx.sEntityClass = sClassName;
  63.                 ent.sEntityName = sEntityName;
  64.                 UpdateAspectsDebugEntity(ctx, ent, aspects);
  65.                 ctx.entities.insert(std::make_pair(ent.sEntityName, ent));
  66.                 m_aspects.insert(std::make_pair(ctx.sEntityClass, ctx));
  67.         }
  68.         else
  69.         {
  70.                 DebugAspectsContext* pCtx = &(it->second);
  71.  
  72.                 TDebugEntities::iterator iter = pCtx->entities.find(CONST_TEMP_STRING(sEntityName));
  73.                 if (pCtx->entities.end() == iter)
  74.                 {
  75.                         DebugAspectsEntity ent;
  76.                         ent.sEntityName = sEntityName;
  77.                         UpdateAspectsDebugEntity(it->second, ent, aspects);
  78.                         pCtx->entities.insert(std::make_pair(ent.sEntityName, ent));
  79.                 }
  80.                 else
  81.                 {
  82.                         UpdateAspectsDebugEntity(it->second, iter->second, aspects);
  83.                 }
  84.         }
  85. }
  86.  
  87. void CNetDebug::DebugRMI(const char* szDescription, size_t nSize)
  88. {
  89.         if (!m_varDebugRMI)
  90.                 return;
  91.  
  92.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  93.  
  94.         TDebugRMI::iterator iter = m_rmi.find(CONST_TEMP_STRING(szDescription));
  95.         if (m_rmi.end() == iter)
  96.         {
  97.                 DebugRMIEntity ent;
  98.                 ent.sDesc = szDescription;
  99.                 ent.invokeCount = 1;
  100.                 ent.totalSize = nSize;
  101.                 m_rmi.insert(std::make_pair(ent.sDesc, ent));
  102.         }
  103.         else
  104.         {
  105.                 DebugRMIEntity* pEnt = &(iter->second);
  106.                 pEnt->invokeCount++;
  107.                 pEnt->totalSize += nSize;
  108.         }
  109. }
  110.  
  111. const char* CNetDebug::IdxToAspectString(int idx)
  112. {
  113.         switch (idx)
  114.         {
  115.         case 0:
  116.                 return "Script";
  117.         case 1:
  118.                 return "Physics";
  119.         case 2:
  120.                 return "GameClientStatic";
  121.         case 3:
  122.                 return "GameServerStatic";
  123.         case 4:
  124.                 return "GameClientDynamic";
  125.         case 5:
  126.                 return "GameServerDynamic";
  127.         default:
  128.                 return "Unknown";
  129.         }
  130. }
  131.  
  132. int CNetDebug::AspectToIdx(EEntityAspects aspect)
  133. {
  134.         switch (aspect)
  135.         {
  136.         case eEA_Script:
  137.                 return 0;
  138.         case eEA_Physics:
  139.                 return 1;
  140.         case eEA_GameClientStatic:
  141.                 return 2;
  142.         case eEA_GameServerStatic:
  143.                 return 3;
  144.         case eEA_GameClientDynamic:
  145.                 return 4;
  146.         case eEA_GameServerDynamic:
  147.                 return 5;
  148.         default:
  149.                 assert(!"Not supported aspect value");
  150.                 return 6;
  151.         }
  152. }
  153.  
  154. void CNetDebug::UpdateAspectsDebugEntity(const DebugAspectsContext& ctx, DebugAspectsEntity& ent, uint8 aspects)
  155. {
  156.         if (!ProcessFilter(ctx.sEntityClass.c_str(), ent.sEntityName.c_str()))
  157.                 return;
  158.  
  159.         ProcessTrap(ent);
  160.  
  161.         if (aspects & eEA_Script) ent.aspectChangeCount[AspectToIdx(eEA_Script)]++;
  162.         if (aspects & eEA_Physics) ent.aspectChangeCount[AspectToIdx(eEA_Physics)]++;
  163.         if (aspects & eEA_GameClientStatic) ent.aspectChangeCount[AspectToIdx(eEA_GameClientStatic)]++;
  164.         if (aspects & eEA_GameServerStatic) ent.aspectChangeCount[AspectToIdx(eEA_GameServerStatic)]++;
  165.         if (aspects & eEA_GameClientDynamic) ent.aspectChangeCount[AspectToIdx(eEA_GameClientDynamic)]++;
  166.         if (aspects & eEA_GameServerDynamic) ent.aspectChangeCount[AspectToIdx(eEA_GameServerDynamic)]++;
  167. }
  168.  
  169. void CNetDebug::UpdateAspectsRates(float fDiffTimeMsec)
  170. {
  171.         for (TDebugAspects::iterator it = m_aspects.begin(); it != m_aspects.end(); ++it)
  172.         {
  173.                 DebugAspectsContext* pCtx = &(it->second);
  174.  
  175.                 for (TDebugEntities::iterator iter = pCtx->entities.begin(); iter != pCtx->entities.end(); ++iter)
  176.                 {
  177.                         DebugAspectsEntity* pEnt = &(iter->second);
  178.  
  179.                         for (int i = 0; i < MAX_ASPECTS; ++i)
  180.                         {
  181.                                 float fCurrRate = (float)pEnt->aspectChangeCount[i] - (float)pEnt->aspectLastCount[i];
  182.                                 if (fCurrRate > 0)
  183.                                         pEnt->entityTTL[i] = MAX_TTL;
  184.  
  185.                                 float fSec = fDiffTimeMsec / (float)UPDATE_DIFF_MSEC;
  186.                                 fCurrRate = fCurrRate / fSec;
  187.                                 pEnt->aspectChangeRate[i] = (pEnt->aspectChangeRate[i] + fCurrRate) / 2.0f;
  188.                                 pEnt->aspectLastCount[i] = pEnt->aspectChangeCount[i];
  189.                         }
  190.                 }
  191.         }
  192. }
  193.  
  194. void CNetDebug::UpdateRMI(float fDiffTimeMSec)
  195. {
  196.         for (TDebugRMI::iterator it = m_rmi.begin(); it != m_rmi.end(); ++it)
  197.         {
  198.                 DebugRMIEntity* pEnt = &(it->second);
  199.  
  200.                 float fDiffBytes = (float)pEnt->totalSize - (float)pEnt->lastTotalSize;
  201.                 float fSec = fDiffTimeMSec / (float)UPDATE_DIFF_MSEC;
  202.                 pEnt->rate = (pEnt->rate + fDiffBytes / fSec) / 2.0f;
  203.  
  204.                 if (pEnt->rate > pEnt->peakRate)
  205.                         pEnt->peakRate = pEnt->rate;
  206.                 pEnt->lastTotalSize = pEnt->totalSize;
  207.         }
  208. }
  209.  
  210. void CNetDebug::ProcessTrap(DebugAspectsEntity& ent)
  211. {
  212.         if (0 == m_trapValue)
  213.                 return;
  214.  
  215.         for (int i = 0; i < MAX_ASPECTS; ++i)
  216.         {
  217.                 if (ent.aspectChangeRate[i] > m_trapValue)
  218.                 {
  219.                         gEnv->pSystem->debug_LogCallStack();
  220.                         m_trapValueCount--;
  221.  
  222.                         if (m_trapValueCount <= 0)
  223.                         {
  224.                                 m_trapValueCount = 1;
  225.                                 m_trapValue = 0;
  226.                         }
  227.                 }
  228.         }
  229. }
  230.  
  231. bool CNetDebug::ProcessFilter(const char* szClass, const char* szEntity)
  232. {
  233.         const char* szFilterClass = gEnv->pConsole->GetCVar("g_debugAspectFilterClass")->GetString();
  234.         const char* szFilterEntity = gEnv->pConsole->GetCVar("g_debugAspectFilterEntity")->GetString();
  235.  
  236.         if (*szFilterClass != '*' && strcmp(szClass, szFilterClass) != 0)
  237.                 return false;
  238.  
  239.         if (*szFilterEntity != '*' && strcmp(szEntity, szFilterEntity) != 0)
  240.                 return false;
  241.  
  242.         return true;
  243. }
  244.  
  245. void CNetDebug::DrawAspects()
  246. {
  247.         float xPos, yPos;
  248.         int row = 0;
  249.         int maxRow = 40;
  250.         float cellSize = 15.0f;
  251.         float color[] = { 0, 1, 0, 1 };
  252.  
  253.         xPos = cellSize;
  254.         yPos = cellSize * 5;
  255.  
  256.         for (TDebugAspects::iterator it = m_aspects.begin(); it != m_aspects.end(); ++it)
  257.         {
  258.                 DebugAspectsContext* pCtx = &(it->second);
  259.  
  260.                 for (TDebugEntities::iterator iter = pCtx->entities.begin(); iter != pCtx->entities.end(); ++iter)
  261.                 {
  262.                         DebugAspectsEntity* pEnt = &(iter->second);
  263.  
  264.                         if (!ProcessFilter(pCtx->sEntityClass.c_str(), pEnt->sEntityName.c_str()))
  265.                                 continue;
  266.  
  267.                         for (int i = 0; i < MAX_ASPECTS; ++i)
  268.                         {
  269.                                 if (pEnt->entityTTL[i] > 0)
  270.                                 {
  271.                                         char msg[256];
  272.                                         ITextModeConsole* pTextModeConsole = gEnv->pSystem->GetITextModeConsole();
  273.  
  274.                                         if (yPos > cellSize * maxRow)
  275.                                         {
  276.                                                 cry_sprintf(msg, "There are more messages to track. Please use filter.");
  277.                                                 color[3] = color[0] = 1;
  278.                                                 IRenderAuxText::Draw2dLabel(xPos, yPos, 1.2f, &color[0], false, "%s", msg);
  279.                                         }
  280.                                         else
  281.                                         {
  282.                                                 cry_sprintf(msg, "Class [%s]: entity [%s] aspect [%s], total [%u], rate [%.2f]",
  283.                                                             pCtx->sEntityClass.c_str(),
  284.                                                             pEnt->sEntityName.c_str(),
  285.                                                             IdxToAspectString(i),
  286.                                                             pEnt->aspectChangeCount[i],
  287.                                                             pEnt->aspectChangeRate[i]);
  288.  
  289.                                                 color[3] = (pEnt->entityTTL[i]) / (float)MAX_TTL;
  290.                                                 IRenderAuxText::Draw2dLabel(xPos, yPos, 1.2f, &color[0], false, "%s", msg);
  291.                                                 if (pTextModeConsole)
  292.                                                         pTextModeConsole->PutText(0, row, msg);
  293.  
  294.                                                 row++;
  295.                                                 yPos += cellSize;
  296.                                         }
  297.                                         if (m_varDebug != 2)
  298.                                                 pEnt->entityTTL[i]--;
  299.                                 }
  300.                         }
  301.                 }
  302.         }
  303. }
  304.  
  305. void CNetDebug::DrawRMI()
  306. {
  307.         float xPos, yPos;
  308.         int row = 0;
  309.         int maxRow = 40;
  310.         float cellSize = 15.0f;
  311.         float color[] = { 0, 1, 0, 1 };
  312.  
  313.         xPos = cellSize;
  314.         yPos = cellSize * 5;
  315.  
  316.         for (TDebugRMI::iterator it = m_rmi.begin(); it != m_rmi.end(); ++it)
  317.         {
  318.                 DebugRMIEntity* pEnt = &(it->second);
  319.  
  320.                 char msg[256];
  321.  
  322.                 ITextModeConsole* pTextModeConsole = gEnv->pSystem->GetITextModeConsole();
  323.  
  324.                 if (yPos < cellSize * maxRow)
  325.                 {
  326.                         cry_sprintf(msg, "[%s]: invoke [%u] total [%" PRISIZE_T "], peak [%.2f], rate [%.2f]",
  327.                                     pEnt->sDesc.c_str(),
  328.                                     pEnt->invokeCount,
  329.                                     pEnt->totalSize,
  330.                                     pEnt->peakRate,
  331.                                     pEnt->rate);
  332.  
  333.                         IRenderAuxText::Draw2dLabel(xPos, yPos, 1.2f, &color[0], false, "%s", msg);
  334.                         if (pTextModeConsole)
  335.                                 pTextModeConsole->PutText(0, row, msg);
  336.  
  337.                         row++;
  338.                         yPos += cellSize;
  339.                 }
  340.         }
  341. }
  342.  
  343. void CNetDebug::Update()
  344. {
  345.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  346.  
  347.         if (!m_varDebug && !m_varDebugRMI)
  348.                 return;
  349.  
  350.         float fFrameTime = gEnv->pTimer->GetFrameStartTime().GetMilliSeconds();
  351.         float fDiffTime = fFrameTime - m_fLastTime;
  352.  
  353.         if (fDiffTime > UPDATE_DIFF_MSEC)
  354.         {
  355.                 m_fLastTime = fFrameTime;
  356.                 if (m_varDebug) UpdateAspectsRates(fDiffTime);
  357.                 if (m_varDebugRMI) UpdateRMI(fDiffTime);
  358.         }
  359.         if (m_varDebug) DrawAspects();
  360.         if (m_varDebugRMI) DrawRMI();
  361. }
  362.  
  363. #endif // ENABLE_NETDEBUG
  364.  
downloadNetDebug.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