<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

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

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgrePredefinedControllers.h"

#include "OgreRoot.h"
#include "OgreMath.h"
#include "OgreLogManager.h"
#include "OgreTextureUnitState.h"

namespace Ogre
{
    //-----------------------------------------------------------------------
    // FrameTimeControllerValue
    //-----------------------------------------------------------------------
    FrameTimeControllerValue::FrameTimeControllerValue()
    {
        // Register self
        Root::getSingleton().addFrameListener(this);
        mFrameTime = 0;
		mTimeFactor = 1;
		mFrameDelay = 0;
        mElapsedTime = 0;

    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameStarted(const FrameEvent &evt)
    {
		if(mFrameDelay)
		{
			// Fixed frame time
			mFrameTime = mFrameDelay;
			mTimeFactor =  mFrameDelay / evt.timeSinceLastFrame;
		}
		else
		{
			// Save the time value after applying time factor
			mFrameTime = mTimeFactor * evt.timeSinceLastFrame;
		}
        // Accumulate the elapsed time
        mElapsedTime += mFrameTime;
        return true;
    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameEnded(const FrameEvent &evt)
    {
        return true;
    }
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getValue() const
    {
        return mFrameTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setValue(Real value)
    {
        // Do nothing - value is set from frame listener
    }
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getTimeFactor(void) const {
		return mTimeFactor;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setTimeFactor(Real tf) {
		if(tf >= 0)
		{
			mTimeFactor = tf;
			mFrameDelay = 0;
		}
	}
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getFrameDelay(void) const {
		return mFrameDelay;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setFrameDelay(Real fd) {
		mTimeFactor = 0;
		mFrameDelay = fd;
	}
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getElapsedTime(void) const
    {
        return mElapsedTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setElapsedTime(Real elapsedTime)
    {
        mElapsedTime = elapsedTime;
    }
    //-----------------------------------------------------------------------
    // TextureFrameControllerValue
    //-----------------------------------------------------------------------
    TextureFrameControllerValue::TextureFrameControllerValue(TextureUnitState* t)
    {
        mTextureLayer = t;
    }
    //-----------------------------------------------------------------------
    Real TextureFrameControllerValue::getValue(void) const
    {
        int numFrames = mTextureLayer->getNumFrames();
        return (mTextureLayer->getCurrentFrame() / numFrames);
    }
    //-----------------------------------------------------------------------
    void TextureFrameControllerValue::setValue(Real value)
    {
        int numFrames = mTextureLayer->getNumFrames();
        mTextureLayer->setCurrentFrame((int)(value * numFrames) % numFrames);
    }
    //-----------------------------------------------------------------------
    // TexCoordModifierControllerValue
    //-----------------------------------------------------------------------
    TexCoordModifierControllerValue::TexCoordModifierControllerValue(TextureUnitState* t,
        bool translateU, bool translateV, bool scaleU, bool scaleV, bool rotate )
    {
        mTextureLayer = t;
        mTransU = translateU;
        mTransV = translateV;
        mScaleU = scaleU;
        mScaleV = scaleV;
        mRotate = rotate;
    }
    //-----------------------------------------------------------------------
    Real TexCoordModifierControllerValue::getValue() const
    {
        const Matrix4& pMat = mTextureLayer->getTextureTransform();
        if (mTransU)
        {
            return pMat[0][3];
        }
        else if (mTransV)
        {
            return pMat[1][3];
        }
        else if (mScaleU)
        {
            return pMat[0][0];
        }
        else if (mScaleV)
        {
            return pMat[1][1];
        }
        // Shouldn't get here
        return 0;
    }
    //-----------------------------------------------------------------------
    void TexCoordModifierControllerValue::setValue(Real value)
    {
        if (mTransU)
        {
            mTextureLayer->setTextureUScroll(value);
        }
        if (mTransV)
        {
            mTextureLayer->setTextureVScroll(value);
        }
        if (mScaleU)
        {
            if (value >= 0)
            {
                // Add 1 to scale (+ve scales up)
                mTextureLayer->setTextureUScale(1 + value);
            }
            else
            {
                // (-ve scales down)
                mTextureLayer->setTextureUScale(1 / -value);
            }
        }
        if (mScaleV)
        {
            if (value >= 0)
            {
                // Add 1 to scale (+ve scales up)
                mTextureLayer->setTextureVScale(1 + value);
            }
            else
            {
                // (-ve scales down)
                mTextureLayer->setTextureVScale(1 / -value);
            }
        }
        if (mRotate)
        {
            mTextureLayer->setTextureRotate(Radian(value * Math::TWO_PI));
        }
    }
    //-----------------------------------------------------------------------
    //-----------------------------------------------------------------------
	FloatGpuParameterControllerValue::FloatGpuParameterControllerValue(
			GpuProgramParameters* params, size_t index) :
		mParams(params), mParamIndex(index)
	{
	}
    //-----------------------------------------------------------------------
	Real FloatGpuParameterControllerValue::getValue(void) const
	{
		// do nothing, reading from a set of params not supported
		return 0.0f;
	}
    //-----------------------------------------------------------------------
	void FloatGpuParameterControllerValue::setValue(Real val)
	{
		static Vector4 v4 = Vector4(0,0,0,0);
		v4.x = val;
		mParams->setConstant(mParamIndex, v4);
	}
	//-----------------------------------------------------------------------
	// PassthroughControllerFunction
	//-----------------------------------------------------------------------
	PassthroughControllerFunction::PassthroughControllerFunction(bool delta)
		: ControllerFunction<Real>(delta)
	{
	}
	//-----------------------------------------------------------------------
	Real PassthroughControllerFunction::calculate(Real source)
	{
		return getAdjustedInput(source);

	}
    //-----------------------------------------------------------------------
    // AnimationControllerFunction
    //-----------------------------------------------------------------------
    AnimationControllerFunction::AnimationControllerFunction(Real sequenceTime, Real timeOffset)
		: ControllerFunction<Real>(false)
    {
        mSeqTime = sequenceTime;
        mTime = timeOffset;
    }
    //-----------------------------------------------------------------------
    Real AnimationControllerFunction::calculate(Real source)
    {
        // Assume source is time since last update
        mTime += source;
        // Wrap
        while (mTime >= mSeqTime) mTime -= mSeqTime;
        while (mTime < 0) mTime += mSeqTime;

        // Return parametric
        return mTime / mSeqTime;
    }
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setTime(Real timeVal)
	{
		mTime = timeVal;
	}
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setSequenceTime(Real seqVal)
	{
		mSeqTime = seqVal;
	}
    //-----------------------------------------------------------------------
    // ScaleControllerFunction
    //-----------------------------------------------------------------------
    ScaleControllerFunction::ScaleControllerFunction(Real factor, bool delta) : ControllerFunction<Real>(delta)
    {
        mScale = factor;
    }
    //-----------------------------------------------------------------------
    Real ScaleControllerFunction::calculate(Real source)
    {
        return getAdjustedInput(source * mScale);

    }
    //-----------------------------------------------------------------------
    // WaveformControllerFunction
    //-----------------------------------------------------------------------
    WaveformControllerFunction::WaveformControllerFunction(WaveformType wType, Real base,  Real frequency, Real phase, Real amplitude, bool delta, Real dutyCycle)
        :ControllerFunction<Real>(delta)
    {
        mWaveType = wType;
        mBase = base;
        mFrequency = frequency;
        mPhase = phase;
        mAmplitude = amplitude;
        mDeltaCount = phase;
		mDutyCycle = dutyCycle;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::getAdjustedInput(Real input)
    {
        Real adjusted = ControllerFunction<Real>::getAdjustedInput(input);

        // If not delta, adjust by phase here
        // (delta inputs have it adjusted at initialisation)
        if (!mDeltaInput)
        {
            adjusted += mPhase;
        }

        return adjusted;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::calculate(Real source)
    {
        Real input = getAdjustedInput(source * mFrequency);
        Real output;
        // For simplicity, factor input down to {0,1)
        // Use looped subtract rather than divide / round
        while (input >= 1.0)
            input -= 1.0;
        while (input < 0.0)
            input += 1.0;

        // Calculate output in -1..1 range
        switch (mWaveType)
        {
        case WFT_SINE:
            output = Math::Sin(Radian(input * Math::TWO_PI));
            break;
        case WFT_TRIANGLE:
            if (input < 0.25)
                output = input * 4;
            else if (input >= 0.25 && input < 0.75)
                output = 1.0 - ((input - 0.25) * 4);
            else
                output = ((input - 0.75) * 4) - 1.0;

            break;
        case WFT_SQUARE:
            if (input <= 0.5)
                output = 1.0;
            else
                output = -1.0;
            break;
        case WFT_SAWTOOTH:
            output = (input * 2) - 1;
            break;
        case WFT_INVERSE_SAWTOOTH:
            output = -((input * 2) - 1);
            break;
		case WFT_PWM:
			if( input <= mDutyCycle )
				output = 1.0;
			else
				output = -1.0;
			break;
        }

        // Scale output into 0..1 range and then by base + amplitude
        return mBase + ((output + 1.0) * 0.5 * mAmplitude);

    }
}

<commit_msg>Fix wave_xform and scaling factors. 1.0 should be the base otherwise it's very unintuitive to try to figure out the correct parameters. Also all previous demos assumed that basis.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

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

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgrePredefinedControllers.h"

#include "OgreRoot.h"
#include "OgreMath.h"
#include "OgreLogManager.h"
#include "OgreTextureUnitState.h"

namespace Ogre
{
    //-----------------------------------------------------------------------
    // FrameTimeControllerValue
    //-----------------------------------------------------------------------
    FrameTimeControllerValue::FrameTimeControllerValue()
    {
        // Register self
        Root::getSingleton().addFrameListener(this);
        mFrameTime = 0;
		mTimeFactor = 1;
		mFrameDelay = 0;
        mElapsedTime = 0;

    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameStarted(const FrameEvent &evt)
    {
		if(mFrameDelay)
		{
			// Fixed frame time
			mFrameTime = mFrameDelay;
			mTimeFactor =  mFrameDelay / evt.timeSinceLastFrame;
		}
		else
		{
			// Save the time value after applying time factor
			mFrameTime = mTimeFactor * evt.timeSinceLastFrame;
		}
        // Accumulate the elapsed time
        mElapsedTime += mFrameTime;
        return true;
    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameEnded(const FrameEvent &evt)
    {
        return true;
    }
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getValue() const
    {
        return mFrameTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setValue(Real value)
    {
        // Do nothing - value is set from frame listener
    }
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getTimeFactor(void) const {
		return mTimeFactor;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setTimeFactor(Real tf) {
		if(tf >= 0)
		{
			mTimeFactor = tf;
			mFrameDelay = 0;
		}
	}
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getFrameDelay(void) const {
		return mFrameDelay;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setFrameDelay(Real fd) {
		mTimeFactor = 0;
		mFrameDelay = fd;
	}
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getElapsedTime(void) const
    {
        return mElapsedTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setElapsedTime(Real elapsedTime)
    {
        mElapsedTime = elapsedTime;
    }
    //-----------------------------------------------------------------------
    // TextureFrameControllerValue
    //-----------------------------------------------------------------------
    TextureFrameControllerValue::TextureFrameControllerValue(TextureUnitState* t)
    {
        mTextureLayer = t;
    }
    //-----------------------------------------------------------------------
    Real TextureFrameControllerValue::getValue(void) const
    {
        int numFrames = mTextureLayer->getNumFrames();
        return (mTextureLayer->getCurrentFrame() / numFrames);
    }
    //-----------------------------------------------------------------------
    void TextureFrameControllerValue::setValue(Real value)
    {
        int numFrames = mTextureLayer->getNumFrames();
        mTextureLayer->setCurrentFrame((int)(value * numFrames) % numFrames);
    }
    //-----------------------------------------------------------------------
    // TexCoordModifierControllerValue
    //-----------------------------------------------------------------------
    TexCoordModifierControllerValue::TexCoordModifierControllerValue(TextureUnitState* t,
        bool translateU, bool translateV, bool scaleU, bool scaleV, bool rotate )
    {
        mTextureLayer = t;
        mTransU = translateU;
        mTransV = translateV;
        mScaleU = scaleU;
        mScaleV = scaleV;
        mRotate = rotate;
    }
    //-----------------------------------------------------------------------
    Real TexCoordModifierControllerValue::getValue() const
    {
        const Matrix4& pMat = mTextureLayer->getTextureTransform();
        if (mTransU)
        {
            return pMat[0][3];
        }
        else if (mTransV)
        {
            return pMat[1][3];
        }
        else if (mScaleU)
        {
            return pMat[0][0];
        }
        else if (mScaleV)
        {
            return pMat[1][1];
        }
        // Shouldn't get here
        return 0;
    }
    //-----------------------------------------------------------------------
    void TexCoordModifierControllerValue::setValue(Real value)
    {
        if (mTransU)
        {
            mTextureLayer->setTextureUScroll(value);
        }
        if (mTransV)
        {
            mTextureLayer->setTextureVScroll(value);
        }
        if (mScaleU)
        {
            mTextureLayer->setTextureUScale(value);
        }
        if (mScaleV)
        {
            mTextureLayer->setTextureVScale(value);
        }
        if (mRotate)
        {
            mTextureLayer->setTextureRotate(Radian(value * Math::TWO_PI));
        }
    }
    //-----------------------------------------------------------------------
    //-----------------------------------------------------------------------
	FloatGpuParameterControllerValue::FloatGpuParameterControllerValue(
			GpuProgramParameters* params, size_t index) :
		mParams(params), mParamIndex(index)
	{
	}
    //-----------------------------------------------------------------------
	Real FloatGpuParameterControllerValue::getValue(void) const
	{
		// do nothing, reading from a set of params not supported
		return 0.0f;
	}
    //-----------------------------------------------------------------------
	void FloatGpuParameterControllerValue::setValue(Real val)
	{
		static Vector4 v4 = Vector4(0,0,0,0);
		v4.x = val;
		mParams->setConstant(mParamIndex, v4);
	}
	//-----------------------------------------------------------------------
	// PassthroughControllerFunction
	//-----------------------------------------------------------------------
	PassthroughControllerFunction::PassthroughControllerFunction(bool delta)
		: ControllerFunction<Real>(delta)
	{
	}
	//-----------------------------------------------------------------------
	Real PassthroughControllerFunction::calculate(Real source)
	{
		return getAdjustedInput(source);

	}
    //-----------------------------------------------------------------------
    // AnimationControllerFunction
    //-----------------------------------------------------------------------
    AnimationControllerFunction::AnimationControllerFunction(Real sequenceTime, Real timeOffset)
		: ControllerFunction<Real>(false)
    {
        mSeqTime = sequenceTime;
        mTime = timeOffset;
    }
    //-----------------------------------------------------------------------
    Real AnimationControllerFunction::calculate(Real source)
    {
        // Assume source is time since last update
        mTime += source;
        // Wrap
        while (mTime >= mSeqTime) mTime -= mSeqTime;
        while (mTime < 0) mTime += mSeqTime;

        // Return parametric
        return mTime / mSeqTime;
    }
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setTime(Real timeVal)
	{
		mTime = timeVal;
	}
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setSequenceTime(Real seqVal)
	{
		mSeqTime = seqVal;
	}
    //-----------------------------------------------------------------------
    // ScaleControllerFunction
    //-----------------------------------------------------------------------
    ScaleControllerFunction::ScaleControllerFunction(Real factor, bool delta) : ControllerFunction<Real>(delta)
    {
        mScale = factor;
    }
    //-----------------------------------------------------------------------
    Real ScaleControllerFunction::calculate(Real source)
    {
        return getAdjustedInput(source * mScale);

    }
    //-----------------------------------------------------------------------
    // WaveformControllerFunction
    //-----------------------------------------------------------------------
    WaveformControllerFunction::WaveformControllerFunction(WaveformType wType, Real base,  Real frequency, Real phase, Real amplitude, bool delta, Real dutyCycle)
        :ControllerFunction<Real>(delta)
    {
        mWaveType = wType;
        mBase = base;
        mFrequency = frequency;
        mPhase = phase;
        mAmplitude = amplitude;
        mDeltaCount = phase;
		mDutyCycle = dutyCycle;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::getAdjustedInput(Real input)
    {
        Real adjusted = ControllerFunction<Real>::getAdjustedInput(input);

        // If not delta, adjust by phase here
        // (delta inputs have it adjusted at initialisation)
        if (!mDeltaInput)
        {
            adjusted += mPhase;
        }

        return adjusted;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::calculate(Real source)
    {
        Real input = getAdjustedInput(source * mFrequency);
        Real output;
        // For simplicity, factor input down to {0,1)
        // Use looped subtract rather than divide / round
        while (input >= 1.0)
            input -= 1.0;
        while (input < 0.0)
            input += 1.0;

        // Calculate output in -1..1 range
        switch (mWaveType)
        {
        case WFT_SINE:
            output = Math::Sin(Radian(input * Math::TWO_PI));
            break;
        case WFT_TRIANGLE:
            if (input < 0.25)
                output = input * 4;
            else if (input >= 0.25 && input < 0.75)
                output = 1.0 - ((input - 0.25) * 4);
            else
                output = ((input - 0.75) * 4) - 1.0;

            break;
        case WFT_SQUARE:
            if (input <= 0.5)
                output = 1.0;
            else
                output = -1.0;
            break;
        case WFT_SAWTOOTH:
            output = (input * 2) - 1;
            break;
        case WFT_INVERSE_SAWTOOTH:
            output = -((input * 2) - 1);
            break;
		case WFT_PWM:
			if( input <= mDutyCycle )
				output = 1.0;
			else
				output = -1.0;
			break;
        }

        // Scale output into 0..1 range and then by base + amplitude
        return mBase + ((output + 1.0) * 0.5 * mAmplitude);

    }
}

<|endoftext|>


<commit_before>#ifndef OWPLAYERITEM_H
#define OWPLAYERITEM_H
#include <QStandardItem>
#include "Logics/Entities/OwPlayer.hpp"

class OwPlayerItem : public QStandardItem
{
public:
    static constexpr int OwPlayerType = QStandardItem::UserType + 1;
    static constexpr int OwPlayerIsFavoriteFlag = OwPlayerType + 1;

private:
    OwPlayer player;

public:
    using QStandardItem::QStandardItem;
    OwPlayerItem(const OwPlayer & player) : player(player) {}

    inline OwPlayer & getPlayer(void) { return this->player; }
    inline const OwPlayer & getPlayer(void) const { return this->player; }

    virtual int type(void) const final { return OwPlayerType; }
    virtual OwPlayerItem * clone(void) const final { return new OwPlayerItem(this->player); }
    virtual QVariant data(int role = OwPlayerIsFavoriteFlag) const final;
};

Q_DECLARE_METATYPE(OwPlayerItem*)
Q_DECLARE_METATYPE(const OwPlayerItem*)

#endif // OWPLAYERITEM_H
<commit_msg>refactor<commit_after>#ifndef OWPLAYERITEM_H
#define OWPLAYERITEM_H
#include <QStandardItem>
#include "Logics/Entities/OwPlayer.hpp"

class OwPlayerItem : public QStandardItem
{
public:
    enum Role
    {
        OwPlayerType = QStandardItem::UserType + 1,
        OwPlayerIsFavoriteFlag
    };

private:
    OwPlayer player;

public:
    using QStandardItem::QStandardItem;
    OwPlayerItem(const OwPlayer & player) : player(player) {}

    inline OwPlayer & getPlayer(void) { return this->player; }
    inline const OwPlayer & getPlayer(void) const { return this->player; }

    virtual int type(void) const final { return OwPlayerType; }
    virtual OwPlayerItem * clone(void) const final { return new OwPlayerItem(this->player); }
    virtual QVariant data(int role = OwPlayerIsFavoriteFlag) const final;
};

Q_DECLARE_METATYPE(OwPlayerItem*)
Q_DECLARE_METATYPE(const OwPlayerItem*)

#endif // OWPLAYERITEM_H
<|endoftext|>


<commit_before>// $Id$

AliEmcalEsdTpcTrackTask* AddTaskEmcalEsdTpcTrack(
  const char *name              = "TpcSpdVertexConstrainedTracks",
  const char *trackCuts         = "Hybrid_LHC11h"
)
{
  enum CutsType {
    kHybrid  = 0,
    kTpcOnly = 1
  };

  enum DataSet {
    kLHC10h  = 0,
    kLHC11a  = 1,
    kLHC11c  = 3,
    kLHC11d  = 3,
    kLHC11h  = 3
  };

  CutsType cutsType = kHybrid;
  DataSet  dataSet  = kLHC11h;

  TString cutsLabel("hybrid tracks");
  TString dataSetLabel("LHC11h");

  TString strTrackCuts(trackCuts);
  strTrackCuts.ToLower();

  if (strTrackCuts.Contains("hybrid")) {
    cutsType = kHybrid;
  }
  else if (strTrackCuts.Contains("tpconly")) {
    cutsType = kTpcOnly;
    cutsLabel = "TPC only constrained tracks";
  }
  else {
    ::Warning("AddTaskEmcalEsdTpcTrack", "Cuts type not recognized, will assume Hybrid");
  }

  if (strTrackCuts.Contains("lhc10h")) {
    dataSet = kLHC10h;
  }
  else if (strTrackCuts.Contains("lhc11a") || strTrackCuts.Contains("lhc12a15a")) {
    dataSet = kLHC11a;
    dataSetLabel = "LHC11a";
  }
  else if (strTrackCuts.Contains("lhc11c")) {
    dataSet = kLHC11c;
    dataSetLabel = "LHC11c";
  }
  else if (strTrackCuts.Contains("lhc11d")) {
    dataSet = kLHC11d;
    dataSetLabel = "LHC11d";
  }
  else if (strTrackCuts.Contains("lhc11h") || strTrackCuts.Contains("lhc12a15e"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC11h";
  }
  else if (strTrackCuts.Contains("lhc12g"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC12g";
  }
  else if (strTrackCuts.Contains("lhc13b"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC13b";
  }
  else if (strTrackCuts.Contains("lhc13c"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC13c";
  }
  else if (strTrackCuts.Contains("lhc12a15f"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC12a15f";
  }
  else {
    ::Warning("AddTaskEmcalEsdTpcTrack", "Dataset not recognized, will assume LHC11h");
  }

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskEmcalEsdTpcTrack", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  AliVEventHandler *evhand = mgr->GetInputEventHandler();
  if (!evhand) {
    ::Error("AddTaskEmcalEsdTpcTrack", "This task requires an input event handler");
    return NULL;
  }

  if (!evhand->InheritsFrom("AliESDInputHandler")) {
    ::Info("AddTaskEmcalEsdTpcTrack", "This task is only needed for ESD analysis. No task added.");
    return NULL;
  }

  //-------------------------------------------------------
  // Init the task and do settings
  //-------------------------------------------------------

  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/CreateTrackCutsPWGJE.C");
  Bool_t includeNoITS = kFALSE;
  AliEmcalEsdTpcTrackTask *eTask = new AliEmcalEsdTpcTrackTask(); // default is TPC only tracks constrained to the vertex

  if ((dataSet == kLHC11c && cutsType == kHybrid) ||
      (dataSet == kLHC11d && cutsType == kHybrid) ||
      (dataSet == kLHC11h && cutsType == kHybrid)) {
    /* hybrid track cuts*/
    AliESDtrackCuts *cutsp = CreateTrackCutsPWGJE(10001008);       //1000 adds SPD any requirement
    AliESDtrackCuts *hybsp = CreateTrackCutsPWGJE(10041008);       //1004 removes ITSrefit requirement from standard set
    hybsp->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
    eTask->SetTrackCuts(cutsp);
    eTask->SetHybridTrackCuts(hybsp);
  }
  else if ((dataSet == kLHC10h && cutsType == kHybrid) ||
           (dataSet == kLHC11a && cutsType == kHybrid)) {
    /* hybrid track cuts*/
    AliESDtrackCuts *cutsp = CreateTrackCutsPWGJE(10001006);       //1000 adds SPD any requirement
    AliESDtrackCuts *hybsp = CreateTrackCutsPWGJE(10041006);       //1004 removes ITSrefit requirement from standard set
    hybsp->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
    eTask->SetTrackCuts(cutsp);
    eTask->SetHybridTrackCuts(hybsp);
    includeNoITS = kTRUE;
  }

  eTask->SetTracksName(name);
  eTask->SetIncludeNoITS(includeNoITS);

  cout << " *** Track selector task configured to select " << cutsLabel  << " in dataset "<< dataSetLabel << " *** " << endl;

  //-------------------------------------------------------
  // Final settings, pass to manager and set the containers
  //-------------------------------------------------------
  mgr->AddTask(eTask);

  // Create containers for input/output
  AliAnalysisDataContainer *cinput1 = mgr->GetCommonInputContainer();
  mgr->ConnectInput(eTask, 0, cinput1);

  return eTask;
}
<commit_msg>from Mauro<commit_after>// $Id$

AliEmcalEsdTpcTrackTask* AddTaskEmcalEsdTpcTrack(
  const char *name              = "TpcSpdVertexConstrainedTracks",
  const char *trackCuts         = "Hybrid_LHC11h"
)
{
  enum CutsType {
    kHybrid  = 0,
    kTpcOnly = 1
  };

  enum DataSet {
    kLHC10h  = 0,
    kLHC11a  = 1,
    kLHC11c  = 3,
    kLHC11d  = 3,
    kLHC11h  = 3
  };

  CutsType cutsType = kHybrid;
  DataSet  dataSet  = kLHC11h;

  TString cutsLabel("hybrid tracks");
  TString dataSetLabel("LHC11h");

  TString strTrackCuts(trackCuts);
  strTrackCuts.ToLower();

  if (strTrackCuts.Contains("hybrid")) {
    cutsType = kHybrid;
  }
  else if (strTrackCuts.Contains("tpconly")) {
    cutsType = kTpcOnly;
    cutsLabel = "TPC only constrained tracks";
  }
  else {
    ::Warning("AddTaskEmcalEsdTpcTrack", "Cuts type not recognized, will assume Hybrid");
  }

  if (strTrackCuts.Contains("lhc10h")) {
    dataSet = kLHC10h;
  }
  else if (strTrackCuts.Contains("lhc11a") || strTrackCuts.Contains("lhc12a15a")) {
    dataSet = kLHC11a;
    dataSetLabel = "LHC11a";
  }
  else if (strTrackCuts.Contains("lhc11c")) {
    dataSet = kLHC11c;
    dataSetLabel = "LHC11c";
  }
  else if (strTrackCuts.Contains("lhc11d")) {
    dataSet = kLHC11d;
    dataSetLabel = "LHC11d";
  }
  else if (strTrackCuts.Contains("lhc11h") || strTrackCuts.Contains("lhc12a15e"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC11h";
  }
  else if (strTrackCuts.Contains("lhc12g"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC12g";
  }
  else if (strTrackCuts.Contains("lhc13b"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC13b";
  }
  else if (strTrackCuts.Contains("lhc13c"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC13c";
  }
  else if (strTrackCuts.Contains("lhc12a15f"))
  {
    dataSet = kLHC11h;
    dataSetLabel = "LHC12a15f";
  }
  else if (strTrackCuts.Contains("lhc12a15g"))
  {
    dataSet = kLHC11d;
    dataSetLabel = "LHC12a15g";
  }
  else if (strTrackCuts.Contains("lhc12f2a"))
  {
    dataSet = kLHC11d;
    dataSetLabel = "LHC12f2a";
  }
  else {
    ::Warning("AddTaskEmcalEsdTpcTrack", "Dataset not recognized, will assume LHC11h");
  }

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskEmcalEsdTpcTrack", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  AliVEventHandler *evhand = mgr->GetInputEventHandler();
  if (!evhand) {
    ::Error("AddTaskEmcalEsdTpcTrack", "This task requires an input event handler");
    return NULL;
  }

  if (!evhand->InheritsFrom("AliESDInputHandler")) {
    ::Info("AddTaskEmcalEsdTpcTrack", "This task is only needed for ESD analysis. No task added.");
    return NULL;
  }

  //-------------------------------------------------------
  // Init the task and do settings
  //-------------------------------------------------------

  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/CreateTrackCutsPWGJE.C");
  Bool_t includeNoITS = kFALSE;
  AliEmcalEsdTpcTrackTask *eTask = new AliEmcalEsdTpcTrackTask(); // default is TPC only tracks constrained to the vertex

  if ((dataSet == kLHC11c && cutsType == kHybrid) ||
      (dataSet == kLHC11d && cutsType == kHybrid) ||
      (dataSet == kLHC11h && cutsType == kHybrid)) {
    /* hybrid track cuts*/
    AliESDtrackCuts *cutsp = CreateTrackCutsPWGJE(10001008);       //1000 adds SPD any requirement
    AliESDtrackCuts *hybsp = CreateTrackCutsPWGJE(10041008);       //1004 removes ITSrefit requirement from standard set
    hybsp->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
    eTask->SetTrackCuts(cutsp);
    eTask->SetHybridTrackCuts(hybsp);
  }
  else if ((dataSet == kLHC10h && cutsType == kHybrid) ||
           (dataSet == kLHC11a && cutsType == kHybrid)) {
    /* hybrid track cuts*/
    AliESDtrackCuts *cutsp = CreateTrackCutsPWGJE(10001006);       //1000 adds SPD any requirement
    AliESDtrackCuts *hybsp = CreateTrackCutsPWGJE(10041006);       //1004 removes ITSrefit requirement from standard set
    hybsp->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
    eTask->SetTrackCuts(cutsp);
    eTask->SetHybridTrackCuts(hybsp);
    includeNoITS = kTRUE;
  }

  eTask->SetTracksName(name);
  eTask->SetIncludeNoITS(includeNoITS);

  cout << " *** Track selector task configured to select " << cutsLabel  << " in dataset "<< dataSetLabel << " *** " << endl;

  //-------------------------------------------------------
  // Final settings, pass to manager and set the containers
  //-------------------------------------------------------
  mgr->AddTask(eTask);

  // Create containers for input/output
  AliAnalysisDataContainer *cinput1 = mgr->GetCommonInputContainer();
  mgr->ConnectInput(eTask, 0, cinput1);

  return eTask;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include <unistd.h>
#include <string>
#include <thread>

#include "gtest/gtest.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/program_desc.h"
#include "paddle/fluid/operators/math/math_function.h"
#include "paddle/fluid/operators/math/selected_rows_functor.h"
#include "paddle/fluid/string/printf.h"

USE_NO_KERNEL_OP(send);
USE_NO_KERNEL_OP(listen_and_serv);
USE_OP(sum);

namespace f = paddle::framework;
namespace p = paddle::platform;
namespace m = paddle::operators::math;

// global for simplicity.
std::unique_ptr<f::OperatorBase> listen_and_serv_op;

void InitTensorsInScope(f::Scope &scope, p::CPUPlace &place) {
  p::CPUDeviceContext ctx(place);
  for (int i = 0; i < 2; ++i) {
    auto var_name = paddle::string::Sprintf("x%d", i);
    auto var = scope.Var(var_name);
    auto tensor = var->GetMutable<f::LoDTensor>();
    tensor->Resize({10, 10});
    float *expect = tensor->mutable_data<float>(place);
    for (int64_t i = 0; i < tensor->numel(); ++i) {
      expect[i] = static_cast<float>(i);
    }
  }

  auto out_var = scope.Var("Out");
  auto out_tensor = out_var->GetMutable<f::LoDTensor>();
  out_tensor->Resize({10, 10});
  out_tensor->mutable_data<float>(place);  // allocate
}

void InitSelectedRowsInScope(f::Scope &scope, p::CPUPlace &place) {
  p::CPUDeviceContext ctx(place);
  int64_t height = 10;
  int64_t row_numel = 10;
  m::SetConstant<p::CPUDeviceContext, float> set_one;
  // init x0
  std::vector<int64_t> rows0{0, 4, 7};
  auto x0_var = scope.Var("x0");
  auto x0 = x0_var->GetMutable<f::SelectedRows>();
  x0->set_rows(rows0);
  x0->set_height(height);
  auto x0_value = x0->mutable_value();
  x0_value->mutable_data<float>(
      f::make_ddim({static_cast<int64_t>(rows0.size()), row_numel}), place);
  set_one(ctx, x0_value, 1.0);

  // init x1
  std::vector<int64_t> rows1{2, 9};
  auto x1_var = scope.Var("x1");
  auto x1 = x1_var->GetMutable<f::SelectedRows>();
  x1->set_rows(rows1);
  x1->set_height(height);
  auto x1_value = x1->mutable_value();
  x1_value->mutable_data<float>(
      f::make_ddim({static_cast<int64_t>(rows1.size()), row_numel}), place);
  set_one(ctx, x1_value, 1.0);

  auto out_var = scope.Var("Out");
  auto out = out_var->GetMutable<f::SelectedRows>();
  auto out_value = out->mutable_value();
  out->set_height(height);
  out_value->mutable_data<float>(f::make_ddim({5, 10}), place);
}

void AddOp(const std::string &type, const f::VariableNameMap &inputs,
           const f::VariableNameMap &outputs, f::AttributeMap attrs,
           f::BlockDesc *block) {
  // insert output
  for (auto kv : outputs) {
    for (auto v : kv.second) {
      auto var = block->Var(v);
      var->SetDataType(f::proto::VarType::FP32);
    }
  }

  // insert op
  auto op = block->AppendOp();
  op->SetType(type);
  for (auto &kv : inputs) {
    op->SetInput(kv.first, kv.second);
  }
  for (auto &kv : outputs) {
    op->SetOutput(kv.first, kv.second);
  }
  op->SetAttrMap(attrs);
}

void StartServerNet(bool is_sparse) {
  f::Scope scope;
  p::CPUPlace place;
  if (is_sparse) {
    InitSelectedRowsInScope(scope, place);
  } else {
    InitTensorsInScope(scope, place);
  }

  // sub program run in listen_and_serv_op, for simple test we use sum
  f::ProgramDesc program;
  f::BlockDesc *optimize_block = program.MutableBlock(0);
  // X for server side tensors, RX for received tensers, must be of same shape.
  AddOp("sum", {{"X", {"x0", "x1"}}}, {{"Out", {"Out"}}}, {}, optimize_block);

  f::AttributeMap attrs;
  attrs.insert({"endpoint", std::string("127.0.0.1:6174")});
  attrs.insert({"Fanin", 1});
  attrs.insert({"ParamList", std::vector<std::string>({"Out"})});
  attrs.insert({"GradList", std::vector<std::string>({"x1"})});
  attrs.insert({"OptimizeBlock", optimize_block});
  listen_and_serv_op =
      f::OpRegistry::CreateOp("listen_and_serv", {{"X", {"x1"}}}, {}, attrs);
  listen_and_serv_op->Run(scope, place);
}

TEST(SendRecvOp, CPUDense) {
  std::thread server_thread(StartServerNet, false);
  sleep(5);  // wait server to start
  // local net
  f::Scope scope;
  p::CPUPlace place;
  InitTensorsInScope(scope, place);
  // create rpc client var
  scope.Var("RPC_CLIENT_VAR");

  f::AttributeMap attrs;
  attrs.insert({"endpoints", std::vector<std::string>({"127.0.0.1:6174"})});
  attrs.insert({"epmap", std::vector<std::string>({"127.0.0.1:6174"})});
  auto send_op = f::OpRegistry::CreateOp(
      "send", {{"X", {"x1"}}},
      {{"Out", {"Out"}}, {"RPCClient", {"RPC_CLIENT_VAR"}}}, attrs);
  send_op->Run(scope, place);

  auto in_var = scope.Var("x1");
  auto tensor = in_var->GetMutable<f::LoDTensor>();
  float *expected = tensor->data<float>();
  auto out_var = scope.Var("Out");
  auto target = out_var->GetMutable<f::LoDTensor>();
  // x1 * 2 == x0
  EXPECT_NE(target->memory_size(), size_t(0));
  float *actual = target->data<float>();
  for (int64_t i = 0; i < target->numel(); ++i) {
    EXPECT_EQ(expected[i] * 2, actual[i]);
  }
  listen_and_serv_op->Stop();
  server_thread.join();
  listen_and_serv_op.reset(nullptr);
}

TEST(SendRecvOp, CPUSparse) {
  std::thread server_thread(StartServerNet, true);
  sleep(3);  // wait server to start
  // local net
  f::Scope scope;
  p::CPUPlace place;
  p::CPUDeviceContext ctx(place);
  InitSelectedRowsInScope(scope, place);
  scope.Var("RPC_CLIENT_VAR");
  f::AttributeMap attrs;
  attrs.insert({"endpoints", std::vector<std::string>({"127.0.0.1:6174"})});
  attrs.insert({"epmap", std::vector<std::string>({"127.0.0.1:6174"})});
  auto send_op = f::OpRegistry::CreateOp(
      "send", {{"X", {"x1"}}},
      {{"Out", {"Out"}}, {"RPCClient", {"RPC_CLIENT_VAR"}}}, attrs);
  send_op->Run(scope, place);

  auto x0 = scope.Var("x0")->GetMutable<f::SelectedRows>();
  auto x1 = scope.Var("x1")->GetMutable<f::SelectedRows>();
  auto out = scope.Var("Out")->GetMutable<f::SelectedRows>();
  auto actual = out->mutable_value();

  std::unique_ptr<f::SelectedRows> expect{new f::SelectedRows()};
  auto expect_value = expect->mutable_value();
  expect_value->mutable_data<float>(f::make_ddim({5, 10}), place);

  m::SelectedRowsAdd<p::CPUDeviceContext, float> add_functor;
  add_functor(ctx, *x0, *x1, expect.get());

  EXPECT_EQ(actual->numel(), expect_value->numel());
  EXPECT_EQ(out->rows().size(), x0->rows().size() + x1->rows().size());

  for (int64_t i = 0; i < expect_value->numel(); ++i) {
    EXPECT_EQ(expect_value->mutable_data<float>(place)[i],
              actual->mutable_data<float>(place)[i]);
  }
  listen_and_serv_op->Stop();
  server_thread.join();
  listen_and_serv_op.reset();
}
<commit_msg>fix block num<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include <unistd.h>
#include <string>
#include <thread>

#include "gtest/gtest.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/program_desc.h"
#include "paddle/fluid/operators/math/math_function.h"
#include "paddle/fluid/operators/math/selected_rows_functor.h"
#include "paddle/fluid/string/printf.h"

USE_NO_KERNEL_OP(send);
USE_NO_KERNEL_OP(listen_and_serv);
USE_OP(sum);

namespace f = paddle::framework;
namespace p = paddle::platform;
namespace m = paddle::operators::math;

// global for simplicity.
std::unique_ptr<f::OperatorBase> listen_and_serv_op;

void InitTensorsInScope(f::Scope &scope, p::CPUPlace &place) {
  p::CPUDeviceContext ctx(place);
  for (int i = 0; i < 2; ++i) {
    auto var_name = paddle::string::Sprintf("x%d", i);
    auto var = scope.Var(var_name);
    auto tensor = var->GetMutable<f::LoDTensor>();
    tensor->Resize({10, 10});
    float *expect = tensor->mutable_data<float>(place);
    for (int64_t i = 0; i < tensor->numel(); ++i) {
      expect[i] = static_cast<float>(i);
    }
  }

  auto out_var = scope.Var("Out");
  auto out_tensor = out_var->GetMutable<f::LoDTensor>();
  out_tensor->Resize({10, 10});
  out_tensor->mutable_data<float>(place);  // allocate
}

void InitSelectedRowsInScope(f::Scope &scope, p::CPUPlace &place) {
  p::CPUDeviceContext ctx(place);
  int64_t height = 10;
  int64_t row_numel = 10;
  m::SetConstant<p::CPUDeviceContext, float> set_one;
  // init x0
  std::vector<int64_t> rows0{0, 4, 7};
  auto x0_var = scope.Var("x0");
  auto x0 = x0_var->GetMutable<f::SelectedRows>();
  x0->set_rows(rows0);
  x0->set_height(height);
  auto x0_value = x0->mutable_value();
  x0_value->mutable_data<float>(
      f::make_ddim({static_cast<int64_t>(rows0.size()), row_numel}), place);
  set_one(ctx, x0_value, 1.0);

  // init x1
  std::vector<int64_t> rows1{2, 9};
  auto x1_var = scope.Var("x1");
  auto x1 = x1_var->GetMutable<f::SelectedRows>();
  x1->set_rows(rows1);
  x1->set_height(height);
  auto x1_value = x1->mutable_value();
  x1_value->mutable_data<float>(
      f::make_ddim({static_cast<int64_t>(rows1.size()), row_numel}), place);
  set_one(ctx, x1_value, 1.0);

  auto out_var = scope.Var("Out");
  auto out = out_var->GetMutable<f::SelectedRows>();
  auto out_value = out->mutable_value();
  out->set_height(height);
  out_value->mutable_data<float>(f::make_ddim({5, 10}), place);
}

void AddOp(const std::string &type, const f::VariableNameMap &inputs,
           const f::VariableNameMap &outputs, f::AttributeMap attrs,
           f::BlockDesc *block) {
  // insert output
  for (auto kv : outputs) {
    for (auto v : kv.second) {
      auto var = block->Var(v);
      var->SetDataType(f::proto::VarType::FP32);
    }
  }

  // insert op
  auto op = block->AppendOp();
  op->SetType(type);
  for (auto &kv : inputs) {
    op->SetInput(kv.first, kv.second);
  }
  for (auto &kv : outputs) {
    op->SetOutput(kv.first, kv.second);
  }
  op->SetAttrMap(attrs);
}

void StartServerNet(bool is_sparse) {
  f::Scope scope;
  p::CPUPlace place;
  if (is_sparse) {
    InitSelectedRowsInScope(scope, place);
  } else {
    InitTensorsInScope(scope, place);
  }

  // sub program run in listen_and_serv_op, for simple test we use sum
  f::ProgramDesc program;
  const auto &root_block = program.Block(0);
  auto *optimize_block = program.AppendBlock(root_block);
  // X for server side tensors, RX for received tensers, must be of same shape.
  AddOp("sum", {{"X", {"x0", "x1"}}}, {{"Out", {"Out"}}}, {}, optimize_block);

  f::AttributeMap attrs;
  attrs.insert({"endpoint", std::string("127.0.0.1:6174")});
  attrs.insert({"Fanin", 1});
  attrs.insert({"ParamList", std::vector<std::string>({"Out"})});
  attrs.insert({"GradList", std::vector<std::string>({"x1"})});
  attrs.insert({"OptimizeBlock", optimize_block});
  listen_and_serv_op =
      f::OpRegistry::CreateOp("listen_and_serv", {{"X", {"x1"}}}, {}, attrs);
  listen_and_serv_op->Run(scope, place);
}

TEST(SendRecvOp, CPUDense) {
  std::thread server_thread(StartServerNet, false);
  sleep(5);  // wait server to start
  // local net
  f::Scope scope;
  p::CPUPlace place;
  InitTensorsInScope(scope, place);
  // create rpc client var
  scope.Var("RPC_CLIENT_VAR");

  f::AttributeMap attrs;
  attrs.insert({"endpoints", std::vector<std::string>({"127.0.0.1:6174"})});
  attrs.insert({"epmap", std::vector<std::string>({"127.0.0.1:6174"})});
  auto send_op = f::OpRegistry::CreateOp(
      "send", {{"X", {"x1"}}},
      {{"Out", {"Out"}}, {"RPCClient", {"RPC_CLIENT_VAR"}}}, attrs);
  send_op->Run(scope, place);

  auto in_var = scope.Var("x1");
  auto tensor = in_var->GetMutable<f::LoDTensor>();
  float *expected = tensor->data<float>();
  auto out_var = scope.Var("Out");
  auto target = out_var->GetMutable<f::LoDTensor>();
  // x1 * 2 == x0
  EXPECT_NE(target->memory_size(), size_t(0));
  float *actual = target->data<float>();
  for (int64_t i = 0; i < target->numel(); ++i) {
    EXPECT_EQ(expected[i] * 2, actual[i]);
  }
  listen_and_serv_op->Stop();
  server_thread.join();
  listen_and_serv_op.reset(nullptr);
}

TEST(SendRecvOp, CPUSparse) {
  std::thread server_thread(StartServerNet, true);
  sleep(3);  // wait server to start
  // local net
  f::Scope scope;
  p::CPUPlace place;
  p::CPUDeviceContext ctx(place);
  InitSelectedRowsInScope(scope, place);
  scope.Var("RPC_CLIENT_VAR");
  f::AttributeMap attrs;
  attrs.insert({"endpoints", std::vector<std::string>({"127.0.0.1:6174"})});
  attrs.insert({"epmap", std::vector<std::string>({"127.0.0.1:6174"})});
  auto send_op = f::OpRegistry::CreateOp(
      "send", {{"X", {"x1"}}},
      {{"Out", {"Out"}}, {"RPCClient", {"RPC_CLIENT_VAR"}}}, attrs);
  send_op->Run(scope, place);

  auto x0 = scope.Var("x0")->GetMutable<f::SelectedRows>();
  auto x1 = scope.Var("x1")->GetMutable<f::SelectedRows>();
  auto out = scope.Var("Out")->GetMutable<f::SelectedRows>();
  auto actual = out->mutable_value();

  std::unique_ptr<f::SelectedRows> expect{new f::SelectedRows()};
  auto expect_value = expect->mutable_value();
  expect_value->mutable_data<float>(f::make_ddim({5, 10}), place);

  m::SelectedRowsAdd<p::CPUDeviceContext, float> add_functor;
  add_functor(ctx, *x0, *x1, expect.get());

  EXPECT_EQ(actual->numel(), expect_value->numel());
  EXPECT_EQ(out->rows().size(), x0->rows().size() + x1->rows().size());

  for (int64_t i = 0; i < expect_value->numel(); ++i) {
    EXPECT_EQ(expect_value->mutable_data<float>(place)[i],
              actual->mutable_data<float>(place)[i]);
  }
  listen_and_serv_op->Stop();
  server_thread.join();
  listen_and_serv_op.reset();
}
<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/fitting/linear_shape_fitting.hpp
 *
 * Copyright 2014, 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef LINEARSHAPEFITTING_HPP_
#define LINEARSHAPEFITTING_HPP_

#include "eos/morphablemodel/PcaModel.hpp"

#include "Eigen/Core"
#include "Eigen/QR"

#include <vector>
#include <cassert>
#include <optional>

namespace eos {
	namespace fitting {

/**
 * Fits the shape of a Morphable Model to given 2D landmarks (i.e. estimates the maximum likelihood solution of the shape coefficients) as proposed in [1].
 * It's a linear, closed-form solution fitting of the shape, with regularisation (prior towards the mean).
 *
 * [1] O. Aldrian & W. Smith, Inverse Rendering of Faces with a 3D Morphable Model, PAMI 2013.
 *
 * Note: Using less than the maximum number of coefficients to fit is not thoroughly tested yet and may contain an error.
 * Note: Returns coefficients following standard normal distribution (i.e. all have similar magnitude). Why? Because we fit using the normalised basis?
 * Note: The standard deviations given should be a vector, i.e. different for each landmark. This is not implemented yet.
 *
 * @param[in] morphable_model The Morphable Model whose shape (coefficients) are estimated.
 * @param[in] affine_camera_matrix A 3x4 affine camera matrix from model to screen-space (should probably be of type CV_32FC1 as all our calculations are done with float).
 * @param[in] landmarks 2D landmarks from an image to fit the model to.
 * @param[in] vertex_ids The vertex ids in the model that correspond to the 2D points.
 * @param[in] base_face The base or reference face from where the fitting is started. Usually this would be the models mean face, which is what will be used if the parameter is not explicitly specified.
 * @param[in] lambda The regularisation parameter (weight of the prior towards the mean).
 * @param[in] num_coefficients_to_fit How many shape-coefficients to fit (all others will stay 0). Should be bigger than zero, or std::nullopt to fit all coefficients.
 * @param[in] detector_standard_deviation The standard deviation of the 2D landmarks given (e.g. of the detector used), in pixels.
 * @param[in] model_standard_deviation The standard deviation of the 3D vertex points in the 3D model, projected to 2D (so the value is in pixels).
 * @return The estimated shape-coefficients (alphas).
 */
inline std::vector<float> fit_shape_to_landmarks_linear(const morphablemodel::PcaModel& shape_model, Eigen::Matrix<float, 3, 4> affine_camera_matrix, const std::vector<Eigen::Vector2f>& landmarks, const std::vector<int>& vertex_ids, Eigen::VectorXf base_face=Eigen::VectorXf(), float lambda=3.0f, std::optional<int> num_coefficients_to_fit= std::optional<int>(), std::optional<float> detector_standard_deviation= std::optional<float>(), std::optional<float> model_standard_deviation= std::optional<float>())
{
	assert(landmarks.size() == vertex_ids.size());

	using Eigen::VectorXf;
	using Eigen::MatrixXf;

	const int num_coeffs_to_fit = num_coefficients_to_fit.value_or(shape_model.get_num_principal_components());
	const int num_landmarks = static_cast<int>(landmarks.size());

	if (base_face.size() == 0)
	{
		base_face = shape_model.get_mean();
	}

	// $\hat{V} \in R^{3N\times m-1}$, subselect the rows of the eigenvector matrix $V$ associated with the $N$ feature points
	// And we insert a row of zeros after every third row, resulting in matrix $\hat{V}_h \in R^{4N\times m-1}$:
	MatrixXf V_hat_h = MatrixXf::Zero(4 * num_landmarks, num_coeffs_to_fit);
	int row_index = 0;
	for (int i = 0; i < num_landmarks; ++i) {
		const MatrixXf basis_rows_ = shape_model.get_rescaled_pca_basis_at_point(vertex_ids[i]); // In the paper, the orthonormal basis might be used? I'm not sure, check it. It's even a mess in the paper. PH 26.5.2014: I think the rescaled basis is fine/better.
		V_hat_h.block(row_index, 0, 3, V_hat_h.cols()) = basis_rows_.block(0, 0, basis_rows_.rows(), num_coeffs_to_fit);
		row_index += 4; // replace 3 rows and skip the 4th one, it has all zeros
	}
	// Form a block diagonal matrix $P \in R^{3N\times 4N}$ in which the camera matrix C (P_Affine, affine_camera_matrix) is placed on the diagonal:
	MatrixXf P = MatrixXf::Zero(3 * num_landmarks, 4 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		P.block<3, 4>(3 * i, 4 * i) = affine_camera_matrix;
	}
	// The variances: Add the 2D and 3D standard deviations.
	// If the user doesn't provide them, we choose the following:
	// 2D (detector) standard deviation: In pixel, we follow [1] and choose sqrt(3) as the default value.
	// 3D (model) variance: 0.0f. It only makes sense to set it to something when we have a different variance for different vertices.
	// The 3D variance has to be projected to 2D (for details, see paper [1]) so the units do match up.
	float sigma_squared_2D = std::pow(detector_standard_deviation.value_or(std::sqrt(3.0f)), 2) + std::pow(model_standard_deviation.value_or(0.0f), 2);
	// We use a VectorXf, and later use .asDiagonal():
	VectorXf Omega = VectorXf::Constant(3 * num_landmarks, 1.0f / sigma_squared_2D);
	// Earlier, we set Sigma in a for-loop and then computed Omega, but it was really unnecessary:
	// Sigma(i, i) = sqrt(sigma_squared_2D), but then Omega is Sigma.t() * Sigma (squares the diagonal) - so we just assign 1/sigma_squared_2D to Omega here.

	// The landmarks in matrix notation (in homogeneous coordinates), $3N\times 1$
	VectorXf y = VectorXf::Ones(3 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		y(3 * i) = landmarks[i][0];
		y((3 * i) + 1) = landmarks[i][1];
		//y((3 * i) + 2) = 1; // already 1, stays (homogeneous coordinate)
	}
	// The mean, with an added homogeneous coordinate (x_1, y_1, z_1, 1, x_2, ...)^t
	VectorXf v_bar = VectorXf::Ones(4 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		v_bar(4 * i) = base_face(vertex_ids[i] * 3);
		v_bar((4 * i) + 1) = base_face(vertex_ids[i] * 3 + 1);
		v_bar((4 * i) + 2) = base_face(vertex_ids[i] * 3 + 2);
		//v_bar((4 * i) + 3) = 1; // already 1, stays (homogeneous coordinate)
	}

	// Bring into standard regularised quadratic form with diagonal distance matrix Omega:
	const MatrixXf A = P * V_hat_h; // camera matrix times the basis
	const MatrixXf b = P * v_bar - y; // camera matrix times the mean, minus the landmarks
	const MatrixXf AtOmegaAReg = A.transpose() * Omega.asDiagonal() * A + lambda * Eigen::MatrixXf::Identity(num_coeffs_to_fit, num_coeffs_to_fit);
	const MatrixXf rhs = -A.transpose() * Omega.asDiagonal() * b; // It's -A^t*Omega^t*b, but we don't need to transpose Omega, since it's a diagonal matrix, and Omega^t = Omega.
	// c_s: The 'x' that we solve for. (The variance-normalised shape parameter vector, $c_s = [a_1/sigma_{s,1} , ..., a_m-1/sigma_{s,m-1}]^t$.)
	// We get coefficients ~ N(0, 1), because we're fitting with the rescaled basis. The coefficients are not multiplied with their eigenvalues.
	const VectorXf c_s = AtOmegaAReg.colPivHouseholderQr().solve(rhs);

	return std::vector<float>(c_s.data(), c_s.data() + c_s.size());
};

	} /* namespace fitting */
} /* namespace eos */

#endif /* LINEARSHAPEFITTING_HPP_ */
<commit_msg>Removed old comment<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/fitting/linear_shape_fitting.hpp
 *
 * Copyright 2014, 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef LINEARSHAPEFITTING_HPP_
#define LINEARSHAPEFITTING_HPP_

#include "eos/morphablemodel/PcaModel.hpp"

#include "Eigen/Core"
#include "Eigen/QR"

#include <vector>
#include <cassert>
#include <optional>

namespace eos {
	namespace fitting {

/**
 * Fits the shape of a Morphable Model to given 2D landmarks (i.e. estimates the maximum likelihood solution of the shape coefficients) as proposed in [1].
 * It's a linear, closed-form solution fitting of the shape, with regularisation (prior towards the mean).
 *
 * [1] O. Aldrian & W. Smith, Inverse Rendering of Faces with a 3D Morphable Model, PAMI 2013.
 *
 * Note: Using less than the maximum number of coefficients to fit is not thoroughly tested yet and may contain an error.
 * Note: Returns coefficients following standard normal distribution (i.e. all have similar magnitude). Why? Because we fit using the normalised basis?
 * Note: The standard deviations given should be a vector, i.e. different for each landmark. This is not implemented yet.
 *
 * @param[in] morphable_model The Morphable Model whose shape (coefficients) are estimated.
 * @param[in] affine_camera_matrix A 3x4 affine camera matrix from model to screen-space.
 * @param[in] landmarks 2D landmarks from an image to fit the model to.
 * @param[in] vertex_ids The vertex ids in the model that correspond to the 2D points.
 * @param[in] base_face The base or reference face from where the fitting is started. Usually this would be the models mean face, which is what will be used if the parameter is not explicitly specified.
 * @param[in] lambda The regularisation parameter (weight of the prior towards the mean).
 * @param[in] num_coefficients_to_fit How many shape-coefficients to fit (all others will stay 0). Should be bigger than zero, or std::nullopt to fit all coefficients.
 * @param[in] detector_standard_deviation The standard deviation of the 2D landmarks given (e.g. of the detector used), in pixels.
 * @param[in] model_standard_deviation The standard deviation of the 3D vertex points in the 3D model, projected to 2D (so the value is in pixels).
 * @return The estimated shape-coefficients (alphas).
 */
inline std::vector<float> fit_shape_to_landmarks_linear(const morphablemodel::PcaModel& shape_model, Eigen::Matrix<float, 3, 4> affine_camera_matrix, const std::vector<Eigen::Vector2f>& landmarks, const std::vector<int>& vertex_ids, Eigen::VectorXf base_face=Eigen::VectorXf(), float lambda=3.0f, std::optional<int> num_coefficients_to_fit= std::optional<int>(), std::optional<float> detector_standard_deviation= std::optional<float>(), std::optional<float> model_standard_deviation= std::optional<float>())
{
	assert(landmarks.size() == vertex_ids.size());

	using Eigen::VectorXf;
	using Eigen::MatrixXf;

	const int num_coeffs_to_fit = num_coefficients_to_fit.value_or(shape_model.get_num_principal_components());
	const int num_landmarks = static_cast<int>(landmarks.size());

	if (base_face.size() == 0)
	{
		base_face = shape_model.get_mean();
	}

	// $\hat{V} \in R^{3N\times m-1}$, subselect the rows of the eigenvector matrix $V$ associated with the $N$ feature points
	// And we insert a row of zeros after every third row, resulting in matrix $\hat{V}_h \in R^{4N\times m-1}$:
	MatrixXf V_hat_h = MatrixXf::Zero(4 * num_landmarks, num_coeffs_to_fit);
	int row_index = 0;
	for (int i = 0; i < num_landmarks; ++i) {
		const MatrixXf basis_rows_ = shape_model.get_rescaled_pca_basis_at_point(vertex_ids[i]); // In the paper, the orthonormal basis might be used? I'm not sure, check it. It's even a mess in the paper. PH 26.5.2014: I think the rescaled basis is fine/better.
		V_hat_h.block(row_index, 0, 3, V_hat_h.cols()) = basis_rows_.block(0, 0, basis_rows_.rows(), num_coeffs_to_fit);
		row_index += 4; // replace 3 rows and skip the 4th one, it has all zeros
	}
	// Form a block diagonal matrix $P \in R^{3N\times 4N}$ in which the camera matrix C (P_Affine, affine_camera_matrix) is placed on the diagonal:
	MatrixXf P = MatrixXf::Zero(3 * num_landmarks, 4 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		P.block<3, 4>(3 * i, 4 * i) = affine_camera_matrix;
	}
	// The variances: Add the 2D and 3D standard deviations.
	// If the user doesn't provide them, we choose the following:
	// 2D (detector) standard deviation: In pixel, we follow [1] and choose sqrt(3) as the default value.
	// 3D (model) variance: 0.0f. It only makes sense to set it to something when we have a different variance for different vertices.
	// The 3D variance has to be projected to 2D (for details, see paper [1]) so the units do match up.
	float sigma_squared_2D = std::pow(detector_standard_deviation.value_or(std::sqrt(3.0f)), 2) + std::pow(model_standard_deviation.value_or(0.0f), 2);
	// We use a VectorXf, and later use .asDiagonal():
	VectorXf Omega = VectorXf::Constant(3 * num_landmarks, 1.0f / sigma_squared_2D);
	// Earlier, we set Sigma in a for-loop and then computed Omega, but it was really unnecessary:
	// Sigma(i, i) = sqrt(sigma_squared_2D), but then Omega is Sigma.t() * Sigma (squares the diagonal) - so we just assign 1/sigma_squared_2D to Omega here.

	// The landmarks in matrix notation (in homogeneous coordinates), $3N\times 1$
	VectorXf y = VectorXf::Ones(3 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		y(3 * i) = landmarks[i][0];
		y((3 * i) + 1) = landmarks[i][1];
		//y((3 * i) + 2) = 1; // already 1, stays (homogeneous coordinate)
	}
	// The mean, with an added homogeneous coordinate (x_1, y_1, z_1, 1, x_2, ...)^t
	VectorXf v_bar = VectorXf::Ones(4 * num_landmarks);
	for (int i = 0; i < num_landmarks; ++i) {
		v_bar(4 * i) = base_face(vertex_ids[i] * 3);
		v_bar((4 * i) + 1) = base_face(vertex_ids[i] * 3 + 1);
		v_bar((4 * i) + 2) = base_face(vertex_ids[i] * 3 + 2);
		//v_bar((4 * i) + 3) = 1; // already 1, stays (homogeneous coordinate)
	}

	// Bring into standard regularised quadratic form with diagonal distance matrix Omega:
	const MatrixXf A = P * V_hat_h; // camera matrix times the basis
	const MatrixXf b = P * v_bar - y; // camera matrix times the mean, minus the landmarks
	const MatrixXf AtOmegaAReg = A.transpose() * Omega.asDiagonal() * A + lambda * Eigen::MatrixXf::Identity(num_coeffs_to_fit, num_coeffs_to_fit);
	const MatrixXf rhs = -A.transpose() * Omega.asDiagonal() * b; // It's -A^t*Omega^t*b, but we don't need to transpose Omega, since it's a diagonal matrix, and Omega^t = Omega.
	// c_s: The 'x' that we solve for. (The variance-normalised shape parameter vector, $c_s = [a_1/sigma_{s,1} , ..., a_m-1/sigma_{s,m-1}]^t$.)
	// We get coefficients ~ N(0, 1), because we're fitting with the rescaled basis. The coefficients are not multiplied with their eigenvalues.
	const VectorXf c_s = AtOmegaAReg.colPivHouseholderQr().solve(rhs);

	return std::vector<float>(c_s.data(), c_s.data() + c_s.size());
};

	} /* namespace fitting */
} /* namespace eos */

#endif /* LINEARSHAPEFITTING_HPP_ */
<|endoftext|>


<commit_before>#pragma once

// C++ wrapper around a statically sized array
//
// Based on:
// https://github.com/stephentu/silo/blob/master/static_vector.h

#include <algorithm>
#include <type_traits>
#include <microscopes/common/macros.hpp>
#include <microscopes/common/assert.hpp>

namespace microscopes {
namespace common {

template <typename T, size_t MaxSize>
class static_vector {

  static const bool is_trivially_destructible =
    std::is_trivially_destructible<T>::value;

  static const bool is_trivially_copyable =
    std::is_trivially_copyable<T>::value;

public:

  typedef T value_type;
  typedef T & reference;
  typedef const T & const_reference;
  typedef size_t size_type;

  inline static_vector() : n(0) {}
  inline ~static_vector() { clear(); }

  inline static_vector(const static_vector &that)
    : n(0)
  {
    assignFrom(that);
  }

  // not efficient, don't use in performance critical parts
  static_vector(std::initializer_list<T> l)
    : n(0)
  {
    for (auto &p : l)
      push_back(p);
  }

  static_vector &
  operator=(const static_vector &that)
  {
    assignFrom(that);
    return *this;
  }

  inline size_t
  size() const
  {
    return n;
  }

  inline bool
  empty() const
  {
    return !n;
  }

  inline reference
  front()
  {
    MICROSCOPES_ASSERT(n > 0);
    MICROSCOPES_ASSERT(n <= MaxSize);
    return *ptr();
  }

  inline const_reference
  front() const
  {
    return const_cast<static_vector *>(this)->front();
  }

  inline reference
  back()
  {
    MICROSCOPES_ASSERT(n > 0);
    MICROSCOPES_ASSERT(n <= MaxSize);
    return ptr()[n - 1];
  }

  inline const_reference
  back() const
  {
    return const_cast<static_vector *>(this)->back();
  }

  inline void
  pop_back()
  {
    MICROSCOPES_ASSERT(n > 0);
    if (!is_trivially_destructible)
      ptr()[n - 1].~T();
    n--;
  }

  inline void
  push_back(const T &obj)
  {
    emplace_back(obj);
  }

  inline void
  push_back(T &&obj)
  {
    emplace_back(std::move(obj));
  }

  // C++11 goodness- a strange syntax this is

  template <class... Args>
  inline void
  emplace_back(Args &&... args)
  {
    MICROSCOPES_ASSERT(n < MaxSize);
    new (&(ptr()[n++])) T(std::forward<Args>(args)...);
  }

  inline reference
  operator[](int i)
  {
    return ptr()[i];
  }

  inline const_reference
  operator[](int i) const
  {
    return const_cast<static_vector *>(this)->operator[](i);
  }

  void
  clear()
  {
    if (!is_trivially_destructible)
      for (size_t i = 0; i < n; i++)
        ptr()[i].~T();
    n = 0;
  }

  inline void
  reserve(size_t n)
  {
  }

  inline void
  resize(size_t n, value_type val = value_type())
  {
    MICROSCOPES_ASSERT(n <= MaxSize);
    if (n > this->n) {
      // expand
      while (this->n < n)
        new (&ptr()[this->n++]) T(val);
    } else if (n < this->n) {
      // shrink
      while (this->n > n) {
        if (!is_trivially_destructible)
          ptr()[this->n - 1].~T();
        this->n--;
      }
    }
  }

  // non-standard API

  template <typename Compare = std::less<T>>
  inline void
  sort(Compare c = Compare())
  {
    std::sort(begin(), end(), c);
  }

private:

  template <typename ObjType>
  class iterator_ : public std::iterator<std::bidirectional_iterator_tag, ObjType> {
    friend class static_vector;
  public:
    inline iterator_() : p(0) {}

    template <typename O>
    inline iterator_(const iterator_<O> &other)
      : p(other.p)
    {}

    inline ObjType &
    operator*() const
    {
      return *p;
    }

    inline ObjType *
    operator->() const
    {
      return p;
    }

    inline bool
    operator==(const iterator_ &o) const
    {
      return p == o.p;
    }

    inline bool
    operator!=(const iterator_ &o) const
    {
      return !operator==(o);
    }

    inline bool
    operator<(const iterator_ &o) const
    {
      return p < o.p;
    }

    inline bool
    operator>=(const iterator_ &o) const
    {
      return !operator<(o);
    }

    inline bool
    operator>(const iterator_ &o) const
    {
      return p > o.p;
    }

    inline bool
    operator<=(const iterator_ &o) const
    {
      return !operator>(o);
    }

    inline iterator_ &
    operator+=(int n)
    {
      p += n;
      return *this;
    }

    inline iterator_ &
    operator-=(int n)
    {
      p -= n;
      return *this;
    }

    inline iterator_
    operator+(int n) const
    {
      iterator_ cpy = *this;
      return cpy += n;
    }

    inline iterator_
    operator-(int n) const
    {
      iterator_ cpy = *this;
      return cpy -= n;
    }

    inline intptr_t
    operator-(const iterator_ &o) const
    {
      return p - o.p;
    }

    inline iterator_ &
    operator++()
    {
      ++p;
      return *this;
    }

    inline iterator_
    operator++(int)
    {
      iterator_ cur = *this;
      ++(*this);
      return cur;
    }

    inline iterator_ &
    operator--()
    {
      --p;
      return *this;
    }

    inline iterator_
    operator--(int)
    {
      iterator_ cur = *this;
      --(*this);
      return cur;
    }

  protected:
    inline iterator_(ObjType *p) : p(p) {}

  private:
    ObjType *p;
  };

public:

  typedef iterator_<T> iterator;
  typedef iterator_<const T> const_iterator;

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

  inline iterator
  begin()
  {
    return iterator(ptr());
  }

  inline const_iterator
  begin() const
  {
    return const_iterator(ptr());
  }

  inline iterator
  end()
  {
    return iterator(endptr());
  }

  inline const_iterator
  end() const
  {
    return const_iterator(endptr());
  }

  inline reverse_iterator
  rbegin()
  {
    return reverse_iterator(end());
  }

  inline const_reverse_iterator
  rbegin() const
  {
    return const_reverse_iterator(end());
  }

  inline reverse_iterator
  rend()
  {
    return reverse_iterator(begin());
  }

  inline const_reverse_iterator
  rend() const
  {
    return const_reverse_iterator(begin());
  }

private:
  void
  assignFrom(const static_vector &that)
  {
    if (unlikely(this == &that))
      return;
    clear();
    MICROSCOPES_ASSERT(that.n <= MaxSize);
    if (is_trivially_copyable) {
      MICROSCOPES_MEMCPY(ptr(), that.ptr(), that.n * sizeof(T));
    } else {
      for (size_t i = 0; i < that.n; i++)
        new (&(ptr()[i])) T(that.ptr()[i]);
    }
    n = that.n;
  }

  inline ALWAYS_INLINE T *
  ptr()
  {
    return reinterpret_cast<T *>(&elems_buf[0]);
  }

  inline ALWAYS_INLINE const T *
  ptr() const
  {
    return reinterpret_cast<const T *>(&elems_buf[0]);
  }

  inline ALWAYS_INLINE T *
  endptr()
  {
    return ptr() + n;
  }

  inline ALWAYS_INLINE const T *
  endptr() const
  {
    return ptr() + n;
  }

  size_t n;
  char elems_buf[sizeof(T) * MaxSize];
};

} // namespace common
} // namespace microscopes
<commit_msg>play to the lowest common denom<commit_after>#pragma once

// C++ wrapper around a statically sized array
//
// Based on:
// https://github.com/stephentu/silo/blob/master/static_vector.h

#include <algorithm>
#include <type_traits>
#include <microscopes/common/macros.hpp>
#include <microscopes/common/assert.hpp>

namespace microscopes {
namespace common {

template <typename T, size_t MaxSize>
class static_vector {

  static const bool is_trivially_destructible =
    std::is_trivially_destructible<T>::value;

  // not supported on g++-4.8
  //static const bool is_trivially_copyable =
  //  std::is_trivially_copyable<T>::value;

  static const bool is_trivially_copyable =
    std::is_scalar<T>::value;

public:

  typedef T value_type;
  typedef T & reference;
  typedef const T & const_reference;
  typedef size_t size_type;

  inline static_vector() : n(0) {}
  inline ~static_vector() { clear(); }

  inline static_vector(const static_vector &that)
    : n(0)
  {
    assignFrom(that);
  }

  // not efficient, don't use in performance critical parts
  static_vector(std::initializer_list<T> l)
    : n(0)
  {
    for (auto &p : l)
      push_back(p);
  }

  static_vector &
  operator=(const static_vector &that)
  {
    assignFrom(that);
    return *this;
  }

  inline size_t
  size() const
  {
    return n;
  }

  inline bool
  empty() const
  {
    return !n;
  }

  inline reference
  front()
  {
    MICROSCOPES_ASSERT(n > 0);
    MICROSCOPES_ASSERT(n <= MaxSize);
    return *ptr();
  }

  inline const_reference
  front() const
  {
    return const_cast<static_vector *>(this)->front();
  }

  inline reference
  back()
  {
    MICROSCOPES_ASSERT(n > 0);
    MICROSCOPES_ASSERT(n <= MaxSize);
    return ptr()[n - 1];
  }

  inline const_reference
  back() const
  {
    return const_cast<static_vector *>(this)->back();
  }

  inline void
  pop_back()
  {
    MICROSCOPES_ASSERT(n > 0);
    if (!is_trivially_destructible)
      ptr()[n - 1].~T();
    n--;
  }

  inline void
  push_back(const T &obj)
  {
    emplace_back(obj);
  }

  inline void
  push_back(T &&obj)
  {
    emplace_back(std::move(obj));
  }

  // C++11 goodness- a strange syntax this is

  template <class... Args>
  inline void
  emplace_back(Args &&... args)
  {
    MICROSCOPES_ASSERT(n < MaxSize);
    new (&(ptr()[n++])) T(std::forward<Args>(args)...);
  }

  inline reference
  operator[](int i)
  {
    return ptr()[i];
  }

  inline const_reference
  operator[](int i) const
  {
    return const_cast<static_vector *>(this)->operator[](i);
  }

  void
  clear()
  {
    if (!is_trivially_destructible)
      for (size_t i = 0; i < n; i++)
        ptr()[i].~T();
    n = 0;
  }

  inline void
  reserve(size_t n)
  {
  }

  inline void
  resize(size_t n, value_type val = value_type())
  {
    MICROSCOPES_ASSERT(n <= MaxSize);
    if (n > this->n) {
      // expand
      while (this->n < n)
        new (&ptr()[this->n++]) T(val);
    } else if (n < this->n) {
      // shrink
      while (this->n > n) {
        if (!is_trivially_destructible)
          ptr()[this->n - 1].~T();
        this->n--;
      }
    }
  }

  // non-standard API

  template <typename Compare = std::less<T>>
  inline void
  sort(Compare c = Compare())
  {
    std::sort(begin(), end(), c);
  }

private:

  template <typename ObjType>
  class iterator_ : public std::iterator<std::bidirectional_iterator_tag, ObjType> {
    friend class static_vector;
  public:
    inline iterator_() : p(0) {}

    template <typename O>
    inline iterator_(const iterator_<O> &other)
      : p(other.p)
    {}

    inline ObjType &
    operator*() const
    {
      return *p;
    }

    inline ObjType *
    operator->() const
    {
      return p;
    }

    inline bool
    operator==(const iterator_ &o) const
    {
      return p == o.p;
    }

    inline bool
    operator!=(const iterator_ &o) const
    {
      return !operator==(o);
    }

    inline bool
    operator<(const iterator_ &o) const
    {
      return p < o.p;
    }

    inline bool
    operator>=(const iterator_ &o) const
    {
      return !operator<(o);
    }

    inline bool
    operator>(const iterator_ &o) const
    {
      return p > o.p;
    }

    inline bool
    operator<=(const iterator_ &o) const
    {
      return !operator>(o);
    }

    inline iterator_ &
    operator+=(int n)
    {
      p += n;
      return *this;
    }

    inline iterator_ &
    operator-=(int n)
    {
      p -= n;
      return *this;
    }

    inline iterator_
    operator+(int n) const
    {
      iterator_ cpy = *this;
      return cpy += n;
    }

    inline iterator_
    operator-(int n) const
    {
      iterator_ cpy = *this;
      return cpy -= n;
    }

    inline intptr_t
    operator-(const iterator_ &o) const
    {
      return p - o.p;
    }

    inline iterator_ &
    operator++()
    {
      ++p;
      return *this;
    }

    inline iterator_
    operator++(int)
    {
      iterator_ cur = *this;
      ++(*this);
      return cur;
    }

    inline iterator_ &
    operator--()
    {
      --p;
      return *this;
    }

    inline iterator_
    operator--(int)
    {
      iterator_ cur = *this;
      --(*this);
      return cur;
    }

  protected:
    inline iterator_(ObjType *p) : p(p) {}

  private:
    ObjType *p;
  };

public:

  typedef iterator_<T> iterator;
  typedef iterator_<const T> const_iterator;

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

  inline iterator
  begin()
  {
    return iterator(ptr());
  }

  inline const_iterator
  begin() const
  {
    return const_iterator(ptr());
  }

  inline iterator
  end()
  {
    return iterator(endptr());
  }

  inline const_iterator
  end() const
  {
    return const_iterator(endptr());
  }

  inline reverse_iterator
  rbegin()
  {
    return reverse_iterator(end());
  }

  inline const_reverse_iterator
  rbegin() const
  {
    return const_reverse_iterator(end());
  }

  inline reverse_iterator
  rend()
  {
    return reverse_iterator(begin());
  }

  inline const_reverse_iterator
  rend() const
  {
    return const_reverse_iterator(begin());
  }

private:
  void
  assignFrom(const static_vector &that)
  {
    if (unlikely(this == &that))
      return;
    clear();
    MICROSCOPES_ASSERT(that.n <= MaxSize);
    if (is_trivially_copyable) {
      MICROSCOPES_MEMCPY(ptr(), that.ptr(), that.n * sizeof(T));
    } else {
      for (size_t i = 0; i < that.n; i++)
        new (&(ptr()[i])) T(that.ptr()[i]);
    }
    n = that.n;
  }

  inline ALWAYS_INLINE T *
  ptr()
  {
    return reinterpret_cast<T *>(&elems_buf[0]);
  }

  inline ALWAYS_INLINE const T *
  ptr() const
  {
    return reinterpret_cast<const T *>(&elems_buf[0]);
  }

  inline ALWAYS_INLINE T *
  endptr()
  {
    return ptr() + n;
  }

  inline ALWAYS_INLINE const T *
  endptr() const
  {
    return ptr() + n;
  }

  size_t n;
  char elems_buf[sizeof(T) * MaxSize];
};

} // namespace common
} // namespace microscopes
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sunjre.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:31:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#if !defined INCLUDED_JFW_PLUGIN_SUNJRE_HXX
#define  INCLUDED_JFW_PLUGIN_SUNJRE_HXX

#include "vendorbase.hxx"
#include "vendorlist.hxx"

namespace jfw_plugin
{

class SunInfo: public VendorBase
{
public:
    static char const* const* getJavaExePaths(int * size);

    static rtl::Reference<VendorBase> createInstance();

    virtual char const* const* getRuntimePaths(int * size);
    virtual char const* const* getLibraryPaths(int* size);

    virtual int compareVersions(const rtl::OUString& sSecond) const;
};

}
#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.4.6); FILE MERGED 2005/10/27 15:08:48 pl 1.4.6.1: #i55991# removed warnings for solaris platform<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sunjre.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 00:09:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#if !defined INCLUDED_JFW_PLUGIN_SUNJRE_HXX
#define  INCLUDED_JFW_PLUGIN_SUNJRE_HXX

#include "vendorbase.hxx"
#include "vendorlist.hxx"

namespace jfw_plugin
{

class SunInfo: public VendorBase
{
public:
    static char const* const* getJavaExePaths(int * size);

    static rtl::Reference<VendorBase> createInstance();

    using VendorBase::getLibraryPaths;
    virtual char const* const* getRuntimePaths(int * size);
    virtual char const* const* getLibraryPaths(int* size);

    virtual int compareVersions(const rtl::OUString& sSecond) const;
};

}
#endif
<|endoftext|>