<commit_before>// TextBox.cc for FbTk - fluxbox toolkit
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: TextBox.cc,v 1.14 2004/10/06 19:05:12 akir Exp $

#include "TextBox.hh"
#include "Font.hh"
#include "EventManager.hh"
#include "App.hh"
#include "KeyUtil.hh"

#ifdef HAVE_CCTYPE
  #include <cctype>
#else
  #include <ctype.h>
#endif
#include <X11/keysym.h>
#include <X11/Xutil.h>

namespace FbTk {

TextBox::TextBox(int screen_num,
                 const Font &font, const std::string &text):
    FbWindow(screen_num, 0, 0, 1, 1, ExposureMask | KeyPressMask | ButtonPressMask),
    m_font(&font),
    m_text(text),
    m_gc(0),
    m_cursor_pos(0),
    m_start_pos(0),
    m_end_pos(0) {

    FbTk::EventManager::instance()->add(*this, *this);
}

TextBox::TextBox(const FbWindow &parent,
                 const Font &font, const std::string &text):
    FbWindow(parent, 0, 0, 1, 1, ExposureMask | KeyPressMask | ButtonPressMask),
    m_font(&font),
    m_text(text),
    m_gc(0),
    m_cursor_pos(0),
    m_start_pos(0),
    m_end_pos(0) {

    FbTk::EventManager::instance()->add(*this, *this);
}

TextBox::~TextBox() {

}

void TextBox::setText(const std::string &text) {
    m_text = text;
    cursorEnd();
    adjustStartPos();
}

void TextBox::setFont(const Font &font) {
    m_font = &font;
}

void TextBox::setGC(GC gc) {
    m_gc = gc;
}

void TextBox::setInputFocus() {
    XSetInputFocus(FbTk::App::instance()->display(),
                   window(),
                   RevertToParent,
                   CurrentTime);
}

void TextBox::cursorHome() {
    m_start_pos = m_cursor_pos = 0;
    adjustEndPos();
}

void TextBox::cursorEnd() {
    m_end_pos = text().size();
    adjustStartPos();
    m_cursor_pos = m_end_pos - m_start_pos;
}

void TextBox::cursorForward() {
    if (m_start_pos + cursorPosition() < m_end_pos)
        m_cursor_pos++;
    else if (m_end_pos < text().size()) {
        m_cursor_pos++;
        m_end_pos++;
        adjustStartPos();
    }
}

void TextBox::cursorBackward() {
    if (cursorPosition())
        m_cursor_pos--;
    else if (m_start_pos) {
        m_start_pos--;
        adjustEndPos();
    }
}

void TextBox::backspace() {
    if (m_start_pos || cursorPosition()) {
        m_text.erase(m_start_pos + cursorPosition() - 1, 1);
        if (cursorPosition())
            setCursorPosition(cursorPosition() - 1);
        else
            m_start_pos--;
        adjustEndPos();
    }
}

void TextBox::deleteForward() {
    if (m_start_pos + m_cursor_pos < m_end_pos) {
        m_text.erase(m_start_pos + m_cursor_pos, 1);
        adjustEndPos();
    }
}

void TextBox::insertText(const std::string &val) {
    m_text.insert(m_start_pos + cursorPosition(), val);
    m_cursor_pos += val.size();
    m_end_pos += val.size();

    if (m_start_pos + cursorPosition() < m_end_pos)
        adjustEndPos();
    else
        adjustStartPos();
}

void TextBox::killToEnd() {
    if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) {
        m_text.erase(cursorPosition());
        setText(m_text);
    }
}

void TextBox::clear() {
    FbWindow::clear();
    // center text by default
    int center_pos = (height() + font().ascent())/2;
    if (gc() == 0)
        setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber()));

    font().drawText(*this, screenNumber(),
                    gc(),
                    text().c_str() + m_start_pos,
                    m_end_pos - m_start_pos,
                    0, center_pos); // pos

    // draw cursor position
    int cursor_pos = font().textWidth(text().c_str() + m_start_pos, m_cursor_pos) + 1;
    drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height());
}

void TextBox::moveResize(int x, int y,
                         unsigned int width, unsigned int height) {
    FbWindow::moveResize(x, y, width, height);
    clear();
}

void TextBox::resize(unsigned int width, unsigned int height) {
    FbWindow::resize(width, height);
    clear();
}

void TextBox::exposeEvent(XExposeEvent &event) {
    clear();
}

void TextBox::buttonPressEvent(XButtonEvent &event) {
    setInputFocus();
    if (event.window == window()) {
        std::string::size_type i;
        std::string::size_type click_pos = m_end_pos;
        int delta = width();
        int tmp = 0;
        for(i = m_start_pos; i <= m_end_pos; i++) {
            tmp = abs(event.x - font().textWidth(m_text.c_str() + m_start_pos, i - m_start_pos));

            if (tmp < delta) {
                delta = tmp;
                click_pos = i;
            }
        }
        m_cursor_pos = click_pos - m_start_pos;
        clear();
    }
}

void TextBox::keyPressEvent(XKeyEvent &event) {
    // strip numlock and scrolllock mask
    event.state = KeyUtil::instance().cleanMods(event.state);

    KeySym ks;
    char keychar[1];
    XLookupString(&event, keychar, 1, &ks, 0);
    // a modifier key by itself doesn't do anything
    if (IsModifierKey(ks)) return;

    if (event.state) { // handle keybindings without state
        if (event.state == ControlMask) {

            switch (ks) {
            case XK_b:
                cursorBackward();
                break;
            case XK_f:
                cursorForward();
                break;
            case XK_a:
                cursorHome();
                break;
            case XK_e:
                cursorEnd();
                break;
            case XK_d:
                deleteForward();
                break;
            case XK_k:
                killToEnd();
                break;
            case XK_c:
                cursorHome();
                m_text = "";
                m_start_pos = 0;
                m_cursor_pos = 0;
                m_end_pos = 0;
                break;
            }
        } else if (event.state == ShiftMask || event.state == 0x2000) {
            if (isprint(keychar[0])) {
                std::string val;
                val += keychar[0];
                insertText(val);
            }
        }

    } else { // no state

        switch (ks) {
        case XK_BackSpace:
            backspace();
            break;
        case XK_Home:
            cursorHome();
            break;
        case XK_End:
            cursorEnd();
            break;
        case XK_Left:
            cursorBackward();
            break;
        case XK_Right:
            cursorForward();
            break;
        case XK_Delete:
            deleteForward();
            break;
        default:
            if (isprint(keychar[0])) {
                std::string val;
                val += keychar[0];
                insertText(val);
            }
        }
    }
    clear();
}

void TextBox::setCursorPosition(int pos) {
    m_cursor_pos = pos < 0 ? 0 : pos;
    if (m_cursor_pos > text().size())
        cursorEnd();
}

void TextBox::adjustEndPos() {
    m_end_pos = text().size();
    int text_width = font().textWidth(text().c_str() + m_start_pos, m_end_pos - m_start_pos);
    while (text_width > static_cast<signed>(width())) {
        m_end_pos--;
        text_width = font().textWidth(text().c_str() + m_start_pos, m_end_pos - m_start_pos);
    }
}

void TextBox::adjustStartPos() {

    int text_width = font().textWidth(text().c_str(), m_end_pos);
    if (text_width < static_cast<signed>(width()))
        return;

    int start_pos = 0;
    while (text_width > static_cast<signed>(width())) {
        start_pos++;
        text_width = font().textWidth(text().c_str() + start_pos, m_end_pos - start_pos);
    }

    // adjust cursorPosition() according relative to change to m_start_pos
    m_cursor_pos -= start_pos - m_start_pos;
    m_start_pos = start_pos;
}

}; // end namespace FbTk
<commit_msg>entering @ and ~ from germankeyboards work again added some stuff to let the user use the numpad too<commit_after>// TextBox.cc for FbTk - fluxbox toolkit
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: TextBox.cc,v 1.15 2004/10/08 11:52:33 akir Exp $

#include "TextBox.hh"
#include "Font.hh"
#include "EventManager.hh"
#include "App.hh"
#include "KeyUtil.hh"

#ifdef HAVE_CCTYPE
  #include <cctype>
#else
  #include <ctype.h>
#endif
#include <X11/keysym.h>
#include <X11/Xutil.h>

namespace FbTk {

TextBox::TextBox(int screen_num,
                 const Font &font, const std::string &text):
    FbWindow(screen_num, 0, 0, 1, 1, ExposureMask | KeyPressMask | ButtonPressMask),
    m_font(&font),
    m_text(text),
    m_gc(0),
    m_cursor_pos(0),
    m_start_pos(0),
    m_end_pos(0) {

    FbTk::EventManager::instance()->add(*this, *this);
}

TextBox::TextBox(const FbWindow &parent,
                 const Font &font, const std::string &text):
    FbWindow(parent, 0, 0, 1, 1, ExposureMask | KeyPressMask | ButtonPressMask),
    m_font(&font),
    m_text(text),
    m_gc(0),
    m_cursor_pos(0),
    m_start_pos(0),
    m_end_pos(0) {

    FbTk::EventManager::instance()->add(*this, *this);
}

TextBox::~TextBox() {

}

void TextBox::setText(const std::string &text) {
    m_text = text;
    cursorEnd();
    adjustStartPos();
}

void TextBox::setFont(const Font &font) {
    m_font = &font;
}

void TextBox::setGC(GC gc) {
    m_gc = gc;
}

void TextBox::setInputFocus() {
    XSetInputFocus(FbTk::App::instance()->display(),
                   window(),
                   RevertToParent,
                   CurrentTime);
}

void TextBox::cursorHome() {
    m_start_pos = m_cursor_pos = 0;
    adjustEndPos();
}

void TextBox::cursorEnd() {
    m_end_pos = text().size();
    adjustStartPos();
    m_cursor_pos = m_end_pos - m_start_pos;
}

void TextBox::cursorForward() {
    if (m_start_pos + cursorPosition() < m_end_pos)
        m_cursor_pos++;
    else if (m_end_pos < text().size()) {
        m_cursor_pos++;
        m_end_pos++;
        adjustStartPos();
    }
}

void TextBox::cursorBackward() {
    if (cursorPosition())
        m_cursor_pos--;
    else if (m_start_pos) {
        m_start_pos--;
        adjustEndPos();
    }
}

void TextBox::backspace() {
    if (m_start_pos || cursorPosition()) {
        m_text.erase(m_start_pos + cursorPosition() - 1, 1);
        if (cursorPosition())
            setCursorPosition(cursorPosition() - 1);
        else
            m_start_pos--;
        adjustEndPos();
    }
}

void TextBox::deleteForward() {
    if (m_start_pos + m_cursor_pos < m_end_pos) {
        m_text.erase(m_start_pos + m_cursor_pos, 1);
        adjustEndPos();
    }
}

void TextBox::insertText(const std::string &val) {
    m_text.insert(m_start_pos + cursorPosition(), val);
    m_cursor_pos += val.size();
    m_end_pos += val.size();

    if (m_start_pos + cursorPosition() < m_end_pos)
        adjustEndPos();
    else
        adjustStartPos();
}

void TextBox::killToEnd() {
    if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) {
        m_text.erase(cursorPosition());
        setText(m_text);
    }
}

void TextBox::clear() {
    FbWindow::clear();
    // center text by default
    int center_pos = (height() + font().ascent())/2;
    if (gc() == 0)
        setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber()));

    font().drawText(*this, screenNumber(),
                    gc(),
                    text().c_str() + m_start_pos,
                    m_end_pos - m_start_pos,
                    0, center_pos); // pos

    // draw cursor position
    int cursor_pos = font().textWidth(text().c_str() + m_start_pos, m_cursor_pos) + 1;
    drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height());
}

void TextBox::moveResize(int x, int y,
                         unsigned int width, unsigned int height) {
    FbWindow::moveResize(x, y, width, height);
    clear();
}

void TextBox::resize(unsigned int width, unsigned int height) {
    FbWindow::resize(width, height);
    clear();
}

void TextBox::exposeEvent(XExposeEvent &event) {
    clear();
}

void TextBox::buttonPressEvent(XButtonEvent &event) {
    setInputFocus();
    if (event.window == window()) {
        std::string::size_type i;
        std::string::size_type click_pos = m_end_pos;
        int delta = width();
        int tmp = 0;
        for(i = m_start_pos; i <= m_end_pos; i++) {
            tmp = abs(event.x - font().textWidth(m_text.c_str() + m_start_pos, i - m_start_pos));

            if (tmp < delta) {
                delta = tmp;
                click_pos = i;
            }
        }
        m_cursor_pos = click_pos - m_start_pos;
        clear();
    }
}

void TextBox::keyPressEvent(XKeyEvent &event) {
    // strip numlock and scrolllock mask
    event.state = KeyUtil::instance().cleanMods(event.state);

    KeySym ks;
    char keychar[1];
    XLookupString(&event, keychar, 1, &ks, 0);
    // a modifier key by itself doesn't do anything
    if (IsModifierKey(ks)) return;

    if (event.state) { // handle keybindings with state
        if (event.state == ControlMask) {

            switch (ks) {
            case XK_b:
                cursorBackward();
                break;
            case XK_f:
                cursorForward();
                break;
            case XK_a:
                cursorHome();
                break;
            case XK_e:
                cursorEnd();
                break;
            case XK_d:
                deleteForward();
                break;
            case XK_k:
                killToEnd();
                break;
            case XK_c:
                cursorHome();
                m_text = "";
                m_start_pos = 0;
                m_cursor_pos = 0;
                m_end_pos = 0;
                break;
            }
        } else if (event.state == ShiftMask || event.state == 0x80) { // shif and altgr
            if (isprint(keychar[0])) {
                std::string val;
                val += keychar[0];
                insertText(val);
            }
        }

    } else { // no state

        switch (ks) {
        case XK_BackSpace:
            backspace();
            break;
        case XK_Home:
            cursorHome();
            break;
        case XK_End:
            cursorEnd();
            break;
        case XK_Left:
            cursorBackward();
            break;
        case XK_Right:
            cursorForward();
            break;
        case XK_Delete:
            deleteForward();
            break;
        default:
            switch (ks) {
            case XK_KP_Insert:
                keychar[0] = '0';
                break;
            case XK_KP_End:
                keychar[0] = '1';
                break;
            case XK_KP_Down:
                keychar[0] = '2';
                break;
            case XK_KP_Page_Down:
                keychar[0] = '3';
                break;
            case XK_KP_Left:
                keychar[0] = '4';
                break;
            case XK_KP_Begin:
                keychar[0] = '5';
                break;
            case XK_KP_Right:
                keychar[0] = '6';
                break;
            case XK_KP_Home:
                keychar[0] = '7';
                break;
            case XK_KP_Up:
                keychar[0] = '8';
                break;
            case XK_KP_Page_Up:
                keychar[0] = '9';
                break;
            case XK_KP_Delete:
                keychar[0] = ',';
                break;
            };
            if (isprint(keychar[0])) {
                std::string val;
                val += keychar[0];
                insertText(val);
            }
        }
    }
    clear();
}

void TextBox::setCursorPosition(int pos) {
    m_cursor_pos = pos < 0 ? 0 : pos;
    if (m_cursor_pos > text().size())
        cursorEnd();
}

void TextBox::adjustEndPos() {
    m_end_pos = text().size();
    int text_width = font().textWidth(text().c_str() + m_start_pos, m_end_pos - m_start_pos);
    while (text_width > static_cast<signed>(width())) {
        m_end_pos--;
        text_width = font().textWidth(text().c_str() + m_start_pos, m_end_pos - m_start_pos);
    }
}

void TextBox::adjustStartPos() {

    int text_width = font().textWidth(text().c_str(), m_end_pos);
    if (text_width < static_cast<signed>(width()))
        return;

    int start_pos = 0;
    while (text_width > static_cast<signed>(width())) {
        start_pos++;
        text_width = font().textWidth(text().c_str() + start_pos, m_end_pos - start_pos);
    }

    // adjust cursorPosition() according relative to change to m_start_pos
    m_cursor_pos -= start_pos - m_start_pos;
    m_start_pos = start_pos;
}

}; // end namespace FbTk
<|endoftext|>


<commit_before>#include "d2RobotModel.h"
#include "../tracer.h"

using namespace qReal::interpreters::robots;
using namespace details;
using namespace d2Model;

const unsigned long black   = 0xFF000000;
const unsigned long white   = 0xFFFFFFFF;
const unsigned long red     = 0xFFFF0000;
const unsigned long green   = 0xFF008000;
const unsigned long blue    = 0xFF0000FF;
const unsigned long yellow  = 0xFFFFFF00;
const unsigned long cyan    = 0xFF00FFFF;
const unsigned long magenta = 0xFFFF00FF;

D2RobotModel::D2RobotModel(QObject *parent)
	: QObject(parent)
	, mD2ModelWidget(NULL)
{
	mAngle = 0;
	mTimer = new QTimer(this);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(nextFragment()));
	initPosition();
}

D2RobotModel::~D2RobotModel()
{
}

void D2RobotModel::initPosition()
{
	mMotorA = initMotor(5, 0, 0, 0);
	mMotorB = initMotor(5, 0, 0, 1);
	mMotorC = initMotor(5, 0, 0, 2);
	setBeep(0, 0);
	mPos = mD2ModelWidget ? mD2ModelWidget->robotPos() : QPointF(0, 0);
	mRotatePoint  = QPointF(0, 0);

}

void D2RobotModel::clear()
{
	initPosition();
	mAngle = 0;
	mPos = QPointF(0,0);
}

D2RobotModel::Motor* D2RobotModel::initMotor(int radius, int speed, long unsigned int degrees, int port)
{
	Motor *motor = new Motor();
	motor->radius = radius;
	motor->speed = speed;
	motor->degrees = degrees;
	if (degrees == 0) {
		motor->activeTime = QPair<ATime, qreal>(DoInf , 0);
	}
	else {
		qreal activeTime = degrees / speed ;
		motor->activeTime = QPair<ATime, qreal>(Do , activeTime);
	}
	mMotors[port] = motor;
	mTurnoverMotors[port] = 0;
	return motor;
}

void D2RobotModel::setBeep(unsigned freq, unsigned time)
{
	mBeep.freq = freq;
	mBeep.time = time;
}

void D2RobotModel::setNewMotor(int speed, unsigned long degrees, const int port)
{
	mMotors[port]->speed = speed;
	mMotors[port]->degrees = degrees;
	if (degrees == 0) {
		mMotors[port]->activeTime = QPair<ATime, qreal>(DoInf , 0);
	}
	else {
		qreal activeTime = degrees * 1.0 / 1.0 * speed ;
		mMotors[port]->activeTime = QPair<ATime, qreal>(Do , activeTime);
	}
	mTurnoverMotors[port] = 0;
}

void D2RobotModel::countOneMotorTime(D2RobotModel::Motor &motor)
{
	if (motor.activeTime.first == Do) {
		motor.activeTime.second -= timeInterval;
		if (motor.activeTime.second <= 0) {
			motor.activeTime.first = End;
			motor.speed = 0;
		}
	}
}

void D2RobotModel::countMotorTime()
{
	countOneMotorTime(*mMotorA);
	countOneMotorTime(*mMotorB);
	countOneMotorTime(*mMotorC);
}

void D2RobotModel::countMotorTurnover()
{
	foreach (Motor *motor, mMotors) {
		int port = mMotors.key(motor);
		qreal degrees = timeInterval * 1.0 * motor->speed ;
		mTurnoverMotors[port] += degrees;
	}
}

int D2RobotModel::readEncoder(int/*inputPort::InputPortEnum*/ const port) const
{
	return mTurnoverMotors[port] / 360;//делим кол-во градусов на полный оборот
}

void D2RobotModel::resetEncoder(int/*inputPort::InputPortEnum*/ const port)
{
	mTurnoverMotors[port] = 0;
}

SensorsConfiguration &D2RobotModel::configuration()
{
	return mSensorsConfiguration;
}

D2ModelWidget *D2RobotModel::createModelWidget()
{
	mD2ModelWidget = new D2ModelWidget(this, &mWorldModel);
	return mD2ModelWidget;
}

QPair<QPoint, qreal> D2RobotModel::countPositionAndDirection(QPointF localPosition, qreal localDirection) const
{
	QPointF point = localPosition - rotatePoint;
	QPointF localPoint = QTransform().translate(-point.x(), -point.y()).rotate(mAngle)
			.translate(point.x(), point.y()).rotate(-mAngle)
			.map(localPosition);

	QPoint resPoint = localPoint.toPoint() + mPos.toPoint();
	qreal direction = localDirection + mAngle;
	return QPair<QPoint, qreal>(resPoint, direction);
}

QPair<QPoint, qreal> D2RobotModel::countPositionAndDirection(inputPort::InputPortEnum const port) const
{
	return countPositionAndDirection(mSensorsConfiguration.position(port), mSensorsConfiguration.direction(port));
}

bool D2RobotModel::readTouchSensor(inputPort::InputPortEnum const port)
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	bool res = mWorldModel.touchSensorReading(neededPosDir.first, neededPosDir.second, port);
	// TODO: Add checks of sensor type.
	return res;
}

int D2RobotModel::readSonarSensor(inputPort::InputPortEnum const port) const
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	return mWorldModel.sonarReading(neededPosDir.first, neededPosDir.second);
}

int D2RobotModel::readColorSensor(inputPort::InputPortEnum const port) const
{
	QImage image = printColorSensor(port);
	QHash<unsigned long, int> countsColor;

	unsigned long* data = (unsigned long*) image.bits();
	int n = image.numBytes() / 4;
	for (int i = 0; i < n; ++i) {
		unsigned long color = data[i];
		countsColor[color] ++;
	}

	switch (mSensorsConfiguration.type(port)) {
	case (sensorType::colorFull):
		return readColorFullSensor(countsColor);
	case (sensorType::colorNone):
		return readColorNoneSensor(countsColor, n);
	case (sensorType::colorRed):
		return readSingleColorSensor(red, countsColor, n);
	case (sensorType::colorGreen):
		return readSingleColorSensor(green, countsColor, n);
	case (sensorType::colorBlue):
		return readSingleColorSensor(blue, countsColor, n);
	default:
		return 0;
	}
}

QImage D2RobotModel::printColorSensor(inputPort::InputPortEnum const port) const
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	QPointF position = neededPosDir.first;
	qreal width = colorSensorWidth / 2.0;
	QRectF scanningRect = QRectF(position.x() -  width, position.y() - width
								 , 2 * width, 2 * width);

	QImage image(scanningRect.size().toSize(), QImage::Format_RGB32);
	QPainter painter(&image);

	QBrush brush(Qt::SolidPattern);
	brush.setColor(Qt::white);
	painter.setBrush(brush);
	painter.setPen(QPen(Qt::black));
	painter.drawRect(mD2ModelWidget->scene()->itemsBoundingRect().adjusted(-width, -width, width, width));

	mD2ModelWidget->setSensorVisible(port, false);
	mD2ModelWidget->scene()->render(&painter, QRectF(), scanningRect);
	mD2ModelWidget->setSensorVisible(port, true);

	return image;
}

int D2RobotModel::readColorFullSensor(QHash<unsigned long, int> countsColor) const
{
	QList<int> values = countsColor.values();
	qSort(values);
	int maxValue = values.last();
	unsigned long maxColor = countsColor.key(maxValue);

	switch (maxColor) {
	case (black):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "BLACK");
		return 1;
	case (red):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "RED");
		return 5;
	case (green):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "GREEN");
		return 3;
	case (blue) :
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "BLUE");
		return 2;
	case (yellow):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "YELLOW");
		return 4;
	case (white):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "WHITE");
		return 6;
	case (cyan):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "CYAN");
		return 7;
	case (magenta):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "MAGENTA");
		return 8;
	default:
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "Other Color");
		return 0;
	}
}

int D2RobotModel::readSingleColorSensor(unsigned long color, QHash<unsigned long, int> countsColor, int n) const
{
	return (static_cast<double>(countsColor[color]) / static_cast<double>(n)) * 100.0;
}

int D2RobotModel::readColorNoneSensor(QHash<unsigned long, int> countsColor, int n) const
{
	double allWhite = static_cast<double>(countsColor[white]);

	QHashIterator<unsigned long, int> i(countsColor);
	while(i.hasNext()) {
		i.next();
		unsigned long color = i.key();
		if (color != white) {
			int b = (color >> 0) & 0xFF;
			int g = (color >> 8) & 0xFF;
			int r = (color >> 16) & 0xFF;
			qreal k = qSqrt(static_cast<qreal>(b * b + g * g + r * r)) / 500.0;
			allWhite += static_cast<qreal>(i.value()) * k;
		}
	}

	return (allWhite / static_cast<qreal>(n)) * 100.0;
}

void D2RobotModel::startInit()
{
	initPosition();
	mTimer->start(timeInterval);
}

void D2RobotModel::stopRobot()
{
	mTimer->stop();
}

void D2RobotModel::countBeep()
{
	if (mBeep.time > 0) {
		mD2ModelWidget->drawBeep(QColor(Qt::red));
		mBeep.time -= timeInterval;
	} else
		mD2ModelWidget->drawBeep(QColor(Qt::green));
}

void D2RobotModel::countNewCoord()
{
	qreal vSpeed = mMotorA->speed * 2 * M_PI * mMotorA->radius * 1.0 / 120000;
	qreal uSpeed = mMotorB->speed * 2 * M_PI * mMotorB->radius * 1.0 / 120000;
	qreal gammaRadians = 0;
	qreal deltaY = 0;
	qreal deltaX = 0;
	qreal averageSpeed = (vSpeed + uSpeed) / 2;

	qreal const oldAngle = mAngle;
	QPointF const oldPosition = mPos;

	if (vSpeed != uSpeed) {
		qreal const vRadius = vSpeed * robotHeight / (vSpeed - uSpeed);
		qreal const averageRadius = vRadius - robotHeight / 2;
		qreal angularSpeed = 0;
		qreal actualRadius = 0;
		if (vSpeed == -uSpeed) {  // TODO: Is it really a special case?
			angularSpeed = vSpeed / vRadius;
			actualRadius = vRadius;
		} else {
			angularSpeed = averageSpeed / averageRadius;
			actualRadius = averageRadius;
		}
		gammaRadians = timeInterval * angularSpeed;
		qreal const gammaDegrees = gammaRadians * 180 / M_PI;

		QTransform map;
		map.rotate(mAngle);
		map.translate(robotWidth / 2, actualRadius);
		map.rotate(gammaDegrees);
		map.translate(-robotWidth / 2, -actualRadius);

		QPointF newStart = map.map(QPointF(0, 0));
		deltaX = newStart.x();
		deltaY = newStart.y();

		mAngle += gammaDegrees;
	} else {
		deltaY = averageSpeed * timeInterval * sin(mAngle * M_PI / 180);
		deltaX = averageSpeed * timeInterval * cos(mAngle * M_PI / 180);
	}
	mPos.setX(mPos.x() + deltaX);
	mPos.setY(mPos.y() + deltaY);
	if(mAngle > 360)
		mAngle -= 360;
	QPolygonF const boundingRegion = mD2ModelWidget->robotBoundingPolygon(mPos, mAngle);
	if (mWorldModel.checkCollision(boundingRegion)) {
		mPos = oldPosition;
		mAngle = oldAngle;
	}
}

void D2RobotModel::nextFragment()
{
	// do nothing until robot gets back on the ground
	if (!mD2ModelWidget->isRobotOnTheGround())
		return;

	mPos = mD2ModelWidget->robotPos();
	countNewCoord();
	mRotatePoint = rotatePoint;
	mD2ModelWidget->draw(mPos, mAngle, mRotatePoint);
	countBeep();
	countMotorTime();
	countMotorTurnover();
}

void D2RobotModel::showModelWidget()
{
	mD2ModelWidget->init(true);
}

void D2RobotModel::rotateOn(double angle)
{
	mPos = mD2ModelWidget ? mD2ModelWidget->robotPos() : QPointF(0, 0);
	mRotatePoint = rotatePoint;
	if(angle > 360)
		angle -= 360;
	mAngle += angle;
	mD2ModelWidget->draw(mPos, mAngle, mRotatePoint);
}

double D2RobotModel::rotateAngle() const
{
	return mAngle;
}
<commit_msg>Fixed robot rotation in place, a part of fix for #227<commit_after>#include "d2RobotModel.h"
#include "../tracer.h"

using namespace qReal::interpreters::robots;
using namespace details;
using namespace d2Model;

const unsigned long black   = 0xFF000000;
const unsigned long white   = 0xFFFFFFFF;
const unsigned long red     = 0xFFFF0000;
const unsigned long green   = 0xFF008000;
const unsigned long blue    = 0xFF0000FF;
const unsigned long yellow  = 0xFFFFFF00;
const unsigned long cyan    = 0xFF00FFFF;
const unsigned long magenta = 0xFFFF00FF;

D2RobotModel::D2RobotModel(QObject *parent)
	: QObject(parent)
	, mD2ModelWidget(NULL)
{
	mAngle = 0;
	mTimer = new QTimer(this);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(nextFragment()));
	initPosition();
}

D2RobotModel::~D2RobotModel()
{
}

void D2RobotModel::initPosition()
{
	mMotorA = initMotor(5, 0, 0, 0);
	mMotorB = initMotor(5, 0, 0, 1);
	mMotorC = initMotor(5, 0, 0, 2);
	setBeep(0, 0);
	mPos = mD2ModelWidget ? mD2ModelWidget->robotPos() : QPointF(0, 0);
	mRotatePoint  = QPointF(0, 0);

}

void D2RobotModel::clear()
{
	initPosition();
	mAngle = 0;
	mPos = QPointF(0,0);
}

D2RobotModel::Motor* D2RobotModel::initMotor(int radius, int speed, long unsigned int degrees, int port)
{
	Motor *motor = new Motor();
	motor->radius = radius;
	motor->speed = speed;
	motor->degrees = degrees;
	if (degrees == 0) {
		motor->activeTime = QPair<ATime, qreal>(DoInf , 0);
	}
	else {
		qreal activeTime = degrees / speed ;
		motor->activeTime = QPair<ATime, qreal>(Do , activeTime);
	}
	mMotors[port] = motor;
	mTurnoverMotors[port] = 0;
	return motor;
}

void D2RobotModel::setBeep(unsigned freq, unsigned time)
{
	mBeep.freq = freq;
	mBeep.time = time;
}

void D2RobotModel::setNewMotor(int speed, unsigned long degrees, const int port)
{
	mMotors[port]->speed = speed;
	mMotors[port]->degrees = degrees;
	if (degrees == 0) {
		mMotors[port]->activeTime = QPair<ATime, qreal>(DoInf , 0);
	}
	else {
		qreal activeTime = degrees * 1.0 / 1.0 * speed ;
		mMotors[port]->activeTime = QPair<ATime, qreal>(Do , activeTime);
	}
	mTurnoverMotors[port] = 0;
}

void D2RobotModel::countOneMotorTime(D2RobotModel::Motor &motor)
{
	if (motor.activeTime.first == Do) {
		motor.activeTime.second -= timeInterval;
		if (motor.activeTime.second <= 0) {
			motor.activeTime.first = End;
			motor.speed = 0;
		}
	}
}

void D2RobotModel::countMotorTime()
{
	countOneMotorTime(*mMotorA);
	countOneMotorTime(*mMotorB);
	countOneMotorTime(*mMotorC);
}

void D2RobotModel::countMotorTurnover()
{
	foreach (Motor *motor, mMotors) {
		int port = mMotors.key(motor);
		qreal degrees = timeInterval * 1.0 * motor->speed ;
		mTurnoverMotors[port] += degrees;
	}
}

int D2RobotModel::readEncoder(int/*inputPort::InputPortEnum*/ const port) const
{
	return mTurnoverMotors[port] / 360;//делим кол-во градусов на полный оборот
}

void D2RobotModel::resetEncoder(int/*inputPort::InputPortEnum*/ const port)
{
	mTurnoverMotors[port] = 0;
}

SensorsConfiguration &D2RobotModel::configuration()
{
	return mSensorsConfiguration;
}

D2ModelWidget *D2RobotModel::createModelWidget()
{
	mD2ModelWidget = new D2ModelWidget(this, &mWorldModel);
	return mD2ModelWidget;
}

QPair<QPoint, qreal> D2RobotModel::countPositionAndDirection(QPointF localPosition, qreal localDirection) const
{
	QPointF point = localPosition - rotatePoint;
	QPointF localPoint = QTransform().translate(-point.x(), -point.y()).rotate(mAngle)
			.translate(point.x(), point.y()).rotate(-mAngle)
			.map(localPosition);

	QPoint resPoint = localPoint.toPoint() + mPos.toPoint();
	qreal direction = localDirection + mAngle;
	return QPair<QPoint, qreal>(resPoint, direction);
}

QPair<QPoint, qreal> D2RobotModel::countPositionAndDirection(inputPort::InputPortEnum const port) const
{
	return countPositionAndDirection(mSensorsConfiguration.position(port), mSensorsConfiguration.direction(port));
}

bool D2RobotModel::readTouchSensor(inputPort::InputPortEnum const port)
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	bool res = mWorldModel.touchSensorReading(neededPosDir.first, neededPosDir.second, port);
	// TODO: Add checks of sensor type.
	return res;
}

int D2RobotModel::readSonarSensor(inputPort::InputPortEnum const port) const
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	return mWorldModel.sonarReading(neededPosDir.first, neededPosDir.second);
}

int D2RobotModel::readColorSensor(inputPort::InputPortEnum const port) const
{
	QImage image = printColorSensor(port);
	QHash<unsigned long, int> countsColor;

	unsigned long* data = (unsigned long*) image.bits();
	int n = image.numBytes() / 4;
	for (int i = 0; i < n; ++i) {
		unsigned long color = data[i];
		countsColor[color] ++;
	}

	switch (mSensorsConfiguration.type(port)) {
	case (sensorType::colorFull):
		return readColorFullSensor(countsColor);
	case (sensorType::colorNone):
		return readColorNoneSensor(countsColor, n);
	case (sensorType::colorRed):
		return readSingleColorSensor(red, countsColor, n);
	case (sensorType::colorGreen):
		return readSingleColorSensor(green, countsColor, n);
	case (sensorType::colorBlue):
		return readSingleColorSensor(blue, countsColor, n);
	default:
		return 0;
	}
}

QImage D2RobotModel::printColorSensor(inputPort::InputPortEnum const port) const
{
	QPair<QPoint, qreal> neededPosDir = countPositionAndDirection(port);
	QPointF position = neededPosDir.first;
	qreal width = colorSensorWidth / 2.0;
	QRectF scanningRect = QRectF(position.x() -  width, position.y() - width
								 , 2 * width, 2 * width);

	QImage image(scanningRect.size().toSize(), QImage::Format_RGB32);
	QPainter painter(&image);

	QBrush brush(Qt::SolidPattern);
	brush.setColor(Qt::white);
	painter.setBrush(brush);
	painter.setPen(QPen(Qt::black));
	painter.drawRect(mD2ModelWidget->scene()->itemsBoundingRect().adjusted(-width, -width, width, width));

	mD2ModelWidget->setSensorVisible(port, false);
	mD2ModelWidget->scene()->render(&painter, QRectF(), scanningRect);
	mD2ModelWidget->setSensorVisible(port, true);

	return image;
}

int D2RobotModel::readColorFullSensor(QHash<unsigned long, int> countsColor) const
{
	QList<int> values = countsColor.values();
	qSort(values);
	int maxValue = values.last();
	unsigned long maxColor = countsColor.key(maxValue);

	switch (maxColor) {
	case (black):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "BLACK");
		return 1;
	case (red):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "RED");
		return 5;
	case (green):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "GREEN");
		return 3;
	case (blue) :
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "BLUE");
		return 2;
	case (yellow):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "YELLOW");
		return 4;
	case (white):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "WHITE");
		return 6;
	case (cyan):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "CYAN");
		return 7;
	case (magenta):
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "MAGENTA");
		return 8;
	default:
		Tracer::debug(tracer::d2Model, "D2RobotModel::readColorFullSensor", "Other Color");
		return 0;
	}
}

int D2RobotModel::readSingleColorSensor(unsigned long color, QHash<unsigned long, int> countsColor, int n) const
{
	return (static_cast<double>(countsColor[color]) / static_cast<double>(n)) * 100.0;
}

int D2RobotModel::readColorNoneSensor(QHash<unsigned long, int> countsColor, int n) const
{
	double allWhite = static_cast<double>(countsColor[white]);

	QHashIterator<unsigned long, int> i(countsColor);
	while(i.hasNext()) {
		i.next();
		unsigned long color = i.key();
		if (color != white) {
			int b = (color >> 0) & 0xFF;
			int g = (color >> 8) & 0xFF;
			int r = (color >> 16) & 0xFF;
			qreal k = qSqrt(static_cast<qreal>(b * b + g * g + r * r)) / 500.0;
			allWhite += static_cast<qreal>(i.value()) * k;
		}
	}

	return (allWhite / static_cast<qreal>(n)) * 100.0;
}

void D2RobotModel::startInit()
{
	initPosition();
	mTimer->start(timeInterval);
}

void D2RobotModel::stopRobot()
{
	mTimer->stop();
}

void D2RobotModel::countBeep()
{
	if (mBeep.time > 0) {
		mD2ModelWidget->drawBeep(QColor(Qt::red));
		mBeep.time -= timeInterval;
	} else
		mD2ModelWidget->drawBeep(QColor(Qt::green));
}

void D2RobotModel::countNewCoord()
{
	qreal const vSpeed = mMotorA->speed * 2 * M_PI * mMotorA->radius * 1.0 / 120000;
	qreal const uSpeed = mMotorB->speed * 2 * M_PI * mMotorB->radius * 1.0 / 120000;
	qreal deltaY = 0;
	qreal deltaX = 0;
	qreal const averageSpeed = (vSpeed + uSpeed) / 2;

	qreal const oldAngle = mAngle;
	QPointF const oldPosition = mPos;

	if (vSpeed != uSpeed) {
		qreal const vRadius = vSpeed * robotHeight / (vSpeed - uSpeed);
		qreal const averageRadius = vRadius - robotHeight / 2;
		qreal angularSpeed = 0;
		qreal actualRadius = 0;
		if (vSpeed == -uSpeed) {
			angularSpeed = vSpeed / vRadius;
			actualRadius = 0;  // Radius is relative to the center of the robot.
		} else {
			angularSpeed = averageSpeed / averageRadius;
			actualRadius = averageRadius;
		}
		qreal const gammaRadians = timeInterval * angularSpeed;
		qreal const gammaDegrees = gammaRadians * 180 / M_PI;

		QTransform map;
		map.rotate(mAngle);
		// TODO: robotWidth / 2 shall actually be a distance between robot center and
		// centers of the wheels by x axis.
		map.translate(robotWidth / 2, actualRadius);
		map.rotate(gammaDegrees);
		map.translate(-robotWidth / 2, -actualRadius);

		QPointF newStart = map.map(QPointF(0, 0));
		deltaX = newStart.x();
		deltaY = newStart.y();

		mAngle += gammaDegrees;
	} else {
		deltaY = averageSpeed * timeInterval * sin(mAngle * M_PI / 180);
		deltaX = averageSpeed * timeInterval * cos(mAngle * M_PI / 180);
	}

	mPos.setX(mPos.x() + deltaX);
	mPos.setY(mPos.y() + deltaY);

	if(mAngle > 360) {
		mAngle -= 360;
	}

	QPolygonF const boundingRegion = mD2ModelWidget->robotBoundingPolygon(mPos, mAngle);
	if (mWorldModel.checkCollision(boundingRegion)) {
		mPos = oldPosition;
		mAngle = oldAngle;
	}
}

void D2RobotModel::nextFragment()
{
	// do nothing until robot gets back on the ground
	if (!mD2ModelWidget->isRobotOnTheGround())
		return;

	mPos = mD2ModelWidget->robotPos();
	countNewCoord();
	mRotatePoint = rotatePoint;
	mD2ModelWidget->draw(mPos, mAngle, mRotatePoint);
	countBeep();
	countMotorTime();
	countMotorTurnover();
}

void D2RobotModel::showModelWidget()
{
	mD2ModelWidget->init(true);
}

void D2RobotModel::rotateOn(double angle)
{
	mPos = mD2ModelWidget ? mD2ModelWidget->robotPos() : QPointF(0, 0);
	mRotatePoint = rotatePoint;
	if(angle > 360)
		angle -= 360;
	mAngle += angle;
	mD2ModelWidget->draw(mPos, mAngle, mRotatePoint);
}

double D2RobotModel::rotateAngle() const
{
	return mAngle;
}
<|endoftext|>


<commit_before>//
// Name:     app.cpp
// Purpose:  The application class for our wxWindows application.
//
// Copyright (c) 2001-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/image.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "vtlib/core/TerrainScene.h"
#include "../Enviro.h"		// for g_App, GetTerrainScene
#include "../Options.h"
#include "vtdata/vtLog.h"

#include "app.h"
#include "frame.h"
#include "StartupDlg.h"

IMPLEMENT_APP(vtApp)

vtApp::vtApp()
{
	m_bShowStartupDialog = true;
}

void vtApp::Args(int argc, wxChar **argv)
{
	for (int i = 0; i < argc; i++)
	{
		wxString2 str = argv[i];
		const char *cstr = str.mb_str();
		g_App.StartupArgument(i, cstr);
		if (!strcmp(cstr, "-no_startup_dialog"))
			m_bShowStartupDialog = false;
		else if (!strcmp(cstr, "-fullscreen"))
			g_Options.m_bFullscreen = true;
		else if(!strncmp(cstr, "-terrain=", 9))
		{
			m_bShowStartupDialog = false;
			g_Options.m_strInitTerrain = cstr+9;
		}
	}
}

//
// Initialize the app object
//
bool vtApp::OnInit()
{
	g_Options.Read("Enviro.ini");

	g_App.Startup();	// starts log

	VTLOG("Application framework: wxWindows v" wxVERSION_NUM_DOT_STRING "\n");
	Args(argc, argv);

	g_App.LoadTerrainDescriptions();

/*	class AA { public: virtual void func() {} };
	class BB : public AA {};
	VTLOG("Testing the ability to use dynamic_cast to downcast...\n");
	BB *b = new BB;
	AA *a = (AA *) b;
	BB *result1 = dynamic_cast<BB *>(a);
	VTLOG("  successful (%lx)\n", result1); */

	//
	// Create and show the Startup Dialog
	//
	if (m_bShowStartupDialog)
	{
		VTLOG("Opening the Startup dialog.\n");
		StartupDlg StartDlg(NULL, -1, _T("Enviro Startup"), wxDefaultPosition);
		StartDlg.GetOptionsFrom(g_Options);
		StartDlg.CenterOnParent();
		int result = StartDlg.ShowModal();
		if (result == wxID_CANCEL)
			return FALSE;

		VTLOG("Writing options to Enviro.ini\n");
		StartDlg.PutOptionsTo(g_Options);
		g_Options.Write();
	}

	//
	// Create the main frame window
	//
	wxString title = _T("VTP Enviro");
#if VTLIB_PSM
	title += _T(" PSM");
#elif VTLIB_OSG
	title += _T(" OSG");
#elif VTLIB_SGL
	title += _T(" SGL");
#elif VTLIB_SSG
	title += _T(" SSG");
#endif
	VTLOG("Creating the frame window.\n");
	vtFrame *frame = new vtFrame(NULL, title,
		wxPoint(50, 50), wxSize(800, 600));

	vtGetScene()->Init();

	g_App.StartControlEngine();

	if (g_Options.m_bFullscreen)
		frame->SetFullScreen(true);

	return true;
}

int vtApp::OnExit()
{
	VTLOG("App Exit\n");
#ifdef VTLIB_PSM
	PSWorld3D::Get()->Stop();
	PSGetScene()->SetWindow(NULL);
#endif
	g_App.Shutdown();
	vtGetScene()->Shutdown();

	return wxApp::OnExit();
}

//
// ask the user to choose from a list of known terrain
//
bool AskForTerrainName(wxWindow *pParent, wxString &str)
{
    vtTerrain *pTerr, *pFirst = GetTerrainScene()->GetFirstTerrain();

	// count them
	int num = 0;
    for (pTerr = pFirst; pTerr; pTerr=pTerr->GetNext())
		num++;

	// get their names
	wxString *choices = new wxString[num];
	num = 0;
	int first_idx = 0;
	for (pTerr = pFirst; pTerr; pTerr=pTerr->GetNext())
	{
#if SUPPORT_WSTRING && UNICODE
		wstring2 ws;
		ws.from_utf8(pTerr->GetName());
		choices[num] = wxString2(ws.c_str());
#else
		choices[num] = wxString2(pTerr->GetName());
#endif
		if (str == choices[num]) first_idx = num;
		num++;
	}

	if (!num)
	{
		wxMessageBox(_T("No terrains found (datapath/Terrains/*.ini)"));
		return false;
	}

	wxSingleChoiceDialog dlg(pParent, _T("Please choose a terrain"),
		_T("Select Terrain"), num, choices);
	dlg.SetSelection(first_idx);
	delete [] choices;
	if (dlg.ShowModal() == wxID_OK)
	{
		str = dlg.GetStringSelection();
		return true;
	}
	else
		return false;
}
<commit_msg>explicitly tell MSVC to dump mem leaks in debug mode<commit_after>//
// Name:     app.cpp
// Purpose:  The application class for our wxWindows application.
//
// Copyright (c) 2001-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/image.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "vtlib/core/TerrainScene.h"
#include "../Enviro.h"		// for g_App, GetTerrainScene
#include "../Options.h"
#include "vtdata/vtLog.h"

#include "app.h"
#include "frame.h"
#include "StartupDlg.h"

IMPLEMENT_APP(vtApp)

vtApp::vtApp()
{
	m_bShowStartupDialog = true;
}

void vtApp::Args(int argc, wxChar **argv)
{
	for (int i = 0; i < argc; i++)
	{
		wxString2 str = argv[i];
		const char *cstr = str.mb_str();
		g_App.StartupArgument(i, cstr);
		if (!strcmp(cstr, "-no_startup_dialog"))
			m_bShowStartupDialog = false;
		else if (!strcmp(cstr, "-fullscreen"))
			g_Options.m_bFullscreen = true;
		else if(!strncmp(cstr, "-terrain=", 9))
		{
			m_bShowStartupDialog = false;
			g_Options.m_strInitTerrain = cstr+9;
		}
	}
}

//
// Initialize the app object
//
bool vtApp::OnInit()
{
#if WIN32 && defined(_MSC_VER) && DEBUG
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	g_Options.Read("Enviro.ini");

	g_App.Startup();	// starts log

	VTLOG("Application framework: wxWindows v" wxVERSION_NUM_DOT_STRING "\n");
	Args(argc, argv);

	g_App.LoadTerrainDescriptions();

/*	class AA { public: virtual void func() {} };
	class BB : public AA {};
	VTLOG("Testing the ability to use dynamic_cast to downcast...\n");
	BB *b = new BB;
	AA *a = (AA *) b;
	BB *result1 = dynamic_cast<BB *>(a);
	VTLOG("  successful (%lx)\n", result1); */

	//
	// Create and show the Startup Dialog
	//
	if (m_bShowStartupDialog)
	{
		VTLOG("Opening the Startup dialog.\n");
		StartupDlg StartDlg(NULL, -1, _T("Enviro Startup"), wxDefaultPosition);
		StartDlg.GetOptionsFrom(g_Options);
		StartDlg.CenterOnParent();
		int result = StartDlg.ShowModal();
		if (result == wxID_CANCEL)
			return FALSE;

		VTLOG("Writing options to Enviro.ini\n");
		StartDlg.PutOptionsTo(g_Options);
		g_Options.Write();
	}

	//
	// Create the main frame window
	//
	wxString title = _T("VTP Enviro");
#if VTLIB_PSM
	title += _T(" PSM");
#elif VTLIB_OSG
	title += _T(" OSG");
#elif VTLIB_SGL
	title += _T(" SGL");
#elif VTLIB_SSG
	title += _T(" SSG");
#endif
	VTLOG("Creating the frame window.\n");
	vtFrame *frame = new vtFrame(NULL, title,
		wxPoint(50, 50), wxSize(800, 600));

	vtGetScene()->Init();

	g_App.StartControlEngine();

	if (g_Options.m_bFullscreen)
		frame->SetFullScreen(true);

	return true;
}

int vtApp::OnExit()
{
	VTLOG("App Exit\n");
#ifdef VTLIB_PSM
	PSWorld3D::Get()->Stop();
	PSGetScene()->SetWindow(NULL);
#endif
	g_App.Shutdown();
	vtGetScene()->Shutdown();

	return wxApp::OnExit();
}

//
// ask the user to choose from a list of known terrain
//
bool AskForTerrainName(wxWindow *pParent, wxString &str)
{
    vtTerrain *pTerr, *pFirst = GetTerrainScene()->GetFirstTerrain();

	// count them
	int num = 0;
    for (pTerr = pFirst; pTerr; pTerr=pTerr->GetNext())
		num++;

	// get their names
	wxString *choices = new wxString[num];
	num = 0;
	int first_idx = 0;
	for (pTerr = pFirst; pTerr; pTerr=pTerr->GetNext())
	{
#if SUPPORT_WSTRING && UNICODE
		wstring2 ws;
		ws.from_utf8(pTerr->GetName());
		choices[num] = wxString2(ws.c_str());
#else
		choices[num] = wxString2(pTerr->GetName());
#endif
		if (str == choices[num]) first_idx = num;
		num++;
	}

	if (!num)
	{
		wxMessageBox(_T("No terrains found (datapath/Terrains/*.ini)"));
		return false;
	}

	wxSingleChoiceDialog dlg(pParent, _T("Please choose a terrain"),
		_T("Select Terrain"), num, choices);
	dlg.SetSelection(first_idx);
	delete [] choices;
	if (dlg.ShowModal() == wxID_OK)
	{
		str = dlg.GetStringSelection();
		return true;
	}
	else
		return false;
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "routing/routing_quality/waypoints.hpp"

using namespace routing_quality;

namespace
{
UNIT_TEST(RoutingQuality_FinlandBridgeInsteadOfFerry)
{
  TEST(CheckCarRoute({56.11155, 12.81101} /* start */, {55.59857, 12.3069} /* finish */,
                     {{{55.56602, 12.88537}}} /* reference track */),
       ());
}
// TODO: This test doesn't pass because routing::RouteWeight::operator<
// prefer roads with less number of barriers. It will be more useful to consider
// barriers only with access=no/private/etc tag.
//UNIT_TEST(RoutingQuality_RussiaToCrimeaFerry)
//{
//  // From Russia to Crimea
//  TEST(CheckCarRoute({45.34123, 36.67679} /* start */, {45.36479, 36.62194} /* finish */,
//                     {{{45.3532, 36.64912}}} /* reference track */),
//       ());
//}

UNIT_TEST(RoutingQuality_RussiaFromCrimeaFerry)
{
  TEST(CheckCarRoute({45.36479, 36.62194} /* start */, {45.34123, 36.67679} /* finish */,
                     {{{45.3532, 36.64912}}} /* reference track */),
       ());
}
}  // namespace
<commit_msg>[routing] Add tests for routing_quality<commit_after>#include "testing/testing.hpp"

#include "routing/routing_quality/waypoints.hpp"

using namespace routing_quality;

namespace
{
UNIT_TEST(Ferry_RoutingQuality_FinlandBridgeInsteadOfFerry)
{
  TEST(CheckCarRoute({56.11155, 12.81101} /* start */, {55.59857, 12.3069} /* finish */,
                     {{{55.56602, 12.88537}}} /* reference track */),
       ());
}
// TODO: This test doesn't pass because routing::RouteWeight::operator<
// prefer roads with less number of barriers. It will be more useful to consider
// barriers only with access=no/private/etc tag.
//UNIT_TEST(Ferry_RoutingQuality_RussiaToCrimeaFerry)
//{
//  // From Russia to Crimea
//  TEST(CheckCarRoute({45.34123, 36.67679} /* start */, {45.36479, 36.62194} /* finish */,
//                     {{{45.3532, 36.64912}}} /* reference track */),
//       ());
//}

UNIT_TEST(Ferry_RoutingQuality_RussiaFromCrimeaFerry)
{
  TEST(CheckCarRoute({45.36479, 36.62194} /* start */, {45.34123, 36.67679} /* finish */,
                     {{{45.3532, 36.64912}}} /* reference track */),
       ());
}

// For tests Ferry_RoutingQuality_1 - Ferry_RoutingQuality_15
// Look to: https://confluence.mail.ru/display/MAPSME/Ferries for more details.

UNIT_TEST(Ferry_RoutingQuality_1)
{
  TEST(CheckCarRoute({67.89425, 13.00747} /* start */, {67.28024, 14.37397} /* finish */,
                     {{{67.60291, 13.65267}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_2)
{
  TEST(CheckCarRoute({51.91347, 5.24265} /* start */, {51.98885, 5.20058} /* finish */,
                     {{{51.97494, 5.10631}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_3)
{
  TEST(CheckCarRoute({50.68323, 7.15683} /* start */, {50.58042, 7.32259} /* finish */,
                     {{{50.72206, 7.14872}, {50.70747, 7.17801}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_4)
{
  TEST(CheckCarRoute({49.37098, 0.84813} /* start */, {49.47950, 0.80918} /* finish */,
                     {{{49.36829, 0.81359}, {49.41177, 0.79639}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_5)
{
  TEST(CheckCarRoute({53.59885, 9.32285} /* start */, {53.93504, 9.48396} /* finish */,
                     {{{53.55170, 9.89848}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_6)
{
  TEST(CheckCarRoute({48.268548, 21.483862} /* start */, {48.24756, 21.54246} /* finish */,
                     {{{48.32574, 21.56094}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_7)
{
  TEST(CheckCarRoute({52.09319, 25.96368} /* start */, {52.02190, 25.98767} /* finish */,
                     {{{52.08914, 26.13001}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_8)
{
  TEST(CheckCarRoute({53.36914, 17.95644} /* start */, {53.46632, 18.01876} /* finish */,
                     {{{53.31395, 17.98559}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_9)
{
  TEST(CheckCarRoute({52.57264, 14.83948} /* start */, {52.74278, 14.95435} /* finish */,
                     {{{52.65097, 14.99906}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_10)
{
  TEST(CheckCarRoute({63.33900, 10.27831} /* start */, {63.33338, 10.22694} /* finish */,
                     {{{63.32261, 10.26896}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_11)
{
  TEST(CheckCarRoute({56.51167, 10.28726} /* start */, {56.57695, 10.11188} /* finish */,
                     {{{56.44610, 10.26030}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_13)
{
  TEST(CheckCarRoute({51.53923, 11.78523} /* start */, {51.62372, 11.86635} /* finish */,
                     {{{51.50772, 11.94096}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_14)
{
  TEST(CheckCarRoute({52.68467, 16.24031} /* start */, {52.74559, 16.27202} /* finish */,
                     {{{52.71631, 16.37917}}} /* reference track */),
       ());
}

UNIT_TEST(Ferry_RoutingQuality_15)
{
  TEST(CheckCarRoute({48.29162, 22.21412} /* start */, {48.27409, 22.46155} /* finish */,
                     {{{48.43306, 22.23317}}} /* reference track */),
       ());
}
}  // namespace
<|endoftext|>


<commit_before>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/numeric_vector.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

Number cubic_test (const Point& p,
                   const Parameters&,
                   const std::string&,
                   const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);
  const Real & z = p(2);

  return x*(1-x)*(1-x) + x*x*(1-y) + x*(1-y)*(1-z) + y*(1-y)*z + z*(1-z)*(1-z);
}

class DefaultCouplingTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( DefaultCouplingTest );

  CPPUNIT_TEST( testCouplingOnEdge3 );
  CPPUNIT_TEST( testCouplingOnQuad9 );
  CPPUNIT_TEST( testCouplingOnTri6 );
  CPPUNIT_TEST( testCouplingOnHex27 );

  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

  void testCoupling(const ElemType elem_type)
  {
    Mesh mesh(*TestCommWorld);

    EquationSystems es(mesh);
    System &sys = es.add_system<System> ("SimpleSystem");
    sys.add_variable("u", THIRD, HIERARCHIC);
    dof_map.default_algebraic_ghosting().set_n_levels(3);

    const UniquePtr<Elem> test_elem = Elem::build(elem_type);
    const Real ymax = test_elem->dim() > 1;
    const Real zmax = test_elem->dim() > 2;
    const unsigned int ny = ymax * 15;
    const unsigned int nz = zmax * 15;

    MeshTools::Generation::build_cube (mesh,
                                       15, ny, nz
                                       0., 1.,
                                       0., ymax,
                                       0., zmax,
                                       elem_type);

    es.init();
    sys.project_solution(cubic_test, NULL, es.parameters);

    for (MeshBase::const_element_iterator elem_it  = mesh.active_local_elements_begin(),
                                          elem_end = mesh.active_local_elements_end();
         elem_it != elem_end; ++elem_it)
      {
        for (unsigned int s1=0; s1 != elem->n_neighbors(); ++s1)
          {
            const Elem *n1 = elem->neighbor(s1);
            if (!n1)
              continue;

            // Let's speed up this test by only checking the ghosted
            // elements which are most likely to break.
            if (n1->processor_id() == mesh.processor_id())
              continue;

            for (unsigned int s2=0; s2 != elem->n_neighbors(); ++s2)
              {
                const Elem *n2 = elem->neighbor(s2);
                if (!n2 ||
                    n2->processor_id() == mesh.processor_id())
                  continue;

                for (unsigned int s3=0; s3 != elem->n_neighbors(); ++s3)
                  {
                    const Elem *n3 = elem->neighbor(s3);
                    if (!n3 ||
                        n3->processor_id() == mesh.processor_id())
                      continue;

                    Point p = n3->centroid();

                    CPPUNIT_ASSERT_DOUBLES_EQUAL(libmesh_real(sys.point_value(0,p,n3)),
                                                 libmesh_real(cubic_test(p,es.parameters,"","")),
                                                 TOLERANCE*TOLERANCE);
                  }
              }
          }
      }
  }

  void testCouplingOnEdge3() { testCoupling(EDGE3); }
  void testCouplingOnQuad9() { testCoupling(QUAD9); }
  void testCouplingOnTri6()  { testCoupling(TRI6); }
  void testCouplingOnHex27() { testCoupling(HEX27); }

};

CPPUNIT_TEST_SUITE_REGISTRATION( DefaultCouplingTest );
<commit_msg>Fix trailing whitespace.<commit_after>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/numeric_vector.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

Number cubic_test (const Point& p,
                   const Parameters&,
                   const std::string&,
                   const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);
  const Real & z = p(2);

  return x*(1-x)*(1-x) + x*x*(1-y) + x*(1-y)*(1-z) + y*(1-y)*z + z*(1-z)*(1-z);
}

class DefaultCouplingTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( DefaultCouplingTest );

  CPPUNIT_TEST( testCouplingOnEdge3 );
  CPPUNIT_TEST( testCouplingOnQuad9 );
  CPPUNIT_TEST( testCouplingOnTri6 );
  CPPUNIT_TEST( testCouplingOnHex27 );

  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

  void testCoupling(const ElemType elem_type)
  {
    Mesh mesh(*TestCommWorld);

    EquationSystems es(mesh);
    System &sys = es.add_system<System> ("SimpleSystem");
    sys.add_variable("u", THIRD, HIERARCHIC);
    dof_map.default_algebraic_ghosting().set_n_levels(3);

    const UniquePtr<Elem> test_elem = Elem::build(elem_type);
    const Real ymax = test_elem->dim() > 1;
    const Real zmax = test_elem->dim() > 2;
    const unsigned int ny = ymax * 15;
    const unsigned int nz = zmax * 15;

    MeshTools::Generation::build_cube (mesh,
                                       15, ny, nz
                                       0., 1.,
                                       0., ymax,
                                       0., zmax,
                                       elem_type);

    es.init();
    sys.project_solution(cubic_test, NULL, es.parameters);

    for (MeshBase::const_element_iterator elem_it  = mesh.active_local_elements_begin(),
                                          elem_end = mesh.active_local_elements_end();
         elem_it != elem_end; ++elem_it)
      {
        for (unsigned int s1=0; s1 != elem->n_neighbors(); ++s1)
          {
            const Elem *n1 = elem->neighbor(s1);
            if (!n1)
              continue;

            // Let's speed up this test by only checking the ghosted
            // elements which are most likely to break.
            if (n1->processor_id() == mesh.processor_id())
              continue;

            for (unsigned int s2=0; s2 != elem->n_neighbors(); ++s2)
              {
                const Elem *n2 = elem->neighbor(s2);
                if (!n2 ||
                    n2->processor_id() == mesh.processor_id())
                  continue;

                for (unsigned int s3=0; s3 != elem->n_neighbors(); ++s3)
                  {
                    const Elem *n3 = elem->neighbor(s3);
                    if (!n3 ||
                        n3->processor_id() == mesh.processor_id())
                      continue;

                    Point p = n3->centroid();

                    CPPUNIT_ASSERT_DOUBLES_EQUAL(libmesh_real(sys.point_value(0,p,n3)),
                                                 libmesh_real(cubic_test(p,es.parameters,"","")),
                                                 TOLERANCE*TOLERANCE);
                  }
              }
          }
      }
  }

  void testCouplingOnEdge3() { testCoupling(EDGE3); }
  void testCouplingOnQuad9() { testCoupling(QUAD9); }
  void testCouplingOnTri6()  { testCoupling(TRI6); }
  void testCouplingOnHex27() { testCoupling(HEX27); }

};

CPPUNIT_TEST_SUITE_REGISTRATION( DefaultCouplingTest );
<|endoftext|>


<commit_before>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2013 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include "D4Group.h"
#include "D4EnumDefs.h"

#include <sstream>

#include "dods-limits.h"
#include "util.h"

namespace libdap {

/** Test if a particular value is legal for a given type. In a D4EnumDef,
 * all values are actually stored in a long long, but the different
 * enumerations can specify different types like Byte, Int32, ..., and this
 * method is used to test that the values match those types.
 */
bool
D4EnumDef::is_valid_enum_value(long long value)
{
    switch (type()) {
        case dods_int8_c:
            return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX);
        case dods_byte_c:
        case dods_uint8_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX);
        case dods_int16_c:
            return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX);
        case dods_uint16_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX);
        case dods_int32_c:
            return (value >= DODS_INT_MIN && value <= DODS_INT_MAX);
        case dods_uint32_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX);
        case dods_int64_c:
            return (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX);
        case dods_uint64_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX);
        default:
            return false;
    }
}

// Note that in order for this to work the second argument must not be a reference.
// jhrg 8/20/13
static bool
enum_def_name_eq(D4EnumDef *d, const string name)
{
    return d->name() == name;
}

D4EnumDef *
D4EnumDefs::find_enum_def(const string &name)
{
    D4EnumDefIter d = find_if(d_enums.begin(), d_enums.end(), bind2nd(ptr_fun(enum_def_name_eq), name));
    return (d != d_enums.end()) ? *d: 0;
}

void D4EnumDef::print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const
{
    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"EnumConst") < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)tuple.label.c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    ostringstream oss;
    oss << tuple.value;
    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "value", (const xmlChar*)oss.str().c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value");

    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element");
}

void D4EnumDef::print_dap4(XMLWriter &xml) const
{
    vector<D4EnumDef::tuple>::const_iterator i = d_tuples.begin();
    while(i != d_tuples.end()) {
        print_value(xml, *i++);
    }
}

void D4EnumDefs::m_print_enum(XMLWriter &xml, D4EnumDef *e) const
{
    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enumeration") < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)e->name().c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "basetype", (const xmlChar*)D4type_name(e->type()).c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    // print each of e.values
    e->print_dap4(xml);

    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element");
}

void D4EnumDefs::print_dap4(XMLWriter &xml, bool constrained) const
{
    D4EnumDefCIter i = d_enums.begin();
    while (i != d_enums.end()) {
        if (!constrained || parent()->find_first_var_that_uses_enumeration(*i))
            m_print_enum(xml, *i);
        ++i;
    }
}

} /* namespace libdap */
<commit_msg>CID 81360<commit_after>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2013 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include "D4Group.h"
#include "D4EnumDefs.h"

#include <sstream>

#include "dods-limits.h"
#include "util.h"

namespace libdap {

/** Test if a particular value is legal for a given type. In a D4EnumDef,
 * all values are actually stored in a long long, but the different
 * enumerations can specify different types like Byte, Int32, ..., and this
 * method is used to test that the values match those types.
 */
bool
D4EnumDef::is_valid_enum_value(long long value)
{
    switch (type()) {
        case dods_int8_c:
            return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX);
        case dods_byte_c:
        case dods_uint8_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX);
        case dods_int16_c:
            return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX);
        case dods_uint16_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX);
        case dods_int32_c:
            return (value >= DODS_INT_MIN && value <= DODS_INT_MAX);
        case dods_uint32_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX);
        case dods_int64_c:
            return true; // This is always true: (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX);
        case dods_uint64_c:
            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX);
        default:
            return false;
    }
}

// Note that in order for this to work the second argument must not be a reference.
// jhrg 8/20/13
static bool
enum_def_name_eq(D4EnumDef *d, const string name)
{
    return d->name() == name;
}

D4EnumDef *
D4EnumDefs::find_enum_def(const string &name)
{
    D4EnumDefIter d = find_if(d_enums.begin(), d_enums.end(), bind2nd(ptr_fun(enum_def_name_eq), name));
    return (d != d_enums.end()) ? *d: 0;
}

void D4EnumDef::print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const
{
    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"EnumConst") < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)tuple.label.c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    ostringstream oss;
    oss << tuple.value;
    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "value", (const xmlChar*)oss.str().c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value");

    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element");
}

void D4EnumDef::print_dap4(XMLWriter &xml) const
{
    vector<D4EnumDef::tuple>::const_iterator i = d_tuples.begin();
    while(i != d_tuples.end()) {
        print_value(xml, *i++);
    }
}

void D4EnumDefs::m_print_enum(XMLWriter &xml, D4EnumDef *e) const
{
    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enumeration") < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)e->name().c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "basetype", (const xmlChar*)D4type_name(e->type()).c_str()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");

    // print each of e.values
    e->print_dap4(xml);

    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
        throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element");
}

void D4EnumDefs::print_dap4(XMLWriter &xml, bool constrained) const
{
    D4EnumDefCIter i = d_enums.begin();
    while (i != d_enums.end()) {
        if (!constrained || parent()->find_first_var_that_uses_enumeration(*i))
            m_print_enum(xml, *i);
        ++i;
    }
}

} /* namespace libdap */
<|endoftext|>


<commit_before>/*
qgvdial is a cross platform Google Voice Dialer
Copyright (C) 2010  Yuvraaj Kelkar

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

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

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Contact: yuvraaj@gmail.com
*/

#include "GvXMLParser.h"
#include <QtXmlPatterns>

GvXMLParser::GvXMLParser (QObject *parent)
: QObject (parent)
, bEmitLog (true)
{
}//GvXMLParser::GvXMLParser

bool
GvXMLParser::startElement (const QString        & /*namespaceURI*/,
                           const QString        & /*localName   */,
                           const QString        & /*qName       */,
                           const QXmlAttributes & /*atts        */)
{
    strChars.clear ();
    return (true);
}//GvXMLParser::startElement

bool
GvXMLParser::endElement (const QString & /*namespaceURI*/,
                         const QString &localName   ,
                         const QString & /*qName       */)
{
    if (localName == "json") {
        strJson = strChars;
        if (bEmitLog) qDebug ("Got json characters");

#if 0
        QFile temp("dump-json.txt");
        temp.open (QIODevice::ReadWrite);
        temp.write (strJson.toAscii ());
        temp.close ();
#endif
    }

    if (localName == "html") {
        strHtml = "" + strChars + "";
        if (bEmitLog) qDebug ("Got html characters");

#if 0
        QFile temp("dump-html.txt");
        temp.open (QIODevice::ReadWrite);
        temp.write (strHtml.toAscii ());
        temp.close ();
#endif
    }// if html
    return (true);
}//GvXMLParser::endElement

bool
GvXMLParser::characters (const QString &ch)
{
    strChars += ch;
    return (true);
}//GvXMLParser::characters

void
GvXMLParser::setEmitLog (bool enable)
{
    bEmitLog = enable;
}//GvXMLParser::setEmitLog
<commit_msg>trim the xml<commit_after>/*
qgvdial is a cross platform Google Voice Dialer
Copyright (C) 2010  Yuvraaj Kelkar

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

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

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Contact: yuvraaj@gmail.com
*/

#include "GvXMLParser.h"
#include <QtXmlPatterns>

GvXMLParser::GvXMLParser (QObject *parent)
: QObject (parent)
, bEmitLog (true)
{
}//GvXMLParser::GvXMLParser

bool
GvXMLParser::startElement (const QString        & /*namespaceURI*/,
                           const QString        & /*localName   */,
                           const QString        & /*qName       */,
                           const QXmlAttributes & /*atts        */)
{
    strChars.clear ();
    return (true);
}//GvXMLParser::startElement

bool
GvXMLParser::endElement (const QString & /*namespaceURI*/,
                         const QString &localName   ,
                         const QString & /*qName       */)
{
    if (localName == "json") {
        strJson = strChars;
        if (bEmitLog) qDebug ("Got json characters");

#if 0
        QFile temp("dump-json.txt");
        temp.open (QIODevice::ReadWrite);
        temp.write (strJson.toAscii ());
        temp.close ();
#endif
    }

    if (localName == "html") {
        strHtml = "" + strChars.trimmed ()+ "";
        if (bEmitLog) qDebug ("Got html characters");

#if 0
        QFile temp("dump-html.txt");
        temp.open (QIODevice::ReadWrite);
        temp.write (strHtml.toAscii ());
        temp.close ();
#endif
    }// if html
    return (true);
}//GvXMLParser::endElement

bool
GvXMLParser::characters (const QString &ch)
{
    strChars += ch;
    return (true);
}//GvXMLParser::characters

void
GvXMLParser::setEmitLog (bool enable)
{
    bEmitLog = enable;
}//GvXMLParser::setEmitLog
<|endoftext|>


<commit_before>// Day8.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

static size_t GetUnescapedSize(const std::string & String);

int main()
{
	std::ifstream Input("Input.txt");

	if (!Input.is_open())
	{
		std::cout << "Error opening File!" << std::endl;
		return 0;
	}

	std::string Line;

	int32_t Difference = 0;

	while (std::getline(Input, Line))
	{
		Difference += (int32_t)(Line.size() - GetUnescapedSize(Line));
	}

	Input.close();

	std::cout << "Difference: " << Difference << std::endl;

	system("pause");

	return 0;
}

size_t GetUnescapedSize(const std::string & String)
{
	size_t Size = 0;
	for (std::string::const_iterator Character = (String.begin() + 1); Character != (String.end() - 1); Character++)
	{
		Size++;
		if (*Character == '\\')
		{
			Character++;

			switch (*Character)
			{
			case 'x':
				Character += 2;
				break;
			default:
				break;
			}
		}
	}

	return Size;
}
<commit_msg>Add solution for Day8 part two<commit_after>// Day8.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

static size_t GetUnescapedSize(const std::string & String);
static size_t GetEscapedSize(const std::string & String);

int main()
{
	std::ifstream Input("Input.txt");

	if (!Input.is_open())
	{
		std::cout << "Error opening File!" << std::endl;
		return 0;
	}

	std::string Line;

	int32_t DifferenceUnescaped = 0;
	int32_t DifferenceEscaped = 0;

	while (std::getline(Input, Line))
	{
		DifferenceUnescaped += (int32_t)(Line.size() - GetUnescapedSize(Line));
		DifferenceEscaped += (int32_t)(GetEscapedSize(Line) - Line.size());
	}

	Input.close();

	std::cout << "Difference Unescaped: " << DifferenceUnescaped << std::endl;
	std::cout << "Difference Escaped: " << DifferenceEscaped << std::endl;

	system("pause");

	return 0;
}

size_t GetUnescapedSize(const std::string & String)
{
	size_t Size = 0;
	for (std::string::const_iterator Character = (String.begin() + 1); Character != (String.end() - 1); Character++)
	{
		Size++;
		if (*Character == '\\')
		{
			Character++;

			switch (*Character)
			{
			case 'x':
				Character += 2;
				break;
			default:
				break;
			}
		}
	}

	return Size;
}

size_t GetEscapedSize(const std::string & String)
{
	size_t Size = 0;
	for (char Character : String)
	{
		switch (Character)
		{
		case '\\':
		case '\"':
			Size++;
		default:
			Size++;
			break;
		}

	}

	return Size + 2;
}<|endoftext|>


<commit_before>//#include <Stk.h>
#include <BandedWG.h>
#include <OpcodeBase.hpp>

template<typename T>
class STKInstrumentAdapter0 : public OpcodeBase< STKInstrumentAdapter0<T> >
{
public:
  // Outputs.
  MYFLT *aoutput;
  // Inputs.
  MYFLT *ifrequency;
  MYFLT *iamplitude;
  MYFLT *kcontroller;
  MYFLT *kvalue;
  // State.
  T *stkobject;
  size_t ksmps;
  int frames;
  STKInstrumentAdapter0() : stkobject(0) {}
  int init(ENVIRON *csound)
  {
    if(!stkobject)
      {
	Stk::setSampleRate(csound->GetSr(csound));
	ksmps = csound->GetKsmps(csound);
	stkobject = new T;
      }
    frames = OpcodeBase< STKInstrumentAdapter0<T> >::h.insdshead->p3 * csound->GetSr(csound);
    stkobject->noteOn(*ifrequency, *iamplitude);
    return OK;
  }
  int kontrol(ENVIRON *csound)
  {
    if(frames <= 0)
      {
	stkobject->noteOff(*iamplitude);
      }
    else
      {
	stkobject->controlChange(*kcontroller, *kvalue);
	for(size_t i = 0; i < ksmps; i++)
	  {
	    aoutput[i] = stkobject->tick();
	  }
	frames -= ksmps;
      }
    return OK;
  }
  int deinit(ENVIRON *csound)
  {
    if(stkobject)
      {
	delete stkobject;
	stkobject = 0;
      }
    return OK;
  }
};

STKInstrumentAdapter0<BandedWG> bandedWG;

extern "C"
{
  OENTRY oentries[] =
    {
      {"BandedWG",  sizeof(bandedWG),  5, "a",  "iikk", (SUBR) bandedWG.init_,  0, (SUBR) bandedWG.kontrol_,  (SUBR) bandedWG.deinit_ },
    };

  /**
   * Called by Csound to obtain the size of
   * the table of OENTRY structures defined in this shared library.
   */

  PUBLIC int opcode_size()
  {
    return sizeof(oentries);
  }

  /**
   * Called by Csound to obtain a pointer to
   * the table of OENTRY structures defined in this shared library.
   */

  PUBLIC OENTRY *opcode_init(ENVIRON *csound)
  {
    return oentries;
  }
};
<commit_msg>The Instrmnt ones more or less work (except for TubeBell, and I did not yet do Mesh2D). I have not done the Effects.<commit_after>#include <string>
#include <cstdlib>

#include <BandedWG.h>
#include <BeeThree.h>
#include <BlowBotl.h>
#include <BlowHole.h>
#include <Bowed.h>
#include <Brass.h>
#include <Clarinet.h>
#include <Drummer.h>
#include <Flute.h>
#include <FMVoices.h>
#include <HevyMetl.h>
#include <Mandolin.h>
//#include <Mesh2D.h>
#include <ModalBar.h>
#include <Moog.h>
#include <PercFlut.h>
#include <Plucked.h>
#include <Resonate.h>
#include <Rhodey.h>
#include <Saxofony.h>
#include <Shakers.h>
#include <Simple.h>
#include <Sitar.h>
#include <StifKarp.h>
#include <TubeBell.h>
#include <VoicForm.h>
#include <Whistle.h>
#include <Wurley.h>

#include <OpcodeBase.hpp>

template<typename T>
class STKInstrumentAdapter : public OpcodeBase< STKInstrumentAdapter<T> >
{
public:
  // Outputs.
  MYFLT *aoutput;
  // Inputs.
  MYFLT *ifrequency;
  MYFLT *iamplitude;
  MYFLT *kcontroller;
  MYFLT *kvalue;
  // State.
  T *instrument;
  size_t ksmps;
  bool released;
  MYFLT oldkcontroller;
  MYFLT oldkvalue;
  STKInstrumentAdapter() : instrument(0) {}
  int init(ENVIRON *csound)
  {
    if(!instrument)
      {
	Stk::setSampleRate(csound->GetSr(csound));
	instrument = new T();
      }
    ksmps = csound->GetKsmps(csound);
    instrument->noteOn(*ifrequency, *iamplitude);
    released = false;
    oldkcontroller = -1.0;
    oldkvalue = -1.0;
    return OK;
  }
  int kontrol(ENVIRON *csound)
  {
    MYFLT scoreTime = csound->GetScoreTime(csound);
    MYFLT offTime = OpcodeBase< STKInstrumentAdapter<T> >::h.insdshead->offtim;
    if(!released &&
       ( offTime <= scoreTime + .025 || OpcodeBase< STKInstrumentAdapter<T> >::h.insdshead->relesing))
      {
	instrument->noteOff(64.0);
	released = true;
      }
    if(!released)
      {
	if(*kcontroller != oldkcontroller || *kvalue != oldkvalue)
	  {
	    instrument->controlChange(static_cast<int>(*kcontroller), *kvalue);
	    oldkcontroller = *kcontroller;
	    oldkvalue = *kvalue;
	  }
	for(size_t i = 0; i < ksmps; i++)
	  {
	    aoutput[i] = instrument->tick();
	  }
      }
    else
      {
	for(size_t i = 0; i < ksmps; i++)
	  {
	    aoutput[i] = 0;
	  }
      }
    return OK;
  }
  int deinit(ENVIRON *csound)
  {
    if(instrument)
      {
	delete instrument;
	instrument = 0;
      }
    return OK;
  }
};

template<typename T>
class STKInstrumentAdapter1 : public OpcodeBase< STKInstrumentAdapter1<T> >
{
public:
  // Outputs.
  MYFLT *aoutput;
  // Inputs.
  MYFLT *ifrequency;
  MYFLT *iamplitude;
  MYFLT *kcontroller;
  MYFLT *kvalue;
  // State.
  T *instrument;
  size_t ksmps;
  bool released;
  MYFLT oldkcontroller;
  MYFLT oldkvalue;
  STKInstrumentAdapter1() : instrument(0) {}
  int init(ENVIRON *csound)
  {
    if(!instrument)
      {
	Stk::setSampleRate(csound->GetSr(csound));
	instrument = new T((StkFloat)10.0);
      }
    ksmps = csound->GetKsmps(csound);
    instrument->noteOn(*ifrequency, *iamplitude);
    released = false;
    oldkcontroller = -1.0;
    oldkvalue = -1.0;
    return OK;
  }
  int kontrol(ENVIRON *csound)
  {
    MYFLT scoreTime = csound->GetScoreTime(csound);
    MYFLT offTime = OpcodeBase< STKInstrumentAdapter1<T> >::h.insdshead->offtim;
    if(!released &&
       ( offTime <= scoreTime + .025 || OpcodeBase< STKInstrumentAdapter1<T> >::h.insdshead->relesing))
      {
	instrument->noteOff(64.0);
	released = true;
      }
    if(!released)
      {
	if(*kcontroller != oldkcontroller || *kvalue != oldkvalue)
	  {
	    instrument->controlChange(static_cast<int>(*kcontroller), *kvalue);
	    oldkcontroller = *kcontroller;
	    oldkvalue = *kvalue;
	  }
	for(size_t i = 0; i < ksmps; i++)
	  {
	    aoutput[i] = instrument->tick();
	  }
      }
    else
      {
	for(size_t i = 0; i < ksmps; i++)
	  {
	    aoutput[i] = 0;
	  }
      }
    return OK;
  }
  int deinit(ENVIRON *csound)
  {
    if(instrument)
      {
	delete instrument;
	instrument = 0;
      }
    return OK;
  }
};

extern "C"
{
  OENTRY oentries[] =
    {
      {
	"STKBandedWG",
	sizeof(STKInstrumentAdapter<BandedWG>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<BandedWG>::init_,
	0,
	(SUBR) STKInstrumentAdapter<BandedWG>::kontrol_,
	(SUBR) STKInstrumentAdapter<BandedWG>::deinit_
      },
      {
	"STKBeeThree",
	sizeof(STKInstrumentAdapter<BeeThree>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<BeeThree>::init_,
	0,
	(SUBR) STKInstrumentAdapter<BeeThree>::kontrol_,
	(SUBR) STKInstrumentAdapter<BeeThree>::deinit_
      },
      {
	"STKBlowBotl",
	sizeof(STKInstrumentAdapter<BlowBotl>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<BlowBotl>::init_,
	0,
	(SUBR) STKInstrumentAdapter<BlowBotl>::kontrol_,
	(SUBR) STKInstrumentAdapter<BlowBotl>::deinit_
      },
      {
	"STKBlowHole",
	sizeof(STKInstrumentAdapter1<BlowHole>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<BlowHole>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<BlowHole>::kontrol_,
	(SUBR) STKInstrumentAdapter1<BlowHole>::deinit_
      },
      {
	"STKBowed",
	sizeof(STKInstrumentAdapter1<Bowed>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Bowed>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Bowed>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Bowed>::deinit_
      },
      {
	"STKBrass",
	sizeof(STKInstrumentAdapter1<Brass>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Brass>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Brass>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Brass>::deinit_
      },
      {
	"STKClarinet",
	sizeof(STKInstrumentAdapter1<Clarinet>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Clarinet>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Clarinet>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Clarinet>::deinit_
      },
      {
	"STKDrummer",
	sizeof(STKInstrumentAdapter<Drummer>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Drummer>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Drummer>::kontrol_,
	(SUBR) STKInstrumentAdapter<Drummer>::deinit_
      },
      {
	"STKFlute",
	sizeof(STKInstrumentAdapter1<Flute>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Flute>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Flute>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Flute>::deinit_
      },
      {
	"STKFMVoices",
	sizeof(STKInstrumentAdapter<FMVoices>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<FMVoices>::init_,
	0,
	(SUBR) STKInstrumentAdapter<FMVoices>::kontrol_,
	(SUBR) STKInstrumentAdapter<FMVoices>::deinit_
      },
      {
	"STKHevyMetl",
	sizeof(STKInstrumentAdapter<HevyMetl>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<HevyMetl>::init_,
	0,
	(SUBR) STKInstrumentAdapter<HevyMetl>::kontrol_,
	(SUBR) STKInstrumentAdapter<HevyMetl>::deinit_
      },
      {
	"STKMandolin",
	sizeof(STKInstrumentAdapter1<Mandolin>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Mandolin>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Mandolin>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Mandolin>::deinit_
      },
      {
	"STKModalBar",
	sizeof(STKInstrumentAdapter<ModalBar>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<ModalBar>::init_,
	0,
	(SUBR) STKInstrumentAdapter<ModalBar>::kontrol_,
	(SUBR) STKInstrumentAdapter<ModalBar>::deinit_
      },
      {
	"STKMoog",
	sizeof(STKInstrumentAdapter<Moog>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Moog>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Moog>::kontrol_,
	(SUBR) STKInstrumentAdapter<Moog>::deinit_
      },
      {
	"STKPercFlut",
	sizeof(STKInstrumentAdapter<PercFlut>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<PercFlut>::init_,
	0,
	(SUBR) STKInstrumentAdapter<PercFlut>::kontrol_,
	(SUBR) STKInstrumentAdapter<PercFlut>::deinit_
      },
      {
	"STKPlucked",
	sizeof(STKInstrumentAdapter1<Plucked>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Plucked>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Plucked>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Plucked>::deinit_
      },
      {
	"STKResonate",
	sizeof(STKInstrumentAdapter<Resonate>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Resonate>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Resonate>::kontrol_,
	(SUBR) STKInstrumentAdapter<Resonate>::deinit_
      },
      {
	"STKRhodey",
	sizeof(STKInstrumentAdapter<Rhodey>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Rhodey>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Rhodey>::kontrol_,
	(SUBR) STKInstrumentAdapter<Rhodey>::deinit_
      },
      {
	"STKSaxofony",
	sizeof(STKInstrumentAdapter1<Saxofony>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<Saxofony>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<Saxofony>::kontrol_,
	(SUBR) STKInstrumentAdapter1<Saxofony>::deinit_
      },
      {
	"STKShakers",
	sizeof(STKInstrumentAdapter<Shakers>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Shakers>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Shakers>::kontrol_,
	(SUBR) STKInstrumentAdapter<Shakers>::deinit_
      },
      {
	"STKSimple",
	sizeof(STKInstrumentAdapter<Simple>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Simple>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Simple>::kontrol_,
	(SUBR) STKInstrumentAdapter<Simple>::deinit_
      },
      {
	"STKSitar",
	sizeof(STKInstrumentAdapter<Sitar>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Sitar>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Sitar>::kontrol_,
	(SUBR) STKInstrumentAdapter<Sitar>::deinit_
      },
      {
	"STKStifKarp",
	sizeof(STKInstrumentAdapter1<StifKarp>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter1<StifKarp>::init_,
	0,
	(SUBR) STKInstrumentAdapter1<StifKarp>::kontrol_,
	(SUBR) STKInstrumentAdapter1<StifKarp>::deinit_
      },
      {
	"STKTubeBell",
	sizeof(STKInstrumentAdapter<TubeBell>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<TubeBell>::init_,
	0,
	(SUBR) STKInstrumentAdapter<TubeBell>::kontrol_,
	(SUBR) STKInstrumentAdapter<TubeBell>::deinit_
      },
      {
	"STKVoicForm",
	sizeof(STKInstrumentAdapter<VoicForm>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<VoicForm>::init_,
	0,
	(SUBR) STKInstrumentAdapter<VoicForm>::kontrol_,
	(SUBR) STKInstrumentAdapter<VoicForm>::deinit_
      },
      {
	"STKWhistle",
	sizeof(STKInstrumentAdapter<Whistle>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Whistle>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Whistle>::kontrol_,
	(SUBR) STKInstrumentAdapter<Whistle>::deinit_
      },
      {
	"STKWurley",
	sizeof(STKInstrumentAdapter<Wurley>),
	5,
	"a",
	"iijj",
	(SUBR) STKInstrumentAdapter<Wurley>::init_,
	0,
	(SUBR) STKInstrumentAdapter<Wurley>::kontrol_,
	(SUBR) STKInstrumentAdapter<Wurley>::deinit_
      },
    };

  /**
   * Called by Csound to obtain the size of
   * the table of OENTRY structures defined in this shared library.
   */

  PUBLIC int opcode_size()
  {
    return sizeof(oentries);
  }

  /**
   * Called by Csound to obtain a pointer to
   * the table of OENTRY structures defined in this shared library.
   */

  PUBLIC OENTRY *opcode_init(ENVIRON *csound)
  {
    std::string path = std::getenv("RAWWAVE_PATH");
    Stk::setRawwavePath(path);
    return oentries;
  }
};
<|endoftext|>


<commit_before>
#include "CMesh.h"

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

CMesh * TraverseMesh(CMesh * Result, aiScene const * Scene, aiNode * Node, glm::mat4 Transformation)
{
	glm::mat4 LocalTransformation = glm::mat4(
		Node->mTransformation.a1, Node->mTransformation.b1, Node->mTransformation.c1, Node->mTransformation.d1,
		Node->mTransformation.a2, Node->mTransformation.b2, Node->mTransformation.c2, Node->mTransformation.d2,
		Node->mTransformation.a3, Node->mTransformation.b3, Node->mTransformation.c3, Node->mTransformation.d3,
		Node->mTransformation.a4, Node->mTransformation.b4, Node->mTransformation.c4, Node->mTransformation.d4
		);
	Transformation = Transformation * LocalTransformation;

	for (uint i = 0; i < Node->mNumMeshes; ++ i)
	{
		aiMesh * Mesh = Scene->mMeshes[Node->mMeshes[i]];
		CMesh::SMeshBuffer * Buffer = new CMesh::SMeshBuffer;

		for (uint j = 0; j < Mesh->mNumVertices; ++ j)
		{
			SVertex Vertex;
			Vertex.Position = vec3f(Mesh->mVertices[j].x, Mesh->mVertices[j].y, Mesh->mVertices[j].z);
			if (Mesh->HasNormals())
				Vertex.Normal = vec3f(Mesh->mNormals[j].x, Mesh->mNormals[j].y, Mesh->mNormals[j].z);
			if (Mesh->HasTextureCoords(0))
				Vertex.TextureCoordinates = vec2f(Mesh->mTextureCoords[0][j].x, Mesh->mTextureCoords[0][j].y);
			if (Mesh->HasVertexColors(0))
				Vertex.Color = color4f(Mesh->mColors[0][j].r, Mesh->mColors[0][j].g, Mesh->mColors[0][j].b, Mesh->mColors[0][j].a);

			glm::vec4 Pos = glm::vec4(Vertex.Position.X, Vertex.Position.Y, Vertex.Position.Z, 1);
			Pos = Transformation * Pos;
			Vertex.Position = vec3f(Pos.x, Pos.y, Pos.z);

			Buffer->Vertices.push_back(Vertex);
		}
		for (uint j = 0; j < Mesh->mNumFaces; ++ j)
		{
			CMesh::STriangle Triangle;
			for (uint k = 0; k < 3; ++ k)
				Triangle.Indices[k] = Mesh->mFaces[j].mIndices[k];

			Buffer->Triangles.push_back(Triangle);
		}

		Result->MeshBuffers.push_back(Buffer);
	}

	for (uint i = 0; i < Node->mNumChildren; ++ i)
		TraverseMesh(Result, Scene, Node->mChildren[i], Transformation);

	return Result;
}

CMesh * CMesh::Load(std::string const & FileName)
{
	Assimp::Importer Importer;

	aiScene const * const Scene = Importer.ReadFile(FileName,
		aiProcess_CalcTangentSpace |
		aiProcess_Triangulate |
		aiProcess_JoinIdenticalVertices |
		aiProcess_SortByPType
	);

	if (! Scene)
	{
		std::cerr << "Failed to import mesh file '" << FileName << "': " << Importer.GetErrorString() << std::endl;
		return 0;
	}

	CMesh * Result = new CMesh;
	TraverseMesh(Result, Scene, Scene->mRootNode, glm::mat4(1));
	return Result;
}
<commit_msg>+ Fixed material loading for assimp<commit_after>
#include "CMesh.h"

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

CMesh * TraverseMesh(CMesh * Result, aiScene const * Scene, aiNode * Node, glm::mat4 Transformation)
{
	glm::mat4 LocalTransformation = glm::mat4(
		Node->mTransformation.a1, Node->mTransformation.b1, Node->mTransformation.c1, Node->mTransformation.d1,
		Node->mTransformation.a2, Node->mTransformation.b2, Node->mTransformation.c2, Node->mTransformation.d2,
		Node->mTransformation.a3, Node->mTransformation.b3, Node->mTransformation.c3, Node->mTransformation.d3,
		Node->mTransformation.a4, Node->mTransformation.b4, Node->mTransformation.c4, Node->mTransformation.d4
		);
	Transformation = Transformation * LocalTransformation;

	for (uint i = 0; i < Node->mNumMeshes; ++ i)
	{
		aiMesh * Mesh = Scene->mMeshes[Node->mMeshes[i]];
		CMesh::SMeshBuffer * Buffer = new CMesh::SMeshBuffer;

		for (uint j = 0; j < Mesh->mNumVertices; ++ j)
		{
			SVertex Vertex;
			Vertex.Position = vec3f(Mesh->mVertices[j].x, Mesh->mVertices[j].y, Mesh->mVertices[j].z);
			if (Mesh->HasNormals())
				Vertex.Normal = vec3f(Mesh->mNormals[j].x, Mesh->mNormals[j].y, Mesh->mNormals[j].z);
			if (Mesh->HasTextureCoords(0))
				Vertex.TextureCoordinates = vec2f(Mesh->mTextureCoords[0][j].x, Mesh->mTextureCoords[0][j].y);
			if (Mesh->HasVertexColors(0))
				Vertex.Color = color4f(Mesh->mColors[0][j].r, Mesh->mColors[0][j].g, Mesh->mColors[0][j].b, Mesh->mColors[0][j].a);

			glm::vec4 Pos = glm::vec4(Vertex.Position.X, Vertex.Position.Y, Vertex.Position.Z, 1);
			Pos = Transformation * Pos;
			Vertex.Position = vec3f(Pos.x, Pos.y, Pos.z);

			Buffer->Vertices.push_back(Vertex);
		}
		for (uint j = 0; j < Mesh->mNumFaces; ++ j)
		{
			CMesh::STriangle Triangle;
			for (uint k = 0; k < 3; ++ k)
				Triangle.Indices[k] = Mesh->mFaces[j].mIndices[k];

			Buffer->Triangles.push_back(Triangle);
		}

		aiMaterial * Material = Scene->mMaterials[Mesh->mMaterialIndex];
		aiColor4D Color;
		Material->Get(AI_MATKEY_COLOR_DIFFUSE, Color);
		Buffer->Material.DiffuseColor = color4f(Color.r, Color.g, Color.b, Color.a);
		Material->Get(AI_MATKEY_COLOR_AMBIENT, Color);
		Buffer->Material.AmbientColor = color4f(Color.r, Color.g, Color.b, Color.a);
		Material->Get(AI_MATKEY_COLOR_SPECULAR, Color);
		Buffer->Material.SpecularColor = color4f(Color.r, Color.g, Color.b, Color.a);

		Result->MeshBuffers.push_back(Buffer);
	}

	for (uint i = 0; i < Node->mNumChildren; ++ i)
		TraverseMesh(Result, Scene, Node->mChildren[i], Transformation);

	return Result;
}

CMesh * CMesh::Load(std::string const & FileName)
{
	Assimp::Importer Importer;

	aiScene const * const Scene = Importer.ReadFile(FileName,
		aiProcess_CalcTangentSpace |
		aiProcess_Triangulate |
		aiProcess_JoinIdenticalVertices |
		aiProcess_SortByPType
	);

	if (! Scene)
	{
		std::cerr << "Failed to import mesh file '" << FileName << "': " << Importer.GetErrorString() << std::endl;
		return 0;
	}

	CMesh * Result = new CMesh;
	TraverseMesh(Result, Scene, Scene->mRootNode, glm::mat4(1));
	return Result;
}
<|endoftext|>


<commit_before><commit_msg>working<commit_after><|endoftext|>