<commit_before>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#include "sessiontabwidget.h"
#include "messageview.h"
#include "settings.h"
#include "session.h"
#include <irccommand.h>
#include <QtGui>

SessionTabWidget::SessionTabWidget(Session* session, QWidget* parent) :
    TabWidget(parent)
{
    d.handler.setSession(session);

    connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabActivated(int)));
    connect(this, SIGNAL(newTabRequested()), this, SLOT(onNewTabRequested()), Qt::QueuedConnection);
    connect(this, SIGNAL(tabMenuRequested(int,QPoint)), this, SLOT(onTabMenuRequested(int,QPoint)));

    connect(session, SIGNAL(activeChanged(bool)), this, SLOT(updateStatus()));
    connect(session, SIGNAL(connectedChanged(bool)), this, SLOT(updateStatus()));

    connect(&d.handler, SIGNAL(receiverToBeAdded(QString)), this, SLOT(openView(QString)));
    connect(&d.handler, SIGNAL(receiverToBeRemoved(QString)), this, SLOT(removeView(QString)));
    connect(&d.handler, SIGNAL(receiverToBeRenamed(QString,QString)), this, SLOT(renameView(QString,QString)));

    d.tabLeftShortcut = new QShortcut(this);
    connect(d.tabLeftShortcut, SIGNAL(activated()), this, SLOT(moveToPrevTab()));

    d.tabRightShortcut = new QShortcut(this);
    connect(d.tabRightShortcut, SIGNAL(activated()), this, SLOT(moveToNextTab()));

    QShortcut* shortcut = new QShortcut(QKeySequence::AddTab, this);
    connect(shortcut, SIGNAL(activated()), this, SLOT(onNewTabRequested()));

    shortcut = new QShortcut(QKeySequence::Close, this);
    connect(shortcut, SIGNAL(activated()), this, SLOT(closeCurrentView()));

    MessageView* view = openView(d.handler.session()->host());
    d.handler.setDefaultReceiver(view);
    updateStatus();

    applySettings(d.settings);
}

Session* SessionTabWidget::session() const
{
    return qobject_cast<Session*>(d.handler.session());
}

MessageView* SessionTabWidget::openView(const QString& receiver)
{
    MessageView* view = d.views.value(receiver.toLower());
    if (!view)
    {
        MessageView::ViewType type = MessageView::ServerView;
        if (!d.views.isEmpty())
            type = session()->isChannel(receiver) ? MessageView::ChannelView : MessageView::QueryView;
        view = new MessageView(type, d.handler.session(), this);
        view->setReceiver(receiver);
        connect(view, SIGNAL(alerted(IrcMessage*)), this, SLOT(onTabAlerted(IrcMessage*)));
        connect(view, SIGNAL(highlighted(IrcMessage*)), this, SLOT(onTabHighlighted(IrcMessage*)));
        connect(view, SIGNAL(queried(QString)), this, SLOT(openView(QString)));

        d.handler.addReceiver(receiver, view);
        d.views.insert(receiver.toLower(), view);
        addTab(view, QString(receiver).replace("&", "&&"));
    }
    setCurrentWidget(view);
    return view;
}

void SessionTabWidget::removeView(const QString& receiver)
{
    MessageView* view = d.views.take(receiver.toLower());
    if (view)
    {
        view->deleteLater();
        if (indexOf(view) == 0)
        {
            deleteLater();
            session()->destructLater();
        }
    }
}

void SessionTabWidget::closeCurrentView()
{
    closeView(currentIndex());
}

void SessionTabWidget::closeView(int index)
{
    MessageView* view = d.views.value(tabText(index).toLower());
    if (view)
    {
        QString reason = tr("%1 %2").arg(QApplication::applicationName())
                                    .arg(QApplication::applicationVersion());
        if (indexOf(view) == 0)
            session()->quit(reason);
        else if (view->viewType() == MessageView::ChannelView)
            d.handler.session()->sendCommand(IrcCommand::createPart(view->receiver(), reason));

        d.handler.removeReceiver(view->receiver());
    }
}

void SessionTabWidget::renameView(const QString& from, const QString& to)
{
    MessageView* view = d.views.take(from.toLower());
    if (view)
    {
        view->setReceiver(to);
        d.views.insert(to.toLower(), view);
        int index = indexOf(view);
        if (index != -1)
            setTabText(index, view->receiver());
    }
}

bool SessionTabWidget::event(QEvent* event)
{
    if (event->type() == QEvent::WindowActivate)
        delayedTabReset();
    return TabWidget::event(event);
}

void SessionTabWidget::updateStatus()
{
    bool inactive = !session()->isActive() && !session()->isConnected();
    setTabInactive(0, inactive);
    emit inactiveStatusChanged(inactive);
}

void SessionTabWidget::tabActivated(int index)
{
    if (index < count() - 1)
    {
        d.handler.setCurrentReceiver(qobject_cast<MessageView*>(currentWidget()));
        setTabAlert(index, false);
        setTabHighlight(index, false);
        if (isVisible())
        {
            window()->setWindowFilePath(tabText(index).replace("&&", "&"));
            if (currentWidget())
                currentWidget()->setFocus();
        }
    }
}

void SessionTabWidget::onNewTabRequested()
{
    QInputDialog dialog(this);
    dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    dialog.setWindowTitle(tr("Join channel"));
    dialog.setLabelText(tr("Channel:"));
    if (dialog.exec())
    {
        QString channel = dialog.textValue();
        if (!channel.isEmpty())
        {
            if (session()->isChannel(channel))
                d.handler.session()->sendCommand(IrcCommand::createJoin(channel));
            openView(channel);
        }
    }
}

void SessionTabWidget::onTabMenuRequested(int index, const QPoint& pos)
{
    QMenu menu;
    if (index == 0)
    {
        if (session()->isActive())
            menu.addAction(tr("Disconnect"), session(), SLOT(quit()));
        else
            menu.addAction(tr("Reconnect"), session(), SLOT(reconnect()));
    }
    if (static_cast<MessageView*>(widget(index))->viewType() == MessageView::ChannelView)
        menu.addAction(tr("Part"), this, SLOT(onTabCloseRequested()))->setData(index);
    else
        menu.addAction(tr("Close"), this, SLOT(onTabCloseRequested()))->setData(index);
    menu.exec(pos);
}

void SessionTabWidget::onTabCloseRequested()
{
    QAction* action = qobject_cast<QAction*>(sender());
    if (action)
        closeView(action->data().toInt());
}

void SessionTabWidget::delayedTabReset()
{
    d.delayedIndexes += currentIndex();
    QTimer::singleShot(500, this, SLOT(delayedTabResetTimeout()));
}

void SessionTabWidget::delayedTabResetTimeout()
{
    if (d.delayedIndexes.isEmpty())
        return;

    int index = d.delayedIndexes.takeFirst();
    tabActivated(index);
}

void SessionTabWidget::onTabAlerted(IrcMessage* message)
{
    int index = indexOf(static_cast<QWidget*>(sender()));
    if (index != -1)
    {
        if (!isVisible() || !isActiveWindow() || index != currentIndex())
        {
            setTabAlert(index, true);
            emit alerted(message);
        }
    }
}

void SessionTabWidget::onTabHighlighted(IrcMessage* message)
{
    int index = indexOf(static_cast<QWidget*>(sender()));
    if (index != -1)
    {
        if (!isVisible() || !isActiveWindow() || index != currentIndex())
        {
            setTabHighlight(index, true);
            emit highlighted(message);
        }
    }
}

void SessionTabWidget::applySettings(const Settings& settings)
{
    d.tabLeftShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabLeft)));
    d.tabRightShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabRight)));

    QColor color(settings.colors.value(Settings::Highlight));
    setTabTextColor(Alert, color);
    setTabTextColor(Highlight, color);

    foreach (MessageView* view, d.views)
        view->applySettings(settings);
    d.settings = settings;
}
<commit_msg>desktop ex: more mnemonic escaping related fixes...<commit_after>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#include "sessiontabwidget.h"
#include "messageview.h"
#include "settings.h"
#include "session.h"
#include <irccommand.h>
#include <QtGui>

SessionTabWidget::SessionTabWidget(Session* session, QWidget* parent) :
    TabWidget(parent)
{
    d.handler.setSession(session);

    connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabActivated(int)));
    connect(this, SIGNAL(newTabRequested()), this, SLOT(onNewTabRequested()), Qt::QueuedConnection);
    connect(this, SIGNAL(tabMenuRequested(int,QPoint)), this, SLOT(onTabMenuRequested(int,QPoint)));

    connect(session, SIGNAL(activeChanged(bool)), this, SLOT(updateStatus()));
    connect(session, SIGNAL(connectedChanged(bool)), this, SLOT(updateStatus()));

    connect(&d.handler, SIGNAL(receiverToBeAdded(QString)), this, SLOT(openView(QString)));
    connect(&d.handler, SIGNAL(receiverToBeRemoved(QString)), this, SLOT(removeView(QString)));
    connect(&d.handler, SIGNAL(receiverToBeRenamed(QString,QString)), this, SLOT(renameView(QString,QString)));

    d.tabLeftShortcut = new QShortcut(this);
    connect(d.tabLeftShortcut, SIGNAL(activated()), this, SLOT(moveToPrevTab()));

    d.tabRightShortcut = new QShortcut(this);
    connect(d.tabRightShortcut, SIGNAL(activated()), this, SLOT(moveToNextTab()));

    QShortcut* shortcut = new QShortcut(QKeySequence::AddTab, this);
    connect(shortcut, SIGNAL(activated()), this, SLOT(onNewTabRequested()));

    shortcut = new QShortcut(QKeySequence::Close, this);
    connect(shortcut, SIGNAL(activated()), this, SLOT(closeCurrentView()));

    MessageView* view = openView(d.handler.session()->host());
    d.handler.setDefaultReceiver(view);
    updateStatus();

    applySettings(d.settings);
}

Session* SessionTabWidget::session() const
{
    return qobject_cast<Session*>(d.handler.session());
}

MessageView* SessionTabWidget::openView(const QString& receiver)
{
    MessageView* view = d.views.value(receiver.toLower());
    if (!view)
    {
        MessageView::ViewType type = MessageView::ServerView;
        if (!d.views.isEmpty())
            type = session()->isChannel(receiver) ? MessageView::ChannelView : MessageView::QueryView;
        view = new MessageView(type, d.handler.session(), this);
        view->setReceiver(receiver);
        connect(view, SIGNAL(alerted(IrcMessage*)), this, SLOT(onTabAlerted(IrcMessage*)));
        connect(view, SIGNAL(highlighted(IrcMessage*)), this, SLOT(onTabHighlighted(IrcMessage*)));
        connect(view, SIGNAL(queried(QString)), this, SLOT(openView(QString)));

        d.handler.addReceiver(receiver, view);
        d.views.insert(receiver.toLower(), view);
        addTab(view, QString(receiver).replace("&", "&&"));
    }
    setCurrentWidget(view);
    return view;
}

void SessionTabWidget::removeView(const QString& receiver)
{
    MessageView* view = d.views.take(receiver.toLower());
    if (view)
    {
        view->deleteLater();
        if (indexOf(view) == 0)
        {
            deleteLater();
            session()->destructLater();
        }
    }
}

void SessionTabWidget::closeCurrentView()
{
    closeView(currentIndex());
}

void SessionTabWidget::closeView(int index)
{
    MessageView* view = d.views.value(tabText(index).replace("&&", "&").toLower());
    if (view)
    {
        QString reason = tr("%1 %2").arg(QApplication::applicationName())
                                    .arg(QApplication::applicationVersion());
        if (indexOf(view) == 0)
            session()->quit(reason);
        else if (view->viewType() == MessageView::ChannelView)
            d.handler.session()->sendCommand(IrcCommand::createPart(view->receiver(), reason));

        d.handler.removeReceiver(view->receiver());
    }
}

void SessionTabWidget::renameView(const QString& from, const QString& to)
{
    MessageView* view = d.views.take(from.toLower());
    if (view)
    {
        view->setReceiver(to);
        d.views.insert(to.toLower(), view);
        int index = indexOf(view);
        if (index != -1)
            setTabText(index, view->receiver().replace("&", "&&"));
    }
}

bool SessionTabWidget::event(QEvent* event)
{
    if (event->type() == QEvent::WindowActivate)
        delayedTabReset();
    return TabWidget::event(event);
}

void SessionTabWidget::updateStatus()
{
    bool inactive = !session()->isActive() && !session()->isConnected();
    setTabInactive(0, inactive);
    emit inactiveStatusChanged(inactive);
}

void SessionTabWidget::tabActivated(int index)
{
    if (index < count() - 1)
    {
        d.handler.setCurrentReceiver(qobject_cast<MessageView*>(currentWidget()));
        setTabAlert(index, false);
        setTabHighlight(index, false);
        if (isVisible())
        {
            window()->setWindowFilePath(tabText(index).replace("&&", "&"));
            if (currentWidget())
                currentWidget()->setFocus();
        }
    }
}

void SessionTabWidget::onNewTabRequested()
{
    QInputDialog dialog(this);
    dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    dialog.setWindowTitle(tr("Join channel"));
    dialog.setLabelText(tr("Channel:"));
    if (dialog.exec())
    {
        QString channel = dialog.textValue();
        if (!channel.isEmpty())
        {
            if (session()->isChannel(channel))
                d.handler.session()->sendCommand(IrcCommand::createJoin(channel));
            openView(channel);
        }
    }
}

void SessionTabWidget::onTabMenuRequested(int index, const QPoint& pos)
{
    QMenu menu;
    if (index == 0)
    {
        if (session()->isActive())
            menu.addAction(tr("Disconnect"), session(), SLOT(quit()));
        else
            menu.addAction(tr("Reconnect"), session(), SLOT(reconnect()));
    }
    if (static_cast<MessageView*>(widget(index))->viewType() == MessageView::ChannelView)
        menu.addAction(tr("Part"), this, SLOT(onTabCloseRequested()))->setData(index);
    else
        menu.addAction(tr("Close"), this, SLOT(onTabCloseRequested()))->setData(index);
    menu.exec(pos);
}

void SessionTabWidget::onTabCloseRequested()
{
    QAction* action = qobject_cast<QAction*>(sender());
    if (action)
        closeView(action->data().toInt());
}

void SessionTabWidget::delayedTabReset()
{
    d.delayedIndexes += currentIndex();
    QTimer::singleShot(500, this, SLOT(delayedTabResetTimeout()));
}

void SessionTabWidget::delayedTabResetTimeout()
{
    if (d.delayedIndexes.isEmpty())
        return;

    int index = d.delayedIndexes.takeFirst();
    tabActivated(index);
}

void SessionTabWidget::onTabAlerted(IrcMessage* message)
{
    int index = indexOf(static_cast<QWidget*>(sender()));
    if (index != -1)
    {
        if (!isVisible() || !isActiveWindow() || index != currentIndex())
        {
            setTabAlert(index, true);
            emit alerted(message);
        }
    }
}

void SessionTabWidget::onTabHighlighted(IrcMessage* message)
{
    int index = indexOf(static_cast<QWidget*>(sender()));
    if (index != -1)
    {
        if (!isVisible() || !isActiveWindow() || index != currentIndex())
        {
            setTabHighlight(index, true);
            emit highlighted(message);
        }
    }
}

void SessionTabWidget::applySettings(const Settings& settings)
{
    d.tabLeftShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabLeft)));
    d.tabRightShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabRight)));

    QColor color(settings.colors.value(Settings::Highlight));
    setTabTextColor(Alert, color);
    setTabTextColor(Highlight, color);

    foreach (MessageView* view, d.views)
        view->applySettings(settings);
    d.settings = settings;
}
<|endoftext|>


<commit_before>#include "text/table.h"
#include "text/cmdline.h"
#include "cortex/cortex.h"
#include "cortex/logger.h"
#include "cortex/measure.hpp"
#include "text/to_params.hpp"
#include "optim/batch/types.h"
#include "optim/stoch/types.h"
#include "cortex/tasks/task_charset.h"
#include "cortex/layers/make_layers.h"

using namespace nano;

size_t gmin_threads = 1;
size_t gmax_threads = 1;

template
<
        typename ttrainer
>
static void evaluate_trainer(model_t& model, const string_t& name,
        table_t& table, const vector_t& x0, const ttrainer& trainer)
{
        auto& row = table.append(name);
        for (size_t nthreads = gmin_threads; nthreads <= gmax_threads; ++ nthreads)
        {
                model.load_params(x0);

                log_info() << "<<< running " << name << " with " << nthreads << " threads...";

                const nano::timer_t timer;

                const auto result = trainer(nthreads);
                NANO_UNUSED1(result);

                row << timer.seconds().count();
        }
}

static void evaluate(model_t& model,
        const task_t& task, const size_t fold,
        const loss_t& loss, const criterion_t& criterion, const vector_t& x0, const size_t epochs,
        const std::vector<batch_optimizer>& batch_optimizers,
        const std::vector<batch_optimizer>& minibatch_optimizers,
        const std::vector<stoch_optimizer>& stochastic_optimizers,
        const string_t& basename, table_t& table)
{
        const auto policy = trainer_policy::all_epochs;

        for (auto optimizer : batch_optimizers)
        {
                const auto optname = "batch-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("batch", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }

        for (auto optimizer : minibatch_optimizers)
        {
                const auto optname = "minibatch-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("minibatch", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }

        for (auto optimizer : stochastic_optimizers)
        {
                const auto optname = "stochastic-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("stochastic", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }
}

int main(int argc, const char* argv[])
{
        using namespace nano;

        // parse the command line
        cmdline_t cmdline("benchmark trainers");
        cmdline.add("", "mlps",                 "use MLPs with varying number of hidden layers");
        cmdline.add("", "mlp0",                 "use MLPs with 0 hidden layers");
        cmdline.add("", "mlp1",                 "use MLPs with 1 hidden layer");
        cmdline.add("", "mlp2",                 "use MLPs with 2 hidden layers");
        cmdline.add("", "mlp3",                 "use MLPs with 3 hidden layers");
        cmdline.add("", "convnets",             "use convolution networks with varying number of convolution layers");
        cmdline.add("", "convnet1",             "use convolution networks with 1 convolution layer");
        cmdline.add("", "convnet2",             "use convolution networks with 2 convolution layers");
        cmdline.add("", "convnet3",             "use convolution networks with 3 convolution layers");
        cmdline.add("", "batch",                "evaluate batch optimizers");
        cmdline.add("", "batch-gd",             "evaluate batch optimizer GD (gradient descent)");
        cmdline.add("", "batch-cgd",            "evaluate batch optimizer CGD (conjugate gradient descent)");
        cmdline.add("", "batch-lbfgs",          "evaluate batch optimizer LBFGS");
        cmdline.add("", "minibatch",            "evaluate mini-batch optimizers");
        cmdline.add("", "minibatch-gd",         "evaluate mini-batch optimizer GD (gradient descent)");
        cmdline.add("", "minibatch-cgd",        "evaluate mini-batch optimizer CGD (conjugate gradient descent)");
        cmdline.add("", "minibatch-lbfgs",      "evaluate mini-batch optimizer LBFGS");
        cmdline.add("", "stochastic",           "evaluate stochastic optimizers");
        cmdline.add("", "stochastic-sg",        "evaluate stochastic optimizer SG (stochastic gradient)");
        cmdline.add("", "stochastic-ngd",       "evaluate stochastic optimizer NGS (normalized gradient descent)");
        cmdline.add("", "stochastic-sgm",       "evaluate stochastic optimizer SGM (stochastic gradient with momentum)");
        cmdline.add("", "stochastic-ag",        "evaluate stochastic optimizer AG (Nesterov's accelerated gradient)");
        cmdline.add("", "stochastic-agfr",      "evaluate stochastic optimizer AG (AG + function value restarts)");
        cmdline.add("", "stochastic-aggr",      "evaluate stochastic optimizer AG (AG + gradient restarts)");
        cmdline.add("", "stochastic-adam",      "evaluate stochastic optimizer ADAM");
        cmdline.add("", "stochastic-adagrad",   "evaluate stochastic optimizer ADAGRAD");
        cmdline.add("", "stochastic-adadelta",  "evaluate stochastic optimizer ADADELTA");
        cmdline.add("", "min-threads",          "minimum number of threads to use", 1);
        cmdline.add("", "max-threads",          "maximum number of threads to use", nano::logical_cpus());

        cmdline.process(argc, argv);

        // check arguments and options
        const bool use_mlps = cmdline.has("mlps");
        const bool use_mlp0 = cmdline.has("mlp0");
        const bool use_mlp1 = cmdline.has("mlp1");
        const bool use_mlp2 = cmdline.has("mlp2");
        const bool use_mlp3 = cmdline.has("mlp3");
        const bool use_convnets = cmdline.has("convnets");
        const bool use_convnet1 = cmdline.has("convnet1");
        const bool use_convnet2 = cmdline.has("convnet2");
        const bool use_convnet3 = cmdline.has("convnet3");
        const auto epochs = size_t(100);
        gmin_threads = cmdline.get<size_t>("min-threads");
        gmax_threads = cmdline.get<size_t>("max-threads");

        if (    !use_mlps &&
                !use_mlp0 &&
                !use_mlp1 &&
                !use_mlp2 &&
                !use_mlp3 &&
                !use_convnets &&
                !use_convnet1 &&
                !use_convnet2 &&
                !use_convnet3)
        {
                cmdline.usage();
        }

        std::vector<batch_optimizer> batch_optimizers;
        if (cmdline.has("batch") || cmdline.has("batch-gd")) batch_optimizers.push_back(batch_optimizer::GD);
        if (cmdline.has("batch") || cmdline.has("batch-cgd")) batch_optimizers.push_back(batch_optimizer::CGD);
        if (cmdline.has("batch") || cmdline.has("batch-lbfgs")) batch_optimizers.push_back(batch_optimizer::LBFGS);

        std::vector<batch_optimizer> minibatch_optimizers;
        if (cmdline.has("minibatch") || cmdline.has("minibatch-gd")) minibatch_optimizers.push_back(batch_optimizer::GD);
        if (cmdline.has("minibatch") || cmdline.has("minibatch-cgd")) minibatch_optimizers.push_back(batch_optimizer::CGD);
        if (cmdline.has("minibatch") || cmdline.has("minibatch-lbfgs")) minibatch_optimizers.push_back(batch_optimizer::LBFGS);

        std::vector<stoch_optimizer> stochastic_optimizers;
        if (cmdline.has("stochastic") || cmdline.has("stochastic-sg")) stochastic_optimizers.push_back(stoch_optimizer::SG);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-ngd")) stochastic_optimizers.push_back(stoch_optimizer::NGD);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-sgm")) stochastic_optimizers.push_back(stoch_optimizer::SGM);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-ag")) stochastic_optimizers.push_back(stoch_optimizer::AG);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-agfr")) stochastic_optimizers.push_back(stoch_optimizer::AGFR);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-aggr")) stochastic_optimizers.push_back(stoch_optimizer::AGGR);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adam")) stochastic_optimizers.push_back(stoch_optimizer::ADAM);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adagrad")) stochastic_optimizers.push_back(stoch_optimizer::ADAGRAD);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adadelta")) stochastic_optimizers.push_back(stoch_optimizer::ADADELTA);

        if (    batch_optimizers.empty() &&
                minibatch_optimizers.empty() &&
                stochastic_optimizers.empty())
        {
                cmdline.usage();
        }

        // create task
        const size_t rows = 20;
        const size_t cols = 20;
        const size_t count = nano::logical_cpus() * 32 * 100;
        const color_mode color = color_mode::rgb;

        charset_task_t task(charset::digit, color, rows, cols, count);
        task.load();

        const size_t fold = 0;
        const auto outputs = task.osize();

        // construct models
        const auto activation = "act-snorm";
        const auto pooling = "pool-full";

        const auto mlp0 = string_t();
        const auto mlp1 = mlp0 + make_affine_layer(64, activation);
        const auto mlp2 = mlp1 + make_affine_layer(64, activation);
        const auto mlp3 = mlp2 + make_affine_layer(64, activation);

        const auto convnet1 =
                make_conv_pool_layer(32, 7, 7, 1, activation, pooling);

        const auto convnet2 =
                make_conv_pool_layer(32, 7, 7, 1, activation, pooling) +
                make_conv_layer(64, 5, 5, 4);

        const auto convnet3 =
                make_conv_layer(32, 7, 7, 1, activation) +
                make_conv_layer(64, 7, 7, 4, activation) +
                make_conv_layer(128, 5, 5, 8, activation);

        const string_t outlayer = make_output_layer(outputs, activation);

        std::vector<std::pair<string_t, string_t>> networks;
        if (use_mlps || use_mlp0) networks.emplace_back(mlp0 + outlayer, "mlp0");
        if (use_mlps || use_mlp1) networks.emplace_back(mlp1 + outlayer, "mlp1");
        if (use_mlps || use_mlp2) networks.emplace_back(mlp2 + outlayer, "mlp2");
        if (use_mlps || use_mlp3) networks.emplace_back(mlp3 + outlayer, "mlp3");
        if (use_convnets || use_convnet1) networks.emplace_back(convnet1 + outlayer, "convnet1");
        if (use_convnets || use_convnet2) networks.emplace_back(convnet2 + outlayer, "convnet2");
        if (use_convnets || use_convnet3) networks.emplace_back(convnet3 + outlayer, "convnet3");

        const strings_t losses = { "classnll" }; //get_losses().ids();
        const strings_t criteria = { "avg" }; //get_criteria().ids();

        table_t table("training time [s]");
        for (size_t nthreads = 1; nthreads <= nano::physical_cpus(); ++ nthreads)
        {
                table.header() << (to_string(nthreads) + "xCPU");
        }

        // vary the model
        for (const auto& net : networks)
        {
                const auto& network = net.first;
                const auto& netname = net.second;

                log_info() << "<<< running network [" << network << "] ...";

                const auto model = get_models().get("forward-network", network);
                model->resize(task, false);

                // generate fixed random starting point
                vector_t x0;
                model->random_params();
                model->save_params(x0);

                // vary the loss
                for (const string_t& iloss : losses)
                {
                        log_info() << "<<< running loss [" << iloss << "] ...";

                        const auto loss = get_losses().get(iloss);

                        // vary the criteria
                        for (const string_t& icriterion : criteria)
                        {
                                const auto criterion = get_criteria().get(icriterion);
                                const auto basename = netname + "-" + iloss + "-" + icriterion + "-";

                                evaluate(*model, task, fold, *loss, *criterion, x0, epochs,
                                         batch_optimizers, minibatch_optimizers, stochastic_optimizers,
                                         basename, table);
                        }
                }
        }

        // show results
        table.print(std::cout);

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<commit_msg>fix crash<commit_after>#include "text/table.h"
#include "text/cmdline.h"
#include "cortex/cortex.h"
#include "cortex/logger.h"
#include "cortex/measure.hpp"
#include "text/to_params.hpp"
#include "optim/batch/types.h"
#include "optim/stoch/types.h"
#include "cortex/tasks/task_charset.h"
#include "cortex/layers/make_layers.h"

using namespace nano;

size_t gmin_threads = 1;
size_t gmax_threads = 1;

template
<
        typename ttrainer
>
static void evaluate_trainer(model_t& model, const string_t& name,
        table_t& table, const vector_t& x0, const ttrainer& trainer)
{
        auto& row = table.append(name);
        for (size_t nthreads = gmin_threads; nthreads <= gmax_threads; ++ nthreads)
        {
                model.load_params(x0);

                log_info() << "<<< running " << name << " with " << nthreads << " threads...";

                const nano::timer_t timer;

                const auto result = trainer(nthreads);
                NANO_UNUSED1(result);

                row << timer.seconds().count();
        }
}

static void evaluate(model_t& model,
        const task_t& task, const size_t fold,
        const loss_t& loss, const criterion_t& criterion, const vector_t& x0, const size_t epochs,
        const std::vector<batch_optimizer>& batch_optimizers,
        const std::vector<batch_optimizer>& minibatch_optimizers,
        const std::vector<stoch_optimizer>& stochastic_optimizers,
        const string_t& basename, table_t& table)
{
        const auto policy = trainer_policy::all_epochs;

        for (auto optimizer : batch_optimizers)
        {
                const auto optname = "batch-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("batch", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }

        for (auto optimizer : minibatch_optimizers)
        {
                const auto optname = "minibatch-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("minibatch", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }

        for (auto optimizer : stochastic_optimizers)
        {
                const auto optname = "stochastic-" + to_string(optimizer);
                const auto params = to_params("opt", optimizer, "epochs", epochs, "policy", policy);
                evaluate_trainer(model, basename + optname, table, x0, [&] (const size_t nthreads)
                {
                        const auto trainer = get_trainers().get("stochastic", params);
                        return trainer->train(task, fold, nthreads, loss, criterion, model);
                });
        }
}

int main(int argc, const char* argv[])
{
        using namespace nano;

        // parse the command line
        cmdline_t cmdline("benchmark trainers");
        cmdline.add("", "mlps",                 "use MLPs with varying number of hidden layers");
        cmdline.add("", "mlp0",                 "use MLPs with 0 hidden layers");
        cmdline.add("", "mlp1",                 "use MLPs with 1 hidden layer");
        cmdline.add("", "mlp2",                 "use MLPs with 2 hidden layers");
        cmdline.add("", "mlp3",                 "use MLPs with 3 hidden layers");
        cmdline.add("", "convnets",             "use convolution networks with varying number of convolution layers");
        cmdline.add("", "convnet1",             "use convolution networks with 1 convolution layer");
        cmdline.add("", "convnet2",             "use convolution networks with 2 convolution layers");
        cmdline.add("", "convnet3",             "use convolution networks with 3 convolution layers");
        cmdline.add("", "batch",                "evaluate batch optimizers");
        cmdline.add("", "batch-gd",             "evaluate batch optimizer GD (gradient descent)");
        cmdline.add("", "batch-cgd",            "evaluate batch optimizer CGD (conjugate gradient descent)");
        cmdline.add("", "batch-lbfgs",          "evaluate batch optimizer LBFGS");
        cmdline.add("", "minibatch",            "evaluate mini-batch optimizers");
        cmdline.add("", "minibatch-gd",         "evaluate mini-batch optimizer GD (gradient descent)");
        cmdline.add("", "minibatch-cgd",        "evaluate mini-batch optimizer CGD (conjugate gradient descent)");
        cmdline.add("", "minibatch-lbfgs",      "evaluate mini-batch optimizer LBFGS");
        cmdline.add("", "stochastic",           "evaluate stochastic optimizers");
        cmdline.add("", "stochastic-sg",        "evaluate stochastic optimizer SG (stochastic gradient)");
        cmdline.add("", "stochastic-ngd",       "evaluate stochastic optimizer NGS (normalized gradient descent)");
        cmdline.add("", "stochastic-sgm",       "evaluate stochastic optimizer SGM (stochastic gradient with momentum)");
        cmdline.add("", "stochastic-ag",        "evaluate stochastic optimizer AG (Nesterov's accelerated gradient)");
        cmdline.add("", "stochastic-agfr",      "evaluate stochastic optimizer AG (AG + function value restarts)");
        cmdline.add("", "stochastic-aggr",      "evaluate stochastic optimizer AG (AG + gradient restarts)");
        cmdline.add("", "stochastic-adam",      "evaluate stochastic optimizer ADAM");
        cmdline.add("", "stochastic-adagrad",   "evaluate stochastic optimizer ADAGRAD");
        cmdline.add("", "stochastic-adadelta",  "evaluate stochastic optimizer ADADELTA");
        cmdline.add("", "min-threads",          "minimum number of threads to use", 1);
        cmdline.add("", "max-threads",          "maximum number of threads to use", nano::logical_cpus());

        cmdline.process(argc, argv);

        // check arguments and options
        const bool use_mlps = cmdline.has("mlps");
        const bool use_mlp0 = cmdline.has("mlp0");
        const bool use_mlp1 = cmdline.has("mlp1");
        const bool use_mlp2 = cmdline.has("mlp2");
        const bool use_mlp3 = cmdline.has("mlp3");
        const bool use_convnets = cmdline.has("convnets");
        const bool use_convnet1 = cmdline.has("convnet1");
        const bool use_convnet2 = cmdline.has("convnet2");
        const bool use_convnet3 = cmdline.has("convnet3");
        const auto epochs = size_t(100);
        gmin_threads = cmdline.get<size_t>("min-threads");
        gmax_threads = cmdline.get<size_t>("max-threads");

        if (    !use_mlps &&
                !use_mlp0 &&
                !use_mlp1 &&
                !use_mlp2 &&
                !use_mlp3 &&
                !use_convnets &&
                !use_convnet1 &&
                !use_convnet2 &&
                !use_convnet3)
        {
                cmdline.usage();
        }

        std::vector<batch_optimizer> batch_optimizers;
        if (cmdline.has("batch") || cmdline.has("batch-gd")) batch_optimizers.push_back(batch_optimizer::GD);
        if (cmdline.has("batch") || cmdline.has("batch-cgd")) batch_optimizers.push_back(batch_optimizer::CGD);
        if (cmdline.has("batch") || cmdline.has("batch-lbfgs")) batch_optimizers.push_back(batch_optimizer::LBFGS);

        std::vector<batch_optimizer> minibatch_optimizers;
        if (cmdline.has("minibatch") || cmdline.has("minibatch-gd")) minibatch_optimizers.push_back(batch_optimizer::GD);
        if (cmdline.has("minibatch") || cmdline.has("minibatch-cgd")) minibatch_optimizers.push_back(batch_optimizer::CGD);
        if (cmdline.has("minibatch") || cmdline.has("minibatch-lbfgs")) minibatch_optimizers.push_back(batch_optimizer::LBFGS);

        std::vector<stoch_optimizer> stochastic_optimizers;
        if (cmdline.has("stochastic") || cmdline.has("stochastic-sg")) stochastic_optimizers.push_back(stoch_optimizer::SG);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-ngd")) stochastic_optimizers.push_back(stoch_optimizer::NGD);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-sgm")) stochastic_optimizers.push_back(stoch_optimizer::SGM);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-ag")) stochastic_optimizers.push_back(stoch_optimizer::AG);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-agfr")) stochastic_optimizers.push_back(stoch_optimizer::AGFR);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-aggr")) stochastic_optimizers.push_back(stoch_optimizer::AGGR);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adam")) stochastic_optimizers.push_back(stoch_optimizer::ADAM);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adagrad")) stochastic_optimizers.push_back(stoch_optimizer::ADAGRAD);
        if (cmdline.has("stochastic") || cmdline.has("stochastic-adadelta")) stochastic_optimizers.push_back(stoch_optimizer::ADADELTA);

        if (    batch_optimizers.empty() &&
                minibatch_optimizers.empty() &&
                stochastic_optimizers.empty())
        {
                cmdline.usage();
        }

        // create task
        const size_t rows = 20;
        const size_t cols = 20;
        const size_t count = nano::logical_cpus() * 32 * 100;
        const color_mode color = color_mode::rgb;

        charset_task_t task(charset::digit, color, rows, cols, count);
        task.load();

        const size_t fold = 0;
        const auto outputs = task.osize();

        // construct models
        const auto activation = "act-snorm";
        const auto pooling = "pool-full";

        const auto mlp0 = string_t();
        const auto mlp1 = mlp0 + make_affine_layer(64, activation);
        const auto mlp2 = mlp1 + make_affine_layer(64, activation);
        const auto mlp3 = mlp2 + make_affine_layer(64, activation);

        const auto convnet1 =
                make_conv_pool_layer(32, 7, 7, 1, activation, pooling);

        const auto convnet2 =
                make_conv_pool_layer(32, 7, 7, 1, activation, pooling) +
                make_conv_layer(64, 5, 5, 4);

        const auto convnet3 =
                make_conv_layer(32, 7, 7, 1, activation) +
                make_conv_layer(64, 7, 7, 4, activation) +
                make_conv_layer(128, 5, 5, 8, activation);

        const string_t outlayer = make_output_layer(outputs, activation);

        std::vector<std::pair<string_t, string_t>> networks;
        if (use_mlps || use_mlp0) networks.emplace_back(mlp0 + outlayer, "mlp0");
        if (use_mlps || use_mlp1) networks.emplace_back(mlp1 + outlayer, "mlp1");
        if (use_mlps || use_mlp2) networks.emplace_back(mlp2 + outlayer, "mlp2");
        if (use_mlps || use_mlp3) networks.emplace_back(mlp3 + outlayer, "mlp3");
        if (use_convnets || use_convnet1) networks.emplace_back(convnet1 + outlayer, "convnet1");
        if (use_convnets || use_convnet2) networks.emplace_back(convnet2 + outlayer, "convnet2");
        if (use_convnets || use_convnet3) networks.emplace_back(convnet3 + outlayer, "convnet3");

        const strings_t losses = { "classnll" }; //get_losses().ids();
        const strings_t criteria = { "avg" }; //get_criteria().ids();

        table_t table("training time [s]");
        for (size_t nthreads = gmin_threads; nthreads <= gmax_threads; ++ nthreads)
        {
                table.header() << (to_string(nthreads) + "xCPU");
        }

        // vary the model
        for (const auto& net : networks)
        {
                const auto& network = net.first;
                const auto& netname = net.second;

                log_info() << "<<< running network [" << network << "] ...";

                const auto model = get_models().get("forward-network", network);
                model->resize(task, false);

                // generate fixed random starting point
                vector_t x0;
                model->random_params();
                model->save_params(x0);

                // vary the loss
                for (const string_t& iloss : losses)
                {
                        log_info() << "<<< running loss [" << iloss << "] ...";

                        const auto loss = get_losses().get(iloss);

                        // vary the criteria
                        for (const string_t& icriterion : criteria)
                        {
                                const auto criterion = get_criteria().get(icriterion);
                                const auto basename = netname + "-" + iloss + "-" + icriterion + "-";

                                evaluate(*model, task, fold, *loss, *criterion, x0, epochs,
                                         batch_optimizers, minibatch_optimizers, stochastic_optimizers,
                                         basename, table);
                        }
                }
        }

        // show results
        table.print(std::cout);

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Petter Strandmark 2012--2013.

#include <functional>
#include <iostream>
#include <random>

#include <spii/auto_diff_term.h>
#include <spii/constraints.h>
#include <spii/interval_term.h>
#include <spii/solver.h>

using namespace spii;

// One term in the negative log-likelihood function for
// a one-dimensional Gaussian distribution.
struct NegLogLikelihood
{
	double sample;
	NegLogLikelihood(double sample)
	{
		this->sample = sample;
	}

	template<typename R>
	R operator()(const R* const mu, const R* const sigma) const
	{
		R diff = (*mu - sample) / *sigma;
		return 0.5 * diff*diff + log(*sigma);
	}
};

int main_function()
{
	std::mt19937 prng(1u);
	std::normal_distribution<double> normal;
	auto randn = std::bind(normal, prng);

	double mu    = 5.0;
	double sigma = 3.0;
	std::cout << "mu = " << mu << ", sigma = " << sigma << std::endl;

	Function f;
	f.add_variable(&mu, 1);
	f.add_variable_with_change<GreaterThanZero>(&sigma, 1, 1);

	for (int i = 0; i < 10000; ++i) {
		double sample = sigma*randn() + mu;
		f.add_term(std::make_shared<IntervalTerm<NegLogLikelihood, 1, 1>>(sample), &mu, &sigma);
	}

	mu    = 0.0;
	sigma = 1.0;
	LBFGSSolver solver;
	SolverResults results;
	solver.solve(f, &results);
	std::cout << "Estimated:" << std::endl;
	std::cout << "f = " << f.evaluate() << " mu = " << mu << ", sigma = " << sigma << std::endl << std::endl;

	return 0;
}

int main()
{
	try {
		return main_function();
	}
	catch (std::exception& e) {
		std::cerr << "Error: " << e.what() << '\n';
		return 1;
	}
}<commit_msg>Updated example and added callback.<commit_after>// Petter Strandmark 2012--2013.

#include <functional>
#include <iostream>
#include <random>

#include <spii/auto_diff_term.h>
#include <spii/constraints.h>
#include <spii/interval_term.h>
#include <spii/solver.h>

using namespace spii;

// One term in the negative log-likelihood function for
// a one-dimensional Gaussian distribution.
struct NegLogLikelihood
{
	double sample;
	NegLogLikelihood(double sample)
	{
		this->sample = sample;
	}

	template<typename R>
	R operator()(const R* const mu, const R* const sigma) const
	{
		R diff = (*mu - sample) / *sigma;
		return 0.5 * diff*diff + log(*sigma);
	}
};

int main_function()
{
	using namespace std;

	mt19937 prng(1u);
	normal_distribution<double> normal;
	auto randn = bind(normal, prng);

	double mu    = 5.0;
	double sigma = 3.0;
	cout << "mu = " << mu << ", sigma = " << sigma << endl;

	Function f;
	f.add_variable(&mu, 1);
	f.add_variable_with_change<GreaterThanZero>(&sigma, 1, 1);

	for (int i = 0; i < 10000; ++i) {
		double sample = sigma*randn() + mu;
		f.add_term(std::make_shared<IntervalTerm<NegLogLikelihood, 1, 1>>(sample), &mu, &sigma);
	}

	mu    = 0.0;
	sigma = 1.0;
	LBFGSSolver solver;

	solver.callback_function = [&](const CallbackInformation& information) -> bool
	{
		f.copy_global_to_user(*information.x);
		cerr << "  -- mu = " << mu << ", sigma = " << sigma << endl;
		return true;
	};

	SolverResults results;
	solver.solve(f, &results);
	cout << "Estimated:" << endl;
	cout << "f = " << f.evaluate() << " mu = " << mu << ", sigma = " << sigma << endl << endl;

	return 0;
}

int main()
{
	try {
		return main_function();
	}
	catch (std::exception& e) {
		std::cerr << "Error: " << e.what() << '\n';
		return 1;
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Jie (Jay) Tan <jtan34@cc.gatech.edu>
 * Date: 07/18/2011
 *
 * Geoorgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "OpenGLRenderInterface.h"
#include "utils/LoadOpengl.h"
#include <iostream>

using namespace std;
using namespace Eigen;

namespace renderer {

    void OpenGLRenderInterface::initialize() {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glCullFace(GL_FRONT);
        glDisable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
        //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
        glShadeModel(GL_SMOOTH);
        clear(Vector3d(1.0, 1.0, 1.0));
    }

    void OpenGLRenderInterface::destroy() {

    }

    void OpenGLRenderInterface::setViewport(int _x,int _y,int _width,int _height) {
        glViewport(_x, _y, _width, _height);
        mViewportX = _x;
        mViewportY = _y;
        mViewportWidth = _width;
        mViewportHeight = _height;
    }

    void OpenGLRenderInterface::getViewport(int& _x, int& _y, int& _width, int& _height) const {
        _x = mViewportX;
        _y = mViewportY;
        _width = mViewportWidth;
        _height =mViewportHeight;
    }

    void OpenGLRenderInterface::clear(const Vector3d& _color) {
        glClearColor((GLfloat)_color[0], (GLfloat)_color[1], (GLfloat)_color[2], 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    void OpenGLRenderInterface::setDefaultLight() {

    }

    void OpenGLRenderInterface::turnLightsOff() {
        glDisable(GL_LIGHTING);
    }

    void OpenGLRenderInterface::turnLightsOn() {
        //not finished yet
        glEnable(GL_LIGHTING);
    }

    void OpenGLRenderInterface::setMaterial(const Vector3d& _diffuse, const Vector3d& _specular, double _cosinePow) {

    }

    void OpenGLRenderInterface::getMaterial(Vector3d& _diffuse, Vector3d& _specular, double& _cosinePow) const {

    }

    void OpenGLRenderInterface::setDefaultMaterial() {

    }

    void OpenGLRenderInterface::pushMatrix() {
        glPushMatrix();
    }

    void OpenGLRenderInterface::popMatrix() {
        glPopMatrix();
    }

    void OpenGLRenderInterface::pushName(int _id) {
        glPushName(_id);
    }

    void OpenGLRenderInterface::popName() {
        glPopName();
    }

    void OpenGLRenderInterface::translate(const Vector3d& _offset) {
        glTranslated(_offset[0], _offset[1], _offset[2]);
    }

    void OpenGLRenderInterface::rotate(const Vector3d& _axis, double _rad) {
        glRotated(_rad, _axis[0], _axis[1], _axis[2]);
    }

    void OpenGLRenderInterface::scale(const Vector3d& _scale) {
        glScaled(_scale[0], _scale[1], _scale[2]);
    }

    void OpenGLRenderInterface::drawEllipsoid(const Vector3d& _size) {
        glScaled(_size(0), _size(1), _size(2));
        glutSolidSphere(0.5, 16, 16);
    }

    void OpenGLRenderInterface::drawCube(const Vector3d& _size) {
        glScaled(_size(0), _size(1), _size(2));
        glutSolidCube(1.0);
    }

    void color4_to_float4(const aiColor4D *c, float f[4])
    {
        f[0] = c->r;
        f[1] = c->g;
        f[2] = c->b;
        f[3] = c->a;
    }

    void set_float4(float f[4], float a, float b, float c, float d)
    {
        f[0] = a;
        f[1] = b;
        f[2] = c;
        f[3] = d;
    }

    void applyMaterial(const struct aiMaterial *mtl)
    {
        float c[4];

        GLenum fill_mode;
        int ret1, ret2;
        aiColor4D diffuse;
        aiColor4D specular;
        aiColor4D ambient;
        aiColor4D emission;
        float shininess, strength;
        int two_sided;
        int wireframe;
        unsigned int max;

        set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
            color4_to_float4(&diffuse, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);

        set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
            color4_to_float4(&specular, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);

        set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
            color4_to_float4(&ambient, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);

        set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
            color4_to_float4(&emission, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);

        max = 1;
        ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
        if(ret1 == AI_SUCCESS) {
            max = 1;
            ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
            if(ret2 == AI_SUCCESS)
                glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
            else
                glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
        }
        else {
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
            set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
        }

        max = 1;
        if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
            fill_mode = wireframe ? GL_LINE : GL_FILL;
        else
            fill_mode = GL_FILL;
        glPolygonMode(GL_FRONT_AND_BACK, fill_mode);

        max = 1;
        if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
            glDisable(GL_CULL_FACE);
        else
            glEnable(GL_CULL_FACE);
    }

    void OpenGLRenderInterface::drawMesh(const Vector3d& _size, const aiScene *_mesh) {
        const aiScene* scene = _mesh;
        glBegin(GL_TRIANGLES);
        for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
            const aiMesh* mesh = scene->mMeshes[i];
            applyMaterial(scene->mMaterials[mesh->mMaterialIndex]);
            if(mesh->mNormals == NULL)
                glDisable(GL_LIGHTING);
            else
                glEnable(GL_LIGHTING);
            for (unsigned int j = 0; j < mesh->mNumFaces; j++) {
                const aiFace* face = &mesh->mFaces[j];
                for(unsigned int k = 0; k < face->mNumIndices; k++) {
                    int index = face->mIndices[k];
                    if(mesh->mColors[0] != NULL)
                        glColor4fv((GLfloat*)&mesh->mColors[0][index]);
                    if(mesh->mNormals != NULL)
                        glNormal3fv(&mesh->mNormals[index].x);
                    glVertex3fv(&mesh->mVertices[index].x);
                }
            }
        }
        glEnd();
    }

    void OpenGLRenderInterface::setPenColor(const Vector4d& _col) {
        glColor4d(_col[0], _col[1], _col[2], _col[3]);
    }

    void OpenGLRenderInterface::setPenColor(const Vector3d& _col) {
        glColor4d(_col[0], _col[1], _col[2], 1.0);
    }

    void OpenGLRenderInterface::readFrameBuffer(DecoBufferType _buffType, DecoColorChannel _ch, void *_pixels) {

    }

    void OpenGLRenderInterface::saveToImage(const char *_filename, DecoBufferType _buffType) {

    }

} // namespace renderer
<commit_msg>Fix color issue<commit_after>/*
 * Copyright (c) 2011, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Jie (Jay) Tan <jtan34@cc.gatech.edu>
 * Date: 07/18/2011
 *
 * Geoorgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "OpenGLRenderInterface.h"
#include "utils/LoadOpengl.h"
#include <iostream>
#include <assimp/cimport.h>

using namespace std;
using namespace Eigen;

namespace renderer {

    void OpenGLRenderInterface::initialize() {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glCullFace(GL_FRONT);
        glDisable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
        //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
        glShadeModel(GL_SMOOTH);
        clear(Vector3d(1.0, 1.0, 1.0));
    }

    void OpenGLRenderInterface::destroy() {

    }

    void OpenGLRenderInterface::setViewport(int _x,int _y,int _width,int _height) {
        glViewport(_x, _y, _width, _height);
        mViewportX = _x;
        mViewportY = _y;
        mViewportWidth = _width;
        mViewportHeight = _height;
    }

    void OpenGLRenderInterface::getViewport(int& _x, int& _y, int& _width, int& _height) const {
        _x = mViewportX;
        _y = mViewportY;
        _width = mViewportWidth;
        _height =mViewportHeight;
    }

    void OpenGLRenderInterface::clear(const Vector3d& _color) {
        glClearColor((GLfloat)_color[0], (GLfloat)_color[1], (GLfloat)_color[2], 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    void OpenGLRenderInterface::setDefaultLight() {

    }

    void OpenGLRenderInterface::turnLightsOff() {
        glDisable(GL_LIGHTING);
    }

    void OpenGLRenderInterface::turnLightsOn() {
        //not finished yet
        glEnable(GL_LIGHTING);
    }

    void OpenGLRenderInterface::setMaterial(const Vector3d& _diffuse, const Vector3d& _specular, double _cosinePow) {

    }

    void OpenGLRenderInterface::getMaterial(Vector3d& _diffuse, Vector3d& _specular, double& _cosinePow) const {

    }

    void OpenGLRenderInterface::setDefaultMaterial() {

    }

    void OpenGLRenderInterface::pushMatrix() {
        glPushMatrix();
    }

    void OpenGLRenderInterface::popMatrix() {
        glPopMatrix();
    }

    void OpenGLRenderInterface::pushName(int _id) {
        glPushName(_id);
    }

    void OpenGLRenderInterface::popName() {
        glPopName();
    }

    void OpenGLRenderInterface::translate(const Vector3d& _offset) {
        glTranslated(_offset[0], _offset[1], _offset[2]);
    }

    void OpenGLRenderInterface::rotate(const Vector3d& _axis, double _rad) {
        glRotated(_rad, _axis[0], _axis[1], _axis[2]);
    }

    void OpenGLRenderInterface::scale(const Vector3d& _scale) {
        glScaled(_scale[0], _scale[1], _scale[2]);
    }

    void OpenGLRenderInterface::drawEllipsoid(const Vector3d& _size) {
        glScaled(_size(0), _size(1), _size(2));
        glutSolidSphere(0.5, 16, 16);
    }

    void OpenGLRenderInterface::drawCube(const Vector3d& _size) {
        glScaled(_size(0), _size(1), _size(2));
        glutSolidCube(1.0);
    }

    void color4_to_float4(const aiColor4D *c, float f[4])
    {
        f[0] = c->r;
        f[1] = c->g;
        f[2] = c->b;
        f[3] = c->a;
    }

    void set_float4(float f[4], float a, float b, float c, float d)
    {
        f[0] = a;
        f[1] = b;
        f[2] = c;
        f[3] = d;
    }

    // This function is taken from the examples coming with assimp
    void applyMaterial(const struct aiMaterial *mtl)
    {
        float c[4];

        GLenum fill_mode;
        int ret1, ret2;
        aiColor4D diffuse;
        aiColor4D specular;
        aiColor4D ambient;
        aiColor4D emission;
        float shininess, strength;
        int two_sided;
        int wireframe;
        unsigned int max;

        set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
            color4_to_float4(&diffuse, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);

        set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
            color4_to_float4(&specular, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);

        set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
            color4_to_float4(&ambient, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);

        set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
            color4_to_float4(&emission, c);
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);

        max = 1;
        ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
        if(ret1 == AI_SUCCESS) {
            max = 1;
            ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
            if(ret2 == AI_SUCCESS)
                glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
            else
                glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
        }
        else {
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
            set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
        }

        max = 1;
        if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
            fill_mode = wireframe ? GL_LINE : GL_FILL;
        else
            fill_mode = GL_FILL;
        glPolygonMode(GL_FRONT_AND_BACK, fill_mode);

        max = 1;
        if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
            glDisable(GL_CULL_FACE);
        else
            glEnable(GL_CULL_FACE);
    }

    // This function is taken from the examples coming with assimp
    void recursiveRender (const struct aiScene *sc, const struct aiNode* nd) {
        unsigned int i;
        unsigned int n = 0, t;
        aiMatrix4x4 m = nd->mTransformation;

        // update transform
        aiTransposeMatrix4(&m);
        glPushMatrix();
        glMultMatrixf((float*)&m);

        // draw all meshes assigned to this node
        for (; n < nd->mNumMeshes; ++n) {
            const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]];

            applyMaterial(sc->mMaterials[mesh->mMaterialIndex]);

            if(mesh->mNormals == NULL) {
                glDisable(GL_LIGHTING);
            } else {
                glEnable(GL_LIGHTING);
            }

            for (t = 0; t < mesh->mNumFaces; ++t) {
                const struct aiFace* face = &mesh->mFaces[t];
                GLenum face_mode;

                switch(face->mNumIndices) {
                    case 1: face_mode = GL_POINTS; break;
                    case 2: face_mode = GL_LINES; break;
                    case 3: face_mode = GL_TRIANGLES; break;
                    default: face_mode = GL_POLYGON; break;
                }

                glBegin(face_mode);

                for(i = 0; i < face->mNumIndices; i++) {
                    int index = face->mIndices[i];
                    if(mesh->mColors[0] != NULL)
                        glColor4fv((GLfloat*)&mesh->mColors[0][index]);
                    if(mesh->mNormals != NULL)
                        glNormal3fv(&mesh->mNormals[index].x);
                    glVertex3fv(&mesh->mVertices[index].x);
                }

                glEnd();
            }

        }

        // draw all children
        for (n = 0; n < nd->mNumChildren; ++n) {
            recursiveRender(sc, nd->mChildren[n]);
        }

        glPopMatrix();
    }

    void OpenGLRenderInterface::drawMesh(const Vector3d& _size, const aiScene *_mesh) {
        recursiveRender(_mesh, _mesh->mRootNode);
    }

    void OpenGLRenderInterface::setPenColor(const Vector4d& _col) {
        glColor4d(_col[0], _col[1], _col[2], _col[3]);
    }

    void OpenGLRenderInterface::setPenColor(const Vector3d& _col) {
        glColor4d(_col[0], _col[1], _col[2], 1.0);
    }

    void OpenGLRenderInterface::readFrameBuffer(DecoBufferType _buffType, DecoColorChannel _ch, void *_pixels) {

    }

    void OpenGLRenderInterface::saveToImage(const char *_filename, DecoBufferType _buffType) {

    }

} // namespace renderer
<|endoftext|>


<commit_before>#include "ncd_gateway.h"
#include "S3B.h"
#include "spark_wiring_eeprom.h"
#include "SparkJson/SparkJson.h"

S3B sModule;
String eventReturns[5];

int initCommands(JsonObject& root);

int i2c(JsonObject& root);
int s3b(JsonObject& root);

int sendEvent(String key){
    int i = key.toInt();
    String eventName = "";
    eventName = "eventReturn_"+key;
    Particle.publish(eventName, eventReturns[i], 60, PRIVATE);
    eventReturns[i] = "";
    return 1;
};
int setEventReturn(String value){
    int index = 0;
    while(eventReturns[index].length() > 1){
        index++;
    }
    eventReturns[index] = value;
    return index;
};

//i2c,32,writem,0,252|6,252

//S3B command format
//rs,0.19.162.0.65.2.32.216,wi,0,252|6,252

int gatewayCommand(String command){

    DynamicJsonBuffer jsonBuffer;

    Serial.println("Received: "+command);

    char commandData[command.length()+1];
    command.toCharArray(commandData, command.length()+1);

    //Parse incomming JSON
    JsonObject& root = jsonBuffer.parseObject(commandData);

    //Check to see if parsing Json object was successful.
    if(!root.success()){
        Serial.println("Failed to parse JSON");
        return 0;
    }
    for(int i = 0; i < root["root"].size(); i++){
        //Check type
        const char* typeChar = root["root"][i]["type"];
        String type = String(typeChar);
        Serial.println("type: "+type);

        if(type.equals("init")){
            initCommands(root["root"][i]);
        }
        if(type.equals("i2c")){
            Serial.println("I2C Command");
            i2c(root["root"][i]);
        }
        if(type.equals("s3b")){
            s3b(root["root"][i]);
        }
    }
    Serial.println("Done");
    return 0;
}

int bytesToInt(byte* b, int size){
    int val = 0;
    for(int i=3;i>-1;i--){
      val = val | b[i] << ((i)*8);
    }
    return val;
}

void dpm(String name, String arg){
    Serial.print(name);
    Serial.print(": ");
    Serial.println(arg);
}
void dpm(String name, int arg){
    Serial.print(name);
    Serial.print(": ");
    Serial.println(arg);
}

int i2c(JsonObject& root){
    int commandsRan = 0;
    for(int i = 0; i < root["args"].size(); i++){
        int addr = root["args"][i]["address"];
        Serial.printf("i2c sending command to address: %i data: ", addr);
        for(int j = 0; j < root["args"][i]["commands"].size(); j++){
            int data[root["args"][i]["commands"][j].size()];
            for(int k = 0; k < root["args"][i]["commands"][j].size(); k++){
                data[k] = root["args"][i]["commands"][j][k];
                Serial.printf("%i, ", data[k]);
            }
            Serial.println();
            writeCommandsI2C(addr, data, root["args"][i]["commands"][j].size());
            commandsRan++;
        }
    }
    Serial.printf("i2c Ran %i commands \n",commandsRan);
    return commandsRan;
}

int s3b(JsonObject& root){

}

//Returns the number of init commands stored to memory
//Format init,i2c,addr,write,arg1,arg2|i2c,addr,write,arg1,arg2
int initCommands(JsonObject& root){
    Serial.println("Init Command");

    char initCommandsToStore[255];
    root.printTo(initCommandsToStore, 255);
    String initCommandString = String(initCommandsToStore);
    Serial.printf("Length of initCommandString: %i \n", initCommandString.length());

    Serial.print("initCommand: ");
    Serial.println(initCommandsToStore);

    int sInd = 0;
    EEPROM.write(sInd, initCommandString.length());
    sInd++;
    for(int i = 0; i < initCommandString.length(); i++){
        EEPROM.write(sInd, initCommandsToStore[i]);
        sInd++;
    }
    Serial.printf("stored %i chars \n", sInd);
}

//Returns the number of init commands ran.
int runInitCommands(){
    if(EEPROM.read(0) == 255){
        Serial.println("No Init Commands Stored");
        return 0;
    }
    int numberOfCommandsRan = 0;

    int ind = 0;
    int commandStringLen = EEPROM.read(ind);
    ind++;
    char commandString[commandStringLen+1];
    for(int i = 0; i < commandStringLen; i++){
        commandString[i] = EEPROM.read(ind);
        ind++;
    }
    Serial.print("Stored Init: ");
    Serial.println(commandString);
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject(commandString);

    //Check to see if parsing Json object was successful.
    if(!root.success()){
        Serial.println("Failed to parse init JSON");
        return 0;
    }else{
        Serial.println("Parse init JSON success");
    }
    i2c(root);
    return numberOfCommandsRan;
}

int clearInit(String args){
    for(int i = 0; i < 2047; i++){
        EEPROM.write(i, 255);
    }
    return 1;
}

<commit_msg>Update ncd_gateway.cpp<commit_after>#include "ncd_gateway.h"
#include "S3B.h"
#include "spark_wiring_eeprom.h"

S3B sModule;
String eventReturns[5];
unsigned long tOut = 3000;

void commandHandler(const char *event, const char *data);

int gatewayCommand(String command);

int ncdApi(byte packetBytes[]);
void i2c_command(byte bytes[], byte *buff);

void array_slice(byte bytes[], int start, int len, byte *buff);
void array_slice(byte bytes[], int start, int len, int *buff);

void init_gateway();

//int s3b(JsonObject& root);

void init_gateway(){
    Particle.function("deviceComm", gatewayCommand);
    Particle.subscribe("ncd_deviceCom", commandHandler, MY_DEVICES);
    Serial1.begin(115200);
    Wire.begin();
}

int gatewayCommand(String arg){
    int length = arg.length();
    byte bytes[length+1];
    arg.getBytes(bytes, length+1);
    //send int pointer for setting to allow me to test how to return results?
    return ncdApi(bytes);
}

void commandHandler(const char *event, const char *data){
    Serial.println("Got Event "+String(event));
    String newCommand = String(data);
    gatewayCommand(newCommand);
}
int ncdApi(byte packetBytes[]){
    int buffLen = 1;
    Serial.println(String(packetBytes[0]));
    switch(packetBytes[0]){
        case 187:
            {
                //packet of packets
                int i=2;
                int max;
                for(int pn = 0; pn<packetBytes[1]; pn++){

                    max=i+packetBytes[i];
                    Serial.println(max);
                    byte intPacket[packetBytes[i]];
                    i++;
                    int ni=0;
                    for(i;i<=max;i++){
                        intPacket[ni]=packetBytes[i];
                        ni++;
                    }
                    ncdApi(intPacket);
                }
                break;
            }
        case 188:
            {
                //plain i2c w/r command
                if(packetBytes[3] > 0){
                    buffLen = packetBytes[3];
                }
                byte buff[buffLen];
                i2c_command(packetBytes, buff);
                break;
            }
        case 189:
            {
                //masking command
                int addr = packetBytes[1];
                int maskOp = packetBytes[2];
                int maskedOffsets = packetBytes[3];
                int readCommandLen = packetBytes[4];
                int readLen = packetBytes[5];
                int readCommand[readCommandLen];

                array_slice(packetBytes, 6, readCommandLen, readCommand);

                int writeCommandLen = packetBytes[6+readCommandLen];
                int writeCommand[writeCommandLen];

                array_slice(packetBytes, 7+readCommandLen, writeCommandLen, writeCommand);

                int writeVals[writeCommandLen];
                int wi=0;
                for(wi; wi<maskedOffsets; wi++){
                    writeVals[wi]=writeCommand[wi];
                    Serial.println(writeVals[wi]);
                }

                writeCommandsI2C(addr, readCommand, readCommandLen);
                Wire.requestFrom(addr, readLen);
                for(int i=0;i<readLen;i++){
                    int current = Wire.read();
                    writeVals[wi] = mask(current, writeCommand[wi], maskOp);
                    Serial.println(current);
                    Serial.println(writeVals[wi]);
                    wi++;
                }

                writeCommandsI2C(addr, writeVals, writeCommandLen);
                break;
            }
    }
    return 1;
}
int mask(int val, int mask, int type){
    switch(type){
        case 0:
            val |= mask;
            break;
        case 1:
            val &= mask;
            break;
        case 2:
            val ^= mask;
            break;
        case 3:
            val = val << mask;
            break;
        case 4:
            val = val >> mask;
    }
    return val;
}
void i2c_command(byte bytes[], byte *buff){
    if(bytes[0] == 188){
        int commands[bytes[2]];
        array_slice(bytes, 4, bytes[2], commands);
        int addr = bytes[1];
        if(bytes[3] == 0){
            //write command
            buff[0]=writeCommandsI2C(addr, commands, bytes[2]);
        }else{
            //read command
            writeCommandsI2C(addr, commands, bytes[2]);
            Wire.requestFrom(addr, bytes[3]);
            for(int i=0;i<bytes[3];i++){
                buff[i] = Wire.read();
            }
        }
    }
}
void array_slice(byte bytes[], int start, int len, byte *buff){
    int ni = 0;
    int end = start+len;
    for(int i=start; i<=end; i++){
        buff[ni] = bytes[i];
        ni++;
    }
}
void array_slice(byte bytes[], int start, int len, int *buff){
    int ni=0;
    int end = start+len;
    for(int i=start; i<=end; i++){
        buff[ni] = bytes[i];
        ni++;
    }
}
int sendEvent(String key){
    int i = key.toInt();
    String eventName = "";
    eventName = "eventReturn_"+key;
    Particle.publish(eventName, eventReturns[i], 60, PRIVATE);
    eventReturns[i] = "";
    return 1;
};
int setEventReturn(String value){
    int index = 0;
    while(eventReturns[index].length() > 1){
        index++;
    }
    eventReturns[index] = value;
    return index;
};
<|endoftext|>


<commit_before>#include <ros.h>
#include <string.h>

#include "MS5837.h"
#include "Adafruit_BNO055.h"
#include "Adafruit_Sensor.h"
#include "DallasTemperature.h"
#include <Wire.h>

#include "std_msgs/String.h"
#include <geometry_msgs/Vector3.h>
#include "sensor_msgs/Imu.h"
#include "sensor_msgs/MagneticField.h"
#include "sensor_msgs/Temperature.h"
#include "sensor_msgs/FluidPressure.h"

#define STANDARD_GRAVITY 9.08665      // [m/s^2]
#define RAD_PER_DEG 0.01745329252     // [1/deg]
#define PASCAL_PER_MILLIBAR 0.01      // [Pa/mbar]
#define MICROTESLA_PER_TESLA 0.000001 // [uT/T]

int id = -1;

ros::NodeHandle nh;

sensor_msgs::Imu imu_raw_msg;
sensor_msgs::MagneticField compass_msg;

sensor_msgs::Temperature imu_temperature_msg;
sensor_msgs::Temperature sensor_temperature_msg;
sensor_msgs::FluidPressure pressure_msg;

std_msgs::String calibration;

ros::Publisher pub_imu("imu/data", &imu_raw_msg);
ros::Publisher pub_mag("imu/mag", &compass_msg);

ros::Publisher pub_pressure("imu/pressure", &pressure_msg);
ros::Publisher pub_imu_temperature("imu/temperature", &imu_temperature_msg);
ros::Publisher pub_sensor_temperature("sensor/temperature", &sensor_temperature_msg);

ros::Publisher pub_calibration("imu/calibration", &calibration);

const int SensorReadDelay = 40;
unsigned long PrevoiusSensorReadMillis = 0;

int dbg_count = 0;

MS5837 barometer;
Adafruit_BNO055 bno055 = Adafruit_BNO055(55);

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

// double GyroLsbSens, AccelLsbSens;
void setupIMU();

void setup() {

    //start ROS-node
    nh.initNode();

    // nh.advertise(pub_dbg);
    nh.advertise(pub_imu_temperature);
    nh.advertise(pub_sensor_temperature);

    nh.advertise(pub_pressure);
    nh.advertise(pub_imu);
    nh.advertise(pub_mag);
    nh.advertise(pub_calibration);

    // Initialize the 'Wire' class for communicating over i2c
    Wire.begin();
    barometer.init();
    barometer.read();

    setupIMU();
    // nh.advertise(pub_mag);
}

void setupIMU() {

    /*
        Sets opmode to NDOF by default

        From Adafruit_BNO055.h:

        OPERATION_MODE_CONFIG                                   = 0X00,
        OPERATION_MODE_ACCONLY                                  = 0X01,
        OPERATION_MODE_MAGONLY                                  = 0X02,
        OPERATION_MODE_GYRONLY                                  = 0X03,
        OPERATION_MODE_ACCMAG                                   = 0X04,
        OPERATION_MODE_ACCGYRO                                  = 0X05,
        OPERATION_MODE_MAGGYRO                                  = 0X06,
        OPERATION_MODE_AMG                                      = 0X07,
        OPERATION_MODE_IMUPLUS                                  = 0X08,
        OPERATION_MODE_COMPASS                                  = 0X09,
        OPERATION_MODE_M4G                                      = 0X0A,
        OPERATION_MODE_NDOF_FMC_OFF                             = 0X0B,
        OPERATION_MODE_NDOF                                     = 0X0C

                    ACCEL   MAG     GYRO    RELATIVE        ABSOLUTE
                                            ORIENTATION     ORIENTATION
        ---------------------------------------------------------------
        IMU     |    X    |   -    |   X  |       X        |     -
        COMPASS |    X    |   X    |   -  |       -        |     X
        M4G     |    X    |   X    |   -  |       X        |     -
        NDOF    |    X    |   X    |   X  |       -        |     X
    */

    id = bno055.begin(bno055.OPERATION_MODE_IMUPLUS);
    bno055.setAxisSign(bno055.REMAP_SIGN_P4);
}

void getPressure() {

    // float pressure = barometer.pressure();
    float pressure = barometer.pressure();
    pressure_msg.fluid_pressure = pressure * 100;
    pub_pressure.publish(&pressure_msg);

}

#define BARO 10
int baro_counter = 0;
void getBarometerTemp() {

    if(baro_counter < BARO){
        baro_counter++;
        return;
    }
    else{
        baro_counter = 0;
    }

    float temp = barometer.temperature();
    imu_temperature_msg.temperature = temp;

    pub_imu_temperature.publish(&imu_temperature_msg);

}

#define DALL 10
int dallas_counter = 50;
void getDallasTemp() {

    if(dallas_counter < DALL){
        dallas_counter++;
        return;
    }
    else{
        dallas_counter = 0;
    }

    sensors.requestTemperatures();
    float temp = sensors.getTempCByIndex(0);
    sensor_temperature_msg.temperature = temp;

    pub_sensor_temperature.publish(&sensor_temperature_msg);

}

void getRawIMU() {

    // sensors_event_t event;
    // bno055.getEvent(&event);

    imu::Vector<3> gyro = bno055.getVector(bno055.VECTOR_GYROSCOPE);
    imu_raw_msg.linear_acceleration.x = gyro[0];
    imu_raw_msg.linear_acceleration.y = gyro[1];
    imu_raw_msg.linear_acceleration.z = gyro[2];

    imu::Vector<3> lin_acc = bno055.getVector(bno055.VECTOR_LINEARACCEL);
    imu_raw_msg.angular_velocity.x = lin_acc[0];
    imu_raw_msg.angular_velocity.y = lin_acc[1];
    imu_raw_msg.angular_velocity.z = lin_acc[2];

    imu::Quaternion qs = bno055.getQuat();
    imu_raw_msg.orientation.x = qs.x();
    imu_raw_msg.orientation.y = qs.y();
    imu_raw_msg.orientation.z = qs.z();
    imu_raw_msg.orientation.w = qs.w();

    imu_raw_msg.header.stamp = ros::Time(millis()/1000.0, 0);
    pub_imu.publish(&imu_raw_msg);

}

bool calibrated = false;

void getCalibrationStatus(){

    // lol
    uint8_t sys, gyro, accel, mag;
    sys = gyro = accel = mag = 0;
    bno055.getCalibration(&sys, &gyro, &accel, &mag);
    char buffer[128] = { '\0' };

    if (sys == 3 && gyro == 3 && accel == 3 && mag == 3){
        if(!calibrated){
            sprintf(buffer, "\n All systems go\n");
            calibrated = true;
        }
        return;
    }

    calibrated = false;
    sprintf(buffer, "\nSys: %d, Gyro: %d, Acc: %d, mag: %d\n", sys, gyro, accel, mag);
    String s = String(buffer);
    calibration.data = s.c_str();
    pub_calibration.publish(&calibration);

}

void loop(){

    nh.spinOnce();

    if( millis() - PrevoiusSensorReadMillis >= SensorReadDelay ) {

        PrevoiusSensorReadMillis = millis();

        barometer.read();
        nh.spinOnce();

        getPressure();
        nh.spinOnce();

        getBarometerTemp();
        nh.spinOnce();

        getDallasTemp();
        nh.spinOnce();

        getRawIMU();
        nh.spinOnce();

        getCalibrationStatus();
        nh.spinOnce();

    }
}

<commit_msg>attemt to config before axis re-sign<commit_after>#include <ros.h>
#include <string.h>

#include "MS5837.h"
#include "Adafruit_BNO055.h"
#include "Adafruit_Sensor.h"
#include "DallasTemperature.h"
#include <Wire.h>

#include "std_msgs/String.h"
#include <geometry_msgs/Vector3.h>
#include "sensor_msgs/Imu.h"
#include "sensor_msgs/MagneticField.h"
#include "sensor_msgs/Temperature.h"
#include "sensor_msgs/FluidPressure.h"

#define STANDARD_GRAVITY 9.08665      // [m/s^2]
#define RAD_PER_DEG 0.01745329252     // [1/deg]
#define PASCAL_PER_MILLIBAR 0.01      // [Pa/mbar]
#define MICROTESLA_PER_TESLA 0.000001 // [uT/T]

int id = -1;

ros::NodeHandle nh;

sensor_msgs::Imu imu_raw_msg;
sensor_msgs::MagneticField compass_msg;

sensor_msgs::Temperature imu_temperature_msg;
sensor_msgs::Temperature sensor_temperature_msg;
sensor_msgs::FluidPressure pressure_msg;

std_msgs::String calibration;

ros::Publisher pub_imu("imu/data", &imu_raw_msg);
ros::Publisher pub_mag("imu/mag", &compass_msg);

ros::Publisher pub_pressure("imu/pressure", &pressure_msg);
ros::Publisher pub_imu_temperature("imu/temperature", &imu_temperature_msg);
ros::Publisher pub_sensor_temperature("sensor/temperature", &sensor_temperature_msg);

ros::Publisher pub_calibration("imu/calibration", &calibration);

const int SensorReadDelay = 40;
unsigned long PrevoiusSensorReadMillis = 0;

int dbg_count = 0;

MS5837 barometer;
Adafruit_BNO055 bno055 = Adafruit_BNO055(55);

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

// double GyroLsbSens, AccelLsbSens;
void setupIMU();

void setup() {

    //start ROS-node
    nh.initNode();

    // nh.advertise(pub_dbg);
    nh.advertise(pub_imu_temperature);
    nh.advertise(pub_sensor_temperature);

    nh.advertise(pub_pressure);
    nh.advertise(pub_imu);
    nh.advertise(pub_mag);
    nh.advertise(pub_calibration);

    // Initialize the 'Wire' class for communicating over i2c
    Wire.begin();
    barometer.init();
    barometer.read();

    setupIMU();
    // nh.advertise(pub_mag);
}

void setupIMU() {

    /*
        Sets opmode to NDOF by default

        From Adafruit_BNO055.h:

        OPERATION_MODE_CONFIG                                   = 0X00,
        OPERATION_MODE_ACCONLY                                  = 0X01,
        OPERATION_MODE_MAGONLY                                  = 0X02,
        OPERATION_MODE_GYRONLY                                  = 0X03,
        OPERATION_MODE_ACCMAG                                   = 0X04,
        OPERATION_MODE_ACCGYRO                                  = 0X05,
        OPERATION_MODE_MAGGYRO                                  = 0X06,
        OPERATION_MODE_AMG                                      = 0X07,
        OPERATION_MODE_IMUPLUS                                  = 0X08,
        OPERATION_MODE_COMPASS                                  = 0X09,
        OPERATION_MODE_M4G                                      = 0X0A,
        OPERATION_MODE_NDOF_FMC_OFF                             = 0X0B,
        OPERATION_MODE_NDOF                                     = 0X0C

                    ACCEL   MAG     GYRO    RELATIVE        ABSOLUTE
                                            ORIENTATION     ORIENTATION
        ---------------------------------------------------------------
        IMU     |    X    |   -    |   X  |       X        |     -
        COMPASS |    X    |   X    |   -  |       -        |     X
        M4G     |    X    |   X    |   -  |       X        |     -
        NDOF    |    X    |   X    |   X  |       -        |     X
    */

    id = bno055.begin(bno055.OPERATION_MODE_CONFIG);
    bno055.setAxisSign(bno055.REMAP_SIGN_P4);
    bno055.setMode(bno055.OPERATION_MODE_IMUPLUS);
}

void getPressure() {

    // float pressure = barometer.pressure();
    float pressure = barometer.pressure();
    pressure_msg.fluid_pressure = pressure * 100;
    pub_pressure.publish(&pressure_msg);

}

#define BARO 10
int baro_counter = 0;
void getBarometerTemp() {

    if(baro_counter < BARO){
        baro_counter++;
        return;
    }
    else{
        baro_counter = 0;
    }

    float temp = barometer.temperature();
    imu_temperature_msg.temperature = temp;

    pub_imu_temperature.publish(&imu_temperature_msg);

}

#define DALL 10
int dallas_counter = 50;
void getDallasTemp() {

    if(dallas_counter < DALL){
        dallas_counter++;
        return;
    }
    else{
        dallas_counter = 0;
    }

    sensors.requestTemperatures();
    float temp = sensors.getTempCByIndex(0);
    sensor_temperature_msg.temperature = temp;

    pub_sensor_temperature.publish(&sensor_temperature_msg);

}

void getRawIMU() {

    // sensors_event_t event;
    // bno055.getEvent(&event);

    imu::Vector<3> gyro = bno055.getVector(bno055.VECTOR_GYROSCOPE);
    imu_raw_msg.linear_acceleration.x = gyro[0];
    imu_raw_msg.linear_acceleration.y = gyro[1];
    imu_raw_msg.linear_acceleration.z = gyro[2];

    imu::Vector<3> lin_acc = bno055.getVector(bno055.VECTOR_LINEARACCEL);
    imu_raw_msg.angular_velocity.x = lin_acc[0];
    imu_raw_msg.angular_velocity.y = lin_acc[1];
    imu_raw_msg.angular_velocity.z = lin_acc[2];

    imu::Quaternion qs = bno055.getQuat();
    imu_raw_msg.orientation.x = qs.x();
    imu_raw_msg.orientation.y = qs.y();
    imu_raw_msg.orientation.z = qs.z();
    imu_raw_msg.orientation.w = qs.w();

    imu_raw_msg.header.stamp = ros::Time(millis()/1000.0, 0);
    pub_imu.publish(&imu_raw_msg);

}

bool calibrated = false;

void getCalibrationStatus(){

    // lol
    uint8_t sys, gyro, accel, mag;
    sys = gyro = accel = mag = 0;
    bno055.getCalibration(&sys, &gyro, &accel, &mag);
    char buffer[128] = { '\0' };

    if (sys == 3 && gyro == 3 && accel == 3 && mag == 3){
        if(!calibrated){
            sprintf(buffer, "\n All systems go\n");
            calibrated = true;
        }
        return;
    }

    calibrated = false;
    sprintf(buffer, "\nSys: %d, Gyro: %d, Acc: %d, mag: %d\n", sys, gyro, accel, mag);
    String s = String(buffer);
    calibration.data = s.c_str();
    pub_calibration.publish(&calibration);

}

void loop(){

    nh.spinOnce();

    if( millis() - PrevoiusSensorReadMillis >= SensorReadDelay ) {

        PrevoiusSensorReadMillis = millis();

        barometer.read();
        nh.spinOnce();

        getPressure();
        nh.spinOnce();

        getBarometerTemp();
        nh.spinOnce();

        getDallasTemp();
        nh.spinOnce();

        getRawIMU();
        nh.spinOnce();

        getCalibrationStatus();
        nh.spinOnce();

    }
}

<|endoftext|>


<commit_before>// MIT License
//
// Copyright (c) 2017 Artur Wyszyński, aljen at hitomi dot pl
//
// 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 <QApplication>
#include <QObject>
#include <QStyleFactory>
#include <iostream>

#include "core/registry.h"
#include "core/version.h"
#include "ui/editor.h"

int main(int argc, char **argv)
{
  std::cerr << "Spaghetti version: " << core::version::STRING
            << ", git: " << core::version::BRANCH << '@' << core::version::COMMIT_SHORT_HASH
            << ", build date: " << __DATE__ << ", " << __TIME__ << '\n';

  QApplication app{ argc, argv };
  app.setStyle(QStyleFactory::create("Fusion"));

  QPalette darkPalette;
  darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::WindowText, Qt::white);
  darkPalette.setColor(QPalette::Base, QColor(25, 25, 25));
  darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
  darkPalette.setColor(QPalette::ToolTipText, Qt::white);
  darkPalette.setColor(QPalette::Text, Qt::white);
  darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::ButtonText, Qt::white);
  darkPalette.setColor(QPalette::BrightText, Qt::red);
  darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
  darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
  darkPalette.setColor(QPalette::HighlightedText, Qt::black);
  app.setPalette(darkPalette);
  app.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }");

  std::locale::global(std::locale("C"));

  core::Registry &registry{ core::Registry::get() };
  registry.registerInternalElements();
  registry.loadPlugins();

  Editor editor{};
  QObject::connect(&app, &QApplication::aboutToQuit, &editor, &Editor::aboutToQuit);
  editor.show();
  // editor.showMaximized();

  return app.exec();
}
<commit_msg>Remove version output in main.cc<commit_after>// MIT License
//
// Copyright (c) 2017 Artur Wyszyński, aljen at hitomi dot pl
//
// 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 <QApplication>
#include <QObject>
#include <QStyleFactory>
#include <iostream>

#include "core/registry.h"
#include "ui/editor.h"

int main(int argc, char **argv)
{
  QApplication app{ argc, argv };
  app.setStyle(QStyleFactory::create("Fusion"));

  QPalette darkPalette;
  darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::WindowText, Qt::white);
  darkPalette.setColor(QPalette::Base, QColor(25, 25, 25));
  darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
  darkPalette.setColor(QPalette::ToolTipText, Qt::white);
  darkPalette.setColor(QPalette::Text, Qt::white);
  darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
  darkPalette.setColor(QPalette::ButtonText, Qt::white);
  darkPalette.setColor(QPalette::BrightText, Qt::red);
  darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
  darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
  darkPalette.setColor(QPalette::HighlightedText, Qt::black);
  app.setPalette(darkPalette);
  app.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }");

  std::locale::global(std::locale("C"));

  core::Registry &registry{ core::Registry::get() };
  registry.registerInternalElements();
  registry.loadPlugins();

  Editor editor{};
  QObject::connect(&app, &QApplication::aboutToQuit, &editor, &Editor::aboutToQuit);
  editor.show();
  // editor.showMaximized();

  return app.exec();
}
<|endoftext|>