<commit_before>//$Id$

#include "AuxiliarySimulationFunctions.h"
#include <math.h>

//! Multiplies the value by two.
//! @param[in] input is the value to multiply.
//! @return the input value times two.
double hopsan::multByTwo(double input)
{
    return 2.0*input;
}

//! @brief Limits a value so it is between min and max
//! @param &value Reference pointer to the value
//! @param min Lower limit of the value
//! @param max Upper limit of the value
void hopsan::limitValue(double &value, double min, double max)
{
    if(min>max)
    {
        double temp;
        temp = max;
        max = min;
        min = temp;
    }
    if(value > max)
    {
        value = max;
    }
    else if(value < min)
    {
        value = min;
    }
}

//! @brief Converts a float point number to a boolean
//! @param value Double value to convert, 1.0 means true, 0.0 means false
bool hopsan::doubleToBool(double value)
{
    return(value > 0.5);
}

//! @brief Converts a boolean value to a float point number
//! @param value Boolean to convert, will return 1.0 if true and 0.0 if false
double hopsan::boolToDouble(bool value)
{
    if(value)
    {
        return 1.0;
    }
    return 0.0;
}

//! @brief Returns the sign of a double (-1.0 or +1.0)
//! @param x Value to determine sign on
double hopsan::sign(double x)
{
    if (x>=0.0)
    {
        return 1.0;
    }
    else
    {
        return -1.0;
    }
}

//! @brief Returns 1.0 if x is positive, else returns 0.0
//! @param x Value to determine if it is positive
double hopsan::onPositive(double x)
{
    if (x < 0.0) { return 0.0; }
    return 1.0;
}

double hopsan::dxOnPositive(double x)
{
    return 0.0;
}

//! @brief Returns 1.0 if x is negative, else returns 0.0
//! @param x Value to determine if it is positive
double hopsan::onNegative(double x)
{
    if (x < 0.0) { return 1.0; }
    return 0.0;
}

double hopsan::dxOnNegative(double x)
{
    return 0.0;
}

double hopsan::signedSquareL(double x, double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x))) * hopsan::sign(x);
}

double hopsan::dxSignedSquareL(double x, double x0)
{
    return (1.0 / (sqrt(x0 + fabs(x)) * 2.0));
}

double hopsan::squareAbsL(double x, double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x)));
}

double hopsan::dxSquareAbsL(double x, double x0)
{
    return 1.0 / (sqrt(x0 + fabs(x)) * 2.0) * hopsan::sign(x);
}

//! @brief Returns 1.0 if input variables have same sign, else returns 0.0
double hopsan::equalSigns(double x, double y)
{
    if (hopsan::sign(x) != hopsan::sign(y)) {
        return 0.0;
    }
    return 1.0;
}

//! @brief Overloads void hopsan::limitValue() with a return value.
//! @see void hopsan::limitValue(&value, min, max)
//! @param x Value to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
double hopsan::limit(double x, double xmin, double xmax)
{
    double output = x;
    hopsan::limitValue(output, xmin, xmax);
    return output;
}

//! @brief Sets the derivative of x to zero if x is outside of limits.
//! Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit(double x, double xmin, double xmax)
{
    if (x >= xmax) { return 0.0; }
    if (x <= xmin) { return 0.0; }
    return 1.0;
}

//! @brief Overloads double hopsan::limit() to also include sx (derivative of x) as input
//! @see void hopsan::limit(&x, min, max)
//! @param x Value to be limited
//! @param sx Derivative of x
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited x value
double hopsan::limit2(double x, double sx, double xmin, double xmax)
{
    return hopsan::limit(x, xmin, xmax);
}

//! @brief Limits the derivative of x when x is outside of its limits.
//! Returns 1.0 if x is within borders, or if x is outside borders but derivative has opposite sign (so that x can only move back to the limited range).
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit2(double x, double sx, double xmin, double xmax)
{
    if (x >= xmax && sx >= 0.0) { return 0.0; }
    if (x <= xmin && sx <= 0.0) { return 0.0; }
    return 1.0;
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Power(double x, double y)
{
    return pow(x, y);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Sin(double x)
{
    return sin(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Cos(double x)
{
    return cos(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Tan(double x)
{
    return tan(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Sqrt(double x)
{
    return Sqrt(x);
}
<commit_msg>Fixed Sqrt function<commit_after>//$Id$

#include "AuxiliarySimulationFunctions.h"
#include <math.h>

//! Multiplies the value by two.
//! @param[in] input is the value to multiply.
//! @return the input value times two.
double hopsan::multByTwo(double input)
{
    return 2.0*input;
}

//! @brief Limits a value so it is between min and max
//! @param &value Reference pointer to the value
//! @param min Lower limit of the value
//! @param max Upper limit of the value
void hopsan::limitValue(double &value, double min, double max)
{
    if(min>max)
    {
        double temp;
        temp = max;
        max = min;
        min = temp;
    }
    if(value > max)
    {
        value = max;
    }
    else if(value < min)
    {
        value = min;
    }
}

//! @brief Converts a float point number to a boolean
//! @param value Double value to convert, 1.0 means true, 0.0 means false
bool hopsan::doubleToBool(double value)
{
    return(value > 0.5);
}

//! @brief Converts a boolean value to a float point number
//! @param value Boolean to convert, will return 1.0 if true and 0.0 if false
double hopsan::boolToDouble(bool value)
{
    if(value)
    {
        return 1.0;
    }
    return 0.0;
}

//! @brief Returns the sign of a double (-1.0 or +1.0)
//! @param x Value to determine sign on
double hopsan::sign(double x)
{
    if (x>=0.0)
    {
        return 1.0;
    }
    else
    {
        return -1.0;
    }
}

//! @brief Returns 1.0 if x is positive, else returns 0.0
//! @param x Value to determine if it is positive
double hopsan::onPositive(double x)
{
    if (x < 0.0) { return 0.0; }
    return 1.0;
}

double hopsan::dxOnPositive(double x)
{
    return 0.0;
}

//! @brief Returns 1.0 if x is negative, else returns 0.0
//! @param x Value to determine if it is positive
double hopsan::onNegative(double x)
{
    if (x < 0.0) { return 1.0; }
    return 0.0;
}

double hopsan::dxOnNegative(double x)
{
    return 0.0;
}

double hopsan::signedSquareL(double x, double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x))) * hopsan::sign(x);
}

double hopsan::dxSignedSquareL(double x, double x0)
{
    return (1.0 / (sqrt(x0 + fabs(x)) * 2.0));
}

double hopsan::squareAbsL(double x, double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x)));
}

double hopsan::dxSquareAbsL(double x, double x0)
{
    return 1.0 / (sqrt(x0 + fabs(x)) * 2.0) * hopsan::sign(x);
}

//! @brief Returns 1.0 if input variables have same sign, else returns 0.0
double hopsan::equalSigns(double x, double y)
{
    if (hopsan::sign(x) != hopsan::sign(y)) {
        return 0.0;
    }
    return 1.0;
}

//! @brief Overloads void hopsan::limitValue() with a return value.
//! @see void hopsan::limitValue(&value, min, max)
//! @param x Value to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
double hopsan::limit(double x, double xmin, double xmax)
{
    double output = x;
    hopsan::limitValue(output, xmin, xmax);
    return output;
}

//! @brief Sets the derivative of x to zero if x is outside of limits.
//! Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit(double x, double xmin, double xmax)
{
    if (x >= xmax) { return 0.0; }
    if (x <= xmin) { return 0.0; }
    return 1.0;
}

//! @brief Overloads double hopsan::limit() to also include sx (derivative of x) as input
//! @see void hopsan::limit(&x, min, max)
//! @param x Value to be limited
//! @param sx Derivative of x
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited x value
double hopsan::limit2(double x, double sx, double xmin, double xmax)
{
    return hopsan::limit(x, xmin, xmax);
}

//! @brief Limits the derivative of x when x is outside of its limits.
//! Returns 1.0 if x is within borders, or if x is outside borders but derivative has opposite sign (so that x can only move back to the limited range).
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit2(double x, double sx, double xmin, double xmax)
{
    if (x >= xmax && sx >= 0.0) { return 0.0; }
    if (x <= xmin && sx <= 0.0) { return 0.0; }
    return 1.0;
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Power(double x, double y)
{
    return pow(x, y);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Sin(double x)
{
    return sin(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Cos(double x)
{
    return cos(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Tan(double x)
{
    return tan(x);
}

//! @brief Wrapper function, for using Mathematica syntax
double hopsan::Sqrt(double x)
{
    return sqrt(x);
}
<|endoftext|>


<commit_before>#include "Particles.hpp"

#include <Util/Easing.hpp>

#include <SFML/Graphics/RenderTarget.hpp>

#include <algorithm>
#include <cassert>
#include <cmath>

namespace
{
	Easers::Cubic sAlphaEaser;
	sf::Texture sParticleTexture;
}

std::list<ParticleManager::Particle> ParticleManager::mParticles;

void ParticleManager::init()
{
	sParticleTexture.loadFromFile("Resources/Particles.png");
}

void ParticleManager::addParticle(Particle&& p)
{
	p.StartLife = p.Life;

	auto it = std::lower_bound(mParticles.begin(), mParticles.end(), p);
	mParticles.insert(it, std::move(p));
}
void ParticleManager::clearParticles()
{
	mParticles.clear();
}
void ParticleManager::variadic_update(float dt)
{
	for (auto it = mParticles.begin(); it != mParticles.end();)
	{
		it->Life -= dt;
		it->Velocity.y = std::min(700.f, it->Velocity.y + 400.f*dt);
		it->Position += it->Velocity * dt;
		it->Angle += it->Rotation * dt;

		it->Color.a = 255 * sAlphaEaser.Out(it->Life / it->StartLife);

		if (it->Life <= 0)
			it = mParticles.erase(it);
		else
			++it;
	}

}
void ParticleManager::draw(sf::RenderTarget& target, Level l)
{
	sf::VertexArray arr(sf::Quads);

	for (auto& p : mParticles)
	{
		if (p.Height < l)
			continue;
		else if (p.Height > l)
			break;

		sf::Vector2f xcoord(std::cos(p.Angle), std::sin(p.Angle));
		sf::Vector2f ycoord(std::cos(p.Angle - M_PI/2.f), std::sin(p.Angle - M_PI/2.f));

		arr.append(sf::Vertex(p.Position - xcoord * p.Rect.width/2.f * p.Scale - ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left, p.Rect.top)));
		arr.append(sf::Vertex(p.Position + xcoord * p.Rect.width/2.f * p.Scale - ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left + p.Rect.width, p.Rect.top)));
		arr.append(sf::Vertex(p.Position + xcoord * p.Rect.width/2.f * p.Scale + ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left + p.Rect.width, p.Rect.top + p.Rect.height)));
		arr.append(sf::Vertex(p.Position - xcoord * p.Rect.width/2.f * p.Scale + ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left, p.Rect.top + p.Rect.height)));
	}

	sf::RenderStates states;
	states.texture = &sParticleTexture;

	target.draw(arr, states);
}

<commit_msg>Clean up particles if they drop off screen<commit_after>#include "Particles.hpp"

#include <Util/Easing.hpp>

#include <SFML/Graphics/RenderTarget.hpp>

#include <algorithm>
#include <cassert>
#include <cmath>

namespace
{
	Easers::Cubic sAlphaEaser;
	sf::Texture sParticleTexture;
}

std::list<ParticleManager::Particle> ParticleManager::mParticles;

void ParticleManager::init()
{
	sParticleTexture.loadFromFile("Resources/Particles.png");
}

void ParticleManager::addParticle(Particle&& p)
{
	p.StartLife = p.Life;

	auto it = std::lower_bound(mParticles.begin(), mParticles.end(), p);
	mParticles.insert(it, std::move(p));
}
void ParticleManager::clearParticles()
{
	mParticles.clear();
}
void ParticleManager::variadic_update(float dt)
{
	for (auto it = mParticles.begin(); it != mParticles.end();)
	{
		it->Life -= dt;
		it->Velocity.y = std::min(700.f, it->Velocity.y + 400.f*dt);
		it->Position += it->Velocity * dt;
		it->Angle += it->Rotation * dt;

		it->Color.a = 255 * sAlphaEaser.Out(it->Life / it->StartLife);

		if (it->Life <= 0 || it->Position.y > 1000)
			it = mParticles.erase(it);
		else
			++it;
	}

}
void ParticleManager::draw(sf::RenderTarget& target, Level l)
{
	sf::VertexArray arr(sf::Quads);

	for (auto& p : mParticles)
	{
		if (p.Height < l)
			continue;
		else if (p.Height > l)
			break;

		sf::Vector2f xcoord(std::cos(p.Angle), std::sin(p.Angle));
		sf::Vector2f ycoord(std::cos(p.Angle - M_PI/2.f), std::sin(p.Angle - M_PI/2.f));

		arr.append(sf::Vertex(p.Position - xcoord * p.Rect.width/2.f * p.Scale - ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left, p.Rect.top)));
		arr.append(sf::Vertex(p.Position + xcoord * p.Rect.width/2.f * p.Scale - ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left + p.Rect.width, p.Rect.top)));
		arr.append(sf::Vertex(p.Position + xcoord * p.Rect.width/2.f * p.Scale + ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left + p.Rect.width, p.Rect.top + p.Rect.height)));
		arr.append(sf::Vertex(p.Position - xcoord * p.Rect.width/2.f * p.Scale + ycoord * p.Rect.height/2.f * p.Scale, p.Color,
		           sf::Vector2f(p.Rect.left, p.Rect.top + p.Rect.height)));
	}

	sf::RenderStates states;
	states.texture = &sParticleTexture;

	target.draw(arr, states);
}

<|endoftext|>


<commit_before>/*
 * Accelerometer.cpp
 *
 *  Created on: 25 May 2015
 *      Author: jeremy
 */

#include "SpiSensor.h"

namespace IO
{

	SpiSensor::SpiSensor()
	{

		if (!bcm2835_init())
		{
			std::cout << "Could not initialise bcm2835" << std::endl;
			return ;
		}

		// Bcm2835 configuration
		{
			bcm2835_spi_begin();
			bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);		// The default
			bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);						// The default
			bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_128);		//
			bcm2835_spi_chipSelect(BCM2835_SPI_CS0);						// The default
			bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);		// the default
		}

		return;
	}

	SpiSensor::~SpiSensor()
	{

		// End Spi transfer
		bcm2835_spi_end();

		// Close bcm2835 library
		bcm2835_close();

		return;
	}

	short SpiSensor::GetData(char channel)
	{

		// Select SPI channel
		char data = 0b11100000 | (channel << 3);

		char mosi[3] = {data};
		char miso[3] = {0};

		// Receive data
		bcm2835_spi_transfernb(mosi, miso, 3);

		// Calculate value from received bits
		short value = ((miso[0] & 0x01) << 11) | (miso[1] << 3) | ((miso[2] >> 5) & 0x07);

		return value;
	}

}

<commit_msg>Updated Spi sensor to make it compatible with the MCP3208.<commit_after>/*
 * Accelerometer.cpp
 *
 *  Created on: 25 May 2015
 *      Author: jeremy
 */

#include "SpiSensor.h"

namespace IO
{

	SpiSensor::SpiSensor()
	{

		if (!bcm2835_init())
		{
			std::cout << "Could not initialise bcm2835" << std::endl;
			return ;
		}

		// Bcm2835 configuration
		{
			bcm2835_spi_begin();
			bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);		// The default
			bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);						// The default
			bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_128);		//
			bcm2835_spi_chipSelect(BCM2835_SPI_CS0);						// The default
			bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);		// the default
		}

		return;
	}

	SpiSensor::~SpiSensor()
	{

		// End Spi transfer
		bcm2835_spi_end();

		// Close bcm2835 library
		bcm2835_close();

		return;
	}

	short SpiSensor::GetData(char channel)
	{

		// Select SPI channel
		char data = 0b11000000 | (channel << 3);

		char mosi[3] = {data};
		char miso[3] = {0};

		// Receive data
		bcm2835_spi_transfernb(mosi, miso, 3);

		// Calculate value from received bits
		short value = ((miso[0] & 0x01) << 11) | (miso[1] << 3) | ((miso[2] >> 5) & 0x07);

		return value;
	}

}

<|endoftext|>


<commit_before>#include "PluginProcessor.h"
#include "PluginEditor.h"
#include "util/util.h"

const double SpeedOfSound = 340.0; // m/s at 15C, normal pressure
const double cmPerMs = SpeedOfSound * 100.0 /* cm in 1 m */ / 1000.0 /* ms in 1 s*/;
const double msPerCm = 1.0 / SpeedOfSound;

DelayEditor::DelayEditor(AudioProcessorWithDelays& processor, int channelId) : _processor(processor), _channelId(channelId)
{
	_onOffSwitch.setButtonText("On");
	_onOffSwitch.addListener(this);
	_onOffSwitch.setToggleState(_processor.isEnabled(channelId), juce::sendNotificationSync);
	addAndMakeVisible(_onOffSwitch);

	_delaySlider.setSliderStyle(Slider::LinearBar);
	_delaySlider.setRange(0.0, 200, 0.1);
	_delaySlider.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
	_delaySlider.setPopupDisplayEnabled(true, this);
	_delaySlider.setTextValueSuffix(" cm");
	_delaySlider.setValue(_processor.delay(channelId));
	_delaySlider.addListener(this);
	addAndMakeVisible(_delaySlider);

	_editor.setMultiLine(false);
	_editor.addListener(this);
	_editor.setText(String(_delaySlider.getValue()));
	addAndMakeVisible(_editor);
}

void DelayEditor::sliderValueChanged(Slider* slider)
{
	const double currentDelayMs = _processor.delay(_channelId);
	const double newDelay = _delaySlider.getValue() * msPerCm;
	if (slider == &_delaySlider && fabs(newDelay - currentDelayMs) >= 0.1 * msPerCm)
	{
		_editor.setText(String(_delaySlider.getValue()));
		_processor.setDelay(newDelay, _channelId);
	}
}

void DelayEditor::textEditorReturnKeyPressed(TextEditor & editor)
{
	_delaySlider.setValue(editor.getText().getDoubleValue());
}

void DelayEditor::buttonClicked(Button* button)
{
	const bool enabled = button->getToggleState();
	if (enabled != _processor.isEnabled(_channelId))
		_processor.setEnabled(enabled, _channelId);
}

void DelayEditor::resized()
{
	auto lBounds = getLocalBounds();
	lBounds.removeFromLeft(10);
	lBounds.removeFromTop(20);
	_onOffSwitch.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), 50, 20));
	lBounds.removeFromLeft(50);

	const int textEditWidth = 50;
	_delaySlider.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), lBounds.getWidth() - 10 - textEditWidth, 20));

	lBounds.removeFromLeft(lBounds.getWidth() - 10 - textEditWidth);
	_editor.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), lBounds.getWidth(), 20));
}

//==============================================================================
AudioProcessorAudioProcessorEditor::AudioProcessorAudioProcessorEditor(AudioProcessorWithDelays& p)
	: AudioProcessorEditor(&p), processor(p)
{
	// Make sure that before the constructor has finished, you've set the
	// editor's size to whatever you need it to be.
	setSize(500, 400);

	for (int i = 0; i < processor.getTotalNumOutputChannels(); ++i)
		createEditor(i);
}

AudioProcessorAudioProcessorEditor::~AudioProcessorAudioProcessorEditor()
{
}

void AudioProcessorAudioProcessorEditor::createEditor(const int channelId)
{
	_editors.emplace_back(processor, channelId);
	addAndMakeVisible(_editors.back());
	resized();
}

//==============================================================================
void AudioProcessorAudioProcessorEditor::paint(Graphics& g)
{
	g.fillAll(Colour(251, 251, 251));
//
// 	g.setColour(Colours::black);
// 	g.setFont(15.0f);
// 	g.drawFittedText("Hello World!", getLocalBounds(), Justification::centred, 1);
}

void AudioProcessorAudioProcessorEditor::resized()
{
	auto lBounds = getLocalBounds();
	for (size_t i = 0; i < _editors.size(); ++i)
	{
		if (i > 0)
			lBounds.removeFromTop(20 + 2*20);
		_editors[i].setBounds(lBounds);
		_editors[i].resized();
	}
}
<commit_msg>Dark color scheme<commit_after>#include "PluginProcessor.h"
#include "PluginEditor.h"
#include "util/util.h"

const double SpeedOfSound = 340.0; // m/s at 15C, normal pressure
const double cmPerMs = SpeedOfSound * 100.0 /* cm in 1 m */ / 1000.0 /* ms in 1 s*/;
const double msPerCm = 1.0 / SpeedOfSound;

const auto bgColor = Colour{48, 48, 48}, textColor = Colour{200, 200, 200};

DelayEditor::DelayEditor(AudioProcessorWithDelays& processor, int channelId) : _processor(processor), _channelId(channelId)
{
	_onOffSwitch.setButtonText("On");
	_onOffSwitch.addListener(this);
	_onOffSwitch.setToggleState(_processor.isEnabled(channelId), juce::sendNotificationSync);
	_onOffSwitch.setColour(ToggleButton::textColourId, textColor);
	_onOffSwitch.setColour(ToggleButton::tickColourId, Colour(130, 130, 178));
	addAndMakeVisible(_onOffSwitch);

	_delaySlider.setSliderStyle(Slider::LinearBar);
	_delaySlider.setRange(0.0, 200, 0.1);
	_delaySlider.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
	_delaySlider.setPopupDisplayEnabled(true, this);
	_delaySlider.setTextValueSuffix(" cm");
	_delaySlider.setValue(_processor.delay(channelId));
	_delaySlider.addListener(this);
	addAndMakeVisible(_delaySlider);

	_editor.setMultiLine(false);
	_editor.addListener(this);
	_editor.setText(String(_delaySlider.getValue()));
	_editor.setColour(TextEditor::backgroundColourId, bgColor);
	_editor.setColour(TextEditor::textColourId, textColor);
	addAndMakeVisible(_editor);
}

void DelayEditor::sliderValueChanged(Slider* slider)
{
	const double currentDelayMs = _processor.delay(_channelId);
	const double newDelay = _delaySlider.getValue() * msPerCm;
	if (slider == &_delaySlider && fabs(newDelay - currentDelayMs) >= 0.1 * msPerCm)
	{
		_editor.setText(String(_delaySlider.getValue()));
		_processor.setDelay(newDelay, _channelId);
	}
}

void DelayEditor::textEditorReturnKeyPressed(TextEditor & editor)
{
	_delaySlider.setValue(editor.getText().getDoubleValue());
}

void DelayEditor::buttonClicked(Button* button)
{
	const bool enabled = button->getToggleState();
	if (enabled != _processor.isEnabled(_channelId))
		_processor.setEnabled(enabled, _channelId);
}

void DelayEditor::resized()
{
	auto lBounds = getLocalBounds();
	lBounds.removeFromLeft(10);
	lBounds.removeFromTop(20);
	_onOffSwitch.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), 50, 20));
	lBounds.removeFromLeft(50);

	const int textEditWidth = 50;
	_delaySlider.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), lBounds.getWidth() - 10 - textEditWidth, 20));

	lBounds.removeFromLeft(lBounds.getWidth() - 10 - textEditWidth);
	_editor.setBounds(Rectangle<int>(lBounds.getX(), lBounds.getY(), lBounds.getWidth(), 20));
}

//==============================================================================
AudioProcessorAudioProcessorEditor::AudioProcessorAudioProcessorEditor(AudioProcessorWithDelays& p)
	: AudioProcessorEditor(&p), processor(p)
{
	// Make sure that before the constructor has finished, you've set the
	// editor's size to whatever you need it to be.
	setSize(500, 400);

	for (int i = 0; i < processor.getTotalNumOutputChannels(); ++i)
		createEditor(i);
}

AudioProcessorAudioProcessorEditor::~AudioProcessorAudioProcessorEditor()
{
}

void AudioProcessorAudioProcessorEditor::createEditor(const int channelId)
{
	_editors.emplace_back(processor, channelId);
	addAndMakeVisible(_editors.back());
	resized();
}

//==============================================================================
void AudioProcessorAudioProcessorEditor::paint(Graphics& g)
{
	g.fillAll(bgColor);
}

void AudioProcessorAudioProcessorEditor::resized()
{
	auto lBounds = getLocalBounds();
	for (size_t i = 0; i < _editors.size(); ++i)
	{
		if (i > 0)
			lBounds.removeFromTop(20 + 2*20);
		_editors[i].setBounds(lBounds);
		_editors[i].resized();
	}
}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSurfaceInterpolationController.h"
#include "mitkMemoryUtilities.h"

mitk::SurfaceInterpolationController::SurfaceInterpolationController()
  :m_SelectedSegmentation(0)
{
  m_ReduceFilter = ReduceContourSetFilter::New();
  m_NormalsFilter = ComputeContourSetNormalsFilter::New();
  m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();

  m_ReduceFilter->SetUseProgressBar(false);
  m_NormalsFilter->SetUseProgressBar(false);
  m_InterpolateSurfaceFilter->SetUseProgressBar(false);

  m_Contours = Surface::New();

  m_PolyData = vtkSmartPointer<vtkPolyData>::New();
  m_PolyData->SetPoints(vtkPoints::New());

  m_InterpolationResult = 0;
  m_CurrentNumberOfReducedContours = 0;
}

mitk::SurfaceInterpolationController::~SurfaceInterpolationController()
{

  for (ContourListMap::iterator it = m_MapOfContourLists.begin(); it != m_MapOfContourLists.end(); it++)
  {
      for (unsigned int j = 0; j < m_MapOfContourLists.at((*it).first).size(); ++j)
      {
          delete(m_MapOfContourLists.at((*it).first).at(j).position);
      }
      m_MapOfContourLists.erase(it);
  }
}

mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance()
{
  static mitk::SurfaceInterpolationController* m_Instance;

  if ( m_Instance == 0)
  {
    m_Instance = new SurfaceInterpolationController();
  }

  return m_Instance;
}

void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour ,RestorePlanePositionOperation* op)
{
  AffineTransform3D::Pointer transform = AffineTransform3D::New();
  transform = op->GetTransform();

  mitk::Vector3D direction = op->GetDirectionVector();
  int pos (-1);

  for (unsigned int i = 0; i < m_MapOfContourLists.at(m_SelectedSegmentation).size(); i++)
  {
      itk::Matrix<float> diffM = transform->GetMatrix()-m_MapOfContourLists.at(m_SelectedSegmentation).at(i).position->GetTransform()->GetMatrix();
      bool isSameMatrix(true);
      for (unsigned int j = 0; j < 3; j++)
      {
        if (fabs(diffM[j][0]) > 0.0001 && fabs(diffM[j][1]) > 0.0001 && fabs(diffM[j][2]) > 0.0001)
        {
          isSameMatrix = false;
          break;
        }
      }
      itk::Vector<float> diffV = m_MapOfContourLists.at(m_SelectedSegmentation).at(i).position->GetTransform()->GetOffset()-transform->GetOffset();
      if ( isSameMatrix && m_MapOfContourLists.at(m_SelectedSegmentation).at(i).position->GetPos() == op->GetPos() && (fabs(diffV[0]) < 0.0001 && fabs(diffV[1]) < 0.0001 && fabs(diffV[2]) < 0.0001) )
      {
        pos = i;
        break;
      }

  }

  if (pos == -1)
  {
    //MITK_INFO<<"New Contour";
    mitk::RestorePlanePositionOperation* newOp = new mitk::RestorePlanePositionOperation (OpRESTOREPLANEPOSITION, op->GetWidth(),
      op->GetHeight(), op->GetSpacing(), op->GetPos(), direction, transform);
    ContourPositionPair newData;
    newData.contour = newContour;
    newData.position = newOp;

    m_ReduceFilter->SetInput(m_MapOfContourLists.at(m_SelectedSegmentation).size(), newContour);
    m_MapOfContourLists.at(m_SelectedSegmentation).push_back(newData);
  }
  else
  {
    //MITK_INFO<<"Modified Contour";
    m_MapOfContourLists.at(m_SelectedSegmentation).at(pos).contour = newContour;
    m_ReduceFilter->SetInput(pos, newContour);
  }

  m_ReduceFilter->Update();
  m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

  for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
  {
    m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
    m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
  }

  this->Modified();
}

void mitk::SurfaceInterpolationController::Interpolate()
{
  if (m_CurrentNumberOfReducedContours< 2)
    return;

  //Setting up progress bar
   /*
    * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
    */
  //mitk::ProgressBar::GetInstance()->AddStepsToDo(8);

  m_InterpolateSurfaceFilter->Update();

  Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput();

  vtkSmartPointer<vtkMarchingCubes> mcFilter = vtkMarchingCubes::New();
  mcFilter->SetInput(distanceImage->GetVtkImageData());
  mcFilter->SetValue(0,0);
  mcFilter->Update();

  m_InterpolationResult = 0;
  m_InterpolationResult = mitk::Surface::New();
  m_InterpolationResult->SetVtkPolyData(mcFilter->GetOutput());
  m_InterpolationResult->GetGeometry()->SetOrigin(distanceImage->GetGeometry()->GetOrigin());

  vtkSmartPointer<vtkAppendPolyData> polyDataAppender = vtkSmartPointer<vtkAppendPolyData>::New();
  for (unsigned int i = 0; i < m_ReduceFilter->GetNumberOfOutputs(); i++)
  {
    polyDataAppender->AddInput(m_ReduceFilter->GetOutput(i)->GetVtkPolyData());
  }
  polyDataAppender->Update();
  m_Contours->SetVtkPolyData(polyDataAppender->GetOutput());

  //Last progress step
  /*
   * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
   */
  //mitk::ProgressBar::GetInstance()->Progress(8);

  m_InterpolationResult->DisconnectPipeline();
}

mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult()
{
    return m_InterpolationResult;
}

mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface()
{
  return m_Contours;
}

void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage &ds)
{
  m_DataStorage = &ds;
}

void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing)
{
  m_ReduceFilter->SetMinSpacing(minSpacing);
}

void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing)
{
  m_ReduceFilter->SetMaxSpacing(maxSpacing);
  m_NormalsFilter->SetMaxSpacing(maxSpacing);
}

void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume)
{
  m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume);
}

void mitk::SurfaceInterpolationController::SetSegmentationImage(Image* workingImage)
{
  m_NormalsFilter->SetSegmentationBinaryImage(workingImage);
}

mitk::Image* mitk::SurfaceInterpolationController::GetImage()
{
  return m_InterpolateSurfaceFilter->GetOutput();
}

double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory()
{
  double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3;
  double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double);
  double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
  double percentage = sizeOfPoints/totalMem;
  return percentage;
}

void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image* segmentation)
{
  if (segmentation == m_SelectedSegmentation)
    return;

  if (segmentation == 0)
    return;

  ContourListMap::iterator it = m_MapOfContourLists.find(segmentation);

  m_SelectedSegmentation = segmentation;

  m_ReduceFilter->Reset();
  m_NormalsFilter->Reset();
  m_InterpolateSurfaceFilter->Reset();

  if (it == m_MapOfContourLists.end())
  {
    ContourPositionPairList newList;
    m_MapOfContourLists.insert(std::pair<mitk::Image*, ContourPositionPairList>(segmentation, newList));
    m_InterpolationResult = 0;
    m_CurrentNumberOfReducedContours = 0;
  }
  else
  {
    for (unsigned int i = 0; i < m_MapOfContourLists.at(m_SelectedSegmentation).size(); i++)
    {
      m_ReduceFilter->SetInput(i, m_MapOfContourLists.at(m_SelectedSegmentation).at(i).contour);
    }

    m_ReduceFilter->Update();

    m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

    for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
    {
      m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
      m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
    }
  }
  Modified();
}

void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation)
{
  if (segmentation != 0)
  {
    m_MapOfContourLists.erase(segmentation);
  }
}
<commit_msg>COMP Removed map.at() calls since this function is not yet supported by the windows compiler<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSurfaceInterpolationController.h"
#include "mitkMemoryUtilities.h"

mitk::SurfaceInterpolationController::SurfaceInterpolationController()
  :m_SelectedSegmentation(0)
{
  m_ReduceFilter = ReduceContourSetFilter::New();
  m_NormalsFilter = ComputeContourSetNormalsFilter::New();
  m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();

  m_ReduceFilter->SetUseProgressBar(false);
  m_NormalsFilter->SetUseProgressBar(false);
  m_InterpolateSurfaceFilter->SetUseProgressBar(false);

  m_Contours = Surface::New();

  m_PolyData = vtkSmartPointer<vtkPolyData>::New();
  m_PolyData->SetPoints(vtkPoints::New());

  m_InterpolationResult = 0;
  m_CurrentNumberOfReducedContours = 0;
}

mitk::SurfaceInterpolationController::~SurfaceInterpolationController()
{

  for (ContourListMap::iterator it = m_MapOfContourLists.begin(); it != m_MapOfContourLists.end(); it++)
  {
      for (unsigned int j = 0; j < m_MapOfContourLists[(*it).first].size(); ++j)
      {
          delete(m_MapOfContourLists[(*it).first].at(j).position);
      }
      m_MapOfContourLists.erase(it);
  }
}

mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance()
{
  static mitk::SurfaceInterpolationController* m_Instance;

  if ( m_Instance == 0)
  {
    m_Instance = new SurfaceInterpolationController();
  }

  return m_Instance;
}

void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour ,RestorePlanePositionOperation* op)
{
  AffineTransform3D::Pointer transform = AffineTransform3D::New();
  transform = op->GetTransform();

  mitk::Vector3D direction = op->GetDirectionVector();
  int pos (-1);

  for (unsigned int i = 0; i < m_MapOfContourLists[m_SelectedSegmentation].size(); i++)
  {
      itk::Matrix<float> diffM = transform->GetMatrix()-m_MapOfContourLists[m_SelectedSegmentation].at(i).position->GetTransform()->GetMatrix();
      bool isSameMatrix(true);
      for (unsigned int j = 0; j < 3; j++)
      {
        if (fabs(diffM[j][0]) > 0.0001 && fabs(diffM[j][1]) > 0.0001 && fabs(diffM[j][2]) > 0.0001)
        {
          isSameMatrix = false;
          break;
        }
      }
      itk::Vector<float> diffV = m_MapOfContourLists[m_SelectedSegmentation].at(i).position->GetTransform()->GetOffset()-transform->GetOffset();
      if ( isSameMatrix && m_MapOfContourLists[m_SelectedSegmentation].at(i).position->GetPos() == op->GetPos() && (fabs(diffV[0]) < 0.0001 && fabs(diffV[1]) < 0.0001 && fabs(diffV[2]) < 0.0001) )
      {
        pos = i;
        break;
      }

  }

  if (pos == -1)
  {
    //MITK_INFO<<"New Contour";
    mitk::RestorePlanePositionOperation* newOp = new mitk::RestorePlanePositionOperation (OpRESTOREPLANEPOSITION, op->GetWidth(),
      op->GetHeight(), op->GetSpacing(), op->GetPos(), direction, transform);
    ContourPositionPair newData;
    newData.contour = newContour;
    newData.position = newOp;

    m_ReduceFilter->SetInput(m_MapOfContourLists[m_SelectedSegmentation].size(), newContour);
    m_MapOfContourLists[m_SelectedSegmentation].push_back(newData);
  }
  else
  {
    //MITK_INFO<<"Modified Contour";
    m_MapOfContourLists[m_SelectedSegmentation].at(pos).contour = newContour;
    m_ReduceFilter->SetInput(pos, newContour);
  }

  m_ReduceFilter->Update();
  m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

  for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
  {
    m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
    m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
  }

  this->Modified();
}

void mitk::SurfaceInterpolationController::Interpolate()
{
  if (m_CurrentNumberOfReducedContours< 2)
    return;

  //Setting up progress bar
   /*
    * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
    */
  //mitk::ProgressBar::GetInstance()->AddStepsToDo(8);

  m_InterpolateSurfaceFilter->Update();

  Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput();

  vtkSmartPointer<vtkMarchingCubes> mcFilter = vtkMarchingCubes::New();
  mcFilter->SetInput(distanceImage->GetVtkImageData());
  mcFilter->SetValue(0,0);
  mcFilter->Update();

  m_InterpolationResult = 0;
  m_InterpolationResult = mitk::Surface::New();
  m_InterpolationResult->SetVtkPolyData(mcFilter->GetOutput());
  m_InterpolationResult->GetGeometry()->SetOrigin(distanceImage->GetGeometry()->GetOrigin());

  vtkSmartPointer<vtkAppendPolyData> polyDataAppender = vtkSmartPointer<vtkAppendPolyData>::New();
  for (unsigned int i = 0; i < m_ReduceFilter->GetNumberOfOutputs(); i++)
  {
    polyDataAppender->AddInput(m_ReduceFilter->GetOutput(i)->GetVtkPolyData());
  }
  polyDataAppender->Update();
  m_Contours->SetVtkPolyData(polyDataAppender->GetOutput());

  //Last progress step
  /*
   * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation
   */
  //mitk::ProgressBar::GetInstance()->Progress(8);

  m_InterpolationResult->DisconnectPipeline();
}

mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult()
{
    return m_InterpolationResult;
}

mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface()
{
  return m_Contours;
}

void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage &ds)
{
  m_DataStorage = &ds;
}

void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing)
{
  m_ReduceFilter->SetMinSpacing(minSpacing);
}

void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing)
{
  m_ReduceFilter->SetMaxSpacing(maxSpacing);
  m_NormalsFilter->SetMaxSpacing(maxSpacing);
}

void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume)
{
  m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume);
}

void mitk::SurfaceInterpolationController::SetSegmentationImage(Image* workingImage)
{
  m_NormalsFilter->SetSegmentationBinaryImage(workingImage);
}

mitk::Image* mitk::SurfaceInterpolationController::GetImage()
{
  return m_InterpolateSurfaceFilter->GetOutput();
}

double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory()
{
  double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3;
  double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double);
  double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
  double percentage = sizeOfPoints/totalMem;
  return percentage;
}

void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image* segmentation)
{
  if (segmentation == m_SelectedSegmentation)
    return;

  if (segmentation == 0)
    return;

  ContourListMap::iterator it = m_MapOfContourLists.find(segmentation);

  m_SelectedSegmentation = segmentation;

  m_ReduceFilter->Reset();
  m_NormalsFilter->Reset();
  m_InterpolateSurfaceFilter->Reset();

  if (it == m_MapOfContourLists.end())
  {
    ContourPositionPairList newList;
    m_MapOfContourLists.insert(std::pair<mitk::Image*, ContourPositionPairList>(segmentation, newList));
    m_InterpolationResult = 0;
    m_CurrentNumberOfReducedContours = 0;
  }
  else
  {
    for (unsigned int i = 0; i < m_MapOfContourLists[m_SelectedSegmentation].size(); i++)
    {
      m_ReduceFilter->SetInput(i, m_MapOfContourLists[m_SelectedSegmentation].at(i).contour);
    }

    m_ReduceFilter->Update();

    m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

    for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
    {
      m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
      m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
    }
  }
  Modified();
}

void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation)
{
  if (segmentation != 0)
  {
    m_MapOfContourLists.erase(segmentation);
  }
}
<|endoftext|>


<commit_before>/**
* @file Simulation.cpp
* @author Benjamin Schlotter
* Implementation of class SimulationOLD
*/

#include "Simulation.h"

using namespace naoth;
using namespace std;

Simulation::Simulation()
{
  simulationModule = registerModule<ActionSimulator>(std::string("ActionSimulator"), true);
  DEBUG_REQUEST_REGISTER("Simulation:draw_best_action", "best action", false);
  DEBUG_REQUEST_REGISTER("Simulation:use_Parameters", "use the Parameters", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:None", "DrawNone", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Short", "DrawShortKick", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Left", "DrawLeftKick", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Right", "DrawRightKick", false);
  getDebugParameterList().add(&theParameters);

  //calculate the actions
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(ActionSimulator::Action(KickActionModel::none, ActionSimulator::ActionParams(), theParameters.friction));
  action_local.push_back(ActionSimulator::Action(KickActionModel::kick_short, theParameters.kick_short, theParameters.friction)); // short
  //action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_left, theParameters.sidekick_left, theParameters.friction)); // left
  //action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_right, theParameters.sidekick_right, theParameters.friction)); // right

  actionsConsequences.resize(action_local.size());
}

Simulation::~Simulation()
{
  getDebugParameterList().remove(&theParameters);
}

void Simulation::execute()
{
  DEBUG_REQUEST("Simulation:use_Parameters",
    action_local.clear();
    action_local.reserve(KickActionModel::numOfActions);

    action_local.push_back(ActionSimulator::Action(KickActionModel::none, ActionSimulator::ActionParams(), theParameters.friction));
    action_local.push_back(ActionSimulator::Action(KickActionModel::kick_short, theParameters.kick_short, theParameters.friction)); // short
    action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_left, theParameters.sidekick_left, theParameters.friction)); // left
    action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_right, theParameters.sidekick_right, theParameters.friction)); // right

    actionsConsequences.resize(action_local.size());
  );

  //Proceed with Calculations only if ball is seen in the last 1 second
  if (!getBallModel().valid || getFrameInfo().getTimeInSeconds() >= getBallModel().getFrameInfoWhenBallWasSeen().getTimeInSeconds() + 1)
  {
    return;
  }
  // simulate the consequences for all actions
  STOPWATCH_START("Simulation:simulateAction");
  for (size_t i = 0; i < action_local.size(); i++) {
    simulationModule->getModuleT()->simulateAction(action_local[i], actionsConsequences[i], 30);
  }
  STOPWATCH_STOP("Simulation:simulateAction");

  // plot projected actions
  DEBUG_REQUEST("Simulation:ActionTarget:None", draw_action_results(actionsConsequences[0], Color(1.0, 1.0, 1.0, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Short", draw_action_results(actionsConsequences[1], Color(255.0 / 255, 172.0 / 255, 18.0 / 255, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Left", draw_action_results(actionsConsequences[2], Color(0.0 / 255, 13.0 / 255, 191.0 / 255, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Right", draw_action_results(actionsConsequences[3], Color(0.0 / 255, 191.0 / 255, 51.0 / 255, 0.7)););

  // now decide which action to execute given their consequences
  size_t best_action = decide_smart(actionsConsequences);
  getKickActionModel().bestAction = action_local[best_action].id();
  //Arghhh BUG: this expected ball pos is not affected by goal boarders/ obstacles
  getKickActionModel().expectedBallPos = getRobotPose() * action_local[best_action].predict(getBallModel().positionPreview, false);

  DEBUG_REQUEST("Simulation:draw_best_action",
    FIELD_DRAWING_CONTEXT;
  /*
  PEN("FF69B4", 35);
  std::string name = action_local[best_action].name();
  TEXT_DRAWING(getRobotPose().translation.x+100, getRobotPose().translation.y-200, name);
  */
  PEN("000000", 1);
  Vector2d expectedBallPos = getKickActionModel().expectedBallPos;
  FILLOVAL(expectedBallPos.x, expectedBallPos.y, 50, 50);

  Vector2d globalBall = getRobotPose() *getBallModel().positionPreview;
  Vector2d action_vector = (expectedBallPos - globalBall).normalize();
  Vector2d from = globalBall + action_vector * 100;
  Vector2d to = globalBall + action_vector * 350;

  PEN("FF0000", 50);
  ARROW(from.x, from.y, to.x, to.y);
  );
}//end execute

size_t Simulation::decide_smart(const std::vector<ActionSimulator::ActionResults>& actionsConsequences) const
{
  std::vector<size_t> acceptableActions;

  // select acceptable actions
  for (size_t i = 0; i < actionsConsequences.size(); ++i)
  {
    const ActionSimulator::ActionResults& results = actionsConsequences[i];

    // if an own-goal is detected, ignore the action
    if (results.category(ActionSimulator::BallPositionCategory::OWNGOAL) > 0) {
      continue;
    }

    // ignore actions with too high chance of kicking out
    double score = results.likelihood(ActionSimulator::BallPositionCategory::INFIELD) + results.likelihood(ActionSimulator::BallPositionCategory::OPPGOAL);
    if (score <= max(0.0, theParameters.good_threshold_percentage)) {
      continue;
    }

    //all actions which are not too bad
    acceptableActions.push_back(i);
  }

  // no acceptable actions
  if (acceptableActions.empty()) {
    return 0; //assumes 0 is the turn action
  }
  // there is a clear decision
  if (acceptableActions.size() == 1) {
    return acceptableActions.front();
  }

  // select the subset of actions with highest goal chance
  std::vector<size_t> goalActions;
  for (size_t i = 0; i < acceptableActions.size(); ++i)
  {
    const ActionSimulator::ActionResults& results = actionsConsequences[acceptableActions[i]];

    // chance of scoring a goal must be significant
    if (results.category(ActionSimulator::BallPositionCategory::OPPGOAL) < theParameters.minGoalParticles) {
      continue;
    }

    // there is no other action to compare yet
    if (goalActions.empty()) {
      goalActions.push_back(acceptableActions[i]);
      continue;
    }

    // the action with the highest chance of scoring the goal is the best
    if (actionsConsequences[goalActions.front()].category(ActionSimulator::BallPositionCategory::OPPGOAL) < results.category(ActionSimulator::BallPositionCategory::OPPGOAL)) {
      goalActions.clear();
      goalActions.push_back(acceptableActions[i]);
      continue;
    }

    if (actionsConsequences[goalActions.front()].category(ActionSimulator::BallPositionCategory::OPPGOAL) == results.category(ActionSimulator::BallPositionCategory::OPPGOAL)) {
      goalActions.push_back(acceptableActions[i]);
      continue;
    }
  }

  // go for the goal action!
  if (goalActions.size() == 1) {
    return goalActions.front();
  }

  // no goal actions => select one of the acceptable actions based on strategic value
  if (goalActions.empty())
  {
    size_t best_action = 0;
    double bestValue = std::numeric_limits<double>::max(); // assuming potential is [0.0, inf]
    for (std::vector<size_t>::const_iterator it = acceptableActions.begin(); it != acceptableActions.end(); ++it)
    {
      double potential = simulationModule->getModuleT()->evaluateAction(actionsConsequences[*it]);
      if (potential < bestValue) {
        best_action = *it;
        bestValue = potential;
      }
    }
    return best_action;
  }

  // find min of goalActions
  size_t best_action = 0;
  double bestValue = std::numeric_limits<double>::max(); // assuming potential is [0.0, inf]
  for (std::vector<size_t>::const_iterator it = goalActions.begin(); it != goalActions.end(); ++it)
  {
    double potential = simulationModule->getModuleT()->evaluateAction(actionsConsequences[*it]);
    if (potential < bestValue) {
      best_action = *it;
      bestValue = potential;
    }
  }
  return best_action;
}

void Simulation::draw_action_results(const ActionSimulator::ActionResults& actionsResults, const Color& color) const
{
  FIELD_DRAWING_CONTEXT;
  std::vector<ActionSimulator::CategorizedBallPosition>::const_iterator ballPosition = actionsResults.positions().begin();
  for (; ballPosition != actionsResults.positions().end(); ++ballPosition)
  {
    Vector2d ball = getRobotPose() * ballPosition->pos();
    if (ballPosition->cat() == ActionSimulator::BallPositionCategory::INFIELD)
    {
      PEN("000000", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
      PEN(color, 1);
      FILLOVAL(ball.x, ball.y, 40, 40);
    }
    else if (ballPosition->cat() == ActionSimulator::BallPositionCategory::OPPGOAL)
    {
      PEN("336600", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
    }
    else //Outside Field
    {
      PEN("66FF33", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
    }
  }
}<commit_msg>turn on sidekicks<commit_after>/**
* @file Simulation.cpp
* @author Benjamin Schlotter
* Implementation of class SimulationOLD
*/

#include "Simulation.h"

using namespace naoth;
using namespace std;

Simulation::Simulation()
{
  simulationModule = registerModule<ActionSimulator>(std::string("ActionSimulator"), true);
  DEBUG_REQUEST_REGISTER("Simulation:draw_best_action", "best action", false);
  DEBUG_REQUEST_REGISTER("Simulation:use_Parameters", "use the Parameters", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:None", "DrawNone", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Short", "DrawShortKick", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Left", "DrawLeftKick", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget:Right", "DrawRightKick", false);
  getDebugParameterList().add(&theParameters);

  //calculate the actions
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(ActionSimulator::Action(KickActionModel::none, ActionSimulator::ActionParams(), theParameters.friction));
  action_local.push_back(ActionSimulator::Action(KickActionModel::kick_short, theParameters.kick_short, theParameters.friction)); // short
  action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_left, theParameters.sidekick_left, theParameters.friction)); // left
  action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_right, theParameters.sidekick_right, theParameters.friction)); // right

  actionsConsequences.resize(action_local.size());
}

Simulation::~Simulation()
{
  getDebugParameterList().remove(&theParameters);
}

void Simulation::execute()
{
  DEBUG_REQUEST("Simulation:use_Parameters",
    action_local.clear();
    action_local.reserve(KickActionModel::numOfActions);

    action_local.push_back(ActionSimulator::Action(KickActionModel::none, ActionSimulator::ActionParams(), theParameters.friction));
    action_local.push_back(ActionSimulator::Action(KickActionModel::kick_short, theParameters.kick_short, theParameters.friction)); // short
    action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_left, theParameters.sidekick_left, theParameters.friction)); // left
    action_local.push_back(ActionSimulator::Action(KickActionModel::sidekick_right, theParameters.sidekick_right, theParameters.friction)); // right

    actionsConsequences.resize(action_local.size());
  );

  //Proceed with Calculations only if ball is seen in the last 1 second
  if (!getBallModel().valid || getFrameInfo().getTimeInSeconds() >= getBallModel().getFrameInfoWhenBallWasSeen().getTimeInSeconds() + 1)
  {
    return;
  }
  // simulate the consequences for all actions
  STOPWATCH_START("Simulation:simulateAction");
  for (size_t i = 0; i < action_local.size(); i++) {
    simulationModule->getModuleT()->simulateAction(action_local[i], actionsConsequences[i], 30);
  }
  STOPWATCH_STOP("Simulation:simulateAction");

  // plot projected actions
  DEBUG_REQUEST("Simulation:ActionTarget:None", draw_action_results(actionsConsequences[0], Color(1.0, 1.0, 1.0, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Short", draw_action_results(actionsConsequences[1], Color(255.0 / 255, 172.0 / 255, 18.0 / 255, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Left", draw_action_results(actionsConsequences[2], Color(0.0 / 255, 13.0 / 255, 191.0 / 255, 0.7)););
  DEBUG_REQUEST("Simulation:ActionTarget:Right", draw_action_results(actionsConsequences[3], Color(0.0 / 255, 191.0 / 255, 51.0 / 255, 0.7)););

  // now decide which action to execute given their consequences
  size_t best_action = decide_smart(actionsConsequences);
  getKickActionModel().bestAction = action_local[best_action].id();
  //Arghhh BUG: this expected ball pos is not affected by goal boarders/ obstacles
  getKickActionModel().expectedBallPos = getRobotPose() * action_local[best_action].predict(getBallModel().positionPreview, false);

  DEBUG_REQUEST("Simulation:draw_best_action",
    FIELD_DRAWING_CONTEXT;
  /*
  PEN("FF69B4", 35);
  std::string name = action_local[best_action].name();
  TEXT_DRAWING(getRobotPose().translation.x+100, getRobotPose().translation.y-200, name);
  */
  PEN("000000", 1);
  Vector2d expectedBallPos = getKickActionModel().expectedBallPos;
  FILLOVAL(expectedBallPos.x, expectedBallPos.y, 50, 50);

  Vector2d globalBall = getRobotPose() *getBallModel().positionPreview;
  Vector2d action_vector = (expectedBallPos - globalBall).normalize();
  Vector2d from = globalBall + action_vector * 100;
  Vector2d to = globalBall + action_vector * 350;

  PEN("FF0000", 50);
  ARROW(from.x, from.y, to.x, to.y);
  );
}//end execute

size_t Simulation::decide_smart(const std::vector<ActionSimulator::ActionResults>& actionsConsequences) const
{
  std::vector<size_t> acceptableActions;

  // select acceptable actions
  for (size_t i = 0; i < actionsConsequences.size(); ++i)
  {
    const ActionSimulator::ActionResults& results = actionsConsequences[i];

    // if an own-goal is detected, ignore the action
    if (results.category(ActionSimulator::BallPositionCategory::OWNGOAL) > 0) {
      continue;
    }

    // ignore actions with too high chance of kicking out
    double score = results.likelihood(ActionSimulator::BallPositionCategory::INFIELD) + results.likelihood(ActionSimulator::BallPositionCategory::OPPGOAL);
    if (score <= max(0.0, theParameters.good_threshold_percentage)) {
      continue;
    }

    //all actions which are not too bad
    acceptableActions.push_back(i);
  }

  // no acceptable actions
  if (acceptableActions.empty()) {
    return 0; //assumes 0 is the turn action
  }
  // there is a clear decision
  if (acceptableActions.size() == 1) {
    return acceptableActions.front();
  }

  // select the subset of actions with highest goal chance
  std::vector<size_t> goalActions;
  for (size_t i = 0; i < acceptableActions.size(); ++i)
  {
    const ActionSimulator::ActionResults& results = actionsConsequences[acceptableActions[i]];

    // chance of scoring a goal must be significant
    if (results.category(ActionSimulator::BallPositionCategory::OPPGOAL) < theParameters.minGoalParticles) {
      continue;
    }

    // there is no other action to compare yet
    if (goalActions.empty()) {
      goalActions.push_back(acceptableActions[i]);
      continue;
    }

    // the action with the highest chance of scoring the goal is the best
    if (actionsConsequences[goalActions.front()].category(ActionSimulator::BallPositionCategory::OPPGOAL) < results.category(ActionSimulator::BallPositionCategory::OPPGOAL)) {
      goalActions.clear();
      goalActions.push_back(acceptableActions[i]);
      continue;
    }

    if (actionsConsequences[goalActions.front()].category(ActionSimulator::BallPositionCategory::OPPGOAL) == results.category(ActionSimulator::BallPositionCategory::OPPGOAL)) {
      goalActions.push_back(acceptableActions[i]);
      continue;
    }
  }

  // go for the goal action!
  if (goalActions.size() == 1) {
    return goalActions.front();
  }

  // no goal actions => select one of the acceptable actions based on strategic value
  if (goalActions.empty())
  {
    size_t best_action = 0;
    double bestValue = std::numeric_limits<double>::max(); // assuming potential is [0.0, inf]
    for (std::vector<size_t>::const_iterator it = acceptableActions.begin(); it != acceptableActions.end(); ++it)
    {
      double potential = simulationModule->getModuleT()->evaluateAction(actionsConsequences[*it]);
      if (potential < bestValue) {
        best_action = *it;
        bestValue = potential;
      }
    }
    return best_action;
  }

  // find min of goalActions
  size_t best_action = 0;
  double bestValue = std::numeric_limits<double>::max(); // assuming potential is [0.0, inf]
  for (std::vector<size_t>::const_iterator it = goalActions.begin(); it != goalActions.end(); ++it)
  {
    double potential = simulationModule->getModuleT()->evaluateAction(actionsConsequences[*it]);
    if (potential < bestValue) {
      best_action = *it;
      bestValue = potential;
    }
  }
  return best_action;
}

void Simulation::draw_action_results(const ActionSimulator::ActionResults& actionsResults, const Color& color) const
{
  FIELD_DRAWING_CONTEXT;
  std::vector<ActionSimulator::CategorizedBallPosition>::const_iterator ballPosition = actionsResults.positions().begin();
  for (; ballPosition != actionsResults.positions().end(); ++ballPosition)
  {
    Vector2d ball = getRobotPose() * ballPosition->pos();
    if (ballPosition->cat() == ActionSimulator::BallPositionCategory::INFIELD)
    {
      PEN("000000", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
      PEN(color, 1);
      FILLOVAL(ball.x, ball.y, 40, 40);
    }
    else if (ballPosition->cat() == ActionSimulator::BallPositionCategory::OPPGOAL)
    {
      PEN("336600", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
    }
    else //Outside Field
    {
      PEN("66FF33", 1);
      FILLOVAL(ball.x, ball.y, 50, 50);
    }
  }
}<|endoftext|>


<commit_before>#include "OVRLipSyncPrivatePCH.h"
#include "VisemeGenerationWorker.h"

//General Log
//DEFINE_LOG_CATEGORY(OVRLipSyncPlugin);

FVisemeGenerationWorker::FVisemeGenerationWorker() {}

FVisemeGenerationWorker::~FVisemeGenerationWorker() {
	delete Thread;
	Thread = NULL;
}

void FVisemeGenerationWorker::ShutDown() {
	Stop();
	Thread->WaitForCompletion();
	delete Thread;

	Manager->DestroyContextExternal();
	Manager->ShutdownLipSync();
}

bool FVisemeGenerationWorker::Init() {

	if (!Manager) {
		ClientMessage(FString(TEXT("Speech Recognition Thread failed to start")));
		InitSuccess = false;
		return InitSuccess;
	}

	if (!VoiceCapture.IsValid() || !VoiceCapture->Start())
	{
		ClientMessage(FString(TEXT("Failed to open audio device")));
		InitSuccess = false;
		return InitSuccess;
	}

	Manager->InitLipSync(16000, VISEME_SAMPLES);
	Manager->CreateContextExternal();

	//memset(buf, 0, VISEME_BUF_SIZE);
	//memset(sampleBuf, 0, VISEME_SAMPLES * sizeof(float));

	InitSuccess = true;

	return InitSuccess;
}

uint32 FVisemeGenerationWorker::Run() {

	if (!Manager || Manager->ovrLipSyncSuccess < 0)
	{
		ClientMessage(FString(TEXT("Pending delete on Manager object")));
		return 1;
	}

	if (!VoiceCapture->Start())
	{
		ClientMessage(FString(TEXT("Failed to start recording")));
		return 2;
	}

	if (Manager->IsInitialized() != Manager->ovrLipSyncSuccess)
	{
		ClientMessage(FString(TEXT("OVR Lip Sync not initialized")));
		return 3;
	}

	while (StopTaskCounter.GetValue() == 0)
	{
		// Capturing samples:
		uint32 bytesAvailable = 0;
		EVoiceCaptureState::Type captureState = VoiceCapture->GetCaptureState(bytesAvailable);
		if (captureState == EVoiceCaptureState::Ok && bytesAvailable > 0)
		{
			//memset(buf, 0, VISEME_BUF_SIZE);
			byteBuffer.Empty();
			sampleBuffer.Empty();

			byteBuffer.AddDefaulted(bytesAvailable);

			uint32 readBytes = 0;
			VoiceCapture->GetVoiceData(byteBuffer.GetData(), byteBuffer.Num(), readBytes);

			uint32 samples = readBytes / 2;

			int16_t sample;
			for (uint32 i = 0; i < samples; i++)
			{
				sample = (byteBuffer[i * 2 + 1] << 8) | byteBuffer[i * 2];
				//sampleBuf[i] = float(sample) / 32768.0f;
				sampleBuffer.Add(float(sample) / 32768.0f);
			}

			// Do fun stuff here
			uint32 Flags = 0;

			Manager->ProcessFrameExternal(sampleBuffer.GetData(), (ovrLipSyncFlag)Flags);

			Manager->VisemeGenerated_method(Manager->CurrentFrame);
		}
	}

	VoiceCapture->Stop();

	return 0;
}

void FVisemeGenerationWorker::Stop() {
	StopTaskCounter.Increment();
}

bool FVisemeGenerationWorker::StartThread(AVisemeGenerationActor* manager) {
	Manager = manager;

	// Initialisation:
	VoiceCapture = FVoiceModule::Get().CreateVoiceCapture();
	if (!VoiceCapture.IsValid())
		InitSuccess = false;

	int32 threadIdx = ILipSync::Get().GetInstanceCounter();
	FString threadName = FString("FVisemeGenerationWorker:") + FString::FromInt(threadIdx);
	InitSuccess = true;
	Thread = FRunnableThread::Create(this, *threadName, 0U, TPri_Highest);

	return InitSuccess;
}

void FVisemeGenerationWorker::ClientMessage(FString text) {
	UE_LOG(OVRLipSyncPluginLog, Log, TEXT("%s"), *text);
}
<commit_msg>Changed sample rate in OVR LipSync initialize...seems to have helped!<commit_after>#include "OVRLipSyncPrivatePCH.h"
#include "VisemeGenerationWorker.h"

//General Log
//DEFINE_LOG_CATEGORY(OVRLipSyncPlugin);

FVisemeGenerationWorker::FVisemeGenerationWorker() {}

FVisemeGenerationWorker::~FVisemeGenerationWorker() {
	delete Thread;
	Thread = NULL;
}

void FVisemeGenerationWorker::ShutDown() {
	Stop();
	Thread->WaitForCompletion();
	delete Thread;

	Manager->DestroyContextExternal();
	Manager->ShutdownLipSync();
}

bool FVisemeGenerationWorker::Init() {

	if (!Manager) {
		ClientMessage(FString(TEXT("Speech Recognition Thread failed to start")));
		InitSuccess = false;
		return InitSuccess;
	}

	if (!VoiceCapture.IsValid() || !VoiceCapture->Start())
	{
		ClientMessage(FString(TEXT("Failed to open audio device")));
		InitSuccess = false;
		return InitSuccess;
	}

	Manager->InitLipSync(44100, VISEME_SAMPLES);
	Manager->CreateContextExternal();

	//memset(buf, 0, VISEME_BUF_SIZE);
	//memset(sampleBuf, 0, VISEME_SAMPLES * sizeof(float));

	InitSuccess = true;

	return InitSuccess;
}

uint32 FVisemeGenerationWorker::Run() {

	if (!Manager || Manager->ovrLipSyncSuccess < 0)
	{
		ClientMessage(FString(TEXT("Pending delete on Manager object")));
		return 1;
	}

	if (!VoiceCapture->Start())
	{
		ClientMessage(FString(TEXT("Failed to start recording")));
		return 2;
	}

	if (Manager->IsInitialized() != Manager->ovrLipSyncSuccess)
	{
		ClientMessage(FString(TEXT("OVR Lip Sync not initialized")));
		return 3;
	}

	while (StopTaskCounter.GetValue() == 0)
	{
		// Capturing samples:
		uint32 bytesAvailable = 0;
		EVoiceCaptureState::Type captureState = VoiceCapture->GetCaptureState(bytesAvailable);
		if (captureState == EVoiceCaptureState::Ok && bytesAvailable > 0)
		{
			//memset(buf, 0, VISEME_BUF_SIZE);
			byteBuffer.Empty();
			sampleBuffer.Empty();

			byteBuffer.AddDefaulted(bytesAvailable);

			uint32 readBytes = 0;
			VoiceCapture->GetVoiceData(byteBuffer.GetData(), byteBuffer.Num(), readBytes);

			uint32 samples = readBytes / 2;

			int16_t sample;
			for (uint32 i = 0; i < samples; i++)
			{
				sample = (byteBuffer[i * 2 + 1] << 8) | byteBuffer[i * 2];
				//sampleBuf[i] = float(sample) / 32768.0f;
				sampleBuffer.Add(float(sample) / 32768.0f);
			}

			// Do fun stuff here
			uint32 Flags = 0;

			Manager->ProcessFrameExternal(sampleBuffer.GetData(), (ovrLipSyncFlag)Flags);

			Manager->VisemeGenerated_method(Manager->CurrentFrame);
		}
	}

	VoiceCapture->Stop();

	return 0;
}

void FVisemeGenerationWorker::Stop() {
	StopTaskCounter.Increment();
}

bool FVisemeGenerationWorker::StartThread(AVisemeGenerationActor* manager) {
	Manager = manager;

	// Initialisation:
	VoiceCapture = FVoiceModule::Get().CreateVoiceCapture();
	if (!VoiceCapture.IsValid())
		InitSuccess = false;

	int32 threadIdx = ILipSync::Get().GetInstanceCounter();
	FString threadName = FString("FVisemeGenerationWorker:") + FString::FromInt(threadIdx);
	InitSuccess = true;
	Thread = FRunnableThread::Create(this, *threadName, 0U, TPri_Highest);

	return InitSuccess;
}

void FVisemeGenerationWorker::ClientMessage(FString text) {
	UE_LOG(OVRLipSyncPluginLog, Log, TEXT("%s"), *text);
}
<|endoftext|>


<commit_before>/*
 * barcodeScanner.cpp
 *
 *  Created on: Apr 26, 2014
 *      Author: Srinivasan
 */

#include <cstddef>
#include "zbar.h"
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
using namespace zbar;
using namespace cv;
string getBarcode(string s){

	/*Init scanner to scan barcodes*/
	ImageScanner scanner;
	scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
	string RetString;
	/*load image*/
	Mat frame = imread(s,0);

	/*convert the image to grey  scale*/
	Mat greyScale;
	cvtColor(frame,greyScale,CV_GRAY2RGB);

	/*get the width and height information*/
	int width 			= frame.cols;
	int height 			= frame.rows;
	unsigned char *data 	= frame.data;
	/*Image scanner only supports Y800format, that is 8bpp grayscale format*/
	/*Wrap the raw image date into Image object provided by zlib*/

	Image image(width, height, "Y800",data, width * height);
	// scan the image for barcode, if no barcode is found outputs an empty string and a warning
	if (scanner.scan(image)){

		// extract results
		for(Image::SymbolIterator symbol = image.symbol_begin();
				symbol != image.symbol_end();
				++symbol) {

			RetString =  symbol->get_data();
		}
		// clean up data
		image.set_data(NULL, 0);
	}
	else
	{
		cout << "WARNING: NO BARCODE FOUND!\n" ;
	}
	return RetString;
}
<commit_msg>updated comments<commit_after>/*
 * barcodeScanner.cpp
 *
 *  Created on: Apr 26, 2014
 *      Author: Srinivasan
 *      For the code to run you will need to
 *      install zlib
 *      add the path to its header files, library libzbar-0,
 *      update the environment path to include the bin folder containing libzbar-0.dll
 */

#include <cstddef>
#include "zbar.h"
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
using namespace zbar;
using namespace cv;
string getBarcode(string s){

	/*Init scanner to scan barcodes*/
	ImageScanner scanner;
	scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
	string RetString;
	/*load image*/
	Mat frame = imread(s,0);

	/*convert the image to grey  scale*/
	Mat greyScale;
	cvtColor(frame,greyScale,CV_GRAY2RGB);

	/*get the width and height information*/
	int width 				= frame.cols;
	int height 				= frame.rows;
	unsigned char *data 	= frame.data;

	/*Image scanner only supports Y800format, that is 8bpp grayscale format*/
	/*Wrap the raw image date into Image object provided by zlib*/

	Image image(width, height, "Y800",data, width * height);
	// scan the image for barcode, if no barcode is found outputs an empty string and a warning
	if (scanner.scan(image)){

		// extract results
		for(Image::SymbolIterator symbol = image.symbol_begin();
				symbol != image.symbol_end();
				++symbol) {

			RetString =  symbol->get_data();
		}
		// clean up data
		image.set_data(NULL, 0);
	}
	else
	{
		cout << "WARNING: NO BARCODE FOUND!\n" ;
	}
	return RetString;
}
<|endoftext|>


<commit_before>#include "grammar.hpp"
#include <CppUnitTest.h>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace Microsoft { namespace VisualStudio { namespace CppUnitTestFramework
{
    using namespace ascii_tree;

    template<>
    wstring ToString<token::toktype>(const token::toktype& type)
    {
        switch (type)
        {
        case token::root_node:
            return L"root_node";
        case token::named_node:
            return L"named_node";
        case token::edge_name:
            return L"edge_name";
        case token::horizontal_edge:
            return L"horizontal_edge";
        case token::ascending_edge_part:
            return L"ascending_edge_part";
        case token::descending_edge_part:
            return L"descending_edge_part";
        case token::vertical_edge_part:
            return L"vertical_edge_part";
        default:
            return L"unknown token";
        }
    }
}}}

namespace
{
    class tokens_assertions
    {
        const vector<token>& tokens_;
    public:
        explicit tokens_assertions(const vector<token>& tokens) : tokens_(tokens) {}
        void should_be_empty() { Assert::IsTrue(tokens_.empty()); }
        void should_equal(std::initializer_list<token> expected)
        {
            auto mismatch_pair = std::mismatch(expected.begin(), expected.end(), tokens_.begin());

            if (mismatch_pair.first != expected.end() || mismatch_pair.second != tokens_.end())
            {
                wstring expectedName(mismatch_pair.first->name.begin(), mismatch_pair.first->name.end());
                wstring actualName(mismatch_pair.second->name.begin(), mismatch_pair.second->name.end());

                wstring message = L"Expected: " + ToString(mismatch_pair.first->type) + L" \"" + expectedName + L"\" "
                    + L"Actual: " + ToString(mismatch_pair.second->type) + L" \"" + actualName + L"\"";

                Assert::Fail(message.c_str());
            }
        }
    };

    tokens_assertions _(const vector<token>& tokens) { return tokens_assertions(tokens); }

    struct root_node : public token
    {
        root_node() : token(token::root_node, "") {}
    };

    struct named_node : public token
    {
        explicit named_node(string&& name) : token(token::named_node, std::move(name)) {}
    };

    struct edge_name : public token
    {
        explicit edge_name(string&& name) : token(token::edge_name, std::move(name)) {}
    };

    struct horizontal_edge : public token
    {
        explicit horizontal_edge(string&& name) : token(token::horizontal_edge, std::move(name)) {}
    };

    struct ascending_edge_part : public token
    {
        ascending_edge_part() : token(token::ascending_edge_part, "") {}
    };

    struct descending_edge_part : public token
    {
        descending_edge_part() : token(token::descending_edge_part, "") {}
    };
}

namespace ascii_tree { namespace spec
{
    TEST_CLASS(can_recognize_ascii_tree_tokens)
    {
    public:

        TEST_METHOD(should_not_recognize_any_tokens_in_an_empty_string)
        {
            auto tokens = tokenize("");
            _(tokens).should_be_empty();
        }

        TEST_METHOD(should_recognize_a_root_node)
        {
            auto tokens = tokenize("[*]");
            _(tokens).should_equal({ root_node() });
        }

        TEST_METHOD(should_recognize_a_root_node_with_spaces)
        {
            auto tokens = tokenize(" [ * ] ");
            _(tokens).should_equal({ root_node() });
        }

        TEST_METHOD(should_recognize_a_named_node)
        {
            const string all_chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            auto tokens = tokenize("[" + all_chars + "]");
            _(tokens).should_equal({ named_node(all_chars.c_str()) });
        }

        TEST_METHOD(should_recognize_a_named_node_with_spaces)
        {
            auto tokens = tokenize(" [ a ] ");
            _(tokens).should_equal({ named_node("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name)
        {
            auto tokens = tokenize("(a)");
            _(tokens).should_equal({ edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name_with_spaces)
        {
            auto tokens = tokenize(" ( a ) ");
            _(tokens).should_equal({ edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part)
        {
            auto tokens = tokenize("/");
            _(tokens).should_equal({ ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_with_spaces)
        {
            auto tokens = tokenize(" / ");
            _(tokens).should_equal({ ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part)
        {
            auto tokens = tokenize("\\");
            _(tokens).should_equal({ descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_with_spaces)
        {
            auto tokens = tokenize(" \\ ");
            _(tokens).should_equal({ descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part)
        {
            auto tokens = tokenize("|");
            _(tokens).should_equal({ { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_with_spaces)
        {
            auto tokens = tokenize(" | ");
            _(tokens).should_equal({ { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge)
        {
            auto tokens = tokenize("-(a)-");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_spaces)
        {
            auto tokens = tokenize(" - ( a ) - ");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_uninterrupted_sequences_of_dashes)
        {
            auto tokens = tokenize("---(a)--");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_named_node)
        {
            auto tokens = tokenize("[*][a]");
            _(tokens).should_equal({ root_node(), named_node("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_horizontal_edge)
        {
            auto tokens = tokenize("[*]-(a)-");
            _(tokens).should_equal({ root_node(), horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("[*]\\");
            _(tokens).should_equal({ root_node(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("[*]/");
            _(tokens).should_equal({ root_node(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("[*]|");
            _(tokens).should_equal({ root_node(), { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_edge_name)
        {
            auto tokens = tokenize("[*](a)");
            _(tokens).should_equal({ root_node(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_root_node)
        {
            auto tokens = tokenize("[a][*]");
            _(tokens).should_equal({ named_node("a"), root_node() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_named_node)
        {
            auto tokens = tokenize("[a][b]");
            _(tokens).should_equal({ named_node("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_horizontal_edge)
        {
            auto tokens = tokenize("[a]-(b)-");
            _(tokens).should_equal({ named_node("a"), horizontal_edge("b") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("[a]\\");
            _(tokens).should_equal({ named_node("a"), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("[a]/");
            _(tokens).should_equal({ named_node("a"), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("[a]|");
            _(tokens).should_equal({ named_node("a"), { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_an_edge_name)
        {
            auto tokens = tokenize("[a](b)");
            _(tokens).should_equal({ named_node("a"), edge_name("b") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_root_node)
        {
            auto tokens = tokenize("-(a)-[*]");
            _(tokens).should_equal({ horizontal_edge("a"), root_node() });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_named_node)
        {
            auto tokens = tokenize("-(a)-[b]");
            _(tokens).should_equal({ horizontal_edge("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("\\[*]");
            _(tokens).should_equal({ descending_edge_part(), root_node() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("\\[a]");
            _(tokens).should_equal({ descending_edge_part(), named_node("a") });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("\\\\");
            _(tokens).should_equal({ descending_edge_part(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("\\/");
            _(tokens).should_equal({ descending_edge_part(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("\\|");
            _(tokens).should_equal({ descending_edge_part(), { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("\\(a)");
            _(tokens).should_equal({ descending_edge_part(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("/[*]");
            _(tokens).should_equal({ ascending_edge_part(), root_node() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("/[a]");
            _(tokens).should_equal({ ascending_edge_part(), named_node("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("/\\");
            _(tokens).should_equal({ ascending_edge_part(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("//");
            _(tokens).should_equal({ ascending_edge_part(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("/|");
            _(tokens).should_equal({ ascending_edge_part(), { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("/(a)");
            _(tokens).should_equal({ ascending_edge_part(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("|[*]");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, root_node() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("|[a]");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, named_node("a") });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("|\\");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("|/");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("||");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("|(a)");
            _(tokens).should_equal({ { token::vertical_edge_part, "" }, edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_root_node)
        {
            auto tokens = tokenize("(a)[*]");
            _(tokens).should_equal({ edge_name("a"), root_node() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_named_node)
        {
            auto tokens = tokenize("(a)[b]");
            _(tokens).should_equal({ edge_name("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("(a)\\");
            _(tokens).should_equal({ edge_name("a"), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("(a)/");
            _(tokens).should_equal({ edge_name("a"), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("(a)|");
            _(tokens).should_equal({ edge_name("a"), { token::vertical_edge_part, "" } });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_an_edge_name)
        {
            auto tokens = tokenize("(a)(b)");
            _(tokens).should_equal({ edge_name("a"), edge_name("b") });
        }

    };
}}
<commit_msg>derive a class to shorten the syntax for describing an vertical edge part in the tests<commit_after>#include "grammar.hpp"
#include <CppUnitTest.h>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace Microsoft { namespace VisualStudio { namespace CppUnitTestFramework
{
    using namespace ascii_tree;

    template<>
    wstring ToString<token::toktype>(const token::toktype& type)
    {
        switch (type)
        {
        case token::root_node:
            return L"root_node";
        case token::named_node:
            return L"named_node";
        case token::edge_name:
            return L"edge_name";
        case token::horizontal_edge:
            return L"horizontal_edge";
        case token::ascending_edge_part:
            return L"ascending_edge_part";
        case token::descending_edge_part:
            return L"descending_edge_part";
        case token::vertical_edge_part:
            return L"vertical_edge_part";
        default:
            return L"unknown token";
        }
    }
}}}

namespace
{
    class tokens_assertions
    {
        const vector<token>& tokens_;
    public:
        explicit tokens_assertions(const vector<token>& tokens) : tokens_(tokens) {}
        void should_be_empty() { Assert::IsTrue(tokens_.empty()); }
        void should_equal(std::initializer_list<token> expected)
        {
            auto mismatch_pair = std::mismatch(expected.begin(), expected.end(), tokens_.begin());

            if (mismatch_pair.first != expected.end() || mismatch_pair.second != tokens_.end())
            {
                wstring expectedName(mismatch_pair.first->name.begin(), mismatch_pair.first->name.end());
                wstring actualName(mismatch_pair.second->name.begin(), mismatch_pair.second->name.end());

                wstring message = L"Expected: " + ToString(mismatch_pair.first->type) + L" \"" + expectedName + L"\" "
                    + L"Actual: " + ToString(mismatch_pair.second->type) + L" \"" + actualName + L"\"";

                Assert::Fail(message.c_str());
            }
        }
    };

    tokens_assertions _(const vector<token>& tokens) { return tokens_assertions(tokens); }

    struct root_node : public token
    {
        root_node() : token(token::root_node, "") {}
    };

    struct named_node : public token
    {
        explicit named_node(string&& name) : token(token::named_node, std::move(name)) {}
    };

    struct edge_name : public token
    {
        explicit edge_name(string&& name) : token(token::edge_name, std::move(name)) {}
    };

    struct horizontal_edge : public token
    {
        explicit horizontal_edge(string&& name) : token(token::horizontal_edge, std::move(name)) {}
    };

    struct ascending_edge_part : public token
    {
        ascending_edge_part() : token(token::ascending_edge_part, "") {}
    };

    struct descending_edge_part : public token
    {
        descending_edge_part() : token(token::descending_edge_part, "") {}
    };

    struct vertical_edge_part : public token
    {
        vertical_edge_part() : token(token::vertical_edge_part, "") {}
    };
}

namespace ascii_tree { namespace spec
{
    TEST_CLASS(can_recognize_ascii_tree_tokens)
    {
    public:

        TEST_METHOD(should_not_recognize_any_tokens_in_an_empty_string)
        {
            auto tokens = tokenize("");
            _(tokens).should_be_empty();
        }

        TEST_METHOD(should_recognize_a_root_node)
        {
            auto tokens = tokenize("[*]");
            _(tokens).should_equal({ root_node() });
        }

        TEST_METHOD(should_recognize_a_root_node_with_spaces)
        {
            auto tokens = tokenize(" [ * ] ");
            _(tokens).should_equal({ root_node() });
        }

        TEST_METHOD(should_recognize_a_named_node)
        {
            const string all_chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            auto tokens = tokenize("[" + all_chars + "]");
            _(tokens).should_equal({ named_node(all_chars.c_str()) });
        }

        TEST_METHOD(should_recognize_a_named_node_with_spaces)
        {
            auto tokens = tokenize(" [ a ] ");
            _(tokens).should_equal({ named_node("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name)
        {
            auto tokens = tokenize("(a)");
            _(tokens).should_equal({ edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name_with_spaces)
        {
            auto tokens = tokenize(" ( a ) ");
            _(tokens).should_equal({ edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part)
        {
            auto tokens = tokenize("/");
            _(tokens).should_equal({ ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_with_spaces)
        {
            auto tokens = tokenize(" / ");
            _(tokens).should_equal({ ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part)
        {
            auto tokens = tokenize("\\");
            _(tokens).should_equal({ descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_with_spaces)
        {
            auto tokens = tokenize(" \\ ");
            _(tokens).should_equal({ descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part)
        {
            auto tokens = tokenize("|");
            _(tokens).should_equal({ vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_with_spaces)
        {
            auto tokens = tokenize(" | ");
            _(tokens).should_equal({ vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge)
        {
            auto tokens = tokenize("-(a)-");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_spaces)
        {
            auto tokens = tokenize(" - ( a ) - ");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_uninterrupted_sequences_of_dashes)
        {
            auto tokens = tokenize("---(a)--");
            _(tokens).should_equal({ horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_named_node)
        {
            auto tokens = tokenize("[*][a]");
            _(tokens).should_equal({ root_node(), named_node("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_horizontal_edge)
        {
            auto tokens = tokenize("[*]-(a)-");
            _(tokens).should_equal({ root_node(), horizontal_edge("a") });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("[*]\\");
            _(tokens).should_equal({ root_node(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("[*]/");
            _(tokens).should_equal({ root_node(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("[*]|");
            _(tokens).should_equal({ root_node(), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_edge_name)
        {
            auto tokens = tokenize("[*](a)");
            _(tokens).should_equal({ root_node(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_root_node)
        {
            auto tokens = tokenize("[a][*]");
            _(tokens).should_equal({ named_node("a"), root_node() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_named_node)
        {
            auto tokens = tokenize("[a][b]");
            _(tokens).should_equal({ named_node("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_horizontal_edge)
        {
            auto tokens = tokenize("[a]-(b)-");
            _(tokens).should_equal({ named_node("a"), horizontal_edge("b") });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("[a]\\");
            _(tokens).should_equal({ named_node("a"), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("[a]/");
            _(tokens).should_equal({ named_node("a"), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("[a]|");
            _(tokens).should_equal({ named_node("a"), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_an_edge_name)
        {
            auto tokens = tokenize("[a](b)");
            _(tokens).should_equal({ named_node("a"), edge_name("b") });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_root_node)
        {
            auto tokens = tokenize("-(a)-[*]");
            _(tokens).should_equal({ horizontal_edge("a"), root_node() });
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_named_node)
        {
            auto tokens = tokenize("-(a)-[b]");
            _(tokens).should_equal({ horizontal_edge("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("\\[*]");
            _(tokens).should_equal({ descending_edge_part(), root_node() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("\\[a]");
            _(tokens).should_equal({ descending_edge_part(), named_node("a") });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("\\\\");
            _(tokens).should_equal({ descending_edge_part(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("\\/");
            _(tokens).should_equal({ descending_edge_part(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("\\|");
            _(tokens).should_equal({ descending_edge_part(), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("\\(a)");
            _(tokens).should_equal({ descending_edge_part(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("/[*]");
            _(tokens).should_equal({ ascending_edge_part(), root_node() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("/[a]");
            _(tokens).should_equal({ ascending_edge_part(), named_node("a") });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("/\\");
            _(tokens).should_equal({ ascending_edge_part(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("//");
            _(tokens).should_equal({ ascending_edge_part(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("/|");
            _(tokens).should_equal({ ascending_edge_part(), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("/(a)");
            _(tokens).should_equal({ ascending_edge_part(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_root_node)
        {
            auto tokens = tokenize("|[*]");
            _(tokens).should_equal({ vertical_edge_part(), root_node() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_named_node)
        {
            auto tokens = tokenize("|[a]");
            _(tokens).should_equal({ vertical_edge_part(), named_node("a") });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("|\\");
            _(tokens).should_equal({ vertical_edge_part(), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("|/");
            _(tokens).should_equal({ vertical_edge_part(), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("||");
            _(tokens).should_equal({ vertical_edge_part(), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_next_to_an_edge_name)
        {
            auto tokens = tokenize("|(a)");
            _(tokens).should_equal({ vertical_edge_part(), edge_name("a") });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_root_node)
        {
            auto tokens = tokenize("(a)[*]");
            _(tokens).should_equal({ edge_name("a"), root_node() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_named_node)
        {
            auto tokens = tokenize("(a)[b]");
            _(tokens).should_equal({ edge_name("a"), named_node("b") });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_descending_edge_part)
        {
            auto tokens = tokenize("(a)\\");
            _(tokens).should_equal({ edge_name("a"), descending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_an_ascending_edge_part)
        {
            auto tokens = tokenize("(a)/");
            _(tokens).should_equal({ edge_name("a"), ascending_edge_part() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_a_vertical_edge_part)
        {
            auto tokens = tokenize("(a)|");
            _(tokens).should_equal({ edge_name("a"), vertical_edge_part() });
        }

        TEST_METHOD(should_recognize_an_edge_name_next_to_an_edge_name)
        {
            auto tokens = tokenize("(a)(b)");
            _(tokens).should_equal({ edge_name("a"), edge_name("b") });
        }

    };
}}
<|endoftext|>