/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
****************************************************************************/

#pragma once

#include "glmSDKAPI.h"
#include "glmTypes.h"
#include "glmSynchroBarrier.h"
#include "glmProcessingBatch.h"
#include "glmMultiThreadProcessor.h"
#include "glmSimulationsCollection.h"
#include "glmAtomic.h"
#include "glmThreading.h"
#include "glmArray.h"

namespace glm
{

	// index is current index in max array, up to 2^20 = 1 million
	// counter is used to compare reaffectation 
	// unused : the entity is not created.
	// -----------------------------------------------------------------------------
	class GLM_SDK_API SimulationsProcessor : public MultiThreadProcessor
	{
		friend class WorkerThread;

	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation);

		SimulationsProcessor();

		virtual ~SimulationsProcessor();

		// init unchanged
		void update(Time dt); // updates all added simulations
		virtual void finish() override; // finish all simulations still in it, close threading engine, delete still registered simulations

		inline void addSimulation(Simulation*); // calls simu init 
		inline bool removeSimulation(Simulation*); // calls simu finish 
		inline SimulationsCollection& getSimulationsCollection() { return _simulationsCollection; }

	private:

		void consumeEngineBatchQueue(); // calls consumeBatchQueue via threads
		void deallocateEngineBatchQueue();

		SimulationsCollection	_simulationsCollection;
	};

	//-------------------------------------------------------------------------
	inline void SimulationsProcessor::addSimulation(Simulation* simulation)
	{
		_simulationsCollection.addSimulation(simulation); // batch init
		consumeEngineBatchQueue();	// to consume init batch
	}

	//-------------------------------------------------------------------------
	inline bool SimulationsProcessor::removeSimulation(Simulation* simulation)
	{
		bool success = _simulationsCollection.removeSimulation(simulation); // batch finish
		consumeEngineBatchQueue();	// to consume finish batch
		return success;
	}
}
