<commit_before>/**
 * This file is part of TelepathyQt
 *
 * @copyright Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * @copyright Copyright (C) 2009 Nokia Corporation
 * @license LGPL 2.1
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt/AbstractInterface>

#include "TelepathyQt/_gen/abstract-interface.moc.hpp"

#include "TelepathyQt/debug-internal.h"

#include <TelepathyQt/Constants>
#include <TelepathyQt/DBusProxy>
#include <TelepathyQt/PendingVariant>
#include <TelepathyQt/PendingVariantMap>
#include <TelepathyQt/PendingVoid>
#include <TelepathyQt/Types>

#include <QDBusPendingCall>
#include <QDBusVariant>

namespace Tp
{

struct TP_QT_NO_EXPORT AbstractInterface::Private
{
    QString mError;
    QString mMessage;
    bool monitorProperties;
};

/**
 * \class AbstractInterface
 * \ingroup clientsideproxies
 * \headerfile TelepathyQt/abstract-interface.h <TelepathyQt/AbstractInterface>
 *
 * \brief The AbstractInterface class is the base class for all client side
 * D-Bus interfaces, allowing access to remote methods/properties/signals.
 */

AbstractInterface::AbstractInterface(const QString &busName,
        const QString &path, const QLatin1String &interface,
        const QDBusConnection &dbusConnection, QObject *parent)
    : QDBusAbstractInterface(busName, path, interface.latin1(), dbusConnection, parent),
      mPriv(new Private)
{
    mPriv->monitorProperties = false;
}

AbstractInterface::AbstractInterface(DBusProxy *parent, const QLatin1String &interface)
    : QDBusAbstractInterface(parent->busName(), parent->objectPath(),
            interface.latin1(), parent->dbusConnection(), parent),
      mPriv(new Private)
{
    mPriv->monitorProperties = false;
    connect(parent, SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
            this, SLOT(invalidate(Tp::DBusProxy*,QString,QString)));
}

AbstractInterface::~AbstractInterface()
{
    delete mPriv;
}

bool AbstractInterface::isValid() const
{
    return QDBusAbstractInterface::isValid() && mPriv->mError.isEmpty();
}

QString AbstractInterface::invalidationReason() const
{
    return mPriv->mError;
}

QString AbstractInterface::invalidationMessage() const
{
    return mPriv->mMessage;
}

void AbstractInterface::invalidate(DBusProxy *proxy,
        const QString &error, const QString &message)
{
    Q_ASSERT(!error.isEmpty());

    if (mPriv->mError.isEmpty()) {
        mPriv->mError = error;
        mPriv->mMessage = message;
    }
}

PendingVariant *AbstractInterface::internalRequestProperty(const QString &name) const
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("Get"));
    msg << interface() << name;
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVariant(pendingCall, DBusProxyPtr(proxy));
}

PendingOperation *AbstractInterface::internalSetProperty(const QString &name,
        const QVariant &newValue)
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("Set"));
    msg << interface() << name << QVariant::fromValue(QDBusVariant(newValue));
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVoid(pendingCall, DBusProxyPtr(proxy));
}

PendingVariantMap *AbstractInterface::internalRequestAllProperties() const
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("GetAll"));
    msg << interface();
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVariantMap(pendingCall, DBusProxyPtr(proxy));
}

/**
 * Sets whether this abstract interface will be monitoring properties or not. If it's set to monitor,
 * the signal propertiesChanged will be emitted whenever a property on this interface will
 * change.
 *
 * By default, AbstractInterface does not monitor properties: you need to call this method
 * for this to happen.
 *
 * \param monitorProperties Whether this interface should monitor property changes or not.
 * \sa isMonitoringProperties
 *     propertiesChanged()
 */
void AbstractInterface::setMonitorProperties(bool monitorProperties)
{
    if (monitorProperties == mPriv->monitorProperties) {
        return;
    }

    QStringList argumentMatch;
    argumentMatch << interface();

    if (monitorProperties) {
        connection().connect(service(), path(), TP_QT_IFACE_PROPERTIES,
                QLatin1String("PropertiesChanged"), argumentMatch,
                QString(), this,
                SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
    } else {
        connection().connect(service(), path(), TP_QT_IFACE_PROPERTIES,
                QLatin1String("PropertiesChanged"), argumentMatch,
                QString(), this,
                SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
    }
}

/**
 * Return whether this abstract interface is monitoring properties or not. If it's monitoring,
 * the signal propertiesChanged will be emitted whenever a property on this interface will
 * change.
 *
 * By default, AbstractInterface does not monitor properties: you need to call setMonitorProperties
 * for this to happen.
 *
 * \return \c true if the interface is monitoring for property changes, \c false otherwise.
 * \sa setMonitorProperties
 *     propertiesChanged()
 */
bool AbstractInterface::isMonitoringProperties() const
{
    return mPriv->monitorProperties;
}

void AbstractInterface::onPropertiesChanged(const QString &interface,
            const QVariantMap &changedProperties,
            const QStringList &invalidatedProperties)
{
    Q_EMIT propertiesChanged(changedProperties, invalidatedProperties);
}

/**
 * \fn void AbstractInterface::propertiesChanged(const QVariantMap &changedProperties,
 *             const QStringList &invalidatedProperties)
 *
 * Emitted when one or more properties on this interface change or become invalidated.
 * This signal will be emitted only if the interface is monitoring properties.
 *
 * \param changedProperties A map of the changed properties with their new value, if any.
 * \param invalidatedProperties A list of the invalidated properties, if any.
 * \sa isMonitoringProperties()
 */

} // Tp
<commit_msg>monitor-properties: Initialize private members inside Private<commit_after>/**
 * This file is part of TelepathyQt
 *
 * @copyright Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * @copyright Copyright (C) 2009 Nokia Corporation
 * @license LGPL 2.1
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt/AbstractInterface>

#include "TelepathyQt/_gen/abstract-interface.moc.hpp"

#include "TelepathyQt/debug-internal.h"

#include <TelepathyQt/Constants>
#include <TelepathyQt/DBusProxy>
#include <TelepathyQt/PendingVariant>
#include <TelepathyQt/PendingVariantMap>
#include <TelepathyQt/PendingVoid>
#include <TelepathyQt/Types>

#include <QDBusPendingCall>
#include <QDBusVariant>

namespace Tp
{

struct TP_QT_NO_EXPORT AbstractInterface::Private
{
    Private();
    QString mError;
    QString mMessage;
    bool monitorProperties;
};

AbstractInterface::Private::Private()
    : monitorProperties(false)
{
}

/**
 * \class AbstractInterface
 * \ingroup clientsideproxies
 * \headerfile TelepathyQt/abstract-interface.h <TelepathyQt/AbstractInterface>
 *
 * \brief The AbstractInterface class is the base class for all client side
 * D-Bus interfaces, allowing access to remote methods/properties/signals.
 */

AbstractInterface::AbstractInterface(const QString &busName,
        const QString &path, const QLatin1String &interface,
        const QDBusConnection &dbusConnection, QObject *parent)
    : QDBusAbstractInterface(busName, path, interface.latin1(), dbusConnection, parent),
      mPriv(new Private)
{
}

AbstractInterface::AbstractInterface(DBusProxy *parent, const QLatin1String &interface)
    : QDBusAbstractInterface(parent->busName(), parent->objectPath(),
            interface.latin1(), parent->dbusConnection(), parent),
      mPriv(new Private)
{
    connect(parent, SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
            this, SLOT(invalidate(Tp::DBusProxy*,QString,QString)));
}

AbstractInterface::~AbstractInterface()
{
    delete mPriv;
}

bool AbstractInterface::isValid() const
{
    return QDBusAbstractInterface::isValid() && mPriv->mError.isEmpty();
}

QString AbstractInterface::invalidationReason() const
{
    return mPriv->mError;
}

QString AbstractInterface::invalidationMessage() const
{
    return mPriv->mMessage;
}

void AbstractInterface::invalidate(DBusProxy *proxy,
        const QString &error, const QString &message)
{
    Q_ASSERT(!error.isEmpty());

    if (mPriv->mError.isEmpty()) {
        mPriv->mError = error;
        mPriv->mMessage = message;
    }
}

PendingVariant *AbstractInterface::internalRequestProperty(const QString &name) const
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("Get"));
    msg << interface() << name;
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVariant(pendingCall, DBusProxyPtr(proxy));
}

PendingOperation *AbstractInterface::internalSetProperty(const QString &name,
        const QVariant &newValue)
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("Set"));
    msg << interface() << name << QVariant::fromValue(QDBusVariant(newValue));
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVoid(pendingCall, DBusProxyPtr(proxy));
}

PendingVariantMap *AbstractInterface::internalRequestAllProperties() const
{
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(),
            TP_QT_IFACE_PROPERTIES, QLatin1String("GetAll"));
    msg << interface();
    QDBusPendingCall pendingCall = connection().asyncCall(msg);
    DBusProxy *proxy = qobject_cast<DBusProxy*>(parent());
    return new PendingVariantMap(pendingCall, DBusProxyPtr(proxy));
}

/**
 * Sets whether this abstract interface will be monitoring properties or not. If it's set to monitor,
 * the signal propertiesChanged will be emitted whenever a property on this interface will
 * change.
 *
 * By default, AbstractInterface does not monitor properties: you need to call this method
 * for this to happen.
 *
 * \param monitorProperties Whether this interface should monitor property changes or not.
 * \sa isMonitoringProperties
 *     propertiesChanged()
 */
void AbstractInterface::setMonitorProperties(bool monitorProperties)
{
    if (monitorProperties == mPriv->monitorProperties) {
        return;
    }

    QStringList argumentMatch;
    argumentMatch << interface();

    if (monitorProperties) {
        connection().connect(service(), path(), TP_QT_IFACE_PROPERTIES,
                QLatin1String("PropertiesChanged"), argumentMatch,
                QString(), this,
                SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
    } else {
        connection().connect(service(), path(), TP_QT_IFACE_PROPERTIES,
                QLatin1String("PropertiesChanged"), argumentMatch,
                QString(), this,
                SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
    }
}

/**
 * Return whether this abstract interface is monitoring properties or not. If it's monitoring,
 * the signal propertiesChanged will be emitted whenever a property on this interface will
 * change.
 *
 * By default, AbstractInterface does not monitor properties: you need to call setMonitorProperties
 * for this to happen.
 *
 * \return \c true if the interface is monitoring for property changes, \c false otherwise.
 * \sa setMonitorProperties
 *     propertiesChanged()
 */
bool AbstractInterface::isMonitoringProperties() const
{
    return mPriv->monitorProperties;
}

void AbstractInterface::onPropertiesChanged(const QString &interface,
            const QVariantMap &changedProperties,
            const QStringList &invalidatedProperties)
{
    Q_EMIT propertiesChanged(changedProperties, invalidatedProperties);
}

/**
 * \fn void AbstractInterface::propertiesChanged(const QVariantMap &changedProperties,
 *             const QStringList &invalidatedProperties)
 *
 * Emitted when one or more properties on this interface change or become invalidated.
 * This signal will be emitted only if the interface is monitoring properties.
 *
 * \param changedProperties A map of the changed properties with their new value, if any.
 * \param invalidatedProperties A list of the invalidated properties, if any.
 * \sa isMonitoringProperties()
 */

} // Tp
<|endoftext|>


<commit_before>#include "scene.h"

void CornellBoxScene::makeScene(aten::scene* scene)
{
	auto light = new aten::sphere(
		aten::vec3(50.0, 90.0, 81.6),
		15.0,
		new aten::emissive(aten::vec3(36.0, 36.0, 36.0)));

	double r = 1e3;

	auto left = new aten::sphere(
		aten::vec3(r + 1, 40.8, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75f, 0.25f, 0.25f)));

	auto right = new aten::sphere(
		aten::vec3(-r + 99, 40.8, 81.6),
		r,
		new aten::lambert(aten::vec3(0.25, 0.25, 0.75)));

	auto wall = new aten::sphere(
		aten::vec3(50, 40.8, r),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	auto floor = new aten::sphere(
		aten::vec3(50, r, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	auto ceil = new aten::sphere(
		aten::vec3(50, -r + 81.6, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	//auto tex = aten::ImageLoader::load("../../asset/earth.bmp");

	// ΋.
	auto green = new aten::sphere(
		aten::vec3(65, 20, 20),
		20,
		new aten::lambert(aten::vec3(0.25, 0.75, 0.25)));
		//new aten::lambert(aten::vec3(1, 1, 1), tex));

	// .
	auto mirror = new aten::sphere(
		aten::vec3(27, 16.5, 47),
		16.5,
		new aten::specular(aten::vec3(0.99, 0.99, 0.99)));

	// KX.
	auto glass = new aten::sphere(
		aten::vec3(77, 16.5, 78),
		16.5,
		new aten::refraction(aten::vec3(0.99, 0.99, 0.99), 1.5));

#if 1
	scene->add(light);
	scene->add(left);
	scene->add(right);
	scene->add(wall);
	scene->add(floor);
	scene->add(ceil);
	scene->add(green);
	scene->add(mirror);
	scene->add(glass);

	scene->addLight(light);
#endif
}

void CornellBoxScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(50.0, 52.0, 295.6);
	at = aten::vec3(50.0, 40.8, 119.0);
}

/////////////////////////////////////////////////////

aten::real drand48()
{
	return (aten::real)::rand() / RAND_MAX;
}

void RandomScene::makeScene(aten::scene* scene)
{
	auto s = new aten::sphere(aten::vec3(0, -1000, 0), 1000, new aten::lambert(aten::vec3(0.8, 0.8, 0.8)));
	scene->add(s);

	int i = 1;
	for (int x = -11; x < 11; x++) {
		for (int z = -11; z < 11; z++) {
			float choose_mtrl = drand48();

			aten::vec3 center(
				x + 0.9 * drand48(),
				0.2,
				z + 0.9 * drand48());

			if ((center - aten::vec3(4, 0.2, 0)).length() > 0.9) {
				if (choose_mtrl < 0.8) {
					// lambert
					s = new aten::sphere(
						center,
						0.2,
						new aten::lambert(aten::vec3(drand48() * drand48(), drand48() * drand48(), drand48() * drand48())));
				}
				else if (choose_mtrl < 0.95) {
					// specular
					s = new aten::sphere(
						center,
						0.2,
						new aten::specular(aten::vec3(0.5 * (1 + drand48()), 0.5 * (1 + drand48()), 0.5 * (1 + drand48()))));
				}
				else {
					// glass
					s = new aten::sphere(center, 0.2, new aten::refraction(aten::vec3(1), 1.5));
				}

				scene->add(s);
			}
		}
	}

	s = new aten::sphere(aten::vec3(0, 1, 0), 1.0, new aten::refraction(aten::vec3(1), 1.5));
	scene->add(s);

	s = new aten::sphere(aten::vec3(-4, 1, 0), 1.0, new aten::lambert(aten::vec3(0.4, 0.2, 0.1)));
	scene->add(s);

	s = new aten::sphere(aten::vec3(4, 1, 0), 1.0, new aten::specular(aten::vec3(0.7, 0.6, 0.5)));
	scene->add(s);
}

void RandomScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(13, 2, 3);
	at = aten::vec3(0, 0, 0);
}

/////////////////////////////////////////////////////

void MtrlTestScene::makeScene(aten::scene* scene)
{
	auto s_blinn = new aten::sphere(aten::vec3(0, 0, 0), 1.0, new aten::MicrofacetBlinn(aten::vec3(0.7, 0.6, 0.5), 200, 0.2));
	scene->add(s_blinn);

	auto s_ggx = new aten::sphere(aten::vec3(-3, 0, 0), 1.0, new aten::MicrofacetGGX(aten::vec3(0.7, 0.6, 0.5), 0.2, 0.2));
	scene->add(s_ggx);

	auto s_beckman = new aten::sphere(aten::vec3(+3, 0, 0), 1.0, new aten::MicrofacetBeckman(aten::vec3(0.7, 0.6, 0.5), 0.2, 0.2));
	scene->add(s_beckman);
}

void MtrlTestScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(0, 0, 13);
	at = aten::vec3(0, 0, 0);
}

/////////////////////////////////////////////////////

void ObjectScene::makeScene(aten::scene* scene)
{
	//auto obj = aten::ObjLoader::load("../../asset/suzanne.obj");
	auto obj = aten::ObjLoader::load("../../asset/teapot.obj");

	auto instance = new aten::objinstance(obj);

	scene->add(instance);
}

void ObjectScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	//pos = aten::vec3(0.0, 0.0, 10.0);
	pos = aten::vec3(0.0, 0.0, 60.0);
	at = aten::vec3(0.0, 0.0, 0.0);
}
<commit_msg>Modify scene for material test.<commit_after>#include "scene.h"

void CornellBoxScene::makeScene(aten::scene* scene)
{
	auto light = new aten::sphere(
		aten::vec3(50.0, 90.0, 81.6),
		15.0,
		new aten::emissive(aten::vec3(36.0, 36.0, 36.0)));

	double r = 1e3;

	auto left = new aten::sphere(
		aten::vec3(r + 1, 40.8, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75f, 0.25f, 0.25f)));

	auto right = new aten::sphere(
		aten::vec3(-r + 99, 40.8, 81.6),
		r,
		new aten::lambert(aten::vec3(0.25, 0.25, 0.75)));

	auto wall = new aten::sphere(
		aten::vec3(50, 40.8, r),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	auto floor = new aten::sphere(
		aten::vec3(50, r, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	auto ceil = new aten::sphere(
		aten::vec3(50, -r + 81.6, 81.6),
		r,
		new aten::lambert(aten::vec3(0.75, 0.75, 0.75)));

	//auto tex = aten::ImageLoader::load("../../asset/earth.bmp");

	// ΋.
	auto green = new aten::sphere(
		aten::vec3(65, 20, 20),
		20,
		new aten::lambert(aten::vec3(0.25, 0.75, 0.25)));
		//new aten::lambert(aten::vec3(1, 1, 1), tex));

	// .
	auto mirror = new aten::sphere(
		aten::vec3(27, 16.5, 47),
		16.5,
		new aten::specular(aten::vec3(0.99, 0.99, 0.99)));

	// KX.
	auto glass = new aten::sphere(
		aten::vec3(77, 16.5, 78),
		16.5,
		new aten::refraction(aten::vec3(0.99, 0.99, 0.99), 1.5));

#if 1
	scene->add(light);
	scene->add(left);
	scene->add(right);
	scene->add(wall);
	scene->add(floor);
	scene->add(ceil);
	scene->add(green);
	scene->add(mirror);
	scene->add(glass);

	scene->addLight(light);
#endif
}

void CornellBoxScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(50.0, 52.0, 295.6);
	at = aten::vec3(50.0, 40.8, 119.0);
}

/////////////////////////////////////////////////////

aten::real drand48()
{
	return (aten::real)::rand() / RAND_MAX;
}

void RandomScene::makeScene(aten::scene* scene)
{
	auto s = new aten::sphere(aten::vec3(0, -1000, 0), 1000, new aten::lambert(aten::vec3(0.8, 0.8, 0.8)));
	scene->add(s);

	int i = 1;
	for (int x = -11; x < 11; x++) {
		for (int z = -11; z < 11; z++) {
			float choose_mtrl = drand48();

			aten::vec3 center(
				x + 0.9 * drand48(),
				0.2,
				z + 0.9 * drand48());

			if ((center - aten::vec3(4, 0.2, 0)).length() > 0.9) {
				if (choose_mtrl < 0.8) {
					// lambert
					s = new aten::sphere(
						center,
						0.2,
						new aten::lambert(aten::vec3(drand48() * drand48(), drand48() * drand48(), drand48() * drand48())));
				}
				else if (choose_mtrl < 0.95) {
					// specular
					s = new aten::sphere(
						center,
						0.2,
						new aten::specular(aten::vec3(0.5 * (1 + drand48()), 0.5 * (1 + drand48()), 0.5 * (1 + drand48()))));
				}
				else {
					// glass
					s = new aten::sphere(center, 0.2, new aten::refraction(aten::vec3(1), 1.5));
				}

				scene->add(s);
			}
		}
	}

	s = new aten::sphere(aten::vec3(0, 1, 0), 1.0, new aten::refraction(aten::vec3(1), 1.5));
	scene->add(s);

	s = new aten::sphere(aten::vec3(-4, 1, 0), 1.0, new aten::lambert(aten::vec3(0.4, 0.2, 0.1)));
	scene->add(s);

	s = new aten::sphere(aten::vec3(4, 1, 0), 1.0, new aten::specular(aten::vec3(0.7, 0.6, 0.5)));
	scene->add(s);
}

void RandomScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(13, 2, 3);
	at = aten::vec3(0, 0, 0);
}

/////////////////////////////////////////////////////

void MtrlTestScene::makeScene(aten::scene* scene)
{
	auto s_blinn = new aten::sphere(aten::vec3(-1, 0, 0), 1.0, new aten::MicrofacetBlinn(aten::vec3(0.7, 0.6, 0.5), 200, 0.2));
	scene->add(s_blinn);

	auto s_ggx = new aten::sphere(aten::vec3(-3, 0, 0), 1.0, new aten::MicrofacetGGX(aten::vec3(0.7, 0.6, 0.5), 0.2, 0.2));
	scene->add(s_ggx);

	auto s_beckman = new aten::sphere(aten::vec3(+1, 0, 0), 1.0, new aten::MicrofacetBeckman(aten::vec3(0.7, 0.6, 0.5), 0.2, 0.2));
	scene->add(s_beckman);

	auto s_glass = new aten::sphere(aten::vec3(+3, 0, 0), 1.0, new aten::specular(aten::vec3(0.7, 0.6, 0.5)));
	scene->add(s_glass);
}

void MtrlTestScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	pos = aten::vec3(0, 0, 13);
	at = aten::vec3(0, 0, 0);
}

/////////////////////////////////////////////////////

void ObjectScene::makeScene(aten::scene* scene)
{
	//auto obj = aten::ObjLoader::load("../../asset/suzanne.obj");
	auto obj = aten::ObjLoader::load("../../asset/teapot.obj");

	auto instance = new aten::objinstance(obj);

	scene->add(instance);
}

void ObjectScene::getCameraPosAndAt(
	aten::vec3& pos,
	aten::vec3& at)
{
	//pos = aten::vec3(0.0, 0.0, 10.0);
	pos = aten::vec3(0.0, 0.0, 60.0);
	at = aten::vec3(0.0, 0.0, 0.0);
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_extension.h"

#include <memory>
#include <string>
#include <vector>

#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/extensions/atom_extension_system.h"
#include "atom/browser/extensions/tab_helper.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "components/prefs/pref_service.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/one_shot_event.h"
#include "native_mate/converter.h"
#include "native_mate/dictionary.h"

namespace mate {

template<>
struct Converter<extensions::Manifest::Location> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     extensions::Manifest::Location* out) {
    std::string type;
    if (!ConvertFromV8(isolate, val, &type))
      return false;

    if (type == "internal")
      *out = extensions::Manifest::Location::INTERNAL;
    else if (type == "external_pref")
      *out = extensions::Manifest::Location::EXTERNAL_PREF;
    else if (type == "external_registry")
      *out = extensions::Manifest::Location::EXTERNAL_REGISTRY;
    else if (type == "unpacked")
      *out = extensions::Manifest::Location::UNPACKED;
    else if (type == "component")
      *out = extensions::Manifest::Location::COMPONENT;
    else if (type == "external_pref_download")
      *out = extensions::Manifest::Location::EXTERNAL_PREF_DOWNLOAD;
    else if (type == "external_policy_download")
      *out = extensions::Manifest::Location::EXTERNAL_POLICY_DOWNLOAD;
    else if (type == "command_line")
      *out = extensions::Manifest::Location::COMMAND_LINE;
    else if (type == "external_policy")
      *out = extensions::Manifest::Location::EXTERNAL_POLICY;
    else if (type == "external_component")
      *out = extensions::Manifest::Location::EXTERNAL_COMPONENT;
    else
      *out = extensions::Manifest::Location::INVALID_LOCATION;
    return true;
  }
};

}  // namespace mate

namespace {

scoped_refptr<extensions::Extension> LoadExtension(const base::FilePath& path,
    const base::DictionaryValue& manifest,
    const extensions::Manifest::Location& manifest_location,
    int flags,
    std::string* error) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);

  scoped_refptr<extensions::Extension> extension(extensions::Extension::Create(
      path, manifest_location, manifest, flags, error));
  if (!extension.get())
    return NULL;

  std::vector<extensions::InstallWarning> warnings;
  if (!extensions::file_util::ValidateExtension(extension.get(),
                                                error,
                                                &warnings))
    return NULL;
  extension->AddInstallWarnings(warnings);

  return extension;
}

}  // namespace

namespace atom {

namespace api {

Extension::Extension(v8::Isolate* isolate,
                 AtomBrowserContext* browser_context)
    : browser_context_(browser_context) {
  Init(isolate);
  extensions::ExtensionRegistry::Get(browser_context_.get())->AddObserver(this);
}

Extension::~Extension() {
  if (extensions::ExtensionRegistry::Get(browser_context_.get())) {
    extensions::ExtensionRegistry::Get(browser_context_.get())->
        RemoveObserver(this);
  }
}

void Extension::LoadOnFILEThread(const base::FilePath path,
    std::unique_ptr<base::DictionaryValue> manifest,
    extensions::Manifest::Location manifest_location,
    int flags) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);

  std::string error;
  if (manifest->empty()) {
    manifest = extensions::file_util::LoadManifest(path, &error);
  }

  if (!manifest || !error.empty()) {
    content::BrowserThread::PostTask(
          content::BrowserThread::UI, FROM_HERE,
          base::Bind(&Extension::NotifyErrorOnUIThread,
              base::Unretained(this), error));
  } else {
    scoped_refptr<extensions::Extension> extension = LoadExtension(path,
                              *manifest,
                              manifest_location,
                              flags,
                              &error);

    if (!extension || !error.empty()) {
      content::BrowserThread::PostTask(
          content::BrowserThread::FILE, FROM_HERE,
          base::Bind(&Extension::NotifyErrorOnUIThread,
              base::Unretained(this), error));
    } else {
      content::BrowserThread::PostTask(
          content::BrowserThread::UI, FROM_HERE,
          base::Bind(&Extension::NotifyLoadOnUIThread,
              base::Unretained(this), base::Passed(&extension)));
    }
  }
}

void Extension::NotifyLoadOnUIThread(
    scoped_refptr<extensions::Extension> extension) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  extensions::ExtensionSystem::Get(browser_context_.get())->ready().Post(
        FROM_HERE,
        base::Bind(&Extension::AddExtension,
          // GetWeakPtr()
          base::Unretained(this), base::Passed(&extension)));
}

void Extension::NotifyErrorOnUIThread(const std::string& error) {
  node::Environment* env = node::Environment::GetCurrent(isolate());
  mate::EmitEvent(isolate(),
                env->process_object(),
                "extension-load-error",
                error);
}

void Extension::Load(mate::Arguments* args) {
  base::FilePath path;
  args->GetNext(&path);

  base::DictionaryValue manifest;
  args->GetNext(&manifest);

  extensions::Manifest::Location manifest_location =
      extensions::Manifest::Location::UNPACKED;
  args->GetNext(&manifest_location);

  int flags = 0;
  args->GetNext(&flags);

  std::unique_ptr<base::DictionaryValue> manifest_copy =
      manifest.CreateDeepCopy();

  content::BrowserThread::PostTask(
        content::BrowserThread::FILE, FROM_HERE,
        base::Bind(&Extension::LoadOnFILEThread,
            base::Unretained(this),
            path, Passed(&manifest_copy), manifest_location, flags));
}

void Extension::AddExtension(scoped_refptr<extensions::Extension> extension) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  extension_service->AddExtension(extension.get());
}

void Extension::OnExtensionReady(content::BrowserContext* browser_context,
                                const extensions::Extension* extension) {
  mate::Dictionary install_info = mate::Dictionary::CreateEmpty(isolate());
  install_info.Set("name", extension->non_localized_name());
  install_info.Set("id", extension->id());
  install_info.Set("url", extension->url().spec());
  install_info.Set("base_path", extension->path().value());
  install_info.Set("version", extension->VersionString());
  install_info.Set("description", extension->description());
  auto manifest = extension->manifest()->value()->CreateDeepCopy();
  install_info.Set("manifest", mate::ConvertToV8(isolate(), *manifest));
  node::Environment* env = node::Environment::GetCurrent(isolate());
  mate::EmitEvent(isolate(),
                  env->process_object(),
                  "EXTENSION_READY_INTERNAL",
                  install_info);
}

void Extension::OnExtensionUnloaded(content::BrowserContext* browser_context,
                            const extensions::Extension* extension,
                            extensions::UnloadedExtensionInfo::Reason reason) {
  node::Environment* env = node::Environment::GetCurrent(isolate());
  mate::EmitEvent(isolate(),
                  env->process_object(),
                  "extension-unloaded",
                  extension->id());
}

void Extension::Disable(const std::string& extension_id) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  if (extension_service) {
    extension_service->DisableExtension(
        extension_id, extensions::Extension::DISABLE_USER_ACTION);
  }
}

void Extension::Enable(const std::string& extension_id) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  if (extension_service) {
    extension_service->EnableExtension(
        extension_id);
  }
}

// static
bool Extension::IsBackgroundPageUrl(GURL url,
                    content::BrowserContext* browser_context) {
  if (url.scheme() != "chrome-extension")
    return false;

  if (extensions::ExtensionSystem::Get(browser_context)
      ->ready().is_signaled()) {
    const extensions::Extension* extension =
        extensions::ExtensionRegistry::Get(browser_context)->
            enabled_extensions().GetExtensionOrAppByURL(url);
    if (extension &&
        url == extensions::BackgroundInfo::GetBackgroundURL(extension))
      return true;
  }

  return false;
}

// static
bool Extension::IsBackgroundPageWebContents(
    content::WebContents* web_contents) {
  auto browser_context = web_contents->GetBrowserContext();
  auto url = web_contents->GetURL();

  return IsBackgroundPageUrl(url, browser_context);
}

// static
bool Extension::IsBackgroundPage(const WebContents* web_contents) {
  return IsBackgroundPageWebContents(web_contents->web_contents());
}

// static
v8::Local<v8::Value> Extension::TabValue(v8::Isolate* isolate,
                    WebContents* web_contents) {
  std::unique_ptr<base::DictionaryValue> value(
      extensions::TabHelper::CreateTabValue(web_contents->web_contents()));
  return mate::ConvertToV8(isolate, *value);
}

// static
bool Extension::HandleURLOverride(GURL* url,
        content::BrowserContext* browser_context) {
  return false;
}

bool Extension::HandleURLOverrideReverse(GURL* url,
          content::BrowserContext* browser_context) {
  return false;
}

// static
mate::Handle<Extension> Extension::Create(
    v8::Isolate* isolate,
    content::BrowserContext* browser_context) {
  auto original_context = extensions::ExtensionsBrowserClient::Get()->
        GetOriginalContext(browser_context);
  return mate::CreateHandle(isolate,
      new Extension(isolate,
          static_cast<AtomBrowserContext*>(original_context)));
}

// static
void Extension::BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype) {
  prototype->SetClassName(mate::StringToV8(isolate, "Extension"));
  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
    .SetMethod("load", &Extension::Load)
    .SetMethod("enable", &Extension::Enable)
    .SetMethod("disable", &Extension::Disable);
}

}  // namespace api

}  // namespace atom

namespace {

void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
                v8::Local<v8::Context> context, void* priv) {
  v8::Isolate* isolate = context->GetIsolate();
  mate::Dictionary dict(isolate, exports);
  dict.SetMethod("tabValue", &atom::api::Extension::TabValue);
  dict.SetMethod("isBackgroundPage", &atom::api::Extension::IsBackgroundPage);
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_extension, Initialize)
<commit_msg>don’t emit if the node env doesn’t exist possible fix for https://stats.brave.com/dashboard#crash/589f7a587978680011f790c6 auditors @bbondy @darkdh<commit_after>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_extension.h"

#include <memory>
#include <string>
#include <vector>

#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/extensions/atom_extension_system.h"
#include "atom/browser/extensions/tab_helper.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "components/prefs/pref_service.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/one_shot_event.h"
#include "native_mate/converter.h"
#include "native_mate/dictionary.h"

namespace mate {

template<>
struct Converter<extensions::Manifest::Location> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     extensions::Manifest::Location* out) {
    std::string type;
    if (!ConvertFromV8(isolate, val, &type))
      return false;

    if (type == "internal")
      *out = extensions::Manifest::Location::INTERNAL;
    else if (type == "external_pref")
      *out = extensions::Manifest::Location::EXTERNAL_PREF;
    else if (type == "external_registry")
      *out = extensions::Manifest::Location::EXTERNAL_REGISTRY;
    else if (type == "unpacked")
      *out = extensions::Manifest::Location::UNPACKED;
    else if (type == "component")
      *out = extensions::Manifest::Location::COMPONENT;
    else if (type == "external_pref_download")
      *out = extensions::Manifest::Location::EXTERNAL_PREF_DOWNLOAD;
    else if (type == "external_policy_download")
      *out = extensions::Manifest::Location::EXTERNAL_POLICY_DOWNLOAD;
    else if (type == "command_line")
      *out = extensions::Manifest::Location::COMMAND_LINE;
    else if (type == "external_policy")
      *out = extensions::Manifest::Location::EXTERNAL_POLICY;
    else if (type == "external_component")
      *out = extensions::Manifest::Location::EXTERNAL_COMPONENT;
    else
      *out = extensions::Manifest::Location::INVALID_LOCATION;
    return true;
  }
};

}  // namespace mate

namespace {

scoped_refptr<extensions::Extension> LoadExtension(const base::FilePath& path,
    const base::DictionaryValue& manifest,
    const extensions::Manifest::Location& manifest_location,
    int flags,
    std::string* error) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);

  scoped_refptr<extensions::Extension> extension(extensions::Extension::Create(
      path, manifest_location, manifest, flags, error));
  if (!extension.get())
    return NULL;

  std::vector<extensions::InstallWarning> warnings;
  if (!extensions::file_util::ValidateExtension(extension.get(),
                                                error,
                                                &warnings))
    return NULL;
  extension->AddInstallWarnings(warnings);

  return extension;
}

}  // namespace

namespace atom {

namespace api {

Extension::Extension(v8::Isolate* isolate,
                 AtomBrowserContext* browser_context)
    : browser_context_(browser_context) {
  Init(isolate);
  extensions::ExtensionRegistry::Get(browser_context_.get())->AddObserver(this);
}

Extension::~Extension() {
  if (extensions::ExtensionRegistry::Get(browser_context_.get())) {
    extensions::ExtensionRegistry::Get(browser_context_.get())->
        RemoveObserver(this);
  }
}

void Extension::LoadOnFILEThread(const base::FilePath path,
    std::unique_ptr<base::DictionaryValue> manifest,
    extensions::Manifest::Location manifest_location,
    int flags) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);

  std::string error;
  if (manifest->empty()) {
    manifest = extensions::file_util::LoadManifest(path, &error);
  }

  if (!manifest || !error.empty()) {
    content::BrowserThread::PostTask(
          content::BrowserThread::UI, FROM_HERE,
          base::Bind(&Extension::NotifyErrorOnUIThread,
              base::Unretained(this), error));
  } else {
    scoped_refptr<extensions::Extension> extension = LoadExtension(path,
                              *manifest,
                              manifest_location,
                              flags,
                              &error);

    if (!extension || !error.empty()) {
      content::BrowserThread::PostTask(
          content::BrowserThread::FILE, FROM_HERE,
          base::Bind(&Extension::NotifyErrorOnUIThread,
              base::Unretained(this), error));
    } else {
      content::BrowserThread::PostTask(
          content::BrowserThread::UI, FROM_HERE,
          base::Bind(&Extension::NotifyLoadOnUIThread,
              base::Unretained(this), base::Passed(&extension)));
    }
  }
}

void Extension::NotifyLoadOnUIThread(
    scoped_refptr<extensions::Extension> extension) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  extensions::ExtensionSystem::Get(browser_context_.get())->ready().Post(
        FROM_HERE,
        base::Bind(&Extension::AddExtension,
          // GetWeakPtr()
          base::Unretained(this), base::Passed(&extension)));
}

void Extension::NotifyErrorOnUIThread(const std::string& error) {
  node::Environment* env = node::Environment::GetCurrent(isolate());
  if (!env)
    return;

  mate::EmitEvent(isolate(),
                env->process_object(),
                "extension-load-error",
                error);
}

void Extension::Load(mate::Arguments* args) {
  base::FilePath path;
  args->GetNext(&path);

  base::DictionaryValue manifest;
  args->GetNext(&manifest);

  extensions::Manifest::Location manifest_location =
      extensions::Manifest::Location::UNPACKED;
  args->GetNext(&manifest_location);

  int flags = 0;
  args->GetNext(&flags);

  std::unique_ptr<base::DictionaryValue> manifest_copy =
      manifest.CreateDeepCopy();

  content::BrowserThread::PostTask(
        content::BrowserThread::FILE, FROM_HERE,
        base::Bind(&Extension::LoadOnFILEThread,
            base::Unretained(this),
            path, Passed(&manifest_copy), manifest_location, flags));
}

void Extension::AddExtension(scoped_refptr<extensions::Extension> extension) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  extension_service->AddExtension(extension.get());
}

void Extension::OnExtensionReady(content::BrowserContext* browser_context,
                                const extensions::Extension* extension) {
  mate::Dictionary install_info = mate::Dictionary::CreateEmpty(isolate());
  install_info.Set("name", extension->non_localized_name());
  install_info.Set("id", extension->id());
  install_info.Set("url", extension->url().spec());
  install_info.Set("base_path", extension->path().value());
  install_info.Set("version", extension->VersionString());
  install_info.Set("description", extension->description());
  auto manifest = extension->manifest()->value()->CreateDeepCopy();
  install_info.Set("manifest", mate::ConvertToV8(isolate(), *manifest));
  node::Environment* env = node::Environment::GetCurrent(isolate());
  if (!env)
    return;

  mate::EmitEvent(isolate(),
                  env->process_object(),
                  "EXTENSION_READY_INTERNAL",
                  install_info);
}

void Extension::OnExtensionUnloaded(content::BrowserContext* browser_context,
                            const extensions::Extension* extension,
                            extensions::UnloadedExtensionInfo::Reason reason) {
  node::Environment* env = node::Environment::GetCurrent(isolate());
  if (!env)
    return;

  mate::EmitEvent(isolate(),
                  env->process_object(),
                  "extension-unloaded",
                  extension->id());
}

void Extension::Disable(const std::string& extension_id) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  if (extension_service) {
    extension_service->DisableExtension(
        extension_id, extensions::Extension::DISABLE_USER_ACTION);
  }
}

void Extension::Enable(const std::string& extension_id) {
  auto extension_service =
      extensions::ExtensionSystem::Get(browser_context_.get())->
          extension_service();
  if (extension_service) {
    extension_service->EnableExtension(
        extension_id);
  }
}

// static
bool Extension::IsBackgroundPageUrl(GURL url,
                    content::BrowserContext* browser_context) {
  if (url.scheme() != "chrome-extension")
    return false;

  if (extensions::ExtensionSystem::Get(browser_context)
      ->ready().is_signaled()) {
    const extensions::Extension* extension =
        extensions::ExtensionRegistry::Get(browser_context)->
            enabled_extensions().GetExtensionOrAppByURL(url);
    if (extension &&
        url == extensions::BackgroundInfo::GetBackgroundURL(extension))
      return true;
  }

  return false;
}

// static
bool Extension::IsBackgroundPageWebContents(
    content::WebContents* web_contents) {
  auto browser_context = web_contents->GetBrowserContext();
  auto url = web_contents->GetURL();

  return IsBackgroundPageUrl(url, browser_context);
}

// static
bool Extension::IsBackgroundPage(const WebContents* web_contents) {
  return IsBackgroundPageWebContents(web_contents->web_contents());
}

// static
v8::Local<v8::Value> Extension::TabValue(v8::Isolate* isolate,
                    WebContents* web_contents) {
  std::unique_ptr<base::DictionaryValue> value(
      extensions::TabHelper::CreateTabValue(web_contents->web_contents()));
  return mate::ConvertToV8(isolate, *value);
}

// static
bool Extension::HandleURLOverride(GURL* url,
        content::BrowserContext* browser_context) {
  return false;
}

bool Extension::HandleURLOverrideReverse(GURL* url,
          content::BrowserContext* browser_context) {
  return false;
}

// static
mate::Handle<Extension> Extension::Create(
    v8::Isolate* isolate,
    content::BrowserContext* browser_context) {
  auto original_context = extensions::ExtensionsBrowserClient::Get()->
        GetOriginalContext(browser_context);
  return mate::CreateHandle(isolate,
      new Extension(isolate,
          static_cast<AtomBrowserContext*>(original_context)));
}

// static
void Extension::BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype) {
  prototype->SetClassName(mate::StringToV8(isolate, "Extension"));
  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
    .SetMethod("load", &Extension::Load)
    .SetMethod("enable", &Extension::Enable)
    .SetMethod("disable", &Extension::Disable);
}

}  // namespace api

}  // namespace atom

namespace {

void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
                v8::Local<v8::Context> context, void* priv) {
  v8::Isolate* isolate = context->GetIsolate();
  mate::Dictionary dict(isolate, exports);
  dict.SetMethod("tabValue", &atom::api::Extension::TabValue);
  dict.SetMethod("isBackgroundPage", &atom::api::Extension::IsBackgroundPage);
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_extension, Initialize)
<|endoftext|>


<commit_before>#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include "mue_algorithm.h"
#include "teams.h"
#include "distances.h"
#include "firstround_select.h"

#include <vector>

BOOST_PYTHON_MODULE (_pymue)
{
	using namespace boost::python;

	class_<mue::Distance_matrix>("DistanceMatrix", init<unsigned int>())
		.def("set_cost", &mue::Distance_matrix::set_cost)
		.def("min_cost", &mue::Distance_matrix::min_cost)
		.def("lookup", &mue::Distance_matrix::lookup);

	class_<mue::Firstround_team_selection>("FirstroundSelection", init<mue::Distance_matrix, unsigned int>());

	class_<std::vector<mue::Team_id> >("TeamVector")
		.def(vector_indexing_suite<std::vector<mue::Team_id> >());

	class_<mue::Calculation>("Calculation", init<unsigned int, mue::Distance_matrix, mue::Distance>())
		.def("calculate_distribution", &mue::Calculation::calculate_distribution)
		.def("solutions", &mue::Calculation::solutions)
		.def("round_stations", &mue::Calculation::round_stations);

	enum_<mue::Calculation::Round>("Round")
		.value("FIRST", mue::Calculation::FIRST)
		.value("SECOND", mue::Calculation::SECOND)
		.value("THIRD", mue::Calculation::THIRD);
}
<commit_msg>Wrap the calculation in a Gil-Release-function<commit_after>#include <vector>

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include "mue_algorithm.h"
#include "teams.h"
#include "distances.h"
#include "firstround_select.h"

#include "scoped_gil.h"

namespace pymue {
	void calculate_without_gil(mue::Calculation &calculation)
	{
		ScopedGILRelease gilRelease;
		calculation.calculate_distribution();
	}
}

BOOST_PYTHON_MODULE (_pymue)
{
	using namespace boost::python;

	class_<mue::Distance_matrix>("DistanceMatrix", init<unsigned int>())
		.def("set_cost", &mue::Distance_matrix::set_cost)
		.def("min_cost", &mue::Distance_matrix::min_cost)
		.def("lookup", &mue::Distance_matrix::lookup);

	class_<mue::Firstround_team_selection>("FirstroundSelection", init<mue::Distance_matrix, unsigned int>());

	class_<std::vector<mue::Team_id> >("TeamVector")
		.def(vector_indexing_suite<std::vector<mue::Team_id> >());

	class_<mue::Calculation>("Calculation", init<unsigned int, mue::Distance_matrix, mue::Distance>())
		.def("calculate_distribution", &mue::Calculation::calculate_distribution)
		.def("solutions", &mue::Calculation::solutions)
		.def("round_stations", &mue::Calculation::round_stations);

	enum_<mue::Calculation::Round>("Round")
		.value("FIRST", mue::Calculation::FIRST)
		.value("SECOND", mue::Calculation::SECOND)
		.value("THIRD", mue::Calculation::THIRD);

	def("calculate", pymue::calculate_without_gil);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/window_sizer.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "gfx/codec/png_codec.h"
#include "net/test/test_server.h"
#include "ui/base/clipboard/clipboard.h"

extern base::hash_map<std::string, int> g_test_timeout_overrides;

namespace {

// Include things like browser frame and scrollbar and make sure we're bigger
// than the test pdf document.
static const int kBrowserWidth = 1000;
static const int kBrowserHeight = 600;
static const int kLoadingTestTimeoutMs = 60000;

// The loading test is really a collection of tests, each one being a different
// PDF file.  But it would be busy work to add a different test for each file.
// Since we run them all in one test, we want a bigger timeout.
class IncreaseLoadingTimeout {
 public:
  IncreaseLoadingTimeout() {
    g_test_timeout_overrides["PDFBrowserTest.Loading"] = kLoadingTestTimeoutMs;
  }
};

IncreaseLoadingTimeout g_increase_loading_timeout;

class PDFBrowserTest : public InProcessBrowserTest,
                       public NotificationObserver {
 public:
  PDFBrowserTest()
      : snapshot_different_(true),
        next_dummy_search_value_(0),
        load_stop_notification_count_(0) {
    EnableDOMAutomation();

    pdf_test_server_.reset(new net::TestServer(
        net::TestServer::TYPE_HTTP,
        FilePath(FILE_PATH_LITERAL("pdf/test"))));
  }

 protected:
  // Use our own TestServer so that we can serve files from the pdf directory.
  net::TestServer* pdf_test_server() { return pdf_test_server_.get(); }

  int load_stop_notification_count() const {
    return load_stop_notification_count_;
  }

  FilePath GetPDFTestDir() {
    return FilePath(FilePath::kCurrentDirectory).AppendASCII("..").
        AppendASCII("..").AppendASCII("..").AppendASCII("pdf").
        AppendASCII("test");
  }

  void Load() {
    GURL url(ui_test_utils::GetTestUrl(
        GetPDFTestDir(),
        FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf"))));
    ui_test_utils::NavigateToURL(browser(), url);
    gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight));

    scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info(
        WindowSizer::CreateDefaultMonitorInfoProvider());
    gfx::Rect screen_bounds = monitor_info->GetPrimaryMonitorBounds();
    ASSERT_GT(screen_bounds.width(), kBrowserWidth);
    ASSERT_GT(screen_bounds.height(), kBrowserHeight);

    browser()->window()->SetBounds(bounds);
  }

  void VerifySnapshot(const std::string& expected_filename) {
    snapshot_different_ = true;
    expected_filename_ = expected_filename;
    RenderViewHost* host =
        browser()->GetSelectedTabContents()->render_view_host();

    host->CaptureSnapshot();
    ui_test_utils::RegisterAndWait(this,
                                   NotificationType::TAB_SNAPSHOT_TAKEN,
                                   Source<RenderViewHost>(host));
    ASSERT_FALSE(snapshot_different_) << "Rendering didn't match, see result "
        "at " << snapshot_filename_.value().c_str();
  }

  void WaitForResponse() {
    // Even if the plugin has loaded the data or scrolled, because of how
    // pepper painting works, we might not have the data.  One way to force this
    // to be flushed is to do a find operation, since on this two-page test
    // document, it'll wait for us to flush the renderer message loop twice and
    // also the browser's once, at which point we're guaranteed to have updated
    // the backingstore.  Hacky, but it works.
    // Note that we need to change the text each time, because if we don't the
    // renderer code will think the second message is to go to next result, but
    // there are none so the plugin will assert.

    string16 query = UTF8ToUTF16(
        std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++)));
    ASSERT_EQ(0, ui_test_utils::FindInPage(
        browser()->GetSelectedTabContents(), query, true, false, NULL));
  }

 private:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kForceInternalPDFPlugin);
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    if (type == NotificationType::TAB_SNAPSHOT_TAKEN) {
      MessageLoopForUI::current()->Quit();
      FilePath reference = ui_test_utils::GetTestFilePath(
          GetPDFTestDir(),
          FilePath().AppendASCII(expected_filename_));
      base::PlatformFileInfo info;
      ASSERT_TRUE(file_util::GetFileInfo(reference, &info));
      int size = static_cast<size_t>(info.size);
      scoped_array<char> data(new char[size]);
      ASSERT_EQ(size, file_util::ReadFile(reference, data.get(), size));

      int w, h;
      std::vector<unsigned char> decoded;
      ASSERT_TRUE(gfx::PNGCodec::Decode(
          reinterpret_cast<unsigned char*>(data.get()), size,
          gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h));
      int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]);

      const SkBitmap* bitmap = Details<const SkBitmap>(details).ptr();
      int32* pixels = static_cast<int32*>(bitmap->getPixels());

      // Get the background color, and use it to figure out the x-offsets in
      // each image.  The reason is that depending on the theme in the OS, the
      // same browser width can lead to slightly different plugin sizes, so the
      // pdf content will start at different x offsets.
      // Also note that the images we saved are cut off before the scrollbar, as
      // that'll change depending on the theme, and also cut off vertically so
      // that the ui controls don't show up, as those fade-in and so the timing
      // will affect their transparency.
      int32 bg_color = ref_pixels[0];
      int ref_x_offset, snapshot_x_offset;
      for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) {
        if (ref_pixels[ref_x_offset] != bg_color)
          break;
      }

      for (snapshot_x_offset = 0; snapshot_x_offset < bitmap->width();
           ++snapshot_x_offset) {
        if (pixels[snapshot_x_offset] != bg_color)
          break;
      }

      int x_max = std::min(
          w - ref_x_offset, bitmap->width() - snapshot_x_offset);
      int y_max = std::min(h, bitmap->height());
      int stride = bitmap->rowBytes();
      snapshot_different_ = false;
      for (int y = 0; y < y_max && !snapshot_different_; ++y) {
        for (int x = 0; x < x_max && !snapshot_different_; ++x) {
          if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] !=
              ref_pixels[y * w + x + ref_x_offset])
            snapshot_different_ = true;
        }
      }

      if (snapshot_different_) {
        std::vector<unsigned char> png_data;
        gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data);
        if (file_util::CreateTemporaryFile(&snapshot_filename_)) {
          file_util::WriteFile(snapshot_filename_,
              reinterpret_cast<char*>(&png_data[0]), png_data.size());
        }
      }
    } else if (type == NotificationType::LOAD_STOP) {
      load_stop_notification_count_++;
    }
  }

  // True if the snapshot differed from the expected value.
  bool snapshot_different_;
  // Internal variable used to synchronize to the renderer.
  int next_dummy_search_value_;
  // The filename of the bitmap to compare the snapshot to.
  std::string expected_filename_;
  // If the snapshot is different, holds the location where it's saved.
  FilePath snapshot_filename_;
  // How many times we've seen NotificationType::LOAD_STOP.
  int load_stop_notification_count_;

  scoped_ptr<net::TestServer> pdf_test_server_;
};

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_Basic FLAKY_Basic
#else
#define MAYBE_Basic Basic
#endif

// Tests basic PDF rendering.  This can be broken depending on bad merges with
// the vendor, so it's important that we have basic sanity checking.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Basic) {

  ASSERT_NO_FATAL_FAILURE(Load());
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());
  ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest.png"));
}

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_Scroll FLAKY_Scroll
#else
#define MAYBE_Scroll Scroll
#endif

// Tests that scrolling works.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Scroll) {
  ASSERT_NO_FATAL_FAILURE(Load());

  // We use wheel mouse event since that's the only one we can easily push to
  // the renderer.  There's no way to push a cross-platform keyboard event at
  // the moment.
  WebKit::WebMouseWheelEvent wheel_event;
  wheel_event.type = WebKit::WebInputEvent::MouseWheel;
  wheel_event.deltaY = -200;
  wheel_event.wheelTicksY = -2;
  TabContents* tab_contents = browser()->GetSelectedTabContents();
  tab_contents->render_view_host()->ForwardWheelEvent(wheel_event);
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());
  ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest_scroll.png"));
}

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_FindAndCopy FLAKY_FindAndCopy
#else
#define MAYBE_FindAndCopy FindAndCopy
#endif

IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_FindAndCopy) {
  ASSERT_NO_FATAL_FAILURE(Load());
  // Verifies that find in page works.
  ASSERT_EQ(3, ui_test_utils::FindInPage(
      browser()->GetSelectedTabContents(), UTF8ToUTF16("adipiscing"), true,
      false, NULL));

  // Verify that copying selected text works.
  ui::Clipboard clipboard;
  // Reset the clipboard first.
  ui::Clipboard::ObjectMap objects;
  ui::Clipboard::ObjectMapParams params;
  params.push_back(std::vector<char>());
  objects[Clipboard::CBF_TEXT] = params;
  clipboard.WriteObjects(objects);

  browser()->GetSelectedTabContents()->render_view_host()->Copy();
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());

  std::string text;
  clipboard.ReadAsciiText(ui::Clipboard::BUFFER_STANDARD, &text);
  ASSERT_EQ("adipiscing", text);
}

// Tests that loading async pdfs works correctly (i.e. document fully loads).
// This also loads all documents that used to crash, to ensure we don't have
// regressions.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Loading) {
  ASSERT_TRUE(pdf_test_server()->Start());

  NavigationController* controller =
      &(browser()->GetSelectedTabContents()->controller());
  NotificationRegistrar registrar;
  registrar.Add(this,
                NotificationType::LOAD_STOP,
                Source<NavigationController>(controller));
  std::string base_url = std::string("files/");

  file_util::FileEnumerator file_enumerator(
      ui_test_utils::GetTestFilePath(GetPDFTestDir(), FilePath()),
      false,
      file_util::FileEnumerator::FILES,
      FILE_PATH_LITERAL("*.pdf"));
  for (FilePath file_path = file_enumerator.Next();
       !file_path.empty();
       file_path = file_enumerator.Next()) {
    std::string filename = WideToASCII(file_path.BaseName().ToWStringHack());

#if defined(OS_MACOSX) || defined(OS_LINUX)
    if (filename == "sample.pdf")
      continue;  // Crashes on Mac and Linux.  http://crbug.com/63549
#endif

    LOG(WARNING) << "PDFBrowserTest.Loading: " << filename;

    GURL url = pdf_test_server()->GetURL(base_url + filename);
    ui_test_utils::NavigateToURL(browser(), url);

    while (true) {
      int last_count = load_stop_notification_count();
      // We might get extraneous NotificationType::LOAD_STOP notifications when
      // doing async loading.  This happens when the first loader is cancelled
      // and before creating a byte-range request loader.
      bool complete = false;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
          browser()->GetSelectedTabContents()->render_view_host(),
          std::wstring(),
          L"window.domAutomationController.send(plugin.documentLoadComplete())",
          &complete));
      if (complete)
        break;

      // Check if the LOAD_STOP notification could have come while we run a
      // nested message loop for the JS call.
      if (last_count != load_stop_notification_count())
        continue;
      ui_test_utils::WaitForLoadStop(controller);
    }
  }
}

}  // namespace
<commit_msg>Fix build break.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/window_sizer.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "gfx/codec/png_codec.h"
#include "net/test/test_server.h"
#include "ui/base/clipboard/clipboard.h"

extern base::hash_map<std::string, int> g_test_timeout_overrides;

namespace {

// Include things like browser frame and scrollbar and make sure we're bigger
// than the test pdf document.
static const int kBrowserWidth = 1000;
static const int kBrowserHeight = 600;
static const int kLoadingTestTimeoutMs = 60000;

// The loading test is really a collection of tests, each one being a different
// PDF file.  But it would be busy work to add a different test for each file.
// Since we run them all in one test, we want a bigger timeout.
class IncreaseLoadingTimeout {
 public:
  IncreaseLoadingTimeout() {
    g_test_timeout_overrides["PDFBrowserTest.Loading"] = kLoadingTestTimeoutMs;
  }
};

IncreaseLoadingTimeout g_increase_loading_timeout;

class PDFBrowserTest : public InProcessBrowserTest,
                       public NotificationObserver {
 public:
  PDFBrowserTest()
      : snapshot_different_(true),
        next_dummy_search_value_(0),
        load_stop_notification_count_(0) {
    EnableDOMAutomation();

    pdf_test_server_.reset(new net::TestServer(
        net::TestServer::TYPE_HTTP,
        FilePath(FILE_PATH_LITERAL("pdf/test"))));
  }

 protected:
  // Use our own TestServer so that we can serve files from the pdf directory.
  net::TestServer* pdf_test_server() { return pdf_test_server_.get(); }

  int load_stop_notification_count() const {
    return load_stop_notification_count_;
  }

  FilePath GetPDFTestDir() {
    return FilePath(FilePath::kCurrentDirectory).AppendASCII("..").
        AppendASCII("..").AppendASCII("..").AppendASCII("pdf").
        AppendASCII("test");
  }

  void Load() {
    GURL url(ui_test_utils::GetTestUrl(
        GetPDFTestDir(),
        FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf"))));
    ui_test_utils::NavigateToURL(browser(), url);
    gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight));

    scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info(
        WindowSizer::CreateDefaultMonitorInfoProvider());
    gfx::Rect screen_bounds = monitor_info->GetPrimaryMonitorBounds();
    ASSERT_GT(screen_bounds.width(), kBrowserWidth);
    ASSERT_GT(screen_bounds.height(), kBrowserHeight);

    browser()->window()->SetBounds(bounds);
  }

  void VerifySnapshot(const std::string& expected_filename) {
    snapshot_different_ = true;
    expected_filename_ = expected_filename;
    RenderViewHost* host =
        browser()->GetSelectedTabContents()->render_view_host();

    host->CaptureSnapshot();
    ui_test_utils::RegisterAndWait(this,
                                   NotificationType::TAB_SNAPSHOT_TAKEN,
                                   Source<RenderViewHost>(host));
    ASSERT_FALSE(snapshot_different_) << "Rendering didn't match, see result "
        "at " << snapshot_filename_.value().c_str();
  }

  void WaitForResponse() {
    // Even if the plugin has loaded the data or scrolled, because of how
    // pepper painting works, we might not have the data.  One way to force this
    // to be flushed is to do a find operation, since on this two-page test
    // document, it'll wait for us to flush the renderer message loop twice and
    // also the browser's once, at which point we're guaranteed to have updated
    // the backingstore.  Hacky, but it works.
    // Note that we need to change the text each time, because if we don't the
    // renderer code will think the second message is to go to next result, but
    // there are none so the plugin will assert.

    string16 query = UTF8ToUTF16(
        std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++)));
    ASSERT_EQ(0, ui_test_utils::FindInPage(
        browser()->GetSelectedTabContents(), query, true, false, NULL));
  }

 private:
  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kForceInternalPDFPlugin);
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    if (type == NotificationType::TAB_SNAPSHOT_TAKEN) {
      MessageLoopForUI::current()->Quit();
      FilePath reference = ui_test_utils::GetTestFilePath(
          GetPDFTestDir(),
          FilePath().AppendASCII(expected_filename_));
      base::PlatformFileInfo info;
      ASSERT_TRUE(file_util::GetFileInfo(reference, &info));
      int size = static_cast<size_t>(info.size);
      scoped_array<char> data(new char[size]);
      ASSERT_EQ(size, file_util::ReadFile(reference, data.get(), size));

      int w, h;
      std::vector<unsigned char> decoded;
      ASSERT_TRUE(gfx::PNGCodec::Decode(
          reinterpret_cast<unsigned char*>(data.get()), size,
          gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h));
      int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]);

      const SkBitmap* bitmap = Details<const SkBitmap>(details).ptr();
      int32* pixels = static_cast<int32*>(bitmap->getPixels());

      // Get the background color, and use it to figure out the x-offsets in
      // each image.  The reason is that depending on the theme in the OS, the
      // same browser width can lead to slightly different plugin sizes, so the
      // pdf content will start at different x offsets.
      // Also note that the images we saved are cut off before the scrollbar, as
      // that'll change depending on the theme, and also cut off vertically so
      // that the ui controls don't show up, as those fade-in and so the timing
      // will affect their transparency.
      int32 bg_color = ref_pixels[0];
      int ref_x_offset, snapshot_x_offset;
      for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) {
        if (ref_pixels[ref_x_offset] != bg_color)
          break;
      }

      for (snapshot_x_offset = 0; snapshot_x_offset < bitmap->width();
           ++snapshot_x_offset) {
        if (pixels[snapshot_x_offset] != bg_color)
          break;
      }

      int x_max = std::min(
          w - ref_x_offset, bitmap->width() - snapshot_x_offset);
      int y_max = std::min(h, bitmap->height());
      int stride = bitmap->rowBytes();
      snapshot_different_ = false;
      for (int y = 0; y < y_max && !snapshot_different_; ++y) {
        for (int x = 0; x < x_max && !snapshot_different_; ++x) {
          if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] !=
              ref_pixels[y * w + x + ref_x_offset])
            snapshot_different_ = true;
        }
      }

      if (snapshot_different_) {
        std::vector<unsigned char> png_data;
        gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data);
        if (file_util::CreateTemporaryFile(&snapshot_filename_)) {
          file_util::WriteFile(snapshot_filename_,
              reinterpret_cast<char*>(&png_data[0]), png_data.size());
        }
      }
    } else if (type == NotificationType::LOAD_STOP) {
      load_stop_notification_count_++;
    }
  }

  // True if the snapshot differed from the expected value.
  bool snapshot_different_;
  // Internal variable used to synchronize to the renderer.
  int next_dummy_search_value_;
  // The filename of the bitmap to compare the snapshot to.
  std::string expected_filename_;
  // If the snapshot is different, holds the location where it's saved.
  FilePath snapshot_filename_;
  // How many times we've seen NotificationType::LOAD_STOP.
  int load_stop_notification_count_;

  scoped_ptr<net::TestServer> pdf_test_server_;
};

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_Basic FLAKY_Basic
#else
#define MAYBE_Basic Basic
#endif

// Tests basic PDF rendering.  This can be broken depending on bad merges with
// the vendor, so it's important that we have basic sanity checking.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Basic) {

  ASSERT_NO_FATAL_FAILURE(Load());
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());
  ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest.png"));
}

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_Scroll FLAKY_Scroll
#else
#define MAYBE_Scroll Scroll
#endif

// Tests that scrolling works.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Scroll) {
  ASSERT_NO_FATAL_FAILURE(Load());

  // We use wheel mouse event since that's the only one we can easily push to
  // the renderer.  There's no way to push a cross-platform keyboard event at
  // the moment.
  WebKit::WebMouseWheelEvent wheel_event;
  wheel_event.type = WebKit::WebInputEvent::MouseWheel;
  wheel_event.deltaY = -200;
  wheel_event.wheelTicksY = -2;
  TabContents* tab_contents = browser()->GetSelectedTabContents();
  tab_contents->render_view_host()->ForwardWheelEvent(wheel_event);
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());
  ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest_scroll.png"));
}

#if defined(OS_MACOSX)
// See http://crbug.com/63223
#define MAYBE_FindAndCopy FLAKY_FindAndCopy
#else
#define MAYBE_FindAndCopy FindAndCopy
#endif

IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_FindAndCopy) {
  ASSERT_NO_FATAL_FAILURE(Load());
  // Verifies that find in page works.
  ASSERT_EQ(3, ui_test_utils::FindInPage(
      browser()->GetSelectedTabContents(), UTF8ToUTF16("adipiscing"), true,
      false, NULL));

  // Verify that copying selected text works.
  ui::Clipboard clipboard;
  // Reset the clipboard first.
  ui::Clipboard::ObjectMap objects;
  ui::Clipboard::ObjectMapParams params;
  params.push_back(std::vector<char>());
  objects[ui::Clipboard::CBF_TEXT] = params;
  clipboard.WriteObjects(objects);

  browser()->GetSelectedTabContents()->render_view_host()->Copy();
  ASSERT_NO_FATAL_FAILURE(WaitForResponse());

  std::string text;
  clipboard.ReadAsciiText(ui::Clipboard::BUFFER_STANDARD, &text);
  ASSERT_EQ("adipiscing", text);
}

// Tests that loading async pdfs works correctly (i.e. document fully loads).
// This also loads all documents that used to crash, to ensure we don't have
// regressions.
IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Loading) {
  ASSERT_TRUE(pdf_test_server()->Start());

  NavigationController* controller =
      &(browser()->GetSelectedTabContents()->controller());
  NotificationRegistrar registrar;
  registrar.Add(this,
                NotificationType::LOAD_STOP,
                Source<NavigationController>(controller));
  std::string base_url = std::string("files/");

  file_util::FileEnumerator file_enumerator(
      ui_test_utils::GetTestFilePath(GetPDFTestDir(), FilePath()),
      false,
      file_util::FileEnumerator::FILES,
      FILE_PATH_LITERAL("*.pdf"));
  for (FilePath file_path = file_enumerator.Next();
       !file_path.empty();
       file_path = file_enumerator.Next()) {
    std::string filename = WideToASCII(file_path.BaseName().ToWStringHack());

#if defined(OS_MACOSX) || defined(OS_LINUX)
    if (filename == "sample.pdf")
      continue;  // Crashes on Mac and Linux.  http://crbug.com/63549
#endif

    LOG(WARNING) << "PDFBrowserTest.Loading: " << filename;

    GURL url = pdf_test_server()->GetURL(base_url + filename);
    ui_test_utils::NavigateToURL(browser(), url);

    while (true) {
      int last_count = load_stop_notification_count();
      // We might get extraneous NotificationType::LOAD_STOP notifications when
      // doing async loading.  This happens when the first loader is cancelled
      // and before creating a byte-range request loader.
      bool complete = false;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
          browser()->GetSelectedTabContents()->render_view_host(),
          std::wstring(),
          L"window.domAutomationController.send(plugin.documentLoadComplete())",
          &complete));
      if (complete)
        break;

      // Check if the LOAD_STOP notification could have come while we run a
      // nested message loop for the JS call.
      if (last_count != load_stop_notification_count())
        continue;
      ui_test_utils::WaitForLoadStop(controller);
    }
  }
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/javascript_environment.h"

#include <string>

#include "atom/browser/microtasks_runner.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/task/task_scheduler/initialization_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/common/content_switches.h"
#include "gin/array_buffer.h"
#include "gin/v8_initializer.h"

#include "atom/common/node_includes.h"
#include "tracing/trace_event.h"

namespace atom {

JavascriptEnvironment::JavascriptEnvironment(uv_loop_t* event_loop)
    : isolate_(Initialize(event_loop)),
      isolate_holder_(base::ThreadTaskRunnerHandle::Get(),
                      gin::IsolateHolder::kSingleThread,
                      gin::IsolateHolder::kAllowAtomicsWait,
                      gin::IsolateHolder::IsolateType::kUtility,
                      gin::IsolateHolder::IsolateCreationMode::kNormal,
                      isolate_),
      isolate_scope_(isolate_),
      locker_(isolate_),
      handle_scope_(isolate_),
      context_(isolate_, v8::Context::New(isolate_)),
      context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {}

JavascriptEnvironment::~JavascriptEnvironment() = default;

v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop) {
  auto* cmd = base::CommandLine::ForCurrentProcess();

  // --js-flags.
  std::string js_flags = cmd->GetSwitchValueASCII(switches::kJavaScriptFlags);
  if (!js_flags.empty())
    v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());

  // The V8Platform of gin relies on Chromium's task schedule, which has not
  // been started at this point, so we have to rely on Node's V8Platform.
  auto* tracing_agent = node::CreateAgent();
  auto* tracing_controller = tracing_agent->GetTracingController();
  node::tracing::TraceEventHelper::SetAgent(tracing_agent);
  platform_ = node::CreatePlatform(
      base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
      tracing_controller);

  v8::V8::InitializePlatform(platform_);
  gin::IsolateHolder::Initialize(
      gin::IsolateHolder::kNonStrictMode, gin::IsolateHolder::kStableV8Extras,
      gin::ArrayBufferAllocator::SharedInstance(),
      nullptr /* external_reference_table */, false /* create_v8_platform */);

  v8::Isolate* isolate = v8::Isolate::Allocate();
  platform_->RegisterIsolate(isolate, event_loop);

  return isolate;
}

void JavascriptEnvironment::OnMessageLoopCreated() {
  DCHECK(!microtasks_runner_);
  microtasks_runner_.reset(new MicrotasksRunner(isolate()));
  base::MessageLoopCurrent::Get()->AddTaskObserver(microtasks_runner_.get());
}

void JavascriptEnvironment::OnMessageLoopDestroying() {
  DCHECK(microtasks_runner_);
  base::MessageLoopCurrent::Get()->RemoveTaskObserver(microtasks_runner_.get());
  platform_->UnregisterIsolate(isolate_);
}

NodeEnvironment::NodeEnvironment(node::Environment* env) : env_(env) {}

NodeEnvironment::~NodeEnvironment() {
  node::FreeEnvironment(env_);
}

}  // namespace atom
<commit_msg>v8: Remove obsolete V8 extras flag<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/javascript_environment.h"

#include <string>

#include "atom/browser/microtasks_runner.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/task/task_scheduler/initialization_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/common/content_switches.h"
#include "gin/array_buffer.h"
#include "gin/v8_initializer.h"

#include "atom/common/node_includes.h"
#include "tracing/trace_event.h"

namespace atom {

JavascriptEnvironment::JavascriptEnvironment(uv_loop_t* event_loop)
    : isolate_(Initialize(event_loop)),
      isolate_holder_(base::ThreadTaskRunnerHandle::Get(),
                      gin::IsolateHolder::kSingleThread,
                      gin::IsolateHolder::kAllowAtomicsWait,
                      gin::IsolateHolder::IsolateType::kUtility,
                      gin::IsolateHolder::IsolateCreationMode::kNormal,
                      isolate_),
      isolate_scope_(isolate_),
      locker_(isolate_),
      handle_scope_(isolate_),
      context_(isolate_, v8::Context::New(isolate_)),
      context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {}

JavascriptEnvironment::~JavascriptEnvironment() = default;

v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop) {
  auto* cmd = base::CommandLine::ForCurrentProcess();

  // --js-flags.
  std::string js_flags = cmd->GetSwitchValueASCII(switches::kJavaScriptFlags);
  if (!js_flags.empty())
    v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());

  // The V8Platform of gin relies on Chromium's task schedule, which has not
  // been started at this point, so we have to rely on Node's V8Platform.
  auto* tracing_agent = node::CreateAgent();
  auto* tracing_controller = tracing_agent->GetTracingController();
  node::tracing::TraceEventHelper::SetAgent(tracing_agent);
  platform_ = node::CreatePlatform(
      base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
      tracing_controller);

  v8::V8::InitializePlatform(platform_);
  gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
                                 gin::ArrayBufferAllocator::SharedInstance(),
                                 nullptr /* external_reference_table */,
                                 false /* create_v8_platform */);

  v8::Isolate* isolate = v8::Isolate::Allocate();
  platform_->RegisterIsolate(isolate, event_loop);

  return isolate;
}

void JavascriptEnvironment::OnMessageLoopCreated() {
  DCHECK(!microtasks_runner_);
  microtasks_runner_.reset(new MicrotasksRunner(isolate()));
  base::MessageLoopCurrent::Get()->AddTaskObserver(microtasks_runner_.get());
}

void JavascriptEnvironment::OnMessageLoopDestroying() {
  DCHECK(microtasks_runner_);
  base::MessageLoopCurrent::Get()->RemoveTaskObserver(microtasks_runner_.get());
  platform_->UnregisterIsolate(isolate_);
}

NodeEnvironment::NodeEnvironment(node::Environment* env) : env_(env) {}

NodeEnvironment::~NodeEnvironment() {
  node::FreeEnvironment(env_);
}

}  // namespace atom
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>

#include <boost/filesystem.hpp>

#include <QPainter>
#include <QCache>

#include <tmx/TMX.h>
#include <tmx/TileLayer.h>
#include <tmx/ObjectLayer.h>

namespace fs = boost::filesystem;

class LayerRenderer : public tmx::LayerVisitor {
public:
  LayerRenderer()
  : map(nullptr), painter(), tilewidth(0), tileheight(0), width(0), height(0) { }

  void renderMap(const fs::path& map_path) {

    map = tmx::parseMapFile(map_path);

    if (!map) {
      return;
    }

    if (map->getOrientation() != tmx::Orientation::ORTHOGONAL) {
      std::printf("Can render only orthogonal maps. Exiting.\n");
      return;
    }

    tilewidth = map->getTileWidth();
    assert(tilewidth);

    tileheight = map->getTileHeight();
    assert(tileheight);

    width = map->getWidth();
    assert(width);

    height = map->getHeight();
    assert(height);

    // create surface

    QImage image(width * tilewidth, height * tileheight, QImage::Format_ARGB32);
    painter.begin(&image);
    map->visitLayers(*this);
    painter.end();

    std::printf("Saving image...\n");
    image.save("map.png");

    delete map;
  }

private:
  tmx::Map *map;

  QPainter painter;

  unsigned tilewidth;
  unsigned tileheight;
  unsigned width;
  unsigned height;

  QCache<QString, QImage> cache;

  const QImage getTexture(const fs::path& path) {
    QString str(path.string().c_str());
    QImage *img = cache.object(str);

    if (img != nullptr) {
      return *img;
    }

    img = new QImage(str);
    assert(!img->isNull());

    cache.insert(str, img);
    return *img;
  }

  enum class Alignment {
    TOP_LEFT,
    BOTTOM_LEFT,
  };

  void drawGID(const QPoint& origin, unsigned gid, Alignment align) {
    auto tileset = map->getTileSetFromGID(gid);
    assert(tileset);
    gid = gid - tileset->getFirstGID();

    if (tileset->hasImage()) {

      auto image = tileset->getImage();
      assert(image);

      const QImage texture = getTexture(image->getSource());

      tmx::Size size;

      if (image->hasSize()) {
        size = image->getSize();
      } else {
        QSize texture_size = texture.size();
        assert(texture_size.width() >= 0);
        assert(texture_size.height() >= 0);
        size.width = texture_size.width();
        size.height = texture_size.height();
      }

      tmx::Rect rect = tileset->getCoords(gid, size);
      QPoint offset;

      if (align == Alignment::BOTTOM_LEFT) {
        offset.ry() -= rect.height;
      }

      painter.drawImage(origin + offset, texture, QRect(rect.x, rect.y, rect.width, rect.height));

    } else {

      auto tile = tileset->getTile(gid);
      assert(tile);
      assert(tile->hasImage());

      auto image = tile->getImage();
      assert(image);

      const QImage texture = getTexture(image->getSource());
      painter.drawImage(origin, texture);

    }
  }

public:
  virtual void visitTileLayer(tmx::TileLayer& layer) {
    if (!layer.isVisible()) {
      return;
    }

    std::printf("Rendering tile layer '%s'.\n", layer.getName().c_str());

    unsigned k = 0;
    for (auto cell : layer) {
      unsigned i = k % width;
      unsigned j = k / width;
      assert(j < height);

      QPoint origin(i * tilewidth, j * tileheight);

      unsigned gid = cell.getGID();

      if (gid != 0) {
        drawGID(origin, gid, Alignment::TOP_LEFT);
      }

      k++;
    }

  }

  virtual void visitObjectLayer(tmx::ObjectLayer &layer) {
    if (!layer.isVisible()) {
      return;
    }

    std::printf("Rendering object layer '%s'.\n", layer.getName().c_str());

    for (auto obj : layer) {
      if (!obj->isTile()) {
        continue;
      }

      auto tile = static_cast<tmx::TileObject *>(obj);

      QPoint origin(tile->getX(), tile->getY());

      unsigned gid = tile->getGID();
      assert(gid != 0);

      drawGID(origin, gid, Alignment::BOTTOM_LEFT);
    }

  }

};

int main(int argc, char *argv[]) {
  if (argc != 2) {
    std::printf("Usage: tmx_render <file.tmx>\n");
    return 1;
  }

  fs::path map_path(argv[1]);

  LayerRenderer renderer;
  renderer.renderMap(map_path);

  return 0;
}
<commit_msg>add override where possible<commit_after>#include <cstdio>
#include <cstdlib>

#include <boost/filesystem.hpp>

#include <QPainter>
#include <QCache>

#include <tmx/TMX.h>
#include <tmx/TileLayer.h>
#include <tmx/ObjectLayer.h>

namespace fs = boost::filesystem;

class LayerRenderer : public tmx::LayerVisitor {
public:
  LayerRenderer()
  : map(nullptr), painter(), tilewidth(0), tileheight(0), width(0), height(0) { }

  void renderMap(const fs::path& map_path) {

    map = tmx::parseMapFile(map_path);

    if (!map) {
      return;
    }

    if (map->getOrientation() != tmx::Orientation::ORTHOGONAL) {
      std::printf("Can render only orthogonal maps. Exiting.\n");
      return;
    }

    tilewidth = map->getTileWidth();
    assert(tilewidth);

    tileheight = map->getTileHeight();
    assert(tileheight);

    width = map->getWidth();
    assert(width);

    height = map->getHeight();
    assert(height);

    // create surface

    QImage image(width * tilewidth, height * tileheight, QImage::Format_ARGB32);
    painter.begin(&image);
    map->visitLayers(*this);
    painter.end();

    std::printf("Saving image...\n");
    image.save("map.png");

    delete map;
  }

private:
  tmx::Map *map;

  QPainter painter;

  unsigned tilewidth;
  unsigned tileheight;
  unsigned width;
  unsigned height;

  QCache<QString, QImage> cache;

  const QImage getTexture(const fs::path& path) {
    QString str(path.string().c_str());
    QImage *img = cache.object(str);

    if (img != nullptr) {
      return *img;
    }

    img = new QImage(str);
    assert(!img->isNull());

    cache.insert(str, img);
    return *img;
  }

  enum class Alignment {
    TOP_LEFT,
    BOTTOM_LEFT,
  };

  void drawGID(const QPoint& origin, unsigned gid, Alignment align) {
    auto tileset = map->getTileSetFromGID(gid);
    assert(tileset);
    gid = gid - tileset->getFirstGID();

    if (tileset->hasImage()) {

      auto image = tileset->getImage();
      assert(image);

      const QImage texture = getTexture(image->getSource());

      tmx::Size size;

      if (image->hasSize()) {
        size = image->getSize();
      } else {
        QSize texture_size = texture.size();
        assert(texture_size.width() >= 0);
        assert(texture_size.height() >= 0);
        size.width = texture_size.width();
        size.height = texture_size.height();
      }

      tmx::Rect rect = tileset->getCoords(gid, size);
      QPoint offset;

      if (align == Alignment::BOTTOM_LEFT) {
        offset.ry() -= rect.height;
      }

      painter.drawImage(origin + offset, texture, QRect(rect.x, rect.y, rect.width, rect.height));

    } else {

      auto tile = tileset->getTile(gid);
      assert(tile);
      assert(tile->hasImage());

      auto image = tile->getImage();
      assert(image);

      const QImage texture = getTexture(image->getSource());
      painter.drawImage(origin, texture);

    }
  }

public:
  virtual void visitTileLayer(tmx::TileLayer& layer) override {
    if (!layer.isVisible()) {
      return;
    }

    std::printf("Rendering tile layer '%s'.\n", layer.getName().c_str());

    unsigned k = 0;
    for (auto cell : layer) {
      unsigned i = k % width;
      unsigned j = k / width;
      assert(j < height);

      QPoint origin(i * tilewidth, j * tileheight);

      unsigned gid = cell.getGID();

      if (gid != 0) {
        drawGID(origin, gid, Alignment::TOP_LEFT);
      }

      k++;
    }

  }

  virtual void visitObjectLayer(tmx::ObjectLayer &layer) override {
    if (!layer.isVisible()) {
      return;
    }

    std::printf("Rendering object layer '%s'.\n", layer.getName().c_str());

    for (auto obj : layer) {
      if (!obj->isTile()) {
        continue;
      }

      auto tile = static_cast<tmx::TileObject *>(obj);

      QPoint origin(tile->getX(), tile->getY());

      unsigned gid = tile->getGID();
      assert(gid != 0);

      drawGID(origin, gid, Alignment::BOTTOM_LEFT);
    }

  }

};

int main(int argc, char *argv[]) {
  if (argc != 2) {
    std::printf("Usage: tmx_render <file.tmx>\n");
    return 1;
  }

  fs::path map_path(argv[1]);

  LayerRenderer renderer;
  renderer.renderMap(map_path);

  return 0;
}
<|endoftext|>