Checkpoint on a utility helper class. Basically, if you have a class that you want to count the numbers of instances, you do this:

class Foo
#ifdef TRACK_OBJECT_USAGE
      : public InstanceCounter<Foo>
#endif

Then, use this macro somewhere in the class body:
SUPPORT_OBJECT_ANALYTICS(Foo)

Lastly, add whatever information you want to trace out to the function ObjectAnalytics::DumpStatistics().

Here's a sample of the output of what I've instrumented so far:

-----------------------------------------------------------
Object Usage Stats

CardPrimitive current count: 7899
CardPrimitive current byte usage: 2053740
CardPrimitive max count: 7908
CardPrimitive max byte usage: 2056080

MTGCard current count: 13973
MTGCard current byte usage: 670704
MTGCard max count: 13982
MTGCard max byte usage: 671136

MTGCardInstance current count: 180
MTGCardInstance current byte usage: 172080
MTGCardInstance max count: 189
MTGCardInstance max byte usage: 180684

-----------------------------------------------------------
This commit is contained in:
wrenczes@gmail.com
2011-04-23 05:16:53 +00:00
parent 8e4de36588
commit bd56723bc0
13 changed files with 167 additions and 1 deletions

View File

@@ -7,10 +7,14 @@
#include <map>
#include "ManaCost.h"
#include "ObjectAnalytics.h"
using namespace std;
class CardPrimitive
#ifdef TRACK_OBJECT_USAGE
: public InstanceCounter<CardPrimitive>
#endif
{
protected:
string lcname;
@@ -37,6 +41,7 @@ public:
vector<int>types;
CardPrimitive();
CardPrimitive(CardPrimitive * source);
virtual ~CardPrimitive();
void setColor(int _color, int removeAllOthers = 0);
void setColor(string _color, int removeAllOthers = 0);

View File

@@ -13,11 +13,16 @@
#include <vector>
#include <map>
#include "ObjectAnalytics.h"
class CardPrimitive;
using namespace std;
class MTGCard
#ifdef TRACK_OBJECT_USAGE
: public InstanceCounter<MTGCard>
#endif
{
protected:
friend class MTGSetInfo;

View File

@@ -25,6 +25,10 @@ struct Pos;
using namespace std;
class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable
#ifdef TRACK_OBJECT_USAGE
, public InstanceCounter<MTGCardInstance>
#endif
{
protected:
int untapping;

View File

@@ -0,0 +1,87 @@
#ifndef OBJECTANALYTICS_H
#define OBJECTANALYTICS_H
#ifdef DEBUG
#define TRACK_OBJECT_USAGE
#endif
#ifdef TRACK_OBJECT_USAGE
namespace ObjectAnalytics
{
/*
** See ObjectAnalytics.cpp for how to add additional objects to this function's dump
*/
void DumpStatistics();
}
#define SUPPORT_OBJECT_ANALYTICS(classname) \
template <> unsigned int InstanceCounter<classname>::sHighWaterMark = 0; \
template <> unsigned int InstanceCounter<classname>::sInstanceCount = 0; \
/**
** Helper class for tracking object instances.
** Usage:
** class Foo
** #ifdef TRACK_OBJECT_USAGE
** : public InstanceCounter<Foo>
** #endif
**
** Additionally, since the implementation uses static counters,
** somewhere in your class body, you need to put in the following macro:
** SUPPORT_OBJECT_ANALYTICS(Foo);
*/
template <typename T>
class InstanceCounter
{
public:
InstanceCounter()
{
if (sHighWaterMark < ++sInstanceCount)
sHighWaterMark = sInstanceCount;
}
InstanceCounter(const InstanceCounter&)
{
if (sHighWaterMark < ++sInstanceCount)
sHighWaterMark = sInstanceCount;
}
InstanceCounter& operator =(const InstanceCounter&)
{
}
~InstanceCounter()
{
--sInstanceCount;
}
static unsigned int GetCurrentObjectCount()
{
return sInstanceCount;
}
static unsigned int GetMaximumObjectCount()
{
return sHighWaterMark;
}
static unsigned int GetCurrentByteCount()
{
return sizeof(T) * sInstanceCount;
}
static unsigned int GetMaximumByteCount()
{
return sizeof(T) * sHighWaterMark;
}
static unsigned int sInstanceCount;
static unsigned int sHighWaterMark;
};
#else
#define SUPPORT_OBJECT_ANALYTICS(classname)
#endif //TRACK_OBJECT_USAGE
#endif //OBJECTANALYTICS_H