123
This commit is contained in:
196
CryCommon/CrySizer.h
Normal file
196
CryCommon/CrySizer.h
Normal file
@@ -0,0 +1,196 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryEngine Source code
|
||||
//
|
||||
// File:CrySizer.h
|
||||
// Declaration and definition of the CrySizer class, which is used to
|
||||
// calculate the memory usage by the subsystems and components, to help
|
||||
// the artists keep the memory budged low.
|
||||
//
|
||||
// History:
|
||||
// December 03, 2002 : Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CRY_COMMON_CRY_SIZER_INTERFACE_HDR_
|
||||
#define _CRY_COMMON_CRY_SIZER_INTERFACE_HDR_
|
||||
|
||||
#ifdef GAMECUBE
|
||||
#include "GCDefines.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN64
|
||||
#include <string.h> // workaround for Amd64 compiler
|
||||
#endif
|
||||
|
||||
// prerequisities
|
||||
//#include <string>
|
||||
//#include <vector>
|
||||
|
||||
// flags applicable to the ICrySizer (retrieved via getFlags() method)
|
||||
//
|
||||
enum ICrySizerFlagsEnum
|
||||
{
|
||||
// if this flag is set, during getSize(), the subsystem must count all the objects
|
||||
// it uses in the other subsystems also
|
||||
CSF_RecurseSubsystems = 1 << 0,
|
||||
|
||||
CSF_Reserved1 = 1 << 1,
|
||||
CSF_Reserved2 = 1 << 2
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// interface ICrySizer
|
||||
// USAGE
|
||||
// An instance of this class is passed down to each and every component in the system.
|
||||
// Every component it's passed to optionally pushes its name on top of the
|
||||
// component name stack (thus ensuring that all the components calculated down
|
||||
// the tree will be assigned the correct subsystem/component name)
|
||||
// Every component must Add its size with one of the Add* functions, and Add the
|
||||
// size of all its subcomponents recursively
|
||||
// In order to push the component/system name on the name stack, the clients must
|
||||
// use the SIZER_COMPONENT_NAME macro or CrySizerComponentNameHelper class:
|
||||
//
|
||||
// void X::getSize (ICrySizer* pSizer)
|
||||
// {
|
||||
// SIZER_COMPONENT_NAME(pSizer, X);
|
||||
// if (!pSizer->Add (this))
|
||||
// return;
|
||||
// pSizer->Add (m_arrMySimpleArray);
|
||||
// pSizer->Add (m_setMySimpleSet);
|
||||
// m_pSubobject->getSize (pSizer);
|
||||
// }
|
||||
//
|
||||
// The Add* functions return bool. If they return true, then the object has been added
|
||||
// to the set for the first time, and you should go on recursively adding all its children.
|
||||
// If it returns false, then you can spare time and rather not go on into recursion;
|
||||
// however it doesn't reflect on the results: an object that's added more than once is
|
||||
// counted only once.
|
||||
//
|
||||
// WARNING:
|
||||
// If you have an array (pointer), you should Add its size with addArray
|
||||
class ICrySizer
|
||||
{
|
||||
public:
|
||||
// this class is used to push/pop the name to/from the stack automatically
|
||||
// (to exclude stack overruns or underruns at runtime)
|
||||
friend class CrySizerComponentNameHelper;
|
||||
|
||||
ICrySizer ():
|
||||
m_nFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ICrySizer () {}
|
||||
|
||||
// adds an object identified by the unique pointer (it needs not be
|
||||
// the actual object position in the memory, though it would be nice,
|
||||
// but it must be unique throughout the system and unchanging for this object)
|
||||
// RETURNS: true if the object has actually been added (for the first time)
|
||||
// and calculated
|
||||
virtual bool AddObject (const void* pIdentifier, size_t nSizeBytes) = 0;
|
||||
|
||||
template <typename T>
|
||||
bool Add (const T* pId, size_t num)
|
||||
{
|
||||
return AddObject(pId, num * sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Add (const T& rObject)
|
||||
{
|
||||
return AddObject (&rObject, sizeof(T));
|
||||
}
|
||||
|
||||
bool Add (const char* szText)
|
||||
{
|
||||
return AddObject(szText, strlen(szText)+1);
|
||||
}
|
||||
|
||||
template <class String>
|
||||
bool AddString (const String& strText)
|
||||
{
|
||||
if (!strText.empty())
|
||||
return AddObject (strText.c_str(), strText.length()+1);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#ifdef _XSTRING_
|
||||
template <class Elem, class Traits, class Allocator>
|
||||
bool Add (const std::basic_string<Elem, Traits, Allocator>& strText)
|
||||
{
|
||||
AddString (strText);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _STRING_
|
||||
bool Add (const string& strText)
|
||||
{
|
||||
AddString(strText);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Container>
|
||||
bool AddContainer (const Container& rContainer)
|
||||
{
|
||||
if (!rContainer.empty())
|
||||
return AddObject (&(*rContainer.begin()),rContainer.size()*sizeof(typename Container::value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns the flags
|
||||
unsigned GetFlags()const {return m_nFlags;}
|
||||
|
||||
protected:
|
||||
// these functions must operate on the component name stack
|
||||
// they are to be only accessible from within class CrySizerComponentNameHelper
|
||||
// which should be used through macro SIZER_COMPONENT_NAME
|
||||
virtual void Push (const char* szComponentName) = 0;
|
||||
// pushes the name that is the name of the previous component . (dot) this name
|
||||
virtual void PushSubcomponent (const char* szSubcomponentName) = 0;
|
||||
virtual void Pop () = 0;
|
||||
|
||||
unsigned m_nFlags;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// This is on-stack class that is only used to push/pop component names
|
||||
// to/from the sizer name stack.
|
||||
//
|
||||
// USAGE:
|
||||
//
|
||||
// Create an instance of this class at the start of a function, before
|
||||
// calling Add* methods of the sizer interface. Everything added in the
|
||||
// function and below will be considered this component, unless
|
||||
// explicitly set otherwise.
|
||||
//
|
||||
class CrySizerComponentNameHelper
|
||||
{
|
||||
public:
|
||||
// pushes the component name on top of the name stack of the given sizer
|
||||
CrySizerComponentNameHelper (ICrySizer* pSizer, const char* szComponentName, bool bSubcomponent):
|
||||
m_pSizer(pSizer)
|
||||
{
|
||||
if (bSubcomponent)
|
||||
pSizer->PushSubcomponent (szComponentName);
|
||||
else
|
||||
pSizer->Push (szComponentName);
|
||||
}
|
||||
|
||||
// pops the component name off top of the name stack of the sizer
|
||||
~CrySizerComponentNameHelper()
|
||||
{
|
||||
m_pSizer->Pop();
|
||||
}
|
||||
|
||||
protected:
|
||||
ICrySizer* m_pSizer;
|
||||
};
|
||||
|
||||
// use this to push (and automatically pop) the sizer component name at the beginning of the
|
||||
// getSize() function
|
||||
#define SIZER_COMPONENT_NAME(pSizerPointer, szComponentName) CrySizerComponentNameHelper __sizerHelper(pSizerPointer, szComponentName, false)
|
||||
#define SIZER_SUBCOMPONENT_NAME(pSizerPointer, szComponentName) CrySizerComponentNameHelper __sizerHelper(pSizerPointer, szComponentName, true)
|
||||
|
||||
#endif //_CRY_COMMON_CRY_SIZER_INTERFACE_HDR_
|
||||
Reference in New Issue
Block a user