/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NPROFILER__
#define	__NPROFILER__


		#include "timing/benchmark.h"


namespace GS {

/*!
	@short	Profiler.
	@author	Emmanuel Julien (ejulien@owloh.com)
*/
struct Profiler
{
		// System is owned by the profiler.
		struct System
		{
			String	label;
			Benchmark profile;

			AutoList <System *> sub_systems;

			void Reset()
			{
				profile.Reset();
				ListForeachPtr(System *, s, sub_systems)
					s->Reset();
			}
		};

		AutoList <System *> root_systems;

		/*!
			@short	Declare a system.
			The system can be declared as a sub-system of another system.
		*/
		System *DeclareSystem(const char *label, System *subsystem_of = 0)
		{
			System *sys = new System;
			if	(sys == 0)
				return 0;

			sys->label = label;

			if	(subsystem_of)
				subsystem_of->sub_systems.Add(sys);
			else
				root_systems.Add(sys);

			return sys;
		}

		/// Reset all system in the profiler.
virtual	void ResetProfiles()
		{
			ListForeachPtr(System *, s, root_systems)
				s->Reset();
		}
};

#if	__ENGINE_RETAIL__
	#define	ScopedSystemProfile(_System) ;
#else
	#define	ScopedSystemProfile(_System) ScopedBenchmark _scoped_profile(_System->profile);
#endif

} // GS


#endif	// __NPROFILER__
