<commit_before>#include <memory>
#include <iostream>
#include <fstream>

#include <eventLoop.hxx>

#include <THandle.hxx>
#include <TG4Trajectory.hxx>

/// User code for the event loop.  This can be copied and used as a skeleton
/// for generic user loop programs.
class TUserLoop: public CP::TEventLoopFunction {
public:
    /// Initialize any class specific variables, but most of the work can be
    /// done in Initialize.  Don't create histograms here!
    TUserLoop() {}
    virtual ~TUserLoop() {};

    /// Print a usage message.  This is generally called when there is a
    /// command line input error.
    void Usage(void) {
    }

    /// Set an option and return true if it is valid.  This is called by the
    /// event loop command line argument processing code for each "-O
    /// [name]=[value]" option found on the command line.  If the command line
    /// has "-O [name]" without a value, then the value string will be equal
    /// to "".  This must return false if the option was not correctly
    /// processed.
    virtual bool SetOption(std::string option,std::string value="") {
        return false;
    }

    /// Called for each event inside the event loop, and returns true if the
    /// event should be saved to the output file.  If the remainder of the
    /// current file should be skipped, this should through the
    /// ENextEventLoopFile exception.  If the daughter class defines this
    /// operator, it should not define the Process() method.
    bool operator () (CP::TEvent& event) {
        CP::THandle<CP::TG4TrajectoryContainer> trajectories
            = event.Get<CP::TG4TrajectoryContainer>("truth/G4Trajectories");
        if (!trajectories) {
            std::cout << "No Trajectory container" << std::endl;
            return false;
        }
        trajectories->ls();
        CP::THandle<CP::TG4Trajectory> traj = trajectories->GetTrajectory(1);
        if (!traj) {
            std::cout << "No Trajectories" << std::endl;
        }
        std::cout << "Print the trajectory" << std::endl;
        traj->ls();
        std::cout << "Get the initial position" << std::endl;
        std::cout << " x " << traj->GetInitialPosition().X() << std::endl;
        std::cout << " y " << traj->GetInitialPosition().Y() << std::endl;
        std::cout << " z " << traj->GetInitialPosition().Z() << std::endl;
        std::cout << "Get the final position" << std::endl;
        std::cout << " x " << traj->GetFinalPosition().X() << std::endl;
        std::cout << " y " << traj->GetFinalPosition().Y() << std::endl;
        std::cout << " z " << traj->GetFinalPosition().Z() << std::endl;

        double dx = traj->GetFinalPosition().X()-traj->GetInitialPosition().X();
        double dy = traj->GetFinalPosition().Y()-traj->GetInitialPosition().Y();
        double dz = traj->GetFinalPosition().Z()-traj->GetInitialPosition().Z();

        double length = std::sqrt(dx*dx + dy*dy + dz*dz);

        std::cout << length << std::endl;

        fOutput << length << std::endl;

        return true;
    }

    /// Called after the arguments are processed but before reading the first
    /// event.  The output file is open so any histograms will be added to the
    /// output file.
    virtual void Initialize(void) {
        fOutput.open("proton100.data");
    }

    /// Called after reading the last event.  The output file is still open,
    /// so you can add extra information.  Because of an ideosyncracy in the
    /// way root handles histograms, objects created in Initialize() will
    /// already be stored in the output file.
    virtual void Finalize(CP::TRootOutput* output) {
        fOutput.close();
    }

private:

    std::ofstream fOutput;

};

int main(int argc, char **argv) {
    TUserLoop userLoop;
    CP::eventLoop(argc,argv,userLoop);
}
<commit_msg>Print the energy too.<commit_after>#include <memory>
#include <iostream>
#include <fstream>

#include <eventLoop.hxx>

#include <THandle.hxx>
#include <TG4Trajectory.hxx>

/// User code for the event loop.  This can be copied and used as a skeleton
/// for generic user loop programs.
class TUserLoop: public CP::TEventLoopFunction {
public:
    /// Initialize any class specific variables, but most of the work can be
    /// done in Initialize.  Don't create histograms here!
    TUserLoop() {}
    virtual ~TUserLoop() {};

    /// Print a usage message.  This is generally called when there is a
    /// command line input error.
    void Usage(void) {
    }

    /// Set an option and return true if it is valid.  This is called by the
    /// event loop command line argument processing code for each "-O
    /// [name]=[value]" option found on the command line.  If the command line
    /// has "-O [name]" without a value, then the value string will be equal
    /// to "".  This must return false if the option was not correctly
    /// processed.
    virtual bool SetOption(std::string option,std::string value="") {
        return false;
    }

    /// Called for each event inside the event loop, and returns true if the
    /// event should be saved to the output file.  If the remainder of the
    /// current file should be skipped, this should through the
    /// ENextEventLoopFile exception.  If the daughter class defines this
    /// operator, it should not define the Process() method.
    bool operator () (CP::TEvent& event) {
        CP::THandle<CP::TG4TrajectoryContainer> trajectories
            = event.Get<CP::TG4TrajectoryContainer>("truth/G4Trajectories");
        if (!trajectories) {
            std::cout << "No Trajectory container" << std::endl;
            return false;
        }
        trajectories->ls();
        CP::THandle<CP::TG4Trajectory> traj = trajectories->GetTrajectory(1);
        if (!traj) {
            std::cout << "No Trajectories" << std::endl;
        }
        std::cout << "Print the trajectory" << std::endl;
        traj->ls();
        std::cout << "Get the initial position" << std::endl;
        std::cout << " x " << traj->GetInitialPosition().X() << std::endl;
        std::cout << " y " << traj->GetInitialPosition().Y() << std::endl;
        std::cout << " z " << traj->GetInitialPosition().Z() << std::endl;
        std::cout << "Get the final position" << std::endl;
        std::cout << " x " << traj->GetFinalPosition().X() << std::endl;
        std::cout << " y " << traj->GetFinalPosition().Y() << std::endl;
        std::cout << " z " << traj->GetFinalPosition().Z() << std::endl;

        double dx = traj->GetFinalPosition().X()-traj->GetInitialPosition().X();
        double dy = traj->GetFinalPosition().Y()-traj->GetInitialPosition().Y();
        double dz = traj->GetFinalPosition().Z()-traj->GetInitialPosition().Z();

        double length = std::sqrt(dx*dx + dy*dy + dz*dz);

        std::cout << "length " << length << std::endl;

        double energy = traj->GetInitialMomentum().E()
            - traj->GetInitialMomentum().M();

        std::cout << "energy " << energy << std::endl;

        fOutput << length << " " << energy << std::endl;

        return true;
    }

    /// Called after the arguments are processed but before reading the first
    /// event.  The output file is open so any histograms will be added to the
    /// output file.
    virtual void Initialize(void) {
        fOutput.open("proton100.data");
    }

    /// Called after reading the last event.  The output file is still open,
    /// so you can add extra information.  Because of an ideosyncracy in the
    /// way root handles histograms, objects created in Initialize() will
    /// already be stored in the output file.
    virtual void Finalize(CP::TRootOutput* output) {
        fOutput.close();
    }

private:

    std::ofstream fOutput;

};

int main(int argc, char **argv) {
    TUserLoop userLoop;
    CP::eventLoop(argc,argv,userLoop);
}
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetSigChTest
#include <boost/test/unit_test.hpp>
#include "../JPetSigCh/JPetSigCh.h"

/// @todo update the method list - tests are outdated
//  JPetSigCh() { init(); }
//  JPetSigCh(EdgeType Edge, float EdgeTime);
//  bool isCharge() const;
//  bool isTime() const;
//  inline float getValue() const { return fValue; }
//  inline EdgeType getType() const { return fType; }
//  inline JPetPM * getPM() const { return (JPetPM*) fPM.GetObject(); }
//  inline JPetTRB * getTRB() const {return (JPetTRB*) fTRB.GetObject(); }
//  inline JPetFEB * getFEB() const {return (JPetFEB*) fFEB.GetObject(); }
//  inline void setPM(JPetPM * pm) { fPM = pm; }
//  inline void setTRB(JPetTRB * trb) { fTRB = trb; }
//  inline void setFEB(JPetFEB * feb) { fFEB= feb; }
//  inline void setValue( float val ) { fValue = val; }
//  inline void setType( EdgeType type ) { fType = type; }
//  inline void setThreshold( float thr ) { fThreshold = thr; }
//  inline void setDAQch( Int_t daqch ) { fDAQch = daqch; }
//  inline float getThreshold() const { return fThreshold; }
//  inline Int_t getDAQch() const { return fDAQch; }
//  Int_t Compare(const TObject* obj) const;
//  inline Bool_t IsSortable() const { return true; }

BOOST_AUTO_TEST_SUITE(FirstSuite)

BOOST_AUTO_TEST_CASE( first )
{
  JPetSigCh test;
  BOOST_REQUIRE_EQUAL(test.isCharge(), 0);
  BOOST_REQUIRE_EQUAL(test.isTime(), 1);
  BOOST_REQUIRE_EQUAL(test.getValue(), JPetSigCh::kUnset);
  BOOST_REQUIRE_EQUAL(test.getType(), JPetSigCh::Leading);
  BOOST_REQUIRE_EQUAL(test.getThreshold(), JPetSigCh::kUnset);
}

BOOST_AUTO_TEST_CASE( second )
{
  float epsilon = 0.001;
  JPetSigCh test;
  JPetPM pm_test;
  JPetFEB feb_test(43, true, "", "", 1, 1, 8, 1);
  JPetTRB trb_test;
  JPetTOMBChannel tomb_test(12);
  float thr_test = 210.043;
  float time_test = 1.2345;

  test.setPM(pm_test);
  test.setTRB(trb_test);
  test.setFEB(feb_test);
  test.setTOMBChannel(tomb_test);
  test.setThreshold(thr_test);
  test.setType(JPetSigCh::Leading);
  test.setValue(time_test);

  BOOST_REQUIRE_EQUAL(test.isTime(), 1);
  BOOST_REQUIRE_EQUAL(test.isCharge(), 0);
  BOOST_REQUIRE_CLOSE(test.getValue(), time_test, epsilon);
  BOOST_REQUIRE_EQUAL(test.getType(), JPetSigCh::Leading);
  BOOST_REQUIRE_EQUAL(test.getChannel(), 12);

  JPetSigCh test2(test);

  BOOST_REQUIRE_EQUAL(test.getPM().getID(), test2.getPM().getID());
  BOOST_REQUIRE_EQUAL(test.getTRB().getID(), test2.getTRB().getID());
  BOOST_REQUIRE_EQUAL(test.getFEB().getID(), test2.getFEB().getID());
  BOOST_REQUIRE_EQUAL(test.getType(), test2.getType());
  BOOST_REQUIRE_CLOSE(test.getValue(), test2.getValue(), epsilon);
  BOOST_REQUIRE_CLOSE(test.getThreshold(), test2.getThreshold(), epsilon);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Update JPetSigCh test after charge field removal<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetSigChTest
#include <boost/test/unit_test.hpp>
#include "../JPetSigCh/JPetSigCh.h"

/// @todo update the method list - tests are outdated
//  JPetSigCh() { init(); }
//  JPetSigCh(EdgeType Edge, float EdgeTime);
//  inline float getValue() const { return fValue; }
//  inline EdgeType getType() const { return fType; }
//  inline JPetPM * getPM() const { return (JPetPM*) fPM.GetObject(); }
//  inline JPetTRB * getTRB() const {return (JPetTRB*) fTRB.GetObject(); }
//  inline JPetFEB * getFEB() const {return (JPetFEB*) fFEB.GetObject(); }
//  inline void setPM(JPetPM * pm) { fPM = pm; }
//  inline void setTRB(JPetTRB * trb) { fTRB = trb; }
//  inline void setFEB(JPetFEB * feb) { fFEB= feb; }
//  inline void setValue( float val ) { fValue = val; }
//  inline void setType( EdgeType type ) { fType = type; }
//  inline void setThreshold( float thr ) { fThreshold = thr; }
//  inline void setDAQch( Int_t daqch ) { fDAQch = daqch; }
//  inline float getThreshold() const { return fThreshold; }
//  inline Int_t getDAQch() const { return fDAQch; }
//  Int_t Compare(const TObject* obj) const;
//  inline Bool_t IsSortable() const { return true; }

BOOST_AUTO_TEST_SUITE(FirstSuite)

BOOST_AUTO_TEST_CASE( first )
{
  JPetSigCh test;
  BOOST_REQUIRE_EQUAL(test.getValue(), JPetSigCh::kUnset);
  BOOST_REQUIRE_EQUAL(test.getType(), JPetSigCh::Leading);
  BOOST_REQUIRE_EQUAL(test.getThreshold(), JPetSigCh::kUnset);
}

BOOST_AUTO_TEST_CASE( second )
{
  float epsilon = 0.001;
  JPetSigCh test;
  JPetPM pm_test;
  JPetFEB feb_test(43, true, "", "", 1, 1, 8, 1);
  JPetTRB trb_test;
  JPetTOMBChannel tomb_test(12);
  float thr_test = 210.043;
  float time_test = 1.2345;

  test.setPM(pm_test);
  test.setTRB(trb_test);
  test.setFEB(feb_test);
  test.setTOMBChannel(tomb_test);
  test.setThreshold(thr_test);
  test.setType(JPetSigCh::Leading);
  test.setValue(time_test);

  BOOST_REQUIRE_CLOSE(test.getValue(), time_test, epsilon);
  BOOST_REQUIRE_EQUAL(test.getType(), JPetSigCh::Leading);
  BOOST_REQUIRE_EQUAL(test.getChannel(), 12);

  JPetSigCh test2(test);

  BOOST_REQUIRE_EQUAL(test.getPM().getID(), test2.getPM().getID());
  BOOST_REQUIRE_EQUAL(test.getTRB().getID(), test2.getTRB().getID());
  BOOST_REQUIRE_EQUAL(test.getFEB().getID(), test2.getFEB().getID());
  BOOST_REQUIRE_EQUAL(test.getType(), test2.getType());
  BOOST_REQUIRE_CLOSE(test.getValue(), test2.getValue(), epsilon);
  BOOST_REQUIRE_CLOSE(test.getThreshold(), test2.getThreshold(), epsilon);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "fx/ConvolverReader.h"
#include "Exception.h"

#include <cstring>
#include <math.h>
#include <algorithm>

#define N 2048
AUD_NAMESPACE_BEGIN

ConvolverReader::ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<IReader> irReader) :
	m_reader(reader), m_irReader(irReader), m_position(0), m_eosReader(false), m_eosTail(false)
{
	m_irChannels = irReader->getSpecs().channels;
	m_inChannels = reader->getSpecs().channels;
	if (m_irChannels != 1 && m_irChannels != m_inChannels)
		AUD_THROW(StateException, "The impulse response and the sound must either have the same amount of channels or the impulse response must be mono");

	m_N = N;
	m_M = m_L = N / 2;

	auto irVector = processFilter();

	//TODO
	/*if (m_irChannels > 1)
		for (int i = 0; i < m_inChannels; i++)
			m_convolvers.push_back(std::make_unique<FFTConvolver>(irVector[i], m_M, m_L, m_N));
	else
		for (int i = 0; i < m_inChannels; i++)
			m_convolvers.push_back(std::make_unique<FFTConvolver>(irVector[0], m_M, m_L, m_N));*/

	for (int i = 0; i < m_inChannels; i++)
		m_vecInOut.push_back((sample_t*)std::malloc(m_L*sizeof(sample_t)));
	m_outBuffer = (sample_t*)std::malloc(m_L*m_inChannels * sizeof(sample_t));
	m_outBufLen = m_eOutBufLen = m_outBufferPos = m_L*m_inChannels;
}

ConvolverReader::~ConvolverReader()
{
	delete m_outBuffer;
	for (int i = 0; i < m_inChannels; i++)
		std::free(m_vecInOut[i]);
}

bool ConvolverReader::isSeekable() const
{
	return m_reader->isSeekable();
}

void ConvolverReader::seek(int position)
{
	m_reader->seek(position);
	for (int i = 0; i < m_inChannels; i++)
		m_convolvers[i]->reset();
}

int ConvolverReader::getLength() const
{
	return m_reader->getLength();
}

int ConvolverReader::getPosition() const
{
	return m_reader->getPosition();
}

Specs ConvolverReader::getSpecs() const
{
	return m_reader->getSpecs();
}

void ConvolverReader::read(int& length, bool& eos, sample_t* buffer)
{
	if (length <= 0)
	{
		length = 0;
		return;
	}

	int writePos = 0;
	do
	{
		int writeLength = std::min((length*m_inChannels) - writePos, m_outBufLen);
		int l = m_L;
		int bufRest = m_eOutBufLen - m_outBufferPos;
		if (bufRest < writeLength)
		{
			if (bufRest > 0)
				std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
			loadBuffer(0);
			std::memcpy(buffer + writePos + bufRest, m_outBuffer, (writeLength - bufRest)*sizeof(sample_t));
			m_outBufferPos = writeLength - bufRest;
		}
		else
		{
			std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
			m_outBufferPos += writeLength;
		}
		writePos += writeLength;
	} while (writePos < length*m_inChannels);
}

void ConvolverReader::loadBuffer(int ini)
{
	int l = m_L;
	m_reader->read(l, m_eosReader, m_outBuffer);
	divideByChannel(m_outBuffer, l*m_inChannels, m_inChannels);
	for (int i = 0; i < m_inChannels; i++)
		m_convolvers[i]->getNext(m_vecInOut[i], l);
	joinByChannel(l);
	return;
}

std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>> ConvolverReader::processFilter()
{
	int channels = m_irReader->getSpecs().channels;
	bool eos = false;
	int length = m_irReader->getLength();
	sample_t* buffer = (sample_t*)std::malloc(length * channels * sizeof(sample_t));
	std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>> result;
	int numParts = ceil((float)length / (N / 2));
	for (int i = 0; i < channels; i++)
	{
		result.push_back(std::make_shared<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>());
		for (int j = 0; j < numParts; j++)
			(*result[i]).push_back(std::make_shared<std::vector<fftwf_complex>>((N / 2) + 1));
	}
	int l = length;
	m_irReader->read(l, eos, buffer);
	Specs specs = m_irReader->getSpecs();
	//if (!eos || l != length)
	//{
	//	std::free(buffer);
	//	AUD_THROW(StateException, "The impulse response can not be read");
	//}

	void* bufferFFT = fftwf_malloc(((N / 2) + 1) * 2 * sizeof(fftwf_complex));
	fftwf_plan p = fftwf_plan_dft_r2c_1d(N, (float*)bufferFFT, (fftwf_complex*)bufferFFT, FFTW_ESTIMATE);
	for (int i = 0; i < channels; i++)
	{
		std::memset(bufferFFT, 0, ((N / 2) + 1) * 2 * sizeof(fftwf_complex));
		int partStart = 0;
		for (int h = 0; h < numParts; h++)
		{
			int k = 0;
			int len = std::min(partStart + ((N / 2)*channels), length*channels);
			for (int j = partStart; j < len; j += channels)
			{
				((float*)bufferFFT)[k] = buffer[j + i];
				k++;
			}
			fftwf_execute(p);
			for (int j = 0; j < (N / 2) + 1; j++)
			{
				(*(*result[i])[h])[j][0] = ((fftwf_complex*)bufferFFT)[j][0];
				(*(*result[i])[h])[j][1] = ((fftwf_complex*)bufferFFT)[j][1];
			}
			partStart += N/2*channels;
		}
	}

	fftwf_free(bufferFFT);
	fftwf_destroy_plan(p);
	std::free(buffer);

	return result;
}

void ConvolverReader::divideByChannel(sample_t* buffer, int len, int channels)
{
	int k = 0;
	for (int i = 0; i < len; i += channels)
	{
		for (int j = 0; j < channels; j++)
			m_vecInOut[j][k] = buffer[i + j];
		k++;
	}
}

void ConvolverReader::joinByChannel(int len)
{
	int k = 0;
	for (int i = 0; i < len*m_inChannels; i += m_inChannels)
	{
		for (int j = 0; j < m_vecInOut.size(); j++)
			m_outBuffer[i + j] = m_vecInOut[j][k];
		k++;
	}
}

AUD_NAMESPACE_END<commit_msg>ConvolverReader class adapted to use Convolver objects<commit_after>#include "fx/ConvolverReader.h"
#include "Exception.h"

#include <cstring>
#include <math.h>
#include <algorithm>

#define N 2048
AUD_NAMESPACE_BEGIN

ConvolverReader::ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<IReader> irReader) :
	m_reader(reader), m_irReader(irReader), m_position(0), m_eosReader(false), m_eosTail(false)
{
	m_irChannels = irReader->getSpecs().channels;
	m_inChannels = reader->getSpecs().channels;
	if (m_irChannels != 1 && m_irChannels != m_inChannels)
		AUD_THROW(StateException, "The impulse response and the sound must either have the same amount of channels or the impulse response must be mono");

	m_N = N;
	m_M = m_L = N / 2;

	auto irVector = processFilter();

	if (m_irChannels > 1)
		for (int i = 0; i < m_inChannels; i++)
			m_convolvers.push_back(std::make_unique<Convolver>(irVector[i], m_N, m_irReader->getLength(), false));
	else
		for (int i = 0; i < m_inChannels; i++)
			m_convolvers.push_back(std::make_unique<Convolver>(irVector[0], m_N, m_irReader->getLength(), false));

	for (int i = 0; i < m_inChannels; i++)
		m_vecInOut.push_back((sample_t*)std::malloc(m_L*sizeof(sample_t)));
	m_outBuffer = (sample_t*)std::malloc(m_L*m_inChannels * sizeof(sample_t));
	m_outBufLen = m_eOutBufLen = m_outBufferPos = m_L*m_inChannels;
}

ConvolverReader::~ConvolverReader()
{
	delete m_outBuffer;
	for (int i = 0; i < m_inChannels; i++)
		std::free(m_vecInOut[i]);
}

bool ConvolverReader::isSeekable() const
{
	return m_reader->isSeekable();
}

void ConvolverReader::seek(int position)
{
	m_reader->seek(position);
	for (int i = 0; i < m_inChannels; i++)
		m_convolvers[i]->reset();
}

int ConvolverReader::getLength() const
{
	return m_reader->getLength();
}

int ConvolverReader::getPosition() const
{
	return m_reader->getPosition();
}

Specs ConvolverReader::getSpecs() const
{
	return m_reader->getSpecs();
}

void ConvolverReader::read(int& length, bool& eos, sample_t* buffer)
{
	if (length <= 0)
	{
		length = 0;
		return;
	}

	int writePos = 0;
	do
	{
		int writeLength = std::min((length*m_inChannels) - writePos, m_outBufLen);
		int l = m_L;
		int bufRest = m_eOutBufLen - m_outBufferPos;
		if (bufRest < writeLength)
		{
			if (bufRest > 0)
				std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
			loadBuffer(0);
			std::memcpy(buffer + writePos + bufRest, m_outBuffer, (writeLength - bufRest)*sizeof(sample_t));
			m_outBufferPos = writeLength - bufRest;
		}
		else
		{
			std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
			m_outBufferPos += writeLength;
		}
		writePos += writeLength;
	} while (writePos < length*m_inChannels);
}

void ConvolverReader::loadBuffer(int ini)
{
	int l = m_L;
	m_reader->read(l, m_eosReader, m_outBuffer);
	divideByChannel(m_outBuffer, l*m_inChannels, m_inChannels);
	for (int i = 0; i < m_inChannels; i++)
		m_convolvers[i]->getNext(m_vecInOut[i], l);
	joinByChannel(l);
	return;
}

std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>> ConvolverReader::processFilter()
{
	int channels = m_irReader->getSpecs().channels;
	bool eos = false;
	int length = m_irReader->getLength();
	sample_t* buffer = (sample_t*)std::malloc(length * channels * sizeof(sample_t));
	std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>> result;
	int numParts = ceil((float)length / (N / 2));
	for (int i = 0; i < channels; i++)
	{
		result.push_back(std::make_shared<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>>());
		for (int j = 0; j < numParts; j++)
			(*result[i]).push_back(std::make_shared<std::vector<fftwf_complex>>((N / 2) + 1));
	}
	int l = length;
	m_irReader->read(l, eos, buffer);
	Specs specs = m_irReader->getSpecs();
	//if (!eos || l != length)
	//{
	//	std::free(buffer);
	//	AUD_THROW(StateException, "The impulse response can not be read");
	//}

	void* bufferFFT = fftwf_malloc(((N / 2) + 1) * 2 * sizeof(fftwf_complex));
	fftwf_plan p = fftwf_plan_dft_r2c_1d(N, (float*)bufferFFT, (fftwf_complex*)bufferFFT, FFTW_ESTIMATE);
	for (int i = 0; i < channels; i++)
	{
		std::memset(bufferFFT, 0, ((N / 2) + 1) * 2 * sizeof(fftwf_complex));
		int partStart = 0;
		for (int h = 0; h < numParts; h++)
		{
			int k = 0;
			int len = std::min(partStart + ((N / 2)*channels), length*channels);
			for (int j = partStart; j < len; j += channels)
			{
				((float*)bufferFFT)[k] = buffer[j + i];
				k++;
			}
			fftwf_execute(p);
			for (int j = 0; j < (N / 2) + 1; j++)
			{
				(*(*result[i])[h])[j][0] = ((fftwf_complex*)bufferFFT)[j][0];
				(*(*result[i])[h])[j][1] = ((fftwf_complex*)bufferFFT)[j][1];
			}
			partStart += N/2*channels;
		}
	}

	fftwf_free(bufferFFT);
	fftwf_destroy_plan(p);
	std::free(buffer);

	return result;
}

void ConvolverReader::divideByChannel(sample_t* buffer, int len, int channels)
{
	int k = 0;
	for (int i = 0; i < len; i += channels)
	{
		for (int j = 0; j < channels; j++)
			m_vecInOut[j][k] = buffer[i + j];
		k++;
	}
}

void ConvolverReader::joinByChannel(int len)
{
	int k = 0;
	for (int i = 0; i < len*m_inChannels; i += m_inChannels)
	{
		for (int j = 0; j < m_vecInOut.size(); j++)
			m_outBuffer[i + j] = m_vecInOut[j][k];
		k++;
	}
}

AUD_NAMESPACE_END<|endoftext|>


<commit_before>// $Id: elem_refinement.C,v 1.18 2006-03-22 21:33:27 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "elem.h"
#include "mesh_refinement.h"

//--------------------------------------------------------------------
// Elem methods

/**
 * The following functions only apply when
 * AMR is enabled and thus are not present
 * otherwise.
 */
#ifdef ENABLE_AMR

void Elem::refine (MeshRefinement& mesh_refinement)
{
  assert (this->refinement_flag() == Elem::REFINE);
  assert (this->active());

  // Create my children if necessary
  if (!_children)
    {
      _children = new Elem*[this->n_children()];

      for (unsigned int c=0; c<this->n_children(); c++)
        {
	  _children[c] = Elem::build(this->type(), this).release();
	  _children[c]->set_refinement_flag(Elem::JUST_REFINED);
	  _children[c]->set_p_level(this->p_level());
        }

      // Compute new nodal locations
      // and asssign nodes to children
      // Make these static.  It is unlikely the
      // sizes will change from call to call, so having these
      // static should save on reallocations
      std::vector<std::vector<Point> >        p    (this->n_children());
      std::vector<std::vector<unsigned int> > keys (this->n_children());
      std::vector<std::vector<Node*> >        nodes(this->n_children());

      // compute new nodal locations
      for (unsigned int c=0; c<this->n_children(); c++)
        {
	  p[c].resize    (this->child(c)->n_nodes());
	  keys[c].resize (this->child(c)->n_nodes());
	  nodes[c].resize(this->child(c)->n_nodes());

	  for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	    {
	      // zero entries
	      p[c][nc].zero();
	      keys[c][nc]  = 0;
	      nodes[c][nc] = NULL;

	      for (unsigned int n=0; n<this->n_nodes(); n++)
	        {
		  // The value from the embedding matrix
		  const float em_val = this->embedding_matrix(c,nc,n);

		  if (em_val != 0.)
		    {
		      p[c][nc].add_scaled (this->point(n), em_val);

		      // We may have found the node, in which case we
		      // won't need to look it up later.
		      if (em_val == 1.)
		        nodes[c][nc] = this->get_node(n);

		      // Otherwise build the key to look for the node
		      else
		        {
                          const unsigned int n_id = _cast_node_address_to_unsigned_int(n);

                          // Compute the key for this new node nc.  This will
			  // be used to locate the node if it already exists
			  // in the mesh.
			  keys[c][nc] +=
			  (((static_cast<unsigned int>(em_val*100000.)%_bp1) *
			    (n_id%_bp1))%_bp1)*_bp2;
		        }
		    }
	        }
	    }

	// assign nodes to children & add them to the mesh
	  for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	    {
	      if (nodes[c][nc] != NULL)
	        {
		  this->child(c)->set_node(nc) = nodes[c][nc];
	        }
	      else
	        {
		  this->child(c)->set_node(nc) =
		    mesh_refinement.add_point(p[c][nc],
					      keys[c][nc]);
		  this->child(c)->get_node(nc)->set_n_systems
                    (this->n_systems());
	        }
	    }

	  mesh_refinement.add_elem (this->child(c));
          this->child(c)->set_n_systems(this->n_systems());
        }
    }
  else
    {
      for (unsigned int c=0; c<this->n_children(); c++)
        {
          assert(this->child(c)->subactive());
          this->child(c)->set_refinement_flag(Elem::JUST_REFINED);
          this->child(c)->set_p_level(this->p_level());
        }
    }

  // Un-set my refinement flag now
  this->set_refinement_flag(Elem::INACTIVE);

  for (unsigned int c=0; c<this->n_children(); c++)
    {
      assert(this->child(c)->parent() == this);
      assert(this->child(c)->active());
    }
  assert (this->ancestor());
}

void Elem::compute_children_node_keys()
{
  // No node keys need to be set if I have no children
  if (!_children)
    return;

  // Temporary storage for keys.
  std::vector<std::vector<unsigned int> > keys (this->n_children());

  // compute new nodal locations
  for (unsigned int c=0; c<this->n_children(); c++)
  {
    keys[c].resize (this->child(c)->n_nodes());

    for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
    {
      for (unsigned int n=0; n<this->n_nodes(); n++)
      {
        // The value from the embedding matrix
        const float em_val = this->embedding_matrix(c,nc,n);

        // The node location is somewhere between existing vertices
        if ((em_val != 0.) && (em_val != 1.))
        {
          const unsigned int n_id = _cast_node_address_to_unsigned_int(n);

          // Compute the key for this new node nc.  This will
          // be used to locate the node if it already exists
          // in the mesh.
          keys[c][nc] +=
            (((static_cast<unsigned int>(em_val*100000.)%_bp1) *
              (n_id%_bp1))%_bp1)*_bp2;
        }
      }
    }
  }

  // By now, all the keys for the child nodes have been computed.
  // keys[c][nc] will have zero entries for nodes that already belonged
  // to the parent.
  for (unsigned int c=0; c<this->n_children(); c++)
    for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
      if (keys[c][nc] != 0)
        this->child(c)->get_node(nc)->set_key() = keys[c][nc];
}

unsigned int Elem::_cast_node_address_to_unsigned_int(const unsigned int n)
{
  // An unsigned int associated with the
  // address of the node n.  We can't use the
  // node number since they can change, so we use the
  // Node's address.  (We also can't use the x,y,z
  // location of the node since that can change too!)

#if SIZEOF_INT == SIZEOF_VOID_P

  // 32-bit machines
  const unsigned int n_id =
    reinterpret_cast<unsigned int>(this->get_node(n));

#elif SIZEOF_LONG_INT == SIZEOF_VOID_P

  // 64-bit machines
  // Another big prime number less than max_unsigned_int
  // for key creation on 64-bit machines
  const unsigned int bp3 = 4294967291;
  const unsigned int n_id =
    reinterpret_cast<long unsigned int>(this->get_node(n))%bp3;

#else
  // Huh?
#error			WHAT KIND OF CRAZY MACHINE IS THIS? CANNOT COMPILE

#endif

  return n_id;
}

void Elem::coarsen()
{
  assert (this->refinement_flag() == Elem::COARSEN_INACTIVE);
  assert (!this->active());

  // We no longer delete children until MeshRefinement::contract()
  // delete [] _children;
  // _children = NULL;

  for (unsigned int c=0; c<this->n_children(); c++)
    {
      assert (this->child(c)->refinement_flag() == Elem::COARSEN);
      this->child(c)->set_refinement_flag(Elem::INACTIVE);
    }

  this->set_refinement_flag(Elem::JUST_COARSENED);

  assert (this->active());
}

void Elem::contract()
{
  // Subactive elements get deleted entirely, not contracted
  assert (this->active());

  // Active contracted elements no longer can have children
  if (_children)
    {
      delete [] _children;
      _children = NULL;
    }
  if (this->refinement_flag() == Elem::JUST_COARSENED)
    this->set_refinement_flag(Elem::DO_NOTHING);
}

#endif // #ifdef ENABLE_AMR

<commit_msg>Maintain a possibly changed p refinement level after element coarsening<commit_after>// $Id: elem_refinement.C,v 1.19 2006-03-22 21:35:02 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "elem.h"
#include "mesh_refinement.h"

//--------------------------------------------------------------------
// Elem methods

/**
 * The following functions only apply when
 * AMR is enabled and thus are not present
 * otherwise.
 */
#ifdef ENABLE_AMR

void Elem::refine (MeshRefinement& mesh_refinement)
{
  assert (this->refinement_flag() == Elem::REFINE);
  assert (this->active());

  // Create my children if necessary
  if (!_children)
    {
      _children = new Elem*[this->n_children()];

      for (unsigned int c=0; c<this->n_children(); c++)
        {
	  _children[c] = Elem::build(this->type(), this).release();
	  _children[c]->set_refinement_flag(Elem::JUST_REFINED);
	  _children[c]->set_p_level(this->p_level());
        }

      // Compute new nodal locations
      // and asssign nodes to children
      // Make these static.  It is unlikely the
      // sizes will change from call to call, so having these
      // static should save on reallocations
      std::vector<std::vector<Point> >        p    (this->n_children());
      std::vector<std::vector<unsigned int> > keys (this->n_children());
      std::vector<std::vector<Node*> >        nodes(this->n_children());

      // compute new nodal locations
      for (unsigned int c=0; c<this->n_children(); c++)
        {
	  p[c].resize    (this->child(c)->n_nodes());
	  keys[c].resize (this->child(c)->n_nodes());
	  nodes[c].resize(this->child(c)->n_nodes());

	  for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	    {
	      // zero entries
	      p[c][nc].zero();
	      keys[c][nc]  = 0;
	      nodes[c][nc] = NULL;

	      for (unsigned int n=0; n<this->n_nodes(); n++)
	        {
		  // The value from the embedding matrix
		  const float em_val = this->embedding_matrix(c,nc,n);

		  if (em_val != 0.)
		    {
		      p[c][nc].add_scaled (this->point(n), em_val);

		      // We may have found the node, in which case we
		      // won't need to look it up later.
		      if (em_val == 1.)
		        nodes[c][nc] = this->get_node(n);

		      // Otherwise build the key to look for the node
		      else
		        {
                          const unsigned int n_id = _cast_node_address_to_unsigned_int(n);

                          // Compute the key for this new node nc.  This will
			  // be used to locate the node if it already exists
			  // in the mesh.
			  keys[c][nc] +=
			  (((static_cast<unsigned int>(em_val*100000.)%_bp1) *
			    (n_id%_bp1))%_bp1)*_bp2;
		        }
		    }
	        }
	    }

	// assign nodes to children & add them to the mesh
	  for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	    {
	      if (nodes[c][nc] != NULL)
	        {
		  this->child(c)->set_node(nc) = nodes[c][nc];
	        }
	      else
	        {
		  this->child(c)->set_node(nc) =
		    mesh_refinement.add_point(p[c][nc],
					      keys[c][nc]);
		  this->child(c)->get_node(nc)->set_n_systems
                    (this->n_systems());
	        }
	    }

	  mesh_refinement.add_elem (this->child(c));
          this->child(c)->set_n_systems(this->n_systems());
        }
    }
  else
    {
      for (unsigned int c=0; c<this->n_children(); c++)
        {
          assert(this->child(c)->subactive());
          this->child(c)->set_refinement_flag(Elem::JUST_REFINED);
          this->child(c)->set_p_level(this->p_level());
        }
    }

  // Un-set my refinement flag now
  this->set_refinement_flag(Elem::INACTIVE);

  for (unsigned int c=0; c<this->n_children(); c++)
    {
      assert(this->child(c)->parent() == this);
      assert(this->child(c)->active());
    }
  assert (this->ancestor());
}

void Elem::compute_children_node_keys()
{
  // No node keys need to be set if I have no children
  if (!_children)
    return;

  // Temporary storage for keys.
  std::vector<std::vector<unsigned int> > keys (this->n_children());

  // compute new nodal locations
  for (unsigned int c=0; c<this->n_children(); c++)
  {
    keys[c].resize (this->child(c)->n_nodes());

    for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
    {
      for (unsigned int n=0; n<this->n_nodes(); n++)
      {
        // The value from the embedding matrix
        const float em_val = this->embedding_matrix(c,nc,n);

        // The node location is somewhere between existing vertices
        if ((em_val != 0.) && (em_val != 1.))
        {
          const unsigned int n_id = _cast_node_address_to_unsigned_int(n);

          // Compute the key for this new node nc.  This will
          // be used to locate the node if it already exists
          // in the mesh.
          keys[c][nc] +=
            (((static_cast<unsigned int>(em_val*100000.)%_bp1) *
              (n_id%_bp1))%_bp1)*_bp2;
        }
      }
    }
  }

  // By now, all the keys for the child nodes have been computed.
  // keys[c][nc] will have zero entries for nodes that already belonged
  // to the parent.
  for (unsigned int c=0; c<this->n_children(); c++)
    for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
      if (keys[c][nc] != 0)
        this->child(c)->get_node(nc)->set_key() = keys[c][nc];
}

unsigned int Elem::_cast_node_address_to_unsigned_int(const unsigned int n)
{
  // An unsigned int associated with the
  // address of the node n.  We can't use the
  // node number since they can change, so we use the
  // Node's address.  (We also can't use the x,y,z
  // location of the node since that can change too!)

#if SIZEOF_INT == SIZEOF_VOID_P

  // 32-bit machines
  const unsigned int n_id =
    reinterpret_cast<unsigned int>(this->get_node(n));

#elif SIZEOF_LONG_INT == SIZEOF_VOID_P

  // 64-bit machines
  // Another big prime number less than max_unsigned_int
  // for key creation on 64-bit machines
  const unsigned int bp3 = 4294967291;
  const unsigned int n_id =
    reinterpret_cast<long unsigned int>(this->get_node(n))%bp3;

#else
  // Huh?
#error			WHAT KIND OF CRAZY MACHINE IS THIS? CANNOT COMPILE

#endif

  return n_id;
}

void Elem::coarsen()
{
  assert (this->refinement_flag() == Elem::COARSEN_INACTIVE);
  assert (!this->active());

  // We no longer delete children until MeshRefinement::contract()
  // delete [] _children;
  // _children = NULL;

  for (unsigned int c=0; c<this->n_children(); c++)
    {
      assert (this->child(c)->refinement_flag() == Elem::COARSEN);
      this->child(c)->set_refinement_flag(Elem::INACTIVE);
      if (this->child(c)->p_level() > this->p_level())
        this->set_p_level(this->child(c)->p_level());
    }

  this->set_refinement_flag(Elem::JUST_COARSENED);

  assert (this->active());
}

void Elem::contract()
{
  // Subactive elements get deleted entirely, not contracted
  assert (this->active());

  // Active contracted elements no longer can have children
  if (_children)
    {
      delete [] _children;
      _children = NULL;
    }
  if (this->refinement_flag() == Elem::JUST_COARSENED)
    this->set_refinement_flag(Elem::DO_NOTHING);
}

#endif // #ifdef ENABLE_AMR

<|endoftext|>


<commit_before>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2019 Grégory Van den Borre
 *
 * More infos available: https://engine.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

#include <Ogre.h>
#include <OgreArchive.h>
#include <OgreDataStream.h>
#include <OgreStringVector.h>
#include <OgreString.h>
#include <yz_physfs_File.hpp>
#include <yz_physfs_Wrapper.hpp>
#include "stdafx.h"

namespace yz {

namespace ogre {

namespace vfs {

/**
* Ogre Archive implementation for a VFS.
*@author Grégory Van den Borre
*/
class Archive: public Ogre::Archive {

public:

    Archive(const yz::physfs::Wrapper* vfs, const Ogre::String& name, const Ogre::String& type) : Ogre::Archive(name, type), vfs(vfs) {
        LOG_FUNCTION
    }

    /** PhysFS is case sensitive in general */
    bool isCaseSensitive() const {
        LOG_FUNCTION
        return true;
    }

    /**
     * Loading is handled by the VFS.
     */
    void load() {
        LOG_FUNCTION
    }

    /**
     * Unloading is handled by the VFS.
     */
    void unload() {
        LOG_FUNCTION
    }

    inline time_t getModifiedTime(const Ogre::String& file) const {
        LOG_FUNCTION
        return this->vfs->getLastModTime(file);
    }

    Ogre::DataStreamPtr open(const Ogre::String& filename, bool append) const;

    Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false) const;

    Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false) const;

    Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true, bool dirs = false) const;

    bool exists(const Ogre::String& filename) const;

    Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern, bool recursive = true, bool dirs = false) const;

private:

    void listInfoRecursive(const Ogre::String& base, bool recursive, bool dirs, Ogre::FileInfoListPtr fileInfoList) const;

    void listRecursive(const Ogre::String& base, bool recursive, bool dirs, Ogre::StringVectorPtr fileList) const;

    const yz::physfs::Wrapper* vfs;
};
}}}
<commit_msg>Update yz_ogre_vfs_Archive.hpp<commit_after>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2019 Grégory Van den Borre
 *
 * More infos available: https://engine.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

#include <Ogre.h>
#include <OgreArchive.h>
#include <OgreDataStream.h>
#include <OgreStringVector.h>
#include <OgreString.h>
#include <yz_physfs_File.hpp>
#include <yz_physfs_Wrapper.hpp>
#include "stdafx.h"
#include "yz_ogre_vfs_DataStream.hpp"

namespace yz {

namespace ogre {

namespace vfs {

/**
* Ogre Archive implementation for a VFS.
*@author Grégory Van den Borre
*/
class Archive: public Ogre::Archive {

public:

    Archive(const yz::physfs::Wrapper* vfs, const Ogre::String& name, const Ogre::String& type) : Ogre::Archive(name, type), vfs(vfs) {
        LOG_FUNCTION
    }

    /** PhysFS is case sensitive in general */
    bool isCaseSensitive() const {
        LOG_FUNCTION
        return true;
    }

    /**
     * Loading is handled by the VFS.
     */
    void load() {
        LOG_FUNCTION
    }

    /**
     * Unloading is handled by the VFS.
     */
    void unload() {
        LOG_FUNCTION
    }

    inline time_t getModifiedTime(const Ogre::String& file) const {
        LOG_FUNCTION
        return this->vfs->getLastModTime(file);
    }

    Ogre::DataStreamPtr open(const Ogre::String& filename, bool append) const;

    Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false) const;

    Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false) const;

    Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true, bool dirs = false) const;

    bool exists(const Ogre::String& filename) const;

    Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern, bool recursive = true, bool dirs = false) const;

private:

    void listInfoRecursive(const Ogre::String& base, bool recursive, bool dirs, Ogre::FileInfoListPtr fileInfoList) const;

    void listRecursive(const Ogre::String& base, bool recursive, bool dirs, Ogre::StringVectorPtr fileList) const;

    const yz::physfs::Wrapper* vfs;
};
}}}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013-2014 Nick Guletskii
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "OSDInstance.hpp"
#include "glinject.hpp"
#include "Colour.hpp"
#include "ConfigurationManager.hpp"
#include "FontRenderer.hpp"
#include "GLAttribState.hpp"
#include "GLXOSD.hpp"
#include "Utils.hpp"
#include <algorithm>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include <GL/gl.h>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
#include <sys/time.h>
namespace glxosd {

OSDInstance::OSDInstance() :
		renderer(nullptr),
		osdText("Gathering data...") {
	const ConfigurationManager &configurationManager =
			GLXOSD::instance()->getConfigurationManager();

	std::string fontName = configurationManager.getProperty<std::string>(
			"font_name");
	int fontSize = configurationManager.getProperty<int>("font_size_int");
	int fontColourR = configurationManager.getProperty<int>(
			"font_colour_r_int");
	int fontColourG = configurationManager.getProperty<int>(
			"font_colour_g_int");
	int fontColourB = configurationManager.getProperty<int>(
			"font_colour_b_int");
	int fontColourA = configurationManager.getProperty<int>(
			"font_colour_a_int");
	int fontOutlineColourR = configurationManager.getProperty<int>(
			"font_outline_colour_r_int");
	int fontOutlineColourG = configurationManager.getProperty<int>(
			"font_outline_colour_g_int");
	int fontOutlineColourB = configurationManager.getProperty<int>(
			"font_outline_colour_b_int");
	int fontOutlineColourA = configurationManager.getProperty<int>(
			"font_outline_colour_a_int");

	float outlineWidth =
			configurationManager.getProperty<bool>("show_text_outline_bool") ?
					configurationManager.getProperty<float>(
							"font_outline_width_float") :
					0;

	int horizontalDPI = configurationManager.getProperty<int>(
			"font_dpi_horizontal_int");
	int verticalDPI = configurationManager.getProperty<int>(
			"font_dpi_vertical_int");

	int textPositionX = configurationManager.getProperty<int>("text_pos_x_int");
	int textPositionY = configurationManager.getProperty<int>("text_pos_y_int");
	float textSpacingY = configurationManager.getProperty<float>(
			"text_spacing_y_float");
	float textSpacingX = configurationManager.getProperty<float>(
			"text_spacing_x_float");

	fpsFormat = configurationManager.getProperty<boost::format>("fps_format");

	frameLoggingMessage = configurationManager.getProperty<std::string>(
			"frame_logging_message_string");
	frameLoggingDumpInProgressMessage = configurationManager.getProperty<std::string>(
			"frame_logging_dump_in_progress_message_string");

	renderer = new FontRenderer(fontName, fontSize, horizontalDPI, verticalDPI,
			outlineWidth);
	renderer->setFontColour(
			ColourRGBA(fontColourR, fontColourG, fontColourB, fontColourA));
	renderer->setFontOutlineColour(
			ColourRGBA(fontOutlineColourR, fontOutlineColourG,
					fontOutlineColourB, fontOutlineColourA));

	renderer->setTextPositionX(textPositionX);
	renderer->setTextPositionY(textPositionY);
	renderer->setTextSpacingX(textSpacingX);
	renderer->setTextSpacingY(textSpacingY);

	currentFrameCount = 0;
	framesPerSecond = 0;
//Set the time for the first time.
	previousTime = getMonotonicTimeNanoseconds() / 1000000ULL;
}

void OSDInstance::update(long currentMilliseconds) {

	framesPerSecond = 1000.0 * currentFrameCount
			/ (currentMilliseconds - previousTime);
	previousTime = currentMilliseconds;
	previousTime = currentMilliseconds;
	currentFrameCount = 0;

	std::stringstream osdTextBuilder;
	osdTextBuilder << boost::format(fpsFormat) % framesPerSecond;

	std::vector<PluginDataProvider>* dataProviders =
			GLXOSD::instance()->getPluginDataProviders();

	std::for_each(dataProviders->begin(), dataProviders->end(),
			[&osdTextBuilder](PluginDataProvider &sensorDataProvider) {
				std::string* strPtr = sensorDataProvider(GLXOSD::instance());
				osdTextBuilder << *strPtr;
				delete strPtr; // Prevent memory leak. Goddamn C ABI forcing me to use pointers!!
				// The weird thing is: it gets deleted even without the delete. How and why?
			});

	osdText = osdTextBuilder.str();
}

void OSDInstance::renderText(unsigned int width, unsigned int height) {
	std::stringstream osd_text_reader;
	osd_text_reader << osdText;
	if (GLXOSD::instance()->isFrameLoggingEnabled()) {
		osd_text_reader << std::endl << frameLoggingMessage;
	}
	if (GLXOSD::instance()->isFrameLoggingDumpInProgress()) {
		osd_text_reader << std::endl << frameLoggingDumpInProgressMessage;
	}

	std::string str = osd_text_reader.str();
	std::transform(str.begin(), str.end(), str.begin(), ::toupper);

	renderer->render(width, height, str);
}

void OSDInstance::render(unsigned int width, unsigned int height) {
	currentFrameCount++;
	long currentTimeMilliseconds = getMonotonicTimeNanoseconds() / 1000000ULL;
//Refresh the info every 500 milliseconds
	if (currentTimeMilliseconds - previousTime >= 500) {
		update(currentTimeMilliseconds);
	}

	// Memorise misc. settings
	GLint program;
	{
		rgl(GetIntegerv)(GL_CURRENT_PROGRAM, &program);
		rgl(UseProgram)(0);
	}

	GLint frontFace;
	{
		rgl(GetIntegerv)(GL_FRONT_FACE, &frontFace);
		rgl(FrontFace)(GL_CCW);
	}

	GLfloat blendColour[4];
	{
		rgl(GetFloatv)(GL_BLEND_COLOR, blendColour);
		rgl(BlendColor)(0, 0, 0, 0);
	}

	GLboolean colourMask[4];
	{
		rgl(GetBooleanv)(GL_COLOR_WRITEMASK, colourMask);
		rgl(ColorMask)(1, 1, 1, 1);
	}

	GLint blendSrc;
	GLint blendDst;
	{
		rgl(GetIntegerv)(GL_BLEND_SRC, &blendSrc);
		rgl(GetIntegerv)(GL_BLEND_DST, &blendDst);
		rgl(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	//Equivalent to glPushAttrib -> glEnable/Disable -> glPopAttrib
	GLAttribState attribState(rgl(Enable), rgl(Disable), rgl(IsEnabled));
	GLAttribState clientAttribState(glEnableClientState, glDisableClientState,
			rgl(IsEnabled));
	{
		attribState.set(GL_ALPHA_TEST, GL_FALSE);
		attribState.set(GL_AUTO_NORMAL, GL_FALSE);
		attribState.set(GL_CULL_FACE, GL_FALSE);
		attribState.set(GL_COLOR_LOGIC_OP, GL_FALSE);
		attribState.set(GL_COLOR_TABLE, GL_FALSE);
		attribState.set(GL_CONVOLUTION_1D, GL_FALSE);
		attribState.set(GL_CONVOLUTION_2D, GL_FALSE);
		attribState.set(GL_DEPTH_TEST, GL_FALSE);
		attribState.set(GL_DITHER, GL_FALSE);
		attribState.set(GL_FOG, GL_FALSE);
		attribState.set(GL_HISTOGRAM, GL_FALSE);
		attribState.set(GL_INDEX_LOGIC_OP, GL_FALSE);
		attribState.set(GL_LIGHTING, GL_FALSE);
		attribState.set(GL_NORMALIZE, GL_FALSE);
		attribState.set(GL_MINMAX, GL_FALSE);
		attribState.set(GL_SEPARABLE_2D, GL_FALSE);
		attribState.set(GL_SCISSOR_TEST, GL_FALSE);
		attribState.set(GL_STENCIL_TEST, GL_FALSE);
		attribState.set(GL_SAMPLE_ALPHA_TO_COVERAGE, GL_FALSE);
		attribState.set(GL_MULTISAMPLE, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_POINT, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_LINE, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_FILL, GL_FALSE);
		attribState.set(GL_SAMPLE_COVERAGE, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_Q, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_R, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_S, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_T, GL_FALSE);
		clientAttribState.set(GL_COLOR_ARRAY, GL_FALSE);
		clientAttribState.set(GL_EDGE_FLAG_ARRAY, GL_FALSE);
		clientAttribState.set(GL_INDEX_ARRAY, GL_FALSE);
		clientAttribState.set(GL_NORMAL_ARRAY, GL_FALSE);
		clientAttribState.set(GL_TEXTURE_COORD_ARRAY, GL_TRUE);
		clientAttribState.set(GL_VERTEX_ARRAY, GL_TRUE);
	}
	{
		attribState.set(GL_TEXTURE_CUBE_MAP, GL_FALSE);
		attribState.set(GL_VERTEX_PROGRAM_ARB, GL_FALSE);
		attribState.set(GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
		attribState.set(GL_BLEND, GL_TRUE);
		attribState.set(GL_TEXTURE_2D, GL_TRUE);
	}

	//Memorise buffer states
	GLint pixelUnpackBufferBinding = 0, arrayBufferBinding = 0, activeTexture =
			0, textureBinding2D = 0, vertexArrayBinding = 0,
			elementArrayBufferBinding = 0, drawFramebufferBinding = 0,
			readFramebufferBinding = 0, glPolygonModeFrontAndBack = 0,
			samplerBinding = 0;
	rgl(GetIntegerv)(GL_PIXEL_UNPACK_BUFFER_BINDING,
			&pixelUnpackBufferBinding);
	rgl(GetIntegerv)(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding);
	rgl(GetIntegerv)(GL_ACTIVE_TEXTURE, &activeTexture);
	rgl(GetIntegerv)(GL_TEXTURE_BINDING_2D, &textureBinding2D);
	rgl(GetIntegerv)(GL_VERTEX_ARRAY_BINDING, &vertexArrayBinding);
	rgl(GetIntegerv)(GL_ELEMENT_ARRAY_BUFFER_BINDING,
			&elementArrayBufferBinding);
	rgl(GetIntegerv)(GL_DRAW_FRAMEBUFFER_BINDING,
			&drawFramebufferBinding);
	rgl(GetIntegerv)(GL_READ_FRAMEBUFFER_BINDING,
			&readFramebufferBinding);
	rgl(GetIntegerv)(GL_POLYGON_MODE,
			&glPolygonModeFrontAndBack);

	//We are borrowing GL_TEXTURE0, so we need to reset its sampler
	rgl(ActiveTexture)(GL_TEXTURE0);
	rgl(GetIntegerv)(GL_SAMPLER_BINDING, &samplerBinding);

	rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, 0);
	rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, 0);
	rgl(PolygonMode)(GL_FRONT_AND_BACK, GL_FILL);

	renderText(width, height);

	//Revert sampler
	rgl(ActiveTexture)(GL_TEXTURE0);
	rgl(BindSampler)(0, samplerBinding);

	//Revert buffer states
	rgl(ActiveTexture)(activeTexture);
	rgl(BindTexture)(GL_TEXTURE_2D, textureBinding2D);
	rgl(BindVertexArray)(vertexArrayBinding);
	rgl(BindBuffer)(GL_PIXEL_UNPACK_BUFFER, pixelUnpackBufferBinding);
	rgl(BindBuffer)(GL_ARRAY_BUFFER, arrayBufferBinding);
	rgl(BindBuffer)(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferBinding);
	rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, drawFramebufferBinding);
	rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, readFramebufferBinding);

	rgl(PolygonMode)(GL_FRONT_AND_BACK, glPolygonModeFrontAndBack);

	//Revert misc settings
	rgl(BlendColor)(blendColour[0], blendColour[1], blendColour[2],
			blendColour[3]);
	rgl(BlendFunc)(blendSrc, blendDst);
	rgl(ColorMask)(colourMask[0], colourMask[1], colourMask[2],
			colourMask[3]);
	rgl(FrontFace)(frontFace);
	rgl(UseProgram)(program);
}
OSDInstance::~OSDInstance() {
}
}

<commit_msg>Fix reset of GL_TEXTURE_BINDING_2D<commit_after>/*
 * Copyright (C) 2013-2014 Nick Guletskii
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "OSDInstance.hpp"
#include "glinject.hpp"
#include "Colour.hpp"
#include "ConfigurationManager.hpp"
#include "FontRenderer.hpp"
#include "GLAttribState.hpp"
#include "GLXOSD.hpp"
#include "Utils.hpp"
#include <algorithm>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include <GL/gl.h>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
#include <sys/time.h>
namespace glxosd {

OSDInstance::OSDInstance() :
		renderer(nullptr),
		osdText("Gathering data...") {
	const ConfigurationManager &configurationManager =
			GLXOSD::instance()->getConfigurationManager();

	std::string fontName = configurationManager.getProperty<std::string>(
			"font_name");
	int fontSize = configurationManager.getProperty<int>("font_size_int");
	int fontColourR = configurationManager.getProperty<int>(
			"font_colour_r_int");
	int fontColourG = configurationManager.getProperty<int>(
			"font_colour_g_int");
	int fontColourB = configurationManager.getProperty<int>(
			"font_colour_b_int");
	int fontColourA = configurationManager.getProperty<int>(
			"font_colour_a_int");
	int fontOutlineColourR = configurationManager.getProperty<int>(
			"font_outline_colour_r_int");
	int fontOutlineColourG = configurationManager.getProperty<int>(
			"font_outline_colour_g_int");
	int fontOutlineColourB = configurationManager.getProperty<int>(
			"font_outline_colour_b_int");
	int fontOutlineColourA = configurationManager.getProperty<int>(
			"font_outline_colour_a_int");

	float outlineWidth =
			configurationManager.getProperty<bool>("show_text_outline_bool") ?
					configurationManager.getProperty<float>(
							"font_outline_width_float") :
					0;

	int horizontalDPI = configurationManager.getProperty<int>(
			"font_dpi_horizontal_int");
	int verticalDPI = configurationManager.getProperty<int>(
			"font_dpi_vertical_int");

	int textPositionX = configurationManager.getProperty<int>("text_pos_x_int");
	int textPositionY = configurationManager.getProperty<int>("text_pos_y_int");
	float textSpacingY = configurationManager.getProperty<float>(
			"text_spacing_y_float");
	float textSpacingX = configurationManager.getProperty<float>(
			"text_spacing_x_float");

	fpsFormat = configurationManager.getProperty<boost::format>("fps_format");

	frameLoggingMessage = configurationManager.getProperty<std::string>(
			"frame_logging_message_string");
	frameLoggingDumpInProgressMessage = configurationManager.getProperty<std::string>(
			"frame_logging_dump_in_progress_message_string");

	renderer = new FontRenderer(fontName, fontSize, horizontalDPI, verticalDPI,
			outlineWidth);
	renderer->setFontColour(
			ColourRGBA(fontColourR, fontColourG, fontColourB, fontColourA));
	renderer->setFontOutlineColour(
			ColourRGBA(fontOutlineColourR, fontOutlineColourG,
					fontOutlineColourB, fontOutlineColourA));

	renderer->setTextPositionX(textPositionX);
	renderer->setTextPositionY(textPositionY);
	renderer->setTextSpacingX(textSpacingX);
	renderer->setTextSpacingY(textSpacingY);

	currentFrameCount = 0;
	framesPerSecond = 0;
//Set the time for the first time.
	previousTime = getMonotonicTimeNanoseconds() / 1000000ULL;
}

void OSDInstance::update(long currentMilliseconds) {

	framesPerSecond = 1000.0 * currentFrameCount
			/ (currentMilliseconds - previousTime);
	previousTime = currentMilliseconds;
	previousTime = currentMilliseconds;
	currentFrameCount = 0;

	std::stringstream osdTextBuilder;
	osdTextBuilder << boost::format(fpsFormat) % framesPerSecond;

	std::vector<PluginDataProvider>* dataProviders =
			GLXOSD::instance()->getPluginDataProviders();

	std::for_each(dataProviders->begin(), dataProviders->end(),
			[&osdTextBuilder](PluginDataProvider &sensorDataProvider) {
				std::string* strPtr = sensorDataProvider(GLXOSD::instance());
				osdTextBuilder << *strPtr;
				delete strPtr; // Prevent memory leak. Goddamn C ABI forcing me to use pointers!!
				// The weird thing is: it gets deleted even without the delete. How and why?
			});

	osdText = osdTextBuilder.str();
}

void OSDInstance::renderText(unsigned int width, unsigned int height) {
	std::stringstream osd_text_reader;
	osd_text_reader << osdText;
	if (GLXOSD::instance()->isFrameLoggingEnabled()) {
		osd_text_reader << std::endl << frameLoggingMessage;
	}
	if (GLXOSD::instance()->isFrameLoggingDumpInProgress()) {
		osd_text_reader << std::endl << frameLoggingDumpInProgressMessage;
	}

	std::string str = osd_text_reader.str();
	std::transform(str.begin(), str.end(), str.begin(), ::toupper);

	renderer->render(width, height, str);
}

void OSDInstance::render(unsigned int width, unsigned int height) {
	currentFrameCount++;
	long currentTimeMilliseconds = getMonotonicTimeNanoseconds() / 1000000ULL;
//Refresh the info every 500 milliseconds
	if (currentTimeMilliseconds - previousTime >= 500) {
		update(currentTimeMilliseconds);
	}

	// Memorise misc. settings
	GLint program;
	{
		rgl(GetIntegerv)(GL_CURRENT_PROGRAM, &program);
		rgl(UseProgram)(0);
	}

	GLint frontFace;
	{
		rgl(GetIntegerv)(GL_FRONT_FACE, &frontFace);
		rgl(FrontFace)(GL_CCW);
	}

	GLfloat blendColour[4];
	{
		rgl(GetFloatv)(GL_BLEND_COLOR, blendColour);
		rgl(BlendColor)(0, 0, 0, 0);
	}

	GLboolean colourMask[4];
	{
		rgl(GetBooleanv)(GL_COLOR_WRITEMASK, colourMask);
		rgl(ColorMask)(1, 1, 1, 1);
	}

	GLint blendSrc;
	GLint blendDst;
	{
		rgl(GetIntegerv)(GL_BLEND_SRC, &blendSrc);
		rgl(GetIntegerv)(GL_BLEND_DST, &blendDst);
		rgl(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	//Equivalent to glPushAttrib -> glEnable/Disable -> glPopAttrib
	GLAttribState attribState(rgl(Enable), rgl(Disable), rgl(IsEnabled));
	GLAttribState clientAttribState(glEnableClientState, glDisableClientState,
			rgl(IsEnabled));
	{
		attribState.set(GL_ALPHA_TEST, GL_FALSE);
		attribState.set(GL_AUTO_NORMAL, GL_FALSE);
		attribState.set(GL_CULL_FACE, GL_FALSE);
		attribState.set(GL_COLOR_LOGIC_OP, GL_FALSE);
		attribState.set(GL_COLOR_TABLE, GL_FALSE);
		attribState.set(GL_CONVOLUTION_1D, GL_FALSE);
		attribState.set(GL_CONVOLUTION_2D, GL_FALSE);
		attribState.set(GL_DEPTH_TEST, GL_FALSE);
		attribState.set(GL_DITHER, GL_FALSE);
		attribState.set(GL_FOG, GL_FALSE);
		attribState.set(GL_HISTOGRAM, GL_FALSE);
		attribState.set(GL_INDEX_LOGIC_OP, GL_FALSE);
		attribState.set(GL_LIGHTING, GL_FALSE);
		attribState.set(GL_NORMALIZE, GL_FALSE);
		attribState.set(GL_MINMAX, GL_FALSE);
		attribState.set(GL_SEPARABLE_2D, GL_FALSE);
		attribState.set(GL_SCISSOR_TEST, GL_FALSE);
		attribState.set(GL_STENCIL_TEST, GL_FALSE);
		attribState.set(GL_SAMPLE_ALPHA_TO_COVERAGE, GL_FALSE);
		attribState.set(GL_MULTISAMPLE, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_POINT, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_LINE, GL_FALSE);
		attribState.set(GL_POLYGON_OFFSET_FILL, GL_FALSE);
		attribState.set(GL_SAMPLE_COVERAGE, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_Q, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_R, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_S, GL_FALSE);
		attribState.set(GL_TEXTURE_GEN_T, GL_FALSE);
		clientAttribState.set(GL_COLOR_ARRAY, GL_FALSE);
		clientAttribState.set(GL_EDGE_FLAG_ARRAY, GL_FALSE);
		clientAttribState.set(GL_INDEX_ARRAY, GL_FALSE);
		clientAttribState.set(GL_NORMAL_ARRAY, GL_FALSE);
		clientAttribState.set(GL_TEXTURE_COORD_ARRAY, GL_TRUE);
		clientAttribState.set(GL_VERTEX_ARRAY, GL_TRUE);
	}
	{
		attribState.set(GL_TEXTURE_CUBE_MAP, GL_FALSE);
		attribState.set(GL_VERTEX_PROGRAM_ARB, GL_FALSE);
		attribState.set(GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
		attribState.set(GL_BLEND, GL_TRUE);
		attribState.set(GL_TEXTURE_2D, GL_TRUE);
	}

	//Memorise buffer states
	GLint pixelUnpackBufferBinding = 0, arrayBufferBinding = 0, activeTexture =
			0, textureBinding2D = 0, vertexArrayBinding = 0,
			elementArrayBufferBinding = 0, drawFramebufferBinding = 0,
			readFramebufferBinding = 0, glPolygonModeFrontAndBack = 0,
			samplerBinding = 0;
	rgl(GetIntegerv)(GL_PIXEL_UNPACK_BUFFER_BINDING,
			&pixelUnpackBufferBinding);
	rgl(GetIntegerv)(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding);
	rgl(GetIntegerv)(GL_ACTIVE_TEXTURE, &activeTexture);
	rgl(GetIntegerv)(GL_VERTEX_ARRAY_BINDING, &vertexArrayBinding);
	rgl(GetIntegerv)(GL_ELEMENT_ARRAY_BUFFER_BINDING,
			&elementArrayBufferBinding);
	rgl(GetIntegerv)(GL_DRAW_FRAMEBUFFER_BINDING,
			&drawFramebufferBinding);
	rgl(GetIntegerv)(GL_READ_FRAMEBUFFER_BINDING,
			&readFramebufferBinding);
	rgl(GetIntegerv)(GL_POLYGON_MODE,
			&glPolygonModeFrontAndBack);

	//We are borrowing GL_TEXTURE0, so we need to reset its sampler
	rgl(ActiveTexture)(GL_TEXTURE0);
	rgl(GetIntegerv)(GL_SAMPLER_BINDING, &samplerBinding);
	rgl(GetIntegerv)(GL_TEXTURE_BINDING_2D, &textureBinding2D);

	rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, 0);
	rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, 0);
	rgl(PolygonMode)(GL_FRONT_AND_BACK, GL_FILL);

	renderText(width, height);

	//Revert sampler
	rgl(ActiveTexture)(GL_TEXTURE0);
	rgl(BindSampler)(0, samplerBinding);
	rgl(BindTexture)(GL_TEXTURE_2D, textureBinding2D);

	//Revert buffer states
	rgl(ActiveTexture)(activeTexture);
	rgl(BindVertexArray)(vertexArrayBinding);
	rgl(BindBuffer)(GL_PIXEL_UNPACK_BUFFER, pixelUnpackBufferBinding);
	rgl(BindBuffer)(GL_ARRAY_BUFFER, arrayBufferBinding);
	rgl(BindBuffer)(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferBinding);
	rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, drawFramebufferBinding);
	rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, readFramebufferBinding);

	rgl(PolygonMode)(GL_FRONT_AND_BACK, glPolygonModeFrontAndBack);

	//Revert misc settings
	rgl(BlendColor)(blendColour[0], blendColour[1], blendColour[2],
			blendColour[3]);
	rgl(BlendFunc)(blendSrc, blendDst);
	rgl(ColorMask)(colourMask[0], colourMask[1], colourMask[2],
			colourMask[3]);
	rgl(FrontFace)(frontFace);
	rgl(UseProgram)(program);
}
OSDInstance::~OSDInstance() {
}
}

<|endoftext|>


<commit_before><commit_msg>Ensure that the pixel line is at least 1 pixel wide.<commit_after><|endoftext|>


<commit_before>// Example STEP-NC Program using C++/CLI
// ========================================
//
// This sample C++ project calls the STEP-NC Machine Programming API
// using the .NET interface with C++/CLI calls.  The program creates a
// small machining program with a few toolpath moves.
//
// The project creates a command line program that writes test.stpnc.
// You can find more examples and other programming documentation at:
//
//	http://www.steptools.com/support/stepnc_docs/
//
#include "MtConnector.h"
using namespace System;

using namespace System::Xml;
using namespace System::Collections::Generic;

//array<int>^ CurrentPos(String ^xml)
List<array<double>^> ^  coordinates(String ^fileName,bool convert_to_inches){
//create instance of the xml reader

	XmlDocument ^doc = gcnew XmlDocument();
	doc->Load(fileName);
	XmlNode ^root = doc->DocumentElement;

		XmlNamespaceManager ^nsmgr = gcnew XmlNamespaceManager(doc->NameTable);
		nsmgr->AddNamespace("base", root->NamespaceURI);

		List<array<double>^> ^Lst = gcnew List<array<double>^>();
		String ^str;
		XmlNodeList^ pathList = root->SelectNodes("//base:PathPosition", nsmgr);

		array<double> ^coor;
		for (int i=0;i<pathList->Count;i++){
			XmlNode^ temp=pathList->Item(i);
			str=temp->InnerText;
			if(str!="UNAVAILABLE"){
			//Console::WriteLine(str);
			array<String^>^ arr;
			arr=str->Split(' ');
			coor=gcnew array<double>(3);
			try
			{
			coor[0]=Convert::ToDouble(arr[0]);
			coor[1]=Convert::ToDouble(arr[1]);
			coor[2]=Convert::ToDouble(arr[2]);
			if(convert_to_inches){
			coor[0]=coor[0]*0.0393701;
			coor[1]=coor[1]*0.0393701;
			coor[2]=coor[2]*0.0393701;

			}
			//Console::WriteLine(arr[0]);
			//Console::WriteLine(coor[0]);
			Lst->Add((array<double> ^)coor->Clone());
			}
			catch (Exception^ e){
			Console::WriteLine(e);

			}
			}

		}
return Lst;
}

void PullFromServer(MtConnector ^ mt){

STEPNCLib::AptStepMaker ^ apt = gcnew STEPNCLib::AptStepMaker();

	////////////////////////
   STEPNCLib::Finder ^find = gcnew STEPNCLib::Finder();
   apt->Inches();

   apt->Open238 ("hardmoldy_ext.stpnc");
    find->Open238 ("hardmoldy_ext.stpnc");
	//feat->OpenSpecificWorkpiece("test_with_rawpiece2.stpnc","HardModly_design.stp");

    int wp_id = find->GetMainWorkplan();
	Console::WriteLine("Main Workplan name %S\n", (find->GetExecutableName(wp_id)));

    // add a new workplan at the end of the project
    apt->NestWorkplanAfter("Workplan for new results", find->GetWorkplanExecutableCount(wp_id) + 1, wp_id);

    // Starting first workingstep in new plan

    // Create a trivial STEP-NC file
    apt->Workingstep("Extension 1");

    // Create a trivial STEP-NC file
    apt->PartNo ("test part");
	 apt->Rawpiece ("HardMoldy_stock.stp");
    long raw_id = apt->GetCurrentRawpiece ();
	 apt->DefineTool(0.25, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0);
    apt->PutWorkpiecePlacement (raw_id, 0, 0, 0, 0, 0, -1, 1, 0, 0);
	apt->GeometryForToolNumber ("Iscar_2.stp", 1);
    apt->LoadTool (1);
     apt->SpindleSpeed (300);
    apt->Feedrate (30);

		apt->GoToXYZ("point0", 0,0,200);
		apt->GoToXYZ("point0", 0,0,200);

   String ^str;
	array<double>^ coor;
	for (int i=0;i<100;i++){
		//Console::WriteLine(i);
	coor=mt->getPos();
	if(coor!=nullptr){

		str= gcnew String(String::Format("point {0} ",i));
		Console::WriteLine(str);
        Console::WriteLine(coor[0]);

		apt->GoToXYZ(str, coor[0]*0.0393701, coor[1]*0.0393701, coor[2]*0.0393701);
	}
	}

    apt->SaveAsModules("hardmoldy_extended");
	Console::WriteLine("done");
	String ^readIn =Console::ReadLine();

}

void appendToFile(String^ file_name,String^ new_file_name,bool convert_to_inches){
	List<array<double>^> ^coor_List= coordinates(file_name,convert_to_inches);
    // Create a trivial STEP-NC file
	Console::WriteLine("Got Position Data From File");
    STEPNCLib::AptStepMaker ^ apt = gcnew STEPNCLib::AptStepMaker();

	////////////////////////
   STEPNCLib::Finder ^find = gcnew STEPNCLib::Finder();

	    //	    APT.Open238("new_hardmoldy.stpnc");
	    //	    Find.Open238("new_hardmoldy.stpnc");
	    apt->Open238("hardmoldy_ext.stpnc");
	    apt->Open238("hardmoldy_ext.stpnc");

	    long wp_id = find->GetMainWorkplan();
	    Console::WriteLine("Main Workplan name " + find->GetExecutableName(wp_id));

	    // add a new workplan at the end of the project
	    apt->NestWorkplanAfter("Workplan for MTConnect results", find->GetWorkplanExecutableCount(wp_id) + 1, wp_id);

	    // Starting first workingstep in new plan
	    apt->Workingstep("testing");

//////////////////////////
    //apt->PartNo("test part");
    //apt->DefineTool(0.25, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0);
	//apt->GeometryForToolNumber ("Iscar_2.stp", 1);

		//String^ boeingTool=find->GetToolNumberAsNumber()
		Console::WriteLine("is tool defined {0}",apt->IsToolDefined(1));
			apt->LoadTool(1);
    apt->SpindleSpeed (300);
    apt->Feedrate (30);
	String ^str;
	array<double>^ coor;
	for (int i=0;i<coor_List->Count;i++){
		coor=coor_List[i];

		str=String::Format("point {0} ",i+1);
		//Console::WriteLine(str);
		//Console::WriteLine(" {0} {1} {2}",coor[0],coor[1],coor[2]);

		apt->GoToXYZ(str, coor[0], coor[1], coor[2]);

	}

	apt->SaveAsModules(new_file_name);
	Console::WriteLine("done");

}
int main(int argc, char * argv[])
{

	MtConnector ^ mt;
	mt=gcnew MtConnector();
	//mt->startPush("http://okuma-matata:5000/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@id=\"Mp1LPathPos\"]");
	//http://agent.mtconnect.org/VMC-3Axis/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@category=\"SAMPLE\"]"
	//http://okuma-matata:5000/sample?count=1000&interval=10

	//mt->getRequest("http://okuma-matata:5000/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@id=\"Mp1LPathPos\"]");
	//PullFromServer(mt);
    appendToFile("moldy_data_iteration_2.xml","moldy.stpnc",true);
	String ^readIn =Console::ReadLine();
	return 0;
}

<commit_msg>Search for a specific workplan by name Begin to get all Rapid tool paths<commit_after>// Example STEP-NC Program using C++/CLI
// ========================================
//
// This sample C++ project calls the STEP-NC Machine Programming API
// using the .NET interface with C++/CLI calls.  The program creates a
// small machining program with a few toolpath moves.
//
// The project creates a command line program that writes test.stpnc.
// You can find more examples and other programming documentation at:
//
//	http://www.steptools.com/support/stepnc_docs/
//
#include "MtConnector.h"
using namespace System;

using namespace System::Xml;
using namespace System::Collections::Generic;

//array<int>^ CurrentPos(String ^xml)
List<array<double>^> ^  coordinates(String ^fileName,bool convert_to_inches){
//create instance of the xml reader

	XmlDocument ^doc = gcnew XmlDocument();
	doc->Load(fileName);
	XmlNode ^root = doc->DocumentElement;

		XmlNamespaceManager ^nsmgr = gcnew XmlNamespaceManager(doc->NameTable);
		nsmgr->AddNamespace("base", root->NamespaceURI);

		List<array<double>^> ^Lst = gcnew List<array<double>^>();
		String ^str;
		XmlNodeList^ pathList = root->SelectNodes("//base:PathPosition", nsmgr);

		array<double> ^coor;
		for (int i=0;i<pathList->Count;i++){
			XmlNode^ temp=pathList->Item(i);
			str=temp->InnerText;
			if(str!="UNAVAILABLE"){
			//Console::WriteLine(str);
			array<String^>^ arr;
			arr=str->Split(' ');
			coor=gcnew array<double>(3);
			try
			{
			coor[0]=Convert::ToDouble(arr[0]);
			coor[1]=Convert::ToDouble(arr[1]);
			coor[2]=Convert::ToDouble(arr[2]);
			if(convert_to_inches){
			coor[0]=coor[0]*0.0393701;
			coor[1]=coor[1]*0.0393701;
			coor[2]=coor[2]*0.0393701;

			}
			//Console::WriteLine(arr[0]);
			//Console::WriteLine(coor[0]);
			Lst->Add((array<double> ^)coor->Clone());
			}
			catch (Exception^ e){
			Console::WriteLine(e);

			}
			}

		}
return Lst;
}

void PullFromServer(MtConnector ^ mt){

STEPNCLib::AptStepMaker ^ apt = gcnew STEPNCLib::AptStepMaker();

	////////////////////////
   STEPNCLib::Finder ^find = gcnew STEPNCLib::Finder();
   apt->Inches();

   apt->Open238 ("hardmoldy_ext.stpnc");
    find->Open238 ("hardmoldy_ext.stpnc");
	//feat->OpenSpecificWorkpiece("test_with_rawpiece2.stpnc","HardModly_design.stp");

    int wp_id = find->GetMainWorkplan();
	Console::WriteLine("Main Workplan name %S\n", (find->GetExecutableName(wp_id)));

    // add a new workplan at the end of the project
    apt->NestWorkplanAfter("Workplan for new results", find->GetWorkplanExecutableCount(wp_id) + 1, wp_id);

    // Starting first workingstep in new plan

    // Create a trivial STEP-NC file
    apt->Workingstep("Extension 1");

    // Create a trivial STEP-NC file
    apt->PartNo ("test part");
	 apt->Rawpiece ("HardMoldy_stock.stp");
    long raw_id = apt->GetCurrentRawpiece ();
	 apt->DefineTool(0.25, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0);
    apt->PutWorkpiecePlacement (raw_id, 0, 0, 0, 0, 0, -1, 1, 0, 0);
	apt->GeometryForToolNumber ("Iscar_2.stp", 1);
    apt->LoadTool (1);
     apt->SpindleSpeed (300);
    apt->Feedrate (30);

		apt->GoToXYZ("point0", 0,0,200);
		apt->GoToXYZ("point0", 0,0,200);

   String ^str;
	array<double>^ coor;
	for (int i=0;i<100;i++){
		//Console::WriteLine(i);
	coor=mt->getPos();
	if(coor!=nullptr){

		str= gcnew String(String::Format("point {0} ",i));
		Console::WriteLine(str);
        Console::WriteLine(coor[0]);

		apt->GoToXYZ(str, coor[0]*0.0393701, coor[1]*0.0393701, coor[2]*0.0393701);
	}
	}

    apt->SaveAsModules("hardmoldy_extended");
	Console::WriteLine("done");
	String ^readIn =Console::ReadLine();

}

void appendToFile(String^ file_name,String^ new_file_name,bool convert_to_inches){
	List<array<double>^> ^coor_List= coordinates(file_name,convert_to_inches);
    // Create a trivial STEP-NC file
	Console::WriteLine("Got Position Data From File");
    STEPNCLib::AptStepMaker ^ apt = gcnew STEPNCLib::AptStepMaker();

	////////////////////////
   STEPNCLib::Finder ^find = gcnew STEPNCLib::Finder();

	    //	    APT.Open238("new_hardmoldy.stpnc");
	    //	    Find.Open238("new_hardmoldy.stpnc");
	    apt->Open238("hardmoldy_ext.stpnc");
	    apt->Open238("hardmoldy_ext.stpnc");

	    long wp_id = find->GetMainWorkplan();
	    Console::WriteLine("Main Workplan name " + find->GetExecutableName(wp_id));

	    // add a new workplan at the end of the project
	    apt->NestWorkplanAfter("Workplan for MTConnect results", find->GetWorkplanExecutableCount(wp_id) + 1, wp_id);

	    // Starting first workingstep in new plan
	    apt->Workingstep("testing");

//////////////////////////
    //apt->PartNo("test part");
    //apt->DefineTool(0.25, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0);
	//apt->GeometryForToolNumber ("Iscar_2.stp", 1);

		//String^ boeingTool=find->GetToolNumberAsNumber()
		Console::WriteLine("is tool defined {0}",apt->IsToolDefined(1));
			apt->LoadTool(1);
    apt->SpindleSpeed (300);
    apt->Feedrate (30);
	String ^str;
	array<double>^ coor;
	for (int i=0;i<coor_List->Count;i++){
		coor=coor_List[i];

		str=String::Format("point {0} ",i+1);
		//Console::WriteLine(str);
		//Console::WriteLine(" {0} {1} {2}",coor[0],coor[1],coor[2]);

		apt->GoToXYZ(str, coor[0], coor[1], coor[2]);

	}

	apt->SaveAsModules(new_file_name);
	Console::WriteLine("done");

}

long long GetWorkplan(String^name,STEPNCLib::AptStepMaker ^ apt, STEPNCLib::Finder ^find){

long long wp_id = find->GetMainWorkplan();
String^ str=nullptr;

str=find->GetExecutableName (wp_id);
	if(str!=nullptr){
		Console::WriteLine("Workplan name: %s\n", str);
		List<long long>^nestedPlans =find->GetWorkplanExecutableAll (wp_id);
		for each (long long x in nestedPlans){
		str=find->GetExecutableName (x);
	if(str!=nullptr){
		Console::WriteLine("Workplan name: %s\n", str);}

	if(str==name){
		return x;
		}

		}

	}

}

List<array<double>^> ^ GetRapidToolPaths()
{

}

*/
int main(int argc, char * argv[])
{

	MtConnector ^ mt;
	mt=gcnew MtConnector();
	//mt->startPush("http://okuma-matata:5000/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@id=\"Mp1LPathPos\"]");
	//http://agent.mtconnect.org/VMC-3Axis/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@category=\"SAMPLE\"]"
	//http://okuma-matata:5000/sample?count=1000&interval=10

	//mt->getRequest("http://okuma-matata:5000/sample?count=1000&interval=10&path=//Path/DataItems/DataItem[@id=\"Mp1LPathPos\"]");
	//PullFromServer(mt);
    appendToFile("moldy_data_iteration_2.xml","moldy.stpnc",true);

	String ^readIn =Console::ReadLine();
	return 0;
}

<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "ifElementGenerator.h"
#include "generatorBase/generatorCustomizer.h"

using namespace generatorBase::simple;
using namespace qReal;

IfElementGenerator::IfElementGenerator(const qrRepo::RepoApi &repo
		, GeneratorCustomizer &customizer
		, const Id &id
		, bool elseIsEmpty
		, bool needInverting
		, bool fromSwitch
		, const QString &conditionFromSwitch
		, QObject *parent)
	: BindingGenerator(repo, customizer, id
			, elseIsEmpty ? "conditional/if.t" : "conditional/ifElse.t"
			, fromSwitch ? QList<Binding *>() << Binding::createStatic("@@CONDITION@@", conditionFromSwitch)
				: QList<Binding *>() << Binding::createConverting("@@CONDITION@@", "Condition"
					, customizer.factory()->boolPropertyConverter(id, "Condition", needInverting))
			, parent)
{
}
<commit_msg>Converting switch condition<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "ifElementGenerator.h"
#include "generatorBase/generatorCustomizer.h"

using namespace generatorBase::simple;
using namespace qReal;

IfElementGenerator::IfElementGenerator(const qrRepo::RepoApi &repo
		, GeneratorCustomizer &customizer
		, const Id &id
		, bool elseIsEmpty
		, bool needInverting
		, bool fromSwitch
		, const QString &conditionFromSwitch
		, QObject *parent)
	: BindingGenerator(repo, customizer, id
			, elseIsEmpty ? "conditional/if.t" : "conditional/ifElse.t"
			, fromSwitch ? QList<Binding *>() << Binding::createStaticConverting("@@CONDITION@@", conditionFromSwitch
									, customizer.factory()->boolPropertyConverter(id, "Condition", needInverting))
				: QList<Binding *>() << Binding::createConverting("@@CONDITION@@", "Condition"
					, customizer.factory()->boolPropertyConverter(id, "Condition", needInverting))
			, parent)
{
}
<|endoftext|>


<commit_before>// Copyright (c) 2008 Dr. Colin Hirsch
// Please see license.txt for license.

#ifndef COHI_PEGTL_HH
#error "Please #include only pegtl.hh (rather than individual pegtl_*.hh files)."
#endif

#ifndef COHI_PEGTL_PARSE_GENERIC_HH
#define COHI_PEGTL_PARSE_GENERIC_HH

namespace pegtl
{
   // The following function is the central wrapper used for parsing.

   template< typename TopRule, typename Input, typename Debug, typename ... States >
   void parse( Input & in, Debug & de, States && ... st )
   {
      // Unless Debug is broken, the return value is always true [because the Debug
      // must convert a local failure (return false) into a global failure (exception)
      // when Must == true, as is the case here].
      const bool b = de.template match< true, TopRule >( in, std::forward< States >( st ) ... );
      assert( b );
   }

   // The next functions add one convenience layer: they take care of instantiating
   // one (or more) of the debug classes supplied with the library, corresponding to
   // their respective names.

   // Parse with a dummy_debug (full speed, no diagnostics).

   template< typename TopRule, typename Input, typename ... States >
   void dummy_parse( Input & in, States && ... st )
   {
      dummy_debug de;
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a dummy_debug (slower, diagnostics on error).

   template< typename TopRule, typename Input, typename ... States >
   void basic_parse( Input & in, States && ... st )
   {
      basic_debug de( tag< TopRule >( 0 ) );
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a trace_debug (fixed overhead depending on the grammar,
   // diagnostics on error, plus optionally trace of all rule invocations).
   // The first bool argument called trace enables or disables rule tracing.

   template< typename TopRule, typename Input, typename ... States >
   void trace_parse( const bool trace, Input & in, States && ... st )
   {
      trace_debug de( tag< TopRule >( 0 ), trace );
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a dummy_debug and, when that fails, use a trace_debug, i.e.
   // try the fastest way, with neither diagnostics nor safety-nets first,
   // and fall-back to a more verbose version only when necessary. In case
   // of errors, the whole input is parsed two times. Note that the state
   // is not cleared in between the two parsing runs; it might be necessary
   // for the application to copy'n'paste this function with an appropriate
   // preparation of the state before starting the second run...!

   template< typename TopRule, typename Input, typename ... States >
   void smart_parse( const bool trace, Input & in, States && ... st )
   {
      try {
	 dummy_parse< TopRule >( in, std::forward< States >( st ) ... );
      }
      catch ( const parse_error & ) {
	 trace_parse< TopRule >( trace, in.rewind(), std::forward< States >( st ) ... );
      }
   }

} // pegtl

#endif
<commit_msg>Remove unused variable warning in pegtl.<commit_after>// Copyright (c) 2008 Dr. Colin Hirsch
// Please see license.txt for license.

#ifndef COHI_PEGTL_HH
#error "Please #include only pegtl.hh (rather than individual pegtl_*.hh files)."
#endif

#ifndef COHI_PEGTL_PARSE_GENERIC_HH
#define COHI_PEGTL_PARSE_GENERIC_HH

namespace pegtl
{
   // The following function is the central wrapper used for parsing.

   template< typename TopRule, typename Input, typename Debug, typename ... States >
   void parse( Input & in, Debug & de, States && ... st )
   {
      // Unless Debug is broken, the return value is always true [because the Debug
      // must convert a local failure (return false) into a global failure (exception)
      // when Must == true, as is the case here].
      const bool b = de.template match< true, TopRule >( in, std::forward< States >( st ) ... );
      assert( b );
      (void)b;
   }

   // The next functions add one convenience layer: they take care of instantiating
   // one (or more) of the debug classes supplied with the library, corresponding to
   // their respective names.

   // Parse with a dummy_debug (full speed, no diagnostics).

   template< typename TopRule, typename Input, typename ... States >
   void dummy_parse( Input & in, States && ... st )
   {
      dummy_debug de;
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a dummy_debug (slower, diagnostics on error).

   template< typename TopRule, typename Input, typename ... States >
   void basic_parse( Input & in, States && ... st )
   {
      basic_debug de( tag< TopRule >( 0 ) );
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a trace_debug (fixed overhead depending on the grammar,
   // diagnostics on error, plus optionally trace of all rule invocations).
   // The first bool argument called trace enables or disables rule tracing.

   template< typename TopRule, typename Input, typename ... States >
   void trace_parse( const bool trace, Input & in, States && ... st )
   {
      trace_debug de( tag< TopRule >( 0 ), trace );
      parse< TopRule >( in, de, std::forward< States >( st ) ... );
   }

   // Parse with a dummy_debug and, when that fails, use a trace_debug, i.e.
   // try the fastest way, with neither diagnostics nor safety-nets first,
   // and fall-back to a more verbose version only when necessary. In case
   // of errors, the whole input is parsed two times. Note that the state
   // is not cleared in between the two parsing runs; it might be necessary
   // for the application to copy'n'paste this function with an appropriate
   // preparation of the state before starting the second run...!

   template< typename TopRule, typename Input, typename ... States >
   void smart_parse( const bool trace, Input & in, States && ... st )
   {
      try {
	 dummy_parse< TopRule >( in, std::forward< States >( st ) ... );
      }
      catch ( const parse_error & ) {
	 trace_parse< TopRule >( trace, in.rewind(), std::forward< States >( st ) ... );
      }
   }

} // pegtl

#endif
<|endoftext|>