
///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_PFX_RenderQueue.h
// Author : Andy Tate
// Date   : 19-Jun-2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __ASURA_PFX_RENDERQUEUE_H__
#define __ASURA_PFX_RENDERQUEUE_H__

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura_TemplateTree.h"
#include "Core/Asura_Mempool.h"
#include "Rendering/Asura_Colour.h"


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class Asura_PFX_Effect;
class Asura_PFX_Particle;
class Asura_PFX_Particle_Template;


////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : Asura_PFX_RenderQueue_Command
// Author       : Andy Tate
// Date         : 19-Jun-2008
//
// Description  : Class used to store the data to be rendered for a particular
//				  PFX effect.
////////////////////////////////////////////////////////////////////////////////

class Asura_PFX_RenderQueue_Command
{
public:
	// Public functions...
	//~Asura_PFX_RenderQueue_Command();

	void	Initialise(const Asura_PFX_Particle* pxParticles,
					   const u_int uNumParticles,
					   const Asura_RGBA& xLightColour,
					   Asura_PFX_Effect& xEffect,
					   void* pPlatformRenderData);

	void	RenderParticles(const Asura_PFX_Particle_Template& xParticleTemplate);

	// Accessor functions...
	void							SetNextCommand(Asura_PFX_RenderQueue_Command* pxCommand)	{ m_pxNextCommand = pxCommand; }
	Asura_PFX_RenderQueue_Command*	GetNextCommand(void)										{ return(m_pxNextCommand); }


protected:

	// Private functions...
	Asura_PFX_RenderQueue_Command(void);
	Asura_PFX_RenderQueue_Command(const Asura_PFX_RenderQueue_Command& xOther);
	~Asura_PFX_RenderQueue_Command();
	// Protected variables...

	// Protected functions...


private:
	// Private variables...
	const Asura_PFX_Particle*		m_pxParticles;			// A pointer to the first particle in our array.
	u_int							m_uNumParticles;		// The number of particles in the array.
	Asura_RGBA						m_xLightColour;			// The colour of light to be applied to the particles.
	Asura_PFX_Effect*				m_pxEffect;				// A pointer to the PFX effect we're using for these particles.
#if defined(ASURA_SUPPORT_MULTITHREADED_JOB_QUEUE)
	void*							m_pPlatformRenderData;	// A pointer to any platform specific data we may need.
#endif	//defined(ASURA_SUPPORT_MULTITHREADED_JOB_QUEUE)
	Asura_PFX_RenderQueue_Command*	m_pxNextCommand;		// A pointer to the next command to be rendered.

	Asura_PFX_RenderQueue_Command&	operator=(const Asura_PFX_RenderQueue_Command& xOther);

};   // End of class 'Asura_PFX_RenderQueue_Command'.



////////////////////////////////////////////////////////////////////////////////
// Class        : Asura_PFX_RenderQueue_CommandList
// Author       : Andy Tate
// Date         : 19-Jun-2008
//
// Description  : Class used to store a list of commands for a particular type
//				  of particle-template.
////////////////////////////////////////////////////////////////////////////////

class Asura_PFX_RenderQueue_CommandList
{
public:
	// Public functions...
	Asura_PFX_RenderQueue_CommandList(void)	: m_pxParticleTemplate(NULL), m_pxFirstCommand(NULL)	{}
	//~Asura_PFX_RenderQueue_CommandList();

	void	AddCommand(Asura_PFX_RenderQueue_Command& xCommand);
	void	RenderParticles(void);

	// Accessor functions...
	void								SetParticleTemplate(const Asura_PFX_Particle_Template* pxTemplate)	{ m_pxParticleTemplate = pxTemplate; }
	const Asura_PFX_Particle_Template*	GetParticleTemplate(void) const										{ return(m_pxParticleTemplate); }


protected:
	// Protected variables...

	// Protected functions...


private:
	// Private variables...
	const Asura_PFX_Particle_Template*	m_pxParticleTemplate;	// A pointer to the particle-template to use for this command.
	Asura_PFX_RenderQueue_Command*		m_pxFirstCommand;		// A pointer to the first command to use.

	// Private functions...
	Asura_PFX_RenderQueue_CommandList(const Asura_PFX_RenderQueue_CommandList& xOther);

	Asura_PFX_RenderQueue_CommandList&	operator=(const Asura_PFX_RenderQueue_CommandList& xOther);

};   // End of class 'Asura_PFX_RenderQueue_CommandList'.



////////////////////////////////////////////////////////////////////////////////
// Class        : Asura_PFX_RenderQueue
// Author       : Andy Tate
// Date         : 19-Jun-2008
//
// Description  : Class used to queue-up PFX to be rendered.
////////////////////////////////////////////////////////////////////////////////

class Asura_PFX_RenderQueue
{
public:
	// Public functions...
	Asura_PFX_RenderQueue(void);
	//~Asura_PFX_RenderQueue();

	// Queue manipulation functions...
	void	AddParticles(const Asura_PFX_Particle_Template& xParticleTemplate,
						 const Asura_PFX_Particle* pxParticles,
						 const u_int uNumParticles,
						 const Asura_RGBA& xLightColour,
						 Asura_PFX_Effect& xEffect,
						 void* pPlatformRenderData);
	void	Flush(void);


protected:
	// Protected variables...

	// Protected functions...
	static int	CommandListCompare(Asura_PFX_Particle_Template const* const& pxTemplate1, Asura_PFX_Particle_Template const* const& pxTemplate2);


private:
	// Private typedefs...
	typedef Asura_TemplateTree<const Asura_PFX_Particle_Template*, Asura_PFX_RenderQueue_CommandList> CommandListContainer;
	typedef Asura_TemplateTree_Iterator<const Asura_PFX_Particle_Template*, Asura_PFX_RenderQueue_CommandList> CommandListIterator;

	// Private variables...
	CommandListContainer	m_xCommandListContainer;	// The data-container used to sort commands by priority.

#if defined(ASURA_PFX_RENDER_QUEUE_SIZE)
	Asura_Mempool			m_xCommandMempool;			// Pool of memory used for allocating commands from.
#else
	Asura_ResizingMempool	m_xCommandMempool;			// Pool of memory used for allocating commands from.
#endif	//!defined(ASURA_PFX_RENDER_QUEUE_SIZE)

	// Private functions...
	Asura_PFX_RenderQueue(const Asura_PFX_RenderQueue& xOther);

	Asura_PFX_RenderQueue&	operator=(const Asura_PFX_RenderQueue& xOther);

};   // End of class 'Asura_PFX_RenderQueue'.


#endif   // ifndef __ASURA_PFX_RENDERQUEUE_H__


/// End of file. ///
