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

@@ -1,4 +1,4 @@
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/DeckManager.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/Navigator.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PlayRestrictions.o objs/Pos.o objs/PrecompiledHeader.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/SimplePopup.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/DeckManager.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/Navigator.o objs/ObjectAnalytics.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PlayRestrictions.o objs/Pos.o objs/PrecompiledHeader.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/SimplePopup.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)

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

View File

@@ -8,6 +8,8 @@
using std::string;
SUPPORT_OBJECT_ANALYTICS(CardPrimitive)
CardPrimitive::CardPrimitive()
{
init();
@@ -44,6 +46,10 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
alias = source->alias;
}
CardPrimitive::~CardPrimitive()
{
}
int CardPrimitive::init()
{
basicAbilities.clear();

View File

@@ -268,6 +268,11 @@ void GameApp::LoadGameStates()
void GameApp::Destroy()
{
LOG("==Destroying GameApp==");
#ifdef TRACK_OBJECT_USAGE
ObjectAnalytics::DumpStatistics();
#endif
for (int i = GAME_STATE_MENU; i <= GAME_STATE_MAX - 1; i++)
{
if (mGameStates[i])

View File

@@ -245,6 +245,10 @@ void GameStateDuel::End()
{
DebugTrace("Ending GameStateDuel");
#ifdef TRACK_OBJECT_USAGE
ObjectAnalytics::DumpStatistics();
#endif
JRenderer::GetInstance()->EnableVSync(false);
if (!premadeDeck && mPlayers[0] && mPlayers[1])
{ // save the stats for the game

View File

@@ -13,6 +13,8 @@
using std::string;
SUPPORT_OBJECT_ANALYTICS(MTGCard)
MTGCard::MTGCard()
{
init();

View File

@@ -14,6 +14,8 @@
using namespace std;
SUPPORT_OBJECT_ANALYTICS(MTGCardInstance)
MTGCardInstance MTGCardInstance::AnyCard = MTGCardInstance();
MTGCardInstance MTGCardInstance::NoCard = MTGCardInstance();

View File

@@ -0,0 +1,38 @@
#include "PrecompiledHeader.h"
#include "ObjectAnalytics.h"
#include "CardPrimitive.h"
#include "DebugRoutines.h"
#include "MTGCard.h"
#include "MTGCardInstance.h"
namespace ObjectAnalytics
{
void DumpStatistics()
{
#ifdef TRACK_OBJECT_USAGE
DebugTrace("-----------------------------------------------------------");
DebugTrace("Object Usage Stats" << std::endl);
DebugTrace("CardPrimitive current count: " << InstanceCounter<CardPrimitive>::GetCurrentObjectCount());
DebugTrace("CardPrimitive current byte usage: " << InstanceCounter<CardPrimitive>::GetCurrentByteCount());
DebugTrace("CardPrimitive max count: " << InstanceCounter<CardPrimitive>::GetMaximumObjectCount());
DebugTrace("CardPrimitive max byte usage: " << InstanceCounter<CardPrimitive>::GetMaximumByteCount() << std::endl);
DebugTrace("MTGCard current count: " << InstanceCounter<MTGCard>::GetCurrentObjectCount());
DebugTrace("MTGCard current byte usage: " << InstanceCounter<MTGCard>::GetCurrentByteCount());
DebugTrace("MTGCard max count: " << InstanceCounter<MTGCard>::GetMaximumObjectCount());
DebugTrace("MTGCard max byte usage: " << InstanceCounter<MTGCard>::GetMaximumByteCount() << std::endl);
DebugTrace("MTGCardInstance current count: " << InstanceCounter<MTGCardInstance>::GetCurrentObjectCount());
DebugTrace("MTGCardInstance current byte usage: " << InstanceCounter<MTGCardInstance>::GetCurrentByteCount());
DebugTrace("MTGCardInstance max count: " << InstanceCounter<MTGCardInstance>::GetMaximumObjectCount());
DebugTrace("MTGCardInstance max byte usage: " << InstanceCounter<MTGCardInstance>::GetMaximumByteCount() << std::endl);
DebugTrace("-----------------------------------------------------------");
#endif
}
}

View File

@@ -379,6 +379,7 @@
<ClCompile Include="src\MTGPack.cpp" />
<ClCompile Include="src\MTGRules.cpp" />
<ClCompile Include="src\Navigator.cpp" />
<ClCompile Include="src\ObjectAnalytics.cpp" />
<ClCompile Include="src\OptionItem.cpp" />
<ClCompile Include="src\PhaseRing.cpp" />
<ClCompile Include="src\Player.cpp" />
@@ -492,6 +493,7 @@
<ClInclude Include="include\MTGPack.h" />
<ClInclude Include="include\MTGRules.h" />
<ClInclude Include="include\Navigator.h" />
<ClInclude Include="include\ObjectAnalytics.h" />
<ClInclude Include="include\OptionItem.h" />
<ClInclude Include="include\OSD.h" />
<ClInclude Include="include\PhaseRing.h" />

View File

@@ -301,6 +301,9 @@
<ClCompile Include="src\PlayRestrictions.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ObjectAnalytics.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\ActionElement.h">
@@ -624,6 +627,9 @@
<ClInclude Include="include\WResourceManagerImpl.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="include\ObjectAnalytics.h">
<Filter>inc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Makefile" />