#pragma once

#include "node.h"
#include "time.h"
#include "memblock.h"
#include "simulate.h"

class UpdateManager;

class SimulationEncore : public Plug
{
	friend class UpdateManager;

private:
	static MemoryBlock* GetAllocatedMemory();

	void* operator new(size_t)			{ return GetAllocatedMemory()->New(); }
	void operator delete(void *where)	{ GetAllocatedMemory()->Delete(where); }

	Simulation *encoreSimulation;
	Simulation::Encore encoreCallback;
	Logical runWatchers;

	SimulationEncore(Simulation *sim, Simulation::Encore callback);
	~SimulationEncore();
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UpdateManager ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class UpdateManager : public Node
{
public:
	//
	//--------------------------------------------------------------------
	// Construction, Destruction
	//--------------------------------------------------------------------
	//
	UpdateManager();
	~UpdateManager();

	Logical TestInstance() const;

	//
	//--------------------------------------------------------------------
	// Execute
	//
	// Perform update management functions
	//--------------------------------------------------------------------
	//
	void Execute(Time target_render_time);

	//
	//----------------------------------------------------------------------
	// CreateEncore
	//
	// Registers a callback to be executed after all entity performances are
	// completed
	//----------------------------------------------------------------------
	//
	void RequestEncore(Simulation *simulation, Simulation::Encore encore);

protected:
	ChainOf<SimulationEncore*> simulationEncores;
};
