hkStatisticsCollector.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:12k
源码类别:
其他游戏
开发平台:
Visual C++
- /*
- *
- * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
- * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
- * 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.
- *
- */
- #ifndef HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
- #define HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
- #include <Common/Base/Container/PointerMap/hkPointerMap.h>
- template<typename T> class hkObjectArray;
- /// This is the interface to a statistics collector for Havok objects. Currently it only
- /// collects memory usage statistics but could be extended in future to collect other
- /// useful stats. Timing stats are collected separately through the hkMonitorStream.
- ///
- /// All hkReferencedObject in Havok (most user level objects) have the following virtual calls:
- ///
- /// verbatim
- /// virtual void calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const
- /// virtual const hkClass* getClassType() const
- /// endverbatim
- ///
- /// The getClassType method provides a way to determine the exact type of a class. The default implementation
- /// of getClassType will return HK_NULL. In this situation if the type is serialized an implementation of hkStatisticsCollector
- /// may still be able to determine the type by looking up the type based on the vtbl. Thus in most circumstances
- /// if a serialized type is being used, using the default behavior of returning HK_NULL, will produce the correct
- /// result. To make a non serialized track memory - this method should be implemented. Care must be taken with any derived type
- /// to make sure it also implements the method, else the wrong type could be returned. The setting up of the hkClass
- /// information for a non serialized type can be achieved by placing
- ///
- /// verbatim extern const hkClass YourClassNameClass; endverbatim
- ///
- /// in the header - before your class. Implementing the getClassTypeMethod to return the type
- ///
- /// verbatim virtual const hkClass* getClassType() const { return &YourClassNameClass; } endverbatim
- ///
- /// Finally the type needs to be implemented in the .cpp file. Place the following after your header includes
- ///
- /// verbatim HK_REFLECTION_DEFINE_STUB_VIRTUAL(YourClassName, hkReferencedObject); endverbatim
- ///
- /// The second parameter to the macro - should be the base class that YouClassName derived from.
- ///
- /// The 'calcContentStatistics' methods purpose is to inform a hkStatisticsCollector interface about all of the
- /// additional memory consumed internally by a class. The method should exclude
- /// the memory taken up by the object itself (the object could be embedded in another object or on the stack).
- ///
- /// If the type is serialized, and all of the additional memory consuming
- /// members (such as arrays, and pointers) are also serialized, then the default implementation will automatically
- /// track all of the memory usage using hkStatisticsCollectorUtil which uses the serialization reflection in
- /// order to track memory. If the class contains some members which aren't serialized but need to be tracked, then
- /// the appropriate calls with the memory to track can be made on the hkStatisticsCollector. The remainder of the serialized
- /// types members can be tracked by
- ///
- /// verbatim hkStatisticsCollectorUtil::addClassContents(const void* obj, const hkClass& cls, hkStatisticsCollector* collector); endverbatim
- ///
- /// Finally a call to the parent classes implementation of calcContentStatistics, should be made, with the parents
- /// class type. Passing the parents class type will ensure if the parents implementation is the hkStatisticsCollectorUtil
- /// implementation, then the correct memory will be followed.
- ///
- /// On a class which doesn't implement serialization, the same two steps should be made - first tell the
- /// hkStatisticsCollector of any additional memory cosumed by just this classes implementation, and then call the parents
- /// implementation. For example
- ///
- /// verbatim
- /// class MyDerived: public: MyBase
- /// {
- /// ...
- /// virtual void calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const;
- /// virtual const hkClass* getClassType() const { return &MyDerivedClass; }
- /// ...
- /// protected:
- /// hkArray<int> m_array;
- /// hkpRigidBody* m_body;
- /// };
- ///
- /// void MyClass::calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const
- /// {
- /// // Add data for this class
- /// collector->addReferencedObject("body", m_body);
- /// collector->addArray("array", m_array);
- /// // Let the base class inform the collector of its memory consumption
- /// MyBase::calcContentStatistics(collector, &MyBaseClass);
- /// }
- /// endverbatim
- ///
- /// Normally the statistics collectors record the memory used the the object
- /// (m_memSizeAndFLags + all used (<= allocated, eg: hkArray:getSize())) and also the total
- /// allocated (m_memSizeAndFLags + all allocated (eg: hkArray::getCapacity()) ) so that
- /// you can work out not only the total memory required but also if there is much wasted memory.
- ///
- /// If an object is serialized in, its memory is is marked as not allocated. As it stands this memory
- /// is not tracked at all by the hkStatistics collector.
- ///
- /// Passing HK_NULL for a pointer to a piece of memory is acceptable - and just indicates that memory hasn't been
- /// allocated. Additionally an implementation of hkStatisticsCollector, should correctly handle if the same block is
- /// passed to the collector appropriately.
- class hkStatisticsCollector: public hkReferencedObject
- {
- public:
- /// Memory Type
- enum MemoryType
- {
- MEM_OBJECT, ///
- MEM_NORMAL, ///
- MEM_ALLOCATED, ///
- MEM_ARRAY, ///
- MEM_OTHER, ///
- MEM_LAST, ///
- };
- enum Flag
- {
- EXCLUDE_OBJECT_MEMORY = 0x1,
- };
- /// Add an object derived from hkReferencedObject. The field name and obj can be HK_NULL as necessary
- /// Flags is a combination of Flag flags or-ed together.
- virtual void addReferencedObject(const char* fieldName, const hkReferencedObject* obj, int flags = 0) = 0;
- /// Add an object not derived from hkReferencedObject. The pointer must point to the start of the object. NOTE that cls, and the pointer
- /// should point to the most derived type of the object to collect memory correctly.
- /// fieldName and the object can be HK_NULL as necessary.
- /// Flags is a combination of Flag flags or-ed together.
- virtual void addObject( const hkClass& cls, const char* fieldName, const void* obj, int flags = 0) = 0;
- /// Add a named chunk of memory for the current object. Both used and total allocated are usually given.
- virtual void addChunk(MemoryType type, const char* name, const void* chunkAddress, int usedSize, int allocatedSize = 0) = 0;
- /// Add a directory for logically grouping objects
- virtual void pushDir( const char* dirName ) = 0;
- /// End the current directory
- virtual void popDir() = 0;
- /// Add a piece of memory which was allocated using hkAllocate or hkAlignedAllocate
- /// (Implemented in hkThreadMemory.cpp)
- void addAllocated( const char* name, const void* chunkAddress );
- /// Add a normal chunk
- void addNormalChunk(const char* name, const void* p, int size, int allocated = 0);
- /// Add an object chunk
- void addObjectChunk(const char* name, const void* p, int size, int allocated = 0);
- /// Get the vtbl registry
- hkVtableClassRegistry* getVtblClassRegistry() const { return m_vtblRegistry; }
- /// Returns the size of an allocated object
- int getReferencedObjectSize(const hkReferencedObject* obj);
- /// Returns the amount of memory that is allocated for a size of an actual allocation
- /// (The allocator generally uses more space than the allocation request asks for)
- static int HK_CALL getAllocatedSize(int size);
- /// A convenience templated function to allow an hkArray to be easily added.
- template<typename T>
- HK_FORCE_INLINE void addArray( const char* name, const hkArray<T>& array )
- {
- if ( !(array.m_capacityAndFlags & array.DONT_DEALLOCATE_FLAG) )
- {
- int allocated = getAllocatedSize(array.getCapacity() * hkSizeOf(T));
- addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), allocated );
- }
- }
- template<typename T>
- HK_FORCE_INLINE void addArray( const char* name, const hkObjectArray<T>& array )
- {
- addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), array.getCapacity() * hkSizeOf(T) );
- }
- template<typename T>
- HK_FORCE_INLINE void addSmallArray( const char* name, const hkSmallArray<T>& array )
- {
- if ( !(array.m_capacityAndFlags & array.DONT_DEALLOCATE_FLAG) )
- {
- // Just assume the allocated is the same as used - as can't use the 'getAllocatedSize' as memory allocation
- // is from a specialized allocator
- addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), array.getCapacity() * hkSizeOf(T) );
- }
- }
- template<typename T>
- HK_FORCE_INLINE void addObjectArray( const char* name, const hkObjectArray<T>& array )
- {
- if ( !(array.m_array.m_capacityAndFlags & array.m_array.DONT_DEALLOCATE_FLAG) )
- {
- int allocated = getAllocatedSize(array.getCapacity() * hkSizeOf(T));
- addChunk( MEM_ARRAY, name, array.begin(), array.getSize() * hkSizeOf(T), allocated );
- }
- }
- template<typename KEY, typename VALUE>
- HK_FORCE_INLINE void addPointerMap( const char* name, const hkPointerMap<KEY,VALUE>& map )
- {
- int used = map.getMemSize();
- int allocated = getAllocatedSize(used);
- addChunk( MEM_NORMAL, name, map.getMemStart(), used, allocated );
- }
- /// Find the type - first thru calling the getClassType on the obj, and then using the registry if there is one set up
- const hkClass* findClassType(const hkReferencedObject* obj);
- /// Return the memory type as a string
- static const char* HK_CALL memoryTypeToCstring(MemoryType type);
- /// Turn memory size to text
- static void HK_CALL memorySizeToText(int size, hkString& stringOut);
- /// Ctor. Pass in the vtblClassRegistry that will be used for type lookup. Can pass in HK_NULL.
- /// NOTE: vtblReg is not reference counted, but must be maintained for the life of the collector
- hkStatisticsCollector(hkVtableClassRegistry* vtblReg);
- /// Dtor
- ~hkStatisticsCollector();
- protected:
- void addReferencedObjectMemory(const hkReferencedObject* obj, int flags);
- void addObjectMemory(const hkClass& cls, const void* obj, int flags);
- public:
- /// A client data which can be used to pass information from the parent to the child.
- /// For children of hkpWorld this points to the hkpCollisionInput.
- const void* m_clientData;
- hkVtableClassRegistry* m_vtblRegistry;
- /// If this is true, packfile memory will also be counted.
- bool m_includePackfileMemory;
- };
- #endif // HKBASE_HKMONITOR_STATISTICS_COLLECTOR_H
- /*
- * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
- *
- * Confidential Information of Havok. (C) Copyright 1999-2009
- * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
- * Logo, and the Havok buzzsaw logo are trademarks of Havok. Title, ownership
- * rights, and intellectual property rights in the Havok software remain in
- * Havok and/or its suppliers.
- *
- * Use of this software for evaluation purposes is subject to and indicates
- * acceptance of the End User licence Agreement for this product. A copy of
- * the license is included with this software and is also available at www.havok.com/tryhavok.
- *
- */