<commit_before>#include <iostream>
#include <cmath>

#include "timer.h"
#include "matrix.h"

#if defined(AMATRIX_COMPARE_WITH_EIGEN)
#include "Eigen/Dense"
#endif

#if defined(AMATRIX_COMPARE_WITH_UBLAS)
#include <boost/numeric/ublas/matrix.hpp>
#endif

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class ComparisonColumn {
    std::string mColumnName;

   protected:
    TMatrixType mA;
    TMatrixType mB;
    TMatrixType mResult;

    void initialize(TMatrixType& TheMatrix) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = j + 1;
    }

    void initializeInverse(TMatrixType& TheMatrix) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = 1.00 / (i + 1);
    }

    void initialize(TMatrixType& TheMatrix, double Value) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = Value;
    }

    void initialize_rotation(TMatrixType& TheMatrix, double AngleInRadian) {
        AMatrix::Matrix<double, 3, 3> block;

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                block(i, j) = 0.00;

        block(0, 0) = std::cos(AngleInRadian);
        block(0, 1) = -std::sin(AngleInRadian);
        block(1, 0) = std::sin(AngleInRadian);
        block(1, 1) = std::cos(AngleInRadian);
        block(2, 2) = 1.00;

        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++) {
                auto block_i = i % 3;
                auto block_j = j % 3;
                TheMatrix(i, j) = block(block_i, block_j);
            }
    }

   public:
    ComparisonColumn() = delete;

    ComparisonColumn(std::string ColumnName) : mColumnName(ColumnName) {
        initialize(mA, 0.00);
        initialize(mB, 0.00);
        initialize(mResult, 0.00);
    }
    std::string const& GetColumnName() { return mColumnName; }
    TMatrixType& GetResult() { return mResult; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                if (mResult(i, j) != Reference(i, j))
                    return false;

        return true;
    }

    void MeasureSumTime() {
        int repeat_number = 10000000;
        initialize(mA, 0.01);
        initialize(mB, 0.20);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = mA + mB;
            mB.noalias() = mResult;
        }
        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureMultTime() {
        int repeat_number = 10000000;
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = D * mA;
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureABAMultTime() {
        int repeat_number = 10000000;
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = mA * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

#if defined(AMATRIX_COMPARE_WITH_UBLAS)

#endif
};

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class UblasComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    using BaseType =
        ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>;

    UblasComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>(
              ColumnName) {}

    void MeasureSumTime() {
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA, 0.01);
        BaseType::initialize(BaseType::mB, 0.20);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            boost::numeric::ublas::noalias(BaseType::mResult) =
                BaseType::mA + BaseType::mB;
            boost::numeric::ublas::noalias(BaseType::mB) = BaseType::mResult;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureMultTime() {
        using namespace boost::numeric::ublas;
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            noalias(BaseType::mResult) = prod(D, BaseType::mA);
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureABAMultTime() {
        using namespace boost::numeric::ublas;
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            noalias(BaseType::mResult) =
                prod(BaseType::mA, TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class EmptyComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    EmptyComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>("") {}
    void MeasureSumTime() {}
    void MeasureABAMultTime() {}

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        return true;
    }
};

template <int NumberOfRows, int NumberOfColumns>
class BenchmarkMatrix {
    ComparisonColumn<AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mAMatrixColumn;
#if defined(AMATRIX_COMPARE_WITH_EIGEN)
    ComparisonColumn<Eigen::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#elif
    EmptyComparisonColumn<Eigen::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#endif
#if defined(AMATRIX_COMPARE_WITH_UBLAS)
    UblasComparisonColumn<boost::numeric::ublas::bounded_matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#elif
    EmptyComparisonColumn<boost::numeric::ublas::bounded_matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#endif
   public:
    BenchmarkMatrix()
        : mAMatrixColumn("AMatrix"),
          mEigenColumn("Eigen"),
          mUblasColumn("Ublas") {
        std::cout << "Benchmark[" << NumberOfRows << "," << NumberOfColumns
                  << "]";
        std::cout << "\t\t" << mAMatrixColumn.GetColumnName();
        std::cout << "\t\t" << mEigenColumn.GetColumnName();
        std::cout << "\t\t" << mUblasColumn.GetColumnName();
        std::cout << std::endl;
    }

    void Run() {
        std::cout << "C = A + B";
        mAMatrixColumn.MeasureSumTime();
        mEigenColumn.MeasureSumTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureSumTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B";
        mAMatrixColumn.MeasureMultTime();
        mEigenColumn.MeasureMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B * A";
        mAMatrixColumn.MeasureABAMultTime();
        mEigenColumn.MeasureABAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureABAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        // std::cout << "AMatrix : " << mAMatrixColumn.GetResult() << std::endl;
        // std::cout << "Eigen   : " << mEigenColumn.GetResult() << std::endl;

        std::cout << std::endl;
    }
};

int main() {
    BenchmarkMatrix<3, 3> benchmark_3_3;
    benchmark_3_3.Run();

    BenchmarkMatrix<4, 4> benchmark_4_4;
    benchmark_4_4.Run();

    BenchmarkMatrix<6, 6> benchmark_6_6;
    benchmark_6_6.Run();

    BenchmarkMatrix<12, 12> benchmark_12_12;
    benchmark_12_12.Run();

    BenchmarkMatrix<16, 16> benchmark_16_16;
    benchmark_16_16.Run();

    return 0;
}
<commit_msg>Fixing ifdefs and prints<commit_after>#include <iostream>
#include <cmath>

#include "timer.h"
#include "matrix.h"

#if defined(AMATRIX_COMPARE_WITH_EIGEN)
#include "Eigen/Dense"
#endif

#if defined(AMATRIX_COMPARE_WITH_UBLAS)
#include <boost/numeric/ublas/matrix.hpp>
#endif

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class ComparisonColumn {
    std::string mColumnName;

   protected:
    TMatrixType mA;
    TMatrixType mB;
    TMatrixType mResult;

    void initialize(TMatrixType& TheMatrix) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = j + 1;
    }

    void initializeInverse(TMatrixType& TheMatrix) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = 1.00 / (i + 1);
    }

    void initialize(TMatrixType& TheMatrix, double Value) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                TheMatrix(i, j) = Value;
    }

    void initialize_rotation(TMatrixType& TheMatrix, double AngleInRadian) {
        AMatrix::Matrix<double, 3, 3> block;

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                block(i, j) = 0.00;

        block(0, 0) = std::cos(AngleInRadian);
        block(0, 1) = -std::sin(AngleInRadian);
        block(1, 0) = std::sin(AngleInRadian);
        block(1, 1) = std::cos(AngleInRadian);
        block(2, 2) = 1.00;

        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++) {
                auto block_i = i % 3;
                auto block_j = j % 3;
                TheMatrix(i, j) = block(block_i, block_j);
            }
    }

   public:
    ComparisonColumn() = delete;

    ComparisonColumn(std::string ColumnName) : mColumnName(ColumnName) {
        initialize(mA, 0.00);
        initialize(mB, 0.00);
        initialize(mResult, 0.00);
    }
    std::string const& GetColumnName() { return mColumnName; }
    TMatrixType& GetResult() { return mResult; }

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        for (int i = 0; i < NumberOfRows; i++)
            for (int j = 0; j < NumberOfColumns; j++)
                if (mResult(i, j) != Reference(i, j))
                    return false;

        return true;
    }

    void MeasureSumTime() {
        int repeat_number = 10000000;
        initialize(mA, 0.01);
        initialize(mB, 0.20);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = mA + mB;
            mB.noalias() = mResult;
        }
        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureMultTime() {
        int repeat_number = 10000000;
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = D * mA;
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

    void MeasureABAMultTime() {
        int repeat_number = 10000000;
        initialize(mA);
        initializeInverse(mB);
        TMatrixType D;
        initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            mResult.noalias() = mA * TMatrixType(D * mA);
            D.noalias() = mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }

#if defined(AMATRIX_COMPARE_WITH_UBLAS)

#endif
};

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class UblasComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    using BaseType =
        ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>;

    UblasComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>(
              ColumnName) {}

    void MeasureSumTime() {
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA, 0.01);
        BaseType::initialize(BaseType::mB, 0.20);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            boost::numeric::ublas::noalias(BaseType::mResult) =
                BaseType::mA + BaseType::mB;
            boost::numeric::ublas::noalias(BaseType::mB) = BaseType::mResult;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureMultTime() {
        using namespace boost::numeric::ublas;
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            noalias(BaseType::mResult) = prod(D, BaseType::mA);
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
    void MeasureABAMultTime() {
        using namespace boost::numeric::ublas;
        int repeat_number = 10000000;
        BaseType::initialize(BaseType::mA);
        BaseType::initializeInverse(BaseType::mB);
        TMatrixType D;
        BaseType::initializeInverse(D);
        Timer timer;
        for (int i_repeat = 0; i_repeat < repeat_number; i_repeat++) {
            noalias(BaseType::mResult) =
                prod(BaseType::mA, TMatrixType(prod(D, BaseType::mA)));
            noalias(D) = BaseType::mB;
        }

        auto elapsed = timer.elapsed().count();
        std::cout << "\t\t" << elapsed;
    }
};

template <typename TMatrixType, int NumberOfRows, int NumberOfColumns>
class EmptyComparisonColumn
    : public ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns> {
   public:
    EmptyComparisonColumn(std::string ColumnName)
        : ComparisonColumn<TMatrixType, NumberOfRows, NumberOfColumns>("") {}
    void MeasureSumTime() {std::cout << "\t\t";}
    void MeasureMultTime() {std::cout << "\t\t";}
    void MeasureABAMultTime() {std::cout << "\t\t";}

    template <typename TMatrixType2>
    bool CheckResult(TMatrixType2 const& Reference) {
        return true;
    }
};

template <int NumberOfRows, int NumberOfColumns>
class BenchmarkMatrix {
    ComparisonColumn<AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mAMatrixColumn;
#if defined(AMATRIX_COMPARE_WITH_EIGEN)
    ComparisonColumn<Eigen::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#else
    EmptyComparisonColumn<AMatrix::Matrix<double, NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mEigenColumn;
#endif
#if defined(AMATRIX_COMPARE_WITH_UBLAS)
    UblasComparisonColumn<boost::numeric::ublas::bounded_matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#else
    EmptyComparisonColumn<AMatrix::Matrix<double,
                              NumberOfRows, NumberOfColumns>,
        NumberOfRows, NumberOfColumns>
        mUblasColumn;
#endif
   public:
    BenchmarkMatrix()
        : mAMatrixColumn("AMatrix"),
          mEigenColumn("Eigen"),
          mUblasColumn("Ublas") {
        std::cout << "Benchmark[" << NumberOfRows << "," << NumberOfColumns
                  << "]";
        std::cout << "\t\t" << mAMatrixColumn.GetColumnName();
        std::cout << "\t\t" << mEigenColumn.GetColumnName();
        std::cout << "\t\t" << mUblasColumn.GetColumnName();
        std::cout << std::endl;
    }

    void Run() {
        std::cout << "C = A + B";
        mAMatrixColumn.MeasureSumTime();
        mEigenColumn.MeasureSumTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureSumTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B";
        mAMatrixColumn.MeasureMultTime();
        mEigenColumn.MeasureMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        std::cout << "C = A * B * A";
        mAMatrixColumn.MeasureABAMultTime();
        mEigenColumn.MeasureABAMultTime();
        if (!mEigenColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        mUblasColumn.MeasureABAMultTime();
        if (!mUblasColumn.CheckResult(mAMatrixColumn.GetResult()))
            std::cout << "(Failed!)";
        std::cout << std::endl;

        // std::cout << "AMatrix : " << mAMatrixColumn.GetResult() << std::endl;
        // std::cout << "Eigen   : " << mEigenColumn.GetResult() << std::endl;

        std::cout << std::endl;
    }
};

int main() {
    BenchmarkMatrix<3, 3> benchmark_3_3;
    benchmark_3_3.Run();

    BenchmarkMatrix<4, 4> benchmark_4_4;
    benchmark_4_4.Run();

    BenchmarkMatrix<6, 6> benchmark_6_6;
    benchmark_6_6.Run();

    BenchmarkMatrix<12, 12> benchmark_12_12;
    benchmark_12_12.Run();

    BenchmarkMatrix<16, 16> benchmark_16_16;
    benchmark_16_16.Run();

    return 0;
}
<|endoftext|>


<commit_before>#include "AliITSPid.h"
#include "TMath.h"
#include <iostream.h>
ClassImp(AliITSPid)

//-----------------------------------------------------------
Float_t AliITSPid::qcorr(Float_t xc)
{
    assert(0);
  Float_t fcorr;
  fcorr=( 0.766 +0.9692*xc -1.267*xc*xc )*( 1.-TMath::Exp(-xc*64.75) );
  if(fcorr<=0.1)fcorr=0.1;
return qtot/fcorr;
}

//-----------------------------------------------------------
#include "vector.h"
#include <algorithm>
Float_t AliITSPid::qtrm(Int_t track)
{
    TVector q(*( this->GetVec(track)  ));
    Int_t nl=(Int_t)q(0);
    if(nl<1)return 0.;
    vector<float> vf(nl);
    switch(nl){
      case  1:q(6)=q(1); break;
      case  2:q(6)=(q(1)+q(2))/2.; break;
      default:
	for(Int_t i=0;i<nl;i++){vf[i]=q(i+1);}
        sort(vf.begin(),vf.end());
        q(6)= (vf[0]+vf[1])/2.;
        break;
    }
    for(Int_t i=0;i<nl;i++){q(i+1)=vf[i];} this->SetVec(track,q);
    return (q(6));
}
//-----------------------------------------------------------
inline
Int_t	AliITSPid::wpik(Int_t nc,Float_t q)
{
       return pion();

    Float_t qmpi,qmk,sigpi,sigk,dpi,dk,ppi,pk;
    qmpi =cut[nc][1];
    sigpi=cut[nc][2];
    qmk  =cut[nc][3];
    sigk =cut[nc][4];
    Float_t dqpi=(q-qmpi)/sigpi;
    Float_t dqk =(q-qmk )/sigk;
    if( dqk<-1. )return pion();
    dpi =fabs(dqpi);
    dk  =fabs(dqk);
    ppi =1.- TMath::Erf(dpi);  // +0.5;
    pk  =1.- TMath::Erf(dk);   // +0.5;
    Float_t rpik=ppi/(pk+0.0000001);
	cout<<"q,dqpi,dqk, wpik: ppi,pk,rpik="
	<<q<<" "<<dqpi<<" "<<dqk<<" "<<ppi<<" "<<pk<<" "<<rpik<<endl;
    if( rpik>=1000. ){return pion();}
    if( rpik>0.001 ){fWk=1./(rpik+1.); fWpi=1.-fWk;return 0;}
    return pion();
}
//-----------------------------------------------------------
inline
Int_t	AliITSPid::wpikp(Int_t nc,Float_t q)
{
       return pion();

   Float_t qmpi,qmk,qmp,sigpi,sigk,sigp,ppi,pka,ppr,rppi,rpka;

    qmpi =cut[nc][1];
    sigpi=cut[nc][2];
    qmk  =cut[nc][3];
    sigk =cut[nc][4];
    qmp  =cut[nc][5];
    sigp =cut[nc][6];

    ppi =TMath::Erf( TMath::Abs((q-qmpi)/sigpi) )+0.5;
    pka =TMath::Erf( TMath::Abs((q-qmk )/sigk)  )+0.5;
    ppr =TMath::Erf( TMath::Abs((q-qmp )/sigp)  )+0.5;

    rppi=ppr/ppi;
    rpka=ppr/pka;
    Float_t rp;
    if( rppi>rpka )  { rp=rpka; }
	         else{ rp=rppi; }
    if( rp>=1000. ){ return proton(); }
    if( rp>0.001  ){ fWp=rp/(rp+1.);return proton(); }

    return 0;
}
//-----------------------------------------------------------
Int_t	AliITSPid::GetPcode(TClonesArray* rps,Float_t pm)
{
    return 0;
}
//-----------------------------------------------------------
Int_t	AliITSPid::GetPcode(Float_t q,Float_t pm)
{
    fWpi=fWk=fWp=-1.;     fPcode=0;
//1)
    if ( pm<=cut[1][0] )
	{ return pion(); }
//2)
    if ( pm<=cut[2][0] )
	{ if( q<cut[2][2] ){ return pion(); } else { return  kaon();} }
//3)
    if ( pm<=cut[3][0] )
	if( q<cut[3][2])
		{ return pion(); }
	     else
		{ if ( q<=cut[3][5] ) {return kaon();} else {return proton();}}
//4)
    if ( pm<=cut[4][0] )
	if( q<cut[4][2] )
		{ return pion(); }
	    else
		{ if( q<=cut[4][4] ) {return kaon();} else {return proton(); }}
//5)
    if ( pm<=cut[5][0] )
	if ( q>cut[5][5] ) {return proton();} else {return wpik(5,q);};
//6)
    if ( pm<=cut[6][0] )
	if ( q>cut[6][5] ) {return proton();} else {return wpik(6,q);};
//7)
    if ( pm<=cut[7][0] )
	if ( q<=cut[7][5] ) {return fPcode;} else {return proton();};
//8)
    if ( pm<=cut[8][0] )
	if ( q<=cut[8][5] ) {return fPcode;} else {return proton();};
//9)
    if ( pm<=cut[9][0] )
	if ( q<=cut[9][5] ) {return fPcode;} else {return proton();};
//10)
    if( pm<=cut[10][0] ){ return wpikp(10,q); }
//11)
    if( pm<=cut[11][0] ){ return wpikp(11,q); }
//12)
    if( pm<=cut[12][0] ){ return wpikp(12,q); }

    return fPcode;
}
//-----------------------------------------------------------
void	AliITSPid::SetCut(Int_t n,Float_t pm,Float_t pilo,Float_t pihi,
			Float_t klo,Float_t khi,Float_t plo,Float_t phi)
{
    cut[n][0]=pm;
    cut[n][1]=pilo;
    cut[n][2]=pihi;
    cut[n][3]=klo;
    cut[n][4]=khi;
    cut[n][5]=plo;
    cut[n][6]=phi;
    return ;
}
//-----------------------------------------------------------
void AliITSPid::SetVec(Int_t ntrack,TVector info)
{
TClonesArray& arr=*trs;
    new( arr[ntrack] ) TVector(info);
}
//-----------------------------------------------------------
TVector* AliITSPid::GetVec(Int_t ntrack)
{
TClonesArray& arr=*trs;
    return (TVector*)arr[ntrack];
}
//-----------------------------------------------------------
void AliITSPid::SetEdep(Int_t track,Float_t Edep)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    Int_t j=(Int_t)xx(0); if(j>4)return;
    xx(++j)=Edep;xx(0)=j;
    TClonesArray &arr=*trs;
    new(arr[track])TVector(xx);
}
//-----------------------------------------------------------
void AliITSPid::SetPmom(Int_t track,Float_t Pmom)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    xx(10)=Pmom;
    TClonesArray &arr=*trs;
    new(arr[track])TVector(xx);
}
//-----------------------------------------------------------
void AliITSPid::SetPcod(Int_t track,Int_t partcode)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    if(xx(11)==0)
	{xx(11)=partcode; mxtrs++;
	TClonesArray &arr=*trs;
	new(arr[track])TVector(xx);
	}
}
//-----------------------------------------------------------
void AliITSPid::Print(Int_t track)
{cout<<mxtrs<<" tracks in AliITSPid obj."<<endl;
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector xx( *((TVector*)trs->At(track)) );
	 xx.Print();
	 }
    else
	{cout<<"No data for track "<<track<<endl;return;}
}
//-----------------------------------------------------------
void AliITSPid::Tab(void)
{
if(trs->GetEntries()==0){cout<<"No entries in TAB"<<endl;return;}
cout<<"------------------------------------------------------------------------"<<endl;
cout<<"Nq"<<"   q1  "<<"   q2  "<<"   q3  "<<"   q4  "<<"   q5   "<<
      " Qtrm    "    <<"  Wpi  "<<"  Wk   "<<"  Wp  "<<"Pmom  "<<endl;
cout<<"------------------------------------------------------------------------"<<endl;
for(Int_t i=0;i<trs->GetEntries();i++)
{
  TVector xx( *((TVector*)trs->At(i)) );
    if( xx.IsValid() && xx(0)>0 )
	{
	    TVector xx( *((TVector*)trs->At(i)) );
	    if(xx(0)>=2)
		{
//       1)Calculate Qtrm
		    xx(6)=(this->qtrm(i));

	    	 }else{
		     xx(6)=xx(1);
		 }
//	 2)Calculate Wpi,Wk,Wp
  	    this->GetPcode(xx(6),xx(10)/1000.);
	    xx(7)=GetWpi();
	    xx(8)=GetWk();
	    xx(9)=GetWp();
//       3)Print table
	    if(xx(0)>0){
		    cout<<xx(0)<<" ";
		    for(Int_t j=1;j<11;j++){
		        cout.width(7);cout.precision(5);cout<<xx(j);
		    }
		    cout<<endl;
		}
//	  4)Update data in TVector
	    TClonesArray &arr=*trs;
	    new(arr[i])TVector(xx);
	}
    else
      {/*cout<<"No data for track "<<i<<endl;*/}
}// End loop for tracks
}
void AliITSPid::Reset(void)
{
  for(Int_t i=0;i<trs->GetEntries();i++){
    TVector xx(0,11);
    TClonesArray &arr=*trs;
    new(arr[i])TVector(xx);
  }
}
//-----------------------------------------------------------
AliITSPid::AliITSPid(Int_t ntrack)
{
    trs = new TClonesArray("TVector",ntrack);
    TClonesArray &arr=*trs;
    for(Int_t i=0;i<ntrack;i++)new(arr[i])TVector(0,11);
    mxtrs=0;
const int inf=10;
//         Ncut Pmom   pilo  pihi    klo    khi     plo    phi
//       cut[j] [0]    [1]    [2]    [3]    [4]     [5]    [6]
//----------------------------------------------------------------
    SetCut(  1, 0.12 ,  0.  ,  0.  , inf  , inf   , inf  , inf  );
    SetCut(  2, 0.20 ,  0.  ,  6.0 , 6.0  , inf   , inf  , inf  );
    SetCut(  3, 0.30 ,  0.  ,  3.5 , 3.5  , 9.0   , 9.0  , inf  );
    SetCut(  4, 0.41 ,  0.  ,  1.9 , 1.9  , 4.0   , 4.0  , inf  );
//----------------------------------------------------------------
    SetCut(  5, 0.47 ,  1.  ,  0.12, 1.98 , 0.17  , 3.5  , inf  );
    SetCut(  6, 0.53 ,  1.  ,  0.12, 1.75 , 0.16  , 3.0  , inf  );
//----------------------------------------------------------------
    SetCut(  7, 0.59 ,  0.  ,  0.  , 1.18 , 0.125 , 2.7  , inf  );
    SetCut(  8, 0.65 ,  0.  ,  0.  , 1.18 , 0.125 , 2.5  , inf  );
    SetCut(  9, 0.73 ,  0.  ,  0.  , 0.   , 0.125 , 2.0  , inf  );
//----------------------------------------------------------------
    SetCut( 10, 0.83 ,  0.  ,  0.  , 1.25 , 0.13  , 2.14 , 0.20 );
    SetCut( 11, 0.93 ,  0.  ,  0.  , 1.18 , 0.125 , 1.88 , 0.18 );
    SetCut( 12, 1.03 ,  0.  ,  0.  , 1.13 , 0.12  , 1.68 , 0.155);
}
//-----------------------------------------------------------

<commit_msg>Inline declaration eliminiated to avoid problems with GCC on RH7.1+<commit_after>#include "AliITSPid.h"
#include "TMath.h"
#include <iostream.h>
ClassImp(AliITSPid)

//-----------------------------------------------------------
Float_t AliITSPid::qcorr(Float_t xc)
{
    assert(0);
  Float_t fcorr;
  fcorr=( 0.766 +0.9692*xc -1.267*xc*xc )*( 1.-TMath::Exp(-xc*64.75) );
  if(fcorr<=0.1)fcorr=0.1;
return qtot/fcorr;
}

//-----------------------------------------------------------
#include "vector.h"
#include <algorithm>
Float_t AliITSPid::qtrm(Int_t track)
{
    TVector q(*( this->GetVec(track)  ));
    Int_t nl=(Int_t)q(0);
    if(nl<1)return 0.;
    vector<float> vf(nl);
    switch(nl){
      case  1:q(6)=q(1); break;
      case  2:q(6)=(q(1)+q(2))/2.; break;
      default:
	for(Int_t i=0;i<nl;i++){vf[i]=q(i+1);}
        sort(vf.begin(),vf.end());
        q(6)= (vf[0]+vf[1])/2.;
        break;
    }
    for(Int_t i=0;i<nl;i++){q(i+1)=vf[i];} this->SetVec(track,q);
    return (q(6));
}
//-----------------------------------------------------------
Int_t	AliITSPid::wpik(Int_t nc,Float_t q)
{
       return pion();

    Float_t qmpi,qmk,sigpi,sigk,dpi,dk,ppi,pk;
    qmpi =cut[nc][1];
    sigpi=cut[nc][2];
    qmk  =cut[nc][3];
    sigk =cut[nc][4];
    Float_t dqpi=(q-qmpi)/sigpi;
    Float_t dqk =(q-qmk )/sigk;
    if( dqk<-1. )return pion();
    dpi =fabs(dqpi);
    dk  =fabs(dqk);
    ppi =1.- TMath::Erf(dpi);  // +0.5;
    pk  =1.- TMath::Erf(dk);   // +0.5;
    Float_t rpik=ppi/(pk+0.0000001);
	cout<<"q,dqpi,dqk, wpik: ppi,pk,rpik="
	<<q<<" "<<dqpi<<" "<<dqk<<" "<<ppi<<" "<<pk<<" "<<rpik<<endl;
    if( rpik>=1000. ){return pion();}
    if( rpik>0.001 ){fWk=1./(rpik+1.); fWpi=1.-fWk;return 0;}
    return pion();
}
//-----------------------------------------------------------
Int_t	AliITSPid::wpikp(Int_t nc,Float_t q)
{
       return pion();

   Float_t qmpi,qmk,qmp,sigpi,sigk,sigp,ppi,pka,ppr,rppi,rpka;

    qmpi =cut[nc][1];
    sigpi=cut[nc][2];
    qmk  =cut[nc][3];
    sigk =cut[nc][4];
    qmp  =cut[nc][5];
    sigp =cut[nc][6];

    ppi =TMath::Erf( TMath::Abs((q-qmpi)/sigpi) )+0.5;
    pka =TMath::Erf( TMath::Abs((q-qmk )/sigk)  )+0.5;
    ppr =TMath::Erf( TMath::Abs((q-qmp )/sigp)  )+0.5;

    rppi=ppr/ppi;
    rpka=ppr/pka;
    Float_t rp;
    if( rppi>rpka )  { rp=rpka; }
	         else{ rp=rppi; }
    if( rp>=1000. ){ return proton(); }
    if( rp>0.001  ){ fWp=rp/(rp+1.);return proton(); }

    return 0;
}
//-----------------------------------------------------------
Int_t	AliITSPid::GetPcode(TClonesArray* rps,Float_t pm)
{
    return 0;
}
//-----------------------------------------------------------
Int_t	AliITSPid::GetPcode(Float_t q,Float_t pm)
{
    fWpi=fWk=fWp=-1.;     fPcode=0;
//1)
    if ( pm<=cut[1][0] )
	{ return pion(); }
//2)
    if ( pm<=cut[2][0] )
	{ if( q<cut[2][2] ){ return pion(); } else { return  kaon();} }
//3)
    if ( pm<=cut[3][0] )
	if( q<cut[3][2])
		{ return pion(); }
	     else
		{ if ( q<=cut[3][5] ) {return kaon();} else {return proton();}}
//4)
    if ( pm<=cut[4][0] )
	if( q<cut[4][2] )
		{ return pion(); }
	    else
		{ if( q<=cut[4][4] ) {return kaon();} else {return proton(); }}
//5)
    if ( pm<=cut[5][0] )
	if ( q>cut[5][5] ) {return proton();} else {return wpik(5,q);};
//6)
    if ( pm<=cut[6][0] )
	if ( q>cut[6][5] ) {return proton();} else {return wpik(6,q);};
//7)
    if ( pm<=cut[7][0] )
	if ( q<=cut[7][5] ) {return fPcode;} else {return proton();};
//8)
    if ( pm<=cut[8][0] )
	if ( q<=cut[8][5] ) {return fPcode;} else {return proton();};
//9)
    if ( pm<=cut[9][0] )
	if ( q<=cut[9][5] ) {return fPcode;} else {return proton();};
//10)
    if( pm<=cut[10][0] ){ return wpikp(10,q); }
//11)
    if( pm<=cut[11][0] ){ return wpikp(11,q); }
//12)
    if( pm<=cut[12][0] ){ return wpikp(12,q); }

    return fPcode;
}
//-----------------------------------------------------------
void	AliITSPid::SetCut(Int_t n,Float_t pm,Float_t pilo,Float_t pihi,
			Float_t klo,Float_t khi,Float_t plo,Float_t phi)
{
    cut[n][0]=pm;
    cut[n][1]=pilo;
    cut[n][2]=pihi;
    cut[n][3]=klo;
    cut[n][4]=khi;
    cut[n][5]=plo;
    cut[n][6]=phi;
    return ;
}
//-----------------------------------------------------------
void AliITSPid::SetVec(Int_t ntrack,TVector info)
{
TClonesArray& arr=*trs;
    new( arr[ntrack] ) TVector(info);
}
//-----------------------------------------------------------
TVector* AliITSPid::GetVec(Int_t ntrack)
{
TClonesArray& arr=*trs;
    return (TVector*)arr[ntrack];
}
//-----------------------------------------------------------
void AliITSPid::SetEdep(Int_t track,Float_t Edep)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    Int_t j=(Int_t)xx(0); if(j>4)return;
    xx(++j)=Edep;xx(0)=j;
    TClonesArray &arr=*trs;
    new(arr[track])TVector(xx);
}
//-----------------------------------------------------------
void AliITSPid::SetPmom(Int_t track,Float_t Pmom)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    xx(10)=Pmom;
    TClonesArray &arr=*trs;
    new(arr[track])TVector(xx);
}
//-----------------------------------------------------------
void AliITSPid::SetPcod(Int_t track,Int_t partcode)
{
    TVector xx(0,11);
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector yy( *((TVector*)trs->At(track)) );xx=yy; }
    if(xx(11)==0)
	{xx(11)=partcode; mxtrs++;
	TClonesArray &arr=*trs;
	new(arr[track])TVector(xx);
	}
}
//-----------------------------------------------------------
void AliITSPid::Print(Int_t track)
{cout<<mxtrs<<" tracks in AliITSPid obj."<<endl;
    if( ((TVector*)trs->At(track))->IsValid() )
	{TVector xx( *((TVector*)trs->At(track)) );
	 xx.Print();
	 }
    else
	{cout<<"No data for track "<<track<<endl;return;}
}
//-----------------------------------------------------------
void AliITSPid::Tab(void)
{
if(trs->GetEntries()==0){cout<<"No entries in TAB"<<endl;return;}
cout<<"------------------------------------------------------------------------"<<endl;
cout<<"Nq"<<"   q1  "<<"   q2  "<<"   q3  "<<"   q4  "<<"   q5   "<<
      " Qtrm    "    <<"  Wpi  "<<"  Wk   "<<"  Wp  "<<"Pmom  "<<endl;
cout<<"------------------------------------------------------------------------"<<endl;
for(Int_t i=0;i<trs->GetEntries();i++)
{
  TVector xx( *((TVector*)trs->At(i)) );
    if( xx.IsValid() && xx(0)>0 )
	{
	    TVector xx( *((TVector*)trs->At(i)) );
	    if(xx(0)>=2)
		{
//       1)Calculate Qtrm
		    xx(6)=(this->qtrm(i));

	    	 }else{
		     xx(6)=xx(1);
		 }
//	 2)Calculate Wpi,Wk,Wp
  	    this->GetPcode(xx(6),xx(10)/1000.);
	    xx(7)=GetWpi();
	    xx(8)=GetWk();
	    xx(9)=GetWp();
//       3)Print table
	    if(xx(0)>0){
		    cout<<xx(0)<<" ";
		    for(Int_t j=1;j<11;j++){
		        cout.width(7);cout.precision(5);cout<<xx(j);
		    }
		    cout<<endl;
		}
//	  4)Update data in TVector
	    TClonesArray &arr=*trs;
	    new(arr[i])TVector(xx);
	}
    else
      {/*cout<<"No data for track "<<i<<endl;*/}
}// End loop for tracks
}
void AliITSPid::Reset(void)
{
  for(Int_t i=0;i<trs->GetEntries();i++){
    TVector xx(0,11);
    TClonesArray &arr=*trs;
    new(arr[i])TVector(xx);
  }
}
//-----------------------------------------------------------
AliITSPid::AliITSPid(Int_t ntrack)
{
    trs = new TClonesArray("TVector",ntrack);
    TClonesArray &arr=*trs;
    for(Int_t i=0;i<ntrack;i++)new(arr[i])TVector(0,11);
    mxtrs=0;
const int inf=10;
//         Ncut Pmom   pilo  pihi    klo    khi     plo    phi
//       cut[j] [0]    [1]    [2]    [3]    [4]     [5]    [6]
//----------------------------------------------------------------
    SetCut(  1, 0.12 ,  0.  ,  0.  , inf  , inf   , inf  , inf  );
    SetCut(  2, 0.20 ,  0.  ,  6.0 , 6.0  , inf   , inf  , inf  );
    SetCut(  3, 0.30 ,  0.  ,  3.5 , 3.5  , 9.0   , 9.0  , inf  );
    SetCut(  4, 0.41 ,  0.  ,  1.9 , 1.9  , 4.0   , 4.0  , inf  );
//----------------------------------------------------------------
    SetCut(  5, 0.47 ,  1.  ,  0.12, 1.98 , 0.17  , 3.5  , inf  );
    SetCut(  6, 0.53 ,  1.  ,  0.12, 1.75 , 0.16  , 3.0  , inf  );
//----------------------------------------------------------------
    SetCut(  7, 0.59 ,  0.  ,  0.  , 1.18 , 0.125 , 2.7  , inf  );
    SetCut(  8, 0.65 ,  0.  ,  0.  , 1.18 , 0.125 , 2.5  , inf  );
    SetCut(  9, 0.73 ,  0.  ,  0.  , 0.   , 0.125 , 2.0  , inf  );
//----------------------------------------------------------------
    SetCut( 10, 0.83 ,  0.  ,  0.  , 1.25 , 0.13  , 2.14 , 0.20 );
    SetCut( 11, 0.93 ,  0.  ,  0.  , 1.18 , 0.125 , 1.88 , 0.18 );
    SetCut( 12, 1.03 ,  0.  ,  0.  , 1.13 , 0.12  , 1.68 , 0.155);
}
//-----------------------------------------------------------

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008-2010, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/TypedStateComponent.h"

#include "IECoreMaya/DisplayStyle.h"

using namespace IECoreMaya;

struct DisplayStyle::Data
{
	IECoreGL::StatePtr wireframeState;
	IECoreGL::StatePtr shadedState;
	IECoreGL::StatePtr pointsState;
	IECoreGL::StatePtr boundsState;
};

DisplayStyle::DisplayStyle()
{
	m_data = new Data;
	m_data->wireframeState = new IECoreGL::State( true );
	m_data->shadedState = new IECoreGL::State( true );
	m_data->pointsState = new IECoreGL::State( true );
	m_data->boundsState = new IECoreGL::State( true );

	m_data->wireframeState->add( new IECoreGL::PrimitiveSolid( false ) );
	m_data->wireframeState->add( new IECoreGL::PrimitiveWireframe( true ) );

	m_data->pointsState->add( new IECoreGL::PrimitiveSolid( false ) );
	m_data->pointsState->add( new IECoreGL::PrimitivePoints( true ) );
	m_data->pointsState->add( new IECoreGL::PrimitivePointWidth( 2.0f ) );

	m_data->boundsState->add( new IECoreGL::PrimitiveSolid( false ) );
	m_data->boundsState->add( new IECoreGL::PrimitiveBound( true ) );
}

DisplayStyle::~DisplayStyle()
{
	delete m_data;
}

IECoreGL::ConstStatePtr DisplayStyle::baseState( M3dView::DisplayStyle style, bool transferCurrentColor )
{
	switch( style )
	{

		case M3dView::kBoundingBox :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->boundsState->add( new IECoreGL::BoundColorStateComponent( wc ) );
			}
			return m_data->boundsState;

		case M3dView::kFlatShaded :
		case M3dView::kGouraudShaded :
			return m_data->shadedState;

		case M3dView::kWireFrame :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->wireframeState->add( new IECoreGL::WireframeColorStateComponent( wc ) );
			}
			return m_data->wireframeState;

		case M3dView::kPoints :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->pointsState->add( new IECoreGL::PointColorStateComponent( wc ) );
			}
			return m_data->pointsState;

		default :
			return m_data->shadedState;

	}
}
<commit_msg>Updating for latest changes on IECoreGL headers.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008-2010, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/TypedStateComponent.h"
#include "IECoreGL/Primitive.h"

#include "IECoreMaya/DisplayStyle.h"

using namespace IECoreMaya;

struct DisplayStyle::Data
{
	IECoreGL::StatePtr wireframeState;
	IECoreGL::StatePtr shadedState;
	IECoreGL::StatePtr pointsState;
	IECoreGL::StatePtr boundsState;
};

DisplayStyle::DisplayStyle()
{
	m_data = new Data;
	m_data->wireframeState = new IECoreGL::State( true );
	m_data->shadedState = new IECoreGL::State( true );
	m_data->pointsState = new IECoreGL::State( true );
	m_data->boundsState = new IECoreGL::State( true );

	m_data->wireframeState->add( new IECoreGL::Primitive::DrawSolid( false ) );
	m_data->wireframeState->add( new IECoreGL::Primitive::DrawWireframe( true ) );

	m_data->pointsState->add( new IECoreGL::Primitive::DrawSolid( false ) );
	m_data->pointsState->add( new IECoreGL::Primitive::DrawPoints( true ) );
	m_data->pointsState->add( new IECoreGL::Primitive::PointWidth( 2.0f ) );

	m_data->boundsState->add( new IECoreGL::Primitive::DrawSolid( false ) );
	m_data->boundsState->add( new IECoreGL::Primitive::DrawBound( true ) );
}

DisplayStyle::~DisplayStyle()
{
	delete m_data;
}

IECoreGL::ConstStatePtr DisplayStyle::baseState( M3dView::DisplayStyle style, bool transferCurrentColor )
{
	switch( style )
	{

		case M3dView::kBoundingBox :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->boundsState->add( new IECoreGL::BoundColorStateComponent( wc ) );
			}
			return m_data->boundsState;

		case M3dView::kFlatShaded :
		case M3dView::kGouraudShaded :
			return m_data->shadedState;

		case M3dView::kWireFrame :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->wireframeState->add( new IECoreGL::WireframeColorStateComponent( wc ) );
			}
			return m_data->wireframeState;

		case M3dView::kPoints :
			if( transferCurrentColor )
			{
				Imath::Color4f wc; glGetFloatv( GL_CURRENT_COLOR, wc.getValue() );
				m_data->pointsState->add( new IECoreGL::PointColorStateComponent( wc ) );
			}
			return m_data->pointsState;

		default :
			return m_data->shadedState;

	}
}
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// 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 <cmath>
#include <limits>
#include <memory>
#include <vector>
#include <unordered_map>

#include "gtest/gtest.h"

#include "BitFunnel/BitFunnelTypes.h"
#include "BitFunnel/Configuration/IFileSystem.h"
#include "BitFunnel/Configuration/Factories.h"
#include "BitFunnel/Index/IIngestor.h"
#include "BitFunnel/Index/IShard.h"
#include "BitFunnel/Index/ISimpleIndex.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Mocks/Factories.h"
#include "BitFunnel/Term.h"
#include "DocumentFrequencyTable.h"
#include "Primes.h"

namespace BitFunnel
{
    static const Term::StreamId c_streamId = 0;

    class SyntheticIndex
    {
    public:
        SyntheticIndex(unsigned documentCount, ShardId numShards)
        {
            m_documentCount = documentCount;
            m_fileSystem = Factories::CreateFileSystem();
            m_index = Factories::CreatePrimeFactorsIndex(*m_fileSystem,
                                                         m_documentCount,
                                                         c_streamId,
                                                         numShards);
        }

        IIngestor & GetIngestor() const
        {
            return m_index->GetIngestor();
        }

        void VerifyQuery(unsigned query)
        {
            auto actualMatches = Match(query);
            auto expectedMatches = Expected(query);

            ASSERT_EQ(actualMatches.size(), expectedMatches.size());
            for (unsigned i = 0; i < actualMatches.size(); ++i)
            {
                    EXPECT_EQ(actualMatches[i], expectedMatches[i]);
            }
        }

    private:

        bool ExpectedMatch(DocId id, unsigned query)
        {
            if (query == 0)
            {
                // Query 0 has no terms so it matches all documents.
                return true;
            }
            else if (id == 0)
            {
                // Document 0 has no terms so it never matches
                // a non-zero query.
                return false;
            }
            else
            {
                // Document and query each have at least one term.
                // Check for matches.
                for (size_t i = 0; query != 0; query >>= 1, ++i)
                {
                    if ((query & 1) != 0)
                    {
                        if (id % Primes::c_primesBelow10000[i] != 0)
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
        }

        std::vector<DocId> Expected(unsigned query)
        {
            std::vector<DocId> results;
            for (DocId i = 0; i < m_documentCount; ++i)
            {
                if (ExpectedMatch(i, query))
                {
                    results.push_back(i);
                }
            }
            return results;
        }

        // Start with an accumulator that matches all documents. Then
        // intersect rows as appropriate. This implies that the "0" query
        // matches all rows. Note that this only handles up to 64 bits, so
        // queries larger than 64 are bogus.
        std::vector<DocId> Match(unsigned query)
        {
            // Load accumulator with 0xFFFFFFFFFFFFFFFF which matches
            // all documents. Then intersect with rows of the query.
            uint64_t accumulator = std::numeric_limits<uint64_t>::max();
            std::vector<DocId> results;

            for (size_t i = 0; query != 0; query >>= 1, ++i)
            {
                if (query & 0x1)
                {
                    char const* text = Primes::c_primesBelow10000Text[i].c_str();

                    Term term(Term::ComputeRawHash(text), c_streamId, 0);
                    RowIdSequence rows(term, m_index->GetTermTable0());
                    for (auto row : rows)
                    {
                        IShard & shard = m_index->GetIngestor().GetShard(0);
                        auto rowOffset = shard.GetRowOffset(row);
                        auto sliceBuffers = shard.GetSliceBuffers();
                        auto base = static_cast<char*>(sliceBuffers[0]);
                        auto ptr = base + rowOffset;
                        accumulator &= *reinterpret_cast<uint64_t*>(ptr);
                    }
                }
            }

            for (unsigned i = 0; accumulator != 0; ++i, accumulator >>= 1)
            {
                if (accumulator & 1)
                {
                    results.push_back(i);
                }
            }
            return results;
        }

        DocId m_documentCount;
        std::unique_ptr<IFileSystem> m_fileSystem;
        std::unique_ptr<ISimpleIndex> m_index;
    };

    // Generate fake documents where each document contains term i which
    // is a prime number iff the docId is divisible by the prime number.
    // Then verify using a fake matcher that talks to the row table to get
    // the appropriate address for the row.
    TEST(Ingestor, Basic)
    {
        const int c_documentCount = 64;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_documentCount, c_numShards);

        for (unsigned i = 0; i < c_documentCount + 1; i++)
        {
            index.VerifyQuery(i);
        }
    }

    std::unordered_map<size_t, size_t>
    CreateDocCountHistogram(DocumentFrequencyTable const & table,
                            unsigned docCount)
    {
        std::unordered_map<size_t, size_t> histogram;
        for (size_t i = 0; i < table.size(); ++i)
        {
            auto entry = table[i];
            ++histogram[static_cast<size_t>(std::round(entry.GetFrequency() * docCount))];
        }
        return histogram;
    }

    // Test DocumentFrequencyTable with 3 documents (0, 1, 2). This uses a
    // PrimeFactorIndex, which means that a document contains the term if the
    // term divides the document. This means that the only term we expect is
    // term "2" in docId 2.
    //
    // table.size() == 1u because there's only one term, "2", in any document.
    //
    // docFreqHistogram[1] == 1u because there's exactly 1 term that appears in
    // 1 document.
    TEST(Ingestor, DocFrequency2)
    {
        const int c_maxDocId = 2;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_maxDocId, c_numShards);
        std::stringstream stream;
        index.GetIngestor().GetShard(0).TemporaryWriteDocumentFrequencyTable(stream, nullptr);

        std::cout << stream.str() << std::endl;

        DocumentFrequencyTable table(stream);

        EXPECT_EQ(table.size(), 1u);
        std::unordered_map<size_t, size_t> docFreqHistogram = CreateDocCountHistogram(table, c_maxDocId);
        EXPECT_EQ(docFreqHistogram[1], 1u);
    }

    // Test DocumentFrequencyTable with 64 documents (0, 1, 2, ..., 63). This
    // uses a PrimeFactorIndex, which means that a document contains the term
    // iff the term divides the document.
    //
    // table.size() == 18u because there are 18 primes <= 63.
    //
    // docFreqHistogram[31] == 1u because there's exactly 1 term that appears in
    // 31 documents: the term "2" appears in documents 2, 4, 6, 8, ..., 62.
    //
    // docFreqHistogram[1] == 7u because there are 7 terms that appear in
    // exactly 1 document: 37, 41, 43, 47, 53, 59, 61, i.e., all primes between
    // 32 and 63 (inclusive).
    TEST(Ingestor, DocFrequency63)
    {
        const int c_maxDocId = 63;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_maxDocId, c_numShards);
        std::stringstream stream;
        index.GetIngestor().GetShard(0).TemporaryWriteDocumentFrequencyTable(stream, nullptr);

        std::cout << stream.str() << std::endl;

        DocumentFrequencyTable table(stream);

        EXPECT_EQ(table.size(), 18u);
        std::unordered_map<size_t, size_t> docFreqHistogram = CreateDocCountHistogram(table, c_maxDocId);

        EXPECT_EQ(docFreqHistogram[21], 1u);
        EXPECT_EQ(docFreqHistogram[31], 1u);
    }
}
<commit_msg>Run multi-shard test.<commit_after>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// 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 <cmath>
#include <limits>
#include <memory>
#include <vector>
#include <unordered_map>

#include "gtest/gtest.h"

#include "BitFunnel/BitFunnelTypes.h"
#include "BitFunnel/Configuration/IFileSystem.h"
#include "BitFunnel/Configuration/Factories.h"
#include "BitFunnel/Index/IIngestor.h"
#include "BitFunnel/Index/IShard.h"
#include "BitFunnel/Index/ISimpleIndex.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Mocks/Factories.h"
#include "BitFunnel/Term.h"
#include "DocumentFrequencyTable.h"
#include "Primes.h"

namespace BitFunnel
{
    static const Term::StreamId c_streamId = 0;

    class SyntheticIndex
    {
    public:
        SyntheticIndex(unsigned documentCount, ShardId numShards)
        {
            m_documentCount = documentCount;
            m_fileSystem = Factories::CreateFileSystem();
            m_index = Factories::CreatePrimeFactorsIndex(*m_fileSystem,
                                                         m_documentCount,
                                                         c_streamId,
                                                         numShards);
        }

        IIngestor & GetIngestor() const
        {
            return m_index->GetIngestor();
        }

        void VerifyQuery(unsigned query)
        {
            auto actualMatches = Match(query);
            auto expectedMatches = Expected(query);

            ASSERT_EQ(actualMatches.size(), expectedMatches.size());
            for (unsigned i = 0; i < actualMatches.size(); ++i)
            {
                    EXPECT_EQ(actualMatches[i], expectedMatches[i]);
            }
        }

    private:

        bool ExpectedMatch(DocId id, unsigned query)
        {
            if (query == 0)
            {
                // Query 0 has no terms so it matches all documents.
                return true;
            }
            else if (id == 0)
            {
                // Document 0 has no terms so it never matches
                // a non-zero query.
                return false;
            }
            else
            {
                // Document and query each have at least one term.
                // Check for matches.
                for (size_t i = 0; query != 0; query >>= 1, ++i)
                {
                    if ((query & 1) != 0)
                    {
                        if (id % Primes::c_primesBelow10000[i] != 0)
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
        }

        std::vector<DocId> Expected(unsigned query)
        {
            std::vector<DocId> results;
            for (DocId i = 0; i < m_documentCount; ++i)
            {
                if (ExpectedMatch(i, query))
                {
                    results.push_back(i);
                }
            }
            return results;
        }

        // Start with an accumulator that matches all documents. Then
        // intersect rows as appropriate. This implies that the "0" query
        // matches all rows. Note that this only handles up to 64 bits, so
        // queries larger than 64 are bogus.
        std::vector<DocId> Match(unsigned query)
        {
            // Load accumulator with 0xFFFFFFFFFFFFFFFF which matches
            // all documents. Then intersect with rows of the query.
            uint64_t accumulator = std::numeric_limits<uint64_t>::max();
            std::vector<DocId> results;

            for (size_t i = 0; query != 0; query >>= 1, ++i)
            {
                if (query & 0x1)
                {
                    char const* text = Primes::c_primesBelow10000Text[i].c_str();

                    Term term(Term::ComputeRawHash(text), c_streamId, 0);
                    RowIdSequence rows(term, m_index->GetTermTable0());
                    for (auto row : rows)
                    {
                        IShard & shard = m_index->GetIngestor().GetShard(0);
                        auto rowOffset = shard.GetRowOffset(row);
                        auto sliceBuffers = shard.GetSliceBuffers();
                        auto base = static_cast<char*>(sliceBuffers[0]);
                        auto ptr = base + rowOffset;
                        accumulator &= *reinterpret_cast<uint64_t*>(ptr);
                    }
                }
            }

            for (unsigned i = 0; accumulator != 0; ++i, accumulator >>= 1)
            {
                if (accumulator & 1)
                {
                    results.push_back(i);
                }
            }
            return results;
        }

        DocId m_documentCount;
        std::unique_ptr<IFileSystem> m_fileSystem;
        std::unique_ptr<ISimpleIndex> m_index;
    };

    // Generate fake documents where each document contains term i which
    // is a prime number iff the docId is divisible by the prime number.
    // Then verify using a fake matcher that talks to the row table to get
    // the appropriate address for the row.
    TEST(Ingestor, Basic)
    {
        const int c_documentCount = 64;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_documentCount, c_numShards);

        for (unsigned i = 0; i < c_documentCount + 1; i++)
        {
            index.VerifyQuery(i);
        }
    }

    std::unordered_map<size_t, size_t>
    CreateDocCountHistogram(DocumentFrequencyTable const & table,
                            unsigned docCount)
    {
        std::unordered_map<size_t, size_t> histogram;
        for (size_t i = 0; i < table.size(); ++i)
        {
            auto entry = table[i];
            ++histogram[static_cast<size_t>(std::round(entry.GetFrequency() * docCount))];
        }
        return histogram;
    }

    // Test DocumentFrequencyTable with 3 documents (0, 1, 2). This uses a
    // PrimeFactorIndex, which means that a document contains the term if the
    // term divides the document. This means that the only term we expect is
    // term "2" in docId 2.
    //
    // table.size() == 1u because there's only one term, "2", in any document.
    //
    // docFreqHistogram[1] == 1u because there's exactly 1 term that appears in
    // 1 document.
    TEST(Ingestor, DocFrequency2)
    {
        const int c_maxDocId = 2;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_maxDocId, c_numShards);
        std::stringstream stream;
        index.GetIngestor().GetShard(0).TemporaryWriteDocumentFrequencyTable(stream, nullptr);

        std::cout << stream.str() << std::endl;

        DocumentFrequencyTable table(stream);

        EXPECT_EQ(table.size(), 1u);
        std::unordered_map<size_t, size_t> docFreqHistogram = CreateDocCountHistogram(table, c_maxDocId);
        EXPECT_EQ(docFreqHistogram[1], 1u);
    }

    // Test DocumentFrequencyTable with 64 documents (0, 1, 2, ..., 63). This
    // uses a PrimeFactorIndex, which means that a document contains the term
    // iff the term divides the document.
    //
    // table.size() == 18u because there are 18 primes <= 63.
    //
    // docFreqHistogram[31] == 1u because there's exactly 1 term that appears in
    // 31 documents: the term "2" appears in documents 2, 4, 6, 8, ..., 62.
    //
    // docFreqHistogram[1] == 7u because there are 7 terms that appear in
    // exactly 1 document: 37, 41, 43, 47, 53, 59, 61, i.e., all primes between
    // 32 and 63 (inclusive).
    TEST(Ingestor, DocFrequency63)
    {
        const int c_maxDocId = 63;
        const ShardId c_numShards = 1;
        SyntheticIndex index(c_maxDocId, c_numShards);
        std::stringstream stream;
        index.GetIngestor().GetShard(0).TemporaryWriteDocumentFrequencyTable(stream, nullptr);

        std::cout << stream.str() << std::endl;

        DocumentFrequencyTable table(stream);

        EXPECT_EQ(table.size(), 18u);
        std::unordered_map<size_t, size_t> docFreqHistogram = CreateDocCountHistogram(table, c_maxDocId);

        EXPECT_EQ(docFreqHistogram[21], 1u);
        EXPECT_EQ(docFreqHistogram[31], 1u);
    }

    // TODO: this test only passes because multi-shard support is so
    // non-existent that it's as if we only have one shard.
    TEST(Ingestor, BasicMultiShard)
    {
        const int c_documentCount = 64;
        const ShardId c_numShards = 2;
        SyntheticIndex index(c_documentCount, c_numShards);

        for (unsigned i = 0; i < c_documentCount + 1; i++)
        {
            index.VerifyQuery(i);
        }
    }

}
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "JoystickManager.h"
#include "QGCApplication.h"

#include <QQmlEngine>

#ifndef __mobile__
    #include "JoystickSDL.h"
    #define __sdljoystick__
#endif

#ifdef __android__
    #include "JoystickAndroid.h"
#endif

QGC_LOGGING_CATEGORY(JoystickManagerLog, "JoystickManagerLog")

const char * JoystickManager::_settingsGroup =              "JoystickManager";
const char * JoystickManager::_settingsKeyActiveJoystick =  "ActiveJoystick";

JoystickManager::JoystickManager(QGCApplication* app, QGCToolbox* toolbox)
    : QGCTool(app, toolbox)
    , _activeJoystick(NULL)
    , _multiVehicleManager(NULL)
{
}

JoystickManager::~JoystickManager() {
    QMap<QString, Joystick*>::iterator i;
    for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
        qDebug() << "Releasing joystick:" << i.key();
        delete i.value();
    }
    qDebug() << "Done";
}

void JoystickManager::setToolbox(QGCToolbox *toolbox)
{
    QGCTool::setToolbox(toolbox);

    _multiVehicleManager = _toolbox->multiVehicleManager();

    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}

void JoystickManager::init() {
#ifdef __sdljoystick__
    if (JoystickSDL::init()) {
        _setActiveJoystickFromSettings();
        connect(&_joystickCheckTimer, &QTimer::timeout, this, &JoystickManager::_updateAvailableJoysticks);
        _joystickCheckTimer.start(250);
    }
#elif defined(__android__)
    _setActiveJoystickFromSettings();
    //TODO: Investigate Android events for Joystick hot plugging & run _joystickCheckTimer if possible
#endif
}

void JoystickManager::_setActiveJoystickFromSettings(void)
{
    QMap<QString,Joystick*> newMap;

#ifdef __sdljoystick__
    // Get the latest joystick mapping
    newMap = JoystickSDL::discover(_multiVehicleManager);
#elif defined(__android__)
    newMap = JoystickAndroid::discover(_multiVehicleManager);
#endif

    if (_activeJoystick && !newMap.contains(_activeJoystick->name())) {
        qCDebug(JoystickManagerLog) << "Active joystick removed";
        setActiveJoystick(NULL);
    }

    // Check to see if our current mapping contains any joysticks that are not in the new mapping
    // If so, those joysticks have been unplugged, and need to be cleaned up
    QMap<QString, Joystick*>::iterator i;
    for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
        if (!newMap.contains(i.key())) {
            qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key();
            i.value()->stopPolling();
            i.value()->wait(1000);
            i.value()->deleteLater();
        }
    }

    _name2JoystickMap = newMap;
    emit availableJoysticksChanged();

    if (!_name2JoystickMap.count()) {
        setActiveJoystick(NULL);
        return;
    }

    QSettings settings;

    settings.beginGroup(_settingsGroup);
    QString name = settings.value(_settingsKeyActiveJoystick).toString();

    if (name.isEmpty()) {
        name = _name2JoystickMap.first()->name();
    }

    setActiveJoystick(_name2JoystickMap.value(name, _name2JoystickMap.first()));
    settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());
}

Joystick* JoystickManager::activeJoystick(void)
{
    return _activeJoystick;
}

void JoystickManager::setActiveJoystick(Joystick* joystick)
{
    QSettings settings;

    if (joystick != NULL && !_name2JoystickMap.contains(joystick->name())) {
        qCWarning(JoystickManagerLog) << "Set active not in map" << joystick->name();
        return;
    }

    if (_activeJoystick == joystick) {
        return;
    }

    if (_activeJoystick) {
        _activeJoystick->stopPolling();
    }

    _activeJoystick = joystick;

    if (_activeJoystick != NULL) {
        qCDebug(JoystickManagerLog) << "Set active:" << _activeJoystick->name();

        settings.beginGroup(_settingsGroup);
        settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());
    }

    emit activeJoystickChanged(_activeJoystick);
    emit activeJoystickNameChanged(_activeJoystick?_activeJoystick->name():"");
}

QVariantList JoystickManager::joysticks(void)
{
    QVariantList list;

    foreach (const QString &name, _name2JoystickMap.keys()) {
        list += QVariant::fromValue(_name2JoystickMap[name]);
    }

    return list;
}

QStringList JoystickManager::joystickNames(void)
{
    return _name2JoystickMap.keys();
}

QString JoystickManager::activeJoystickName(void)
{
    return _activeJoystick ? _activeJoystick->name() : QString();
}

void JoystickManager::setActiveJoystickName(const QString& name)
{
    if (!_name2JoystickMap.contains(name)) {
        qCWarning(JoystickManagerLog) << "Set active not in map" << name;
        return;
    }

    setActiveJoystick(_name2JoystickMap[name]);
}

/*
 * TODO: move this to the right place: JoystickSDL.cc and JoystickAndroid.cc respectively and call through Joystick.cc
 */
void JoystickManager::_updateAvailableJoysticks(void)
{
#ifdef __sdljoystick__
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch(event.type) {
        case SDL_QUIT:
            qCDebug(JoystickManagerLog) << "SDL ERROR:" << SDL_GetError();
            break;
        case SDL_JOYDEVICEADDED:
            qCDebug(JoystickManagerLog) << "Joystick added:" << event.jdevice.which;
            _setActiveJoystickFromSettings();
            break;
        case SDL_JOYDEVICEREMOVED:
            qCDebug(JoystickManagerLog) << "Joystick removed:" << event.jdevice.which;
            _setActiveJoystickFromSettings();
            break;
        default:
            break;
        }
    }
#elif defined(__android__)
    /*
     * TODO: Investigate Android events for Joystick hot plugging
     */
#endif
}
<commit_msg>Joystick: Change from foreach to c++11 for<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "JoystickManager.h"
#include "QGCApplication.h"

#include <QQmlEngine>

#ifndef __mobile__
    #include "JoystickSDL.h"
    #define __sdljoystick__
#endif

#ifdef __android__
    #include "JoystickAndroid.h"
#endif

QGC_LOGGING_CATEGORY(JoystickManagerLog, "JoystickManagerLog")

const char * JoystickManager::_settingsGroup =              "JoystickManager";
const char * JoystickManager::_settingsKeyActiveJoystick =  "ActiveJoystick";

JoystickManager::JoystickManager(QGCApplication* app, QGCToolbox* toolbox)
    : QGCTool(app, toolbox)
    , _activeJoystick(NULL)
    , _multiVehicleManager(NULL)
{
}

JoystickManager::~JoystickManager() {
    QMap<QString, Joystick*>::iterator i;
    for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
        qDebug() << "Releasing joystick:" << i.key();
        delete i.value();
    }
    qDebug() << "Done";
}

void JoystickManager::setToolbox(QGCToolbox *toolbox)
{
    QGCTool::setToolbox(toolbox);

    _multiVehicleManager = _toolbox->multiVehicleManager();

    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}

void JoystickManager::init() {
#ifdef __sdljoystick__
    if (JoystickSDL::init()) {
        _setActiveJoystickFromSettings();
        connect(&_joystickCheckTimer, &QTimer::timeout, this, &JoystickManager::_updateAvailableJoysticks);
        _joystickCheckTimer.start(250);
    }
#elif defined(__android__)
    _setActiveJoystickFromSettings();
    //TODO: Investigate Android events for Joystick hot plugging & run _joystickCheckTimer if possible
#endif
}

void JoystickManager::_setActiveJoystickFromSettings(void)
{
    QMap<QString,Joystick*> newMap;

#ifdef __sdljoystick__
    // Get the latest joystick mapping
    newMap = JoystickSDL::discover(_multiVehicleManager);
#elif defined(__android__)
    newMap = JoystickAndroid::discover(_multiVehicleManager);
#endif

    if (_activeJoystick && !newMap.contains(_activeJoystick->name())) {
        qCDebug(JoystickManagerLog) << "Active joystick removed";
        setActiveJoystick(NULL);
    }

    // Check to see if our current mapping contains any joysticks that are not in the new mapping
    // If so, those joysticks have been unplugged, and need to be cleaned up
    QMap<QString, Joystick*>::iterator i;
    for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
        if (!newMap.contains(i.key())) {
            qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key();
            i.value()->stopPolling();
            i.value()->wait(1000);
            i.value()->deleteLater();
        }
    }

    _name2JoystickMap = newMap;
    emit availableJoysticksChanged();

    if (!_name2JoystickMap.count()) {
        setActiveJoystick(NULL);
        return;
    }

    QSettings settings;

    settings.beginGroup(_settingsGroup);
    QString name = settings.value(_settingsKeyActiveJoystick).toString();

    if (name.isEmpty()) {
        name = _name2JoystickMap.first()->name();
    }

    setActiveJoystick(_name2JoystickMap.value(name, _name2JoystickMap.first()));
    settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());
}

Joystick* JoystickManager::activeJoystick(void)
{
    return _activeJoystick;
}

void JoystickManager::setActiveJoystick(Joystick* joystick)
{
    QSettings settings;

    if (joystick != NULL && !_name2JoystickMap.contains(joystick->name())) {
        qCWarning(JoystickManagerLog) << "Set active not in map" << joystick->name();
        return;
    }

    if (_activeJoystick == joystick) {
        return;
    }

    if (_activeJoystick) {
        _activeJoystick->stopPolling();
    }

    _activeJoystick = joystick;

    if (_activeJoystick != NULL) {
        qCDebug(JoystickManagerLog) << "Set active:" << _activeJoystick->name();

        settings.beginGroup(_settingsGroup);
        settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());
    }

    emit activeJoystickChanged(_activeJoystick);
    emit activeJoystickNameChanged(_activeJoystick?_activeJoystick->name():"");
}

QVariantList JoystickManager::joysticks(void)
{
    QVariantList list;

    for (const QString &name: _name2JoystickMap.keys()) {
        list += QVariant::fromValue(_name2JoystickMap[name]);
    }

    return list;
}

QStringList JoystickManager::joystickNames(void)
{
    return _name2JoystickMap.keys();
}

QString JoystickManager::activeJoystickName(void)
{
    return _activeJoystick ? _activeJoystick->name() : QString();
}

void JoystickManager::setActiveJoystickName(const QString& name)
{
    if (!_name2JoystickMap.contains(name)) {
        qCWarning(JoystickManagerLog) << "Set active not in map" << name;
        return;
    }

    setActiveJoystick(_name2JoystickMap[name]);
}

/*
 * TODO: move this to the right place: JoystickSDL.cc and JoystickAndroid.cc respectively and call through Joystick.cc
 */
void JoystickManager::_updateAvailableJoysticks(void)
{
#ifdef __sdljoystick__
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch(event.type) {
        case SDL_QUIT:
            qCDebug(JoystickManagerLog) << "SDL ERROR:" << SDL_GetError();
            break;
        case SDL_JOYDEVICEADDED:
            qCDebug(JoystickManagerLog) << "Joystick added:" << event.jdevice.which;
            _setActiveJoystickFromSettings();
            break;
        case SDL_JOYDEVICEREMOVED:
            qCDebug(JoystickManagerLog) << "Joystick removed:" << event.jdevice.which;
            _setActiveJoystickFromSettings();
            break;
        default:
            break;
        }
    }
#elif defined(__android__)
    /*
     * TODO: Investigate Android events for Joystick hot plugging
     */
#endif
}
<|endoftext|>


<commit_before>// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//

// Shader.cpp: Implements the Shader class and its  derived classes
// VertexShader and FragmentShader. Implements GL shader objects and related
// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.

#include "Shader.h"

#include "main.h"
#include "utilities.h"

#include <string>

namespace es2
{
bool Shader::compilerInitialized = false;

Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
    mSource = NULL;

	clear();

    mRefCount = 0;
    mDeleteStatus = false;
}

Shader::~Shader()
{
    delete[] mSource;
}

GLuint Shader::getName() const
{
    return mHandle;
}

void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
{
    delete[] mSource;
    int totalLength = 0;

    for(int i = 0; i < count; i++)
    {
        if(length && length[i] >= 0)
        {
            totalLength += length[i];
        }
        else
        {
            totalLength += (int)strlen(string[i]);
        }
    }

    mSource = new char[totalLength + 1];
    char *code = mSource;

    for(int i = 0; i < count; i++)
    {
        int stringLength;

        if(length && length[i] >= 0)
        {
            stringLength = length[i];
        }
        else
        {
            stringLength = (int)strlen(string[i]);
        }

        strncpy(code, string[i], stringLength);
        code += stringLength;
    }

    mSource[totalLength] = '\0';
}

int Shader::getInfoLogLength() const
{
    if(infoLog.empty())
    {
        return 0;
    }
    else
    {
       return infoLog.size() + 1;
    }
}

void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
{
    int index = 0;

	if(bufSize > 0)
	{
		if(!infoLog.empty())
		{
			index = std::min(bufSize - 1, (GLsizei)infoLog.size());
			memcpy(infoLogOut, infoLog.c_str(), index);
		}

        infoLogOut[index] = '\0';
    }

    if(length)
    {
        *length = index;
    }
}

int Shader::getSourceLength() const
{
    if(!mSource)
    {
        return 0;
    }
    else
    {
       return strlen(mSource) + 1;
    }
}

void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
{
    int index = 0;

	if(bufSize > 0)
	{
		if(mSource)
		{
			index = std::min(bufSize - 1, (int)strlen(mSource));
			memcpy(source, mSource, index);
		}

        source[index] = '\0';
    }

    if(length)
    {
        *length = index;
    }
}

TranslatorASM *Shader::createCompiler(GLenum shaderType)
{
	if(!compilerInitialized)
	{
		InitCompilerGlobals();
		compilerInitialized = true;
	}

	TranslatorASM *assembler = new TranslatorASM(this, shaderType);

	ShBuiltInResources resources;
	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
	resources.OES_standard_derivatives = 1;
	resources.OES_fragment_precision_high = 1;
	resources.MaxCallStackDepth = 16;
	assembler->Init(resources);

	return assembler;
}

void Shader::clear()
{
	infoLog.clear();

	varyings.clear();
	activeUniforms.clear();
	activeAttributes.clear();
}

void Shader::compile()
{
	clear();

	createShader();
	TranslatorASM *compiler = createCompiler(getType());

	// Ensure we don't pass a NULL source to the compiler
    char *source = "\0";
	if(mSource)
    {
        source = mSource;
    }

	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);

	if(false)
	{
		static int serial = 1;
		char buffer[256];
		sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
		FILE *file = fopen(buffer, "wt");
		fprintf(file, mSource);
		fclose(file);
		getShader()->print("shader-output-%d-%d.txt", getName(), serial);
		serial++;
	}

	if(!success)
	{
		deleteShader();

		infoLog = compiler->getInfoSink().info.c_str();
        TRACE("\n%s", infoLog.c_str());
	}

	delete compiler;
}

bool Shader::isCompiled()
{
    return getShader() != 0;
}

void Shader::addRef()
{
    mRefCount++;
}

void Shader::release()
{
    mRefCount--;

    if(mRefCount == 0 && mDeleteStatus)
    {
        mResourceManager->deleteShader(mHandle);
    }
}

unsigned int Shader::getRefCount() const
{
    return mRefCount;
}

bool Shader::isFlaggedForDeletion() const
{
    return mDeleteStatus;
}

void Shader::flagForDeletion()
{
    mDeleteStatus = true;
}

void Shader::releaseCompiler()
{
    FreeCompilerGlobals();
	compilerInitialized = false;
}

GLenum Shader::parseType(const std::string &type)
{
    if(type == "float")
    {
        return GL_FLOAT;
    }
    else if(type == "float2")
    {
        return GL_FLOAT_VEC2;
    }
    else if(type == "float3")
    {
        return GL_FLOAT_VEC3;
    }
    else if(type == "float4")
    {
        return GL_FLOAT_VEC4;
    }
    else if(type == "float2x2")
    {
        return GL_FLOAT_MAT2;
    }
    else if(type == "float3x3")
    {
        return GL_FLOAT_MAT3;
    }
    else if(type == "float4x4")
    {
        return GL_FLOAT_MAT4;
    }
    else UNREACHABLE();

    return GL_NONE;
}

// true if varying x has a higher priority in packing than y
bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
{
    if(x.type == y.type)
    {
        return x.size() > y.size();
    }

    switch (x.type)
    {
      case GL_FLOAT_MAT4: return true;
      case GL_FLOAT_MAT2:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return true;
          case GL_FLOAT_VEC4: return true;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC4:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return true;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_MAT3:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC3:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return false;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC2:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return false;
          case GL_FLOAT_VEC3: return false;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT: return false;
      default: UNREACHABLE();
    }

    return false;
}

VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	vertexShader = 0;
}

VertexShader::~VertexShader()
{
	delete vertexShader;
}

GLenum VertexShader::getType()
{
    return GL_VERTEX_SHADER;
}

int VertexShader::getSemanticIndex(const std::string &attributeName)
{
    if(!attributeName.empty())
    {
		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
        {
            if(attribute->name == attributeName)
            {
				return attribute->registerIndex;
            }
        }
    }

    return -1;
}

sw::Shader *VertexShader::getShader() const
{
	return vertexShader;
}

sw::VertexShader *VertexShader::getVertexShader() const
{
	return vertexShader;
}

void VertexShader::createShader()
{
	delete vertexShader;
	vertexShader = new sw::VertexShader();
}

void VertexShader::deleteShader()
{
	delete vertexShader;
	vertexShader = nullptr;
}

FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	pixelShader = 0;
}

FragmentShader::~FragmentShader()
{
	delete pixelShader;
}

GLenum FragmentShader::getType()
{
    return GL_FRAGMENT_SHADER;
}

sw::Shader *FragmentShader::getShader() const
{
	return pixelShader;
}

sw::PixelShader *FragmentShader::getPixelShader() const
{
	return pixelShader;
}

void FragmentShader::createShader()
{
	delete pixelShader;
	pixelShader = new sw::PixelShader();
}

void FragmentShader::deleteShader()
{
	delete pixelShader;
	pixelShader = nullptr;
}

}
<commit_msg>Reject GLSL ES 3.00 shaders for OpenGL ES 2.0 contexts.<commit_after>// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//

// Shader.cpp: Implements the Shader class and its  derived classes
// VertexShader and FragmentShader. Implements GL shader objects and related
// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.

#include "Shader.h"

#include "main.h"
#include "utilities.h"

#include <string>

namespace es2
{
bool Shader::compilerInitialized = false;

Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
    mSource = NULL;

	clear();

    mRefCount = 0;
    mDeleteStatus = false;
}

Shader::~Shader()
{
    delete[] mSource;
}

GLuint Shader::getName() const
{
    return mHandle;
}

void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
{
    delete[] mSource;
    int totalLength = 0;

    for(int i = 0; i < count; i++)
    {
        if(length && length[i] >= 0)
        {
            totalLength += length[i];
        }
        else
        {
            totalLength += (int)strlen(string[i]);
        }
    }

    mSource = new char[totalLength + 1];
    char *code = mSource;

    for(int i = 0; i < count; i++)
    {
        int stringLength;

        if(length && length[i] >= 0)
        {
            stringLength = length[i];
        }
        else
        {
            stringLength = (int)strlen(string[i]);
        }

        strncpy(code, string[i], stringLength);
        code += stringLength;
    }

    mSource[totalLength] = '\0';
}

int Shader::getInfoLogLength() const
{
    if(infoLog.empty())
    {
        return 0;
    }
    else
    {
       return infoLog.size() + 1;
    }
}

void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
{
    int index = 0;

	if(bufSize > 0)
	{
		if(!infoLog.empty())
		{
			index = std::min(bufSize - 1, (GLsizei)infoLog.size());
			memcpy(infoLogOut, infoLog.c_str(), index);
		}

        infoLogOut[index] = '\0';
    }

    if(length)
    {
        *length = index;
    }
}

int Shader::getSourceLength() const
{
    if(!mSource)
    {
        return 0;
    }
    else
    {
       return strlen(mSource) + 1;
    }
}

void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
{
    int index = 0;

	if(bufSize > 0)
	{
		if(mSource)
		{
			index = std::min(bufSize - 1, (int)strlen(mSource));
			memcpy(source, mSource, index);
		}

        source[index] = '\0';
    }

    if(length)
    {
        *length = index;
    }
}

TranslatorASM *Shader::createCompiler(GLenum shaderType)
{
	if(!compilerInitialized)
	{
		InitCompilerGlobals();
		compilerInitialized = true;
	}

	TranslatorASM *assembler = new TranslatorASM(this, shaderType);

	ShBuiltInResources resources;
	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
	resources.OES_standard_derivatives = 1;
	resources.OES_fragment_precision_high = 1;
	resources.MaxCallStackDepth = 16;
	assembler->Init(resources);

	return assembler;
}

void Shader::clear()
{
	infoLog.clear();

	varyings.clear();
	activeUniforms.clear();
	activeAttributes.clear();
}

void Shader::compile()
{
	clear();

	createShader();
	TranslatorASM *compiler = createCompiler(getType());

	// Ensure we don't pass a NULL source to the compiler
    char *source = "\0";
	if(mSource)
    {
        source = mSource;
    }

	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);

	if(false)
	{
		static int serial = 1;
		char buffer[256];
		sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
		FILE *file = fopen(buffer, "wt");
		fprintf(file, mSource);
		fclose(file);
		getShader()->print("shader-output-%d-%d.txt", getName(), serial);
		serial++;
	}

	int shaderVersion = compiler->getShaderVersion();
	int clientVersion = es2::getContext()->getClientVersion();

	if(shaderVersion >= 300 && clientVersion < 3)
	{
		infoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
		success = false;
	}

	if(!success)
	{
		deleteShader();

		infoLog += compiler->getInfoSink().info.c_str();
        TRACE("\n%s", infoLog.c_str());
	}

	delete compiler;
}

bool Shader::isCompiled()
{
    return getShader() != 0;
}

void Shader::addRef()
{
    mRefCount++;
}

void Shader::release()
{
    mRefCount--;

    if(mRefCount == 0 && mDeleteStatus)
    {
        mResourceManager->deleteShader(mHandle);
    }
}

unsigned int Shader::getRefCount() const
{
    return mRefCount;
}

bool Shader::isFlaggedForDeletion() const
{
    return mDeleteStatus;
}

void Shader::flagForDeletion()
{
    mDeleteStatus = true;
}

void Shader::releaseCompiler()
{
    FreeCompilerGlobals();
	compilerInitialized = false;
}

GLenum Shader::parseType(const std::string &type)
{
    if(type == "float")
    {
        return GL_FLOAT;
    }
    else if(type == "float2")
    {
        return GL_FLOAT_VEC2;
    }
    else if(type == "float3")
    {
        return GL_FLOAT_VEC3;
    }
    else if(type == "float4")
    {
        return GL_FLOAT_VEC4;
    }
    else if(type == "float2x2")
    {
        return GL_FLOAT_MAT2;
    }
    else if(type == "float3x3")
    {
        return GL_FLOAT_MAT3;
    }
    else if(type == "float4x4")
    {
        return GL_FLOAT_MAT4;
    }
    else UNREACHABLE();

    return GL_NONE;
}

// true if varying x has a higher priority in packing than y
bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
{
    if(x.type == y.type)
    {
        return x.size() > y.size();
    }

    switch (x.type)
    {
      case GL_FLOAT_MAT4: return true;
      case GL_FLOAT_MAT2:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return true;
          case GL_FLOAT_VEC4: return true;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC4:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return true;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_MAT3:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return true;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC3:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return false;
          case GL_FLOAT_VEC3: return true;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT_VEC2:
        switch(y.type)
        {
          case GL_FLOAT_MAT4: return false;
          case GL_FLOAT_MAT2: return false;
          case GL_FLOAT_VEC4: return false;
          case GL_FLOAT_MAT3: return false;
          case GL_FLOAT_VEC3: return false;
          case GL_FLOAT_VEC2: return true;
          case GL_FLOAT:      return true;
          default: UNREACHABLE();
        }
        break;
      case GL_FLOAT: return false;
      default: UNREACHABLE();
    }

    return false;
}

VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	vertexShader = 0;
}

VertexShader::~VertexShader()
{
	delete vertexShader;
}

GLenum VertexShader::getType()
{
    return GL_VERTEX_SHADER;
}

int VertexShader::getSemanticIndex(const std::string &attributeName)
{
    if(!attributeName.empty())
    {
		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
        {
            if(attribute->name == attributeName)
            {
				return attribute->registerIndex;
            }
        }
    }

    return -1;
}

sw::Shader *VertexShader::getShader() const
{
	return vertexShader;
}

sw::VertexShader *VertexShader::getVertexShader() const
{
	return vertexShader;
}

void VertexShader::createShader()
{
	delete vertexShader;
	vertexShader = new sw::VertexShader();
}

void VertexShader::deleteShader()
{
	delete vertexShader;
	vertexShader = nullptr;
}

FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	pixelShader = 0;
}

FragmentShader::~FragmentShader()
{
	delete pixelShader;
}

GLenum FragmentShader::getType()
{
    return GL_FRAGMENT_SHADER;
}

sw::Shader *FragmentShader::getShader() const
{
	return pixelShader;
}

sw::PixelShader *FragmentShader::getPixelShader() const
{
	return pixelShader;
}

void FragmentShader::createShader()
{
	delete pixelShader;
	pixelShader = new sw::PixelShader();
}

void FragmentShader::deleteShader()
{
	delete pixelShader;
	pixelShader = nullptr;
}

}
<|endoftext|>


<commit_before>template<typename T> void ascii::Log::Print(T message, bool newLine)
{
    if (Enabled())
    {
        cout << message;
        if (newLine)
        {
            cout << endl;
        }
    }
}

template<typename T> void ascii::Log::Error(T errorMessage)
{
    Print("*========================ERROR========================*");
    Print(errorMessage);
    Print("*========================ERROR========================*");
}
<commit_msg>Log error messages get more space for clarity<commit_after>template<typename T> void ascii::Log::Print(T message, bool newLine)
{
    if (Enabled())
    {
        cout << message;
        if (newLine)
        {
            cout << endl;
        }
    }
}

template<typename T> void ascii::Log::Error(T errorMessage)
{
    Print("");
    Print("*========================ERROR========================*");
    Print(errorMessage);
    Print("*========================ERROR========================*");
    Print("");
}
<|endoftext|>