<commit_before>// © Copyright (c) 2018 SqYtCO

#include "graphiccore.h"
#include "core.h"
#include "openglwidget.h"
#include "hashlifesystem.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths>
#include <QLabel>
#ifdef ENABLE_CALC_TIME_MEASUREMENT
#include <QDebug>
#include <chrono>
#endif

GraphicConfiguration GraphicCore::gconfig;
OpenGLWidget* GraphicCore::opengl;
QLabel* GraphicCore::gen_counter;
std::unique_ptr<std::thread> GraphicCore::stepping_thread;
std::atomic_bool GraphicCore::stepping_stop;
bool GraphicCore::stepping_block;
std::unique_ptr<std::thread> GraphicCore::generating_thread;
std::atomic_bool GraphicCore::generating_stop;
std::unique_ptr<std::thread> GraphicCore::calc_thread;
std::atomic_bool GraphicCore::calc_stop;
std::mutex GraphicCore::system_mutex;

void GraphicCore::init()
{
	// get correct config path
	QString config_path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
	if(config_path[config_path.size() - 1] != '/')
		config_path.append('/');

	// set config paths
	Core::get_config()->set_config_path(config_path.toStdString());
	gconfig.set_config_path(config_path.toStdString());

	// create new system with correct configuration
	Core::new_system();

	stepping_stop = true;
	stepping_block = false;

	generating_stop = true;
}

void GraphicCore::init_gui(OpenGLWidget* opengl, QLabel* gen_counter)
{
	GraphicCore::opengl = opengl;

	GraphicCore::gen_counter = gen_counter;
	gen_counter->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
	gen_counter->setAlignment(Qt::AlignRight | Qt::AlignBottom);
	gen_counter->setWindowFlags(Qt::SubWindow);
	gen_counter->setForegroundRole(QPalette::BrightText);
	update_generation_counter();
}

void GraphicCore::reset_cells(Cell_State state)
{
	Core::reset_cells(state);
	update_generation_counter();
	update_opengl();
}

void GraphicCore::new_system()
{
	stop_step();
	stop_generating();
	// generate new system and fill with random cells if it is set
	Core::new_system();
	update_generation_counter();
	update_opengl();
}

void GraphicCore::reset_movement()
{
	opengl->reset_movement();
}

void GraphicCore::update_generation_counter()
{
	gen_counter->setVisible(!gconfig.get_hide_generation_counter());
	gen_counter->setFont(QFont("", static_cast<int>(get_config()->get_generation_counter_size())));
	gen_counter->setText(QString::number(Core::get_generation()));
}

void GraphicCore::update_opengl()
{
	opengl->update();
}

void GraphicCore::read_save()
{
	QString selected_filter("Game Of Life(*.gol)");
	Core::load(QFileDialog::getOpenFileName(nullptr, QFileDialog::tr("Select a file to open..."), Core::get_config()->get_save_path().c_str(), QFileDialog::tr("All Files(*);;Game Of Life(*.gol)"), &selected_filter).toStdString());
	update_opengl();
	update_generation_counter();
}

void GraphicCore::write_save_as()
{
	// ask for file name
	QString selected_filter("Game Of Life(*.gol)");
	QString file_name = QFileDialog::getSaveFileName(nullptr, QFileDialog::tr("Choose a file name to save..."), Core::get_config()->get_save_path().c_str(), QFileDialog::tr("All Files(*);;Game Of Life(*.gol)"), &selected_filter);

	// return if no file name was entered
	if(file_name.isEmpty())
		return;

	// write save; warning if writing fails
	if(!Core::save(file_name.toStdString()))
		QMessageBox::warning(nullptr, QMessageBox::tr("Write Error"), QMessageBox::tr("Writing Save Failed!\nPlease Check Your Permissions."));
}

void GraphicCore::write_save()
{
	// write save; warning if writing fails
	if(!Core::save())
		QMessageBox::warning(nullptr, QMessageBox::tr("Write Error"), QMessageBox::tr("Writing Save Failed!\nPlease Check Your Permissions."));
}

void GraphicCore::next_generations(std::size_t generations)
{
	while(generations)
	{
		if(stepping_stop)
			break;
		else
			generations -= Core::next_generation(generations);
	}

	stepping_stop = true;

	// send signals to main thread (update GUI)
	emit opengl->cell_changed();
	emit opengl->start_update();
}

void GraphicCore::step()
{
	wait_for_calculation();
	// stop last step
	stop_step();

	// if thread is not blocked, start new step
	if(!stepping_block)
	{
		stepping_stop = false;
		stepping_thread.reset(new std::thread(next_generations, gconfig.get_generations_per_step()));
	}
}

void GraphicCore::stop_step()
{
	stepping_stop = true;
	if(stepping_thread)
	{
		stepping_thread->join();
		stepping_thread.reset(nullptr);
	}
}

void GraphicCore::start_generating()
{
	if(generating_running())
		return;

	wait_for_calculation();
	stop_step();
	stepping_block = true;

	if(generating_thread)
		generating_thread->join();

	generating_stop = false;
	generating_thread.reset(new std::thread([&]()
	{
		while(!generating_stop)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(gconfig.get_delay()));

			system_mutex.lock();
#ifdef ENABLE_CALC_TIME_MEASUREMENT
			auto begin = std::chrono::high_resolution_clock::now();
#endif
			Core::next_generation();
#ifdef ENABLE_CALC_TIME_MEASUREMENT
			auto end = std::chrono::high_resolution_clock::now();
			qDebug() << "calculating: " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "µs";
#endif
			system_mutex.unlock();

			emit opengl->cell_changed();
			emit opengl->start_update();
		}
	}));

	emit opengl->generating_start_stop();
}

void GraphicCore::stop_generating()
{
	if(generating_stop)
		return;

	generating_stop = true;

	if(generating_thread)
		generating_thread->join();
	generating_thread.reset(nullptr);
	stepping_block = false;

	emit opengl->generating_start_stop();
}

void GraphicCore::calc_next_generation()
{
	wait_for_calculation();

	calc_thread.reset(new std::thread([]()
	{
		Core::calc_next_generation(gconfig.get_generations_per_step());
		emit opengl->start_update();
	}));
}

void GraphicCore::wait_for_calculation()
{
	if(calc_thread)
	{
		calc_thread->join();
		calc_thread.reset(nullptr);
	}
}
<commit_msg>small changes<commit_after>// © Copyright (c) 2018 SqYtCO

#include "graphiccore.h"
#include "core.h"
#include "openglwidget.h"
#include "hashlifesystem.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths>
#include <QLabel>
#ifdef ENABLE_CALC_TIME_MEASUREMENT
#include <QDebug>
#include <chrono>
#endif

GraphicConfiguration GraphicCore::gconfig;
OpenGLWidget* GraphicCore::opengl;
QLabel* GraphicCore::gen_counter;
std::unique_ptr<std::thread> GraphicCore::stepping_thread;
std::atomic_bool GraphicCore::stepping_stop;
bool GraphicCore::stepping_block;
std::unique_ptr<std::thread> GraphicCore::generating_thread;
std::atomic_bool GraphicCore::generating_stop;
std::unique_ptr<std::thread> GraphicCore::calc_thread;
std::atomic_bool GraphicCore::calc_stop;
std::mutex GraphicCore::system_mutex;

void GraphicCore::init()
{
	// get correct config path
	QString config_path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
	if(config_path[config_path.size() - 1] != '/')
		config_path.append('/');

	// set config paths
	Core::get_config()->set_config_path(config_path.toStdString());
	gconfig.set_config_path(config_path.toStdString());

	// create new system with correct configuration
	Core::new_system();

	stepping_stop = true;
	stepping_block = false;

	generating_stop = true;
}

void GraphicCore::init_gui(OpenGLWidget* opengl, QLabel* gen_counter)
{
	GraphicCore::opengl = opengl;

	GraphicCore::gen_counter = gen_counter;
	gen_counter->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
	gen_counter->setAlignment(Qt::AlignRight | Qt::AlignBottom);
	gen_counter->setWindowFlags(Qt::SubWindow);
	gen_counter->setForegroundRole(QPalette::BrightText);
	update_generation_counter();
}

void GraphicCore::reset_cells(Cell_State state)
{
	Core::reset_cells(state);
	update_generation_counter();
	update_opengl();
}

void GraphicCore::new_system()
{
	stop_step();
	stop_generating();
	wait_for_calculation();

	// generate new system and fill with random cells if it is set
	Core::new_system();

	update_generation_counter();
	update_opengl();
}

void GraphicCore::reset_movement()
{
	opengl->reset_movement();
}

void GraphicCore::update_generation_counter()
{
	gen_counter->setVisible(!gconfig.get_hide_generation_counter());
	gen_counter->setFont(QFont("", static_cast<int>(get_config()->get_generation_counter_size())));
	gen_counter->setText(QString::number(Core::get_generation()));
}

void GraphicCore::update_opengl()
{
	opengl->update();
}

void GraphicCore::read_save()
{
	QString selected_filter("Game Of Life(*.gol)");
	Core::load(QFileDialog::getOpenFileName(nullptr, QFileDialog::tr("Select a file to open..."), Core::get_config()->get_save_path().c_str(), QFileDialog::tr("All Files(*);;Game Of Life(*.gol)"), &selected_filter).toStdString());
	update_opengl();
	update_generation_counter();
}

void GraphicCore::write_save_as()
{
	// ask for file name
	QString selected_filter("Game Of Life(*.gol)");
	QString file_name = QFileDialog::getSaveFileName(nullptr, QFileDialog::tr("Choose a file name to save..."), Core::get_config()->get_save_path().c_str(), QFileDialog::tr("All Files(*);;Game Of Life(*.gol)"), &selected_filter);

	// return if no file name was entered
	if(file_name.isEmpty())
		return;

	// write save; warning if writing fails
	if(!Core::save(file_name.toStdString()))
		QMessageBox::warning(nullptr, QMessageBox::tr("Write Error"), QMessageBox::tr("Writing Save Failed!\nPlease Check Your Permissions."));
}

void GraphicCore::write_save()
{
	// write save; warning if writing fails
	if(!Core::save())
		QMessageBox::warning(nullptr, QMessageBox::tr("Write Error"), QMessageBox::tr("Writing Save Failed!\nPlease Check Your Permissions."));
}

void GraphicCore::next_generations(std::size_t generations)
{
	while(generations)
	{
		if(stepping_stop)
			break;
		else
			generations -= Core::next_generation(generations);
	}

	stepping_stop = true;

	// send signals to main thread (update GUI)
	emit opengl->cell_changed();
	emit opengl->start_update();
}

void GraphicCore::step()
{
	wait_for_calculation();
	// stop last step
	stop_step();

	// if thread is not blocked, start new step
	if(!stepping_block)
	{
		stepping_stop = false;
		stepping_thread.reset(new std::thread(next_generations, gconfig.get_generations_per_step()));
	}
}

void GraphicCore::stop_step()
{
	stepping_stop = true;
	if(stepping_thread)
	{
		stepping_thread->join();
		stepping_thread.reset(nullptr);
	}
}

void GraphicCore::start_generating()
{
	if(generating_running())
		return;

	wait_for_calculation();
	stop_step();
	stepping_block = true;

	if(generating_thread)
		generating_thread->join();

	generating_stop = false;
	generating_thread.reset(new std::thread([&]()
	{
		while(!generating_stop)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(gconfig.get_delay()));

			system_mutex.lock();
#ifdef ENABLE_CALC_TIME_MEASUREMENT
			auto begin = std::chrono::high_resolution_clock::now();
#endif
			Core::next_generation();
#ifdef ENABLE_CALC_TIME_MEASUREMENT
			auto end = std::chrono::high_resolution_clock::now();
			qDebug() << "calculating: " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "µs";
#endif
			system_mutex.unlock();

			emit opengl->cell_changed();
			emit opengl->start_update();
		}
	}));

	emit opengl->generating_start_stop();
}

void GraphicCore::stop_generating()
{
	if(generating_stop)
		return;

	generating_stop = true;

	if(generating_thread)
		generating_thread->join();
	generating_thread.reset(nullptr);
	stepping_block = false;

	emit opengl->generating_start_stop();
}

void GraphicCore::calc_next_generation()
{
	if(generating_running())
		return;

	wait_for_calculation();

	calc_thread.reset(new std::thread([]()
	{
		Core::calc_next_generation(gconfig.get_generations_per_step());
		emit opengl->start_update();
	}));
}

void GraphicCore::wait_for_calculation()
{
	if(calc_thread)
	{
		calc_thread->join();
		calc_thread.reset(nullptr);
	}
}
<|endoftext|>


<commit_before>#if !defined HOST_API_HPP
#define HOST_API_HPP

#include <iterator>

#include "device_info.hpp"

namespace tvr
{
	namespace pa
	{
		class host_api_info
		{
		public:
			class iterator: public std::iterator<std::random_access_iterator_tag, host_api_info, PaHostApiIndex>
			{
			public:
				iterator() {}
				iterator(PaHostApiIndex index) : _index(index) { check_index(); }
				~iterator(){}

				bool operator==(const iterator& item) const
				{
					return _index == item._index;
				}

				bool operator!=(const iterator& item) const
				{
					return _index != item._index;
				}

				bool operator<(const iterator& item) const
				{
					return _index < item._index;
				}

				iterator& operator=(const iterator& orig)
				{
					_index = orig._index;
					return *this;
				}

				iterator& operator++()
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > ::Pa_GetHostApiCount())
					{
						--_index;
					}
					return *this;
				}

				iterator& operator++(int)
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > ::Pa_GetHostApiCount())
					{
						--_index;
					}
					return *this;
				}

				iterator& operator--()
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				iterator& operator--(int)
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				iterator& operator+=(PaHostApiIndex diff)
				{
					_index += diff;
					check_index();
					return *this;
				}

				iterator& operator-=(PaHostApiIndex diff)
				{
					_index -= diff;
					check_index();
					return *this;
				}

				host_api_info operator[](PaHostApiIndex loc) const
				{
					iterator iter(loc);
					return *iter;
				}

				host_api_info operator*() const
				{
					host_api_info result(_index);
					return result;
				}

			private:
				void check_index()
				{
					if (_index < 0)
						_index = 0;
					if (_index > ::Pa_GetHostApiCount())
						_index = ::Pa_GetHostApiCount();
				}

			private:
				PaHostApiIndex _index;
			};

			struct device_iterator : public std::iterator<std::random_access_iterator_tag, device_info, int>
			{
				device_iterator(const host_api_info& host): _index(0), _host(host){ check_index(); }
				device_iterator(const host_api_info& host, int index):_index(index), _host(host){ check_index(); }
				~device_iterator(){}

				bool operator==(const device_iterator& item) const
				{
					return _index == item._index;
				}

				bool operator!=(const device_iterator& item) const
				{
					return _index != item._index;
				}

				bool operator<(const device_iterator& item) const
				{
					return _index < item._index;
				}

				device_iterator& operator=(const device_iterator& orig)
				{
					_index = orig._index;
					return *this;
				}

				device_iterator& operator++()
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > max())
					{
						--_index;
					}
					return *this;
				}

				device_iterator& operator++(int)
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > max())
					{
						--_index;
					}
					return *this;
				}

				device_iterator& operator--()
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				device_iterator& operator--(int)
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				device_iterator& operator+=(int diff)
				{
					_index += diff;
					check_index();
					return *this;
				}

				device_iterator& operator-=(int diff)
				{
					_index -= diff;
					check_index();
					return *this;
				}

				device_info operator[](int loc) const
				{
					device_iterator iter(_host, loc);
					return *iter;
				}

				device_info operator*() const
				{
					device_info result(_host.get_device_index(_index));
					return result;
				}

			private:
				void check_index()
				{
					if (_index < 0)
						_index = 0;
					if (_index > max())
						_index = max();
				}

				int max() const
				{
					return _host.get_info().deviceCount;
				}
			private:
				int _index;
				const host_api_info& _host;
			};

		public:
			host_api_info()
			{
				_info = ::Pa_GetHostApiInfo(::Pa_GetDefaultHostApi());
			}

			host_api_info(PaHostApiIndex index)
			{
				_info = ::Pa_GetHostApiInfo(index);
			}

			host_api_info(const host_api_info& orig)
			{
				*this = orig;
			}

			host_api_info& operator=(const host_api_info& orig)
			{
				_info = orig._info;
				_index = orig._index;
				return *this;
			}

			const PaHostApiInfo& get_info() const
			{
				return *_info;
			}

			PaHostApiIndex get_index() const
			{
				return _index;
			}

			int get_device_count() const
			{
				return _info->deviceCount;
			}

			PaDeviceIndex get_device_index(int hostApiDeviceIndex) const
			{
				return ::Pa_HostApiDeviceIndexToDeviceIndex(_index, hostApiDeviceIndex);
			}

			device_iterator device_begin() const
			{
				device_iterator result(*this, 0);
				return result;
			}

			device_iterator device_end() const
			{
				device_iterator result(*this, get_device_count());
				return result;
			}

			static iterator begin()
			{
				iterator iter(0);
				return iter;
			}

			static iterator end()
			{
				iterator iter(::Pa_GetHostApiCount());
				return iter;
			}

			static host_api_info get_host_api_info(PaHostApiTypeId id)
			{
				host_api_info result(::Pa_HostApiTypeIdToHostApiIndex(id));
				return result;
			}

			device_info get_device(int hostApiDeviceIndex)
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, hostApiDeviceIndex));
				return result;
			}

			device_info get_default_output_device()
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, _info->defaultOutputDevice));
				return result;
			}

			device_info get_default_input_device()
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, _info->defaultInputDevice));
				return result;
			}
		private:
			const PaHostApiInfo* _info;
			PaHostApiIndex _index;
		};
	}
}

#endif // HOST_API_HPP

<commit_msg>Fixed issues preventing this from working properly in Linux.<commit_after>#if !defined HOST_API_HPP
#define HOST_API_HPP

#include <iterator>

#include "device_info.hpp"

namespace tvr
{
	namespace pa
	{
		class host_api_info
		{
		public:
			class iterator: public std::iterator<std::random_access_iterator_tag, host_api_info, PaHostApiIndex>
			{
			public:
				iterator() {}
				iterator(PaHostApiIndex index) : _index(index) { check_index(); }
				~iterator(){}

				bool operator==(const iterator& item) const
				{
					return _index == item._index;
				}

				bool operator!=(const iterator& item) const
				{
					return _index != item._index;
				}

				bool operator<(const iterator& item) const
				{
					return _index < item._index;
				}

				iterator& operator=(const iterator& orig)
				{
					_index = orig._index;
					return *this;
				}

				iterator& operator++()
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > ::Pa_GetHostApiCount())
					{
						--_index;
					}
					return *this;
				}

				iterator& operator++(int)
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > ::Pa_GetHostApiCount())
					{
						--_index;
					}
					return *this;
				}

				iterator& operator--()
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				iterator& operator--(int)
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				iterator& operator+=(PaHostApiIndex diff)
				{
					_index += diff;
					check_index();
					return *this;
				}

				iterator& operator-=(PaHostApiIndex diff)
				{
					_index -= diff;
					check_index();
					return *this;
				}

				host_api_info operator[](PaHostApiIndex loc) const
				{
					iterator iter(loc);
					return *iter;
				}

				host_api_info operator*() const
				{
					host_api_info result(_index);
					return result;
				}

			private:
				void check_index()
				{
					if (_index < 0)
						_index = 0;
					if (_index > ::Pa_GetHostApiCount())
						_index = ::Pa_GetHostApiCount();
				}

			private:
				PaHostApiIndex _index;
			};

			struct device_iterator : public std::iterator<std::random_access_iterator_tag, device_info, int>
			{
				device_iterator(const host_api_info& host): _index(0), _host(host){ check_index(); }
				device_iterator(const host_api_info& host, int index):_index(index), _host(host){ check_index(); }
				~device_iterator(){}

				bool operator==(const device_iterator& item) const
				{
					return _index == item._index;
				}

				bool operator!=(const device_iterator& item) const
				{
					return _index != item._index;
				}

				bool operator<(const device_iterator& item) const
				{
					return _index < item._index;
				}

				device_iterator& operator=(const device_iterator& orig)
				{
					_index = orig._index;
					return *this;
				}

				device_iterator& operator++()
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > max())
					{
						--_index;
					}
					return *this;
				}

				device_iterator& operator++(int)
				{
					// We can never have more than Pa_GetHostApiCount host apis.
					if (++_index > max())
					{
						--_index;
					}
					return *this;
				}

				device_iterator& operator--()
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				device_iterator& operator--(int)
				{
					// We can never have less than zero.
					if (--_index < 0)
					{
						_index = 0;
					}
					return *this;
				}

				device_iterator& operator+=(int diff)
				{
					_index += diff;
					check_index();
					return *this;
				}

				device_iterator& operator-=(int diff)
				{
					_index -= diff;
					check_index();
					return *this;
				}

				device_info operator[](int loc) const
				{
					device_iterator iter(_host, loc);
					return *iter;
				}

				device_info operator*() const
				{
					device_info result(_host.get_device_index(_index));
					return result;
				}

			private:
				void check_index()
				{
					if (_index < 0)
						_index = 0;
					if (_index > max())
						_index = max();
				}

				int max() const
				{
					return _host.get_info().deviceCount;
				}
			private:
				int _index;
				const host_api_info& _host;
			};

		public:
			host_api_info():_info(0)
			{
				_index = ::Pa_GetDefaultHostApi();
				_info = ::Pa_GetHostApiInfo(_index);
			}

			host_api_info(PaHostApiIndex index): _index(index)
			{
				_info = ::Pa_GetHostApiInfo(index);
			}

			host_api_info(const host_api_info& orig)
			{
				*this = orig;
			}

			host_api_info& operator=(const host_api_info& orig)
			{
				_info = orig._info;
				_index = orig._index;
				return *this;
			}

			const PaHostApiInfo& get_info() const
			{
				return *_info;
			}

			PaHostApiIndex get_index() const
			{
				return _index;
			}

			int get_device_count() const
			{
				return _info->deviceCount;
			}

			PaDeviceIndex get_device_index(int hostApiDeviceIndex) const
			{
				return ::Pa_HostApiDeviceIndexToDeviceIndex(_index, hostApiDeviceIndex);
			}

			device_iterator device_begin() const
			{
				device_iterator result(*this, 0);
				return result;
			}

			device_iterator device_end() const
			{
				device_iterator result(*this, get_device_count());
				return result;
			}

			static iterator begin()
			{
				iterator iter(0);
				return iter;
			}

			static iterator end()
			{
				iterator iter(::Pa_GetHostApiCount());
				return iter;
			}

			static host_api_info get_host_api_info(PaHostApiTypeId id)
			{
				host_api_info result(::Pa_HostApiTypeIdToHostApiIndex(id));
				return result;
			}

			device_info get_device(int hostApiDeviceIndex)
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, hostApiDeviceIndex));
				return result;
			}

			device_info get_default_output_device()
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, _info->defaultOutputDevice));
				return result;
			}

			device_info get_default_input_device()
			{
				device_info result(::Pa_HostApiDeviceIndexToDeviceIndex(_index, _info->defaultInputDevice));
				return result;
			}
		private:
			const PaHostApiInfo* _info;
			PaHostApiIndex _index;
		};
	}
}

#endif // HOST_API_HPP

<|endoftext|>


<commit_before><commit_msg>Part Design: Workbench: commonize construciton of default part and body<commit_after><|endoftext|>


<commit_before>#include "all.h"
#include "boost_test.h"

class MockBlock : public Block
{
	void reset(void) {}
	void work(void) {}
};

BOOST_AUTO_TEST_CASE( noodleTest )
{
	BOOST_CHECK(0);
#if 0
	MockBlock b1;
	MockBlock b2;

	Noodle n1(&b1, &b2);
	BOOST_CHECK_EQUAL(n1.m_sourceBlock, &b1);
	BOOST_CHECK_EQUAL(n1.m_sinkBlock, &b2);
	BOOST_CHECK_EQUAL(n1.m_sourceIndex, 0);
	BOOST_CHECK_EQUAL(n1.m_sinkIndex, 0);

	Noodle n2(&b1, &b2, 1, 2);
	BOOST_CHECK_EQUAL(n2.m_sourceBlock, &b1);
	BOOST_CHECK_EQUAL(n2.m_sinkBlock, &b2);
	BOOST_CHECK_EQUAL(n2.m_sourceIndex, 1);
	BOOST_CHECK_EQUAL(n2.m_sinkIndex, 2);
#endif
}
<commit_msg>update NoodleTest for recent changes<commit_after>#include "all.h"
#include "boost_test.h"

class MockBlock : public Block
{
	void reset(void) {}
	void work(void) {}
};

BOOST_AUTO_TEST_CASE( noodleTest )
{
	MockBlock b1, b2;

	Endpoint from = {&b1, "out"};
	Endpoint to   = {&b1, "in"};

	Noodle n(from, to);

	/* should be empty */
	BOOST_CHECK(n.empty());

	/* should not be empty */
	n.push(0);
	BOOST_CHECK(!n.empty());

	/* should be empty once again */
	BOOST_CHECK_EQUAL(n.pop(), 0);
	BOOST_CHECK(n.empty());

	/* what goes in one end should come out the other */
	srand(time(nullptr));
	int samples[100];
	for (size_t i = 0; i < 100; ++i)
	{
		samples[i] = rand();
		n.push(samples[i]);
	}
	for (size_t i = 0; i < 100; ++i)
	{
		BOOST_CHECK_EQUAL(n.pop(), samples[i]);
	}
}
<|endoftext|>


<commit_before>#include <iostream>

#ifndef SASS_NODE_INCLUDED
#include "node.hpp"
#endif

#include "node_factory.hpp"

int main()
{
  using namespace Sass;
  using namespace std;

  cout << sizeof(Node) << endl;
  cout << sizeof(Node_Impl) << endl;

  return 0;
}<commit_msg>Unit testing the new node stuff. This file is gonna' go away.<commit_after>#include <iostream>

#ifndef SASS_NODE_INCLUDED
#include "node.hpp"
#endif

#include "node_factory.hpp"

int main()
{
  using namespace Sass;
  using namespace std;

  cout << sizeof(Node) << endl;
  cout << sizeof(Node_Impl) << endl << endl;

  Node_Factory make = Node_Factory();

  Node interior(make.node(block, 0, 0, 3));

  cout << interior.size() << endl;
  cout << interior.has_children() << endl;
  cout << interior.eval_me() << endl << endl;

  Node num(make.node(0, 0, 255, 123, 32));

  cout << num.size() << endl;
  cout << num.has_children() << endl;
  cout << num.has_statements() << endl << endl;

  cout << num[1].is_numeric() << endl;
  cout << num[1].numeric_value() << endl << endl;

  return 0;
}<|endoftext|>


<commit_before>#include "stf.h"
#include "sfl/just_ptr.h"

using namespace sfl;

class Parent
{
public:
	int a;
};

class Child : public Parent
{
public:
	Child()
	{
		a = 6;
	}

	Child(int value)
	{
		a = value;
	}
};

TEST(just_ptr, Hierarchy)
{
	{
		just_ptr<Child> value = sfl::make_just<Child>();
		just_ptr<Parent> p = value;
		ASSERT_EQ(6, p->a);
	}
	{
		just_ptr<Child> value = sfl::make_just<Child>(3);
		just_ptr<Parent> p = value;
		ASSERT_EQ(3, p->a);
	}
}<commit_msg>middle of refactor (too much memory consumption on parsing google data)<commit_after>#include "stf.h"
#include "sfl/just_ptr.h"

using namespace sfl;

class Parent
{
public:
	int a;
};

class Child : public Parent
{
public:
	Child()
	{
		a = 6;
	}

	Child(int value)
	{
		a = value;
	}
};

TEST(just_ptr, Hierarchy)
{
	{
		just_ptr<Child> value = sfl::make_just<Child>();
		just_ptr<Parent> p = value;
		ASSERT_EQ(6, p->a);
	}
	{
		just_ptr<Child> value = sfl::make_just<Child>(3);
		just_ptr<Parent> p = value;
		ASSERT_EQ(3, p->a);
	}
}

TEST(just_ptr, Delete)
{
	static bool deleted = false;

	struct JustMock
	{
		~JustMock()
		{
			deleted = true;
		}
	};

	JustMock *m = new JustMock();
	{
		just_ptr<JustMock> ptr(sfl::Unsafe(), m);
	}
	ASSERT_TRUE(deleted);
}<|endoftext|>


<commit_before>/*******************************************************************************
 * tests/api/io_test.cpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <thrill/common/logger.hpp>
#include <thrill/common/system_exception.hpp>
#include <thrill/thrill.hpp>

#include <gtest/gtest.h>

#include <algorithm>
#include <cstdlib>
#include <functional>
#include <random>
#include <string>
#include <vector>

#include <dirent.h>
#include <glob.h>
#include <sys/stat.h>

using namespace thrill;
using thrill::api::Context;
using thrill::api::DIARef;

/*!
 * A class which creates a temporary directory in /tmp/ and returns it via
 * get(). When the object is destroyed the temporary directory is wiped
 * non-recursively.
 */
class TemporaryDirectory
{
public:
    //! Create a temporary directory, returns its name without trailing /.
    static std::string make_directory(
        const char* sample = "/tmp/thrill-testsuite-") {

        std::string tmp_dir = std::string(sample) + "XXXXXX";
        // evil const_cast, but mkdtemp replaces the XXXXXX with something
        // unique. it also mkdirs.
        mkdtemp(const_cast<char*>(tmp_dir.c_str()));

        return tmp_dir;
    }

    //! wipe temporary directory NON RECURSIVELY!
    static void wipe_directory(const std::string& tmp_dir) {
        DIR* d = opendir(tmp_dir.c_str());
        if (d == nullptr) {
            throw common::SystemException(
                      "Could open temporary directory " + tmp_dir, errno);
        }

        struct dirent* de, entry;
        while (readdir_r(d, &entry, &de) == 0 && de != nullptr) {
            // skip ".", "..", and also hidden files (don't create them).
            if (de->d_name[0] == '.') continue;

            std::string path = tmp_dir + "/" + de->d_name;
            int r = unlink(path.c_str());
            if (r != 0)
                sLOG1 << "Could not unlink temporary file " << path
                      << ": " << strerror(errno);
        }

        closedir(d);

        if (rmdir(tmp_dir.c_str()) != 0) {
            sLOG1 << "Could not unlink temporary directory " << tmp_dir
                  << ": " << strerror(errno);
        }
    }

    TemporaryDirectory()
        : dir_(make_directory())
    { }

    ~TemporaryDirectory() {
        wipe_directory(dir_);
    }

    //! non-copyable: delete copy-constructor
    TemporaryDirectory(const TemporaryDirectory&) = delete;
    //! non-copyable: delete assignment operator
    TemporaryDirectory& operator = (const TemporaryDirectory&) = delete;

    //! return the temporary directory name
    const std::string & get() const { return dir_; }

protected:
    std::string dir_;
};

TEST(IO, ReadSingleFile) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 1;
            for (int element : out_vec) {
                ASSERT_EQ(element, i++);
            }

            ASSERT_EQ((size_t)16, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadFolder) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            ASSERT_EQ(ReadLines(ctx, "read_folder/*").Size(), 20);
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadPartOfFolderCompressed) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            // folder read_ints contains compressed and non-compressed files with integers
            // from 25 to 1 and a file 'donotread', which contains non int-castable
            // strings
            auto integers = ReadLines(ctx, "read_ints/read*")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 25;
            for (int element : out_vec) {
                ASSERT_EQ(element, i--);
            }

            ASSERT_EQ((size_t)25, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, GenerateFromFileRandomIntegers) {
    api::RunSameThread(
        [](api::Context& ctx) {
            std::default_random_engine generator({ std::random_device()() });
            std::uniform_int_distribution<int> distribution(1000, 10000);

            size_t generate_size = distribution(generator);

            auto input = GenerateFromFile(
                ctx,
                "test1",
                [](const std::string& line) {
                    return std::stoi(line);
                },
                generate_size);

            size_t writer_size = 0;

            input.Map(
                [&writer_size](const int& item) {
                    // file contains ints between 1  and 16
                    // fails if wrong integer is generated
                    EXPECT_GE(item, 1);
                    EXPECT_GE(16, item);
                    writer_size++;
                    return std::to_string(item) + "\n";
                })
            .WriteLinesMany("out1_");

            // DIA contains as many elements as we wanted to generate
            ASSERT_EQ(generate_size, writer_size);
        });
}

TEST(IO, GenerateIntegerWriteBinary) {
    api::RunLocalTests(
        [](api::Context& ctx) {

            size_t generate_size = 320000;

            // generate a dia of integers
            auto dia = Generate(
                ctx,
                [](const size_t index) {
                    return index * 42;
                },
                generate_size);

            // write to temporary directory
            TemporaryDirectory tmpdir;

            dia.WriteBinary(tmpdir.get() + "/IO.GenerateIntegerWriteBinary",
                            16 * 1024);
        });
}

TEST(IO, GenerateStringWriteBinary) {
    api::RunLocalTests(
        [](api::Context& ctx) {

            size_t generate_size = 320000;

            auto dia = Generate(
                ctx,
                [](const size_t index) {
                    return std::to_string(index * 42);
                },
                generate_size);

            // write to temporary directory
            TemporaryDirectory tmpdir;

            dia.WriteBinary(tmpdir.get() + "/IO.GenerateStringWriteBinary",
                            16 * 1024);
        });
}

TEST(IO, WriteBinaryCorrectSize) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {

            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            integers.WriteBinary("binary/output_");

            ctx.Barrier();

            if (ctx.my_rank() == 0) {
                glob_t glob_result;
                struct stat filestat;
                glob("binary/*", GLOB_TILDE, nullptr, &glob_result);
                size_t directory_size = 0;

                for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
                    const char* filepath = glob_result.gl_pathv[i];

                    if (stat(filepath, &filestat)) {
                        throw std::runtime_error(
                                  "ERROR: Invalid file " + std::string(filepath));
                    }
                    if (!S_ISREG(filestat.st_mode)) continue;

                    directory_size += filestat.st_size;

                    remove(filepath);
                }
                globfree(&glob_result);

                ASSERT_EQ(16 * sizeof(int), directory_size);
            }
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadBinary) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {

            std::string path = "testsf.out";

            auto integers2 = api::ReadBinary<int>(
                ctx, "./binary" + std::to_string(ctx.num_workers()) + "/*");

            integers2.Map(
                [](const int& item) {
                    return std::to_string(item);
                })
            .WriteLines(path);

            // Race condition as one worker might be finished while others are
            // still writing to output file.
            ctx.Barrier();

            std::ifstream file(path);
            size_t begin = file.tellg();
            file.seekg(0, std::ios::end);
            size_t end = file.tellg();
            ASSERT_EQ(end - begin, 39);
            file.seekg(0);
            for (int i = 1; i <= 16; i++) {
                std::string line;
                std::getline(file, line);
                ASSERT_EQ(std::stoi(line), i);
            }
        };

    api::RunLocalTests(start_func);
}

/******************************************************************************/
<commit_msg>Adding Write-Read tests for WriteBinary and ReadBinary. pair<size_t, string> do not work.<commit_after>/*******************************************************************************
 * tests/api/io_test.cpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <thrill/common/logger.hpp>
#include <thrill/common/system_exception.hpp>
#include <thrill/thrill.hpp>

#include <gtest/gtest.h>

#include <algorithm>
#include <cstdlib>
#include <functional>
#include <random>
#include <string>
#include <vector>

#include <dirent.h>
#include <glob.h>
#include <sys/stat.h>

using namespace thrill;
using thrill::api::Context;
using thrill::api::DIARef;

/*!
 * A class which creates a temporary directory in /tmp/ and returns it via
 * get(). When the object is destroyed the temporary directory is wiped
 * non-recursively.
 */
class TemporaryDirectory
{
public:
    //! Create a temporary directory, returns its name without trailing /.
    static std::string make_directory(
        const char* sample = "/tmp/thrill-testsuite-") {

        std::string tmp_dir = std::string(sample) + "XXXXXX";
        // evil const_cast, but mkdtemp replaces the XXXXXX with something
        // unique. it also mkdirs.
        mkdtemp(const_cast<char*>(tmp_dir.c_str()));

        return tmp_dir;
    }

    //! wipe temporary directory NON RECURSIVELY!
    static void wipe_directory(const std::string& tmp_dir, bool do_rmdir) {
        DIR* d = opendir(tmp_dir.c_str());
        if (d == nullptr) {
            throw common::SystemException(
                      "Could open temporary directory " + tmp_dir, errno);
        }

        struct dirent* de, entry;
        while (readdir_r(d, &entry, &de) == 0 && de != nullptr) {
            // skip ".", "..", and also hidden files (don't create them).
            if (de->d_name[0] == '.') continue;

            std::string path = tmp_dir + "/" + de->d_name;
            int r = unlink(path.c_str());
            if (r != 0)
                sLOG1 << "Could not unlink temporary file " << path
                      << ": " << strerror(errno);
        }

        closedir(d);

        if (!do_rmdir) return;

        if (rmdir(tmp_dir.c_str()) != 0) {
            sLOG1 << "Could not unlink temporary directory " << tmp_dir
                  << ": " << strerror(errno);
        }
    }

    TemporaryDirectory()
        : dir_(make_directory())
    { }

    ~TemporaryDirectory() {
        wipe_directory(dir_, true);
    }

    //! non-copyable: delete copy-constructor
    TemporaryDirectory(const TemporaryDirectory&) = delete;
    //! non-copyable: delete assignment operator
    TemporaryDirectory& operator = (const TemporaryDirectory&) = delete;

    //! return the temporary directory name
    const std::string & get() const { return dir_; }

    //! wipe contents of directory
    void wipe() const {
        wipe_directory(dir_, false);
    }

protected:
    std::string dir_;
};

TEST(IO, ReadSingleFile) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 1;
            for (int element : out_vec) {
                ASSERT_EQ(element, i++);
            }

            ASSERT_EQ((size_t)16, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadFolder) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            ASSERT_EQ(ReadLines(ctx, "read_folder/*").Size(), 20);
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadPartOfFolderCompressed) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            // folder read_ints contains compressed and non-compressed files with integers
            // from 25 to 1 and a file 'donotread', which contains non int-castable
            // strings
            auto integers = ReadLines(ctx, "read_ints/read*")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 25;
            for (int element : out_vec) {
                ASSERT_EQ(element, i--);
            }

            ASSERT_EQ((size_t)25, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, GenerateFromFileRandomIntegers) {
    api::RunSameThread(
        [](api::Context& ctx) {
            std::default_random_engine generator({ std::random_device()() });
            std::uniform_int_distribution<int> distribution(1000, 10000);

            size_t generate_size = distribution(generator);

            auto input = GenerateFromFile(
                ctx,
                "test1",
                [](const std::string& line) {
                    return std::stoi(line);
                },
                generate_size);

            size_t writer_size = 0;

            input.Map(
                [&writer_size](const int& item) {
                    // file contains ints between 1  and 16
                    // fails if wrong integer is generated
                    EXPECT_GE(item, 1);
                    EXPECT_GE(16, item);
                    writer_size++;
                    return std::to_string(item) + "\n";
                })
            .WriteLinesMany("out1_");

            // DIA contains as many elements as we wanted to generate
            ASSERT_EQ(generate_size, writer_size);
        });
}

TEST(IO, GenerateIntegerWriteReadBinary) {
    TemporaryDirectory tmpdir;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of integers and write them to disk
            size_t generate_size = 320000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) { return index + 42; },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.IntegerBinary",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the integers from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<size_t>(
                    ctx,
                    tmpdir.get() + "/IO.IntegerBinary-*");

                std::vector<size_t> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(42 + i, vec[i]);
                }
            }
        });
}

// make weird test strings of different lengths
std::string test_string(size_t index) {
    return std::string('0' + index % 100, (index * index) % 20);
}

TEST(IO, GenerateStringWriteBinary) {
    TemporaryDirectory tmpdir;

    // use pairs for easier checking and stranger string sizes.
    using Item = std::pair<size_t, std::string>;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of string Items and write them to disk
            size_t generate_size = 320000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) {
                        return Item(index, test_string(index));
                    },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.StringBinary",
                                16 * 1024);
            }
            ctx.Barrier();

#if 0
            // read the Items from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<Item>(
                    ctx,
                    tmpdir.get() + "/IO.StringBinary-*");

                std::vector<Item> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(Item(i, test_string(i)), vec[i]);
                }
            }
#endif
        });
}

TEST(IO, WriteBinaryCorrectSize) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {

            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            integers.WriteBinary("binary/output_");

            ctx.Barrier();

            if (ctx.my_rank() == 0) {
                glob_t glob_result;
                struct stat filestat;
                glob("binary/*", GLOB_TILDE, nullptr, &glob_result);
                size_t directory_size = 0;

                for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
                    const char* filepath = glob_result.gl_pathv[i];

                    if (stat(filepath, &filestat)) {
                        throw std::runtime_error(
                                  "ERROR: Invalid file " + std::string(filepath));
                    }
                    if (!S_ISREG(filestat.st_mode)) continue;

                    directory_size += filestat.st_size;

                    remove(filepath);
                }
                globfree(&glob_result);

                ASSERT_EQ(16 * sizeof(int), directory_size);
            }
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadBinary) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {

            std::string path = "testsf.out";

            auto integers2 = api::ReadBinary<int>(
                ctx, "./binary" + std::to_string(ctx.num_workers()) + "/*");

            integers2.Map(
                [](const int& item) {
                    return std::to_string(item);
                })
            .WriteLines(path);

            // Race condition as one worker might be finished while others are
            // still writing to output file.
            ctx.Barrier();

            std::ifstream file(path);
            size_t begin = file.tellg();
            file.seekg(0, std::ios::end);
            size_t end = file.tellg();
            ASSERT_EQ(end - begin, 39);
            file.seekg(0);
            for (int i = 1; i <= 16; i++) {
                std::string line;
                std::getline(file, line);
                ASSERT_EQ(std::stoi(line), i);
            }
        };

    api::RunLocalTests(start_func);
}

/******************************************************************************/
<|endoftext|>


<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2011, Michele Bosi                                             */
/*  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.                                   */
/*                                                                                */
/*  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.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef TypInfo_INCLUDE_ONCE
#define TypInfo_INCLUDE_ONCE

/**
 * \file TypeInfo.hpp
 * Set of macros and templates implementing a simple portable RTTI system.
*/

//! Represents a class type.
struct TypeInfo
{
  TypeInfo(const char* name): Name(name)
  {
    // just for debugging
    // printf("Initializing TypeInfo \"%s\" at %p\n", name, this);
  }
  const char* Name;
};

#define INSTRUMENT_BASE_CLASS(ClassName)                                                                    \
public:                                                                                \
  /* static functions */                                                                                \
  static const char* staticName() { return #ClassName; }                                                    \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
  /* virtual functions */                                                                                \
  virtual const char* objectName() const { return #ClassName; }                                             \
  virtual const TypeInfo* objectType() const { return staticType(); }                                       \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType();                                                                            \
  }                                                                                \
private:

#define INSTRUMENT_CLASS(ClassName, BaseClass)                                                              \
private:                                                                                \
  typedef BaseClass super;                                                                                \
public:                                                                                \
  /* static functions */                                                                                \
  static const char* staticName() { return #ClassName; }                                                    \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
  /* virtual functions */                                                                                \
  virtual const char* objectName() const { return #ClassName; }                                             \
  virtual const TypeInfo* objectType() const { return staticType(); }                                       \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType() || super::isOfType(type);                                                   \
  }                                                                                \
private:

#define INSTRUMENT_CLASS2(ClassName, BaseClass1, BaseClass2)                                                \
private:                                                                                \
  typedef BaseClass1 super1;                                                                                \
  typedef BaseClass2 super2;                                                                                \
public:                                                                                \
  /* static functions */                                                                                \
  static const char* staticName() { return #ClassName; }                                                    \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
  /* virtual functions */                                                                                \
  virtual const char* objectName() const { return #ClassName; }                                             \
  virtual const TypeInfo* objectType() const { return staticType(); }                                       \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType() || super1::isOfType(type) || super2::isOfType(type);                        \
  }                                                                                \
private:

template<class B, class A>
B* vl_cast(A obj)
{
  if(obj->isOfType(B::staticType()))
    return static_cast<B*>(obj);
  else
    return NULL;
}

template<class B, class A>
const B* vl_const_cast(const A obj)
{
  if(obj->isOfType(B::staticType()))
    return static_cast<const B*>(obj);
  else
    return NULL;
}

/******************************************************************************
 USAGE EXAMPLES
*******************************************************************************

class Base
{
  INSTRUMENT_BASE_CLASS(Base)
};

class ClassA: public Base
{
  INSTRUMENT_CLASS(vl::ClassA, Base)
};

class ClassB: public ClassA
{
  INSTRUMENT_CLASS(vl::ClassB, ClassA)
};

class ClassC: public Base
{
  INSTRUMENT_CLASS(vl::ClassC, Base)
};

class ClassD: public ClassC
{
  INSTRUMENT_CLASS(vl::ClassD, ClassC)
};

class ClassBD: public ClassB, public ClassD
{
  INSTRUMENT_CLASS2(vl::ClassBD, ClassB, ClassD)
};

*******************************************************************************/

#endif
<commit_msg>TypeInfo: simple portable RTTI implementation.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2011, Michele Bosi                                             */
/*  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.                                   */
/*                                                                                */
/*  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.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef TypInfo_INCLUDE_ONCE
#define TypInfo_INCLUDE_ONCE

/**
 * \file TypeInfo.hpp
 * Set of macros and templates implementing a simple portable RTTI system.
*/

//! Represents a class type.
struct TypeInfo
{
  TypeInfo(const char* name): Name(name)
  {
    // just for debugging
    // printf("Initializing TypeInfo \"%s\" at %p\n", name, this);
  }
  const char* Name;
};

#define INSTRUMENT_BASE_CLASS(ClassName)                                                                    \
public:                                                                                \
  /* static functions */                                                                                \
  /** Returns the name of the class. */                                                                     \
  static const char* staticName() { return #ClassName; }                                                    \
  /** Returns the TypeInfo of the class. */                                                                 \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
                                                                                \
  /* virtual functions */                                                                                \
  /** Returns the name of the object's class. */                                                            \
  virtual const char* className() const { return #ClassName; }                                              \
  /** Returns the TypeInfo of the object's class. */                                                        \
  virtual const TypeInfo* classType() const { return staticType(); }                                        \
  /** Returns \a true if \a type matches the object's class type. */                                        \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType();                                                                            \
  }                                                                                \
private:

#define INSTRUMENT_CLASS(ClassName, BaseClass)                                                              \
private:                                                                                \
  typedef BaseClass super;                                                                                \
public:                                                                                \
  /* static functions */                                                                                \
  /** Returns the name of the class. */                                                                     \
  static const char* staticName() { return #ClassName; }                                                    \
  /** Returns the TypeInfo of the class. */                                                                 \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
                                                                                \
  /* virtual functions */                                                                                \
  /** Returns the name of the object's class. */                                                            \
  virtual const char* className() const { return #ClassName; }                                              \
  /** Returns the TypeInfo of the object's class. */                                                        \
  virtual const TypeInfo* classType() const { return staticType(); }                                        \
  /** Returns \a true if \a type matches the object's class type. */                                        \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType() || super::isOfType(type);                                                   \
  }                                                                                \
private:

#define INSTRUMENT_CLASS2(ClassName, BaseClass1, BaseClass2)                                                \
private:                                                                                \
  typedef BaseClass1 super1;                                                                                \
  typedef BaseClass2 super2;                                                                                \
public:                                                                                \
  /* static functions */                                                                                \
  /** Returns the name of the class. */                                                                     \
  static const char* staticName() { return #ClassName; }                                                    \
  /** Returns the TypeInfo of the class. */                                                                 \
  static const TypeInfo* staticType() { static const TypeInfo class_type(#ClassName); return &class_type; } \
                                                                                \
  /* virtual functions */                                                                                \
  /** Returns the name of the object's class. */                                                            \
  virtual const char* className() const { return #ClassName; }                                              \
  /** Returns the TypeInfo of the object's class. */                                                        \
  virtual const TypeInfo* classType() const { return staticType(); }                                        \
  /** Returns \a true if \a type matches the object's class type. */                                        \
  virtual bool isOfType(const TypeInfo* type) const                                                         \
  {                                                                                \
    return type == staticType() || super1::isOfType(type) || super2::isOfType(type);                        \
  }                                                                                \
private:

template<class B, class A>
B* vl_cast(A obj)
{
  if(obj->isOfType(B::staticType()))
    return static_cast<B*>(obj);
  else
    return NULL;
}

template<class B, class A>
const B* vl_const_cast(const A obj)
{
  if(obj->isOfType(B::staticType()))
    return static_cast<const B*>(obj);
  else
    return NULL;
}

/******************************************************************************
 USAGE EXAMPLES
*******************************************************************************

class Base
{
  INSTRUMENT_BASE_CLASS(Base)
};

class ClassA: public Base
{
  INSTRUMENT_CLASS(vl::ClassA, Base)
};

class ClassB: public ClassA
{
  INSTRUMENT_CLASS(vl::ClassB, ClassA)
};

class ClassC: public Base
{
  INSTRUMENT_CLASS(vl::ClassC, Base)
};

class ClassD: public ClassC
{
  INSTRUMENT_CLASS(vl::ClassD, ClassC)
};

class ClassBD: public ClassB, public ClassD
{
  INSTRUMENT_CLASS2(vl::ClassBD, ClassB, ClassD)
};

*******************************************************************************/

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Jeongseok Lee <jslee02@gmail.com>
 *
 * 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 <gtest/gtest.h>

#include "dart/dart.h"

using namespace std;
using namespace Eigen;
using namespace dart;
using namespace common;
using namespace dynamics;
using namespace simulation;

static int callCount0 = 0;
static int callCount1 = 0;
static int callCount2 = 0;

//==============================================================================
void foo0() { callCount0++; }
void foo1(int /*_val*/) { callCount1++; }
void foo2(int /*_val1*/, float /*_val2*/) { callCount2++; }
double foo3() { return 10.0; }

//==============================================================================
class Viewer
{
public:
  static void onSignal1Static(int /*_val*/) { callCount1++; }
  static void onSignal2Static(int /*_val1*/, float /*_val2*/) { callCount2++; }
  void onSignal1(int /*_val*/) { callCount1++; }
  void onSignal2(int /*_val1*/, float /*_val2*/) { callCount2++; }
};

//==============================================================================
TEST(Signal, Basic)
{
  Signal<void()> signal0;
  Signal<void(int)> signal1;
  Signal<void(int, float)> signal2;
  Signal<double()> signal3;

  Connection connection0 = signal0.connect(&foo0);
  Connection connection1 = signal1.connect(&foo1);
  Connection connection2 = signal2.connect(&foo2);
  Connection connection3 = signal3.connect(&foo3);

  EXPECT_EQ(signal0.getNumConnections(), 1);
  EXPECT_EQ(signal1.getNumConnections(), 1);
  EXPECT_EQ(signal2.getNumConnections(), 1);
  EXPECT_EQ(signal3.getNumConnections(), 1);

  EXPECT_TRUE(connection0.isConnected());
  EXPECT_TRUE(connection1.isConnected());
  EXPECT_TRUE(connection2.isConnected());
  EXPECT_TRUE(connection3.isConnected());

  connection0.disconnect();
  connection1.disconnect();
  connection2.disconnect();
  connection3.disconnect();

  // The connections are still exist in the signal as disconnected state.
  // The disconnected connections will be removed when the signal raises or
  // flushDisconnections() is explictly called.
  EXPECT_EQ(signal0.getNumConnections(), 0);
  EXPECT_EQ(signal1.getNumConnections(), 0);
  EXPECT_EQ(signal2.getNumConnections(), 0);
  EXPECT_EQ(signal3.getNumConnections(), 0);

  signal0();

  EXPECT_FALSE(connection0.isConnected());
  EXPECT_FALSE(connection1.isConnected());
  EXPECT_FALSE(connection2.isConnected());
  EXPECT_FALSE(connection3.isConnected());
}

//==============================================================================
TEST(Signal, NonStaticMemberFunction)
{
  Signal<void(int)> signal1;
  Signal<void(int, float)> signal2;
  Viewer viewer;

  // Connect static member function
  signal1.connect(&Viewer::onSignal1Static);
  signal2.connect(&Viewer::onSignal2Static);

  // Connect non-static member function
  using placeholders::_1;
  using placeholders::_2;
  signal1.connect(bind(&Viewer::onSignal1, &viewer, _1));
  signal2.connect(bind(&Viewer::onSignal2, &viewer, _1, _2));

  // The signal should have the maximum number of listeners
  EXPECT_EQ(signal1.getNumConnections(), 2);
  EXPECT_EQ(signal2.getNumConnections(), 2);

  // Check the number of calls
  callCount1 = 0;
  callCount2 = 0;
  signal1.raise(0);
  signal2.raise(0, 0);
  EXPECT_EQ(callCount1, 2);
  EXPECT_EQ(callCount2, 2);
}

//==============================================================================
float product(float x, float y) { return x * y; }
float quotient(float x, float y) { return x / y; }
float sum(float x, float y) { return x + y; }
float difference(float x, float y) { return x - y; }

// combiner which returns the maximum value returned by all slots
template <typename T>
struct maximum
{
  typedef T result_type;

  template <typename InputIterator>
  static T process(InputIterator first, InputIterator last)
  {
    // If there are no slots to call, just return the
    // default-constructed value
    if (first == last)
      return T();

    T max_value = *first++;

    while (first != last)
    {
      if (max_value < *first)
        max_value = *first;
      ++first;
    }

    return max_value;
  }
};

//==============================================================================
TEST(Signal, ReturnValues)
{
  Signal<float(float, float)> signal1;

  signal1.connect(&product);
  signal1.connect(&quotient);
  signal1.connect(&sum);
  signal1.connect(&difference);

  EXPECT_EQ(signal1(5, 3), 2);

  Signal<float(float, float), maximum> signal2;

  signal2.connect(&product);
  signal2.connect(&quotient);
  signal2.connect(&sum);
  signal2.connect(&difference);

  EXPECT_EQ(signal2(5, 3), 15);
}

////==============================================================================
//TEST(Signal, SignalToSignal)
//{
//  Signal<void(int)> signal1;
//  Signal<void(int)> signal2;

//  Connection connection = signal1.connect(signal2);
//  signal2.connect(foo1);
//  signal2.connect(foo1);
//  signal2.connect(foo1);
//  signal2.connect(foo1);

//  signal1.raise(0);

//  // Check the number of calls
//  callCount1 = 0;
//  signal1.raise(0);
//  EXPECT_EQ(callCount1, 4);

//  // Check the number of calls
//  callCount1 = 0;
//  signal1(0);
//  EXPECT_EQ(callCount1, 4);

//  connection.disconnect();

//  // Check the number of calls
//  callCount1 = 0;
//  signal1.raise(0);
//  EXPECT_EQ(callCount1, 0);

//  // Check the number of calls
//  callCount1 = 0;
//  signal1(0);
//  EXPECT_EQ(callCount1, 0);

//  signal1.disconnectAll();
//  EXPECT_EQ(signal1.getNumConnections(), 0);

//  auto connection2 = signal1.connect(signal1);
//  EXPECT_EQ(signal1.getNumConnections(), 0);
//  EXPECT_FALSE(connection2.isConnected());
//  signal1(0);
//  EXPECT_EQ(callCount1, 0);
//}

//==============================================================================
void frameChangecCallback(const Entity* _entity,
                          const Frame* _oldParentFrame,
                          const Frame* _newParentFrame)
{
  assert(_entity);

  std::string oldFrameName
      = _oldParentFrame == nullptr ? "(empty)" : _oldParentFrame->getName();
  std::string newFrameName
      = _newParentFrame == nullptr ? "(empty)" : _newParentFrame->getName();

  std::cout << "[" << _entity->getName() << "]: "
            << oldFrameName << " --> " << newFrameName << std::endl;
}

//==============================================================================
void vizShapeAddedCallback(const Entity* _entity,
                           const Shape* _newShape)
{
  assert(_entity);

  std::cout << "[" << _entity->getName() << "]: New shape '"
            << _newShape->getShapeType() << "' type added." << std::endl;
}

//==============================================================================
TEST(Signal, FrameSignals)
{
  Isometry3d tf1(Isometry3d::Identity());
  tf1.translate(Vector3d(0.1,-0.1,0));

  Isometry3d tf2(Isometry3d::Identity());
  tf2.translate(Vector3d(0,0.1,0));
  tf2.rotate(AngleAxisd(45.0*M_PI/180.0, Vector3d(1,0,0)));

  Isometry3d tf3(Isometry3d::Identity());
  tf3.translate(Vector3d(0,0,0.1));
  tf3.rotate(AngleAxisd(60*M_PI/180.0, Vector3d(0,1,0)));

  SimpleFrame F1(Frame::World(), "F1", tf1);
  SimpleFrame F2(&F1, "F2", tf2);
  SimpleFrame F3(&F2, "F3", tf3);

  Connection cf1 = F1.onFrameChanged.connect(frameChangecCallback);
  Connection cf2 = F2.onFrameChanged.connect(frameChangecCallback);
  ScopedConnection cf3(F3.onFrameChanged.connect(frameChangecCallback));

  Connection cv1 = F1.onVizShapeAdded.connect(vizShapeAddedCallback);
  Connection cv2 = F2.onVizShapeAdded.connect(vizShapeAddedCallback);
  ScopedConnection cv3(F3.onVizShapeAdded.connect(vizShapeAddedCallback));

  F1.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));
  F2.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));
  F3.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));

  F3.setParentFrame(&F1);
}

//==============================================================================
int main(int argc, char* argv[])
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<commit_msg>Update tests for Signal 1) Remove signal-to-signal test 2) Add scoped connection test 3) Update return value test<commit_after>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Jeongseok Lee <jslee02@gmail.com>
 *
 * 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 <gtest/gtest.h>

#include "dart/dart.h"

using namespace std;
using namespace Eigen;
using namespace dart;
using namespace common;
using namespace dynamics;
using namespace simulation;

static int callCount0 = 0;
static int callCount1 = 0;
static int callCount2 = 0;

//==============================================================================
void foo0() { callCount0++; }
void foo1(int /*_val*/) { callCount1++; }
void foo2(int /*_val1*/, float /*_val2*/) { callCount2++; }
double foo3() { return 10.0; }

//==============================================================================
class Viewer
{
public:
  static void onSignal1Static(int /*_val*/) { callCount1++; }
  static void onSignal2Static(int /*_val1*/, float /*_val2*/) { callCount2++; }
  void onSignal1(int /*_val*/) { callCount1++; }
  void onSignal2(int /*_val1*/, float /*_val2*/) { callCount2++; }
};

//==============================================================================
TEST(Signal, Basic)
{
  Signal<void()> signal0;
  Signal<void(int)> signal1;
  Signal<void(int, float)> signal2;
  Signal<double()> signal3;

  Connection connection0 = signal0.connect(&foo0);
  Connection connection1 = signal1.connect(&foo1);
  Connection connection2 = signal2.connect(&foo2);
  Connection connection3 = signal3.connect(&foo3);

  EXPECT_EQ(signal0.getNumConnections(), 1);
  EXPECT_EQ(signal1.getNumConnections(), 1);
  EXPECT_EQ(signal2.getNumConnections(), 1);
  EXPECT_EQ(signal3.getNumConnections(), 1);

  EXPECT_TRUE(connection0.isConnected());
  EXPECT_TRUE(connection1.isConnected());
  EXPECT_TRUE(connection2.isConnected());
  EXPECT_TRUE(connection3.isConnected());

  connection0.disconnect();
  connection1.disconnect();
  connection2.disconnect();
  connection3.disconnect();

  EXPECT_EQ(signal0.getNumConnections(), 0);
  EXPECT_EQ(signal1.getNumConnections(), 0);
  EXPECT_EQ(signal2.getNumConnections(), 0);
  EXPECT_EQ(signal3.getNumConnections(), 0);

  signal0();

  EXPECT_FALSE(connection0.isConnected());
  EXPECT_FALSE(connection1.isConnected());
  EXPECT_FALSE(connection2.isConnected());
  EXPECT_FALSE(connection3.isConnected());
}

//==============================================================================
TEST(Signal, NonStaticMemberFunction)
{
  Signal<void(int)> signal1;
  Signal<void(int, float)> signal2;
  Viewer viewer;

  // Connect static member function
  signal1.connect(&Viewer::onSignal1Static);
  signal2.connect(&Viewer::onSignal2Static);

  // Connect non-static member function
  using placeholders::_1;
  using placeholders::_2;
  signal1.connect(bind(&Viewer::onSignal1, &viewer, _1));
  signal2.connect(bind(&Viewer::onSignal2, &viewer, _1, _2));

  // The signal should have the maximum number of listeners
  EXPECT_EQ(signal1.getNumConnections(), 2);
  EXPECT_EQ(signal2.getNumConnections(), 2);

  // Check the number of calls
  callCount1 = 0;
  callCount2 = 0;
  signal1.raise(0);
  signal2.raise(0, 0);
  EXPECT_EQ(callCount1, 2);
  EXPECT_EQ(callCount2, 2);
}

//==============================================================================
TEST(Signal, ScopedConnection)
{
  Signal<void(int)> signal;
  Connection c = signal.connect(foo1);
  EXPECT_EQ(signal.getNumConnections(), 1);

  {
    ScopedConnection sc(signal.connect(foo1));
    EXPECT_EQ(signal.getNumConnections(), 2);
  }

  EXPECT_EQ(signal.getNumConnections(), 1);
}

//==============================================================================
float product(float x, float y) { return x * y; }
float quotient(float x, float y) { return x / y; }
float sum(float x, float y) { return x + y; }
float difference(float x, float y) { return x - y; }

// combiner which returns the maximum value returned by all slots
template <typename T>
struct signal_maximum
{
  typedef T result_type;

  template <typename InputIterator>
  static T process(InputIterator first, InputIterator last)
  {
    // If there are no slots to call, just return the
    // default-constructed value
    if (first == last)
      return T();

    T max_value = *first++;

    while (first != last)
    {
      if (max_value < *first)
        max_value = *first;
      ++first;
    }

    return max_value;
  }
};

// combiner which returns the maximum value returned by all slots
template <typename T>
struct signal_sum
{
  typedef T result_type;

  template <typename InputIterator>
  static T process(InputIterator first, InputIterator last)
  {
    // If there are no slots to call, just return the
    // default-constructed value
    if (first == last)
      return T();

    T sum = *first;
    first++;

    while (first != last)
    {
      sum += *first;
      ++first;
    }

    return sum;
  }
};

//==============================================================================
TEST(Signal, ReturnValues)
{
  const float tol = 1e-6;

  const float a = 5.0f;
  const float b = 3.0f;

  std::vector<float> res(4);
  res[0] = product(a, b);
  res[1] = quotient(a, b);
  res[2] = sum(a, b);
  res[3] = difference(a, b);

  Signal<float(float, float), signal_maximum> signal1;
  signal1.connect(&product);
  signal1.connect(&quotient);
  signal1.connect(&sum);
  signal1.connect(&difference);
  EXPECT_EQ(signal1(5, 3), *std::max_element(res.begin(), res.end()));

  Signal<float(float, float), signal_sum> signal2;
  signal2.connect(&product);
  signal2.connect(&quotient);
  signal2.connect(&sum);
  signal2.connect(&difference);
  EXPECT_NEAR(signal2(5, 3), std::accumulate(res.begin(), res.end(), 0.0), tol);
}

//==============================================================================
void frameChangecCallback(const Entity* _entity,
                          const Frame* _oldParentFrame,
                          const Frame* _newParentFrame)
{
  assert(_entity);

  std::string oldFrameName
      = _oldParentFrame == nullptr ? "(empty)" : _oldParentFrame->getName();
  std::string newFrameName
      = _newParentFrame == nullptr ? "(empty)" : _newParentFrame->getName();

  std::cout << "[" << _entity->getName() << "]: "
            << oldFrameName << " --> " << newFrameName << std::endl;
}

//==============================================================================
void vizShapeAddedCallback(const Entity* _entity,
                           const Shape* _newShape)
{
  assert(_entity);

  std::cout << "[" << _entity->getName() << "]: New shape '"
            << _newShape->getShapeType() << "' type added." << std::endl;
}

//==============================================================================
TEST(Signal, FrameSignals)
{
  Isometry3d tf1(Isometry3d::Identity());
  tf1.translate(Vector3d(0.1,-0.1,0));

  Isometry3d tf2(Isometry3d::Identity());
  tf2.translate(Vector3d(0,0.1,0));
  tf2.rotate(AngleAxisd(45.0*M_PI/180.0, Vector3d(1,0,0)));

  Isometry3d tf3(Isometry3d::Identity());
  tf3.translate(Vector3d(0,0,0.1));
  tf3.rotate(AngleAxisd(60*M_PI/180.0, Vector3d(0,1,0)));

  SimpleFrame F1(Frame::World(), "F1", tf1);
  SimpleFrame F2(&F1, "F2", tf2);
  SimpleFrame F3(&F2, "F3", tf3);

  Connection cf1 = F1.onFrameChanged.connect(frameChangecCallback);
  Connection cf2 = F2.onFrameChanged.connect(frameChangecCallback);
  ScopedConnection cf3(F3.onFrameChanged.connect(frameChangecCallback));

  Connection cv1 = F1.onVizShapeAdded.connect(vizShapeAddedCallback);
  Connection cv2 = F2.onVizShapeAdded.connect(vizShapeAddedCallback);
  ScopedConnection cv3(F3.onVizShapeAdded.connect(vizShapeAddedCallback));

  F1.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));
  F2.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));
  F3.addVisualizationShape(new BoxShape(Vector3d(0.05, 0.05, 0.02)));

  F3.setParentFrame(&F1);
}

//==============================================================================
int main(int argc, char* argv[])
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<|endoftext|>


<commit_before>#include <common-ee.h>
#include <assert.h>
#include <kernel.h>
#include "dmaregs.h"
#include "dmasend.h"

namespace DMA {
	void SendSimple(volatile Channel *chan, void *data, int size) {
		// Must be aligned to 16 bytes.
		assert((size & 0xf) == 0 && (((u32)data) & 0xf) == 0);

		// First, we need to flush the dcache for this data.
		SyncDCache(data, (u8 *)data + size);

		// Enable DMA, and turn off release signal/cycle, MFIFO, and stall control.
		*D_CTRL = D_CTRL_DMAE;

		// Now set the packet address and size.
		chan->madr = data;
		chan->qwc = size / 16;
		chan->tadr = 0;

		if (chan->madr != data) {
			printf("WARNING: DMA transfer did not accept MADR: %08x\n", (u32)chan->madr ^ (u32)data);
		}
		const char *madrStart = (const char *)chan->madr;

		// And start the transfer.  Let's keep it simple.
		chan->chcr |= CHCR_STR;

		int i = 100000;
		while (--i > 0 && chan->chcr.Ongoing()) {
			continue;
		}

		if (chan->madr != madrStart + size) {
			printf("WARNING: DMA transfer MADR did not increase as expected: %08x\n", (u32)chan->madr ^ (u32)data);
		}

		if (i == 0) {
			printf("ERROR: DMA transfer timed out.\n");
		}
	}

	void SendChain(volatile Channel *chan, void *dmatag, int size) {
		// Must be aligned to 16 bytes.
		assert((size & 0xf) == 0 && (((u32)dmatag) & 0xf) == 0);

		// We need to flush the dcache for the tag.  The caller will need to flush for the data.
		SyncDCache(dmatag, (u8 *)dmatag + size);

		// Here, we only need the tag address.
		chan->madr = 0;
		chan->qwc = 0;
		chan->tadr = dmatag;

		// Start the transfer in chain mode.
		chan->chcr = (chan->chcr & ~CHCR_MOD_ANY) | CHCR_MOD_CHAIN | CHCR_STR;

		int i = 100000;
		while (--i > 0 && chan->chcr.Ongoing()) {
			continue;
		}

		// Clear the mode back for next time.
		chan->chcr &= ~CHCR_MOD_ANY;

		if (i == 0) {
			printf("ERROR: DMA transfer timed out.\n");
		}
	}
}
<commit_msg>Set "from memory" flag for DMA transfers.<commit_after>#include <common-ee.h>
#include <assert.h>
#include <kernel.h>
#include "dmaregs.h"
#include "dmasend.h"

namespace DMA {
	void SendSimple(volatile Channel *chan, void *data, int size) {
		// Must be aligned to 16 bytes.
		assert((size & 0xf) == 0 && (((u32)data) & 0xf) == 0);

		// First, we need to flush the dcache for this data.
		SyncDCache(data, (u8 *)data + size);

		// Enable DMA, and turn off release signal/cycle, MFIFO, and stall control.
		*D_CTRL = D_CTRL_DMAE;

		// Now set the packet address and size.
		chan->madr = data;
		chan->qwc = size / 16;
		chan->tadr = 0;

		if (chan->madr != data) {
			printf("WARNING: DMA transfer did not accept MADR: %08x\n", (u32)chan->madr ^ (u32)data);
		}
		const char *madrStart = (const char *)chan->madr;

		// And start the transfer.  Let's keep it simple.
		chan->chcr |= CHCR_STR | CHCR_DIR;

		int i = 100000;
		while (--i > 0 && chan->chcr.Ongoing()) {
			continue;
		}

		if (chan->madr != madrStart + size) {
			printf("WARNING: DMA transfer MADR did not increase as expected: %08x\n", (u32)chan->madr ^ (u32)data);
		}

		if (i == 0) {
			printf("ERROR: DMA transfer timed out.\n");
		}
	}

	void SendChain(volatile Channel *chan, void *dmatag, int size) {
		// Must be aligned to 16 bytes.
		assert((size & 0xf) == 0 && (((u32)dmatag) & 0xf) == 0);

		// We need to flush the dcache for the tag.  The caller will need to flush for the data.
		SyncDCache(dmatag, (u8 *)dmatag + size);

		// Here, we only need the tag address.
		chan->madr = 0;
		chan->qwc = 0;
		chan->tadr = dmatag;

		// Start the transfer in chain mode.
		chan->chcr = (chan->chcr & ~CHCR_MOD_ANY) | CHCR_MOD_CHAIN | CHCR_STR;

		int i = 100000;
		while (--i > 0 && chan->chcr.Ongoing()) {
			continue;
		}

		// Clear the mode back for next time.
		chan->chcr &= ~CHCR_MOD_ANY;

		if (i == 0) {
			printf("ERROR: DMA transfer timed out.\n");
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>OGG and OGV added to supported media types for omnibox, href and command line.<commit_after><|endoftext|>


<commit_before><commit_msg>Kill one indentation level.<commit_after><|endoftext|>


<commit_before>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

SCENARIO("Matrix init", "[init]") {
	GIVEN("The number of lines and columns") {
		auto lines = 36;
		auto columns = 39;

		WHEN("Create instansce of Matrix") {
			Matrix matrix(lines, columns);
			THEN("The number of lines and columns must be preserved") {
				REQUIRE(matrix.GetNumberOfLines() == lines);
				REQUIRE(matrix.GetNumberOfColumns() == columns);
			}
		}
	}
}

SCENARIO("Matrix InitFromFile", "[fill]") {
	Matrix A(2, 2);
	A.InitFromFile("A2x2.txt");
	REQUIRE( A[0][0] == 1 );
	REQUIRE( A[0][1] == 1 );
	REQUIRE( A[1][0] == 2 );
	REQUIRE( A[1][1] == 2 );
}
SCENARIO("Matrix +", "[addition]") {
	Matrix A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix B(3, 3);
	B.InitFromFile("B3x3.txt");
	Matrix expected = Matrix(3, 3);
	expected.InitFromFile("(A3x3)+(B3x3).txt");

	Matrix result = A + B;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE(result[i][j] == expected[i][j]);
		}
	}
}
/*
SCENARIO("Matrix *", "[multiplication]") {
	Matrix<int> A = Matrix<int>(2, 2);
	std::ifstream("A2x2.txt") >> A;
	Matrix<int> B = Matrix<int>(2, 2);
	std::ifstream("B2x2.txt") >> B;
	Matrix<int> expected = Matrix<int>(2, 2);
	std::ifstream("A*B2x2.txt") >> expected;

	Matrix<int> result = A * B;
	REQUIRE(result == expected);
}
*/
<commit_msg>Update init.cpp<commit_after>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

SCENARIO("Matrix init", "[init]") {
	GIVEN("The number of lines and columns") {
		auto lines = 36;
		auto columns = 39;

		WHEN("Create instansce of Matrix") {
			Matrix matrix(lines, columns);
			THEN("The number of lines and columns must be preserved") {
				REQUIRE(matrix.GetNumberOfLines() == lines);
				REQUIRE(matrix.GetNumberOfColumns() == columns);
			}
		}
	}
}

SCENARIO("Matrix InitFromFile", "[fill]") {
	Matrix A(2, 2);
	A.InitFromFile("A2x2.txt");
	REQUIRE( A[0][0] == 1 );
	REQUIRE( A[0][1] == 1 );
	REQUIRE( A[1][0] == 2 );
	REQUIRE( A[1][1] == 2 );
}
SCENARIO("Matrix +", "[addition]") {
	Matrix A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix B(3, 3);
	B.InitFromFile("B3x3.txt");
	Matrix expected = Matrix(3, 3);
	expected.InitFromFile("(A3x3)+(B3x3).txt");

	Matrix result = A + B;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE(result[i][j] == expected[i][j]);
		}
	}
}

SCENARIO("Matrix *", "[multiplication]") {
	Matrix A = Matrix(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix C = Matrix(3, 1);
	C.InitFromFile("C3x1.txt");
	Matrix expected = Matrix(3, 1);
	expected.InitFrom("(A3x3)(C3x1).txt");

	Matrix result = A * B;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE(result[i][j] == expected[i][j]);
		}
	}
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE metrics test
#include <boost/test/unit_test.hpp>
#include "ten/metrics.hh"
#include <thread>
#include <atomic>

#include "ten/ewma.hh"

using namespace ten;

void my_thread() {
#if 1
    metrics::record()
        //.incr<metrics::counter>("thing")
        .counter("thing").incr();
        ;
#else
    metrics::record([](metrics::metric_group &g) {
        g.get<metrics::counter>("thing").incr();
    });
#endif
}

static const int nthreads = 100;

BOOST_AUTO_TEST_CASE(thread_local_test) {
    std::vector<std::thread> threads(nthreads);
    for (auto &i : threads) {
        i = std::move(std::thread(my_thread));
    }

    {
        auto mg = metrics::global.aggregate();
        for (auto kv : mg) {
            DVLOG(1) << "metric: " << kv.first << " = " << boost::apply_visitor(metrics::json_visitor(), kv.second);
        }
    }

    for (auto &i : threads) {
        i.join();
    }

    auto mg = metrics::global.aggregate();

    BOOST_CHECK_EQUAL(nthreads, metrics::value<metrics::counter>(mg, "thing"));
    for (auto kv : mg) {
        DVLOG(1) << "metric: " << kv.first << " = " << boost::apply_visitor(metrics::json_visitor(), kv.second);
    }
}

BOOST_AUTO_TEST_CASE(timer_test) {
    using namespace metrics;
    time_op to("timer1");
    usleep(5*1000);
    to.stop();
    auto mg = metrics::global.aggregate();
    BOOST_CHECK(value<timer>(mg, "timer1").count() >= 5);
}

BOOST_AUTO_TEST_CASE(ewma_test) {
    using namespace std::chrono;
    ewma<seconds> m1(seconds{1});
    ewma<seconds> m5(seconds{5});
    ewma<seconds> m60(seconds{60});
    for (unsigned i=0; i<60*5; ++i) {
        m1.update(10);
        m1.tick();
        m5.update(10);
        m5.tick();
        m60.update(10);
        m60.tick();
    }
    LOG(INFO) << "rate1: " << m1.rate();
    LOG(INFO) << "rate5: " << m5.rate();
    LOG(INFO) << "rate60: " << m60.rate();
}

<commit_msg>test moving avg rate conversion<commit_after>#define BOOST_TEST_MODULE metrics test
#include <boost/test/unit_test.hpp>
#include "ten/metrics.hh"
#include <thread>
#include <atomic>

#include "ten/ewma.hh"

using namespace ten;

void my_thread() {
#if 1
    metrics::record()
        //.incr<metrics::counter>("thing")
        .counter("thing").incr();
        ;
#else
    metrics::record([](metrics::metric_group &g) {
        g.get<metrics::counter>("thing").incr();
    });
#endif
}

static const int nthreads = 100;

BOOST_AUTO_TEST_CASE(thread_local_test) {
    std::vector<std::thread> threads(nthreads);
    for (auto &i : threads) {
        i = std::move(std::thread(my_thread));
    }

    {
        auto mg = metrics::global.aggregate();
        for (auto kv : mg) {
            DVLOG(1) << "metric: " << kv.first << " = " << boost::apply_visitor(metrics::json_visitor(), kv.second);
        }
    }

    for (auto &i : threads) {
        i.join();
    }

    auto mg = metrics::global.aggregate();

    BOOST_CHECK_EQUAL(nthreads, metrics::value<metrics::counter>(mg, "thing"));
    for (auto kv : mg) {
        DVLOG(1) << "metric: " << kv.first << " = " << boost::apply_visitor(metrics::json_visitor(), kv.second);
    }
}

BOOST_AUTO_TEST_CASE(timer_test) {
    using namespace metrics;
    time_op to("timer1");
    usleep(5*1000);
    to.stop();
    auto mg = metrics::global.aggregate();
    BOOST_CHECK(value<timer>(mg, "timer1").count() >= 5);
}

BOOST_AUTO_TEST_CASE(ewma_test) {
    using namespace std::chrono;
    ewma<seconds> m1(seconds{1});
    ewma<seconds> m5(seconds{5});
    ewma<seconds> m60(seconds{60});
    for (unsigned i=0; i<60*5; ++i) {
        m1.update(10);
        m1.tick();
        m5.update(10);
        m5.tick();
        m60.update(10);
        m60.tick();
    }
    LOG(INFO) << "rate1: "  << m1.rate()  << "/s, " << m1.rate<minutes>()  << "/m";
    LOG(INFO) << "rate5: "  << m5.rate()  << "/s, " << m5.rate<minutes>()  << "/m";
    LOG(INFO) << "rate60: " << m60.rate() << "/s, " << m60.rate<minutes>() << "/m";
}

<|endoftext|>