This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwdebug/wwprofile.h

297 lines
9.5 KiB
C
Raw Permalink Normal View History

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWDebug *
* *
* $Archive:: /Commando/Code/wwdebug/wwprofile.h $*
* *
* $Author:: Jani_p $*
* *
* $Modtime:: 3/25/02 2:05p $*
* *
* $Revision:: 14 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
//#define ENABLE_TIME_AND_MEMORY_LOG
#ifndef WWPROFILE_H
#define WWPROFILE_H
#include "wwstring.h"
#ifdef _UNIX
typedef signed long long __int64;
typedef signed long long _int64;
#endif
// enable profiling by default in debug mode.
#ifdef WWDEBUG
#define ENABLE_WWPROFILE
#endif
extern unsigned WWProfile_Get_System_Time(); // timeGetTime() wrapper
class FileClass;
/*
** A node in the WWProfile Hierarchy Tree
*/
class WWProfileHierachyNodeClass {
public:
WWProfileHierachyNodeClass( const char * name, WWProfileHierachyNodeClass * parent );
~WWProfileHierachyNodeClass( void );
WWProfileHierachyNodeClass * Get_Sub_Node( const char * name );
WWProfileHierachyNodeClass * Get_Parent( void ) { return Parent; }
WWProfileHierachyNodeClass * Get_Sibling( void ) { return Sibling; }
WWProfileHierachyNodeClass * Get_Child( void ) { return Child; }
void Reset( void );
void Call( void );
bool Return( void );
const char * Get_Name( void ) { return Name; }
int Get_Total_Calls( void ) { return TotalCalls; }
float Get_Total_Time( void ) { return TotalTime; }
WWProfileHierachyNodeClass* Clone_Hierarchy(WWProfileHierachyNodeClass* parent);
void Write_To_File(FileClass* file,int recursion);
int Get_Total_Calls() const { return TotalCalls; }
float Get_Total_Time() const { return TotalTime; }
void Set_Total_Calls(int calls) { TotalCalls=calls; }
void Set_Total_Time(float time) { TotalTime=time; }
protected:
const char * Name;
int TotalCalls;
float TotalTime;
__int64 StartTime;
int RecursionCounter;
WWProfileHierachyNodeClass * Parent;
WWProfileHierachyNodeClass * Child;
WWProfileHierachyNodeClass * Sibling;
};
/*
** An iterator to navigate through the tree
*/
class WWProfileIterator
{
public:
// Access all the children of the current parent
void First(void);
void Next(void);
bool Is_Done(void);
void Enter_Child( void ); // Make the current child the new parent
void Enter_Child( int index ); // Make the given child the new parent
void Enter_Parent( void ); // Make the current parent's parent the new parent
// Access the current child
const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
// Access the current parent
const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); }
int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); }
float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); }
protected:
WWProfileHierachyNodeClass * CurrentParent;
WWProfileHierachyNodeClass * CurrentChild;
WWProfileIterator( WWProfileHierachyNodeClass * start );
friend class WWProfileManager;
};
/*
** An iterator to walk through the tree in depth first order
*/
class WWProfileInOrderIterator
{
public:
void First(void);
void Next(void);
bool Is_Done(void);
// Access the current node
const char * Get_Current_Name( void ) { return CurrentNode->Get_Name(); }
int Get_Current_Total_Calls( void ) { return CurrentNode->Get_Total_Calls(); }
float Get_Current_Total_Time( void ) { return CurrentNode->Get_Total_Time(); }
protected:
WWProfileHierachyNodeClass * CurrentNode;
WWProfileInOrderIterator( void );
friend class WWProfileManager;
};
/*
** The Manager for the WWProfile system
*/
class WWProfileManager {
public:
static void Start_Profile( const char * name );
static void Stop_Profile( void );
static void Start_Root_Profile( const char * name );
static void Stop_Root_Profile( void );
static void Reset( void );
static void Increment_Frame_Counter( void );
static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; }
static float Get_Time_Since_Reset( void );
static WWProfileIterator * Get_Iterator( void );
static void Release_Iterator( WWProfileIterator * iterator );
static WWProfileInOrderIterator * Get_In_Order_Iterator( void );
static void Release_In_Order_Iterator( WWProfileInOrderIterator * iterator );
static WWProfileHierachyNodeClass * Get_Root( void ) { return &Root; }
static void Begin_Collecting();
static void End_Collecting(const char* filename);
private:
static WWProfileHierachyNodeClass Root;
static WWProfileHierachyNodeClass * CurrentNode;
static WWProfileHierachyNodeClass * CurrentRootNode;
static int FrameCounter;
static __int64 ResetTime;
friend class WWProfileInOrderIterator;
};
/*
** WWProfileSampleClass is a simple way to profile a function's scope
** Use the WWPROFILE macro at the start of scope to time
*/
class WWProfileSampleClass {
bool IsRoot;
public:
WWProfileSampleClass( const char * name, bool is_root ) : IsRoot(is_root)
{
if (IsRoot) WWProfileManager::Start_Root_Profile( name );
else WWProfileManager::Start_Profile( name );
}
~WWProfileSampleClass( void )
{
if (IsRoot) WWProfileManager::Stop_Root_Profile();
else WWProfileManager::Stop_Profile();
}
};
#ifdef ENABLE_WWPROFILE
#define WWPROFILE( name ) WWProfileSampleClass _wwprofile( name, false )
#define WWROOTPROFILE( name ) WWProfileSampleClass _wwprofile( name, true )
#else
#define WWPROFILE( name )
#define WWROOTPROFILE( name )
#endif
/*
** WWTimeIt is like WWProfile, but it doesn't save anything, it just times one routine, regardless of thread
*/
class WWTimeItClass {
public:
WWTimeItClass( const char * name );
~WWTimeItClass( void );
private:
const char * Name;
__int64 Time;
};
#ifdef ENABLE_WWPROFILE
#define WWTIMEIT( name ) WWTimeItClass _wwtimeit( name )
#else
#define WWTIMEIT( name )
#endif
/*
** TSS 06/27/01
** WWMeasureItClass is like WWTimeItClass, but it pokes the result into the given float,
** and can be used in the release build.
*/
class WWMeasureItClass {
public:
WWMeasureItClass( float * p_result );
~WWMeasureItClass( void );
private:
__int64 Time;
float * PResult;
};
// ----------------------------------------------------------------------------
//
// Use the first macro to log time and memory usage within the stack segment.
// Use the second macro to log intermediate values. The intermediate values are
// calculated from the previous intermediate log, so you can log how much each
// item takes by placing the macro after each of the
//
// ----------------------------------------------------------------------------
#ifdef ENABLE_TIME_AND_MEMORY_LOG
#define WWLOG_PREPARE_TIME_AND_MEMORY(t) WWMemoryAndTimeLog memory_and_time_log(t)
#define WWLOG_INTERMEDIATE(t) memory_and_time_log.Log_Intermediate(t)
#else
#define WWLOG_PREPARE_TIME_AND_MEMORY(t)
#define WWLOG_INTERMEDIATE(t)
#endif
struct WWMemoryAndTimeLog
{
unsigned TimeStart;
unsigned IntermediateTimeStart;
int AllocCountStart;
int IntermediateAllocCountStart;
int AllocSizeStart;
int IntermediateAllocSizeStart;
StringClass Name;
static unsigned TabCount;
WWMemoryAndTimeLog(const char* name);
~WWMemoryAndTimeLog();
void Log_Intermediate(const char* text);
};
#endif // WWPROFILE_H