1
1
forked from 0ad/0ad
0ad/source/ps/Profile.h
Ykkrosh fa45d214b3 # Added support for COLLADA skeletal animations.
Moved COLLADA-loading code into separate class, since it now handles
both PMD and PSA.
Desingletonised CSkeletonAnimManager, moved into CGameView.
Made Atlas load its icons with buffered IO, for possible efficiency.

This was SVN commit r4934.
2007-03-01 18:52:53 +00:00

171 lines
4.5 KiB
C++

/**
* =========================================================================
* File : Profile.h
* Project : Pyrogenesis
* Description : GPG3-style hierarchical profiler
*
* @author Mark Thompson (mark@wildfiregames.com / mot20@cam.ac.uk)
* =========================================================================
*/
#ifndef PROFILE_H_INCLUDED
#define PROFILE_H_INCLUDED
#include <vector>
#include "Singleton.h"
#include "scripting/ScriptableObject.h"
#define PROFILE_AMORTIZE
#define PROFILE_AMORTIZE_FRAMES 50
class CProfileManager;
class CProfileNodeTable;
class CProfileNode : public CJSObject<CProfileNode, true>
{
friend class CProfileManager;
friend class CProfileNodeTable;
const char* name;
int calls_total;
int calls_frame_current;
#ifdef PROFILE_AMORTIZE
int calls_frame_buffer[PROFILE_AMORTIZE_FRAMES];
int* calls_frame_last;
float calls_frame_amortized;
#else
int calls_frame_last;
#endif
double time_total;
double time_frame_current;
#ifdef PROFILE_AMORTIZE
double time_frame_buffer[PROFILE_AMORTIZE_FRAMES];
double* time_frame_last;
double time_frame_amortized;
#else
double time_frame_last;
#endif
long mallocs_total;
long mallocs_frame_current;
long mallocs_frame_last;
double start;
long start_mallocs;
int recursion;
CProfileNode* parent;
std::vector<CProfileNode*> children;
std::vector<CProfileNode*> script_children;
CProfileNodeTable* display_table;
public:
typedef std::vector<CProfileNode*>::iterator profile_iterator;
typedef std::vector<CProfileNode*>::const_iterator const_profile_iterator;
CProfileNode( const char* name, CProfileNode* parent );
~CProfileNode();
const char* GetName() const { return( name ); }
int GetCalls() const { return( calls_total ); }
double GetTime() const { return( time_total ); }
#ifdef PROFILE_AMORTIZE
float GetFrameCalls() const { return( calls_frame_amortized / PROFILE_AMORTIZE_FRAMES ); }
double GetFrameTime() const { return( time_frame_amortized / PROFILE_AMORTIZE_FRAMES ); }
#else
int GetFrameCalls() const { return( calls_frame_last ); }
double GetFrameTime() const { return( time_frame_last ); }
#endif
long GetFrameMallocs() const { return( mallocs_frame_last ); }
const CProfileNode* GetChild( const char* name ) const;
const CProfileNode* GetScriptChild( const char* name ) const;
const std::vector<CProfileNode*>* GetChildren() const { return( &children ); }
const std::vector<CProfileNode*>* GetScriptChildren() const { return( &script_children ); }
bool CanExpand();
CProfileNode* GetChild( const char* name );
CProfileNode* GetScriptChild( const char* name );
CProfileNode* GetParent() const { return( parent ); }
// Resets timing information for this node and all its children
void Reset();
// Resets frame timings for this node and all its children
void Frame();
// Enters the node
void Call();
// Leaves the node. Returns true if the node has actually been left
bool Return();
// Javascript stuff...
static void ScriptingInit();
jsval JS_GetName(JSContext*) { return( ToJSVal( CStrW( name ) ) ); }
};
class CProfileManager : public Singleton<CProfileManager>
{
CProfileNode* root;
CProfileNode* current;
double start;
double frame_start;
std::map<CStr8, const char*> m_internedStrings;
public:
CProfileManager();
~CProfileManager();
// Begins timing for a named subsection
void Start( const char* name );
void StartScript( const char* name );
// Ends timing for the current subsection
void Stop();
// Resets all timing information
void Reset();
// Resets frame timing information
void Frame();
// Resets absolutely everything
void StructuralReset();
const char* InternString( const CStr8& intern );
inline const CProfileNode* GetCurrent() { return( current ); }
inline const CProfileNode* GetRoot() { return( root ); }
double GetTime();
double GetFrameTime();
};
#define g_Profiler CProfileManager::GetSingleton()
class CProfileSample
{
static std::map<CStrW, char*> evMap;
public:
CProfileSample( const char* name )
{
if (CProfileManager::IsInitialised())
g_Profiler.Start( name );
}
~CProfileSample()
{
if (CProfileManager::IsInitialised())
g_Profiler.Stop();
}
};
// Put a PROFILE( xyz ) block at the start of all code to be profiled.
// Profile blocks last until the end of the containing scope.
#define PROFILE( name ) CProfileSample __profile( name )
// Cheat a bit to make things slightly easier on the user
#define PROFILE_START( name ) { CProfileSample __profile( name )
#define PROFILE_END( name ) }
#endif // PROFILE_H_INCLUDED