BVB Source Codes

CRYENGINE Show XMLCPB_AttrWriter.cpp Source code

Return Download CRYENGINE: download XMLCPB_AttrWriter.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4. *************************************************************************/
  5.  
  6. #include "StdAfx.h"
  7. #include "XMLCPB_AttrWriter.h"
  8. #include "XMLCPB_Writer.h"
  9.  
  10. #define CHECK_FOR_UNINITIALIZED_DATA 0
  11.  
  12. using namespace XMLCPB;
  13.  
  14. #ifdef XMLCPB_COLLECT_STATS
  15. CAttrWriter::SStatistics CAttrWriter::m_statistics;
  16. #endif
  17.  
  18. #if CHECK_FOR_UNINITIALIZED_DATA
  19. bool IsInitialized(uint32 val)
  20. {
  21.         return (val != 0xCDCDCDCD) && (val != 0xCCCCCCCC) && (val != 0xBAADF00D);
  22. }
  23.  
  24. bool IsInitialized(char val)
  25. {
  26.         return (val != 0xCD) && (val != 0xCC);
  27. }
  28.  
  29. template<typename T>
  30. bool IsInitialized(T val)
  31. {
  32.         return IsInitialized(*reinterpret_cast<uint32*>(&val));
  33. }
  34.  
  35.         #define ASSERT_INITIALIZED(cond, name) CRY_ASSERT_TRACE(IsInitialized(cond), ("Saving uninitialized variable %s", name))
  36. #else
  37.         #define ASSERT_INITIALIZED(cond, name)
  38. #endif
  39.  
  40. // Note: Without NO_INLINE gcc and clang would infer the input type range
  41. //       and statically optimize away the condition
  42. //       (e.g. for a bool value b, IsInRange(b, 0, 2) would be evaluated
  43. //       as true at compile-time)
  44. NO_INLINE bool IsInRange(int value, int lower, int upper)
  45. {
  46.         return (unsigned int)(value - lower) < upper - lower;
  47. }
  48.  
  49. //////////////////////////////////////////////////////////////////////////
  50.  
  51. CAttrWriter::CAttrWriter(CWriter& Writer)
  52.         : m_type(DT_INVALID)
  53.         , m_Writer(Writer)
  54. {
  55. }
  56.  
  57. //////////////////////////////////////////////////////////////////////////
  58.  
  59. void CAttrWriter::SetName(const char* pName)
  60. {
  61.         m_nameID = m_Writer.GetAttrNamesTable().GetStringID(pName);
  62. }
  63.  
  64. //////////////////////////////////////////////////////////////////////////
  65.  
  66. void CAttrWriter::Set(const char* pName, const char* pDataString)
  67. {
  68.         assert(pDataString);
  69.  
  70.         int size = strlen(pDataString);
  71.         if (size > MAX_SIZE_FOR_A_DATASTRING)
  72.         {
  73.                 Set(pName, (const uint8*)pDataString, size + 1, true); // store as raw data instead of pooled string  (+1 to include the ending 0). Uses immediateCopy to mimic the behavior of the normal strings, which are not guaranteed to be permanent (they can be local)
  74.                 return;
  75.         }
  76.  
  77.         ASSERT_INITIALIZED(pDataString[0], pName);
  78.         SetName(pName);
  79.  
  80.         StringID constantID = m_Writer.GetStrDataConstantsTable().GetStringID(pDataString, false);
  81.  
  82.         if (constantID == XMLCPB_INVALID_ID)
  83.         {
  84.                 m_type = DT_STR;
  85.                 m_data.m_dataStringID = m_Writer.GetStrDataTable().GetStringID(pDataString);
  86.         }
  87.         else
  88.         {
  89.                 m_type = eAttrDataType(DT_FIRST_CONST_STR + constantID);
  90.         }
  91. }
  92.  
  93. //////////////////////////////////////////////////////////////////////////
  94.  
  95. void CAttrWriter::Set(const char* pAttrName, int64 val)
  96. {
  97.         Set(pAttrName, (uint64)val);
  98. }
  99.  
  100. //////////////////////////////////////////////////////////////////////////
  101.  
  102. void CAttrWriter::Set(const char* pAttrName, uint64 val)
  103. {
  104.         ASSERT_INITIALIZED(val, pAttrName);
  105.         SetName(pAttrName);
  106.  
  107.         m_type = DT_INT64;
  108.         m_data.m_uint64 = val;
  109. }
  110.  
  111. //////////////////////////////////////////////////////////////////////////
  112.  
  113. void CAttrWriter::Set(const char* pAttrName, int val)
  114. {
  115.         ASSERT_INITIALIZED(val, pAttrName);
  116.         SetName(pAttrName);
  117.  
  118.         if (val >= 0 && val <= 10)
  119.         {
  120.                 m_type = eAttrDataType(DT_0 + val);
  121.                 return;
  122.         }
  123.         else if (val == 255)
  124.         {
  125.                 m_type = DT_255;
  126.                 return;
  127.         }
  128.         else if (val > 0)
  129.         {
  130.                 if (val < 256)
  131.                 {
  132.                         m_data.m_uint = val;
  133.                         m_type = DT_POS8;
  134.                         return;
  135.                 }
  136.                 if (val < 65536)
  137.                 {
  138.                         m_data.m_uint = val;
  139.                         m_type = DT_POS16;
  140.                         return;
  141.                 }
  142.         }
  143.         else
  144.         {
  145.                 if (val > -256)
  146.                 {
  147.                         m_data.m_uint = -val;
  148.                         m_type = DT_NEG8;
  149.                         return;
  150.                 }
  151.                 if (val > -65536)
  152.                 {
  153.                         m_data.m_uint = -val;
  154.                         m_type = DT_NEG16;
  155.                         return;
  156.                 }
  157.         }
  158.  
  159.         m_data.m_uint = val;
  160.         m_type = DT_INT32;
  161. }
  162.  
  163. void CAttrWriter::Set(const char* pAttrName, uint val)
  164. {
  165.         Set(pAttrName, int(val));
  166. }
  167.  
  168. void CAttrWriter::Set(const char* pAttrName, bool val)
  169. {
  170.         assert(IsInRange((int)val, 0, 2));
  171.  
  172.         SetName(pAttrName);
  173.         m_type = eAttrDataType(DT_0 + val);
  174. }
  175.  
  176. //////////////////////////////////////////////////////////////////////////
  177.  
  178. void CAttrWriter::Set(const char* pAttrName, float val)
  179. {
  180.         ASSERT_INITIALIZED(val, pAttrName);
  181.         if (val == 0)
  182.         {
  183.                 SetName(pAttrName);
  184.                 m_type = DT_0;
  185.                 return;
  186.         }
  187.  
  188.         if (fabsf(val) < 65536.0f) // fcmp but avoids FPE when val==MAX_FLOAT and abs(MIN_INT) problem if <-4Mb
  189.         {
  190.                 float val10 = val * 10.0f;
  191.                 float intPart = floorf(val10);
  192.                 if (val10 == intPart)
  193.                 {
  194.                         int vali = (int)intPart; // LHS
  195.                         int avali = abs(vali);
  196.                         if ((vali % 10) == 0)
  197.                         {
  198.                                 Set(pAttrName, vali / 10);
  199.                                 return;
  200.                         }
  201.                         else if (avali < 128)
  202.                         {
  203.                                 SetName(pAttrName);
  204.                                 m_data.m_uint = int(vali);
  205.                                 m_type = DT_F1_1DEC;
  206.                                 return;
  207.                         }
  208.                 }
  209.         }
  210.  
  211.         SetName(pAttrName);
  212.         m_data.m_float.v0 = val;
  213.         m_type = DT_F1;
  214. }
  215.  
  216. void CAttrWriter::Set(const char* pAttrName, const Vec2& _val)
  217. {
  218.         Vec3 val(_val.x, _val.y, 0);
  219.         Set(pAttrName, val);
  220. }
  221.  
  222. void CAttrWriter::Set(const char* pAttrName, const Ang3& _val)
  223. {
  224.         Vec3 val(_val.x, _val.y, _val.z);
  225.         Set(pAttrName, val);
  226. }
  227.  
  228. void CAttrWriter::Set(const char* pAttrName, const Vec3& val)
  229. {
  230.         ASSERT_INITIALIZED(val.x, pAttrName);
  231.         ASSERT_INITIALIZED(val.y, pAttrName);
  232.         ASSERT_INITIALIZED(val.z, pAttrName);
  233.         SetName(pAttrName);
  234.         // TODO: this sequence of if's could be optimized, but it would get harder to understand. check if it is worth it.
  235.         if (val.x == 0 && val.y == 0 && val.z == 0)
  236.         {
  237.                 m_type = DT_0;
  238.                 return;
  239.         }
  240.  
  241.         if (val.x == 1 && val.y == 0 && val.z == 0)
  242.         {
  243.                 m_type = DT_F3_100;
  244.                 return;
  245.         }
  246.  
  247.         if (val.x == 0 && val.y == 1 && val.z == 0)
  248.         {
  249.                 m_type = DT_F3_010;
  250.                 return;
  251.         }
  252.  
  253.         if (val.x == 0 && val.y == 0 && val.z == 1)
  254.         {
  255.                 m_type = DT_F3_001;
  256.                 return;
  257.         }
  258.  
  259.         {
  260.                 uint32 numVals = 0;
  261.                 m_data.m_floatSemiConstant.constMask = 0;
  262.                 PackFloatInSemiConstType(val.x, 0, numVals);
  263.                 PackFloatInSemiConstType(val.y, 1, numVals);
  264.                 PackFloatInSemiConstType(val.z, 2, numVals);
  265.                 if (numVals == 2)
  266.                 {
  267.                         m_type = DT_F3_1CONST;
  268.                         return;
  269.                 }
  270.                 if (numVals == 1)
  271.                 {
  272.                         m_type = DT_F3_2CONST;
  273.                         return;
  274.                 }
  275.                 if (numVals == 0)
  276.                 {
  277.                         m_type = DT_F3_3CONST;
  278.                         return;
  279.                 }
  280.         }
  281.  
  282.         m_type = DT_F3;
  283. }
  284.  
  285. void CAttrWriter::Set(const char* pAttrName, const Quat& val)
  286. {
  287.         ASSERT_INITIALIZED(val.v.x, pAttrName);
  288.         ASSERT_INITIALIZED(val.v.y, pAttrName);
  289.         ASSERT_INITIALIZED(val.v.z, pAttrName);
  290.         ASSERT_INITIALIZED(val.w, pAttrName);
  291.  
  292.         SetName(pAttrName);
  293.         if (val.v.x == 0 && val.v.y == 0 && val.v.z == 0 && val.w == 0)
  294.         {
  295.                 m_type = DT_0;
  296.                 return;
  297.         }
  298.  
  299.         {
  300.                 uint32 numVals = 0;
  301.                 m_data.m_floatSemiConstant.constMask = 0;
  302.                 PackFloatInSemiConstType(val.v.x, 0, numVals);
  303.                 PackFloatInSemiConstType(val.v.y, 1, numVals);
  304.                 PackFloatInSemiConstType(val.v.z, 2, numVals);
  305.                 PackFloatInSemiConstType(val.w, 3, numVals);
  306.                 if (numVals == 3)
  307.                 {
  308.                         m_type = DT_F4_1CONST;
  309.                         return;
  310.                 }
  311.                 if (numVals == 2)
  312.                 {
  313.                         m_type = DT_F4_2CONST;
  314.                         return;
  315.                 }
  316.                 if (numVals == 1)
  317.                 {
  318.                         m_type = DT_F4_3CONST;
  319.                         return;
  320.                 }
  321.                 if (numVals == 0)
  322.                 {
  323.                         m_type = DT_F4_4CONST;
  324.                         return;
  325.                 }
  326.         }
  327.  
  328.         m_type = DT_F4;
  329. }
  330.  
  331. void CAttrWriter::Set(const char* pAttrName, const uint8* data, uint32 len, bool needInmediateCopy)
  332. {
  333.         assert(data && len > 0);
  334.         ASSERT_INITIALIZED(data[0], pAttrName);
  335.  
  336.         SetName(pAttrName);
  337.  
  338.         m_data.m_rawData.size = len;
  339.         m_type = DT_RAWDATA;
  340.  
  341.         if (!needInmediateCopy)
  342.         {
  343.                 m_data.m_rawData.data = data;
  344.                 m_data.m_rawData.allocatedData = NULL;
  345.         }
  346.         else
  347.         {
  348.                 m_data.m_rawData.allocatedData = new uint8[m_data.m_rawData.size];
  349.                 memcpy(m_data.m_rawData.allocatedData, data, m_data.m_rawData.size);
  350.                 m_data.m_rawData.data = NULL;
  351.         }
  352. }
  353.  
  354. //////////////////////////////////////////////////////////////////////////
  355. // in a "multi float semi constant type" there is first a byte, separated in 4 2-bit-fields. Each field corresponds to one of the multifloat components, and it indicates if that
  356. // if that float is a constant (and which constant) or if is a random value. If is a random value, it is stored as a full float.
  357. // this function, called once for every member of the multifloat struct, builds the byte header and store the floats in the apropiate positions.
  358.  
  359. void CAttrWriter::PackFloatInSemiConstType(float val, uint32 ind, uint32& numVals)
  360. {
  361.         uint32 type = PFSC_VAL;
  362.  
  363.         if (val == 0 || val == -0)
  364.                 type = PFSC_0;
  365.         else if (val == 1)
  366.                 type = PFSC_1;
  367.         else if (val == -1)
  368.                 type = PFSC_N1;
  369.  
  370.         if (type == PFSC_VAL)
  371.         {
  372.                 assert(numVals < 4);
  373.                 m_data.m_floatSemiConstant.v[numVals] = val;
  374.                 ++numVals;
  375.         }
  376.  
  377.         type = type << (ind * 2);
  378.         m_data.m_floatSemiConstant.constMask |= type;
  379. }
  380.  
  381. //////////////////////////////////////////////////////////////////////////
  382. // header refers to the 16 bits value that holds the type+tag
  383.  
  384. uint16 CAttrWriter::CalcHeader() const
  385. {
  386.         assert(m_type != DT_INVALID);
  387.         assert(m_nameID <= MAX_NAMEID);
  388.         uint16 header = (m_nameID << BITS_TYPEID) | m_type;
  389.         return header;
  390. }
  391.  
  392. //////////////////////////////////////////////////////////////////////////
  393. // compacting is the process of converting the node information into final binary data, and store it into the writer main buffer.
  394. // nameID : 10 bits  (1023 id max)
  395. // typeID : 6 bits  (63 max )
  396.  
  397. void CAttrWriter::Compact()
  398. {
  399.         static_assert(uint32(DT_NUMTYPES) <= uint32(MAX_NUM_TYPES), "Too many types!");
  400.         static_assert(BITS_TYPEID + BITS_NAMEID <= 16, "Wrong bit positions!");
  401.  
  402. #ifdef XMLCPB_COLLECT_STATS
  403.         if (m_Writer.IsSavingIntoFile())
  404.                 AddDataToStatistics();
  405. #endif
  406.  
  407.         if (GetDataTypeSize(m_type) == 0)
  408.                 return;
  409.  
  410.         CBufferWriter& buffer = m_Writer.GetMainBuffer();
  411.  
  412.         // data
  413.         switch (m_type)
  414.         {
  415.         case DT_STR:
  416.                 {
  417.                         assert(m_data.m_dataStringID < MAX_NUM_STRDATA);
  418.                         uint16 dataStringID = m_data.m_dataStringID;
  419.                         buffer.AddDataEndianAware(dataStringID);
  420.                         break;
  421.                 }
  422.  
  423.         case DT_INT32:
  424.                 {
  425.                         buffer.AddDataEndianAware(m_data.m_uint);
  426.                         break;
  427.                 }
  428.  
  429.         case DT_INT64:
  430.                 {
  431.                         buffer.AddDataEndianAware(m_data.m_uint64);
  432.                         break;
  433.                 }
  434.  
  435.         case DT_POS16:
  436.         case DT_NEG16:
  437.                 {
  438.                         uint16 val = m_data.m_uint;
  439.                         buffer.AddDataEndianAware(val);
  440.                         break;
  441.                 }
  442.  
  443.         case DT_POS8:
  444.         case DT_NEG8:
  445.                 {
  446.                         uint8 val = m_data.m_uint;
  447.                         buffer.AddData(&val, sizeof(val));
  448.                         break;
  449.                 }
  450.  
  451.         case DT_F1:
  452.                 {
  453.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  454.                         break;
  455.                 }
  456.  
  457.         case DT_F1_1DEC:
  458.                 {
  459.                         uint8 val = m_data.m_uint;
  460.                         buffer.AddData(&val, sizeof(val));
  461.                         break;
  462.                 }
  463.  
  464.         case DT_F3:
  465.                 {
  466.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  467.                         buffer.AddData(&m_data.m_float.v1, sizeof(m_data.m_float.v1));
  468.                         buffer.AddData(&m_data.m_float.v2, sizeof(m_data.m_float.v2));
  469.                         break;
  470.                 }
  471.  
  472.         case DT_F3_1CONST:
  473.                 {
  474.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  475.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  476.                         buffer.AddData(&m_data.m_float.v1, sizeof(m_data.m_float.v1));
  477.                         break;
  478.                 }
  479.  
  480.         case DT_F3_2CONST:
  481.                 {
  482.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  483.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  484.                         break;
  485.                 }
  486.  
  487.         case DT_F3_3CONST:
  488.                 {
  489.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  490.                         break;
  491.                 }
  492.  
  493.         case DT_F4:
  494.                 {
  495.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  496.                         buffer.AddData(&m_data.m_float.v1, sizeof(m_data.m_float.v1));
  497.                         buffer.AddData(&m_data.m_float.v2, sizeof(m_data.m_float.v2));
  498.                         buffer.AddData(&m_data.m_float.v3, sizeof(m_data.m_float.v3));
  499.                         break;
  500.                 }
  501.  
  502.         case DT_F4_1CONST:
  503.                 {
  504.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  505.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  506.                         buffer.AddData(&m_data.m_float.v1, sizeof(m_data.m_float.v1));
  507.                         buffer.AddData(&m_data.m_float.v2, sizeof(m_data.m_float.v2));
  508.                         break;
  509.                 }
  510.         case DT_F4_2CONST:
  511.                 {
  512.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  513.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  514.                         buffer.AddData(&m_data.m_float.v1, sizeof(m_data.m_float.v1));
  515.                         break;
  516.                 }
  517.         case DT_F4_3CONST:
  518.                 {
  519.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  520.                         buffer.AddData(&m_data.m_float.v0, sizeof(m_data.m_float.v0));
  521.                         break;
  522.                 }
  523.         case DT_F4_4CONST:
  524.                 {
  525.                         buffer.AddData(&m_data.m_floatSemiConstant.constMask, sizeof(m_data.m_floatSemiConstant.constMask));
  526.                         break;
  527.                 }
  528.  
  529.         case DT_RAWDATA:
  530.                 {
  531.                         uint32 size = m_data.m_rawData.size;
  532.                         buffer.AddData(&size, sizeof(size));
  533.                         buffer.AddData(m_data.m_rawData.data ? m_data.m_rawData.data : m_data.m_rawData.allocatedData, m_data.m_rawData.size);
  534.                         break;
  535.                 }
  536.  
  537.         default:
  538.                 assert(false);
  539.                 break;
  540.         }
  541. }
  542.  
  543. //////////////////////////////////////////////////////////////////////////
  544. // for debug purposes
  545. const char* CAttrWriter::GetName() const
  546. {
  547.         return m_Writer.GetAttrNamesTable().GetString(m_nameID);
  548. }
  549.  
  550. //////////////////////////////////////////////////////////////////////////
  551. // for debug purposes
  552. const char* CAttrWriter::GetStrData() const
  553. {
  554.         if (m_type == DT_STR)
  555.         {
  556.                 return m_Writer.GetStrDataTable().GetString(m_data.m_dataStringID);
  557.         }
  558.         if (IsTypeStrConstant(m_type))
  559.                 return m_Writer.GetStrDataConstantsTable().GetString(GetStringConstantID(m_type));
  560.  
  561.         assert(false);
  562.  
  563.         return NULL;
  564. }
  565.  
  566. //////////////////////////////////////////////////////////////////////////
  567. #ifdef XMLCPB_CHECK_HARDCODED_LIMITS
  568. void CAttrWriter::CheckHardcodedLimits(int attrIndex)
  569. {
  570.         if (m_nameID > MAX_NAMEID)
  571.         {
  572.                 CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "XMLCPB ERROR: IDAttrName overflow: %u / %d (attr index:%d)", m_nameID, MAX_NAMEID, attrIndex);
  573.                 m_Writer.NotifyInternalError();
  574.         }
  575.         else if (m_type == DT_STR && m_data.m_dataStringID > MAX_STRDATAID)
  576.         {
  577.                 CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "XMLCPB ERROR: StrDataId overflow: %u / %d (attr index:%d)", m_data.m_dataStringID, MAX_STRDATAID, attrIndex);
  578.                 m_Writer.NotifyInternalError();
  579.         }
  580. }
  581.  
  582. #endif
  583.  
  584. //////////////////////////////////////////////////////////////////////////
  585. // for debug/profiling purposes only
  586. #ifdef XMLCPB_COLLECT_STATS
  587. void CAttrWriter::AddDataToStatistics()
  588. {
  589.         m_statistics.m_typeCount[m_type]++;
  590.  
  591.         switch (m_type)
  592.         {
  593.         case DT_STR:
  594.                 {
  595.                         StringID stringId = /*IsTypeStrConstant(m_type) ? XMLCPB_INVALID_ID : */ m_data.m_dataStringID;
  596.                         std::map<StringID, uint>::iterator iter = m_statistics.m_stringIDMap.find(stringId);
  597.                         if (iter != m_statistics.m_stringIDMap.end())
  598.                                 iter->second++;
  599.                         else
  600.                                 m_statistics.m_stringIDMap[stringId] = 1;
  601.                         break;
  602.                 }
  603.  
  604.         case DT_INT32:
  605.                 {
  606.  
  607.                         std::map<uint32, uint>::iterator iter = m_statistics.m_uint32Map.find(m_data.m_uint);
  608.                         if (iter != m_statistics.m_uint32Map.end())
  609.                                 iter->second++;
  610.                         else
  611.                                 m_statistics.m_uint32Map[m_data.m_uint] = 1;
  612.                         break;
  613.                 }
  614.  
  615.         case DT_INT64:
  616.                 {
  617.                         std::map<uint64, uint>::iterator iter = m_statistics.m_uint64Map.find(m_data.m_uint64);
  618.                         if (iter != m_statistics.m_uint64Map.end())
  619.                                 iter->second++;
  620.                         else
  621.                                 m_statistics.m_uint64Map[m_data.m_uint64] = 1;
  622.                         break;
  623.                 }
  624.  
  625.         case DT_F1:
  626.                 {
  627.                         std::map<float, uint>::iterator iter = m_statistics.m_floatMap.find(m_data.m_float.v0);
  628.                         if (iter != m_statistics.m_floatMap.end())
  629.                                 iter->second++;
  630.                         else
  631.                                 m_statistics.m_floatMap[m_data.m_float.v0] = 1;
  632.                         break;
  633.                 }
  634.  
  635.         case DT_F3:
  636.                 {
  637.                         SFloat3 val(m_data.m_float.v0, m_data.m_float.v1, m_data.m_float.v2);
  638.                         std::map<SFloat3, uint>::iterator iter = m_statistics.m_float3Map.find(val);
  639.                         if (iter != m_statistics.m_float3Map.end())
  640.                                 iter->second++;
  641.                         else
  642.                                 m_statistics.m_float3Map[val] = 1;
  643.                         break;
  644.                 }
  645.  
  646.         case DT_F4:
  647.                 {
  648.                         SFloat4 val(m_data.m_float.v0, m_data.m_float.v1, m_data.m_float.v2, m_data.m_float.v3);
  649.                         std::map<SFloat4, uint>::iterator iter = m_statistics.m_float4Map.find(val);
  650.                         if (iter != m_statistics.m_float4Map.end())
  651.                                 iter->second++;
  652.                         else
  653.                                 m_statistics.m_float4Map[val] = 1;
  654.                         break;
  655.                 }
  656.         }
  657. }
  658.  
  659. //////////////////////////////////////////////////////////////////////////
  660. // for debug/profiling purposes only
  661. void CAttrWriter::WriteFileStatistics(const CStringTableWriter& stringTable)
  662. {
  663.         FILE* pFile = gEnv->pCryPak->FOpen("DataAttrStatistics.txt", "wb");
  664.         assert(pFile);
  665.  
  666.         string strTmp;
  667.  
  668.         for (int i = 0; i < DT_NUMTYPES; i++)
  669.         {
  670.                 strTmp.Format(" type: %s   times: %d \n", GetDataTypeName(eAttrDataType(i)), m_statistics.m_typeCount[i]);
  671.                 gEnv->pCryPak->FWrite(strTmp.c_str(), strTmp.size(), 1, pFile);
  672.         }
  673.  
  674.         const int MIN_AMOUNT_FOR_FILE = 50;
  675.  
  676.         sortingMapType sortingMap;
  677.  
  678.         {
  679.                 sortingMap.clear();
  680.                 std::map<StringID, uint>::iterator iter = m_statistics.m_stringIDMap.begin();
  681.                 while (iter != m_statistics.m_stringIDMap.end())
  682.                 {
  683.                         if (iter->second > MIN_AMOUNT_FOR_FILE)
  684.                         {
  685.                                 const char* pStr = iter->first == XMLCPB_INVALID_ID ? "someConstant" : stringTable.GetString(iter->first);
  686.  
  687.                                 strTmp.Format("%s : %d\n", pStr, iter->second);
  688.                                 sortingMap.insert(std::pair<uint, string>(iter->second, strTmp));
  689.                         }
  690.                         ++iter;
  691.                 }
  692.                 WriteDataTypeEntriesStatistics(pFile, sortingMap, "\n------------data strings-----------------\n");
  693.         }
  694.  
  695.         {
  696.                 sortingMap.clear();
  697.                 std::map<uint32, uint>::iterator iter = m_statistics.m_uint32Map.begin();
  698.                 while (iter != m_statistics.m_uint32Map.end())
  699.                 {
  700.                         if (iter->second > MIN_AMOUNT_FOR_FILE)
  701.                         {
  702.                                 strTmp.Format("%d (%x) : %d\n", iter->first, iter->first, iter->second);
  703.                                 sortingMap.insert(std::pair<uint, string>(iter->second, strTmp));
  704.                         }
  705.                         ++iter;
  706.                 }
  707.                 WriteDataTypeEntriesStatistics(pFile, sortingMap, "\n------------uint32-----------------\n");
  708.         }
  709.  
  710.         {
  711.                 sortingMap.clear();
  712.                 std::map<float, uint>::iterator iter = m_statistics.m_floatMap.begin();
  713.                 while (iter != m_statistics.m_floatMap.end())
  714.                 {
  715.                         if (iter->second > MIN_AMOUNT_FOR_FILE)
  716.                         {
  717.                                 strTmp.Format("%f : %d\n", iter->first, iter->second);
  718.                                 sortingMap.insert(std::pair<uint, string>(iter->second, strTmp));
  719.                         }
  720.                         ++iter;
  721.                 }
  722.                 WriteDataTypeEntriesStatistics(pFile, sortingMap, "\n------------F1-----------------\n");
  723.         }
  724.  
  725.         {
  726.                 sortingMap.clear();
  727.                 std::map<SFloat3, uint>::iterator iter = m_statistics.m_float3Map.begin();
  728.                 while (iter != m_statistics.m_float3Map.end())
  729.                 {
  730.                         if (iter->second > MIN_AMOUNT_FOR_FILE)
  731.                         {
  732.                                 strTmp.Format("%f,%f,%f: %d\n", iter->first.v0, iter->first.v1, iter->first.v2, iter->second);
  733.                                 sortingMap.insert(std::pair<uint, string>(iter->second, strTmp));
  734.                         }
  735.                         ++iter;
  736.                 }
  737.                 WriteDataTypeEntriesStatistics(pFile, sortingMap, "\n------------F3-----------------\n");
  738.         }
  739.  
  740.         {
  741.                 sortingMap.clear();
  742.                 std::map<SFloat4, uint>::iterator iter = m_statistics.m_float4Map.begin();
  743.                 while (iter != m_statistics.m_float4Map.end())
  744.                 {
  745.                         if (iter->second > MIN_AMOUNT_FOR_FILE)
  746.                         {
  747.                                 strTmp.Format("%f,%f,%f,%f: %d\n", iter->first.v0, iter->first.v1, iter->first.v2, iter->first.v3, iter->second);
  748.                                 sortingMap.insert(std::pair<uint, string>(iter->second, strTmp));
  749.                         }
  750.                         ++iter;
  751.                 }
  752.                 WriteDataTypeEntriesStatistics(pFile, sortingMap, "\n------------F4-----------------\n");
  753.         }
  754.  
  755.         gEnv->pCryPak->FClose(pFile);
  756. }
  757.  
  758. // for debug/profiling purposes only
  759. void CAttrWriter::WriteDataTypeEntriesStatistics(FILE* pFile, const sortingMapType& sortingMap, const char* pHeaderStr)
  760. {
  761.         gEnv->pCryPak->FWrite(pHeaderStr, strlen(pHeaderStr), 1, pFile);
  762.         sortingMapType::const_iterator iterSorted = sortingMap.begin();
  763.         while (iterSorted != sortingMap.end())
  764.         {
  765.                 const string& strTmp = iterSorted->second;
  766.                 gEnv->pCryPak->FWrite(strTmp.c_str(), strTmp.size(), 1, pFile);
  767.                 ++iterSorted;
  768.         }
  769. }
  770. #endif
  771.  
downloadXMLCPB_AttrWriter.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