<commit_before>/***********************************************************************************
** MIT License                                                                    **
**                                                                                **
** Copyright (c) 2018 Victor DENIS (victordenis01@gmail.com)                      **
**                                                                                **
** 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.                                                                      **
***********************************************************************************/

#include "TreeWidget.hpp"

#include <QInputDialog>

#include <QMenu>
#include <QAction>

#include <QApplication>
#include <QClipboard>

#include "AdBlock/Rule.hpp"
#include "AdBlock/Subscription.hpp"

namespace Sn {
namespace ADB {

TreeWidget::TreeWidget(Subscription* subscription, QWidget* parent) :
	QTreeWidget(parent),
	m_subscription(subscription),
	m_itemChangingBlock(false)
{
	setContextMenuPolicy(Qt::CustomContextMenu);
	setHeaderHidden(true);
	setAlternatingRowColors(true);
	setLayoutDirection(Qt::LeftToRight);

	connect(this, &QTreeWidget::customContextMenuRequested, this, &TreeWidget::contextMenuRequested);
	connect(this, &QTreeWidget::itemChanged, this, &TreeWidget::itemChanged);
	connect(m_subscription, &Subscription::subscriptionUpdated, this, &TreeWidget::subscriptionUpdated);
	connect(m_subscription, &Subscription::subscriptionError, this, &TreeWidget::subscriptionError);
}

void TreeWidget::showRule(const Rule* rule)
{
	if (!m_topItem && rule)
		m_ruleToBeSelected = rule->filter();
	else if (!m_ruleToBeSelected.isEmpty()) {
		QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);

		if (!items.isEmpty()) {
			QTreeWidgetItem* item = items[0];

			setCurrentItem(item);
			scrollToItem(item, QAbstractItemView::PositionAtCenter);
		}

		m_ruleToBeSelected.clear();
	}
}

void TreeWidget::refresh()
{
	m_itemChangingBlock = true;
	clear();

	QFont boldFont{};
	boldFont.setBold(true);

	m_topItem = new QTreeWidgetItem(this);
	m_topItem->setText(0, m_subscription->title());
	m_topItem->setFont(0, boldFont);
	addTopLevelItem(m_topItem);

	const QVector<Rule*>& allRules = m_subscription->allRulles();
	int index = 0;

		foreach (const Rule* rule, allRules) {
			QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
			item->setText(0, rule->filter());
			item->setData(0, Qt::UserRole + 10, index);

			if (m_subscription->canEditRules())
				item->setFlags(item->flags() | Qt::ItemIsEditable);

			adjustItemFeature(item, rule);
			++index;
		}

	showRule(nullptr);
	m_itemChangingBlock = false;
}

void TreeWidget::addRule()
{
	if (!m_subscription->canEditRules())
		return;

	QString newRule{QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:"))};

	if (newRule.isEmpty())
		return;

	Rule* rule{new Rule(newRule, m_subscription)};
	int offset = m_subscription->addRule(rule);
	QTreeWidgetItem* item{new QTreeWidgetItem()};

	item->setText(0, newRule);
	item->setData(0, Qt::UserRole + 10, offset);
	item->setFlags(item->flags() | Qt::ItemIsEditable);

	m_itemChangingBlock = true;
	m_topItem->addChild(item);
	m_itemChangingBlock = false;

	adjustItemFeature(item, rule);
}

void TreeWidget::removeRule()
{
	QTreeWidgetItem* item{currentItem()};

	if (!item || !m_subscription->canEditRules() || item == m_topItem)
		return;

	int offset{item->data(0, Qt::UserRole + 10).toInt()};

	m_subscription->removeRule(offset);
	m_refreshAllItemsNeeded = true;
	delete item;
}

void TreeWidget::contextMenuRequested(const QPoint& pos)
{
	if (!m_subscription->canEditRules())
		return;

	QTreeWidgetItem* item = itemAt(pos);
	if (!item)
		return;

	QMenu menu{};
	menu.addAction(tr("Add Rule"), this, &TreeWidget::addRule);
	menu.addSeparator();

	QAction* deleteAction{menu.addAction(tr("Remove Rule"), this, &TreeWidget::removeRule)};

	if (!item->parent())
		deleteAction->setDisabled(true);

	menu.exec(viewport()->mapToGlobal(pos));
}

void TreeWidget::itemChanged(QTreeWidgetItem* item)
{
	if (!item || m_itemChangingBlock)
		return;

	m_itemChangingBlock = true;
	m_refreshAllItemsNeeded = true;

	int offset{item->data(0, Qt::UserRole + 10).toInt()};
	const Rule* oldRule{m_subscription->rule(offset)};

	// Disable the rule
	if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) {
		const Rule* rule = m_subscription->disableRule(offset);
		adjustItemFeature(item, rule);
	} // Enable the rule
	else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
		const Rule* rule{m_subscription->enableRule(offset)};
		adjustItemFeature(item, rule);
	} // Custom rule has been chanded
	else if (m_subscription->canEditRules()) {
		Rule* newRule{new Rule(item->text(0), m_subscription)};
		const Rule* rule{m_subscription->replaceRule(newRule, offset)};
		adjustItemFeature(item, rule);
	}

	m_itemChangingBlock = false;
}

void TreeWidget::copyFilter()
{
	QTreeWidgetItem* item{currentItem()};

	if (!item)
		return;

	QApplication::clipboard()->setText(item->text(0));
}

void TreeWidget::subscriptionUpdated()
{
	refresh();

	m_itemChangingBlock = true;
	m_topItem->setText(0, tr("%1 (recently updated").arg(m_subscription->title()));
	m_itemChangingBlock = false;
}

void TreeWidget::subscriptionError(const QString& message)
{
	refresh();

	m_itemChangingBlock = true;
	m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message));
	m_itemChangingBlock = false;
}

void TreeWidget::adjustItemFeature(QTreeWidgetItem* item, const Rule* rule)
{
	if (!rule->isEnabled()) {
		QFont font{};

		font.setItalic(true);
		item->setForeground(0, QColor(Qt::gray));

		if (!rule->isComment()) {
			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
			item->setCheckState(0, Qt::Unchecked);
			item->setFont(0, font);
		}

		return;
	}

	item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
	item->setCheckState(0, Qt::Checked);

	if (rule->isException()) {
		item->setForeground(0, QColor(Qt::darkGreen));
		item->setFont(0, QFont());
	}
	else if (rule->isCSSRule()) {
		item->setForeground(0, QColor(Qt::darkBlue));
		item->setFont(0, QFont());
	}
}

void TreeWidget::keyPressEvent(QKeyEvent* event)
{
	if ((event->key() == Qt::Key_C && event->modifiers()) & Qt::ControlModifier)
		copyFilter();

	if (event->key() == Qt::Key_Delete)
		removeRule();

	QTreeWidget::keyPressEvent(event);
}
}
}<commit_msg>little fix<commit_after>/***********************************************************************************
** MIT License                                                                    **
**                                                                                **
** Copyright (c) 2018 Victor DENIS (victordenis01@gmail.com)                      **
**                                                                                **
** 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.                                                                      **
***********************************************************************************/

#include "TreeWidget.hpp"

#include <QInputDialog>

#include <QMenu>
#include <QAction>

#include <QApplication>
#include <QClipboard>

#include "AdBlock/Rule.hpp"
#include "AdBlock/Subscription.hpp"

namespace Sn {
namespace ADB {

TreeWidget::TreeWidget(Subscription* subscription, QWidget* parent) :
	QTreeWidget(parent),
	m_subscription(subscription),
	m_itemChangingBlock(false)
{
	setContextMenuPolicy(Qt::CustomContextMenu);
	setHeaderHidden(true);
	setAlternatingRowColors(true);
	setLayoutDirection(Qt::LeftToRight);

	connect(this, &QTreeWidget::customContextMenuRequested, this, &TreeWidget::contextMenuRequested);
	connect(this, &QTreeWidget::itemChanged, this, &TreeWidget::itemChanged);
	connect(m_subscription, &Subscription::subscriptionUpdated, this, &TreeWidget::subscriptionUpdated);
	connect(m_subscription, &Subscription::subscriptionError, this, &TreeWidget::subscriptionError);
}

void TreeWidget::showRule(const Rule* rule)
{
	if (!m_topItem && rule)
		m_ruleToBeSelected = rule->filter();
	else if (!m_ruleToBeSelected.isEmpty()) {
		QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);

		if (!items.isEmpty()) {
			QTreeWidgetItem* item = items[0];

			setCurrentItem(item);
			scrollToItem(item, QAbstractItemView::PositionAtCenter);
		}

		m_ruleToBeSelected.clear();
	}
}

void TreeWidget::refresh()
{
	m_itemChangingBlock = true;
	clear();

	QFont boldFont{};
	boldFont.setBold(true);

	m_topItem = new QTreeWidgetItem(this);
	m_topItem->setText(0, m_subscription->title());
	m_topItem->setFont(0, boldFont);
	addTopLevelItem(m_topItem);

	const QVector<Rule*>& allRules = m_subscription->allRulles();
	int index = 0;

		foreach (const Rule* rule, allRules) {
			QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
			item->setText(0, rule->filter());
			item->setData(0, Qt::UserRole + 10, index);

			if (m_subscription->canEditRules())
				item->setFlags(item->flags() | Qt::ItemIsEditable);

			adjustItemFeature(item, rule);
			++index;
		}

	showRule(nullptr);
	m_itemChangingBlock = false;
}

void TreeWidget::addRule()
{
	if (!m_subscription->canEditRules())
		return;

	QString newRule{QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:"))};

	if (newRule.isEmpty())
		return;

	Rule* rule{new Rule(newRule, m_subscription)};
	int offset = m_subscription->addRule(rule);
	QTreeWidgetItem* item{new QTreeWidgetItem()};

	item->setText(0, newRule);
	item->setData(0, Qt::UserRole + 10, offset);
	item->setFlags(item->flags() | Qt::ItemIsEditable);

	m_itemChangingBlock = true;
	m_topItem->addChild(item);
	m_itemChangingBlock = false;

	adjustItemFeature(item, rule);
}

void TreeWidget::removeRule()
{
	QTreeWidgetItem* item{currentItem()};

	if (!item || !m_subscription->canEditRules() || item == m_topItem)
		return;

	int offset{item->data(0, Qt::UserRole + 10).toInt()};

	m_subscription->removeRule(offset);
	m_refreshAllItemsNeeded = true;
	delete item;
}

void TreeWidget::contextMenuRequested(const QPoint& pos)
{
	if (!m_subscription->canEditRules())
		return;

	QTreeWidgetItem* item = itemAt(pos);
	if (!item)
		return;

	QMenu menu{};
	menu.addAction(tr("Add Rule"), this, &TreeWidget::addRule);
	menu.addSeparator();

	QAction* deleteAction{menu.addAction(tr("Remove Rule"), this, &TreeWidget::removeRule)};

	if (!item->parent())
		deleteAction->setDisabled(true);

	menu.exec(viewport()->mapToGlobal(pos));
}

void TreeWidget::itemChanged(QTreeWidgetItem* item)
{
	if (!item || m_itemChangingBlock)
		return;

	m_itemChangingBlock = true;
	m_refreshAllItemsNeeded = true;

	int offset{item->data(0, Qt::UserRole + 10).toInt()};
	const Rule* oldRule{m_subscription->rule(offset)};

	// Disable the rule
	if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) {
		const Rule* rule = m_subscription->disableRule(offset);
		adjustItemFeature(item, rule);
	} // Enable the rule
	else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
		const Rule* rule{m_subscription->enableRule(offset)};
		adjustItemFeature(item, rule);
	} // Custom rule has been chanded
	else if (m_subscription->canEditRules()) {
		Rule* newRule{new Rule(item->text(0), m_subscription)};
		const Rule* rule{m_subscription->replaceRule(newRule, offset)};
		adjustItemFeature(item, rule);
	}

	m_itemChangingBlock = false;
}

void TreeWidget::copyFilter()
{
	QTreeWidgetItem* item{currentItem()};

	if (!item)
		return;

	QApplication::clipboard()->setText(item->text(0));
}

void TreeWidget::subscriptionUpdated()
{
	refresh();

	m_itemChangingBlock = true;
	m_topItem->setText(0, tr("%1 (recently updated").arg(m_subscription->title()));
	m_itemChangingBlock = false;
}

void TreeWidget::subscriptionError(const QString& message)
{
	refresh();

	m_itemChangingBlock = true;
	m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message));
	m_itemChangingBlock = false;
}

void TreeWidget::adjustItemFeature(QTreeWidgetItem* item, const Rule* rule)
{
	if (!rule->isEnabled()) {
		QFont font{};

		font.setItalic(true);
		item->setForeground(0, QColor(Qt::gray));

		if (!rule->isComment()) {
			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
			item->setCheckState(0, Qt::Unchecked);
			item->setFont(0, font);
		}

		return;
	}

	item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
	item->setCheckState(0, Qt::Checked);

	if (rule->isException()) {
		item->setForeground(0, QColor(Qt::darkGreen));
		item->setFont(0, QFont());
	}
	else if (rule->isCSSRule()) {
		item->setForeground(0, QColor(Qt::darkBlue));
		item->setFont(0, QFont());
	}
}

void TreeWidget::keyPressEvent(QKeyEvent* event)
{
	if (event->key() == Qt::Key_C && (event->modifiers() & Qt::ControlModifier))
		copyFilter();

	if (event->key() == Qt::Key_Delete)
		removeRule();

	QTreeWidget::keyPressEvent(event);
}
}
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Alexander Fronkin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "marcrecord.h"

using namespace marcrecord;

/*
 * Constructor.
 */
MarcRecord::Subfield::Subfield(char id, const std::string &data)
{
	clear();
	m_id = id;
	m_data = data;
}

/*
 * Clear subfield data.
 */
void
MarcRecord::Subfield::clear(void)
{
	m_id = ' ';
	m_data.erase();
}

/*
 * Get identifier of subfield.
 */
char &
MarcRecord::Subfield::getId(void)
{
	return m_id;
}

/*
 * Set identifier of subfield.
 */
void
MarcRecord::Subfield::setId(const char &id)
{
	m_id = id;
}

/*
 * Get data of subfield.
 */
std::string &
MarcRecord::Subfield::getData(void)
{
	return m_data;
}

/*
 * Set data of subfield.
 */
void
MarcRecord::Subfield::setData(const std::string &data)
{
	m_data = data;
}

/*
 * Check presence of embedded field.
 */
bool
MarcRecord::Subfield::isEmbedded(void)
{
	return (m_id == '1' ? true : false);
}

/*
 * Get tag of embedded field.
 */
std::string
MarcRecord::Subfield::getEmbeddedTag(void)
{
	if (m_id != '1') {
		return "";
	}

	return m_data.substr(0, 3);
}

/*
 * Get indicator 1 of embedded field.
 */
char
MarcRecord::Subfield::getEmbeddedInd1(void)
{
	if (m_id != '1' || m_data.substr(0, 3) < "010") {
		return '?';
	}

	return m_data[3];
}

/*
 * Get indicator 2 of embedded field.
 */
char
MarcRecord::Subfield::getEmbeddedInd2(void)
{
	if (m_id != '1' || m_data.substr(0, 3) < "010") {
		return '?';
	}

	return m_data[4];
}

/*
 * Get data of embedded field.
 */
std::string
MarcRecord::Subfield::getEmbeddedData(void)
{
	if (m_id != '1' || m_data.substr(0, 3) >= "010") {
		return "";
	}

	return m_data.substr(3);
}
<commit_msg>Added boundary checking before substr in embedded subfields functions<commit_after>/*
 * Copyright (c) 2013, Alexander Fronkin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "marcrecord.h"

using namespace marcrecord;

/*
 * Constructor.
 */
MarcRecord::Subfield::Subfield(char id, const std::string &data)
{
	clear();
	m_id = id;
	m_data = data;
}

/*
 * Clear subfield data.
 */
void
MarcRecord::Subfield::clear(void)
{
	m_id = ' ';
	m_data.erase();
}

/*
 * Get identifier of subfield.
 */
char &
MarcRecord::Subfield::getId(void)
{
	return m_id;
}

/*
 * Set identifier of subfield.
 */
void
MarcRecord::Subfield::setId(const char &id)
{
	m_id = id;
}

/*
 * Get data of subfield.
 */
std::string &
MarcRecord::Subfield::getData(void)
{
	return m_data;
}

/*
 * Set data of subfield.
 */
void
MarcRecord::Subfield::setData(const std::string &data)
{
	m_data = data;
}

/*
 * Check presence of embedded field.
 */
bool
MarcRecord::Subfield::isEmbedded(void)
{
	return (m_id == '1' ? true : false);
}

/*
 * Get tag of embedded field.
 */
std::string
MarcRecord::Subfield::getEmbeddedTag(void)
{
	if (m_id != '1') {
		return "";
	}

	return m_data.size() >= 3 ? m_data.substr(0, 3) : m_data;
}

/*
 * Get indicator 1 of embedded field.
 */
char
MarcRecord::Subfield::getEmbeddedInd1(void)
{
	if (m_id != '1' || m_data.size() < 4 || m_data.substr(0, 3) < "010") {
		return '?';
	}

	return m_data[3];
}

/*
 * Get indicator 2 of embedded field.
 */
char
MarcRecord::Subfield::getEmbeddedInd2(void)
{
	if (m_id != '1' || m_data.size() < 5 || m_data.substr(0, 3) < "010") {
		return '?';
	}

	return m_data[4];
}

/*
 * Get data of embedded field.
 */
std::string
MarcRecord::Subfield::getEmbeddedData(void)
{
	if (m_id != '1' || m_data.size() < 3 || m_data.substr(0, 3) >= "010") {
		return "";
	}

	return m_data.substr(3);
}
<|endoftext|>


<commit_before>/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

#include "qwt_arrow_button.h"
#include "qwt_math.h"
#include <qpainter.h>
#include <qstyle.h>
#include <qstyleoption.h>
#include <qevent.h>
#include <qapplication.h>

static const int MaxNum = 3;
static const int Margin = 2;
static const int Spacing = 1;

class QwtArrowButton::PrivateData
{
public:
    int num;
    Qt::ArrowType arrowType;
};

static QStyleOptionButton styleOpt( const QwtArrowButton* btn )
{
    QStyleOptionButton option;
    option.init( btn );
    option.features = QStyleOptionButton::None;
    if ( btn->isFlat() )
        option.features |= QStyleOptionButton::Flat;
    if ( btn->menu() )
        option.features |= QStyleOptionButton::HasMenu;
    if ( btn->autoDefault() || btn->isDefault() )
        option.features |= QStyleOptionButton::AutoDefaultButton;
    if ( btn->isDefault() )
        option.features |= QStyleOptionButton::DefaultButton;
    if ( btn->isDown() )
        option.state |= QStyle::State_Sunken;
    if ( !btn->isFlat() && !btn->isDown() )
        option.state |= QStyle::State_Raised;

    return option;
}

/*!
  \param num Number of arrows
  \param arrowType see Qt::ArrowType in the Qt docs.
  \param parent Parent widget
*/
QwtArrowButton::QwtArrowButton( int num,
        Qt::ArrowType arrowType, QWidget *parent ):
    QPushButton( parent )
{
    d_data = new PrivateData;
    d_data->num = qBound( 1, num, MaxNum );
    d_data->arrowType = arrowType;

    setAutoRepeat( true );
    setAutoDefault( false );

    switch ( d_data->arrowType )
    {
        case Qt::LeftArrow:
        case Qt::RightArrow:
            setSizePolicy( QSizePolicy::Expanding,
                QSizePolicy::Fixed );
            break;
        default:
            setSizePolicy( QSizePolicy::Fixed,
                QSizePolicy::Expanding );
    }
}

//! Destructor
QwtArrowButton::~QwtArrowButton()
{
    delete d_data;
    d_data = NULL;
}

/*!
  \brief The direction of the arrows
*/
Qt::ArrowType QwtArrowButton::arrowType() const
{
    return d_data->arrowType;
}

/*!
  \brief The number of arrows
*/
int QwtArrowButton::num() const
{
    return d_data->num;
}

/*!
  \return the bounding rectangle for the label
*/
QRect QwtArrowButton::labelRect() const
{
    const int m = Margin;

    QRect r = rect();
    r.setRect( r.x() + m, r.y() + m,
        r.width() - 2 * m, r.height() - 2 * m );

    if ( isDown() )
    {
        QStyleOptionButton option = styleOpt( this );
        const int ph = style()->pixelMetric(
            QStyle::PM_ButtonShiftHorizontal, &option, this );
        const int pv = style()->pixelMetric(
            QStyle::PM_ButtonShiftVertical, &option, this );

        r.translate( ph, pv );
    }

    return r;
}

/*!
   Paint event handler
   \param event Paint event
*/
void QwtArrowButton::paintEvent( QPaintEvent *event )
{
    QPushButton::paintEvent( event );
    QPainter painter( this );
    drawButtonLabel( &painter );
}

/*!
  \brief Draw the button label

  \param painter Painter
  \sa The Qt Manual for QPushButton
*/
void QwtArrowButton::drawButtonLabel( QPainter *painter )
{
    const bool isVertical = d_data->arrowType == Qt::UpArrow ||
        d_data->arrowType == Qt::DownArrow;

    const QRect r = labelRect();
    QSize boundingSize = labelRect().size();
    if ( isVertical )
        boundingSize.transpose();

    const int w =
        ( boundingSize.width() - ( MaxNum - 1 ) * Spacing ) / MaxNum;

    QSize arrow = arrowSize( Qt::RightArrow,
        QSize( w, boundingSize.height() ) );

    if ( isVertical )
        arrow.transpose();

    QRect contentsSize; // aligned rect where to paint all arrows
    if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow )
    {
        contentsSize.setWidth( d_data->num * arrow.width()
            + ( d_data->num - 1 ) * Spacing );
        contentsSize.setHeight( arrow.height() );
    }
    else
    {
        contentsSize.setWidth( arrow.width() );
        contentsSize.setHeight( d_data->num * arrow.height()
            + ( d_data->num - 1 ) * Spacing );
    }

    QRect arrowRect( contentsSize );
    arrowRect.moveCenter( r.center() );
    arrowRect.setSize( arrow );

    painter->save();
    for ( int i = 0; i < d_data->num; i++ )
    {
        drawArrow( painter, arrowRect, d_data->arrowType );

        int dx = 0;
        int dy = 0;

        if ( isVertical )
            dy = arrow.height() + Spacing;
        else
            dx = arrow.width() + Spacing;

        arrowRect.translate( dx, dy );
    }
    painter->restore();

    if ( hasFocus() )
    {
        QStyleOptionFocusRect option;
        option.init( this );
        option.backgroundColor = palette().color( QPalette::Window );

        style()->drawPrimitive( QStyle::PE_FrameFocusRect,
            &option, painter, this );
    }
}

/*!
    Draw an arrow int a bounding rectangle

    \param painter Painter
    \param r Rectangle where to paint the arrow
    \param arrowType Arrow type
*/
void QwtArrowButton::drawArrow( QPainter *painter,
    const QRect &r, Qt::ArrowType arrowType ) const
{
    QPolygon pa( 3 );

    switch ( arrowType )
    {
        case Qt::UpArrow:
            pa.setPoint( 0, r.bottomLeft() );
            pa.setPoint( 1, r.bottomRight() );
            pa.setPoint( 2, r.center().x(), r.top() );
            break;
        case Qt::DownArrow:
            pa.setPoint( 0, r.topLeft() );
            pa.setPoint( 1, r.topRight() );
            pa.setPoint( 2, r.center().x(), r.bottom() );
            break;
        case Qt::RightArrow:
            pa.setPoint( 0, r.topLeft() );
            pa.setPoint( 1, r.bottomLeft() );
            pa.setPoint( 2, r.right(), r.center().y() );
            break;
        case Qt::LeftArrow:
            pa.setPoint( 0, r.topRight() );
            pa.setPoint( 1, r.bottomRight() );
            pa.setPoint( 2, r.left(), r.center().y() );
            break;
        default:
            break;
    }

    painter->save();

    painter->setPen( palette().color( QPalette::ButtonText ) );
    painter->setBrush( palette().brush( QPalette::ButtonText ) );
    painter->drawPolygon( pa );

    painter->restore();
}

/*!
  \return a size hint
*/
QSize QwtArrowButton::sizeHint() const
{
    const QSize hint = minimumSizeHint();
    return hint.expandedTo( QApplication::globalStrut() );
}

/*!
  \brief Return a minimum size hint
*/
QSize QwtArrowButton::minimumSizeHint() const
{
    const QSize asz = arrowSize( Qt::RightArrow, QSize() );

    QSize sz(
        2 * Margin + ( MaxNum - 1 ) * Spacing + MaxNum * asz.width(),
        2 * Margin + asz.height()
    );

    if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow )
        sz.transpose();

    QStyleOption styleOption;
    styleOption.init( this );

    sz = style()->sizeFromContents( QStyle::CT_PushButton,
        &styleOption, sz, this );

    return sz;
}

/*!
   Calculate the size for a arrow that fits into a rectangle of a given size

   \param arrowType Arrow type
   \param boundingSize Bounding size
   \return Size of the arrow
*/
QSize QwtArrowButton::arrowSize( Qt::ArrowType arrowType,
    const QSize &boundingSize ) const
{
    QSize bs = boundingSize;
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
        bs.transpose();

    const int MinLen = 2;
    const QSize sz = bs.expandedTo(
        QSize( MinLen, 2 * MinLen - 1 ) ); // minimum

    int w = sz.width();
    int h = 2 * w - 1;

    if ( h > sz.height() )
    {
        h = sz.height();
        w = ( h + 1 ) / 2;
    }

    QSize arrSize( w, h );
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
        arrSize.transpose();

    return arrSize;
}

/*!
  \brief autoRepeat for the space keys
*/
void QwtArrowButton::keyPressEvent( QKeyEvent *event )
{
    if ( event->isAutoRepeat() && event->key() == Qt::Key_Space )
        Q_EMIT clicked();

    QPushButton::keyPressEvent( event );
}
<commit_msg>QwtArrowButton fixed<commit_after>/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

#include "qwt_arrow_button.h"
#include "qwt_math.h"
#include <qpainter.h>
#include <qstyle.h>
#include <qstyleoption.h>
#include <qevent.h>
#include <qapplication.h>

static const int MaxNum = 3;
static const int Margin = 2;
static const int Spacing = 1;

class QwtArrowButton::PrivateData
{
public:
    int num;
    Qt::ArrowType arrowType;
};

static QStyleOptionButton styleOpt( const QwtArrowButton* btn )
{
    QStyleOptionButton option;
    option.init( btn );
    option.features = QStyleOptionButton::None;
    if ( btn->isFlat() )
        option.features |= QStyleOptionButton::Flat;
    if ( btn->menu() )
        option.features |= QStyleOptionButton::HasMenu;
    if ( btn->autoDefault() || btn->isDefault() )
        option.features |= QStyleOptionButton::AutoDefaultButton;
    if ( btn->isDefault() )
        option.features |= QStyleOptionButton::DefaultButton;
    if ( btn->isDown() )
        option.state |= QStyle::State_Sunken;
    if ( !btn->isFlat() && !btn->isDown() )
        option.state |= QStyle::State_Raised;

    return option;
}

/*!
  \param num Number of arrows
  \param arrowType see Qt::ArrowType in the Qt docs.
  \param parent Parent widget
*/
QwtArrowButton::QwtArrowButton( int num,
        Qt::ArrowType arrowType, QWidget *parent ):
    QPushButton( parent )
{
    d_data = new PrivateData;
    d_data->num = qBound( 1, num, MaxNum );
    d_data->arrowType = arrowType;

    setAutoRepeat( true );
    setAutoDefault( false );

    switch ( d_data->arrowType )
    {
        case Qt::LeftArrow:
        case Qt::RightArrow:
            setSizePolicy( QSizePolicy::Expanding,
                QSizePolicy::Fixed );
            break;
        default:
            setSizePolicy( QSizePolicy::Fixed,
                QSizePolicy::Expanding );
    }
}

//! Destructor
QwtArrowButton::~QwtArrowButton()
{
    delete d_data;
    d_data = NULL;
}

/*!
  \brief The direction of the arrows
*/
Qt::ArrowType QwtArrowButton::arrowType() const
{
    return d_data->arrowType;
}

/*!
  \brief The number of arrows
*/
int QwtArrowButton::num() const
{
    return d_data->num;
}

/*!
  \return the bounding rectangle for the label
*/
QRect QwtArrowButton::labelRect() const
{
    const int m = Margin;

    QRect r = rect();
    r.setRect( r.x() + m, r.y() + m,
        r.width() - 2 * m, r.height() - 2 * m );

    if ( isDown() )
    {
        QStyleOptionButton option = styleOpt( this );
        const int ph = style()->pixelMetric(
            QStyle::PM_ButtonShiftHorizontal, &option, this );
        const int pv = style()->pixelMetric(
            QStyle::PM_ButtonShiftVertical, &option, this );

        r.translate( ph, pv );
    }

    return r;
}

/*!
   Paint event handler
   \param event Paint event
*/
void QwtArrowButton::paintEvent( QPaintEvent *event )
{
    QPushButton::paintEvent( event );
    QPainter painter( this );
    drawButtonLabel( &painter );
}

/*!
  \brief Draw the button label

  \param painter Painter
  \sa The Qt Manual for QPushButton
*/
void QwtArrowButton::drawButtonLabel( QPainter *painter )
{
    const bool isVertical = d_data->arrowType == Qt::UpArrow ||
        d_data->arrowType == Qt::DownArrow;

    const QRect r = labelRect();
    QSize boundingSize = labelRect().size();
    if ( isVertical )
        boundingSize.transpose();

    const int w =
        ( boundingSize.width() - ( MaxNum - 1 ) * Spacing ) / MaxNum;

    QSize arrow = arrowSize( Qt::RightArrow,
        QSize( w, boundingSize.height() ) );

    if ( isVertical )
        arrow.transpose();

    QRect contentsSize; // aligned rect where to paint all arrows
    if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow )
    {
        contentsSize.setWidth( d_data->num * arrow.width()
            + ( d_data->num - 1 ) * Spacing );
        contentsSize.setHeight( arrow.height() );
    }
    else
    {
        contentsSize.setWidth( arrow.width() );
        contentsSize.setHeight( d_data->num * arrow.height()
            + ( d_data->num - 1 ) * Spacing );
    }

    QRect arrowRect( contentsSize );
    arrowRect.moveCenter( r.center() );
    arrowRect.setSize( arrow );

    painter->save();
    for ( int i = 0; i < d_data->num; i++ )
    {
        drawArrow( painter, arrowRect, d_data->arrowType );

        int dx = 0;
        int dy = 0;

        if ( isVertical )
            dy = arrow.height() + Spacing;
        else
            dx = arrow.width() + Spacing;

        arrowRect.translate( dx, dy );
    }
    painter->restore();

    if ( hasFocus() )
    {
        QStyleOptionFocusRect option;
        option.init( this );
        option.backgroundColor = palette().color( QPalette::Window );

        style()->drawPrimitive( QStyle::PE_FrameFocusRect,
            &option, painter, this );
    }
}

/*!
    Draw an arrow int a bounding rectangle

    \param painter Painter
    \param r Rectangle where to paint the arrow
    \param arrowType Arrow type
*/
void QwtArrowButton::drawArrow( QPainter *painter,
    const QRect &r, Qt::ArrowType arrowType ) const
{
    QPolygon pa( 3 );

    switch ( arrowType )
    {
        case Qt::UpArrow:
            pa.setPoint( 0, r.bottomLeft() );
            pa.setPoint( 1, r.bottomRight() );
            pa.setPoint( 2, r.center().x(), r.top() );
            break;
        case Qt::DownArrow:
            pa.setPoint( 0, r.topLeft() );
            pa.setPoint( 1, r.topRight() );
            pa.setPoint( 2, r.center().x(), r.bottom() );
            break;
        case Qt::RightArrow:
            pa.setPoint( 0, r.topLeft() );
            pa.setPoint( 1, r.bottomLeft() );
            pa.setPoint( 2, r.right(), r.center().y() );
            break;
        case Qt::LeftArrow:
            pa.setPoint( 0, r.topRight() );
            pa.setPoint( 1, r.bottomRight() );
            pa.setPoint( 2, r.left(), r.center().y() );
            break;
        default:
            break;
    }

    painter->save();

    painter->setRenderHint( QPainter::Antialiasing, true );
    painter->setPen( Qt::NoPen );
    painter->setBrush( palette().brush( QPalette::ButtonText ) );
    painter->drawPolygon( pa );

    painter->restore();
}

/*!
  \return a size hint
*/
QSize QwtArrowButton::sizeHint() const
{
    const QSize hint = minimumSizeHint();
    return hint.expandedTo( QApplication::globalStrut() );
}

/*!
  \brief Return a minimum size hint
*/
QSize QwtArrowButton::minimumSizeHint() const
{
    const QSize asz = arrowSize( Qt::RightArrow, QSize() );

    QSize sz(
        2 * Margin + ( MaxNum - 1 ) * Spacing + MaxNum * asz.width(),
        2 * Margin + asz.height()
    );

    if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow )
        sz.transpose();

    QStyleOption styleOption;
    styleOption.init( this );

    sz = style()->sizeFromContents( QStyle::CT_PushButton,
        &styleOption, sz, this );

    return sz;
}

/*!
   Calculate the size for a arrow that fits into a rectangle of a given size

   \param arrowType Arrow type
   \param boundingSize Bounding size
   \return Size of the arrow
*/
QSize QwtArrowButton::arrowSize( Qt::ArrowType arrowType,
    const QSize &boundingSize ) const
{
    QSize bs = boundingSize;
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
        bs.transpose();

    const int MinLen = 2;
    const QSize sz = bs.expandedTo(
        QSize( MinLen, 2 * MinLen - 1 ) ); // minimum

    int w = sz.width();
    int h = 2 * w - 1;

    if ( h > sz.height() )
    {
        h = sz.height();
        w = ( h + 1 ) / 2;
    }

    QSize arrSize( w, h );
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
        arrSize.transpose();

    return arrSize;
}

/*!
  \brief autoRepeat for the space keys
*/
void QwtArrowButton::keyPressEvent( QKeyEvent *event )
{
    if ( event->isAutoRepeat() && event->key() == Qt::Key_Space )
        Q_EMIT clicked();

    QPushButton::keyPressEvent( event );
}
<|endoftext|>


<commit_before>#include "robocup-py.hpp"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <string>
#include <sstream>

using namespace boost::python;

#include <Geometry2d/Point.hpp>
#include <Robot.hpp>
#include <SystemState.hpp>
#include <protobuf/LogFrame.pb.h>

//	this is here so boost can work with std::shared_ptr
template<class T> T * get_pointer( std::shared_ptr<T> const& p) {
	return p.get();
}

std::string Point_repr(Geometry2d::Point *thiss) {
	std::ostringstream ss;
	ss << "Point(";
	ss << thiss->x;
	ss << ", ";
	ss << thiss->y;
	ss << ")";

	std::string repr(ss.str());
	return repr;
}

std::string Robot_repr(Robot *thiss) {
	std::ostringstream ss;
	ss << "<Robot ";
	ss << (thiss->self() ? "us[" : "them[");
	ss << thiss->shell();
	ss << "], pos=";
	ss << Point_repr(&(thiss->pos));
	ss << ">";

	std::string repr(ss.str());
	return repr;
}

void OurRobot_move_to(OurRobot *thiss, Geometry2d::Point *to) {
	thiss->move(*to);
}

/**
 * The code in this block wraps up c++ classes and makes them
 * accessible to python in the 'robocup' module.
 */
BOOST_PYTHON_MODULE(robocup)
{
	class_<Geometry2d::Point>("Point", init<float, float>())
		.def_readwrite("x", &Geometry2d::Point::x)
		.def_readwrite("y", &Geometry2d::Point::y)
		.def(self - self)
		.def(self + self)
		.def("mag", &Geometry2d::Point::mag)
		.def("__repr__", &Point_repr)
	;

	class_<Geometry2d::Segment>("Segment", init<Geometry2d::Point, Geometry2d::Point>())
		.def("center", &Geometry2d::Segment::center)
	;

	//		I'm holding off for now because GameState needs some attention on the C++
	//		side of things before we spread its shortcomings into the python world too...
	class_<GameState>("GameState")
		.def_readonly("our_score", &GameState::ourScore)
		.def_readonly("their_score", &GameState::theirScore)
		.def("is_halted", &GameState::halt)
		.def("is_stopped", &GameState::stopped)
		.def("is_playing", &GameState::playing)
		.def("is_kickoff", &GameState::kickoff)
		.def("is_penalty", &GameState::penalty)
		.def("is_direct", &GameState::direct)
		.def("is_indirect", &GameState::indirect)
		.def("is_our_kickoff", &GameState::ourKickoff)
		.def("is_our_penalty", &GameState::ourPenalty)
		.def("is_our_direct", &GameState::ourDirect)
		.def("is_our_indirect", &GameState::ourIndirect)
		.def("is_our_free_kick", &GameState::ourFreeKick)
		.def("is_their_kickoff", &GameState::theirKickoff)
		.def("is_their_penalty", &GameState::theirPenalty)
		.def("is_their_direct", &GameState::theirDirect)
		.def("is_their_indirect", &GameState::theirIndirect)
		.def("is_their_free_kick", &GameState::theirFreeKick)
		.def("is_setup_restart", &GameState::setupRestart)
		.def("can_kick", &GameState::canKick)
		.def("stay_away_from_ball", &GameState::stayAwayFromBall)
		.def("stay_on_side", &GameState::stayOnSide)
		.def("stay_behind_penalty_line", &GameState::stayBehindPenaltyLine)
	;

	class_<Robot>("Robot", init<int, bool>())
		.def("shell_id", &Robot::shell)
		.def("is_ours", &Robot::self)
		.def_readwrite("pos", &Robot::pos)
		.def_readwrite("vel", &Robot::vel)
		.def_readwrite("angle", &Robot::angle)
		.def_readwrite("angle_vel", &Robot::angleVel)
		.def("__repr__", &Robot_repr);
	;

	class_<OurRobot, OurRobot *, std::shared_ptr<OurRobot>, bases<Robot> >("OurRobot", init<int, SystemState*>())
		.def("move_to", &OurRobot_move_to)
	;

	class_<OpponentRobot, std::shared_ptr<OpponentRobot>, bases<Robot> >("OpponentRobot", init<int>());

	class_<Ball, std::shared_ptr<Ball> >("Ball", init<>())
		.def_readonly("pos", &Ball::pos)
		.def_readonly("vel", &Ball::vel)
		.def_readonly("valid", &Ball::valid)
	;

	class_<std::vector<OurRobot *> >("vector_OurRobot")
		.def(vector_indexing_suite<std::vector<OurRobot *> >())
	;

	class_<std::vector<OpponentRobot *> >("vector_OpponentRobot")
		.def(vector_indexing_suite<std::vector<OpponentRobot *> >())
	;

	class_<SystemState>("SystemState")
		.def_readonly("our_robots", &SystemState::self)
		.def_readonly("their_robots", &SystemState::opp)
		.def_readonly("ball", &SystemState::ball)
		.def_readonly("game_state", &SystemState::gameState)
		.def_readonly("timestamp", &SystemState::timestamp)

		//	debug drawing methods
		.def("draw_circle", &SystemState::drawCircle)
		.def("draw_path", &SystemState::drawPath)
		.def("draw_text", &SystemState::drawText)
		.def("draw_obstacle", &SystemState::drawObstacle)
		.def("draw_obstacles", &SystemState::drawObstacles)
	;
}
<commit_msg>wrapped Geometry2d::Rect for python<commit_after>#include "robocup-py.hpp"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <string>
#include <sstream>

using namespace boost::python;

#include <Geometry2d/Point.hpp>
#include <Geometry2d/Rect.hpp>
#include <Robot.hpp>
#include <SystemState.hpp>
#include <protobuf/LogFrame.pb.h>

//	this is here so boost can work with std::shared_ptr
template<class T> T * get_pointer( std::shared_ptr<T> const& p) {
	return p.get();
}

std::string Point_repr(Geometry2d::Point *thiss) {
	std::ostringstream ss;
	ss << "Point(";
	ss << thiss->x;
	ss << ", ";
	ss << thiss->y;
	ss << ")";

	std::string repr(ss.str());
	return repr;
}

std::string Robot_repr(Robot *thiss) {
	std::ostringstream ss;
	ss << "<Robot ";
	ss << (thiss->self() ? "us[" : "them[");
	ss << thiss->shell();
	ss << "], pos=";
	ss << Point_repr(&(thiss->pos));
	ss << ">";

	std::string repr(ss.str());
	return repr;
}

void OurRobot_move_to(OurRobot *thiss, Geometry2d::Point *to) {
	thiss->move(*to);
}

void Rect_contains_rect(Geometry2d::Rect *thiss, Geometry2d::Rect *other) {
	return thiss->contains(*other);
}

void Rect_contains_point(Geometry2d::Rect *thiss, Geometry2d::Point *pt) {
	return thiss->contains(*pt);
}

/**
 * The code in this block wraps up c++ classes and makes them
 * accessible to python in the 'robocup' module.
 */
BOOST_PYTHON_MODULE(robocup)
{
	class_<Geometry2d::Point>("Point", init<float, float>())
		.def_readwrite("x", &Geometry2d::Point::x)
		.def_readwrite("y", &Geometry2d::Point::y)
		.def(self - self)
		.def(self + self)
		.def("mag", &Geometry2d::Point::mag)
		.def("__repr__", &Point_repr)
	;

	class_<Geometry2d::Segment>("Segment", init<Geometry2d::Point, Geometry2d::Point>())
		.def("center", &Geometry2d::Segment::center)
	;

	class_<Geometry2d::Rect>("Rect"), init<Geometry2d::Point, Geometry2d::Point>())
		.def("contains_rect", &Rect_contains_rect)
		.def("contains_point", &Rect_contains_point)
		.def("min_x", &Geometry2d::Rect::minx)
		.def("min_y", &Geometry2d::Rect::miny)
		.def("max_x", &Geometry2d::Rect::maxx)
		.def("max_y", &Geometry2d::Rect::maxy)
		.def("near_point", &Geometry2d::Rect::nearPoint)
		.def("intersects_rect", &Geometry2d::intersects)
	;

	//		I'm holding off for now because GameState needs some attention on the C++
	//		side of things before we spread its shortcomings into the python world too...
	class_<GameState>("GameState")
		.def_readonly("our_score", &GameState::ourScore)
		.def_readonly("their_score", &GameState::theirScore)
		.def("is_halted", &GameState::halt)
		.def("is_stopped", &GameState::stopped)
		.def("is_playing", &GameState::playing)
		.def("is_kickoff", &GameState::kickoff)
		.def("is_penalty", &GameState::penalty)
		.def("is_direct", &GameState::direct)
		.def("is_indirect", &GameState::indirect)
		.def("is_our_kickoff", &GameState::ourKickoff)
		.def("is_our_penalty", &GameState::ourPenalty)
		.def("is_our_direct", &GameState::ourDirect)
		.def("is_our_indirect", &GameState::ourIndirect)
		.def("is_our_free_kick", &GameState::ourFreeKick)
		.def("is_their_kickoff", &GameState::theirKickoff)
		.def("is_their_penalty", &GameState::theirPenalty)
		.def("is_their_direct", &GameState::theirDirect)
		.def("is_their_indirect", &GameState::theirIndirect)
		.def("is_their_free_kick", &GameState::theirFreeKick)
		.def("is_setup_restart", &GameState::setupRestart)
		.def("can_kick", &GameState::canKick)
		.def("stay_away_from_ball", &GameState::stayAwayFromBall)
		.def("stay_on_side", &GameState::stayOnSide)
		.def("stay_behind_penalty_line", &GameState::stayBehindPenaltyLine)
	;

	class_<Robot>("Robot", init<int, bool>())
		.def("shell_id", &Robot::shell)
		.def("is_ours", &Robot::self)
		.def_readwrite("pos", &Robot::pos)
		.def_readwrite("vel", &Robot::vel)
		.def_readwrite("angle", &Robot::angle)
		.def_readwrite("angle_vel", &Robot::angleVel)
		.def("__repr__", &Robot_repr);
	;

	class_<OurRobot, OurRobot *, std::shared_ptr<OurRobot>, bases<Robot> >("OurRobot", init<int, SystemState*>())
		.def("move_to", &OurRobot_move_to)
	;

	class_<OpponentRobot, std::shared_ptr<OpponentRobot>, bases<Robot> >("OpponentRobot", init<int>());

	class_<Ball, std::shared_ptr<Ball> >("Ball", init<>())
		.def_readonly("pos", &Ball::pos)
		.def_readonly("vel", &Ball::vel)
		.def_readonly("valid", &Ball::valid)
	;

	class_<std::vector<OurRobot *> >("vector_OurRobot")
		.def(vector_indexing_suite<std::vector<OurRobot *> >())
	;

	class_<std::vector<OpponentRobot *> >("vector_OpponentRobot")
		.def(vector_indexing_suite<std::vector<OpponentRobot *> >())
	;

	class_<SystemState>("SystemState")
		.def_readonly("our_robots", &SystemState::self)
		.def_readonly("their_robots", &SystemState::opp)
		.def_readonly("ball", &SystemState::ball)
		.def_readonly("game_state", &SystemState::gameState)
		.def_readonly("timestamp", &SystemState::timestamp)

		//	debug drawing methods
		.def("draw_circle", &SystemState::drawCircle)
		.def("draw_path", &SystemState::drawPath)
		.def("draw_text", &SystemState::drawText)
		.def("draw_obstacle", &SystemState::drawObstacle)
		.def("draw_obstacles", &SystemState::drawObstacles)
	;
}
<|endoftext|>


<commit_before>#include <deque>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>

#include "sstring.h"
#include "being.h"
#include "extern.h"

using namespace std;

namespace {
  deque<pair<int, char> > collection;
  int n = 1;

  void add_int(int const& k) {
    n = k;
  }

  void add_char(char const& c) {
    collection.push_back(make_pair(n, c));
    n = 1;
  }
};

bool parse(string path, deque<pair<int, char> >& res )
{
  string::const_iterator begin = path.begin();
  string::const_iterator end = path.end();
  using boost::spirit::qi::int_;
  using boost::spirit::qi::char_;

  boost::spirit::qi::parse(
    begin, end,
    *(-int_[&add_int] >> char_("neswud")[&add_char]));

  if (begin == end) {
    res.resize(collection.size());
    copy(collection.begin(), collection.end(), res.begin());
  }

  collection.clear();

  return begin == end;
}

/*
int main() {
  deque<pair<int, char> > res;

  if (parse("neswud1n2e10s11w20u21d1000n", res)) {
    cout << "Good parse:" << endl;
    while (!res.empty()) {
      cout << res.front().first << res.front().second << endl;
      res.pop_front();
    }
  } else {
    cout << "Bad parse" << endl;
  }
*/

void TBeing::doRun(sstring const& path) {
  deque<pair<int, char> > res;
  if (parse(path, res)) {
    while (!res.empty()) {
      int steps = res.front().first;
      char dir = res.front().second;
      for (int i = 0; i < steps; i++) {
	doMove(getDirFromChar(sstring() + dir));
      }
      res.pop_front();
    }
  }
}
<commit_msg>Accept spaces in 'run' command<commit_after>#include <deque>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>

#include "sstring.h"
#include "being.h"
#include "extern.h"

using namespace std;

namespace {
  deque<pair<int, char> > collection;
  int n = 1;

  void add_int(int const& k) {
    n = k;
  }

  void add_char(char const& c) {
    if (c != ' ') {
      collection.push_back(make_pair(n, c));
      n = 1;
    }
  }
};

bool parse(string path, deque<pair<int, char> >& res )
{
  string::const_iterator begin = path.begin();
  string::const_iterator end = path.end();
  using boost::spirit::qi::int_;
  using boost::spirit::qi::char_;

  boost::spirit::qi::parse(
    begin, end,
    *(-int_[&add_int] >> char_("neswud ")[&add_char]));

  if (begin == end) {
    res.resize(collection.size());
    copy(collection.begin(), collection.end(), res.begin());
  }

  collection.clear();

  return begin == end;
}

/*
int main() {
  deque<pair<int, char> > res;

  if (parse("neswud1n2e10s11w20u21d1000n", res)) {
    cout << "Good parse:" << endl;
    while (!res.empty()) {
      cout << res.front().first << res.front().second << endl;
      res.pop_front();
    }
  } else {
    cout << "Bad parse" << endl;
  }
*/

void TBeing::doRun(sstring const& path) {
  deque<pair<int, char> > res;
  if (parse(path, res)) {
    while (!res.empty()) {
      int steps = res.front().first;
      char dir = res.front().second;
      for (int i = 0; i < steps; i++) {
	doMove(getDirFromChar(sstring() + dir));
      }
      res.pop_front();
    }
  }
}
<|endoftext|>


<commit_before><commit_msg>coverity#1242932 Uncaught exception<commit_after><|endoftext|>


<commit_before>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  mud_assert(real_roomp(0) != NULL, "couldn't load room 0");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    bool invalidated = false;
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
        iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){

        if((*iter)->run(pulse, obj)){
          delete obj;
          invalidated = true;
          break;
        }
      }
    }
    if (invalidated) {
      auto newObjIter = find(object_list.begin(), object_list.end(), placeholder);
      if (objIter != newObjIter)
        objIter = newObjIter;
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if (tmp_ch->roomp == NULL || tmp_ch->getName().empty() || (tmp_ch->desc && tmp_ch->desc->character != tmp_ch))
    {
      vlogf(LOG_BUG, format("Error: character_list contains a bogus item (%s), removing.") % (
          tmp_ch->roomp == nullptr ? "no roomptr" :
          tmp_ch->getName().empty() ? "no name" :
          tmp_ch->desc && tmp_ch->desc->character != tmp_ch ? "bad char ptr in desc" :
          "bug"
          ));
      tmp_ch = temp;
      temp = temp->next;
    }

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      assert(tmp_ch); // I suppose this guy exists if we have already dereferenced it
      // even if shortDescr is NULL.
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
          tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      tmp_ch = temp;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
        (tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
          tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(TCharProcess *char_proc : char_procs) {
      if(char_proc->should_run(pulse.pulse)){
        if(char_proc->run(pulse, tmp_ch)){
          vlogf(LOG_MISC, format("Deleting char %s in room %i due to proc %s") %
              tmp_ch->getName() % tmp_ch ->roomp->number % char_proc->name);
          delete tmp_ch;
          tmp_ch = temp;
          break;
        }
      }
      if (!tmp_ch->roomp || tmp_ch->getName().empty()) {
        vlogf(LOG_BUG, format("Error: char %s roomp %p in proc %s") %
            tmp_ch->getName() % tmp_ch ->roomp % char_proc->name);
        tmp_ch = temp;
        temp = temp->next;
      }
    }
  }
}

void TScheduler::run(int pulseNum)
{
  pulse.init(pulseNum);

  // run general processes
  for(TProcess* proc : procs) {
    if(proc->should_run(pulse.pulse)){
      proc->run(pulse);
    }
  }

  pulse.init12(pulseNum);

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<commit_msg>remove spammy log line<commit_after>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  mud_assert(real_roomp(0) != NULL, "couldn't load room 0");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    bool invalidated = false;
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
        iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){

        if((*iter)->run(pulse, obj)){
          delete obj;
          invalidated = true;
          break;
        }
      }
    }
    if (invalidated) {
      auto newObjIter = find(object_list.begin(), object_list.end(), placeholder);
      if (objIter != newObjIter)
        objIter = newObjIter;
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if (tmp_ch->roomp == NULL || tmp_ch->getName().empty() || (tmp_ch->desc && tmp_ch->desc->character != tmp_ch))
    {
      vlogf(LOG_BUG, format("Error: character_list contains a bogus item (%s), removing.") % (
          tmp_ch->roomp == nullptr ? "no roomptr" :
          tmp_ch->getName().empty() ? "no name" :
          tmp_ch->desc && tmp_ch->desc->character != tmp_ch ? "bad char ptr in desc" :
          "bug"
          ));
      tmp_ch = temp;
      temp = temp->next;
    }

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      assert(tmp_ch); // I suppose this guy exists if we have already dereferenced it
      // even if shortDescr is NULL.
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
          tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      tmp_ch = temp;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
        (tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
          tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(TCharProcess *char_proc : char_procs) {
      if(char_proc->should_run(pulse.pulse)){
        if(char_proc->run(pulse, tmp_ch)){
          delete tmp_ch;
          tmp_ch = temp;
          break;
        }
      }
      if (!tmp_ch->roomp || tmp_ch->getName().empty()) {
        vlogf(LOG_BUG, format("Error: char %s roomp %p in proc %s") %
            tmp_ch->getName() % tmp_ch ->roomp % char_proc->name);
        tmp_ch = temp;
        temp = temp->next;
      }
    }
  }
}

void TScheduler::run(int pulseNum)
{
  pulse.init(pulseNum);

  // run general processes
  for(TProcess* proc : procs) {
    if(proc->should_run(pulse.pulse)){
      proc->run(pulse);
    }
  }

  pulse.init12(pulseNum);

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   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.
*/

#include <gtest/gtest.h>

#include <Core/Thread/Parallel.h>

TEST(ParallelTests, CanDoubleNumberInParallel)
{
  EXPECT_TRUE(false);
}<commit_msg>Write basic parallel unit test.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   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.
*/

#include <gtest/gtest.h>
#include <numeric>

#include <Core/Thread/Parallel.h>

using namespace SCIRun::Core::Thread;

TEST(ParallelTests, CanDoubleNumberInParallel)
{
  int size = Parallel::NumCores();
  std::vector<int> nums(size);
  int i = 0;
  std::generate(nums.begin(), nums.end(), [&]() {return i++;});

  int expectedSum = size * (size-1) / 2;
  EXPECT_EQ(expectedSum, std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>()));

  Parallel::RunTasks([&](int i) {nums[i]*=2;}, Parallel::NumCores());

  EXPECT_EQ(expectedSum * 2, std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>()));
}

//TODO
#if 0
TEST(ParallelTests, CanDoubleNumberWithParallelForEach)
{
  int size = 1000; //
  std::vector<int> nums(size);
  int i = 0;
  std::generate(nums.begin(), nums.end(), [&]() {return i++;});

  int expectedSum = size * (size-1) / 2;
  EXPECT_EQ(expectedSum, std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>()));

  Parallel::ForEach([&](int i) {nums[i]*=2; std::cout << i << std::endl;}, Parallel::NumCores());

  EXPECT_EQ(expectedSum * 2, std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>()));

  //EXPECT_TRUE(false);
}
#endif<|endoftext|>


<commit_before>/// \file ROOT/RBrowser.hxx
/// \ingroup WebGui ROOT7
/// \author Bertrand Bellenot <bertrand.bellenot@cern.ch>
/// \date 2019-02-28
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RBrowser
#define ROOT7_RBrowser

#include <ROOT/RWebWindow.hxx>
#include <ROOT/RCanvas.hxx>
#include <ROOT/RBrowserItem.hxx>

#include <vector>
#include <memory>
#include <stdint.h>

class TString;
class TCanvas;
class TFile;

namespace ROOT {
namespace Experimental {

/** Representation of single item in the file browser */
class RRootFileItem : public RBrowserItem {
public:
   // internal data, used for generate directory list
   int type{0};             ///<! file type
   int uid{0};              ///<! file uid
   int gid{0};              ///<! file gid
   bool islink{false};      ///<! true if symbolic link
   bool isdir{false};       ///<! true if directory
   long modtime{0};         ///<! modification time
   int64_t size{0};         ///<! file size

   // this is part for browser, visible for I/O
   std::string icon;     ///< icon name
   std::string fsize;    ///< file size
   std::string mtime;    ///< modification time
   std::string ftype;    ///< file attributes
   std::string fuid;     ///< user id
   std::string fgid;     ///< group id

   RRootFileItem() = default;

   RRootFileItem(const std::string &_name, int _nchilds) : RBrowserItem(_name, _nchilds) {}

   // should be here, one needs virtual table for correct streaming of RRootBrowserReply
   virtual ~RRootFileItem() = default;
};

/** Web-based ROOT file browser */

class RBrowser {

protected:

   std::string fTitle;  ///<! title
   unsigned fConnId{0}; ///<! default connection id

   std::string fDescPath;                ///<! last scanned directory
   std::vector<RRootFileItem> fDesc;     ///<! plain list of current directory
   std::vector<RRootFileItem *> fSorted; ///<! current sorted list (no ownership)

   bool fUseRCanvas{false};             ///<!  which canvas should be used
   std::vector<std::unique_ptr<TCanvas>> fCanvases;  ///<! canvases created by browser, should be closed at the end
   std::string fActiveCanvas;            ///<! name of active for RBrowser canvas, not a gPad!
   std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> fRCanvases; ///<!  ROOT7 canvases

   std::shared_ptr<RWebWindow> fWebWindow;   ///<! web window to browser

   TCanvas *AddCanvas();
   TCanvas *GetActiveCanvas() const;
   TFile *OpenFile(const std::string &fname);
   std::string GetCanvasUrl(TCanvas *canv);
   void CloseCanvas(const std::string &name);

   std::shared_ptr<RCanvas> AddRCanvas();
   std::shared_ptr<RCanvas> GetActiveRCanvas() const;
   std::string GetRCanvasUrl(std::shared_ptr<RCanvas> &canv);

   void AddFolder(const char *name);
   void AddFile(const char *name);
   void Browse(const std::string &path);
   void Build(const std::string &path);
   std::string GetClassIcon(std::string &classname);
   std::string GetFileIcon(TString &name);
   std::string ProcessBrowserRequest(const std::string &msg);
   std::string ProcessDblClick(const std::string &path);

   bool IsBuild() const { return fDesc.size() > 0; }

   void SendInitMsg(unsigned connid);
   void WebWindowCallback(unsigned connid, const std::string &arg);

public:
   RBrowser(bool use_rcanvas = false);
   virtual ~RBrowser();

   bool GetUseRCanvas() const { return fUseRCanvas; }
   void SetUseRCanvas(bool on = true) { fUseRCanvas = on; }

   /// show Browser in specified place
   void Show(const RWebDisplayArgs &args = "", bool always_start_new_browser = false);

   /// hide Browser
   void Hide();

};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>[rbrowser] use RCanvas by default<commit_after>/// \file ROOT/RBrowser.hxx
/// \ingroup WebGui ROOT7
/// \author Bertrand Bellenot <bertrand.bellenot@cern.ch>
/// \date 2019-02-28
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RBrowser
#define ROOT7_RBrowser

#include <ROOT/RWebWindow.hxx>
#include <ROOT/RCanvas.hxx>
#include <ROOT/RBrowserItem.hxx>

#include <vector>
#include <memory>
#include <stdint.h>

class TString;
class TCanvas;
class TFile;

namespace ROOT {
namespace Experimental {

/** Representation of single item in the file browser */
class RRootFileItem : public RBrowserItem {
public:
   // internal data, used for generate directory list
   int type{0};             ///<! file type
   int uid{0};              ///<! file uid
   int gid{0};              ///<! file gid
   bool islink{false};      ///<! true if symbolic link
   bool isdir{false};       ///<! true if directory
   long modtime{0};         ///<! modification time
   int64_t size{0};         ///<! file size

   // this is part for browser, visible for I/O
   std::string icon;     ///< icon name
   std::string fsize;    ///< file size
   std::string mtime;    ///< modification time
   std::string ftype;    ///< file attributes
   std::string fuid;     ///< user id
   std::string fgid;     ///< group id

   RRootFileItem() = default;

   RRootFileItem(const std::string &_name, int _nchilds) : RBrowserItem(_name, _nchilds) {}

   // should be here, one needs virtual table for correct streaming of RRootBrowserReply
   virtual ~RRootFileItem() = default;
};

/** Web-based ROOT file browser */

class RBrowser {

protected:

   std::string fTitle;  ///<! title
   unsigned fConnId{0}; ///<! default connection id

   std::string fDescPath;                ///<! last scanned directory
   std::vector<RRootFileItem> fDesc;     ///<! plain list of current directory
   std::vector<RRootFileItem *> fSorted; ///<! current sorted list (no ownership)

   bool fUseRCanvas{false};             ///<!  which canvas should be used
   std::vector<std::unique_ptr<TCanvas>> fCanvases;  ///<! canvases created by browser, should be closed at the end
   std::string fActiveCanvas;            ///<! name of active for RBrowser canvas, not a gPad!
   std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> fRCanvases; ///<!  ROOT7 canvases

   std::shared_ptr<RWebWindow> fWebWindow;   ///<! web window to browser

   TCanvas *AddCanvas();
   TCanvas *GetActiveCanvas() const;
   TFile *OpenFile(const std::string &fname);
   std::string GetCanvasUrl(TCanvas *canv);
   void CloseCanvas(const std::string &name);

   std::shared_ptr<RCanvas> AddRCanvas();
   std::shared_ptr<RCanvas> GetActiveRCanvas() const;
   std::string GetRCanvasUrl(std::shared_ptr<RCanvas> &canv);

   void AddFolder(const char *name);
   void AddFile(const char *name);
   void Browse(const std::string &path);
   void Build(const std::string &path);
   std::string GetClassIcon(std::string &classname);
   std::string GetFileIcon(TString &name);
   std::string ProcessBrowserRequest(const std::string &msg);
   std::string ProcessDblClick(const std::string &path);

   bool IsBuild() const { return fDesc.size() > 0; }

   void SendInitMsg(unsigned connid);
   void WebWindowCallback(unsigned connid, const std::string &arg);

public:
   RBrowser(bool use_rcanvas = true);
   virtual ~RBrowser();

   bool GetUseRCanvas() const { return fUseRCanvas; }
   void SetUseRCanvas(bool on = true) { fUseRCanvas = on; }

   /// show Browser in specified place
   void Show(const RWebDisplayArgs &args = "", bool always_start_new_browser = false);

   /// hide Browser
   void Hide();

};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TProcTop::TProcTop(){
  if((shmid=shmget(gamePort, shm_size, IPC_CREAT | 0666)) < 0){
    vlogf(LOG_BUG, "failed to get shared memory segment in TScheduler()");
    shm=NULL;
  } else if((shm = (char *)shmat(shmid, NULL, 0)) == (char *) -1){
    vlogf(LOG_BUG, "failed to attach shared memory segment in TScheduler()");
    shm=NULL;
  }
}

void TProcTop::clear(){
  if(shm){
    memset(shm, 0, shm_size);
    shm_ptr=shm;
    added.clear();
  }
}

void TProcTop::add(const sstring &s){
  if(shm &&
     ((unsigned int)(shm_size-(shm_ptr-shm)) > (s.length()+1)) &&
     (added.find(s)==added.end())){
    strcpy(shm_ptr, s.c_str());
    shm_ptr+=s.length()+1;
    added[s]=true;
  }
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;
  TTiming timer;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter)
      (*iter)->timing=0;
  }

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, obj)){
	  delete obj;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
	(*iter)->timing=0;
      }
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;
  TTiming timer;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter)
      (*iter)->timing=0;

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
	    tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
	(tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
	    tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, tmp_ch)){
	  delete tmp_ch;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
    temp = tmp_ch->next;  // just for safety
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
      }
    }
  }

}

void TScheduler::run(int pulseNum)
{
  TTiming timer;

  pulse.init(pulseNum);
  top.clear();

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run general processes
  for(std::vector<TProcess *>::iterator iter=procs.begin();
      iter!=procs.end();++iter){
    if((*iter)->should_run(pulse.pulse)){
      if(toggleInfo[TOG_GAMELOOP]->toggle)
	timer.start();
	top.add((*iter)->name);

      (*iter)->run(pulse);

      if(toggleInfo[TOG_GAMELOOP]->toggle){
	timer.end();
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)(timer.getElapsed()*1000000));
      }
    }
  }

  pulse.init12(pulseNum);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) distributed pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<commit_msg>Added a check for room 0 to be loadable<commit_after>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TProcTop::TProcTop(){
  if((shmid=shmget(gamePort, shm_size, IPC_CREAT | 0666)) < 0){
    vlogf(LOG_BUG, "failed to get shared memory segment in TScheduler()");
    shm=NULL;
  } else if((shm = (char *)shmat(shmid, NULL, 0)) == (char *) -1){
    vlogf(LOG_BUG, "failed to attach shared memory segment in TScheduler()");
    shm=NULL;
  }
}

void TProcTop::clear(){
  if(shm){
    memset(shm, 0, shm_size);
    shm_ptr=shm;
    added.clear();
  }
}

void TProcTop::add(const sstring &s){
  if(shm &&
     ((unsigned int)(shm_size-(shm_ptr-shm)) > (s.length()+1)) &&
     (added.find(s)==added.end())){
    strcpy(shm_ptr, s.c_str());
    shm_ptr+=s.length()+1;
    added[s]=true;
  }
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  mud_assert(real_roomp(0) != NULL, "couldn't load room 0");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;
  TTiming timer;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter)
      (*iter)->timing=0;
  }

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, obj)){
	  delete obj;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
	(*iter)->timing=0;
      }
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;
  TTiming timer;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter)
      (*iter)->timing=0;

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
	    tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
	(tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
	    tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, tmp_ch)){
	  delete tmp_ch;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
    temp = tmp_ch->next;  // just for safety
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
      }
    }
  }

}

void TScheduler::run(int pulseNum)
{
  TTiming timer;

  pulse.init(pulseNum);
  top.clear();

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run general processes
  for(std::vector<TProcess *>::iterator iter=procs.begin();
      iter!=procs.end();++iter){
    if((*iter)->should_run(pulse.pulse)){
      if(toggleInfo[TOG_GAMELOOP]->toggle)
	timer.start();
	top.add((*iter)->name);

      (*iter)->run(pulse);

      if(toggleInfo[TOG_GAMELOOP]->toggle){
	timer.end();
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)(timer.getElapsed()*1000000));
      }
    }
  }

  pulse.init12(pulseNum);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) distributed pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<|endoftext|>


<commit_before><commit_msg>Update photonic DCA (b->e vs Multi)<commit_after><|endoftext|>