<commit_before>/** @file runtime.hpp
*/

#ifndef RUNTIME_HPP_INCLUDED
#define RUNTIME_HPP_INCLUDED

#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <array>
#include <assert.h>
#include <stdlib.h>

#include "StateMachineOwner.hpp"
#include "threadpool.hpp"
#include "ievent.hpp"
#include "threadpoolmanager.hpp"
#include "ESRoot/Types.hpp"
#include "ESRoot/AtomicCounter.hpp"

namespace Execution
{

template<typename RuntimeType, int NC>
class IRuntime
{
public:

	/*!
	Returns the runtime instance during the model execution.
	*/
	static ES::RuntimePtr<RuntimeType,NC> getRuntimeInstance()
	{
		if (instance == nullptr)
		{
			instance = RuntimeType::createRuntime();
		}
		return instance;
	}

	/*!
	Registers a state machine in the runtime instance so
	the threaded runtime can record the number of object instances during the model execution.
	Called by the state machine constructor.
	*/
	void setupObject(ES::StateMachineRef sm)
	{
		static_cast<RuntimeType*>(this)->setupObjectSpecificRuntime(sm);
	}

	/*!
	Removes a state machine from the runtime instance when
	the threaded runtime can record the number of object instances during the model execution.
	Called by the state machine destructor.
	*/
	void removeObject(ES::StateMachineRef sm)
	{
		static_cast<RuntimeType*>(this)->removeObject(sm);
	}

	/*!
	Sets the deployment configuration for the threaded runtime instance.
	*/
	void configure(std::array<ES::SharedPtr<Configuration>, NC> configuration)
	{
		if (!(static_cast<RuntimeType*>(this)->isConfigurated()))
		{
			static_cast<RuntimeType*>(this)->setConfiguration(configuration);
		}

	}

	/*!
	Starts the model execution.
	*/
	void startRT()
	{
		static_cast<RuntimeType*>(this)->start();
	}

	/*!
	Stops the runtime instance when there are no more messages to process and under processing.
	*/
	void stopUponCompletion()
	{
		static_cast<RuntimeType*>(this)->stopUponCompletion();
	}

protected:
	static ES::RuntimePtr<RuntimeType,NC> instance;
	IRuntime() {}
};

template<int NC>
class SingleThreadRT : public IRuntime<SingleThreadRT<NC>, NC>
{
public:
	virtual ~SingleThreadRT();

	/*!
	Processes the events while the message queue is not empty.
	*/
	void start();

	void setupObjectSpecificRuntime(ES::StateMachineRef);
	void removeObject(ES::StateMachineRef);
	void setConfiguration(std::array<ES::SharedPtr<Configuration>,NC>);
	bool isConfigurated();
	void stopUponCompletion();
	static ES::RuntimePtr<SingleThreadRT,NC> createRuntime() { return ES::RuntimePtr<SingleThreadRT<NC>,NC>(new SingleThreadRT<NC>()); }
private:
	SingleThreadRT();
	ES::SharedPtr<ES::MessageQueueType> _messageQueue;

};

template<int NC>
class ConfiguredThreadedRT : public IRuntime<ConfiguredThreadedRT<NC>,NC>
{
	typedef typename std::array<unsigned, NC>::size_type id_type;
public:
	virtual ~ConfiguredThreadedRT();
	/*!
	Starts the thread pools.
	*/
	void start();

	void setupObjectSpecificRuntime(ES::StateMachineRef);
	void removeObject(ES::StateMachineRef);
	void setConfiguration(std::array<ES::SharedPtr<Configuration>, NC>);
	bool isConfigurated();
	void stopUponCompletion();
	static ES::RuntimePtr<ConfiguredThreadedRT,NC> createRuntime() { return ES::RuntimePtr<ConfiguredThreadedRT<NC>,NC>(new ConfiguredThreadedRT<NC>()); }
private:
	ConfiguredThreadedRT();
	ES::SharedPtr<ThreadPoolManager<NC>> poolManager;
	std::array<unsigned, NC> numberOfObjects;

	ES::SharedPtr<ES::AtomicCounter> worker;
	ES::SharedPtr<ES::AtomicCounter> messages;
	std::condition_variable stop_request_cond;
};

template<typename RuntimeType, int NC>
ES::RuntimePtr<RuntimeType,NC> IRuntime<RuntimeType, NC>::instance = nullptr;

// SingleThreadRT
template<int NC>
SingleThreadRT<NC>::SingleThreadRT() :_messageQueue(new ES::MessageQueueType()) {}

template<int NC>
void SingleThreadRT<NC>::setupObjectSpecificRuntime(ES::StateMachineRef sm)
{
	sm->setMessageQueue(_messageQueue);
	sm->setMessageCounter(ES::SharedPtr<ES::AtomicCounter>(new ES::AtomicCounter()));
}

template<int NC>
SingleThreadRT<NC>::~SingleThreadRT()
{
}

template<int NC>
bool SingleThreadRT<NC>::isConfigurated()
{
	return true;
}

template<int NC>
void SingleThreadRT<NC>::start()
{

	while (!_messageQueue->isEmpty())
	{
		ES::EventRef e = _messageQueue->next();
		if (Model::IEvent<Model::EventBase>::eventIsValid(e)) {
			const ES::StateMachineRef sm = e->getTargetSM();
			sm->processNextEvent();
		}
		else {
			_messageQueue->dequeue(e); // drop event
		}

	}

}

template<int NC>
void SingleThreadRT<NC>::setConfiguration(std::array<ES::SharedPtr<Configuration>, NC>) {}

template<int NC>
void SingleThreadRT<NC>::stopUponCompletion() {}

template<int NC>
void SingleThreadRT<NC>::removeObject(ES::StateMachineRef) {}

// ConfiguredThreadedRT
template<int NC>
ConfiguredThreadedRT<NC>::ConfiguredThreadedRT () :
	poolManager (new ThreadPoolManager<NC> ()),
	worker (new ES::AtomicCounter ()),
	messages (new ES::AtomicCounter ()) {}

template<int NC>
ConfiguredThreadedRT<NC>::~ConfiguredThreadedRT () {}

template<int NC>
void ConfiguredThreadedRT<NC>::start ()
{
	assert (isConfigurated () && "The configurated threaded runtime should be configured before starting.");

	if (isConfigurated ())
	{
		for (id_type i = 0; i < (id_type)NC; i++)
		{
			ES::SharedPtr<StateMachineThreadPool> pool = poolManager->getPool (i);
			pool->setWorkersCounter (worker);
			pool->setMessageCounter (messages);
			pool->setStopReqest (&stop_request_cond);
			pool->startPool (poolManager->calculateNOfThreads (i,numberOfObjects[i]));
		}
	}
}

template<int NC>
void ConfiguredThreadedRT<NC>::removeObject (ES::StateMachineRef sm)
{
	id_type objectId = (id_type) sm->getPoolId ();
	numberOfObjects[objectId]--;
	poolManager->recalculateThreads (objectId, numberOfObjects[objectId]);
}

template<int NC>
void ConfiguredThreadedRT<NC>::stopUponCompletion ()
{
	for (int i = 0; i < NC; i++)
	{
		poolManager->getPool ((id_type)i)->stopUponCompletion ();
	}
}

template<int NC>
void ConfiguredThreadedRT<NC>::setupObjectSpecificRuntime (ES::StateMachineRef sm)
{

	sm->setMessageCounter (messages);
	id_type objectId = (id_type)sm->getPoolId ();
	ES::SharedPtr<StateMachineThreadPool> matchedPool = poolManager->getPool (objectId);
	sm->setPool (matchedPool);
	numberOfObjects[objectId]++;
	poolManager->recalculateThreads (objectId, numberOfObjects[objectId]);
}

template<int NC>
bool ConfiguredThreadedRT<NC>::isConfigurated ()
{
	return poolManager->isConfigurated ();
}

template<int NC>
void ConfiguredThreadedRT<NC>::setConfiguration (std::array<ES::SharedPtr<Configuration>, NC> conf)
{
	poolManager->setConfiguration (conf);
	for (id_type i = 0; i < numberOfObjects.size (); ++i) {
		numberOfObjects[i] = 0;
	}
}

}

#endif // RUNTIME_HPP_INCLUDED
<commit_msg>Make runtime instance thread safe<commit_after>/** @file runtime.hpp
*/

#ifndef RUNTIME_HPP_INCLUDED
#define RUNTIME_HPP_INCLUDED

#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <array>
#include <assert.h>
#include <stdlib.h>

#include "StateMachineOwner.hpp"
#include "threadpool.hpp"
#include "ievent.hpp"
#include "threadpoolmanager.hpp"
#include "ESRoot/Types.hpp"
#include "ESRoot/AtomicCounter.hpp"

namespace Execution
{

template<typename RuntimeType, int NC>
class IRuntime
{
public:

	/*!
	Returns the runtime instance during the model execution.
	*/
	static ES::RuntimePtr<RuntimeType,NC> getRuntimeInstance()
	{
		std::call_once (runtimeInstanceInitFlag, initRuntime);
		return instance;
	}

	/*!
	Registers a state machine in the runtime instance so
	the threaded runtime can record the number of object instances during the model execution.
	Called by the state machine constructor.
	*/
	void setupObject(ES::StateMachineRef sm)
	{
		static_cast<RuntimeType*>(this)->setupObjectSpecificRuntime(sm);
	}

	/*!
	Removes a state machine from the runtime instance when
	the threaded runtime can record the number of object instances during the model execution.
	Called by the state machine destructor.
	*/
	void removeObject(ES::StateMachineRef sm)
	{
		static_cast<RuntimeType*>(this)->removeObject(sm);
	}

	/*!
	Sets the deployment configuration for the threaded runtime instance.
	*/
	void configure(std::array<ES::SharedPtr<Configuration>, NC> configuration)
	{
		if (!(static_cast<RuntimeType*>(this)->isConfigurated()))
		{
			static_cast<RuntimeType*>(this)->setConfiguration(configuration);
		}

	}

	/*!
	Starts the model execution.
	*/
	void startRT()
	{
		static_cast<RuntimeType*>(this)->start();
	}

	/*!
	Stops the runtime instance when there are no more messages to process and under processing.
	*/
	void stopUponCompletion()
	{
		static_cast<RuntimeType*>(this)->stopUponCompletion();
	}

protected:
	IRuntime () {}

private:
	static void initRuntime ()
	{
		instance = RuntimeType::createRuntime ();

	}
	static ES::RuntimePtr<RuntimeType, NC> instance;
	static std::once_flag				   runtimeInstanceInitFlag;
};

template<int NC>
class SingleThreadRT : public IRuntime<SingleThreadRT<NC>, NC>
{
public:
	virtual ~SingleThreadRT();

	/*!
	Processes the events while the message queue is not empty.
	*/
	void start();

	void setupObjectSpecificRuntime(ES::StateMachineRef);
	void removeObject(ES::StateMachineRef);
	void setConfiguration(std::array<ES::SharedPtr<Configuration>,NC>);
	bool isConfigurated();
	void stopUponCompletion();
	static ES::RuntimePtr<SingleThreadRT, NC> createRuntime () { return ES::RuntimePtr<SingleThreadRT<NC>, NC> (new SingleThreadRT<NC> ()); }
private:
	SingleThreadRT ();
	ES::SharedPtr<ES::MessageQueueType> _messageQueue;

};

template<int NC>
class ConfiguredThreadedRT : public IRuntime<ConfiguredThreadedRT<NC>,NC>
{
	typedef typename std::array<unsigned, NC>::size_type id_type;
public:
	virtual ~ConfiguredThreadedRT();
	/*!
	Starts the thread pools.
	*/
	void start();

	void setupObjectSpecificRuntime(ES::StateMachineRef);
	void removeObject(ES::StateMachineRef);
	void setConfiguration(std::array<ES::SharedPtr<Configuration>, NC>);
	bool isConfigurated();
	void stopUponCompletion();
	static ES::RuntimePtr<ConfiguredThreadedRT, NC> createRuntime () { return ES::RuntimePtr<ConfiguredThreadedRT<NC>, NC> (new ConfiguredThreadedRT<NC> ()); }
private:
	ConfiguredThreadedRT ();
	ES::SharedPtr<ThreadPoolManager<NC>> poolManager;
	std::array<unsigned, NC> numberOfObjects;

	ES::SharedPtr<ES::AtomicCounter> worker;
	ES::SharedPtr<ES::AtomicCounter> messages;
	std::condition_variable stop_request_cond;
};

template<typename RuntimeType, int NC>
ES::RuntimePtr<RuntimeType,NC> IRuntime<RuntimeType, NC>::instance = nullptr;
template<typename RuntimeType, int NC>
std::once_flag				 IRuntime<RuntimeType, NC>::runtimeInstanceInitFlag;

// SingleThreadRT
template<int NC>
SingleThreadRT<NC>::SingleThreadRT() :_messageQueue(new ES::MessageQueueType()) {}

template<int NC>
void SingleThreadRT<NC>::setupObjectSpecificRuntime(ES::StateMachineRef sm)
{
	sm->setMessageQueue(_messageQueue);
	sm->setMessageCounter(ES::SharedPtr<ES::AtomicCounter>(new ES::AtomicCounter()));
}

template<int NC>
SingleThreadRT<NC>::~SingleThreadRT()
{
}

template<int NC>
bool SingleThreadRT<NC>::isConfigurated()
{
	return true;
}

template<int NC>
void SingleThreadRT<NC>::start()
{

	while (!_messageQueue->isEmpty())
	{
		ES::EventRef e = _messageQueue->next();
		if (Model::IEvent<Model::EventBase>::eventIsValid(e)) {
			const ES::StateMachineRef sm = e->getTargetSM();
			sm->processNextEvent();
		}
		else {
			_messageQueue->dequeue(e); // drop event
		}

	}

}

template<int NC>
void SingleThreadRT<NC>::setConfiguration(std::array<ES::SharedPtr<Configuration>, NC>) {}

template<int NC>
void SingleThreadRT<NC>::stopUponCompletion() {}

template<int NC>
void SingleThreadRT<NC>::removeObject(ES::StateMachineRef) {}

// ConfiguredThreadedRT
template<int NC>
ConfiguredThreadedRT<NC>::ConfiguredThreadedRT () :
	poolManager (new ThreadPoolManager<NC> ()),
	worker (new ES::AtomicCounter ()),
	messages (new ES::AtomicCounter ()) {}

template<int NC>
ConfiguredThreadedRT<NC>::~ConfiguredThreadedRT () {}

template<int NC>
void ConfiguredThreadedRT<NC>::start ()
{
	assert (isConfigurated () && "The configurated threaded runtime should be configured before starting.");

	if (isConfigurated ())
	{
		for (id_type i = 0; i < (id_type)NC; i++)
		{
			ES::SharedPtr<StateMachineThreadPool> pool = poolManager->getPool (i);
			pool->setWorkersCounter (worker);
			pool->setMessageCounter (messages);
			pool->setStopReqest (&stop_request_cond);
			pool->startPool (poolManager->calculateNOfThreads (i,numberOfObjects[i]));
		}
	}
}

template<int NC>
void ConfiguredThreadedRT<NC>::removeObject (ES::StateMachineRef sm)
{
	id_type objectId = (id_type) sm->getPoolId ();
	numberOfObjects[objectId]--;
	poolManager->recalculateThreads (objectId, numberOfObjects[objectId]);
}

template<int NC>
void ConfiguredThreadedRT<NC>::stopUponCompletion ()
{
	for (int i = 0; i < NC; i++)
	{
		poolManager->getPool ((id_type)i)->stopUponCompletion ();
	}
}

template<int NC>
void ConfiguredThreadedRT<NC>::setupObjectSpecificRuntime (ES::StateMachineRef sm)
{

	sm->setMessageCounter (messages);
	id_type objectId = (id_type)sm->getPoolId ();
	ES::SharedPtr<StateMachineThreadPool> matchedPool = poolManager->getPool (objectId);
	sm->setPool (matchedPool);
	numberOfObjects[objectId]++;
	poolManager->recalculateThreads (objectId, numberOfObjects[objectId]);
}

template<int NC>
bool ConfiguredThreadedRT<NC>::isConfigurated ()
{
	return poolManager->isConfigurated ();
}

template<int NC>
void ConfiguredThreadedRT<NC>::setConfiguration (std::array<ES::SharedPtr<Configuration>, NC> conf)
{
	poolManager->setConfiguration (conf);
	for (id_type i = 0; i < numberOfObjects.size (); ++i) {
		numberOfObjects[i] = 0;
	}
}

}

#endif // RUNTIME_HPP_INCLUDED
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   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.
 *   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 HOLDER 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 "dart/dynamics/Chain.h"
#include "dart/dynamics/FreeJoint.h"

namespace dart {
namespace dynamics {

//==============================================================================
Chain::Criteria::Criteria(BodyNode* _start, BodyNode* _target)
  : mStart(_start),
    mTarget(_target)
{
  // Do nothing
}

//==============================================================================
std::vector<BodyNode*> Chain::Criteria::satisfy() const
{
  return convert().satisfy();
}

//==============================================================================
Linkage::Criteria Chain::Criteria::convert() const
{
  Linkage::Criteria criteria;
  criteria.mStart.mNode = mStart;
  criteria.mTargets.push_back(
        Linkage::Criteria::Target(mTarget.lock(),
                                  Linkage::Criteria::NEUTRAL, true));

  return criteria;
}

//==============================================================================
Chain::Criteria::operator Linkage::Criteria() const
{
  return convert();
}

//==============================================================================
ChainPtr Chain::create(const Chain::Criteria& _criteria,
                       const std::string& _name)
{
  ChainPtr chain = Chain::create(_criteria, _name);
  chain->mPtr = chain;
  return chain;
}

//==============================================================================
ChainPtr Chain::create(BodyNode* _start, BodyNode* _target,
                       const std::string& _name)
{
  ChainPtr chain = Chain::create(_start, _target, _name);
  chain->mPtr = chain;
  return chain;
}

//==============================================================================
bool Chain::isStillChain() const
{
  if(!isAssembled())
    return false;

  // Make sure there are no Branches and no parent FreeJoints on the BodyNodes
  // on the inside of the chain
  for(size_t i=1; i<mBodyNodes.size()-1; ++i)
  {
    if(mBodyNodes[i]->getNumChildBodyNodes() > 1)
      return false;

    if(dynamic_cast<FreeJoint*>(mBodyNodes[i]->getParentJoint()))
      return false;
  }

  // Make sure there is not a FreeJoint at the final BodyNode (which was not
  // tested above)
  if(mBodyNodes.size() > 1)
  {
    if(dynamic_cast<FreeJoint*>(mBodyNodes.back()->getParentJoint()))
      return false;
  }

  return true;
}

//==============================================================================
Chain::Chain(const Chain::Criteria& _criteria, const std::string& _name)
  : Linkage(_criteria, _name)
{
  // Do nothing
}

//==============================================================================
Chain::Chain(BodyNode* _start, BodyNode* _target, const std::string& _name)
  : Linkage(Chain::Criteria(_start, _target), _name)
{
  // Do nothing
}

} // namespace dynamics
} // namespace dart

<commit_msg>fixed silly Chain::create bug<commit_after>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   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.
 *   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 HOLDER 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 "dart/dynamics/Chain.h"
#include "dart/dynamics/FreeJoint.h"

namespace dart {
namespace dynamics {

//==============================================================================
Chain::Criteria::Criteria(BodyNode* _start, BodyNode* _target)
  : mStart(_start),
    mTarget(_target)
{
  // Do nothing
}

//==============================================================================
std::vector<BodyNode*> Chain::Criteria::satisfy() const
{
  return convert().satisfy();
}

//==============================================================================
Linkage::Criteria Chain::Criteria::convert() const
{
  Linkage::Criteria criteria;
  criteria.mStart.mNode = mStart;
  criteria.mTargets.push_back(
        Linkage::Criteria::Target(mTarget.lock(),
                                  Linkage::Criteria::NEUTRAL, true));

  return criteria;
}

//==============================================================================
Chain::Criteria::operator Linkage::Criteria() const
{
  return convert();
}

//==============================================================================
ChainPtr Chain::create(const Chain::Criteria& _criteria,
                       const std::string& _name)
{
  ChainPtr chain(new Chain(_criteria, _name));
  chain->mPtr = chain;
  return chain;
}

//==============================================================================
ChainPtr Chain::create(BodyNode* _start, BodyNode* _target,
                       const std::string& _name)
{
  ChainPtr chain(new Chain(_start, _target, _name));
  chain->mPtr = chain;
  return chain;
}

//==============================================================================
bool Chain::isStillChain() const
{
  if(!isAssembled())
    return false;

  // Make sure there are no Branches and no parent FreeJoints on the BodyNodes
  // on the inside of the chain
  for(size_t i=1; i<mBodyNodes.size()-1; ++i)
  {
    if(mBodyNodes[i]->getNumChildBodyNodes() > 1)
      return false;

    if(dynamic_cast<FreeJoint*>(mBodyNodes[i]->getParentJoint()))
      return false;
  }

  // Make sure there is not a FreeJoint at the final BodyNode (which was not
  // tested above)
  if(mBodyNodes.size() > 1)
  {
    if(dynamic_cast<FreeJoint*>(mBodyNodes.back()->getParentJoint()))
      return false;
  }

  return true;
}

//==============================================================================
Chain::Chain(const Chain::Criteria& _criteria, const std::string& _name)
  : Linkage(_criteria, _name)
{
  // Do nothing
}

//==============================================================================
Chain::Chain(BodyNode* _start, BodyNode* _target, const std::string& _name)
  : Linkage(Chain::Criteria(_start, _target), _name)
{
  // Do nothing
}

} // namespace dynamics
} // namespace dart

<|endoftext|>


<commit_before>#include "MyView.hpp"

// STL headers.
#include <algorithm>
#include <iostream>
#include <vector>

// Engine headers.
#include <tygra/FileHelper.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <Terrain/HeightMap.hpp>

// Constants.
const int kVertexPosition { 0 },
          kVertexNormal   { 1 };

/////////////////////////////////
// Constructors and destructor //
/////////////////////////////////

MyView::MyView (MyView&& move)
{
    *this = std::move (move);
}

MyView& MyView::operator= (MyView&& move)
{
    if (this != &move)
    {
        // TODO: Write the move constructor.
    }

    return *this;
}

////////////////////
// Initialisation //
////////////////////

void MyView::windowViewWillStart (std::shared_ptr<tygra::Window> window)
{
    // Let the framework do it's business, it isn't relevant to us.
    frameworkLoading();

    // Generate the terrain.
    terrainLoading();
}

void MyView::frameworkLoading()
{
    GLint compile_status = 0;
    GLint link_status = 0;
    GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    std::string vertex_shader_string = tygra::stringFromFile("terrain_vs.glsl");
    const char *vertex_shader_code = vertex_shader_string.c_str();
    glShaderSource(vertex_shader, 1,
                   (const GLchar **) &vertex_shader_code, NULL);
    glCompileShader(vertex_shader);
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetShaderInfoLog(vertex_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    std::string fragment_shader_string = tygra::stringFromFile("terrain_fs.glsl");
    const char *fragment_shader_code = fragment_shader_string.c_str();
    glShaderSource(fragment_shader, 1,
                   (const GLchar **) &fragment_shader_code, NULL);
    glCompileShader(fragment_shader);
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetShaderInfoLog(fragment_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    m_terrainShader = glCreateProgram();
    glAttachShader(m_terrainShader, vertex_shader);
    glDeleteShader(vertex_shader);
    glAttachShader(m_terrainShader, fragment_shader);
    glDeleteShader(fragment_shader);
    glLinkProgram(m_terrainShader);
    glGetProgramiv(m_terrainShader, GL_LINK_STATUS, &link_status);
    if (link_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetProgramInfoLog(m_terrainShader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    vertex_shader_string = tygra::stringFromFile("shapes_vs.glsl");
    vertex_shader_code = vertex_shader_string.c_str();
    glShaderSource(vertex_shader, 1,
        (const GLchar **)&vertex_shader_code, NULL);
    glCompileShader(vertex_shader);
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetShaderInfoLog(vertex_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    fragment_shader_string = tygra::stringFromFile("shapes_fs.glsl");
    fragment_shader_code = fragment_shader_string.c_str();
    glShaderSource(fragment_shader, 1,
        (const GLchar **)&fragment_shader_code, NULL);
    glCompileShader(fragment_shader);
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetShaderInfoLog(fragment_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    m_shapesShader = glCreateProgram();
    glAttachShader(m_shapesShader, vertex_shader);
    glDeleteShader(vertex_shader);
    glAttachShader(m_shapesShader, fragment_shader);
    glDeleteShader(fragment_shader);
    glLinkProgram(m_shapesShader);
    glGetProgramiv(m_shapesShader, GL_LINK_STATUS, &link_status);
    if (link_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetProgramInfoLog(m_terrainShader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    glGenVertexArrays(1, &m_cubeVAO);
    glBindVertexArray(m_cubeVAO);
    glGenBuffers(1, &m_cubeVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_cubeVBO);
    float cube_vertices[] = {
        -0.5f, 0.f, -0.5f,   0.5f, 0.f, -0.5f,   0.5f, 0.f,  0.5f,
        -0.5f, 0.f, -0.5f,   0.5f, 0.f,  0.5f,  -0.5f, 0.f,  0.5f,
        -0.5f, 0.f,  0.5f,   0.5f, 0.f,  0.5f,   0.5f, 1.f,  0.5f,
        -0.5f, 0.f,  0.5f,   0.5f, 1.f,  0.5f,  -0.5f, 1.f,  0.5f,
         0.5f, 0.f,  0.5f,   0.5f, 0.f, -0.5f,   0.5f, 1.f, -0.5f,
         0.5f, 0.f,  0.5f,   0.5f, 1.f, -0.5f,   0.5f, 1.f,  0.5f,
         0.5f, 0.f, -0.5f,  -0.5f, 0.f, -0.5f,  -0.5f, 1.f, -0.5f,
         0.5f, 0.f, -0.5f,  -0.5f, 1.f, -0.5f,   0.5f, 1.f, -0.5f,
        -0.5f, 0.f, -0.5f,  -0.5f, 0.f,  0.5f,  -0.5f, 1.f,  0.5f,
        -0.5f, 0.f, -0.5f,  -0.5f, 1.f,  0.5f,  -0.5f, 1.f, -0.5f,
        -0.5f, 1.f,  0.5f,   0.5f, 1.f,  0.5f,   0.5f, 1.f, -0.5f,
        -0.5f, 1.f,  0.5f,   0.5f, 1.f, -0.5f,  -0.5f, 1.f, -0.5f,
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices),
                 cube_vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(kVertexPosition);
    glVertexAttribPointer(kVertexPosition, 3, GL_FLOAT, GL_FALSE,
        sizeof(glm::vec3), TGL_BUFFER_OFFSET(0));
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void MyView::terrainLoading()
{
    // Obtain the terrain properties from the scene information and generate the terrain.
    const auto& file   = m_scene->getTerrainHeightMapName();

    const auto  width  = m_scene->getTerrainSizeX(),
                height = m_scene->getTerrainSizeY(),
                depth  = -m_scene->getTerrainSizeZ();

    // Construct the terrain scalar to get the correct visual output.
    const auto scale = glm::vec3 (width, height, depth);
    //const auto scale = glm::vec3 (256.f, 20.f, -256.f);

    // Load the height map with the desired values.
    const HeightMap heightMap { file, scale };

    // Build the terrain and get it ready for rendering.
    m_terrain.setDivisor (256);
    m_terrain.buildFromHeightMap (heightMap, 4096, 4096);
    m_terrain.prepareForRender (m_terrainShader);
}

//////////////
// Clean up //
//////////////

void MyView::windowViewDidStop (std::shared_ptr<tygra::Window> window)
{
    glDeleteProgram (m_terrainShader);
    glDeleteProgram (m_shapesShader);

    glDeleteBuffers (1, &m_cubeVBO);
    glDeleteVertexArrays (1, &m_cubeVAO);

    m_terrain.cleanUp();
}

///////////////
// Rendering //
///////////////

void MyView::windowViewDidReset (std::shared_ptr<tygra::Window> window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void MyView::windowViewRender (std::shared_ptr<tygra::Window> window)
{
    // Framework crap, not allowed to touch.
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    const float aspect_ratio = viewport[2] / (float)viewport[3];
    const auto& camera = m_scene->getCamera();
    glm::mat4 projection_xform = glm::perspective(camera.getVerticalFieldOfViewInDegrees(),
                                                  aspect_ratio,
                                                  camera.getNearPlaneDistance(),
                                                  camera.getFarPlaneDistance());
    glm::vec3 camera_pos = camera.getPosition();
    glm::vec3 camera_at = camera.getPosition() + camera.getDirection();
    glm::vec3 world_up{ 0, 1, 0 };
    glm::mat4 view_xform = glm::lookAt(camera_pos, camera_at, world_up);

    // Personal crap, I can touch this as much as I want *wink* *wink*.
    glClearColor(0.f, 0.f, 0.25f, 0.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, m_shadeNormals ? GL_FILL : GL_LINE);

    glUseProgram(m_terrainShader);

    GLuint shading_id = glGetUniformLocation(m_terrainShader, "use_normal");
    glUniform1i(shading_id, m_shadeNormals);

    glm::mat4 world_xform = glm::mat4(1);
    glm::mat4 view_world_xform = view_xform * world_xform;

    GLuint projection_xform_id = glGetUniformLocation(m_terrainShader,
                                                      "projection_xform");
    glUniformMatrix4fv(projection_xform_id, 1, GL_FALSE,
                       glm::value_ptr(projection_xform));

    GLuint view_world_xform_id = glGetUniformLocation(m_terrainShader,
                                                      "view_world_xform");
    glUniformMatrix4fv(view_world_xform_id, 1, GL_FALSE,
                       glm::value_ptr(view_world_xform));

    m_terrain.draw();
    //glBindVertexArray(m_terrainMesh.vao);
    //glDrawElements(GL_TRIANGLES, m_terrainMesh.element_count, GL_UNSIGNED_INT, 0);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    glUseProgram(m_shapesShader);

    projection_xform_id = glGetUniformLocation(m_shapesShader,
                                               "projection_xform");
    glUniformMatrix4fv(projection_xform_id, 1, GL_FALSE,
                       glm::value_ptr(projection_xform));

    glBindVertexArray(m_cubeVAO);

    for (const auto& pos : m_scene->getAllShapePositions())
    {
        world_xform = glm::translate(glm::mat4(1), glm::vec3(pos.x, 64, -pos.y));
        view_world_xform = view_xform * world_xform;

        view_world_xform_id = glGetUniformLocation(m_shapesShader,
                                                   "view_world_xform");
        glUniformMatrix4fv(view_world_xform_id, 1, GL_FALSE,
                           glm::value_ptr(view_world_xform));

        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}<commit_msg>Made it easier to change the scale and maintain the same noise.<commit_after>#include "MyView.hpp"

// STL headers.
#include <algorithm>
#include <iostream>
#include <vector>

// Engine headers.
#include <tygra/FileHelper.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <Terrain/HeightMap.hpp>

// Constants.
const int kVertexPosition { 0 },
          kVertexNormal   { 1 };

/////////////////////////////////
// Constructors and destructor //
/////////////////////////////////

MyView::MyView (MyView&& move)
{
    *this = std::move (move);
}

MyView& MyView::operator= (MyView&& move)
{
    if (this != &move)
    {
        // TODO: Write the move constructor.
    }

    return *this;
}

////////////////////
// Initialisation //
////////////////////

void MyView::windowViewWillStart (std::shared_ptr<tygra::Window> window)
{
    // Let the framework do it's business, it isn't relevant to us.
    frameworkLoading();

    // Generate the terrain.
    terrainLoading();
}

void MyView::frameworkLoading()
{
    GLint compile_status = 0;
    GLint link_status = 0;
    GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    std::string vertex_shader_string = tygra::stringFromFile("terrain_vs.glsl");
    const char *vertex_shader_code = vertex_shader_string.c_str();
    glShaderSource(vertex_shader, 1,
                   (const GLchar **) &vertex_shader_code, NULL);
    glCompileShader(vertex_shader);
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetShaderInfoLog(vertex_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    std::string fragment_shader_string = tygra::stringFromFile("terrain_fs.glsl");
    const char *fragment_shader_code = fragment_shader_string.c_str();
    glShaderSource(fragment_shader, 1,
                   (const GLchar **) &fragment_shader_code, NULL);
    glCompileShader(fragment_shader);
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetShaderInfoLog(fragment_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    m_terrainShader = glCreateProgram();
    glAttachShader(m_terrainShader, vertex_shader);
    glDeleteShader(vertex_shader);
    glAttachShader(m_terrainShader, fragment_shader);
    glDeleteShader(fragment_shader);
    glLinkProgram(m_terrainShader);
    glGetProgramiv(m_terrainShader, GL_LINK_STATUS, &link_status);
    if (link_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length]= "";
        glGetProgramInfoLog(m_terrainShader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    vertex_shader_string = tygra::stringFromFile("shapes_vs.glsl");
    vertex_shader_code = vertex_shader_string.c_str();
    glShaderSource(vertex_shader, 1,
        (const GLchar **)&vertex_shader_code, NULL);
    glCompileShader(vertex_shader);
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetShaderInfoLog(vertex_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    fragment_shader_string = tygra::stringFromFile("shapes_fs.glsl");
    fragment_shader_code = fragment_shader_string.c_str();
    glShaderSource(fragment_shader, 1,
        (const GLchar **)&fragment_shader_code, NULL);
    glCompileShader(fragment_shader);
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
    if (compile_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetShaderInfoLog(fragment_shader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    m_shapesShader = glCreateProgram();
    glAttachShader(m_shapesShader, vertex_shader);
    glDeleteShader(vertex_shader);
    glAttachShader(m_shapesShader, fragment_shader);
    glDeleteShader(fragment_shader);
    glLinkProgram(m_shapesShader);
    glGetProgramiv(m_shapesShader, GL_LINK_STATUS, &link_status);
    if (link_status != GL_TRUE) {
        const int string_length = 1024;
        GLchar log[string_length] = "";
        glGetProgramInfoLog(m_terrainShader, string_length, NULL, log);
        std::cerr << log << std::endl;
    }
    glGenVertexArrays(1, &m_cubeVAO);
    glBindVertexArray(m_cubeVAO);
    glGenBuffers(1, &m_cubeVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_cubeVBO);
    float cube_vertices[] = {
        -0.5f, 0.f, -0.5f,   0.5f, 0.f, -0.5f,   0.5f, 0.f,  0.5f,
        -0.5f, 0.f, -0.5f,   0.5f, 0.f,  0.5f,  -0.5f, 0.f,  0.5f,
        -0.5f, 0.f,  0.5f,   0.5f, 0.f,  0.5f,   0.5f, 1.f,  0.5f,
        -0.5f, 0.f,  0.5f,   0.5f, 1.f,  0.5f,  -0.5f, 1.f,  0.5f,
         0.5f, 0.f,  0.5f,   0.5f, 0.f, -0.5f,   0.5f, 1.f, -0.5f,
         0.5f, 0.f,  0.5f,   0.5f, 1.f, -0.5f,   0.5f, 1.f,  0.5f,
         0.5f, 0.f, -0.5f,  -0.5f, 0.f, -0.5f,  -0.5f, 1.f, -0.5f,
         0.5f, 0.f, -0.5f,  -0.5f, 1.f, -0.5f,   0.5f, 1.f, -0.5f,
        -0.5f, 0.f, -0.5f,  -0.5f, 0.f,  0.5f,  -0.5f, 1.f,  0.5f,
        -0.5f, 0.f, -0.5f,  -0.5f, 1.f,  0.5f,  -0.5f, 1.f, -0.5f,
        -0.5f, 1.f,  0.5f,   0.5f, 1.f,  0.5f,   0.5f, 1.f, -0.5f,
        -0.5f, 1.f,  0.5f,   0.5f, 1.f, -0.5f,  -0.5f, 1.f, -0.5f,
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices),
                 cube_vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(kVertexPosition);
    glVertexAttribPointer(kVertexPosition, 3, GL_FLOAT, GL_FALSE,
        sizeof(glm::vec3), TGL_BUFFER_OFFSET(0));
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void MyView::terrainLoading()
{
    // Obtain the terrain properties from the scene information and generate the terrain.
    const auto& file   = m_scene->getTerrainHeightMapName();

    const auto  width  = m_scene->getTerrainSizeX(),
                height = m_scene->getTerrainSizeY(),
                depth  = -m_scene->getTerrainSizeZ();

    const auto  shrink = 8U;

    // Construct the terrain scalar to get the correct visual output.
    const auto scale = glm::vec3 (width, height, depth);

    // Load the height map with the desired values.
    const HeightMap heightMap { file, scale / (float) shrink };

    // Build the terrain and get it ready for rendering.
    m_terrain.setDivisor (256);
    m_terrain.buildFromHeightMap (heightMap, 8192U / shrink, 8192U / shrink);
    m_terrain.prepareForRender (m_terrainShader);
}

//////////////
// Clean up //
//////////////

void MyView::windowViewDidStop (std::shared_ptr<tygra::Window> window)
{
    glDeleteProgram (m_terrainShader);
    glDeleteProgram (m_shapesShader);

    glDeleteBuffers (1, &m_cubeVBO);
    glDeleteVertexArrays (1, &m_cubeVAO);

    m_terrain.cleanUp();
}

///////////////
// Rendering //
///////////////

void MyView::windowViewDidReset (std::shared_ptr<tygra::Window> window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void MyView::windowViewRender (std::shared_ptr<tygra::Window> window)
{
    // Framework crap, not allowed to touch.
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    const float aspect_ratio = viewport[2] / (float)viewport[3];
    const auto& camera = m_scene->getCamera();
    glm::mat4 projection_xform = glm::perspective(camera.getVerticalFieldOfViewInDegrees(),
                                                  aspect_ratio,
                                                  camera.getNearPlaneDistance(),
                                                  camera.getFarPlaneDistance());
    glm::vec3 camera_pos = camera.getPosition();
    glm::vec3 camera_at = camera.getPosition() + camera.getDirection();
    glm::vec3 world_up{ 0, 1, 0 };
    glm::mat4 view_xform = glm::lookAt(camera_pos, camera_at, world_up);

    // Personal crap, I can touch this as much as I want *wink* *wink*.
    glClearColor(0.f, 0.f, 0.25f, 0.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, m_shadeNormals ? GL_FILL : GL_LINE);

    glUseProgram(m_terrainShader);

    GLuint shading_id = glGetUniformLocation(m_terrainShader, "use_normal");
    glUniform1i(shading_id, m_shadeNormals);

    glm::mat4 world_xform = glm::mat4(1);
    glm::mat4 view_world_xform = view_xform * world_xform;

    GLuint projection_xform_id = glGetUniformLocation(m_terrainShader,
                                                      "projection_xform");
    glUniformMatrix4fv(projection_xform_id, 1, GL_FALSE,
                       glm::value_ptr(projection_xform));

    GLuint view_world_xform_id = glGetUniformLocation(m_terrainShader,
                                                      "view_world_xform");
    glUniformMatrix4fv(view_world_xform_id, 1, GL_FALSE,
                       glm::value_ptr(view_world_xform));

    m_terrain.draw();
    //glBindVertexArray(m_terrainMesh.vao);
    //glDrawElements(GL_TRIANGLES, m_terrainMesh.element_count, GL_UNSIGNED_INT, 0);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    glUseProgram(m_shapesShader);

    projection_xform_id = glGetUniformLocation(m_shapesShader,
                                               "projection_xform");
    glUniformMatrix4fv(projection_xform_id, 1, GL_FALSE,
                       glm::value_ptr(projection_xform));

    glBindVertexArray(m_cubeVAO);

    for (const auto& pos : m_scene->getAllShapePositions())
    {
        world_xform = glm::translate(glm::mat4(1), glm::vec3(pos.x, 64, -pos.y));
        view_world_xform = view_xform * world_xform;

        view_world_xform_id = glGetUniformLocation(m_shapesShader,
                                                   "view_world_xform");
        glUniformMatrix4fv(view_world_xform_id, 1, GL_FALSE,
                           glm::value_ptr(view_world_xform));

        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}<|endoftext|>


<commit_before>/*
 * Copyright 2009, 2010 Google Inc.
 *
 * 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 <esnpapi.h>
#include <org/w3c/dom.h>

#include <assert.h>

std::map<const std::string, Object* (*)(ProxyObject object)> ProxyControl::proxyConstructorMap;

ProxyControl::ProxyControl(NPP npp) :
    npp(npp),
    nestingCount(1)
{
}

ProxyControl::~ProxyControl()
{
    // TODO: Release objects in newList and oldList
}

Object* ProxyControl::createProxy(NPObject* object, const Reflect::Type type)
{
    if (!object)
    {
        return 0;
    }

    std::string className = getInterfaceName(npp, object);
    if (className == "Object")
    {
        // TODO: We should define 'Object' interface
        return 0;
    }

    bool usedHint = false;
    for (;;)
    {
        std::map<const std::string, Object* (*)(ProxyObject object)>::iterator it;
        it = proxyConstructorMap.find(className);
        if (it != proxyConstructorMap.end())
        {
            ProxyObject browserObject(object, npp);
            if (Object* object = (*it).second(browserObject))
            {
                return track(object);
            }
        }
        if (!type.isObject() || usedHint)
        {
            break;
        }
        className = type.getQualifiedName();
        size_t pos = className.rfind(':');
        if (pos != std::string::npos)
        {
            className = className.substr(pos + 1);
            printf("%s: use the class name '%s' as hinted.\n", __func__, className.c_str());
        }
        usedHint = true;
    }
    return 0;
}

long ProxyControl::enter()
{
    return ++nestingCount;
}

long ProxyControl::leave()
{
    --nestingCount;
    assert(0 <= nestingCount);
    if (nestingCount == 0)
    {
        while (!newList.empty())
        {
            Object* object = newList.front();
            newList.pop_front();
            if (0 < object->release())
            {
                oldList.push_back(object);
            }
        }
    }
    return nestingCount;
}

void ProxyControl::registerMetaData(const char* meta, Object* (*createProxy)(ProxyObject object), const char* alias)
{
    Reflect::Interface interface(meta);
    std::string name = interface.getName();
    if (alias)
    {
        name = alias;
    }
    proxyConstructorMap[name] = createProxy;
    printf("%s\n", name.c_str());
}

ProxyObject::ProxyObject(NPObject* object, NPP npp) :
    object(object),
    npp(npp),
    count(0)
{
}

ProxyObject::ProxyObject(const ProxyObject& original) :
    object(original.object),
    npp(original.npp),
    count(original.count)
{
}

ProxyObject::~ProxyObject()
{
    // TODO: Remove this from newList or oldList is it is still included
}

unsigned int ProxyObject::retain()
{
    NPN_RetainObject(object);
    return ++count;
}

unsigned int ProxyObject::release()
{
    if (0 < count)
    {
        NPN_ReleaseObject(object);
        --count;
    }
    if (count == 0)
    {
        delete this;
        return 0;
    }
    return count;
}

unsigned int ProxyObject::mark()
{
    return ++count;
}

PluginInstance::PluginInstance(NPP npp, NPObject* window) :
    proxyControl(npp),
    stubControl(npp),
    window(0)
{
    npp->pdata = this;
    this->window = interface_cast<org::w3c::dom::html::Window*>(proxyControl.createProxy(window, Reflect::Type("O14::html::Window")));
    if (this->window)
    {
        ProxyObject* proxy = interface_cast<ProxyObject*>(this->window);
        proxy->mark();
        proxy->retain();
    }
}

PluginInstance::~PluginInstance()
{
    if (window)
    {
        window->release();
    }
}

<commit_msg>(~ProxyObject) : Fix a typo.<commit_after>/*
 * Copyright 2009, 2010 Google Inc.
 *
 * 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 <esnpapi.h>
#include <org/w3c/dom.h>

#include <assert.h>

std::map<const std::string, Object* (*)(ProxyObject object)> ProxyControl::proxyConstructorMap;

ProxyControl::ProxyControl(NPP npp) :
    npp(npp),
    nestingCount(1)
{
}

ProxyControl::~ProxyControl()
{
    // TODO: Release objects in newList and oldList
}

Object* ProxyControl::createProxy(NPObject* object, const Reflect::Type type)
{
    if (!object)
    {
        return 0;
    }

    std::string className = getInterfaceName(npp, object);
    if (className == "Object")
    {
        // TODO: We should define 'Object' interface
        return 0;
    }

    bool usedHint = false;
    for (;;)
    {
        std::map<const std::string, Object* (*)(ProxyObject object)>::iterator it;
        it = proxyConstructorMap.find(className);
        if (it != proxyConstructorMap.end())
        {
            ProxyObject browserObject(object, npp);
            if (Object* object = (*it).second(browserObject))
            {
                return track(object);
            }
        }
        if (!type.isObject() || usedHint)
        {
            break;
        }
        className = type.getQualifiedName();
        size_t pos = className.rfind(':');
        if (pos != std::string::npos)
        {
            className = className.substr(pos + 1);
            printf("%s: use the class name '%s' as hinted.\n", __func__, className.c_str());
        }
        usedHint = true;
    }
    return 0;
}

long ProxyControl::enter()
{
    return ++nestingCount;
}

long ProxyControl::leave()
{
    --nestingCount;
    assert(0 <= nestingCount);
    if (nestingCount == 0)
    {
        while (!newList.empty())
        {
            Object* object = newList.front();
            newList.pop_front();
            if (0 < object->release())
            {
                oldList.push_back(object);
            }
        }
    }
    return nestingCount;
}

void ProxyControl::registerMetaData(const char* meta, Object* (*createProxy)(ProxyObject object), const char* alias)
{
    Reflect::Interface interface(meta);
    std::string name = interface.getName();
    if (alias)
    {
        name = alias;
    }
    proxyConstructorMap[name] = createProxy;
    printf("%s\n", name.c_str());
}

ProxyObject::ProxyObject(NPObject* object, NPP npp) :
    object(object),
    npp(npp),
    count(0)
{
}

ProxyObject::ProxyObject(const ProxyObject& original) :
    object(original.object),
    npp(original.npp),
    count(original.count)
{
}

ProxyObject::~ProxyObject()
{
    // TODO: Remove this from newList or oldList if it is still included
}

unsigned int ProxyObject::retain()
{
    NPN_RetainObject(object);
    return ++count;
}

unsigned int ProxyObject::release()
{
    if (0 < count)
    {
        NPN_ReleaseObject(object);
        --count;
    }
    if (count == 0)
    {
        delete this;
        return 0;
    }
    return count;
}

unsigned int ProxyObject::mark()
{
    return ++count;
}

PluginInstance::PluginInstance(NPP npp, NPObject* window) :
    proxyControl(npp),
    stubControl(npp),
    window(0)
{
    npp->pdata = this;
    this->window = interface_cast<org::w3c::dom::html::Window*>(proxyControl.createProxy(window, Reflect::Type("O14::html::Window")));
    if (this->window)
    {
        ProxyObject* proxy = interface_cast<ProxyObject*>(this->window);
        proxy->mark();
        proxy->retain();
    }
}

PluginInstance::~PluginInstance()
{
    if (window)
    {
        window->release();
    }
}

<|endoftext|>


<commit_before>/**
 ** \file object/primitive-class.cc
 ** \brief Creation of the URBI object primitive.
 */

#include "object/primitive-class.hh"
#include "object/object.hh"

namespace object
{
  rObject primitive_class;

  /*-----------------------.
  | Primitive primitives.  |
  `-----------------------*/

  void
  primitive_class_initialize ()
  {
  }

}; // namespace object
<commit_msg>Implement apply() for primitives<commit_after>/**
 ** \file object/primitive-class.cc
 ** \brief Creation of the URBI object primitive.
 */

#include "object/primitive-class.hh"
#include "object/atom.hh"
#include "object/object.hh"

#include "runner/runner.hh"

namespace object
{
  rObject primitive_class;

  /*-----------------------.
  | Primitive primitives.  |
  `-----------------------*/

  static rObject
  primitive_class_apply (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG (1, List);
    return r.apply (args[0], arg1);
  }

  void
  primitive_class_initialize ()
  {
#define DECLARE(Name)				\
    DECLARE_PRIMITIVE(primitive, Name)
    DECLARE (apply);
#undef DECLARE
  }

}; // namespace object
<|endoftext|>


<commit_before>#pragma once

#include "Material.hpp"

namespace RealRT
{

    class PhongMaterial : public Material
    {
        public:

            PhongMaterial(const Vector3D &color, float reflectance, float refractance, float indexOfRefraction, float diffuseScalar, float specularScalar);

            float BidirectionReflectanceDistributionFunction(const Vector3D &in, const Vector3D &out, const Vector3D &norm) const;
    };

    //some material definitions
    const PhongMaterial DiffuseRed(Vector3D(0.9f,0.1f,0.1f),0.1f,0.0f,0.0f,0.9f,0.2f);
    const PhongMaterial DiffuseGreen(Vector3D(0.1f,0.9f,0.1f),0.1f,0.0f,0.0f,0.9f,0.2f);
    const PhongMaterial DiffuseBlue(Vector3D(0.1f,0.1f,0.9f),0.1f,0.0f,0.0f,0.9f,0.2f);

    const PhongMaterial ReflectiveRed(Vector3D(0.9f,0.1f,0.1f),0.9f,0.0f,0.0f,0.1f,0.9f);
    const PhongMaterial ReflectiveGreen(Vector3D(0.1f,0.9f,0.1f),0.9f,0.0f,0.0f,0.1f,0.9f);
    const PhongMaterial ReflectiveBlue(Vector3D(0.1f,0.1f,0.9f),0.9f,0.0f,0.0f,0.1f,0.9f);

    const PhongMaterial Mirror(Vector3D(1.0f,1.0f,1.0f),0.9f,0.0f,0.0f,0.1f,0.9f);

    const PhongMaterial TranslucentGreen(Vector3D(0.1f,0.9f,0.2f),0.5f,0.0f,0.0f,0.1f,0.9f);
    const PhongMaterial TranslucentRed(Vector3D(0.9f,0.2f,0.1f),0.5f,0.0f,0.0f,0.0f,1.9f);
    const PhongMaterial TranslucentBlue(Vector3D(0.2f,0.1f,0.9f),0.5f,0.0f,0.0f,0.1f,0.9f);

    const PhongMaterial Transparent(Vector3D(1.0f,1.0f,1.0f),0.5f,0.9f,1.0f,0.0f,0.9f);

    const PhongMaterial WhiteLight(Vector3D(1.0f,1.0f,1.0f),0.0f,0.0f,0.0f,1.0f,0.0f);

    const PhongMaterial Blank(Vector3D(0.0f,0.0f,0.0f),0.0f,0.0f,0.0f,0.0f,0.0f);

}
<commit_msg>Updated material definitions to shared_ptr <commit_after>#pragma once

#include "Material.hpp"
#include <memory>

namespace RealRT
{

    class PhongMaterial : public Material
    {
        public:

            PhongMaterial(const Vector3D &color, float reflectance, float refractance, float indexOfRefraction, float diffuseScalar, float specularScalar);

            float BidirectionReflectanceDistributionFunction(const Vector3D &in, const Vector3D &out, const Vector3D &norm) const;
    };

    //some material definitions
    const std::shared_ptr<Material> DiffuseRed = std::make_shared<PhongMaterial>(Vector3D(0.9f,0.1f,0.1f),0.1f,0.0f,0.0f,0.9f,0.2f);
    const std::shared_ptr<Material> DiffuseGreen = std::make_shared<PhongMaterial>(Vector3D(0.1f,0.9f,0.1f),0.1f,0.0f,0.0f,0.9f,0.2f);
    const std::shared_ptr<Material> DiffuseBlue = std::make_shared<PhongMaterial>(Vector3D(0.1f,0.1f,0.9f),0.1f,0.0f,0.0f,0.9f,0.2f);

    const std::shared_ptr<Material> ReflectiveRed = std::make_shared<PhongMaterial>(Vector3D(0.9f,0.1f,0.1f),0.9f,0.0f,0.0f,0.1f,0.9f);
    const std::shared_ptr<Material> ReflectiveGreen = std::make_shared<PhongMaterial>(Vector3D(0.1f,0.9f,0.1f),0.9f,0.0f,0.0f,0.1f,0.9f);
    const std::shared_ptr<Material> ReflectiveBlue = std::make_shared<PhongMaterial>(Vector3D(0.1f,0.1f,0.9f),0.9f,0.0f,0.0f,0.1f,0.9f);

    const std::shared_ptr<Material> Mirror = std::make_shared<PhongMaterial>(Vector3D(1.0f,1.0f,1.0f),0.9f,0.0f,0.0f,0.1f,0.9f);

    const std::shared_ptr<Material> TranslucentGreen = std::make_shared<PhongMaterial>(Vector3D(0.1f,0.9f,0.2f),0.5f,0.0f,0.0f,0.1f,0.9f);
    const std::shared_ptr<Material> TranslucentRed = std::make_shared<PhongMaterial>(Vector3D(0.9f,0.2f,0.1f),0.5f,0.0f,0.0f,0.0f,1.9f);
    const std::shared_ptr<Material> TranslucentBlue = std::make_shared<PhongMaterial>(Vector3D(0.2f,0.1f,0.9f),0.5f,0.0f,0.0f,0.1f,0.9f);

    const std::shared_ptr<Material> Transparent = std::make_shared<PhongMaterial>(Vector3D(1.0f,1.0f,1.0f),0.5f,0.9f,1.0f,0.0f,0.9f);

    const std::shared_ptr<Material> WhiteLight = std::make_shared<PhongMaterial>(Vector3D(1.0f,1.0f,1.0f),0.0f,0.0f,0.0f,1.0f,0.0f);

    const std::shared_ptr<Material> Blank = std::make_shared<PhongMaterial>(Vector3D(0.0f,0.0f,0.0f),0.0f,0.0f,0.0f,0.0f,0.0f);

}
<|endoftext|>


<commit_before>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2015.  ALL RIGHTS RESERVED.
*
* $COPYRIGHT$
* $HEADER$
*/

#include "uct_test.h"
extern "C" {
#include <ucs/time/time.h>
#include <ucs/datastruct/queue.h>
#include "uct/ib/ud/ud_def.h"
#include "uct/ib/ud/ud_ep.h"
#include "uct/ib/ud/ud_iface.h"
};
/* test ud connect data structures */
class test_ud_ds : public uct_test {
public:
    virtual void init() {
        uct_test::init();

        m_e1 = new entity(GetParam(), 0);
        m_e2 = new entity(GetParam(), 0);

        uct_iface_get_address(m_e1->iface(), &adr1.super);
        uct_iface_get_address(m_e2->iface(), &adr2.super);
    }
    uct_ud_iface_t *iface(entity *e) {
        return ucs_derived_of(e->iface(), uct_ud_iface_t);
    }

    uct_ud_ep_t *ep(entity *e, int i) {
        return ucs_derived_of(e->ep(i), uct_ud_ep_t);
    }

    void cleanup() {
        uct_test::cleanup();
    }

    void test_cep_insert(entity *e, uct_ud_iface_addr_t *adr);

protected:
    entity *m_e1, *m_e2;
    uct_ud_iface_addr_t adr1, adr2;
    static int N;
};

int test_ud_ds::N = 1000;

UCS_TEST_P(test_ud_ds, if_addr) {
    EXPECT_EQ(adr1.lid, adr2.lid);
    EXPECT_NE(adr1.qp_num, adr2.qp_num);
}

void test_ud_ds::test_cep_insert(entity *e, uct_ud_iface_addr_t *adr)
{
    int i;
    uct_ud_ep_t *my_ep;

    for (i = 0; i < N; i++) {
        e->add_ep();
        //printf("ep id: %d", ep(e, i)->ep_id);
        EXPECT_EQ(ep(e, i)->ep_id, i);
        EXPECT_EQ(ep(e, i)->dest_ep_id, UCT_UD_EP_NULL_ID);
        EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(e), adr, ep(e, i), UCT_UD_EP_CONN_ID_MAX));
        EXPECT_EQ(ep(e, i)->conn_id, i);
    }
    /* lookup non existing ep */
    my_ep = uct_ud_iface_cep_lookup(iface(e), adr, 3333);
    EXPECT_TRUE(my_ep == NULL);
    for (i = 0; i < N; i++) {
        my_ep = uct_ud_iface_cep_lookup(iface(e), adr, i);
        EXPECT_TRUE(my_ep != NULL);
        EXPECT_EQ(ep(e, i)->ep_id, i);
        EXPECT_EQ(ep(e, i)->conn_id, i);
    }
}

/* simulate creq send */
UCS_TEST_P(test_ud_ds, cep_insert) {
    test_cep_insert(m_e1, &adr1);
    test_cep_insert(m_e1, &adr2);
}

UCS_TEST_P(test_ud_ds, cep_replace) {

    uct_ud_ep_t *my_ep;

    /* add N connections */
    test_cep_insert(m_e1, &adr1);

    /* Assume that we have 5 connections pending and 3 CREQs received */
    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N), N+1));
    EXPECT_EQ(ep(m_e1, N)->conn_id, N+1);

    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+1), N+4));
    EXPECT_EQ(ep(m_e1, N+1)->conn_id, N+4);

    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+2), N+5));
    EXPECT_EQ(ep(m_e1, N+2)->conn_id, N+5);

    /* we initiate 2 connections */
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, UCT_UD_EP_CONN_ID_MAX);
    EXPECT_TRUE(my_ep == NULL);
    m_e1->add_ep();
    /* slot N must be free. conn_id will be N+1 when inserting ep with no id */
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+3), UCT_UD_EP_CONN_ID_MAX));
    EXPECT_EQ(ep(m_e1, N+3)->conn_id, N);

    /* slot N+1 already occupied */
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, UCT_UD_EP_CONN_ID_MAX);
    EXPECT_TRUE(my_ep != NULL);
    EXPECT_EQ(my_ep->conn_id, N+1);

    /* replace ep */
    m_e1->add_ep();
    ep(m_e1, N+4)->conn_id = my_ep->conn_id;
    uct_ud_iface_cep_replace(my_ep, ep(m_e1, N+4), uct_ud_ep_cp);
    EXPECT_EQ(ep(m_e1, N+4)->dest_if->conn_id_last, N+2);
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, N+1);
    EXPECT_TRUE(my_ep != NULL);
    EXPECT_EQ(my_ep, ep(m_e1, N+4));
}

_UCT_INSTANTIATE_TEST_CASE(test_ud_ds, ud)

<commit_msg>GTEST/UD: fixes compilation error<commit_after>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2015.  ALL RIGHTS RESERVED.
*
* $COPYRIGHT$
* $HEADER$
*/

#include "uct_test.h"
extern "C" {
#include <ucs/time/time.h>
#include <ucs/datastruct/queue.h>
#include "uct/ib/ud/ud_def.h"
#include "uct/ib/ud/ud_ep.h"
#include "uct/ib/ud/ud_iface.h"
};
/* test ud connect data structures */
class test_ud_ds : public uct_test {
public:
    virtual void init() {
        uct_test::init();

        m_e1 = create_entity(0);
        m_e2 = create_entity(0);

        uct_iface_get_address(m_e1->iface(), &adr1.super);
        uct_iface_get_address(m_e2->iface(), &adr2.super);
    }
    uct_ud_iface_t *iface(entity *e) {
        return ucs_derived_of(e->iface(), uct_ud_iface_t);
    }

    uct_ud_ep_t *ep(entity *e, int i) {
        return ucs_derived_of(e->ep(i), uct_ud_ep_t);
    }

    void cleanup() {
        uct_test::cleanup();
    }

    void test_cep_insert(entity *e, uct_ud_iface_addr_t *adr);

protected:
    entity *m_e1, *m_e2;
    uct_ud_iface_addr_t adr1, adr2;
    static int N;
};

int test_ud_ds::N = 1000;

UCS_TEST_P(test_ud_ds, if_addr) {
    EXPECT_EQ(adr1.lid, adr2.lid);
    EXPECT_NE(adr1.qp_num, adr2.qp_num);
}

void test_ud_ds::test_cep_insert(entity *e, uct_ud_iface_addr_t *adr)
{
    int i;
    uct_ud_ep_t *my_ep;

    for (i = 0; i < N; i++) {
        e->add_ep();
        //printf("ep id: %d", ep(e, i)->ep_id);
        EXPECT_EQ(ep(e, i)->ep_id, i);
        EXPECT_EQ(ep(e, i)->dest_ep_id, UCT_UD_EP_NULL_ID);
        EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(e), adr, ep(e, i), UCT_UD_EP_CONN_ID_MAX));
        EXPECT_EQ(ep(e, i)->conn_id, i);
    }
    /* lookup non existing ep */
    my_ep = uct_ud_iface_cep_lookup(iface(e), adr, 3333);
    EXPECT_TRUE(my_ep == NULL);
    for (i = 0; i < N; i++) {
        my_ep = uct_ud_iface_cep_lookup(iface(e), adr, i);
        EXPECT_TRUE(my_ep != NULL);
        EXPECT_EQ(ep(e, i)->ep_id, i);
        EXPECT_EQ(ep(e, i)->conn_id, i);
    }
}

/* simulate creq send */
UCS_TEST_P(test_ud_ds, cep_insert) {
    test_cep_insert(m_e1, &adr1);
    test_cep_insert(m_e1, &adr2);
}

UCS_TEST_P(test_ud_ds, cep_replace) {

    uct_ud_ep_t *my_ep;

    /* add N connections */
    test_cep_insert(m_e1, &adr1);

    /* Assume that we have 5 connections pending and 3 CREQs received */
    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N), N+1));
    EXPECT_EQ(ep(m_e1, N)->conn_id, N+1);

    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+1), N+4));
    EXPECT_EQ(ep(m_e1, N+1)->conn_id, N+4);

    m_e1->add_ep();
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+2), N+5));
    EXPECT_EQ(ep(m_e1, N+2)->conn_id, N+5);

    /* we initiate 2 connections */
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, UCT_UD_EP_CONN_ID_MAX);
    EXPECT_TRUE(my_ep == NULL);
    m_e1->add_ep();
    /* slot N must be free. conn_id will be N+1 when inserting ep with no id */
    EXPECT_UCS_OK(uct_ud_iface_cep_insert(iface(m_e1), &adr1, ep(m_e1, N+3), UCT_UD_EP_CONN_ID_MAX));
    EXPECT_EQ(ep(m_e1, N+3)->conn_id, N);

    /* slot N+1 already occupied */
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, UCT_UD_EP_CONN_ID_MAX);
    EXPECT_TRUE(my_ep != NULL);
    EXPECT_EQ(my_ep->conn_id, N+1);

    /* replace ep */
    m_e1->add_ep();
    ep(m_e1, N+4)->conn_id = my_ep->conn_id;
    uct_ud_iface_cep_replace(my_ep, ep(m_e1, N+4), uct_ud_ep_clone);
    EXPECT_EQ(ep(m_e1, N+4)->dest_if->conn_id_last, N+2);
    my_ep = uct_ud_iface_cep_lookup(iface(m_e1), &adr1, N+1);
    EXPECT_TRUE(my_ep != NULL);
    EXPECT_EQ(my_ep, ep(m_e1, N+4));
}

_UCT_INSTANTIATE_TEST_CASE(test_ud_ds, ud)

<|endoftext|>


<commit_before>/* **********************************************************
 * Copyright (c) 2015 Google, 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 Google, Inc. nor the names of its contributors 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 GOOGLE, INC. 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.
 */

/* Test parsing options.
 */

#include "dr_api.h"
#include "client_tools.h"
#include "droption.h"
#include <string.h>

static droption_t<unsigned int> op_x
(DROPTION_SCOPE_CLIENT, "x", 0, 0, 64, "Some param",
 "Longer desc of some param.");
static droption_t<std::string> op_y
(DROPTION_SCOPE_CLIENT, "y", DROPTION_FLAG_ACCUMULATE, "<default>", "Another param",
 "Longer desc of another param.");
static droption_t<std::string> op_z
(DROPTION_SCOPE_CLIENT, "z", "", "Yet another param",
 "Longer desc of yet another param.");
static droption_t<int> op_foo
(DROPTION_SCOPE_CLIENT, "foo", 8, "Missing param",
 "Longer desc of missing param.");
static droption_t<std::string> op_bar
(DROPTION_SCOPE_CLIENT, "bar", "some string with spaces", "Missing string param",
 "Longer desc of missing string param.");
static droption_t<bool> op_flag
(DROPTION_SCOPE_CLIENT, "flag", true, "Bool param",
 "Longer desc of bool param.");
static droption_t<std::string> op_sweep
(DROPTION_SCOPE_CLIENT, "sweep", DROPTION_FLAG_SWEEP | DROPTION_FLAG_ACCUMULATE,
 "", "All the unknown params",
 "Longer desc of unknown param accum.");
static droption_t<std::string> op_front
(DROPTION_SCOPE_FRONTEND, "front", "", "Front-end param",
 "Longer desc of front-end param.");
static droption_t<std::string> op_front2
(DROPTION_SCOPE_FRONTEND, "front2", "", "Front-end param2",
 "Longer desc of front-end param2.");

DR_EXPORT void
dr_init(client_id_t client_id)
{
    // Test dr_get_option_array().
    int argc;
    const char **argv;
    bool ok = dr_get_option_array(client_id, &argc, &argv, MAXIMUM_PATH);
    ASSERT(ok);
    ASSERT(argc == 16);
    ASSERT(strcmp(argv[1], "-x") == 0);
    ASSERT(strcmp(argv[2], "4") == 0);
    ASSERT(strcmp(argv[3], "-y") == 0);
    ASSERT(strcmp(argv[4], "quoted string") == 0);
    ASSERT(strcmp(argv[5], "-z") == 0);
    ASSERT(strcmp(argv[6], "first") == 0);
    ASSERT(strcmp(argv[7], "-z") == 0);
    ASSERT(strcmp(argv[8], "single quotes -dash --dashes") == 0);
    ASSERT(strcmp(argv[9], "-front") == 0);
    ASSERT(strcmp(argv[10], "value") == 0);
    ASSERT(strcmp(argv[11], "-y") == 0);
    ASSERT(strcmp(argv[12], "accum") == 0);
    ASSERT(strcmp(argv[13], "-front2") == 0);
    ASSERT(strcmp(argv[14], "value2") == 0);
    ASSERT(strcmp(argv[15], "-no_flag") == 0);
    ok = dr_free_option_array(argc, argv);
    ASSERT(ok);

    // Test dr_parse_options() and droption_t declarations above.
    ok = dr_parse_options(client_id, NULL, NULL);
    ASSERT(ok);
    ASSERT(op_x.specified());
    ASSERT(op_y.specified());
    ASSERT(op_z.specified());
    dr_printf("param x = %d\n", op_x.get_value());
    dr_printf("param y = |%s|\n", op_y.get_value().c_str());
    dr_printf("param z = |%s|\n", op_z.get_value().c_str());
    dr_printf("param foo = %d\n", op_foo.get_value());
    dr_printf("param bar = |%s|\n", op_bar.get_value().c_str());
    dr_printf("param flag = |%d|\n", op_flag.get_value());
    dr_printf("param sweep = |%s|\n", op_sweep.get_value().c_str());
    ASSERT(!op_foo.specified());
    ASSERT(!op_bar.specified());
}
<commit_msg>i#1720 spurious client.option_parse failures: client to use STDERR<commit_after>/* **********************************************************
 * Copyright (c) 2015 Google, 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 Google, Inc. nor the names of its contributors 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 GOOGLE, INC. 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.
 */

/* Test parsing options.
 */

#include "dr_api.h"
#include "client_tools.h"
#include "droption.h"
#include <string.h>

static droption_t<unsigned int> op_x
(DROPTION_SCOPE_CLIENT, "x", 0, 0, 64, "Some param",
 "Longer desc of some param.");
static droption_t<std::string> op_y
(DROPTION_SCOPE_CLIENT, "y", DROPTION_FLAG_ACCUMULATE, "<default>", "Another param",
 "Longer desc of another param.");
static droption_t<std::string> op_z
(DROPTION_SCOPE_CLIENT, "z", "", "Yet another param",
 "Longer desc of yet another param.");
static droption_t<int> op_foo
(DROPTION_SCOPE_CLIENT, "foo", 8, "Missing param",
 "Longer desc of missing param.");
static droption_t<std::string> op_bar
(DROPTION_SCOPE_CLIENT, "bar", "some string with spaces", "Missing string param",
 "Longer desc of missing string param.");
static droption_t<bool> op_flag
(DROPTION_SCOPE_CLIENT, "flag", true, "Bool param",
 "Longer desc of bool param.");
static droption_t<std::string> op_sweep
(DROPTION_SCOPE_CLIENT, "sweep", DROPTION_FLAG_SWEEP | DROPTION_FLAG_ACCUMULATE,
 "", "All the unknown params",
 "Longer desc of unknown param accum.");
static droption_t<std::string> op_front
(DROPTION_SCOPE_FRONTEND, "front", "", "Front-end param",
 "Longer desc of front-end param.");
static droption_t<std::string> op_front2
(DROPTION_SCOPE_FRONTEND, "front2", "", "Front-end param2",
 "Longer desc of front-end param2.");

DR_EXPORT void
dr_init(client_id_t client_id)
{
    // Test dr_get_option_array().
    int argc;
    const char **argv;
    bool ok = dr_get_option_array(client_id, &argc, &argv, MAXIMUM_PATH);
    ASSERT(ok);
    ASSERT(argc == 16);
    ASSERT(strcmp(argv[1], "-x") == 0);
    ASSERT(strcmp(argv[2], "4") == 0);
    ASSERT(strcmp(argv[3], "-y") == 0);
    ASSERT(strcmp(argv[4], "quoted string") == 0);
    ASSERT(strcmp(argv[5], "-z") == 0);
    ASSERT(strcmp(argv[6], "first") == 0);
    ASSERT(strcmp(argv[7], "-z") == 0);
    ASSERT(strcmp(argv[8], "single quotes -dash --dashes") == 0);
    ASSERT(strcmp(argv[9], "-front") == 0);
    ASSERT(strcmp(argv[10], "value") == 0);
    ASSERT(strcmp(argv[11], "-y") == 0);
    ASSERT(strcmp(argv[12], "accum") == 0);
    ASSERT(strcmp(argv[13], "-front2") == 0);
    ASSERT(strcmp(argv[14], "value2") == 0);
    ASSERT(strcmp(argv[15], "-no_flag") == 0);
    ok = dr_free_option_array(argc, argv);
    ASSERT(ok);

    // Test dr_parse_options() and droption_t declarations above.
    ok = dr_parse_options(client_id, NULL, NULL);
    ASSERT(ok);
    ASSERT(op_x.specified());
    ASSERT(op_y.specified());
    ASSERT(op_z.specified());
    dr_fprintf(STDERR, "param x = %d\n", op_x.get_value());
    dr_fprintf(STDERR, "param y = |%s|\n", op_y.get_value().c_str());
    dr_fprintf(STDERR, "param z = |%s|\n", op_z.get_value().c_str());
    dr_fprintf(STDERR, "param foo = %d\n", op_foo.get_value());
    dr_fprintf(STDERR, "param bar = |%s|\n", op_bar.get_value().c_str());
    dr_fprintf(STDERR, "param flag = |%d|\n", op_flag.get_value());
    dr_fprintf(STDERR, "param sweep = |%s|\n", op_sweep.get_value().c_str());
    ASSERT(!op_foo.specified());
    ASSERT(!op_bar.specified());
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void array_for_matrix(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
  typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols);

  ColVectorType cv1 = ColVectorType::Random(rows);
  RowVectorType rv1 = RowVectorType::Random(cols);

  Scalar  s1 = internal::random<Scalar>(),
          s2 = internal::random<Scalar>();

  // scalar addition
  VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
  VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows,cols,s1) + m1);
  VERIFY_IS_APPROX(((m1*Scalar(2)).array() - s2).matrix(), (m1+m1) - MatrixType::Constant(rows,cols,s2) );
  m3 = m1;
  m3.array() += s2;
  VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix());
  m3 = m1;
  m3.array() -= s1;
  VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());

  // reductions
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).squaredNorm());
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));

  // vector-wise ops
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);

  // empty objects
  VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(),  RowVectorType::Zero(cols));
  VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows));

  // verify the const accessors exist
  const Scalar& ref_m1 = m.matrix().array().coeffRef(0);
  const Scalar& ref_m2 = m.matrix().array().coeffRef(0,0);
  const Scalar& ref_a1 = m.array().matrix().coeffRef(0);
  const Scalar& ref_a2 = m.array().matrix().coeffRef(0,0);
  VERIFY(&ref_a1 == &ref_m1);
  VERIFY(&ref_a2 == &ref_m2);
}

template<typename MatrixType> void comparisons(const MatrixType& m)
{
  using std::abs;
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  Index rows = m.rows();
  Index cols = m.cols();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols);

  VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());
  VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());
  if (rows*cols>1)
  {
    m3 = m1;
    m3(r,c) += 1;
    VERIFY(! (m1.array() < m3.array()).all() );
    VERIFY(! (m1.array() > m3.array()).all() );
  }

  // comparisons to scalar
  VERIFY( (m1.array() != (m1(r,c)+1) ).any() );
  VERIFY( (m1.array() > (m1(r,c)-1) ).any() );
  VERIFY( (m1.array() < (m1(r,c)+1) ).any() );
  VERIFY( (m1.array() == m1(r,c) ).any() );

  // test Select
  VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );
  VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
  for (int j=0; j<cols; ++j)
  for (int i=0; i<rows; ++i)
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
                        .select(MatrixType::Zero(rows,cols),m1), m3);
  // shorter versions:
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
                        .select(0,m1), m3);
  VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())
                        .select(m1,0), m3);
  // even shorter version:
  VERIFY_IS_APPROX( (m1.array().abs()<mid).select(0,m1), m3);

  // count
  VERIFY(((m1.array().abs()+1)>RealScalar(0.1)).count() == rows*cols);

  typedef Matrix<typename MatrixType::Index, Dynamic, 1> VectorOfIndices;

  // TODO allows colwise/rowwise for array
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));
}

template<typename VectorType> void lpNorm(const VectorType& v)
{
  using std::sqrt;
  VectorType u = VectorType::Random(v.size());

  VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
  VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
  VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
}

template<typename MatrixType> void cwise_min_max(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols);

  // min/max with array
  Scalar maxM1 = m1.maxCoeff();
  Scalar minM1 = m1.minCoeff();

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin(MatrixType::Constant(rows,cols, minM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows,cols, maxM1)));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows,cols, maxM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows,cols, minM1)));

  // min/max with scalar input
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin( minM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMin( maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax( maxM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMax( minM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1).array(), (m1.array().min)( minM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().min)( maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1).array(), (m1.array().max)( maxM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().max)( minM1));

}

template<typename MatrixTraits> void resize(const MatrixTraits& t)
{
  typedef typename MatrixTraits::Index Index;
  typedef typename MatrixTraits::Scalar Scalar;
  typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
  typedef Array<Scalar,Dynamic,Dynamic> Array2DType;
  typedef Matrix<Scalar,Dynamic,1> VectorType;
  typedef Array<Scalar,Dynamic,1> Array1DType;

  Index rows = t.rows(), cols = t.cols();

  MatrixType m(rows,cols);
  VectorType v(rows);
  Array2DType a2(rows,cols);
  Array1DType a1(rows);

  m.array().resize(rows+1,cols+1);
  VERIFY(m.rows()==rows+1 && m.cols()==cols+1);
  a2.matrix().resize(rows+1,cols+1);
  VERIFY(a2.rows()==rows+1 && a2.cols()==cols+1);
  v.array().resize(cols);
  VERIFY(v.size()==cols);
  a1.matrix().resize(cols);
  VERIFY(a1.size()==cols);
}

void regression_bug_654()
{
  ArrayXf a = RowVectorXf(3);
  VectorXf v = Array<float,1,Dynamic>(3);
}

void test_array_for_matrix()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( array_for_matrix(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( array_for_matrix(Matrix2f()) );
    CALL_SUBTEST_3( array_for_matrix(Matrix4d()) );
    CALL_SUBTEST_4( array_for_matrix(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( array_for_matrix(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array_for_matrix(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( comparisons(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( comparisons(Matrix2f()) );
    CALL_SUBTEST_3( comparisons(Matrix4d()) );
    CALL_SUBTEST_5( comparisons(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( comparisons(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( cwise_min_max(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( cwise_min_max(Matrix2f()) );
    CALL_SUBTEST_3( cwise_min_max(Matrix4d()) );
    CALL_SUBTEST_5( cwise_min_max(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( cwise_min_max(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( lpNorm(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( lpNorm(Vector2f()) );
    CALL_SUBTEST_7( lpNorm(Vector3d()) );
    CALL_SUBTEST_8( lpNorm(Vector4f()) );
    CALL_SUBTEST_5( lpNorm(VectorXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_4( lpNorm(VectorXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_4( resize(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( resize(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  CALL_SUBTEST_6( regression_bug_654() );
}
<commit_msg>bug 679: add respective unit test<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void array_for_matrix(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
  typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols);

  ColVectorType cv1 = ColVectorType::Random(rows);
  RowVectorType rv1 = RowVectorType::Random(cols);

  Scalar  s1 = internal::random<Scalar>(),
          s2 = internal::random<Scalar>();

  // scalar addition
  VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
  VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows,cols,s1) + m1);
  VERIFY_IS_APPROX(((m1*Scalar(2)).array() - s2).matrix(), (m1+m1) - MatrixType::Constant(rows,cols,s2) );
  m3 = m1;
  m3.array() += s2;
  VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix());
  m3 = m1;
  m3.array() -= s1;
  VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());

  // reductions
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).squaredNorm());
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));

  // vector-wise ops
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);

  // empty objects
  VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(),  RowVectorType::Zero(cols));
  VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows));

  // verify the const accessors exist
  const Scalar& ref_m1 = m.matrix().array().coeffRef(0);
  const Scalar& ref_m2 = m.matrix().array().coeffRef(0,0);
  const Scalar& ref_a1 = m.array().matrix().coeffRef(0);
  const Scalar& ref_a2 = m.array().matrix().coeffRef(0,0);
  VERIFY(&ref_a1 == &ref_m1);
  VERIFY(&ref_a2 == &ref_m2);
}

template<typename MatrixType> void comparisons(const MatrixType& m)
{
  using std::abs;
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  Index rows = m.rows();
  Index cols = m.cols();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols);

  VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());
  VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());
  if (rows*cols>1)
  {
    m3 = m1;
    m3(r,c) += 1;
    VERIFY(! (m1.array() < m3.array()).all() );
    VERIFY(! (m1.array() > m3.array()).all() );
  }

  // comparisons to scalar
  VERIFY( (m1.array() != (m1(r,c)+1) ).any() );
  VERIFY( (m1.array() > (m1(r,c)-1) ).any() );
  VERIFY( (m1.array() < (m1(r,c)+1) ).any() );
  VERIFY( (m1.array() == m1(r,c) ).any() );

  // test Select
  VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );
  VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
  for (int j=0; j<cols; ++j)
  for (int i=0; i<rows; ++i)
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
                        .select(MatrixType::Zero(rows,cols),m1), m3);
  // shorter versions:
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
                        .select(0,m1), m3);
  VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())
                        .select(m1,0), m3);
  // even shorter version:
  VERIFY_IS_APPROX( (m1.array().abs()<mid).select(0,m1), m3);

  // count
  VERIFY(((m1.array().abs()+1)>RealScalar(0.1)).count() == rows*cols);

  typedef Matrix<typename MatrixType::Index, Dynamic, 1> VectorOfIndices;

  // TODO allows colwise/rowwise for array
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));
}

template<typename VectorType> void lpNorm(const VectorType& v)
{
  using std::sqrt;
  VectorType u = VectorType::Random(v.size());

  VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
  VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
  VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
}

template<typename MatrixType> void cwise_min_max(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols);

  // min/max with array
  Scalar maxM1 = m1.maxCoeff();
  Scalar minM1 = m1.minCoeff();

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin(MatrixType::Constant(rows,cols, minM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows,cols, maxM1)));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows,cols, maxM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows,cols, minM1)));

  // min/max with scalar input
  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin( minM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1));
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1));
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)( -minM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax( maxM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1));
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1));
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1).array(), (m1.array().min)( minM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().min)( maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1).array(), (m1.array().max)( maxM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().max)( minM1));

}

template<typename MatrixTraits> void resize(const MatrixTraits& t)
{
  typedef typename MatrixTraits::Index Index;
  typedef typename MatrixTraits::Scalar Scalar;
  typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
  typedef Array<Scalar,Dynamic,Dynamic> Array2DType;
  typedef Matrix<Scalar,Dynamic,1> VectorType;
  typedef Array<Scalar,Dynamic,1> Array1DType;

  Index rows = t.rows(), cols = t.cols();

  MatrixType m(rows,cols);
  VectorType v(rows);
  Array2DType a2(rows,cols);
  Array1DType a1(rows);

  m.array().resize(rows+1,cols+1);
  VERIFY(m.rows()==rows+1 && m.cols()==cols+1);
  a2.matrix().resize(rows+1,cols+1);
  VERIFY(a2.rows()==rows+1 && a2.cols()==cols+1);
  v.array().resize(cols);
  VERIFY(v.size()==cols);
  a1.matrix().resize(cols);
  VERIFY(a1.size()==cols);
}

void regression_bug_654()
{
  ArrayXf a = RowVectorXf(3);
  VectorXf v = Array<float,1,Dynamic>(3);
}

void test_array_for_matrix()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( array_for_matrix(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( array_for_matrix(Matrix2f()) );
    CALL_SUBTEST_3( array_for_matrix(Matrix4d()) );
    CALL_SUBTEST_4( array_for_matrix(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( array_for_matrix(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array_for_matrix(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( comparisons(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( comparisons(Matrix2f()) );
    CALL_SUBTEST_3( comparisons(Matrix4d()) );
    CALL_SUBTEST_5( comparisons(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( comparisons(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( cwise_min_max(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( cwise_min_max(Matrix2f()) );
    CALL_SUBTEST_3( cwise_min_max(Matrix4d()) );
    CALL_SUBTEST_5( cwise_min_max(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( cwise_min_max(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( lpNorm(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( lpNorm(Vector2f()) );
    CALL_SUBTEST_7( lpNorm(Vector3d()) );
    CALL_SUBTEST_8( lpNorm(Vector4f()) );
    CALL_SUBTEST_5( lpNorm(VectorXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_4( lpNorm(VectorXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_4( resize(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( resize(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  CALL_SUBTEST_6( regression_bug_654() );
}
<|endoftext|>


<commit_before>#if !(defined MPL_ERROR_HPP)

#define MPL_ERROR_HPP

#include <exception>

namespace mpl {

  class error : public ::std::exception {
  protected:
    const char *const str;

  public:
    explicit error(const char *const str = "unknown") : str(str) {}

    ~error() override = default;

    const char *what() const noexcept override { return str; }
  };

  class invalid_rank : public error {
  public:
    invalid_rank() : error("invalid rank") {}

    ~invalid_rank() override = default;
  };

  class invalid_tag : public error {
  public:
    invalid_tag() : error("invalid tag") {}

    ~invalid_tag() override = default;
  };

  class invalid_size : public error {
  public:
    invalid_size() : error("invalid size") {}

    ~invalid_size() override = default;
  };

  class invalid_count : public error {
  public:
    invalid_count() : error("invalid count") {}

    ~invalid_count() override = default;
  };

  class invalid_layout : public error {
  public:
    invalid_layout() : error("invalid layout") {}

    ~invalid_layout() override = default;
  };

  class invalid_dim : public error {
  public:
    invalid_dim() : error("invalid dimension") {}

    ~invalid_dim() override = default;
  };

  class invalid_datatype_bound : public error {
  public:
    invalid_datatype_bound() : error("invalid datatype bound") {}

    ~invalid_datatype_bound() override = default;
  };

  class invalid_argument : public error {
  public:
    invalid_argument() : error("invalid argument") {}

    ~invalid_argument() override = default;
  };

}  // namespace mpl

#endif
<commit_msg>remove redundant code<commit_after>#if !(defined MPL_ERROR_HPP)

#define MPL_ERROR_HPP

#include <exception>

namespace mpl {

  class error : public ::std::exception {
  protected:
    const char *const str;

  public:
    explicit error(const char *const str = "unknown") : str(str) {}

    const char *what() const noexcept override { return str; }
  };

  class invalid_rank : public error {
  public:
    invalid_rank() : error("invalid rank") {}
  };

  class invalid_tag : public error {
  public:
    invalid_tag() : error("invalid tag") {}
  };

  class invalid_size : public error {
  public:
    invalid_size() : error("invalid size") {}
  };

  class invalid_count : public error {
  public:
    invalid_count() : error("invalid count") {}
  };

  class invalid_layout : public error {
  public:
    invalid_layout() : error("invalid layout") {}
  };

  class invalid_dim : public error {
  public:
    invalid_dim() : error("invalid dimension") {}
  };

  class invalid_datatype_bound : public error {
  public:
    invalid_datatype_bound() : error("invalid datatype bound") {}
  };

  class invalid_argument : public error {
  public:
    invalid_argument() : error("invalid argument") {}
  };

}  // namespace mpl

#endif
<|endoftext|>