hkStatisticsCollector.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:12k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. #ifndef HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
  9. #define HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
  10. #include <Common/Base/Container/PointerMap/hkPointerMap.h>
  11. template<typename T> class hkObjectArray;
  12. /// This is the interface to a statistics collector for Havok objects. Currently it only
  13. /// collects memory usage statistics but could be extended in future to collect other
  14. /// useful stats. Timing stats are collected separately through the hkMonitorStream.
  15. ///
  16. /// All hkReferencedObject in Havok (most user level objects) have the following virtual calls:
  17. ///
  18. /// verbatim
  19. ///    virtual void calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const
  20. ///    virtual const hkClass* getClassType() const
  21. /// endverbatim
  22. ///
  23. /// The getClassType method provides a way to determine the exact type of a class. The default implementation
  24. /// of getClassType will return HK_NULL. In this situation if the type is serialized an implementation of hkStatisticsCollector
  25. /// may still be able to determine the type by looking up the type based on the vtbl. Thus in most circumstances
  26. /// if a serialized type is being used, using the default behavior of returning HK_NULL, will produce the correct
  27. /// result. To make a non serialized track memory - this method should be implemented. Care must be taken with any derived type
  28. /// to make sure it also implements the method, else the wrong type could be returned. The setting up of the hkClass
  29. /// information for a non serialized type can be achieved by placing
  30. ///
  31. /// verbatim extern const hkClass YourClassNameClass; endverbatim
  32. ///
  33. /// in the header - before your class. Implementing the getClassTypeMethod to return the type
  34. ///
  35. /// verbatim virtual const hkClass* getClassType() const { return &YourClassNameClass; } endverbatim
  36. ///
  37. /// Finally the type needs to be implemented in the .cpp file. Place the following after your header includes
  38. ///
  39. /// verbatim HK_REFLECTION_DEFINE_STUB_VIRTUAL(YourClassName, hkReferencedObject); endverbatim
  40. ///
  41. /// The second parameter to the macro - should be the base class that YouClassName derived from.
  42. ///
  43. /// The 'calcContentStatistics' methods purpose is to inform a hkStatisticsCollector interface about all of the
  44. /// additional memory consumed internally by a class. The method should exclude
  45. /// the memory taken up by the object itself (the object could be embedded in another object or on the stack).
  46. ///
  47. /// If the type is serialized, and all of the additional memory consuming
  48. /// members (such as arrays, and pointers) are also serialized, then the default implementation will automatically
  49. /// track all of the memory usage using hkStatisticsCollectorUtil which uses the serialization reflection in
  50. /// order to track memory. If the class contains some members which aren't serialized but need to be tracked, then
  51. /// the appropriate calls with the memory to track can be made on the hkStatisticsCollector. The remainder of the serialized
  52. /// types members can be tracked by
  53. ///
  54. /// verbatim hkStatisticsCollectorUtil::addClassContents(const void* obj, const hkClass& cls, hkStatisticsCollector* collector); endverbatim
  55. ///
  56. /// Finally a call to the parent classes implementation of calcContentStatistics, should be made, with the parents
  57. /// class type. Passing the parents class type will ensure if the parents implementation is the hkStatisticsCollectorUtil
  58. /// implementation, then the correct memory will be followed.
  59. ///
  60. /// On a class which doesn't implement serialization, the same two steps should be made - first tell the
  61. /// hkStatisticsCollector of any additional memory cosumed by just this classes implementation, and then call the parents
  62. /// implementation. For example
  63. ///
  64. /// verbatim
  65. /// class MyDerived: public: MyBase
  66. /// {
  67. ///      ...
  68. ///     virtual void calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const;
  69. ///     virtual const hkClass* getClassType() const { return &MyDerivedClass; }
  70. ///     ...
  71. ///     protected:
  72. ///     hkArray<int> m_array;
  73. ///     hkpRigidBody* m_body;
  74. /// };
  75. ///
  76. /// void MyClass::calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const
  77. /// {
  78. ///     // Add data for this class
  79. ///     collector->addReferencedObject("body", m_body);
  80. ///     collector->addArray("array", m_array);
  81. ///     // Let the base class inform the collector of its memory consumption
  82. ///     MyBase::calcContentStatistics(collector, &MyBaseClass);
  83. /// }
  84. /// endverbatim
  85. ///
  86. /// Normally the statistics collectors record the memory used the the object
  87. /// (m_memSizeAndFLags + all used (<= allocated, eg: hkArray:getSize())) and also the total
  88. /// allocated (m_memSizeAndFLags + all allocated (eg: hkArray::getCapacity()) ) so that
  89. /// you can work out not only the total memory required but also if there is much wasted memory.
  90. ///
  91. /// If an object is serialized in, its memory is is marked as not allocated. As it stands this memory
  92. /// is not tracked at all by the hkStatistics collector.
  93. ///
  94. /// Passing HK_NULL for a pointer to a piece of memory is acceptable - and just indicates that memory hasn't been
  95. /// allocated. Additionally an implementation of hkStatisticsCollector, should correctly handle if the same block is
  96. /// passed to the collector appropriately.
  97. class hkStatisticsCollector: public hkReferencedObject
  98. {
  99. public:
  100. /// Memory Type
  101.         enum MemoryType
  102.         {
  103.             MEM_OBJECT,         ///
  104.             MEM_NORMAL,         ///
  105.             MEM_ALLOCATED,      ///
  106.             MEM_ARRAY,          ///
  107.             MEM_OTHER,          ///
  108.             MEM_LAST,           ///
  109.         };
  110.         enum Flag
  111.         {
  112.             EXCLUDE_OBJECT_MEMORY = 0x1,        
  113.         };
  114.             /// Add an object derived from hkReferencedObject. The field name and obj can be HK_NULL as necessary
  115.             /// Flags is a combination of Flag flags or-ed together.
  116.         virtual void addReferencedObject(const char* fieldName, const hkReferencedObject* obj, int flags = 0) = 0;
  117.             /// Add an object not derived from hkReferencedObject. The pointer must point to the start of the object. NOTE that cls, and the pointer
  118.             /// should point to the most derived type of the object to collect memory correctly.
  119.             /// fieldName and the object can be HK_NULL as necessary.
  120.             /// Flags is a combination of Flag flags or-ed together.
  121.         virtual void addObject( const hkClass& cls, const char* fieldName, const void* obj, int flags = 0) = 0;
  122. /// Add a named chunk of memory for the current object. Both used and total allocated are usually given.
  123.         virtual void addChunk(MemoryType type, const char* name, const void* chunkAddress, int usedSize, int allocatedSize = 0) = 0;
  124. /// Add a directory for logically grouping objects
  125. virtual void pushDir( const char* dirName ) = 0;
  126. /// End the current directory
  127. virtual void popDir() = 0;
  128.             /// Add a piece of memory which was allocated using hkAllocate or hkAlignedAllocate
  129.             /// (Implemented in hkThreadMemory.cpp)
  130.         void addAllocated( const char* name, const void* chunkAddress );
  131.             /// Add a normal chunk
  132.         void addNormalChunk(const char* name, const void* p, int size, int allocated = 0);
  133.             /// Add an object chunk
  134.         void addObjectChunk(const char* name, const void* p, int size, int allocated = 0);
  135. /// Get the vtbl registry
  136. hkVtableClassRegistry* getVtblClassRegistry() const { return m_vtblRegistry; }
  137.             /// Returns the size of an allocated object
  138.         int getReferencedObjectSize(const hkReferencedObject* obj);
  139. /// Returns the amount of memory that is allocated for a size of an actual allocation
  140. /// (The allocator generally uses more space than the allocation request asks for)
  141. static int HK_CALL getAllocatedSize(int size);
  142. /// A convenience templated function to allow an hkArray to be easily added.
  143. template<typename T>
  144.         HK_FORCE_INLINE void addArray( const char* name, const hkArray<T>& array )
  145. {
  146. if ( !(array.m_capacityAndFlags & array.DONT_DEALLOCATE_FLAG) )
  147. {
  148. int allocated = getAllocatedSize(array.getCapacity() * hkSizeOf(T));
  149.                 addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), allocated );
  150. }
  151. }
  152. template<typename T>
  153. HK_FORCE_INLINE void addArray( const char* name, const hkObjectArray<T>& array )
  154. {
  155. addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), array.getCapacity() * hkSizeOf(T) );
  156. }
  157. template<typename T>
  158.         HK_FORCE_INLINE void addSmallArray( const char* name, const hkSmallArray<T>& array )
  159. {
  160. if ( !(array.m_capacityAndFlags & array.DONT_DEALLOCATE_FLAG) )
  161. {
  162. // Just assume the allocated is the same as used - as can't use the 'getAllocatedSize' as memory allocation
  163. // is from a specialized allocator
  164.                 addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), array.getCapacity() * hkSizeOf(T) );
  165. }
  166. }
  167. template<typename T>
  168.         HK_FORCE_INLINE void addObjectArray( const char* name, const hkObjectArray<T>& array )
  169. {
  170. if ( !(array.m_array.m_capacityAndFlags & array.m_array.DONT_DEALLOCATE_FLAG) )
  171. {
  172. int allocated = getAllocatedSize(array.getCapacity() * hkSizeOf(T));
  173.                 addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), allocated );
  174. }
  175. }
  176. template<typename KEY, typename VALUE>
  177.         HK_FORCE_INLINE void addPointerMap( const char* name, const hkPointerMap<KEY,VALUE>& map )
  178. {
  179. int used = map.getMemSize();
  180. int allocated = getAllocatedSize(used);
  181.             addChunk( MEM_NORMAL, name, map.getMemStart(), used, allocated );
  182. }
  183.             /// Find the type - first thru calling the getClassType on the obj, and then using the registry if there is one set up
  184.         const hkClass* findClassType(const hkReferencedObject* obj);
  185. /// Return the memory type as a string
  186. static const char* HK_CALL memoryTypeToCstring(MemoryType type);
  187. /// Turn memory size to text
  188. static void HK_CALL memorySizeToText(int size, hkString& stringOut);
  189. /// Ctor. Pass in the vtblClassRegistry that will be used for type lookup. Can pass in HK_NULL.
  190. /// NOTE: vtblReg is not reference counted, but must be maintained for the life of the collector
  191. hkStatisticsCollector(hkVtableClassRegistry* vtblReg);
  192. /// Dtor
  193. ~hkStatisticsCollector();
  194.     protected:
  195.         void addReferencedObjectMemory(const hkReferencedObject* obj, int flags);
  196.         void addObjectMemory(const hkClass& cls, const void* obj, int flags);
  197. public:
  198. /// A client data which can be used to pass information from the parent to the child.
  199. /// For children of hkpWorld this points to the hkpCollisionInput.
  200. const void* m_clientData;
  201. hkVtableClassRegistry* m_vtblRegistry;
  202. /// If this is true, packfile memory will also be counted.
  203. bool m_includePackfileMemory;
  204. };
  205. #endif // HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
  206. /*
  207. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  208. * Confidential Information of Havok.  (C) Copyright 1999-2009
  209. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  210. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  211. * rights, and intellectual property rights in the Havok software remain in
  212. * Havok and/or its suppliers.
  213. * Use of this software for evaluation purposes is subject to and indicates
  214. * acceptance of the End User licence Agreement for this product. A copy of
  215. * the license is included with this software and is also available at www.havok.com/tryhavok.
  216. */