<commit_before>#include "WarlordState.h"

WarlordState::WarlordState()
{
}

WarlordState::~WarlordState()
{
}

void WarlordState::Init(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	int redBuildings = 0;
	for (size_t i = 0, blen = player->GetBuildings()->Size(); i < blen; ++i) {
		if (player->GetBuildings()->ShowCardByIndex(i).GetColor() == 4)
			redBuildings++;
	}
	if (redBuildings > 0) {
		int gold = game->RemoveGold(redBuildings);
		if (gold != -1) {
			player->AddGold(gold);
			player->GetClient()->writeline("You receive 1 gold coin for each red building, " + std::to_string(gold) + " gold received!");
		}
	}
	else {
		player->GetClient()->writeline("You do not own any red buildings and therefor receive no gold");
	}
}

void WarlordState::Cleanup(shared_ptr<Player> &player, shared_ptr<Game> &game)
{

}

void WarlordState::HandleEvents(shared_ptr<Player> &player, shared_ptr<Game> &game)
{

}

void WarlordState::Update(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	Render(player, "Warlord");
	ResetChoices(player, game);
	_endTurn = false;
	int choice = -1;
	while (!_endTurn) {
		do {
			RenderChoices(player);
			choice = HandleChoice(player, game, GetNumberOfChoices() - 1);
		} while (choice == -1);
		HandleTurn(player, game, choice);
	}
}

void WarlordState::UseAbility(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	if (game->GetOpponent(player)->GetBuildings()->Size() >= 8) {
		player->GetClient()->writeline("Your opponent has built 8 or more buildings, you are not allowed to destroy his buildings!");
	}
	else if (game->GetOpponent(player)->HasCharacterCard("Bishop")) {
		player->GetClient()->writeline("Your opponent has the bishop card, you are not allowed to destroy his buildings!");
	}
	else {
		// Print opponent cards
		LookAtOpponent(player, game);

		player->GetClient()->writeline("Which building do you want to destroy?");

		int choice = -1;
		do {
			choice = HandleChoice(player, game, player->GetBuildings()->Size() - 1);
		} while (choice == -1);

		BuildingCard destroy = game->GetOpponent(player)->GetBuildings()->ShowCardByIndex(choice);
		if (destroy.GetName() == "Dungeon")
			player->GetClient()->writeline("A dungeon cannot be destroyed!");
		else {
			if (destroy.GetValue() == 1)
				game->GetOpponent(player)->DestroyByIndex(choice);
			else  {
				int cost = destroy.GetValue() - 1;
				if (player->GetGoldAmount() >= cost) {
					// Player has enough gold to destroy building
					player->RemoveGold(cost);
					game->AddGold(cost);
					game->GetOpponent(player)->DestroyByIndex(choice);
					player->GetClient()->writeline("Building destroyed!");
				}
				else {
					// Not enough gold to destroy this building
					player->GetClient()->writeline("Not enough gold available to destroy this building!");
				}
			}
		}
	}
}<commit_msg>restock card after destroy<commit_after>#include "WarlordState.h"

WarlordState::WarlordState()
{
}

WarlordState::~WarlordState()
{
}

void WarlordState::Init(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	int redBuildings = 0;
	for (size_t i = 0, blen = player->GetBuildings()->Size(); i < blen; ++i) {
		if (player->GetBuildings()->ShowCardByIndex(i).GetColor() == 4)
			redBuildings++;
	}
	if (redBuildings > 0) {
		int gold = game->RemoveGold(redBuildings);
		if (gold != -1) {
			player->AddGold(gold);
			player->GetClient()->writeline("You receive 1 gold coin for each red building, " + std::to_string(gold) + " gold received!");
		}
	}
	else {
		player->GetClient()->writeline("You do not own any red buildings and therefor receive no gold");
	}
}

void WarlordState::Cleanup(shared_ptr<Player> &player, shared_ptr<Game> &game)
{

}

void WarlordState::HandleEvents(shared_ptr<Player> &player, shared_ptr<Game> &game)
{

}

void WarlordState::Update(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	Render(player, "Warlord");
	ResetChoices(player, game);
	_endTurn = false;
	int choice = -1;
	while (!_endTurn) {
		do {
			RenderChoices(player);
			choice = HandleChoice(player, game, GetNumberOfChoices() - 1);
		} while (choice == -1);
		HandleTurn(player, game, choice);
	}
}

void WarlordState::UseAbility(shared_ptr<Player> &player, shared_ptr<Game> &game)
{
	if (game->GetOpponent(player)->GetBuildings()->Size() >= 8) {
		player->GetClient()->writeline("Your opponent has built 8 or more buildings, you are not allowed to destroy his buildings!");
	}
	else if (game->GetOpponent(player)->HasCharacterCard("Bishop")) {
		player->GetClient()->writeline("Your opponent has the bishop card, you are not allowed to destroy his buildings!");
	}
	else {
		// Print opponent cards
		LookAtOpponent(player, game);

		player->GetClient()->writeline("Which building do you want to destroy?");

		int choice = -1;
		do {
			choice = HandleChoice(player, game, player->GetBuildings()->Size() - 1);
		} while (choice == -1);

		BuildingCard destroy = game->GetOpponent(player)->GetBuildings()->ShowCardByIndex(choice);
		if (destroy.GetName() == "Dungeon")
			player->GetClient()->writeline("A dungeon cannot be destroyed!");
		else {
			if (destroy.GetValue() == 1)
				game->GetOpponent(player)->DestroyByIndex(choice);
			else  {
				int cost = destroy.GetValue() - 1;
				if (player->GetGoldAmount() >= cost) {
					// Player has enough gold to destroy building
					player->RemoveGold(cost);
					game->AddGold(cost);
					BuildingCard card = game->GetOpponent(player)->GetBuildings()->GetCardByIndex(choice);
					game->AddBuildingCard(card);
					player->GetClient()->writeline("Building destroyed!");
				}
				else {
					// Not enough gold to destroy this building
					player->GetClient()->writeline("Not enough gold available to destroy this building!");
				}
			}
		}
	}
}<|endoftext|>


<commit_before>#include <sirius.h>

using namespace sirius;

// backward and forward transform of a random array
void test1()
{
    std::cout << "test1" << std::endl;
    sirius::Global global;

    double a1[] = {10, 10, 0};
    double a2[] = {0, 8, 3};
    double a3[] = {1, 7, 15};
    //double a1[] = {42, 42, 0};
    //double a2[] = {42, 0, 42};
    //double a3[] = {0, 42, 42};

    global.set_lattice_vectors(a1, a2, a3);
    global.set_pw_cutoff(20.0);
    global.add_atom_type(1, "H");
    double pos[] = {0, 0, 0};
    double vf[] = {0, 0, 0};

    global.add_atom(1, pos, vf);

    global.initialize();

    std::cout << "grid size : " << global.fft().size() << std::endl;
    std::cout << "dimensions : " << global.fft().size(0) << " "
                                 << global.fft().size(1) << " "
                                 << global.fft().size(2) << std::endl;

    std::vector<complex16> fft1(global.fft().size());
    std::vector<complex16> fft2(global.fft().size());

    for (int i = 0; i < global.fft().size(); i++)
    {
        fft1[i] = complex16(double(rand()) / RAND_MAX, double(rand()) / RAND_MAX);
        fft2[i] = fft1[i];
    }

    sirius::Timer* t = new sirius::Timer(std::string("test1"));
    global.fft().input(&fft1[0]);
    global.fft().transform(-1);
    global.fft().output(&fft1[0]);

    global.fft().input(&fft1[0]);
    global.fft().transform(1);
    global.fft().output(&fft1[0]);

    delete t;

    double d = 0.0;
    for (int i = 0; i < global.fft().size(); i++)
        d += abs(fft1[i] - fft2[i]);

    std::cout << "total diff : " << d << std::endl;
}

// transform of a single harmonic and comparison with an exact value
void test2()
{
    std::cout << "test2" << std::endl;
    double a1[] = {10, 0, -7};
    double a2[] = {0, 10, 20};
    double a3[] = {-9, -11, 10};

    sirius::Global global;

    global.set_lattice_vectors(a1, a2, a3);
    global.set_pw_cutoff(10.0);

    global.add_atom_type(1, "H");
    double pos[] = {0, 0, 0};
    double vf[] = {0, 0, 0};

    global.add_atom(1, pos, vf);

    global.initialize();

    std::cout << "grid size : " << global.fft().size() << std::endl;

    double d = 0.0;

    std::vector<complex16> fft1(global.fft().size());
    for (int i0 = -2; i0 <= 2; i0++)
        for (int i1 = -2; i1 <= 2; i1++)
            for (int i2 = -2; i2 <= 2; i2++)
            {
                memset(&fft1[0], 0, fft1.size() * sizeof(complex16));
                fft1[global.fft().index(i0, i1, i2)] = complex16(1.0, 0.0);
                global.fft().input(&fft1[0]);
                global.fft().transform(1);
                global.fft().output(&fft1[0]);

                double gv[3];
                int fgv[] = {i0, i1, i2};
                global.get_coordinates<cartesian, reciprocal>(fgv, gv);

                mdarray<complex16,3> fft2(&fft1[0], global.fft().size(0), global.fft().size(1), global.fft().size(2));
                for (int j0 = 0; j0 < global.fft().size(0); j0++)
                    for (int j1 = 0; j1 < global.fft().size(1); j1++)
                        for (int j2 = 0; j2 < global.fft().size(2); j2++)
                        {
                            double frv[] = {double(j0) / global.fft().size(0),
                                            double(j1) / global.fft().size(1),
                                            double(j2) / global.fft().size(2)};
                            double rv[3];
                            global.get_coordinates<cartesian, direct>(frv, rv);
                            d += abs(fft2(j0, j1, j2) - exp(complex16(0.0, Utils::scalar_product(rv, gv))));
                        }
            }

    std::cout << "total diff : " << d << std::endl;
}

int main(int argn, char **argv)
{
    Platform::initialize(1);
    test1();
    test2();
    sirius::Timer::print();
}
<commit_msg>clean fft test<commit_after>#include <sirius.h>

using namespace sirius;

// backward and forward transform of a random array
void test1()
{
    printf("\ntest1: backward and forward transform of a random array\n");

    Global global;

    double a1[] = {10, 10, 0};
    double a2[] = {0, 8, 3};
    double a3[] = {1, 7, 15};

    global.set_lattice_vectors(a1, a2, a3);
    global.set_pw_cutoff(20.0);
    global.add_atom_type(1, "Si");
    double pos[] = {0, 0, 0};

    global.add_atom(1, pos);

    global.initialize(1);

    global.Reciprocal_lattice::print_info();

    std::vector<complex16> fft1(global.fft().size());
    std::vector<complex16> fft2(global.fft().size());

    for (int i = 0; i < global.fft().size(); i++)
    {
        fft1[i] = complex16(double(rand()) / RAND_MAX, double(rand()) / RAND_MAX);
        fft2[i] = fft1[i];
    }

    Timer t("fft::transform|-1,+1");
    global.fft().input(&fft1[0]);
    global.fft().transform(-1);
    global.fft().output(&fft1[0]);

    global.fft().input(&fft1[0]);
    global.fft().transform(1);
    global.fft().output(&fft1[0]);
    t.stop();

    double d = 0.0;
    for (int i = 0; i < global.fft().size(); i++) d += pow(abs(fft1[i] - fft2[i]), 2);
    d = sqrt(d / global.fft().size());
    printf("\nRMS difference : %18.10e", d);
    if (d < 1e-10)
    {
        printf("  OK\n");
    }
    else
    {
        printf("  Fail\n");
    }

    Timer::print();
    Timer::clear();
}

void test2()
{
    printf("\ntest2: straightforward transform of a single harmonic and comparison with FFT result\n");
    double a1[] = {10, 0, -7};
    double a2[] = {0, 10, 20};
    double a3[] = {-9, -11, 10};

    Global global;

    global.set_lattice_vectors(a1, a2, a3);
    global.set_pw_cutoff(10.0);

    global.add_atom_type(1, "Si");
    double pos[] = {0, 0, 0};

    global.add_atom(1, pos);

    global.initialize(1);

    global.Reciprocal_lattice::print_info();
    printf("\n");

    std::vector<complex16> fft1(global.fft().size());

    // loop over lowest harmonics in reciprocal space
    for (int i0 = -2; i0 <= 2; i0++)
    {
        for (int i1 = -2; i1 <= 2; i1++)
        {
            for (int i2 = -2; i2 <= 2; i2++)
            {
                double d = 0.0;

                memset(&fft1[0], 0, fft1.size() * sizeof(complex16));
                // load a single harmonic
                fft1[global.fft().index(i0, i1, i2)] = complex16(1.0, 0.0);
                global.fft().input(&fft1[0]);
                global.fft().transform(1);
                global.fft().output(&fft1[0]);

                double gv[3];
                int fgv[] = {i0, i1, i2};
                global.get_coordinates<cartesian, reciprocal>(fgv, gv);

                // map FFT buffer to a 3D array
                mdarray<complex16, 3> fft2(&fft1[0], global.fft().size(0), global.fft().size(1), global.fft().size(2));

                // loop over 3D array (real space)
                for (int j0 = 0; j0 < global.fft().size(0); j0++)
                {
                    for (int j1 = 0; j1 < global.fft().size(1); j1++)
                    {
                        for (int j2 = 0; j2 < global.fft().size(2); j2++)
                        {
                            // get real space fractional coordinate
                            double frv[] = {double(j0) / global.fft().size(0),
                                            double(j1) / global.fft().size(1),
                                            double(j2) / global.fft().size(2)};
                            double rv[3];
                            global.get_coordinates<cartesian, direct>(frv, rv);
                            d += pow(abs(fft2(j0, j1, j2) - exp(complex16(0.0, Utils::scalar_product(rv, gv)))), 2);
                        }
                    }
                }
                d = sqrt(d / global.fft().size());
                printf("harmonic %4i %4i %4i, RMS difference : %18.10e", i0, i1, i2, d);
                if (d < 1e-10)
                {
                    printf("  OK\n");
                }
                else
                {
                    printf("  Fail\n");
                }
            }
        }
    }

    Timer::print();
    Timer::clear();
}

void test3()
{
    printf("\ntest3: show timers for large unit cell FFT\n");
    double a1[] = {60, 0, 0};
    double a2[] = {0, 60, 0};
    double a3[] = {0, 0, 60};
    Global global;

    global.set_lattice_vectors(a1, a2, a3);
    global.set_pw_cutoff(9.0);
    global.add_atom_type(1, "Si");
    double pos[] = {0, 0, 0};

    global.add_atom(1, pos);
    global.initialize(1);
    global.Reciprocal_lattice::print_info();

    Timer t("fft::transform");
    global.fft().transform(1);
    t.stop();

    Timer::print();
    Timer::clear();
}

int main(int argn, char **argv)
{
    Platform::set_num_fft_threads(1);
    Platform::initialize(1);
    test1();
    test2();
    test3();
}
<|endoftext|>


<commit_before>/*
    Auto away-presence setter-class
    Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>

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

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

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

#include "autoaway.h"

#include <TelepathyQt4/AccountManager>
#include <TelepathyQt4/AccountSet>

#include <KDebug>
#include <KIdleTime>
#include <KConfig>
#include <KConfigGroup>

#include "common/global-presence.h"

AutoAway::AutoAway(GlobalPresence* globalPresence, QObject* parent)
    : TelepathyKDEDModulePlugin(globalPresence, parent),
      m_awayTimeoutId(-1),
      m_extAwayTimeoutId(-1)
{
    setPluginPriority(99);
    readConfig();

    connect(KIdleTime::instance(), SIGNAL(timeoutReached(int)),
            this, SLOT(timeoutReached(int)));

    connect(KIdleTime::instance(), SIGNAL(resumingFromIdle()),
            this, SLOT(backFromIdle()));
}

AutoAway::~AutoAway()
{
}

void AutoAway::timeoutReached(int id)
{
    if (!isEnabled()) {
        return;
    }
    KIdleTime::instance()->catchNextResumeEvent();
    if (id == m_awayTimeoutId) {
        if (m_globalPresence->currentPresence().type() != Tp::Presence::away().type() ||
            m_globalPresence->currentPresence().type() != Tp::Presence::xa().type() ||
            m_globalPresence->currentPresence().type() != Tp::Presence::hidden().type()) {

            setRequestedPresence(Tp::Presence::away());
            setActive(true);
        } else if (id == m_extAwayTimeoutId) {
            if (m_globalPresence->currentPresence().type() == Tp::Presence::away().type()) {
                setRequestedPresence(Tp::Presence::xa());
                setActive(true);
            }
        }
    }
}

void AutoAway::backFromIdle()
{
    kDebug();
    setActive(false);
}

void AutoAway::readConfig()
{
    KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
    KConfigGroup kdedConfig = config->group("KDED");

    bool autoAwayEnabled = kdedConfig.readEntry("autoAwayEnabled", true);
    bool autoXAEnabled = kdedConfig.readEntry("autoXAEnabled", true);

    //remove all our timeouts and only readd them if auto-away is enabled
    //WARNING: can't use removeAllTimeouts because this runs inside KDED, it would remove other KDED timeouts as well
    KIdleTime::instance()->removeIdleTimeout(m_awayTimeoutId);
    KIdleTime::instance()->removeIdleTimeout(m_extAwayTimeoutId);

    if (autoAwayEnabled) {
        int awayTime = kdedConfig.readEntry("awayAfter", 5);
        m_awayTimeoutId = KIdleTime::instance()->addIdleTimeout(awayTime * 60 * 1000);
        setEnabled(true);
    } else {
        setEnabled(false);
    }
    if (autoAwayEnabled && autoXAEnabled) {
        int xaTime = kdedConfig.readEntry("xaAfter", 15);
        m_extAwayTimeoutId = KIdleTime::instance()->addIdleTimeout(xaTime * 60 * 1000);
    }
}

void AutoAway::onSettingsChanged()
{
    readConfig();
}
<commit_msg>Fix auto-setting presence to Not Available, which didn't work because of a badly positioned bracket<commit_after>/*
    Auto away-presence setter-class
    Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>

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

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

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

#include "autoaway.h"

#include <TelepathyQt4/AccountManager>
#include <TelepathyQt4/AccountSet>

#include <KDebug>
#include <KIdleTime>
#include <KConfig>
#include <KConfigGroup>

#include "common/global-presence.h"

AutoAway::AutoAway(GlobalPresence* globalPresence, QObject* parent)
    : TelepathyKDEDModulePlugin(globalPresence, parent),
      m_awayTimeoutId(-1),
      m_extAwayTimeoutId(-1)
{
    setPluginPriority(99);
    readConfig();

    connect(KIdleTime::instance(), SIGNAL(timeoutReached(int)),
            this, SLOT(timeoutReached(int)));

    connect(KIdleTime::instance(), SIGNAL(resumingFromIdle()),
            this, SLOT(backFromIdle()));
}

AutoAway::~AutoAway()
{
}

void AutoAway::timeoutReached(int id)
{
    if (!isEnabled()) {
        return;
    }
    KIdleTime::instance()->catchNextResumeEvent();
    if (id == m_awayTimeoutId) {
        if (m_globalPresence->currentPresence().type() != Tp::Presence::away().type() ||
            m_globalPresence->currentPresence().type() != Tp::Presence::xa().type() ||
            m_globalPresence->currentPresence().type() != Tp::Presence::hidden().type()) {

            setRequestedPresence(Tp::Presence::away());
            setActive(true);
        }
    } else if (id == m_extAwayTimeoutId) {
        if (m_globalPresence->currentPresence().type() == Tp::Presence::away().type()) {
            setRequestedPresence(Tp::Presence::xa());
            setActive(true);
        }
    }
}

void AutoAway::backFromIdle()
{
    kDebug();
    setActive(false);
}

void AutoAway::readConfig()
{
    KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
    KConfigGroup kdedConfig = config->group("KDED");

    bool autoAwayEnabled = kdedConfig.readEntry("autoAwayEnabled", true);
    bool autoXAEnabled = kdedConfig.readEntry("autoXAEnabled", true);

    //remove all our timeouts and only readd them if auto-away is enabled
    //WARNING: can't use removeAllTimeouts because this runs inside KDED, it would remove other KDED timeouts as well
    KIdleTime::instance()->removeIdleTimeout(m_awayTimeoutId);
    KIdleTime::instance()->removeIdleTimeout(m_extAwayTimeoutId);

    if (autoAwayEnabled) {
        int awayTime = kdedConfig.readEntry("awayAfter", 5);
        m_awayTimeoutId = KIdleTime::instance()->addIdleTimeout(awayTime * 60 * 1000);
        setEnabled(true);
    } else {
        setEnabled(false);
    }
    if (autoAwayEnabled && autoXAEnabled) {
        int xaTime = kdedConfig.readEntry("xaAfter", 15);
        m_extAwayTimeoutId = KIdleTime::instance()->addIdleTimeout(xaTime * 60 * 1000);
    }
}

void AutoAway::onSettingsChanged()
{
    readConfig();
}
<|endoftext|>


<commit_before>/*
* Top Level window for KArm.
* Distributed under the GPL.
*/

/*
 * $Id$
 */

#include "top.h"
#include <qstring.h>
#include <qkeycode.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qpopupmenu.h>
#include <kconfig.h>
#include <kaccel.h>
#include <kapp.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmenubar.h>
#include <kaction.h>
#include <kstdaction.h>
#include <qvbox.h>
#include <qtimer.h>
#include <qstring.h>

#include "kaccelmenuwatch.h"
#include "karm.h"
#include "print.h"
#include "docking.h"
#include "preferences.h"

KarmWindow::KarmWindow()
  : KMainWindow(0),
	_accel( new KAccel( this ) ),
	_watcher( new KAccelMenuWatch( _accel, this ) ),
	_karm( new Karm( this ) ),
	_totalTime( 0 )
{
  setCentralWidget( _karm );
  connect( _karm, SIGNAL( sessionTimeChanged( long ) ),
		   this, SLOT( updateTime( long ) ) );

  // status bar

  statusBar()->insertItem( i18n( "This session: %1" )
                           .arg(QString::fromLatin1("0:00")), 0, 0, true );

  // setup PreferenceDialog.
  _preferences = Preferences::instance();

  // popup menus
  makeMenus();
  _watcher->updateMenus();

  // connections
  connect( _karm, SIGNAL(timerTick()), this, SLOT(updateTime()));

  _preferences->load();
  loadGeometry();

  // FIXME: this shouldnt stay. We need to check whether the
  // file exists and if not, create a blank one and ask whether
  // we want to add a task.
  _karm->load();

  DockWidget *dockWidget = new DockWidget(this,"doc widget");
  dockWidget->show();
}

void KarmWindow::save()
{
  _karm->save();
  saveGeometry();
}

void KarmWindow::quit()
{
  save();
  kapp->quit();
}

KarmWindow::~KarmWindow()
{
  quit();
}

/**
 * Updates the total time tally by one minute.
 */
void KarmWindow::updateTime()
{
  _totalTime++;
  updateStatusBar();
}

/**
 * Updates the total time tally by the value specified in newval.
 */
void KarmWindow::updateTime( long difference )
{
  _totalTime += difference;
  updateStatusBar();
}

void KarmWindow::updateStatusBar()
{
  QString time = Karm::formatTime( _totalTime );
  statusBar()->changeItem( i18n("This session: %1" ).arg(time), 0);
}

void KarmWindow::saveProperties( KConfig* )
{
  _karm->save();
}

void KarmWindow::keyBindings()
{
  KKeyDialog::configureKeys( actionCollection(), xmlFile());
}

void KarmWindow::resetSessionTime()
{
  _totalTime = 0;
  statusBar()->changeItem( i18n("This session: %1").arg(QString::fromLatin1("0:00")), 0 );
	_karm->resetSessionTimeForAllTasks();
}

void KarmWindow::makeMenus()
{
  KAction
    *actionKeyBindings,
    *actionResetSession,
    *actionStart,
    *actionStop,
    *actionNew,
    *actionNewSub,
    *actionDelete,
    *actionEdit;

  (void) KStdAction::quit(this, SLOT(quit()), actionCollection());
  (void) KStdAction::print(this, SLOT(print()), actionCollection());
  actionKeyBindings = KStdAction::keyBindings(this, SLOT(keyBindings()),actionCollection());
  (void) KStdAction::preferences(_preferences, SLOT(showDialog()),actionCollection());
  (void) KStdAction::save(_preferences, SLOT(save()),actionCollection());
  actionResetSession = new KAction(i18n("&Reset Session Time"), CTRL + Key_R,this,
                                   SLOT(resetSessionTime()),actionCollection(),
                                   "reset_session_time");
  actionStart = new KAction(i18n("&Start"), QString::fromLatin1("1rightarrow"),
                            CTRL + Key_S ,_karm,
                            SLOT(startTimer()),actionCollection(),"start");
  actionStop = new KAction(i18n("S&top"), QString::fromLatin1("stop"),
                           CTRL + Key_T,_karm,
                           SLOT(stopCurrentTimer()),actionCollection(),"stop");
  actionNew = KStdAction::action( KStdAction::New, _karm,	SLOT(newTask()),
                                  actionCollection(),"new_task");
  actionNewSub = new KAction(i18n("New Subtask"), QString::fromLatin1("kmultiple"),
                             CTRL+ALT+Key_N,
                             _karm, SLOT(newSubTask()),
                             actionCollection(), "new_sub_task");
  actionDelete = new KAction(i18n("&Delete"), QString::fromLatin1("editdelete"),
                             Key_Delete,_karm,
                             SLOT(deleteTask()),actionCollection(),"delete_task");
  actionEdit = new KAction(i18n("&Edit"), QString::fromLatin1("edit"),
                           CTRL + Key_E,_karm,
                           SLOT(editTask()),actionCollection(),"edit_task");
  createGUI( QString::fromLatin1("karmui.rc") );

  // Tool tops must be set after the createGUI.
  actionKeyBindings->setToolTip(i18n("Configure key bindings"));
  actionKeyBindings->setWhatsThis(i18n("This will let you configure keybindings which is specific to karm"));

  actionResetSession->setToolTip(i18n("Reset session time"));
  actionResetSession->setWhatsThis(i18n("This will reset the session time for all tasks."));

  actionStart->setToolTip(i18n("Start timing for selected task"));
  actionStart->setWhatsThis(i18n("This will start timing for the selected task.\n"
                            "It is even possible to time several tasks simultaneously.\n\n"
                            "You may also start timing of a tasks by double clicking the left mouse "
                            "button on a given task. This will, however, stop timing of other tasks."));

  actionStop->setToolTip(i18n("Stop timing of the selected task"));
  actionStop->setWhatsThis(i18n("Stop timing of the selected task"));

  actionNew->setToolTip(i18n("Create new top level task"));
  actionNew->setWhatsThis(i18n("This will create a new top level task."));

  actionDelete->setToolTip(i18n("Delete selected task"));
  actionDelete->setWhatsThis(i18n("This will delete the selected task and all its subtasks."));

  actionEdit->setToolTip(i18n("Edit name or times for selected task"));
  actionEdit->setWhatsThis(i18n("This will bring up a dialog box where you may edit the parameters for the selected task."));
}

void KarmWindow::print()
{
  MyPrinter printer(_karm);
  printer.print();
}

void KarmWindow::loadGeometry()
{
  KConfig &config = *kapp->config();

  config.setGroup( QString::fromLatin1("Main Window Geometry") );
  int w = config.readNumEntry( QString::fromLatin1("Width"), 100 );
  int h = config.readNumEntry( QString::fromLatin1("Height"), 100 );
  w = QMAX( w, sizeHint().width() );
  h = QMAX( h, sizeHint().height() );
  resize(w, h);
}

void KarmWindow::saveGeometry()
{
  KConfig &config = *KGlobal::config();
  config.setGroup( QString::fromLatin1("Main Window Geometry"));
  config.writeEntry( QString::fromLatin1("Width"), width());
  config.writeEntry( QString::fromLatin1("Height"), height());
  config.sync();
}

#include "top.moc"
<commit_msg>Shortcut for Start changed from "Ctrl-S" to "S" Shortcut for Stop changed from "Ctrl-T" to "ESC"<commit_after>/*
* Top Level window for KArm.
* Distributed under the GPL.
*/

/*
 * $Id$
 */

#include "top.h"
#include <qstring.h>
#include <qkeycode.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qpopupmenu.h>
#include <kconfig.h>
#include <kaccel.h>
#include <kapp.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmenubar.h>
#include <kaction.h>
#include <kstdaction.h>
#include <qvbox.h>
#include <qtimer.h>
#include <qstring.h>

#include "kaccelmenuwatch.h"
#include "karm.h"
#include "print.h"
#include "docking.h"
#include "preferences.h"

KarmWindow::KarmWindow()
  : KMainWindow(0),
	_accel( new KAccel( this ) ),
	_watcher( new KAccelMenuWatch( _accel, this ) ),
	_karm( new Karm( this ) ),
	_totalTime( 0 )
{
  setCentralWidget( _karm );
  connect( _karm, SIGNAL( sessionTimeChanged( long ) ),
		   this, SLOT( updateTime( long ) ) );

  // status bar

  statusBar()->insertItem( i18n( "This session: %1" )
                           .arg(QString::fromLatin1("0:00")), 0, 0, true );

  // setup PreferenceDialog.
  _preferences = Preferences::instance();

  // popup menus
  makeMenus();
  _watcher->updateMenus();

  // connections
  connect( _karm, SIGNAL(timerTick()), this, SLOT(updateTime()));

  _preferences->load();
  loadGeometry();

  // FIXME: this shouldnt stay. We need to check whether the
  // file exists and if not, create a blank one and ask whether
  // we want to add a task.
  _karm->load();

  DockWidget *dockWidget = new DockWidget(this,"doc widget");
  dockWidget->show();
}

void KarmWindow::save()
{
  _karm->save();
  saveGeometry();
}

void KarmWindow::quit()
{
  save();
  kapp->quit();
}

KarmWindow::~KarmWindow()
{
  quit();
}

/**
 * Updates the total time tally by one minute.
 */
void KarmWindow::updateTime()
{
  _totalTime++;
  updateStatusBar();
}

/**
 * Updates the total time tally by the value specified in newval.
 */
void KarmWindow::updateTime( long difference )
{
  _totalTime += difference;
  updateStatusBar();
}

void KarmWindow::updateStatusBar()
{
  QString time = Karm::formatTime( _totalTime );
  statusBar()->changeItem( i18n("This session: %1" ).arg(time), 0);
}

void KarmWindow::saveProperties( KConfig* )
{
  _karm->save();
}

void KarmWindow::keyBindings()
{
  KKeyDialog::configureKeys( actionCollection(), xmlFile());
}

void KarmWindow::resetSessionTime()
{
  _totalTime = 0;
  statusBar()->changeItem( i18n("This session: %1").arg(QString::fromLatin1("0:00")), 0 );
	_karm->resetSessionTimeForAllTasks();
}

void KarmWindow::makeMenus()
{
  KAction
    *actionKeyBindings,
    *actionResetSession,
    *actionStart,
    *actionStop,
    *actionNew,
    *actionNewSub,
    *actionDelete,
    *actionEdit;

  (void) KStdAction::quit(this, SLOT(quit()), actionCollection());
  (void) KStdAction::print(this, SLOT(print()), actionCollection());
  actionKeyBindings = KStdAction::keyBindings(this, SLOT(keyBindings()),actionCollection());
  (void) KStdAction::preferences(_preferences, SLOT(showDialog()),actionCollection());
  (void) KStdAction::save(_preferences, SLOT(save()),actionCollection());
  actionResetSession = new KAction(i18n("&Reset Session Time"), CTRL + Key_R,this,
                                   SLOT(resetSessionTime()),actionCollection(),
                                   "reset_session_time");
  actionStart = new KAction(i18n("&Start"), QString::fromLatin1("1rightarrow"),
                            Key_S ,_karm,
                            SLOT(startTimer()),actionCollection(),"start");
  actionStop = new KAction(i18n("S&top"), QString::fromLatin1("stop"),
                           Key_Escape,_karm,
                           SLOT(stopCurrentTimer()),actionCollection(),"stop");
  actionNew = KStdAction::action( KStdAction::New, _karm,	SLOT(newTask()),
                                  actionCollection(),"new_task");
  actionNewSub = new KAction(i18n("New Subtask"), QString::fromLatin1("kmultiple"),
                             CTRL+ALT+Key_N,
                             _karm, SLOT(newSubTask()),
                             actionCollection(), "new_sub_task");
  actionDelete = new KAction(i18n("&Delete"), QString::fromLatin1("editdelete"),
                             Key_Delete,_karm,
                             SLOT(deleteTask()),actionCollection(),"delete_task");
  actionEdit = new KAction(i18n("&Edit"), QString::fromLatin1("edit"),
                           CTRL + Key_E,_karm,
                           SLOT(editTask()),actionCollection(),"edit_task");
  createGUI( QString::fromLatin1("karmui.rc") );

  // Tool tops must be set after the createGUI.
  actionKeyBindings->setToolTip(i18n("Configure key bindings"));
  actionKeyBindings->setWhatsThis(i18n("This will let you configure keybindings which is specific to karm"));

  actionResetSession->setToolTip(i18n("Reset session time"));
  actionResetSession->setWhatsThis(i18n("This will reset the session time for all tasks."));

  actionStart->setToolTip(i18n("Start timing for selected task"));
  actionStart->setWhatsThis(i18n("This will start timing for the selected task.\n"
                            "It is even possible to time several tasks simultaneously.\n\n"
                            "You may also start timing of a tasks by double clicking the left mouse "
                            "button on a given task. This will, however, stop timing of other tasks."));

  actionStop->setToolTip(i18n("Stop timing of the selected task"));
  actionStop->setWhatsThis(i18n("Stop timing of the selected task"));

  actionNew->setToolTip(i18n("Create new top level task"));
  actionNew->setWhatsThis(i18n("This will create a new top level task."));

  actionDelete->setToolTip(i18n("Delete selected task"));
  actionDelete->setWhatsThis(i18n("This will delete the selected task and all its subtasks."));

  actionEdit->setToolTip(i18n("Edit name or times for selected task"));
  actionEdit->setWhatsThis(i18n("This will bring up a dialog box where you may edit the parameters for the selected task."));
}

void KarmWindow::print()
{
  MyPrinter printer(_karm);
  printer.print();
}

void KarmWindow::loadGeometry()
{
  KConfig &config = *kapp->config();

  config.setGroup( QString::fromLatin1("Main Window Geometry") );
  int w = config.readNumEntry( QString::fromLatin1("Width"), 100 );
  int h = config.readNumEntry( QString::fromLatin1("Height"), 100 );
  w = QMAX( w, sizeHint().width() );
  h = QMAX( h, sizeHint().height() );
  resize(w, h);
}

void KarmWindow::saveGeometry()
{
  KConfig &config = *KGlobal::config();
  config.setGroup( QString::fromLatin1("Main Window Geometry"));
  config.writeEntry( QString::fromLatin1("Width"), width());
  config.writeEntry( QString::fromLatin1("Height"), height());
  config.sync();
}

#include "top.moc"
<|endoftext|>


<commit_before>/**
 *
 * Terminology (Matroid - Graph) for escalated version of algorithm:
 *  Basis - Spanning forest
 *  Independent set - Tree (i.e. subset of a basis)
 *  Circuit - cycle
 *  Cocircuit - minimal edge-cut
 *  Hyperplane - maximal set not containing any basis (= complement of a min-cut)
 *
 *  Spanning forest - union of spanning trees of each component of an unconnected graph
 *
 */

#include <iostream>
#include <stdexcept>
#include <ogdf/basic/Queue.h>
#include <ogdf/basic/Graph.h>
#include <ogdf/basic/Stack.h>
#include <ogdf/basic/simple_graph_alg.h>

#include "helpers.hpp"
#include "graphcoloring.h"

using namespace std;
using namespace ogdf;

int m; // Cocircuit size bound

/**
 * @brief Takes a csv file with lines "<id>;<source>;<target>;<edge name>;..." and transforms it into graph
 * @param sEdgesFileName
 */
void csvToGraph(string sEdgesFileName, Graph &G) {
    ifstream fEdges(sEdgesFileName);
    if (!fEdges.is_open())
        throw new invalid_argument("Edges file doesn't exist or could not be accessed");

    vector<node> nodes;
    int id, u, v, nSize = 0;

    for (string line; getline(fEdges, line);) {
        sscanf(line.c_str(), "%d;%d;%d;", &id, &u, &v);

        if (u > nSize) {
            nodes.resize(u + 1);
            nSize = u;
        }

        if (v > nSize) {
            nodes.resize(v + 1);
            nSize = v;
        }

        // Skip if there already is an edge between these two nodes
        /*if (nodes.at(u) && nodes.at(v) &&
            (G.searchEdge(nodes.at(u), nodes.at(v)) || G.searchEdge(nodes.at(v), nodes.at(u)))) {
            continue;
        }*/

        if(nodes.at(u) == nullptr)
            nodes[u] = G.newNode(u);

        if(nodes[v] == nullptr)
            nodes[v] = G.newNode(v);

        G.newEdge(nodes[u], nodes[v], id);
    }
}

/**
 * Performs BFS to find the shortest path from s to t in graph G without using any edge from the forbidden edges.
 * Returns empty set if no such path exists.
 */
List<edge> shortestPath(const Graph &G, const GraphColoring &coloring, node s, node t, const List<edge> &forbidden) {
    List<edge> path;
    node v, u;
    edge e;

    Queue<node> Q;

    NodeArray<bool> visited(G, false);
    NodeArray<node> predecessor(G);

    Q.append(s);
    visited[s] = true;

    while(!Q.empty()) {
        v = Q.pop();

        if (v == t) {
            // traceback predecessors and reconstruct path
            for (node n = t; n != s; n = predecessor[n]) {
                e = G.searchEdge(n, predecessor[n]); // Takes O(min(deg(v), deg(w))) (that's fast on sparse graphs)
                if (coloring[e] != Color::RED)
                    path.pushFront(e);
            }
            break;
        }

        forall_adj_edges(e, v) {
            // TODO: Use BST or array (id -> bool) to represent forbidden and fasten the following search? (Probably not
            // necessary as forbidden size is bound by the constant m)
            if (forbidden.search(e).valid()) continue;

            u = e->opposite(v);
            if (!visited[u]) {
                predecessor[u] = v;
                visited[u] = true;
                Q.append(u);
            }
        }
    }

    return path;
}

/**
 * @brief hideConnectedBlueSubgraph
 * @param G
 * @param coloring
 * @param u
 */
void hideConnectedBlueSubgraph(Graph &G, const GraphColoring &coloring, node start) {
    Queue<node> Q;
    Q.append(start);

    NodeArray<bool> visited(G, false);

    node u, v;
    edge e;
    while(!Q.empty()) {
        u = Q.pop();
        forall_adj_edges(e, u) {
            if (coloring[e] == Color::BLUE) {
                v = e->opposite(u);
                if (!visited[v]) {
                    visited[v] = true;
                    Q.append(v);
                }
                G.hideEdge(e);
            }
        }
    }
}

bool findPathToAnyBlueAndColorItBlue(const Graph &G, GraphColoring &coloring, node start) {
    Queue<node> Q;
    Q.append(start);

    NodeArray<bool> visited(G, false);
    NodeArray<edge> accessEdge(G);

    node u, n;
    edge e;
    while(!Q.empty()) {
        u = Q.pop();

        if (coloring[u] == Color::BLUE && u != start) {
            // reconstruct path and go on
            edge ae;
            node n1, n2;
            for (n1 = u; n1 != start;) {
                // TODO: Use search edge instead?
                ae = accessEdge[n1];
                n2 = ae->opposite(n1);

                coloring[n1] = Color::BLUE;
                coloring[n2] = Color::BLUE;
                coloring[ae] = Color::BLUE;
                n1 = n2;
            }
            return true;
        }

        forall_adj_edges(e, u) {
            n = e->opposite(u);
            if (!visited[n]) {
                visited[n] = true;
                accessEdge[n] = e;
                Q.append(n);
            }
        }
    }

    return false;
}

/**
 * @return bool True for successful reconnection, false otherwise
 */
bool reconnectBlueSubgraph(Graph &G, const List<edge> &X, GraphColoring &coloring, node u, node v, edge c) {
    //  if u has blue adjacent edges (except of c) AND v has blue adjacent edges (exc. of c) then
    //     enumerate one blue subgraph, call it G_b1
    //     create graph G_rest = G \ X \ G_r \ G_b1 and BFS in it until blue is found (use hideEdge!)
    //     (or BFS (avoid red and X) from u to first blue edge not in G_b1)
    //     -> path found, color it blue and continue
    //     -> path not found, fail here (return;)

    G.hideEdge(c); // Don't consider c

    bool uaIsEmpty = true, vaIsEmpty = true;
    edge e;

    forall_adj_edges(e, u) {
        if (coloring[e] == Color::BLUE) {
            uaIsEmpty = false;
            break;
        }
    }

    forall_adj_edges(e, v) {
        if (coloring[e] == Color::BLUE) {
            vaIsEmpty = false;
            break;
        }
    }

    if (!uaIsEmpty && !vaIsEmpty) {
        // G_b has been disconnected, hide X, G_r and one component of blue subgraph (TODO: Maintain G_rest through the whole algorithm and not recompute here every time?)
        for(List<edge>::const_iterator it = X.begin(); it != X.end(); it++) G.hideEdge(*it);
        forall_edges(e, G) { if(coloring[e] == Color::RED) G.hideEdge(e); }
        hideConnectedBlueSubgraph(G, coloring, u);

        // BFS in G from u to the first found blue edge
        //  -> not found => fail here
        //  -> path found => color it blue and continue

        if (!findPathToAnyBlueAndColorItBlue(G, coloring, u)) {
            G.restoreAllEdges();
            return false;
        }

    } // else c is just a branch with a single leaf, nothing happened G_b stays connected

    G.restoreAllEdges();
    return true;
}

void GenCocircuits(List<List<edge>> &Cocircuits, Graph &G, GraphColoring coloring, List<edge> X, node red, node blue) {
    if (X.size() > m) return;

    // Find set D = (a short circuit C in G, s. t. |C ∩ X| = 1) \ X
    List<edge> D = shortestPath(G, coloring, red, blue, X);

    if (D.size() > 0) {

        // for each c ∈ D, recursively call GenCocircuits(X ∪ {c}).
        for(List<edge>::iterator iterator = D.begin(); iterator != D.end(); iterator++) {
            edge c = *iterator;

            List<edge> newX = X;
            newX.pushBack(c);

            // Coloring red-c path red, determining u and v, coloring the rest blue
            node n1 = red, n2 = blue, // after the first of the following for cycles these are the
                                      // nodes of the last red edge (one of them has to be incident with c)
                                      // initialized to red and blue since the first for can have 0 iterations
                 u, v; // c = (u,v), say u is red (and so will be all vertices on the path from the first red to u)

            for(List<edge>::iterator j = D.begin(); j != iterator; j++) {
                edge e = *j;

                n1 = e->source();
                n2 = e->target();

                coloring[n1] = Color::RED;
                coloring[n2] = Color::RED;
            }

            // Determine u, v, s.t. u is really red and v blue
            if (c->source() == n1 || c->target() == n1) { // if n1 is in c then n1 == u
                u = n1;
            } else { // n2 is in c so n2 == u
                u = n2;
            }

            v = c->opposite(u);

            // Color the rest of the path blue
            for(List<edge>::iterator j = iterator.succ(); j != D.end(); j++) {
                edge e = *j;

                coloring[e->source()] = Color::BLUE;
                coloring[e->target()] = Color::BLUE;
            }

            // If c = (u, v) is blue, reconnect blue subgraph (find the shortest path from u to v using only nonred edges)
            if (coloring[c] == Color::BLUE) {
                reconnectBlueSubgraph(G, X, coloring, u, v, c);
            }

            GenCocircuits(Cocircuits, G, coloring, newX, u, v);
        }

    } else {
        // If there is no such circuit C above (line 4), then return ‘Cocircuit: X’.
        Cocircuits.pushBack(X);
    }
}

/**
 * Returns edges spanning forest of (possibly disconnected) graph G
 * @param G
 */
List<edge> spanningEdges(const Graph &G) {
    EdgeArray<bool> isBackedge(G, false);

    List<edge> backedges;
    isAcyclicUndirected(G, backedges);

    for(List<edge>::iterator i = backedges.begin(); i != backedges.end(); i++) {
        isBackedge[*i] = true;
    }

    List<edge> spanningEdges;
    edge e;
    forall_edges(e, G) {
        if (!isBackedge[e]) {
            spanningEdges.pushBack(e);
        }
    }

    return spanningEdges;
}

void CircuitCocircuit(Graph &G, List<List<edge>> &cocircuits) {
    List<edge> base = spanningEdges(G);

    edge e;
    for(List<edge>::iterator i = base.begin(); i != base.end(); i++) {
        e = *i;
        List<edge> X; // (Indexes might be sufficient? Check later)
        GraphColoring coloring(G);
        X.pushBack(e);
        coloring[e->source()] = Color::RED;
        coloring[e->target()] = Color::BLUE;

        GenCocircuits(cocircuits, G, coloring, X, e->source(), e->target());
    }
}

// TODO: Read from stdin?
int main(int argc, char* argv[])
{
    if (argc != 3 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
        cout << "Usage: " << argv[0] << " <graph.csv> <cocircuit size bound>" << endl;
        exit(1);
    }

    string graphFile(argv[1]);
    m = stoi(argv[2]);
    if (m < 1) {
        cerr << "Cocircuit size bound lower than 1. Terminating." << endl;
        exit(2);
    }

    try {
        Graph G;
        csvToGraph(graphFile, G);

        List<List<edge>> cocircuits;
        CircuitCocircuit(G, cocircuits);

        for(List<List<edge> >::iterator it = cocircuits.begin(); it != cocircuits.end(); ++it) {
            cout << *it << endl;
        }

    } catch (invalid_argument *e) {
        cerr << "Error: " << e->what() << endl;
        return 1;
    }

    return 0;
}

<commit_msg>Keep vertices colored<commit_after>/**
 *
 * Terminology (Matroid - Graph) for escalated version of algorithm:
 *  Basis - Spanning forest
 *  Independent set - Tree (i.e. subset of a basis)
 *  Circuit - cycle
 *  Cocircuit - minimal edge-cut
 *  Hyperplane - maximal set not containing any basis (= complement of a min-cut)
 *
 *  Spanning forest - union of spanning trees of each component of an unconnected graph
 *
 */

#include <iostream>
#include <stdexcept>
#include <ogdf/basic/Queue.h>
#include <ogdf/basic/Graph.h>
#include <ogdf/basic/Stack.h>
#include <ogdf/basic/simple_graph_alg.h>

#include "helpers.hpp"
#include "graphcoloring.h"

using namespace std;
using namespace ogdf;

int m; // Cocircuit size bound

/**
 * @brief Takes a csv file with lines "<id>;<source>;<target>;<edge name>;..." and transforms it into graph
 * @param sEdgesFileName
 */
void csvToGraph(string sEdgesFileName, Graph &G) {
    ifstream fEdges(sEdgesFileName);
    if (!fEdges.is_open())
        throw new invalid_argument("Edges file doesn't exist or could not be accessed");

    vector<node> nodes;
    int id, u, v, nSize = 0;

    for (string line; getline(fEdges, line);) {
        sscanf(line.c_str(), "%d;%d;%d;", &id, &u, &v);

        if (u > nSize) {
            nodes.resize(u + 1);
            nSize = u;
        }

        if (v > nSize) {
            nodes.resize(v + 1);
            nSize = v;
        }

        // Skip if there already is an edge between these two nodes
        /*if (nodes.at(u) && nodes.at(v) &&
            (G.searchEdge(nodes.at(u), nodes.at(v)) || G.searchEdge(nodes.at(v), nodes.at(u)))) {
            continue;
        }*/

        if(nodes.at(u) == nullptr)
            nodes[u] = G.newNode(u);

        if(nodes[v] == nullptr)
            nodes[v] = G.newNode(v);

        G.newEdge(nodes[u], nodes[v], id);
    }
}

/**
 * Performs BFS to find the shortest path from s to t in graph G without using any edge from the forbidden edges.
 * Returns empty set if no such path exists.
 */
List<edge> shortestPath(const Graph &G, const GraphColoring &coloring, node s, node t, const List<edge> &forbidden) {
    List<edge> path;
    node v, u;
    edge e;

    Queue<node> Q;

    NodeArray<bool> visited(G, false);
    NodeArray<node> predecessor(G);

    Q.append(s);
    visited[s] = true;

    while(!Q.empty()) {
        v = Q.pop();

        if (v == t) {
            // traceback predecessors and reconstruct path
            for (node n = t; n != s; n = predecessor[n]) {
                e = G.searchEdge(n, predecessor[n]); // Takes O(min(deg(v), deg(w))) (that's fast on sparse graphs)
                if (coloring[e] != Color::RED)
                    path.pushFront(e);
            }
            break;
        }

        forall_adj_edges(e, v) {
            // TODO: Use BST or array (id -> bool) to represent forbidden and fasten the following search? (Probably not
            // necessary as forbidden size is bound by the constant m)
            if (forbidden.search(e).valid()) continue;

            u = e->opposite(v);
            if (!visited[u]) {
                predecessor[u] = v;
                visited[u] = true;
                Q.append(u);
            }
        }
    }

    return path;
}

/**
 * @brief hideConnectedBlueSubgraph
 * @param G
 * @param coloring
 * @param u
 */
void hideConnectedBlueSubgraph(Graph &G, const GraphColoring &coloring, node start) {
    Queue<node> Q;
    Q.append(start);

    NodeArray<bool> visited(G, false);

    node u, v;
    edge e;
    while(!Q.empty()) {
        u = Q.pop();
        forall_adj_edges(e, u) {
            if (coloring[e] == Color::BLUE) {
                v = e->opposite(u);
                if (!visited[v]) {
                    visited[v] = true;
                    Q.append(v);
                }
                G.hideEdge(e);
            }
        }
    }
}

bool findPathToAnyBlueAndColorItBlue(const Graph &G, GraphColoring &coloring, node start) {
    Queue<node> Q;
    Q.append(start);

    NodeArray<bool> visited(G, false);
    NodeArray<edge> accessEdge(G);

    node u, n;
    edge e;
    while(!Q.empty()) {
        u = Q.pop();

        if (coloring[u] == Color::BLUE && u != start) {
            // reconstruct path and go on
            edge ae;
            node n1, n2;
            for (n1 = u; n1 != start;) {
                // TODO: Use search edge instead?
                ae = accessEdge[n1];
                n2 = ae->opposite(n1);

                coloring[n1] = Color::BLUE;
                coloring[n2] = Color::BLUE;
                coloring[ae] = Color::BLUE;
                n1 = n2;
            }
            return true;
        }

        forall_adj_edges(e, u) {
            n = e->opposite(u);
            if (!visited[n]) {
                visited[n] = true;
                accessEdge[n] = e;
                Q.append(n);
            }
        }
    }

    return false;
}

/**
 * @return bool True for successful reconnection, false otherwise
 */
bool reconnectBlueSubgraph(Graph &G, const List<edge> &X, GraphColoring &coloring, node u, node v, edge c) {
    //  if u has blue adjacent edges (except of c) AND v has blue adjacent edges (exc. of c) then
    //     enumerate one blue subgraph, call it G_b1
    //     create graph G_rest = G \ X \ G_r \ G_b1 and BFS in it until blue is found (use hideEdge!)
    //     (or BFS (avoid red and X) from u to first blue edge not in G_b1)
    //     -> path found, color it blue and continue
    //     -> path not found, fail here (return;)

    G.hideEdge(c); // Don't consider c

    bool uaIsEmpty = true, vaIsEmpty = true;
    edge e;

    forall_adj_edges(e, u) {
        if (coloring[e] == Color::BLUE) {
            uaIsEmpty = false;
            break;
        }
    }

    forall_adj_edges(e, v) {
        if (coloring[e] == Color::BLUE) {
            vaIsEmpty = false;
            break;
        }
    }

    if (!uaIsEmpty && !vaIsEmpty) {
        // G_b has been disconnected, hide X, G_r and one component of blue subgraph (TODO: Maintain G_rest through the whole algorithm and not recompute here every time?)
        for(List<edge>::const_iterator it = X.begin(); it != X.end(); it++) G.hideEdge(*it);
        forall_edges(e, G) { if(coloring[e] == Color::RED) G.hideEdge(e); }
        hideConnectedBlueSubgraph(G, coloring, u);

        // BFS in G from u to the first found blue edge
        //  -> not found => fail here
        //  -> path found => color it blue and continue

        if (!findPathToAnyBlueAndColorItBlue(G, coloring, u)) {
            G.restoreAllEdges();
            return false;
        }

    } // else c is just a branch with a single leaf, nothing happened G_b stays connected

    G.restoreAllEdges();
    return true;
}

void GenCocircuits(List<List<edge>> &Cocircuits, Graph &G, GraphColoring coloring, List<edge> X, node red, node blue) {
    if (X.size() > m) return;

    // Find set D = (a short circuit C in G, s. t. |C ∩ X| = 1) \ X
    List<edge> D = shortestPath(G, coloring, red, blue, X);

    if (D.size() > 0) {

        // for each c ∈ D, recursively call GenCocircuits(X ∪ {c}).
        for(List<edge>::iterator iterator = D.begin(); iterator != D.end(); iterator++) {
            edge c = *iterator;

            List<edge> newX = X;
            newX.pushBack(c);

            // Coloring red-c path red, determining u and v, coloring the rest blue
            node n1 = red, n2 = blue, // after the first of the following for cycles these are the
                                      // nodes of the last red edge (one of them has to be incident with c)
                                      // initialized to red and blue since the first for can have 0 iterations
                 u, v; // c = (u,v), say u is red (and so will be all vertices on the path from the first red to u)

            for(List<edge>::iterator j = D.begin(); j != iterator; j++) {
                edge e = *j;

                n1 = e->source();
                n2 = e->target();

                coloring[n1] = Color::RED;
                coloring[n2] = Color::RED;
                coloring[e] = Color::RED;
            }

            // Determine u, v, s.t. u is really red and v blue
            if (c->source() == n1 || c->target() == n1) { // if n1 is in c then n1 == u
                u = n1;
            } else { // n2 is in c so n2 == u
                u = n2;
            }

            v = c->opposite(u);

            // Color the rest of the path blue
            for(List<edge>::iterator j = iterator.succ(); j != D.end(); j++) {
                edge e = *j;

                coloring[e->source()] = Color::BLUE;
                coloring[e->target()] = Color::BLUE;
                coloring[e] = Color::BLUE;
            }

            // If c = (u, v) is blue, reconnect blue subgraph (find the shortest path from u to v using only nonred edges)
            if (coloring[c] == Color::BLUE) {
                reconnectBlueSubgraph(G, X, coloring, u, v, c);
            }

            GenCocircuits(Cocircuits, G, coloring, newX, u, v);
        }

    } else {
        // If there is no such circuit C above (line 4), then return ‘Cocircuit: X’.
        Cocircuits.pushBack(X);
    }
}

/**
 * Returns edges spanning forest of (possibly disconnected) graph G
 * @param G
 */
List<edge> spanningEdges(const Graph &G) {
    EdgeArray<bool> isBackedge(G, false);

    List<edge> backedges;
    isAcyclicUndirected(G, backedges);

    for(List<edge>::iterator i = backedges.begin(); i != backedges.end(); i++) {
        isBackedge[*i] = true;
    }

    List<edge> spanningEdges;
    edge e;
    forall_edges(e, G) {
        if (!isBackedge[e]) {
            spanningEdges.pushBack(e);
        }
    }

    return spanningEdges;
}

void CircuitCocircuit(Graph &G, List<List<edge>> &cocircuits) {
    List<edge> base = spanningEdges(G);

    edge e;
    for(List<edge>::iterator i = base.begin(); i != base.end(); i++) {
        e = *i;
        List<edge> X; // (Indexes might be sufficient? Check later)
        GraphColoring coloring(G);
        X.pushBack(e);
        coloring[e->source()] = Color::RED;
        coloring[e->target()] = Color::BLUE;

        GenCocircuits(cocircuits, G, coloring, X, e->source(), e->target());
    }
}

// TODO: Read from stdin?
int main(int argc, char* argv[])
{
    if (argc != 3 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
        cout << "Usage: " << argv[0] << " <graph.csv> <cocircuit size bound>" << endl;
        exit(1);
    }

    string graphFile(argv[1]);
    m = stoi(argv[2]);
    if (m < 1) {
        cerr << "Cocircuit size bound lower than 1. Terminating." << endl;
        exit(2);
    }

    try {
        Graph G;
        csvToGraph(graphFile, G);

        List<List<edge>> cocircuits;
        CircuitCocircuit(G, cocircuits);

        for(List<List<edge> >::iterator it = cocircuits.begin(); it != cocircuits.end(); ++it) {
            cout << *it << endl;
        }

    } catch (invalid_argument *e) {
        cerr << "Error: " << e->what() << endl;
        return 1;
    }

    return 0;
}

<|endoftext|>


<commit_before>#include "Crazyradio.h"

#include <sstream>
#include <stdexcept>

#include <libusb-1.0/libusb.h>

enum
{
    SET_RADIO_CHANNEL   = 0x01,
    SET_RADIO_ADDRESS   = 0x02,
    SET_DATA_RATE       = 0x03,
    SET_RADIO_POWER     = 0x04,
    SET_RADIO_ARD       = 0x05,
    SET_RADIO_ARC       = 0x06,
    ACK_ENABLE          = 0x10,
    SET_CONT_CARRIER    = 0x20,
    SCANN_CHANNELS      = 0x21,
    LAUNCH_BOOTLOADER   = 0xFF,
};

Crazyradio::Crazyradio(
    uint32_t devid)
    : ITransport()
    , USBDevice(0x1915, 0x7777)
    , m_channel(0)
    , m_address(0)
    , m_datarate(Datarate_250KPS)
{
    open(devid);
    setDatarate(Datarate_2MPS);
    setChannel(2);
    setContCarrier(false);
    setAddress(0xE7E7E7E7E7);
    setPower(Power_0DBM);
    setArc(3);
    setArdBytes(32);
}

Crazyradio::~Crazyradio()
{
}

uint32_t Crazyradio::numDevices()
{
    return USBDevice::numDevices(0x1915, 0x7777);
}

void Crazyradio::setChannel(uint8_t channel)
{
    sendVendorSetup(SET_RADIO_CHANNEL, channel, 0, NULL, 0);
    m_channel = channel;
}

void Crazyradio::setAddress(uint64_t address)
{
    unsigned char a[5];
    a[4] = (address >> 0) & 0xFF;
    a[3] = (address >> 8) & 0xFF;
    a[2] = (address >> 16) & 0xFF;
    a[1] = (address >> 24) & 0xFF;
    a[0] = (address >> 32) & 0xFF;

    // sendVendorSetup(SET_RADIO_ADDRESS, 0, 0, a, 5);
    // unsigned char a[] = {0xe7, 0xe7, 0xe7, 0xe7, 0x02};

    int status = libusb_control_transfer(
        m_handle,
        LIBUSB_REQUEST_TYPE_VENDOR,
        SET_RADIO_ADDRESS,
        0,
        0,
        a,
        5,
        /*timeout*/ 1000);
    // if (status != LIBUSB_SUCCESS) {
    //     std::cerr << "sendVendorSetup: " << libusb_error_name(status) << std::endl;
    // }
    m_address = address;
}

void Crazyradio::setDatarate(Datarate datarate)
{
    sendVendorSetup(SET_DATA_RATE, datarate, 0, NULL, 0);
    m_datarate = datarate;
}

void Crazyradio::setPower(Power power)
{
    sendVendorSetup(SET_RADIO_POWER, power, 0, NULL, 0);
}

void Crazyradio::setArc(uint8_t arc)
{
    sendVendorSetup(SET_RADIO_ARC, arc, 0, NULL, 0);
}

void Crazyradio::setArdTime(uint8_t us)
{
    // Auto Retransmit Delay:
    // 0000 - Wait 250uS
    // 0001 - Wait 500uS
    // 0010 - Wait 750uS
    // ........
    // 1111 - Wait 4000uS

    // Round down, to value representing a multiple of 250uS
    int t = (us / 250) - 1;
    if (t < 0) {
        t = 0;
    }
    if (t > 0xF) {
        t = 0xF;
    }
    sendVendorSetup(SET_RADIO_ARD, t, 0, NULL, 0);
}

void Crazyradio::setArdBytes(uint8_t nbytes)
{
    sendVendorSetup(SET_RADIO_ARD, 0x80 | nbytes, 0, NULL, 0);
}

void Crazyradio::setAckEnable(bool enable)
{
    sendVendorSetup(ACK_ENABLE, enable, 0, NULL, 0);
}

void Crazyradio::setContCarrier(bool active)
{
    sendVendorSetup(SET_CONT_CARRIER, active, 0, NULL, 0);
}

void Crazyradio::sendPacket(
    const uint8_t* data,
    uint32_t length,
    Ack& result)
{
    int status;
    int transferred;

    if (!m_handle) {
        throw std::runtime_error("No valid device handle!");
    }

    // Send data
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x01 | LIBUSB_ENDPOINT_OUT),
        (uint8_t*)data,
        length,
        &transferred,
        /*timeout*/ 1000);
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }
    if (length != transferred) {
        std::stringstream sstr;
        sstr << "Did transfer " << transferred << " but " << length << " was requested!";
        throw std::runtime_error(sstr.str());
    }

    // Read result
    result.ack = false;
    result.size = 0;
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x81 | LIBUSB_ENDPOINT_IN),
        (unsigned char*)&result,
        sizeof(result) - 1,
        &transferred,
        /*timeout*/ 1000);
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }

    result.size = transferred - 1;
}

void Crazyradio::sendPacketNoAck(
    const uint8_t* data,
    uint32_t length)
{
    int status;
    int transferred;

    if (!m_handle) {
        throw std::runtime_error("No valid device handle!");
    }

    // Send data
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x01 | LIBUSB_ENDPOINT_OUT),
        (uint8_t*)data,
        length,
        &transferred,
        /*timeout*/ 1000);
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }
    if (length != transferred) {
        std::stringstream sstr;
        sstr << "Did transfer " << transferred << " but " << length << " was requested!";
        throw std::runtime_error(sstr.str());
    }
}
<commit_msg>Handle LIBUSB_ERROR_TIMEOUT more gracefully<commit_after>#include "Crazyradio.h"

#include <sstream>
#include <stdexcept>

#include <libusb-1.0/libusb.h>

enum
{
    SET_RADIO_CHANNEL   = 0x01,
    SET_RADIO_ADDRESS   = 0x02,
    SET_DATA_RATE       = 0x03,
    SET_RADIO_POWER     = 0x04,
    SET_RADIO_ARD       = 0x05,
    SET_RADIO_ARC       = 0x06,
    ACK_ENABLE          = 0x10,
    SET_CONT_CARRIER    = 0x20,
    SCANN_CHANNELS      = 0x21,
    LAUNCH_BOOTLOADER   = 0xFF,
};

Crazyradio::Crazyradio(
    uint32_t devid)
    : ITransport()
    , USBDevice(0x1915, 0x7777)
    , m_channel(0)
    , m_address(0)
    , m_datarate(Datarate_250KPS)
{
    open(devid);
    setDatarate(Datarate_2MPS);
    setChannel(2);
    setContCarrier(false);
    setAddress(0xE7E7E7E7E7);
    setPower(Power_0DBM);
    setArc(3);
    setArdBytes(32);
}

Crazyradio::~Crazyradio()
{
}

uint32_t Crazyradio::numDevices()
{
    return USBDevice::numDevices(0x1915, 0x7777);
}

void Crazyradio::setChannel(uint8_t channel)
{
    sendVendorSetup(SET_RADIO_CHANNEL, channel, 0, NULL, 0);
    m_channel = channel;
}

void Crazyradio::setAddress(uint64_t address)
{
    unsigned char a[5];
    a[4] = (address >> 0) & 0xFF;
    a[3] = (address >> 8) & 0xFF;
    a[2] = (address >> 16) & 0xFF;
    a[1] = (address >> 24) & 0xFF;
    a[0] = (address >> 32) & 0xFF;

    // sendVendorSetup(SET_RADIO_ADDRESS, 0, 0, a, 5);
    // unsigned char a[] = {0xe7, 0xe7, 0xe7, 0xe7, 0x02};

    int status = libusb_control_transfer(
        m_handle,
        LIBUSB_REQUEST_TYPE_VENDOR,
        SET_RADIO_ADDRESS,
        0,
        0,
        a,
        5,
        /*timeout*/ 1000);
    // if (status != LIBUSB_SUCCESS) {
    //     std::cerr << "sendVendorSetup: " << libusb_error_name(status) << std::endl;
    // }
    m_address = address;
}

void Crazyradio::setDatarate(Datarate datarate)
{
    sendVendorSetup(SET_DATA_RATE, datarate, 0, NULL, 0);
    m_datarate = datarate;
}

void Crazyradio::setPower(Power power)
{
    sendVendorSetup(SET_RADIO_POWER, power, 0, NULL, 0);
}

void Crazyradio::setArc(uint8_t arc)
{
    sendVendorSetup(SET_RADIO_ARC, arc, 0, NULL, 0);
}

void Crazyradio::setArdTime(uint8_t us)
{
    // Auto Retransmit Delay:
    // 0000 - Wait 250uS
    // 0001 - Wait 500uS
    // 0010 - Wait 750uS
    // ........
    // 1111 - Wait 4000uS

    // Round down, to value representing a multiple of 250uS
    int t = (us / 250) - 1;
    if (t < 0) {
        t = 0;
    }
    if (t > 0xF) {
        t = 0xF;
    }
    sendVendorSetup(SET_RADIO_ARD, t, 0, NULL, 0);
}

void Crazyradio::setArdBytes(uint8_t nbytes)
{
    sendVendorSetup(SET_RADIO_ARD, 0x80 | nbytes, 0, NULL, 0);
}

void Crazyradio::setAckEnable(bool enable)
{
    sendVendorSetup(ACK_ENABLE, enable, 0, NULL, 0);
}

void Crazyradio::setContCarrier(bool active)
{
    sendVendorSetup(SET_CONT_CARRIER, active, 0, NULL, 0);
}

void Crazyradio::sendPacket(
    const uint8_t* data,
    uint32_t length,
    Ack& result)
{
    result.ack = false;
    result.size = 0;

    int status;
    int transferred;

    if (!m_handle) {
        throw std::runtime_error("No valid device handle!");
    }

    // Send data
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x01 | LIBUSB_ENDPOINT_OUT),
        (uint8_t*)data,
        length,
        &transferred,
        /*timeout*/ 1000);
    if (status == LIBUSB_ERROR_TIMEOUT) {
        return;
    }
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }
    if (length != transferred) {
        std::stringstream sstr;
        sstr << "Did transfer " << transferred << " but " << length << " was requested!";
        throw std::runtime_error(sstr.str());
    }

    // Read result
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x81 | LIBUSB_ENDPOINT_IN),
        (unsigned char*)&result,
        sizeof(result) - 1,
        &transferred,
        /*timeout*/ 1000);
    if (status == LIBUSB_ERROR_TIMEOUT) {
        return;
    }
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }

    result.size = transferred - 1;
}

void Crazyradio::sendPacketNoAck(
    const uint8_t* data,
    uint32_t length)
{
    int status;
    int transferred;

    if (!m_handle) {
        throw std::runtime_error("No valid device handle!");
    }

    // Send data
    status = libusb_bulk_transfer(
        m_handle,
        /* endpoint*/ (0x01 | LIBUSB_ENDPOINT_OUT),
        (uint8_t*)data,
        length,
        &transferred,
        /*timeout*/ 1000);
    if (status == LIBUSB_ERROR_TIMEOUT) {
        return;
    }
    if (status != LIBUSB_SUCCESS) {
        throw std::runtime_error(libusb_error_name(status));
    }
    if (length != transferred) {
        std::stringstream sstr;
        sstr << "Did transfer " << transferred << " but " << length << " was requested!";
        throw std::runtime_error(sstr.str());
    }
}
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeObject.cpp,v $
//   $Revision: 1.31 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2008/03/11 23:32:12 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"
#include "CEvaluationTree.h"
#include "CExpression.h"
#include "report/CCopasiObjectName.h"
#include "report/CCopasiObject.h"
#include "report/CCopasiContainer.h"
#include "model/CModel.h"
#include "CopasiDataModel/CCopasiDataModel.h"

#include "sbml/math/ASTNode.h"
#include "sbml/SBase.h"
#include "sbml/SBMLTypeCodes.h"
#include "sbml/Compartment.h"
#include "sbml/Species.h"
#include "sbml/Parameter.h"
#include "sbml/Reaction.h"

CEvaluationNodeObject::CEvaluationNodeObject():
    CEvaluationNode(CEvaluationNode::INVALID, ""),
    mpValue(NULL),
    mRegisteredObjectCN("")
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type) (CEvaluationNode::OBJECT | subType), data),
    mpValue(NULL),
    mRegisteredObjectCN(data.substr(1, data.length() - 2))
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const CEvaluationNodeObject & src):
    CEvaluationNode(src),
    mpValue(src.mpValue),
    mRegisteredObjectCN(src.mRegisteredObjectCN)
{}

CEvaluationNodeObject::~CEvaluationNodeObject() {}

bool CEvaluationNodeObject::compile(const CEvaluationTree * pTree)
{
  const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);
  if (!pExpression) return false;

  const CCopasiObject * pObject =
    pExpression->getNodeObject(mRegisteredObjectCN);

  if (pObject)
    mpValue = (C_FLOAT64 *) pObject->getValuePointer();
  else
    mpValue = NULL;

  if (mpValue == NULL) return false;
  if (!pObject->isValueDbl()) return false;

  mData = "<" + mRegisteredObjectCN + ">";

  return (getChild() == NULL); // We must not have any children.
}

CEvaluationNode::Data CEvaluationNodeObject::getData() const
{return "<" + mRegisteredObjectCN + ">";}

bool CEvaluationNodeObject::setData(const Data & data)
{
  mData = data;
  mRegisteredObjectCN = data.substr(1, data.length() - 2);

  return true;
}

std::string CEvaluationNodeObject::getInfix() const
  {return "<" + mRegisteredObjectCN + ">";}

#if 0
std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * pTree) const
  {
    const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);
    if (!pExpression) return false;

    const CCopasiObject * pObject =
      CCopasiContainer::ObjectFromName(mRegisteredObjectCN);

    if (pObject == NULL) return "<" + mRegisteredObjectCN + ">";

    return "<" + pObject->getObjectDisplayName() + ">";
  }
#endif

std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * /* pTree */) const
  {
    return "<" + mRegisteredObjectCN + ">";
  }

std::string CEvaluationNodeObject::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

std::string CEvaluationNodeObject::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

std::string CEvaluationNodeObject::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

CEvaluationNode* CEvaluationNodeObject::createNodeFromASTTree(const ASTNode& node)
{
  CEvaluationNodeObject* pNode = NULL;
  ASTNodeType_t type = node.getType();
  switch (type)
    {
    case AST_NAME_TIME:
    case AST_NAME:
      pNode = new CEvaluationNodeObject(ANY, CCopasiObjectName(std::string("<") + node.getName() + std::string(">")));
      break;
    default:
      break;
    }
  return pNode;
}

ASTNode* CEvaluationNodeObject::toAST() const
  {
    ASTNode* node = new ASTNode();
    node->setType(AST_NAME);
    // since I can not get the model in which this node is located, I just
    // assume that it will always be the current global model.
    CCopasiObject* object = CCopasiContainer::ObjectFromName(mRegisteredObjectCN);
    assert(object);
    // if it is a reference, we get the parent of the reference
    if (object->isReference())
      {
        object = object->getObjectParent();
      }
    CModelEntity* pME = dynamic_cast<CModelEntity*>(object);
    if (pME != NULL)
      {
        CModel* pModel = dynamic_cast<CModel*>(pME);
        if (pModel != NULL)
          {
            node->setType(AST_NAME_TIME);
            node->setName("time");
            if (pModel->getInitialTime() != 0.0)
              {
                CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1);
              }
          }
        else
          {
            node->setName(pME->getSBMLId().c_str());
          }
      }
    else
      {
        CCopasiParameter* pPara = dynamic_cast<CCopasiParameter*>(object);
        if (pPara != NULL)
          {
            node->setName(pPara->getObjectName().c_str());
          }
        else
          {
            fatalError();
          }
      }
    return node;
  }

const CRegisteredObjectName & CEvaluationNodeObject::getObjectCN() const
  {return mRegisteredObjectCN;}

#include "utilities/copasimathml.h"

void CEvaluationNodeObject::writeMathML(std::ostream & out,
                                        const std::vector<std::vector<std::string> > & /* env */,
                                        bool /* expand */,
                                        unsigned C_INT32 l) const
  {
    const CCopasiObject* obj = CCopasiContainer::ObjectFromName(mRegisteredObjectCN);
    out << SPC(l) << CMathMl::getMMLName(obj) << std::endl;
    //or use mValue instead?
  }
<commit_msg>Fixed Bug 1077. An invalid object no longer will lead to a crash.<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeObject.cpp,v $
//   $Revision: 1.32 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2008/09/08 16:36:55 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"
#include "CEvaluationTree.h"
#include "CExpression.h"
#include "report/CCopasiObjectName.h"
#include "report/CCopasiObject.h"
#include "report/CCopasiContainer.h"
#include "model/CModel.h"
#include "CopasiDataModel/CCopasiDataModel.h"

#include "sbml/math/ASTNode.h"
#include "sbml/SBase.h"
#include "sbml/SBMLTypeCodes.h"
#include "sbml/Compartment.h"
#include "sbml/Species.h"
#include "sbml/Parameter.h"
#include "sbml/Reaction.h"

CEvaluationNodeObject::CEvaluationNodeObject():
    CEvaluationNode(CEvaluationNode::INVALID, ""),
    mpValue(NULL),
    mRegisteredObjectCN("")
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type) (CEvaluationNode::OBJECT | subType), data),
    mpValue(NULL),
    mRegisteredObjectCN(data.substr(1, data.length() - 2))
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const CEvaluationNodeObject & src):
    CEvaluationNode(src),
    mpValue(src.mpValue),
    mRegisteredObjectCN(src.mRegisteredObjectCN)
{}

CEvaluationNodeObject::~CEvaluationNodeObject() {}

bool CEvaluationNodeObject::compile(const CEvaluationTree * pTree)
{
  const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);
  if (!pExpression) return false;

  const CCopasiObject * pObject =
    pExpression->getNodeObject(mRegisteredObjectCN);

  if (pObject)
    mpValue = (C_FLOAT64 *) pObject->getValuePointer();
  else
    {
      mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mpValue = &mValue;
    }

  if (mpValue == NULL) return false;
  if (!pObject->isValueDbl()) return false;

  mData = "<" + mRegisteredObjectCN + ">";

  return (getChild() == NULL); // We must not have any children.
}

CEvaluationNode::Data CEvaluationNodeObject::getData() const
{return "<" + mRegisteredObjectCN + ">";}

bool CEvaluationNodeObject::setData(const Data & data)
{
  mData = data;
  mRegisteredObjectCN = data.substr(1, data.length() - 2);

  return true;
}

std::string CEvaluationNodeObject::getInfix() const
  {return "<" + mRegisteredObjectCN + ">";}

#if 0
std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * pTree) const
  {
    const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);
    if (!pExpression) return false;

    const CCopasiObject * pObject =
      CCopasiContainer::ObjectFromName(mRegisteredObjectCN);

    if (pObject == NULL) return "<" + mRegisteredObjectCN + ">";

    return "<" + pObject->getObjectDisplayName() + ">";
  }
#endif

std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * /* pTree */) const
  {
    return "<" + mRegisteredObjectCN + ">";
  }

std::string CEvaluationNodeObject::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

std::string CEvaluationNodeObject::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

std::string CEvaluationNodeObject::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
  {
    return mData;
  }

CEvaluationNode* CEvaluationNodeObject::createNodeFromASTTree(const ASTNode& node)
{
  CEvaluationNodeObject* pNode = NULL;
  ASTNodeType_t type = node.getType();
  switch (type)
    {
    case AST_NAME_TIME:
    case AST_NAME:
      pNode = new CEvaluationNodeObject(ANY, CCopasiObjectName(std::string("<") + node.getName() + std::string(">")));
      break;
    default:
      break;
    }
  return pNode;
}

ASTNode* CEvaluationNodeObject::toAST() const
  {
    ASTNode* node = new ASTNode();
    node->setType(AST_NAME);
    // since I can not get the model in which this node is located, I just
    // assume that it will always be the current global model.
    CCopasiObject* object = CCopasiContainer::ObjectFromName(mRegisteredObjectCN);
    assert(object);
    // if it is a reference, we get the parent of the reference
    if (object->isReference())
      {
        object = object->getObjectParent();
      }
    CModelEntity* pME = dynamic_cast<CModelEntity*>(object);
    if (pME != NULL)
      {
        CModel* pModel = dynamic_cast<CModel*>(pME);
        if (pModel != NULL)
          {
            node->setType(AST_NAME_TIME);
            node->setName("time");
            if (pModel->getInitialTime() != 0.0)
              {
                CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1);
              }
          }
        else
          {
            node->setName(pME->getSBMLId().c_str());
          }
      }
    else
      {
        CCopasiParameter* pPara = dynamic_cast<CCopasiParameter*>(object);
        if (pPara != NULL)
          {
            node->setName(pPara->getObjectName().c_str());
          }
        else
          {
            fatalError();
          }
      }
    return node;
  }

const CRegisteredObjectName & CEvaluationNodeObject::getObjectCN() const
  {return mRegisteredObjectCN;}

#include "utilities/copasimathml.h"

void CEvaluationNodeObject::writeMathML(std::ostream & out,
                                        const std::vector<std::vector<std::string> > & /* env */,
                                        bool /* expand */,
                                        unsigned C_INT32 l) const
  {
    const CCopasiObject* obj = CCopasiContainer::ObjectFromName(mRegisteredObjectCN);
    out << SPC(l) << CMathMl::getMMLName(obj) << std::endl;
    //or use mValue instead?
  }
<|endoftext|>


<commit_before>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

const int width=640, height=480;
const int pipRadius = 10;
const int racketWidth = 20;

int pipX = width/2, pipY = height/2;

int pipStartSpeed = 300; // pixels per second

int pipXSpeed, pipYSpeed;

int racketSpeed = 200;

int lastTime = 0;

enum RacketPosition {LEFT, RIGHT};

struct Racket {
    int y;
    int size;
    int halfSize;
    int speed;
    float r, g, b;
    RacketPosition position;

    Racket(RacketPosition position, int y, int size, int speed, float r, float g, float b) {
        this->position = position;
        this->speed = speed;
        this->y = y;
        this->size = size;
        this->halfSize = size/2;
        this->r = r;
        this->g = g;
        this->b = b;
    }
};

Racket racket1 = Racket(LEFT, height/2, 120, 0, 1, 1, 0);
Racket racket2 = Racket(RIGHT, height/2, 120, 0, 0, 1, 1);

void reshape(GLFWwindow* window, int width, int height ) {
    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION );
    glLoadIdentity();
    glScalef(1.f, -1.f, 1.f);
    glOrtho(0, width, height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

void drawNet() {
    glPushMatrix();

    glColor3f(0, 0, 1);
    glLineWidth(5);

    glBegin(GL_LINES);
        glVertex2d(width/2, 0);
        glVertex2d(width/2, height);
    glEnd();

    glPopMatrix();
}

void drawBall() {
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);

    glBegin(GL_QUADS);
        glVertex2d(pipX - pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY - pipRadius);
        glVertex2d(pipX - pipRadius, pipY - pipRadius);
    glEnd();

    glPopMatrix();
}

void drawRacket(Racket racket) {
    glPushMatrix();

    glColor3f(racket.r, racket.g, racket.b);

    int racketLeft;

    switch(racket.position) {
        case RIGHT:
            racketLeft = width - racketWidth;
            break;
        case LEFT:
            racketLeft = 0;
        default:
            break;
    }

    glBegin(GL_QUADS);
        glVertex2d(racketLeft, racket.y + racket.halfSize);
        glVertex2d(racketLeft + racketWidth, racket.y + racket.halfSize);
        glVertex2d(racketLeft + racketWidth, racket.y - racket.halfSize);
        glVertex2d(racketLeft, racket.y - racket.halfSize);
    glEnd();

    glPopMatrix();
}

void resetPipSpeed() {
    pipXSpeed = (pipStartSpeed + 25 - (rand() % 50)) * (rand()%2 > 0 ? 1 : -1);
    pipYSpeed = (pipStartSpeed + 25 - (rand() % 50)) * (rand()%2 > 0 ? 1 : -1);
}

int guessWherePipIsGoing() {
    int distanceToWall = 0;
    if (pipXSpeed > 0) {
        distanceToWall = width - (pipRadius * 2) - pipX;
    } else {
        distanceToWall = pipX - (pipRadius * 2);
    }
    float angle = atan(pipYSpeed / abs(pipXSpeed));
    int guess = pipY + (tan(angle) * distanceToWall);

    cout << "predicted y: " << guess << endl;

    if (guess > height) {
        guess = height*3/4;
    } else if (guess < 0) {
        guess = height/4;
    }

    return guess;
}

void moveRacketToY(Racket & racket, int timeDiff) {
    int targetY = height/2;

    racket.speed = 0;

    if (racket.position == RIGHT && pipXSpeed > 0) {
        targetY = guessWherePipIsGoing();
    } else if (racket.position == LEFT && pipXSpeed <= 0) {
        targetY = guessWherePipIsGoing();
    }

    if(racket.y < targetY) {
        if (height - racket.y <= racket.halfSize) {
            racket.y = height - racket.halfSize;
        } else if (targetY - racket.y > (racketSpeed * timeDiff) / 1000) {
            racket.y += (racketSpeed * timeDiff) / 1000;
            racket.speed += racketSpeed;
        } else {
            racket.y = targetY;
        }
    } else if(racket.y > targetY) {
        if (racket.y <= racket.halfSize) {
            racket.y = racket.halfSize;
        } else if (racket.y - targetY > (racketSpeed * timeDiff) / 1000) {
            racket.y -= (racketSpeed * timeDiff) / 1000;
            racket.speed -= racketSpeed;
        } else {
            racket.y = targetY;
        }
    }
}

bool collidesWithRacket(Racket racket) {
    if (pipY > racket.y + racket.halfSize || pipY < racket.y - racket.halfSize)
        return false;

    switch(racket.position) {
        case RIGHT:
            if (pipX < width - racketWidth)
                return false;
            break;
        case LEFT:
            if (pipX > racketWidth)
                return false;
        default:
            break;
    }

    pipYSpeed += racket.speed;
    return true;

}

void recalculateBall(int timeDiff) {
    pipX += (pipXSpeed * timeDiff)/1000;
    pipY += (pipYSpeed * timeDiff)/1000;

    if (pipY < pipRadius || pipY > height - pipRadius) {
        if (pipY < pipRadius) pipY = pipRadius;
        if (pipY > height - pipRadius) pipY = height - pipRadius;
        pipYSpeed = -pipYSpeed;
    }

    if (collidesWithRacket(racket1) || collidesWithRacket(racket2)) {
        if (pipX < racketWidth + pipRadius) pipX = racketWidth + pipRadius;
        if (pipX > width - racketWidth - pipRadius) pipX = width - racketWidth - pipRadius;
        pipXSpeed = -pipXSpeed;
    } else if (pipX < pipRadius || pipX > width - pipRadius) {
        if (pipX < pipRadius) pipX = pipRadius;
        if (pipX > width - pipRadius) pipX = width - pipRadius;
        pipX = width/2;
        pipY = height/2;
        resetPipSpeed();
    }
}

int main(void) {
    srand(time(NULL));

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(width, height, "Lana Tennis", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    reshape(window, width, height);

    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glfwSetWindowSizeCallback(window, reshape);

    resetPipSpeed();

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window)) {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        int newTime = floor(glfwGetTime() * 1000);
        if (newTime - lastTime > 10) {
            recalculateBall(newTime - lastTime);

            moveRacketToY(racket1, newTime - lastTime);
            moveRacketToY(racket2, newTime - lastTime);

            lastTime = newTime;
        }

        drawNet();
        drawBall();
        drawRacket(racket1);
        drawRacket(racket2);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}<commit_msg>Reduce racket size to 60<commit_after>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

const int width=640, height=480;
const int pipRadius = 10;
const int racketWidth = 20;

int pipX = width/2, pipY = height/2;

int pipStartSpeed = 300; // pixels per second

int pipXSpeed, pipYSpeed;

int racketSpeed = 200;

int lastTime = 0;

enum RacketPosition {LEFT, RIGHT};

struct Racket {
    int y;
    int size;
    int halfSize;
    int speed;
    float r, g, b;
    RacketPosition position;

    Racket(RacketPosition position, int y, int size, int speed, float r, float g, float b) {
        this->position = position;
        this->speed = speed;
        this->y = y;
        this->size = size;
        this->halfSize = size/2;
        this->r = r;
        this->g = g;
        this->b = b;
    }
};

Racket racket1 = Racket(LEFT, height/2, 60, 0, 1, 1, 0);
Racket racket2 = Racket(RIGHT, height/2, 60, 0, 0, 1, 1);

void reshape(GLFWwindow* window, int width, int height ) {
    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION );
    glLoadIdentity();
    glScalef(1.f, -1.f, 1.f);
    glOrtho(0, width, height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

void drawNet() {
    glPushMatrix();

    glColor3f(0, 0, 1);
    glLineWidth(5);

    glBegin(GL_LINES);
        glVertex2d(width/2, 0);
        glVertex2d(width/2, height);
    glEnd();

    glPopMatrix();
}

void drawBall() {
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);

    glBegin(GL_QUADS);
        glVertex2d(pipX - pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY - pipRadius);
        glVertex2d(pipX - pipRadius, pipY - pipRadius);
    glEnd();

    glPopMatrix();
}

void drawRacket(Racket racket) {
    glPushMatrix();

    glColor3f(racket.r, racket.g, racket.b);

    int racketLeft;

    switch(racket.position) {
        case RIGHT:
            racketLeft = width - racketWidth;
            break;
        case LEFT:
            racketLeft = 0;
        default:
            break;
    }

    glBegin(GL_QUADS);
        glVertex2d(racketLeft, racket.y + racket.halfSize);
        glVertex2d(racketLeft + racketWidth, racket.y + racket.halfSize);
        glVertex2d(racketLeft + racketWidth, racket.y - racket.halfSize);
        glVertex2d(racketLeft, racket.y - racket.halfSize);
    glEnd();

    glPopMatrix();
}

void resetPipSpeed() {
    pipXSpeed = (pipStartSpeed + 25 - (rand() % 50)) * (rand()%2 > 0 ? 1 : -1);
    pipYSpeed = (pipStartSpeed + 25 - (rand() % 50)) * (rand()%2 > 0 ? 1 : -1);
}

int guessWherePipIsGoing() {
    int distanceToWall = 0;
    if (pipXSpeed > 0) {
        distanceToWall = width - (pipRadius * 2) - pipX;
    } else {
        distanceToWall = pipX - (pipRadius * 2);
    }
    float angle = atan(pipYSpeed / abs(pipXSpeed));
    int guess = pipY + (tan(angle) * distanceToWall);

    cout << "predicted y: " << guess << endl;

    if (guess > height) {
        guess = height*3/4;
    } else if (guess < 0) {
        guess = height/4;
    }

    return guess;
}

void moveRacketToY(Racket & racket, int timeDiff) {
    int targetY = height/2;

    racket.speed = 0;

    if (racket.position == RIGHT && pipXSpeed > 0) {
        targetY = guessWherePipIsGoing();
    } else if (racket.position == LEFT && pipXSpeed <= 0) {
        targetY = guessWherePipIsGoing();
    }

    if(racket.y < targetY) {
        if (height - racket.y <= racket.halfSize) {
            racket.y = height - racket.halfSize;
        } else if (targetY - racket.y > (racketSpeed * timeDiff) / 1000) {
            racket.y += (racketSpeed * timeDiff) / 1000;
            racket.speed += racketSpeed;
        } else {
            racket.y = targetY;
        }
    } else if(racket.y > targetY) {
        if (racket.y <= racket.halfSize) {
            racket.y = racket.halfSize;
        } else if (racket.y - targetY > (racketSpeed * timeDiff) / 1000) {
            racket.y -= (racketSpeed * timeDiff) / 1000;
            racket.speed -= racketSpeed;
        } else {
            racket.y = targetY;
        }
    }
}

bool collidesWithRacket(Racket racket) {
    if (pipY > racket.y + racket.halfSize || pipY < racket.y - racket.halfSize)
        return false;

    switch(racket.position) {
        case RIGHT:
            if (pipX < width - racketWidth)
                return false;
            break;
        case LEFT:
            if (pipX > racketWidth)
                return false;
        default:
            break;
    }

    pipYSpeed += racket.speed;
    return true;

}

void recalculateBall(int timeDiff) {
    pipX += (pipXSpeed * timeDiff)/1000;
    pipY += (pipYSpeed * timeDiff)/1000;

    if (pipY < pipRadius || pipY > height - pipRadius) {
        if (pipY < pipRadius) pipY = pipRadius;
        if (pipY > height - pipRadius) pipY = height - pipRadius;
        pipYSpeed = -pipYSpeed;
    }

    if (collidesWithRacket(racket1) || collidesWithRacket(racket2)) {
        if (pipX < racketWidth + pipRadius) pipX = racketWidth + pipRadius;
        if (pipX > width - racketWidth - pipRadius) pipX = width - racketWidth - pipRadius;
        pipXSpeed = -pipXSpeed;
    } else if (pipX < pipRadius || pipX > width - pipRadius) {
        if (pipX < pipRadius) pipX = pipRadius;
        if (pipX > width - pipRadius) pipX = width - pipRadius;
        pipX = width/2;
        pipY = height/2;
        resetPipSpeed();
    }
}

int main(void) {
    srand(time(NULL));

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(width, height, "Lana Tennis", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    reshape(window, width, height);

    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glfwSetWindowSizeCallback(window, reshape);

    resetPipSpeed();

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window)) {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        int newTime = floor(glfwGetTime() * 1000);
        if (newTime - lastTime > 10) {
            recalculateBall(newTime - lastTime);

            moveRacketToY(racket1, newTime - lastTime);
            moveRacketToY(racket2, newTime - lastTime);

            lastTime = newTime;
        }

        drawNet();
        drawBall();
        drawRacket(racket1);
        drawRacket(racket2);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// main.cpp
// Description : Main programm, were everything starts
//
// Author : Stefan Papst
// Softwareengeneering and Businessmanagement @ TU GRAZ
//------------------------------------------------------------------------------

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
  //Init the win
  sf::RenderWindow window(sf::VideoMode(600, 600), "SFML PingPong");
  window.setVerticalSyncEnabled(true);
  //create background with color "white
  sf::RectangleShape background(sf::Vector2f(600.f, 600.f));
  background.setFillColor(sf::Color::White);

  //load texture
  sf::Texture smiley;
  if (!smiley.loadFromFile("smiley.png"))
  {
    std::cout << "Loading File not possible!" << std::endl;
    std::cin.get();
    return 1;
  }
  //put texture in sprite
  smiley.setSmooth(true);
  sf::Sprite sprite;
  sprite.setTexture(smiley);
  sprite.setPosition(275.f, 275.f);
  sprite.setScale(.5f,.5f);

  //while running loop
  while (window.isOpen())
  {

  sf::Event event;
  while (window.pollEvent(event))
  {
    switch (event.type)
    {
      case sf::Event::Closed:
        window.close();
        break;
      case sf::Event::KeyPressed:
        switch (event.key.code)
        {
          case sf::Keyboard::W:
            sprite.move(0.f,-5.f);
            //std::cout << "notized key W" << std::endl;
            break;
          case sf::Keyboard::S:
            sprite.move(0.f, 5.f);
            //std::cout << "notized key S" << std::endl;
            break;
          case sf::Keyboard::A:
            sprite.move(-5.f, 0.f);
            //std::cout << "notized key A" << std::endl;
            break;
          case sf::Keyboard::D:
            sprite.move(5.f, 0.f);
            //std::cout << "notized key D" << std::endl;
            break;
        }
        break;

    }

  }

  window.clear();
  window.draw(background);
  window.draw(sprite);
  window.display();
  }
  return 0;
}<commit_msg>-put keyboard handling out of pollevent loop to get smooth movement<commit_after>//------------------------------------------------------------------------------
// main.cpp
// Description : Main programm, were everything starts
//
// Author : Stefan Papst
// Softwareengeneering and Businessmanagement @ TU GRAZ
//------------------------------------------------------------------------------

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
  //Init the win
  sf::RenderWindow window(sf::VideoMode(600, 600), "SFML PingPong");
  window.setVerticalSyncEnabled(true);
  //create background with color "white
  sf::RectangleShape background(sf::Vector2f(600.f, 600.f));
  background.setFillColor(sf::Color::White);

  //load texture
  sf::Texture smiley;
  if (!smiley.loadFromFile("smiley.png"))
  {
    std::cout << "Loading File not possible!" << std::endl;
    std::cin.get();
    return 1;
  }
  //put texture in sprite
  smiley.setSmooth(true);
  sf::Sprite sprite;
  sprite.setTexture(smiley);
  sprite.setPosition(275.f, 275.f);
  sprite.setScale(.5f,.5f);

  //while running loop
  while (window.isOpen())
  {

  sf::Event event;
  while (window.pollEvent(event))
  {
    switch (event.type)
    {
      case sf::Event::Closed:
        window.close();
        break;
    }

  }
   //smooth movement
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
      sprite.move(0.f, -5.f);
      //std::cout << "notized key W" << std::endl;
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
      sprite.move(0.f, 5.f);
        //std::cout << "notized key S" << std::endl;
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
      sprite.move(-5.f, 0.f);
      //std::cout << "notized key A" << std::endl;
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
      sprite.move(5.f, 0.f);
      //std::cout << "notized key D" << std::endl;

  window.clear();
  window.draw(background);
  window.draw(sprite);
  window.display();
  }
  return 0;
}<|endoftext|>