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

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

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

#include "braininavat.h"
#include <QtGui>
#include "brainview.h"
#include "c2eBrain.h"

#include <fstream>
using namespace std;

// Constructor which creates the main window.

BrainInAVat::BrainInAVat() {
	ourCreature = 0;
	scrollArea = new QScrollArea(this);
	ourView = new BrainView(this);
	scrollArea->setWidget(ourView);
	setCentralWidget(scrollArea);

	(void)statusBar();
	setWindowTitle(tr("openc2e's Brain in a Vat"));
	resize(600, 400);

	/* File menu */

	openAct = new QAction(tr("&Open..."), this);
	openAct->setShortcut(tr("Ctrl+O"));
	openAct->setStatusTip(tr("Open a genome file"));
	connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

	for (int i = 0; i < MaxRecentFiles; ++i) {
		recentFileActs[i] = new QAction(this);
		recentFileActs[i]->setVisible(false);
		connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));
	}

	exitAct = new QAction(tr("E&xit"), this);
	exitAct->setShortcut(tr("Ctrl+Q"));
	exitAct->setStatusTip(tr("Exit Brain in a Vat"));
	connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(openAct);
	separatorAct = fileMenu->addSeparator();
	for (int i = 0; i < MaxRecentFiles; ++i)
		fileMenu->addAction(recentFileActs[i]);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAct);
	updateRecentFileActions();

	/* View menu */

	neuronActGroup = new QActionGroup(this);
	dendriteActGroup = new QActionGroup(this);
	thresholdActGroup = new QActionGroup(this);

	// neuron/dendrite variable selection
	for (unsigned int i = 0; i < 8; i++) {
		// TODO: friendly names for neuron/dendrite vars

		neuronActs[i] = new QAction(tr("Neuron var %1").arg(i), this);
		neuronActGroup->addAction(neuronActs[i]);
		neuronActs[i]->setCheckable(true);
		connect(neuronActs[i], SIGNAL(triggered()), this, SLOT(setSomeVar()));
		dendriteActs[i] = new QAction(tr("Dendrite var %1").arg(i), this);
		dendriteActGroup->addAction(dendriteActs[i]);
		dendriteActs[i]->setCheckable(true);
		connect(dendriteActs[i], SIGNAL(triggered()), this, SLOT(setSomeVar()));
	}
	neuronActs[0]->setChecked(true);
	dendriteActs[0]->setChecked(true);

	// threshold for element visibility
	noThresholdAct = new QAction(tr("Show all elements"), this);
	thresholdActGroup->addAction(noThresholdAct);
	noThresholdAct->setCheckable(true);
	noThresholdAct->setChecked(true);
	connect(noThresholdAct, SIGNAL(triggered()), this, SLOT(setNoThreshold()));
	nonZeroThresholdAct = new QAction(tr("Show elements with non-zero values only"), this);
	thresholdActGroup->addAction(nonZeroThresholdAct);
	nonZeroThresholdAct->setCheckable(true);
	connect(nonZeroThresholdAct, SIGNAL(triggered()), this, SLOT(setNonZeroThreshold()));
	showNoneAct = new QAction(tr("Show no elements"), this);
	thresholdActGroup->addAction(showNoneAct);
	showNoneAct->setCheckable(true);
	connect(showNoneAct, SIGNAL(triggered()), this, SLOT(setShowNone()));

	viewMenu = menuBar()->addMenu(tr("&View"));
	for (unsigned int i = 0; i < 8; i++)
		viewMenu->addAction(neuronActs[i]);
	viewMenu->addSeparator();
	for (unsigned int i = 0; i < 8; i++)
		viewMenu->addAction(dendriteActs[i]);
	viewMenu->addSeparator();
	viewMenu->addAction(noThresholdAct);
	viewMenu->addAction(nonZeroThresholdAct);
	viewMenu->addAction(showNoneAct);

	/* Control menu */

	tickAct = new QAction(tr("&Tick"), this);
	tickAct->setStatusTip(tr("Run the brain through one iteration"));
	tickAct->setEnabled(false);
	connect(tickAct, SIGNAL(triggered()), this, SLOT(tick()));

	sleepToggleAct = new QAction(tr("&Sleep"), this);
	sleepToggleAct->setStatusTip(tr("Set whether the brain is asleep (and dreaming) or not"));
	sleepToggleAct->setCheckable(true);
	sleepToggleAct->setEnabled(false);
	connect(sleepToggleAct, SIGNAL(triggered()), this, SLOT(toggleSleep()));

	controlMenu = menuBar()->addMenu(tr("&Control"));
	controlMenu->addAction(tickAct);
	controlMenu->addAction(sleepToggleAct);

	controlToolbar = addToolBar(tr("Control"));
	controlToolbar->addAction(tickAct);

	/* Help menu */

	menuBar()->addSeparator();

	aboutAct = new QAction(tr("&About"), this);
	aboutAct->setStatusTip(tr("Find out about Brain in a Vat"));
	connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAct);
}

BrainInAVat::~BrainInAVat() {
	if (ourCreature)
		delete ourCreature;
	delete ourView;
}

// action handlers

void BrainInAVat::open() {
	QString fileName = QFileDialog::getOpenFileName(this, tr("Pick a genome"), QString(), tr("Genomes (*.gen)"));
	if (!fileName.isEmpty())
		loadFile(fileName);
}

void BrainInAVat::openRecentFile() {
	QAction *action = qobject_cast<QAction *>(sender());

	if (action)
		loadFile(action->data().toString());
}

void BrainInAVat::about() {
	QMessageBox::about(this, tr("openc2e's Brain in a Vat"), tr("An openc2e tool to monitor and experiment upon creature brains."));
}

void BrainInAVat::tick() {
	// brain updates are every 4 ticks
	// TODO: this is icky
	for (unsigned int i = 0; i < 4; i++)
		ourCreature->tick();

	ourView->update();
}

void BrainInAVat::setSomeVar() {
	QAction *action = qobject_cast<QAction *>(sender());

	for (unsigned int i = 0; i < 8; i++) {
		if (action == neuronActs[i])
			ourView->neuron_var = i;
		else if (action == dendriteActs[i])
			ourView->dendrite_var = i;
	}

	ourView->update();
}

void BrainInAVat::setNoThreshold() {
	ourView->threshold = -1000.0f;
	ourView->update();
}

void BrainInAVat::setNonZeroThreshold() {
	ourView->threshold = 0.0f;
	ourView->update();
}

void BrainInAVat::setShowNone() {
	ourView->threshold = 1000.0f;
	ourView->update();
}

void BrainInAVat::toggleSleep() {
	ourCreature->setDreaming(!ourCreature->isDreaming());
	sleepToggleAct->setChecked(ourCreature->isDreaming());
}

// code to Do Things!

void BrainInAVat::loadFile(const QString &fileName) {
	// zot any existing file
	setCurrentFile(QString());
	if (ourCreature) {
		delete ourCreature;
		ourCreature = 0;
	}
	tickAct->setEnabled(false);
	sleepToggleAct->setChecked(false);
	sleepToggleAct->setEnabled(false);
	ourView->update();

	ifstream f(fileName.toAscii(), std::ios::binary);
	if (f.fail()) {
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("Cannot read file %1.").arg(fileName));
		return;
	}

	QApplication::setOverrideCursor(Qt::WaitCursor);

	// read genome
	f >> noskipws;
	shared_ptr<genomeFile> gfile(new genomeFile());
	try {
		f >> *gfile;
	} catch (genomeException &e) {
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("Failed loading the genome due to error '%1'!").arg(e.what()));
		QApplication::restoreOverrideCursor();
		return;
	}

	// TODO: dialog to pick age, gender, variant?

	// create creature
	if (gfile->getVersion() == 3) {
		ourCreature = new c2eCreature(gfile, true, 0);
	} else {
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("This genome is of version %1, which is unsupported.").arg(gfile->getVersion()));
		QApplication::restoreOverrideCursor();
		return;
	}

	QApplication::restoreOverrideCursor();

	// we're done; update title/recent files, and display a temporary status message
	tickAct->setEnabled(true);
	sleepToggleAct->setEnabled(true);
	ourView->resize(ourView->minimumSize());
	ourView->update();
	setCurrentFile(fileName);
	statusBar()->showMessage(tr("Loaded %1 genes").arg(gfile->genes.size()), 2000);
}

// Some Recent Files magic.

void BrainInAVat::setCurrentFile(const QString &fileName) {
	curFile = fileName;
	if (curFile.isEmpty()) {
		setWindowTitle(tr("openc2e's Brain in a Vat"));
		return; // TODO: is this correct?
	} else
		setWindowTitle(tr("%1 - %2").arg(strippedName(curFile)).arg(tr("openc2e's Brain in a Vat")));

	// read the list of recent files
	QSettings settings("ccdevnet.org", "Brain In A Vat");
	QStringList files = settings.value("recentFileList").toStringList();

	// make sure the current file is at the top!
	files.removeAll(fileName);
	files.prepend(fileName);
	// remove any which are over the size
	while (files.size() > MaxRecentFiles)
		files.removeLast();

	// store the list of recent files
	settings.setValue("recentFileList", files);

	// update ourselves..
	updateRecentFileActions(); // obviously assumes we only have one window
}

void BrainInAVat::updateRecentFileActions() {
	// read the list of recent files
	QSettings settings("ccdevnet.org", "Brain In A Vat");
	QStringList files = settings.value("recentFileList").toStringList();

	// enable recent files actions as needed
	int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);
	for (int i = 0; i < numRecentFiles; ++i) {
		QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
		recentFileActs[i]->setText(text);
		recentFileActs[i]->setData(files[i]);
		recentFileActs[i]->setVisible(true);
	}

	// make sure the rest are disabled [ie, hidden]
	for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
		recentFileActs[j]->setVisible(false);

	// only show the separator if there are recent files
	separatorAct->setVisible(numRecentFiles > 0);
}

QString BrainInAVat::strippedName(const QString &fullFileName) {
	return QFileInfo(fullFileName).fileName();
}

<commit_msg>braininavat: catch exceptions from c2eCreature constructor<commit_after>/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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

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

#include "braininavat.h"
#include <QtGui>
#include "brainview.h"
#include "c2eBrain.h"

#include <fstream>
using namespace std;

// Constructor which creates the main window.

BrainInAVat::BrainInAVat() {
	ourCreature = 0;
	scrollArea = new QScrollArea(this);
	ourView = new BrainView(this);
	scrollArea->setWidget(ourView);
	setCentralWidget(scrollArea);

	(void)statusBar();
	setWindowTitle(tr("openc2e's Brain in a Vat"));
	resize(600, 400);

	/* File menu */

	openAct = new QAction(tr("&Open..."), this);
	openAct->setShortcut(tr("Ctrl+O"));
	openAct->setStatusTip(tr("Open a genome file"));
	connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

	for (int i = 0; i < MaxRecentFiles; ++i) {
		recentFileActs[i] = new QAction(this);
		recentFileActs[i]->setVisible(false);
		connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));
	}

	exitAct = new QAction(tr("E&xit"), this);
	exitAct->setShortcut(tr("Ctrl+Q"));
	exitAct->setStatusTip(tr("Exit Brain in a Vat"));
	connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(openAct);
	separatorAct = fileMenu->addSeparator();
	for (int i = 0; i < MaxRecentFiles; ++i)
		fileMenu->addAction(recentFileActs[i]);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAct);
	updateRecentFileActions();

	/* View menu */

	neuronActGroup = new QActionGroup(this);
	dendriteActGroup = new QActionGroup(this);
	thresholdActGroup = new QActionGroup(this);

	// neuron/dendrite variable selection
	for (unsigned int i = 0; i < 8; i++) {
		// TODO: friendly names for neuron/dendrite vars

		neuronActs[i] = new QAction(tr("Neuron var %1").arg(i), this);
		neuronActGroup->addAction(neuronActs[i]);
		neuronActs[i]->setCheckable(true);
		connect(neuronActs[i], SIGNAL(triggered()), this, SLOT(setSomeVar()));
		dendriteActs[i] = new QAction(tr("Dendrite var %1").arg(i), this);
		dendriteActGroup->addAction(dendriteActs[i]);
		dendriteActs[i]->setCheckable(true);
		connect(dendriteActs[i], SIGNAL(triggered()), this, SLOT(setSomeVar()));
	}
	neuronActs[0]->setChecked(true);
	dendriteActs[0]->setChecked(true);

	// threshold for element visibility
	noThresholdAct = new QAction(tr("Show all elements"), this);
	thresholdActGroup->addAction(noThresholdAct);
	noThresholdAct->setCheckable(true);
	noThresholdAct->setChecked(true);
	connect(noThresholdAct, SIGNAL(triggered()), this, SLOT(setNoThreshold()));
	nonZeroThresholdAct = new QAction(tr("Show elements with non-zero values only"), this);
	thresholdActGroup->addAction(nonZeroThresholdAct);
	nonZeroThresholdAct->setCheckable(true);
	connect(nonZeroThresholdAct, SIGNAL(triggered()), this, SLOT(setNonZeroThreshold()));
	showNoneAct = new QAction(tr("Show no elements"), this);
	thresholdActGroup->addAction(showNoneAct);
	showNoneAct->setCheckable(true);
	connect(showNoneAct, SIGNAL(triggered()), this, SLOT(setShowNone()));

	viewMenu = menuBar()->addMenu(tr("&View"));
	for (unsigned int i = 0; i < 8; i++)
		viewMenu->addAction(neuronActs[i]);
	viewMenu->addSeparator();
	for (unsigned int i = 0; i < 8; i++)
		viewMenu->addAction(dendriteActs[i]);
	viewMenu->addSeparator();
	viewMenu->addAction(noThresholdAct);
	viewMenu->addAction(nonZeroThresholdAct);
	viewMenu->addAction(showNoneAct);

	/* Control menu */

	tickAct = new QAction(tr("&Tick"), this);
	tickAct->setStatusTip(tr("Run the brain through one iteration"));
	tickAct->setEnabled(false);
	connect(tickAct, SIGNAL(triggered()), this, SLOT(tick()));

	sleepToggleAct = new QAction(tr("&Sleep"), this);
	sleepToggleAct->setStatusTip(tr("Set whether the brain is asleep (and dreaming) or not"));
	sleepToggleAct->setCheckable(true);
	sleepToggleAct->setEnabled(false);
	connect(sleepToggleAct, SIGNAL(triggered()), this, SLOT(toggleSleep()));

	controlMenu = menuBar()->addMenu(tr("&Control"));
	controlMenu->addAction(tickAct);
	controlMenu->addAction(sleepToggleAct);

	controlToolbar = addToolBar(tr("Control"));
	controlToolbar->addAction(tickAct);

	/* Help menu */

	menuBar()->addSeparator();

	aboutAct = new QAction(tr("&About"), this);
	aboutAct->setStatusTip(tr("Find out about Brain in a Vat"));
	connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAct);
}

BrainInAVat::~BrainInAVat() {
	if (ourCreature)
		delete ourCreature;
	delete ourView;
}

// action handlers

void BrainInAVat::open() {
	QString fileName = QFileDialog::getOpenFileName(this, tr("Pick a genome"), QString(), tr("Genomes (*.gen)"));
	if (!fileName.isEmpty())
		loadFile(fileName);
}

void BrainInAVat::openRecentFile() {
	QAction *action = qobject_cast<QAction *>(sender());

	if (action)
		loadFile(action->data().toString());
}

void BrainInAVat::about() {
	QMessageBox::about(this, tr("openc2e's Brain in a Vat"), tr("An openc2e tool to monitor and experiment upon creature brains."));
}

void BrainInAVat::tick() {
	// brain updates are every 4 ticks
	// TODO: this is icky
	for (unsigned int i = 0; i < 4; i++)
		ourCreature->tick();

	ourView->update();
}

void BrainInAVat::setSomeVar() {
	QAction *action = qobject_cast<QAction *>(sender());

	for (unsigned int i = 0; i < 8; i++) {
		if (action == neuronActs[i])
			ourView->neuron_var = i;
		else if (action == dendriteActs[i])
			ourView->dendrite_var = i;
	}

	ourView->update();
}

void BrainInAVat::setNoThreshold() {
	ourView->threshold = -1000.0f;
	ourView->update();
}

void BrainInAVat::setNonZeroThreshold() {
	ourView->threshold = 0.0f;
	ourView->update();
}

void BrainInAVat::setShowNone() {
	ourView->threshold = 1000.0f;
	ourView->update();
}

void BrainInAVat::toggleSleep() {
	ourCreature->setDreaming(!ourCreature->isDreaming());
	sleepToggleAct->setChecked(ourCreature->isDreaming());
}

// code to Do Things!

void BrainInAVat::loadFile(const QString &fileName) {
	// zot any existing file
	setCurrentFile(QString());
	if (ourCreature) {
		delete ourCreature;
		ourCreature = 0;
	}
	tickAct->setEnabled(false);
	sleepToggleAct->setChecked(false);
	sleepToggleAct->setEnabled(false);
	ourView->update();

	ifstream f(fileName.toAscii(), std::ios::binary);
	if (f.fail()) {
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("Cannot read file %1.").arg(fileName));
		return;
	}

	QApplication::setOverrideCursor(Qt::WaitCursor);

	// read genome
	f >> noskipws;
	shared_ptr<genomeFile> gfile(new genomeFile());
	try {
		f >> *gfile;
	} catch (genomeException &e) {
		QApplication::restoreOverrideCursor();
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("Failed loading the genome due to error '%1'!").arg(e.what()));
		return;
	}

	// TODO: dialog to pick age, gender, variant?

	// create creature
	if (gfile->getVersion() == 3) {
		try {
			ourCreature = new c2eCreature(gfile, true, 0);
		} catch (creaturesException &e) {
			QApplication::restoreOverrideCursor();
			QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), e.what());
			return;
		}
	} else {
		QApplication::restoreOverrideCursor();
		QMessageBox::warning(this, tr("openc2e's Brain in a Vat"), tr("This genome is of version %1, which is unsupported.").arg(gfile->getVersion()));
		return;
	}

	QApplication::restoreOverrideCursor();

	// we're done; update title/recent files, and display a temporary status message
	tickAct->setEnabled(true);
	sleepToggleAct->setEnabled(true);
	ourView->resize(ourView->minimumSize());
	ourView->update();
	setCurrentFile(fileName);
	statusBar()->showMessage(tr("Loaded %1 genes").arg(gfile->genes.size()), 2000);
}

// Some Recent Files magic.

void BrainInAVat::setCurrentFile(const QString &fileName) {
	curFile = fileName;
	if (curFile.isEmpty()) {
		setWindowTitle(tr("openc2e's Brain in a Vat"));
		return; // TODO: is this correct?
	} else
		setWindowTitle(tr("%1 - %2").arg(strippedName(curFile)).arg(tr("openc2e's Brain in a Vat")));

	// read the list of recent files
	QSettings settings("ccdevnet.org", "Brain In A Vat");
	QStringList files = settings.value("recentFileList").toStringList();

	// make sure the current file is at the top!
	files.removeAll(fileName);
	files.prepend(fileName);
	// remove any which are over the size
	while (files.size() > MaxRecentFiles)
		files.removeLast();

	// store the list of recent files
	settings.setValue("recentFileList", files);

	// update ourselves..
	updateRecentFileActions(); // obviously assumes we only have one window
}

void BrainInAVat::updateRecentFileActions() {
	// read the list of recent files
	QSettings settings("ccdevnet.org", "Brain In A Vat");
	QStringList files = settings.value("recentFileList").toStringList();

	// enable recent files actions as needed
	int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);
	for (int i = 0; i < numRecentFiles; ++i) {
		QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
		recentFileActs[i]->setText(text);
		recentFileActs[i]->setData(files[i]);
		recentFileActs[i]->setVisible(true);
	}

	// make sure the rest are disabled [ie, hidden]
	for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
		recentFileActs[j]->setVisible(false);

	// only show the separator if there are recent files
	separatorAct->setVisible(numRecentFiles > 0);
}

QString BrainInAVat::strippedName(const QString &fullFileName) {
	return QFileInfo(fullFileName).fileName();
}

<|endoftext|>


<commit_before>#include <iostream>

#include <Windows.h>

#define NDEBUG
#include <GL/freeglut.h>

#include "Rectangle.h"
#include "Circle.h"

#include <vector>

#include <cstdlib>
#include <ctime>

MF::Circle pilka(0.6, 1.0, 0.0, 0.0);
MF::Rectangle paletka(10, 1, 0.0, 1.0, 0.0);

std::vector<MF::Rectangle> sciany;
std::vector<MF::Rectangle> klocki;

int punkty = 0;

/* GLUT callback Handlers */
void resize(int width, int height)
{
	const float ar = (float)width / (float)height;

	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

/*logika gry*/
void loop(int value)
{
	//sprawdzanie kolizji ze cianami
	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		pilka.Kolizja(*itr);
	}

	for (auto itr = klocki.begin(); itr != klocki.end();)
	{
		if (pilka.Kolizja(*itr))
		{
			itr = klocki.erase(itr);
			punkty++;

			// to wywouje problem - system cls jest wolne
			//system("cls");
			//printf("Punkty: %d", punkty);
		}
		else
		{
			itr++;
		}
	}

	//sprawdzanie kolizji z paletk
	pilka.Kolizja(paletka);

	//wyliczenie nowej pozycji piki
	pilka.Aktualizuj(glutGet(GLUT_ELAPSED_TIME));

	pilka.UpdateFigurePosition();

	glutTimerFunc(1, loop, 0);
}

void idle()
{
	glutPostRedisplay();
}

void display()
{
	// clear the scene
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();

	pilka.Draw();
	paletka.Draw();

	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		itr->Draw();
	}

	for (auto itr = klocki.begin(); itr != klocki.end(); itr++)
	{
		itr->Draw();
	}

	glPopMatrix();

	glutSwapBuffers();
}

void passiveMouseMotion(int mouse_x, int mouse_y)
{
	paletka.SetPosition((mouse_x - 300) / 15, -15);
	paletka.UpdatePhysicsPosition();
}

void keyboard(unsigned char key_pressed, int mouse_x, int mouse_y)
{
	switch (key_pressed)
	{
		case 'a':
			{
				paletka.Move(-1.0, 0.0);
			}
			break;
		case 'd':
			{
				paletka.Move(1.0, 0.0);
			}
			break;
	}

	paletka.UpdatePhysicsPosition();
}

void InitGLUTScene(char* window_name)
{
	glutInitWindowSize(600, 600);
	glutInitWindowPosition(40, 40);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);

	glutCreateWindow(window_name);

	// set white as the clear colour
	glClearColor(1, 1, 1, 1);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);
}

void SetCallbackFunctions()
{
	//glutReshapeFunc(resize);
	glutDisplayFunc(display);
	glutIdleFunc(idle);
	glutKeyboardFunc(keyboard);
	glutPassiveMotionFunc(passiveMouseMotion);
	glutTimerFunc(5, loop, 0);

	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
}

void InitObjects()
{
	//pika
	pilka.SetPosition(0, -12);

	pilka.UstawPredkosc(3e-2, 60);
	pilka.UstawFizyke(9.81*1E-6, -90);

	//paletka
	paletka.SetPosition(0, -15);

	//klocki
	for (int l = 2, n = 0; l < 6; l++, n++)
	{
		for (int i = -16; i < 20; i += 4)
		{
			double red = (double)(rand() % 1000) / 1000.0;
			double green = (double)(rand() % 1000) / 1000.0;
			double blue = (double)(rand() % 1000) / 1000.0;
			MF::Rectangle newBlock(4, 1, red, green, blue);
			newBlock.SetPosition(i, l);
			klocki.push_back(newBlock);
		}
	}

	//ciany
	{
		MF::Rectangle sciana(68, 2, 0.5, 0.5, 0.5);
		sciana.SetPosition(0, 20);
		sciany.push_back(sciana);
	}

	{
		MF::Rectangle sciana(4, 60, 0.5, 0.5, 0.5);
		sciana.SetPosition(21, 0);
		sciany.push_back(sciana);
	}

	{
		MF::Rectangle sciana(4, 60, 0.5, 0.5, 0.5);
		sciana.SetPosition(-21, 0);
		sciany.push_back(sciana);
	}

	paletka.UpdatePhysicsPosition();
	pilka.UpdatePhysicsPosition();
	for (auto itr = klocki.begin(); itr != klocki.end(); itr++)
	{
		itr->UpdatePhysicsPosition();
	}
	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		itr->UpdatePhysicsPosition();
	}
}

int main(int argc, char *argv[])
{
	// it's still possible to use console to print messages
	printf("Hello openGL world!");
	// the same can be done with cout / cin

	srand(time(NULL));

	glutInit(&argc, argv);
	InitGLUTScene("freeglut template");

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glOrtho(-20.0, 20.0, -20.0, 20.0, -20.0, 20.0);

	SetCallbackFunctions();
	InitObjects();

	// start GLUT event loop. It ends when user close the window.
	glutMainLoop();

	// sposb na wykonanie czego po zakoczeniu gluta
	printf("End of GLUT");

	return 0;
}<commit_msg>Change from Ortho to Projection, mouse calculation to be fixed<commit_after>#include <iostream>

#include <Windows.h>

#define NDEBUG
#include <GL/freeglut.h>

#include "Rectangle.h"
#include "Circle.h"

#include <vector>

#include <cstdlib>
#include <ctime>

MF::Circle pilka(0.6, 1.0, 0.0, 0.0);
MF::Rectangle paletka(10, 1, 0.0, 1.0, 0.0);

std::vector<MF::Rectangle> sciany;
std::vector<MF::Rectangle> klocki;

int punkty = 0;

/* GLUT callback Handlers */
void resize(int width, int height)
{
	const float ar = (float)width / (float)height;

	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
	gluLookAt(0, 0, 45, 0, 0, 0, 0, 1, 0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

/*logika gry*/
void loop(int value)
{
	//sprawdzanie kolizji ze cianami
	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		pilka.Kolizja(*itr);
	}

	for (auto itr = klocki.begin(); itr != klocki.end();)
	{
		if (pilka.Kolizja(*itr))
		{
			itr = klocki.erase(itr);
			punkty++;

			// to wywouje problem - system cls jest wolne
			//system("cls");
			//printf("Punkty: %d", punkty);
		}
		else
		{
			itr++;
		}
	}

	//sprawdzanie kolizji z paletk
	pilka.Kolizja(paletka);

	//wyliczenie nowej pozycji piki
	pilka.Aktualizuj(glutGet(GLUT_ELAPSED_TIME));

	pilka.UpdateFigurePosition();

	glutTimerFunc(1, loop, 0);
}

void idle()
{
	glutPostRedisplay();
}

void display()
{
	// clear the scene
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();

	pilka.Draw();
	paletka.Draw();

	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		itr->Draw();
	}

	for (auto itr = klocki.begin(); itr != klocki.end(); itr++)
	{
		itr->Draw();
	}

	glPopMatrix();

	glutSwapBuffers();
}

void passiveMouseMotion(int mouse_x, int mouse_y)
{
	paletka.SetPosition((mouse_x - 300) / 15, -15);
	paletka.UpdatePhysicsPosition();
}

void keyboard(unsigned char key_pressed, int mouse_x, int mouse_y)
{
	switch (key_pressed)
	{
		case 'a':
			{
				paletka.Move(-1.0, 0.0);
			}
			break;
		case 'd':
			{
				paletka.Move(1.0, 0.0);
			}
			break;
	}

	paletka.UpdatePhysicsPosition();
}

void InitGLUTScene(char* window_name)
{
	glutInitWindowSize(600, 600);
	glutInitWindowPosition(40, 40);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);

	glutCreateWindow(window_name);

	// set white as the clear colour
	glClearColor(1, 1, 1, 1);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);
}

void SetCallbackFunctions()
{
	glutReshapeFunc(resize);
	glutDisplayFunc(display);
	glutIdleFunc(idle);
	glutKeyboardFunc(keyboard);
	glutPassiveMotionFunc(passiveMouseMotion);
	glutTimerFunc(5, loop, 0);

	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
}

void InitObjects()
{
	//pika
	pilka.SetPosition(0, -12);

	pilka.UstawPredkosc(3e-2, 60);
	pilka.UstawFizyke(9.81*1E-6, -90);

	//paletka
	paletka.SetPosition(0, -15);

	//klocki
	for (int l = 2, n = 0; l < 6; l++, n++)
	{
		for (int i = -16; i < 20; i += 4)
		{
			double red = (double)(rand() % 1000) / 1000.0;
			double green = (double)(rand() % 1000) / 1000.0;
			double blue = (double)(rand() % 1000) / 1000.0;
			MF::Rectangle newBlock(4, 1, red, green, blue);
			newBlock.SetPosition(i, l);
			klocki.push_back(newBlock);
		}
	}

	//ciany
	{
		MF::Rectangle sciana(68, 2, 0.5, 0.5, 0.5);
		sciana.SetPosition(0, 22);
		sciany.push_back(sciana);
	}

	{
		MF::Rectangle sciana(4, 60, 0.5, 0.5, 0.5);
		sciana.SetPosition(21, 0);
		sciany.push_back(sciana);
	}

	{
		MF::Rectangle sciana(4, 60, 0.5, 0.5, 0.5);
		sciana.SetPosition(-21, 0);
		sciany.push_back(sciana);
	}

	paletka.UpdatePhysicsPosition();
	pilka.UpdatePhysicsPosition();
	for (auto itr = klocki.begin(); itr != klocki.end(); itr++)
	{
		itr->UpdatePhysicsPosition();
	}
	for (auto itr = sciany.begin(); itr != sciany.end(); itr++)
	{
		itr->UpdatePhysicsPosition();
	}
}

int main(int argc, char *argv[])
{
	// it's still possible to use console to print messages
	printf("Hello openGL world!");
	// the same can be done with cout / cin

	srand(time(NULL));

	glutInit(&argc, argv);
	InitGLUTScene("freeglut template");

	SetCallbackFunctions();
	InitObjects();

	// start GLUT event loop. It ends when user close the window.
	glutMainLoop();

	// sposb na wykonanie czego po zakoczeniu gluta
	printf("End of GLUT");

	return 0;
}<|endoftext|>


<commit_before>/*
 * Parser.cpp
 *****************************************************************************
 * Copyright © 2015 - VideoLAN and VLC Authors
 *
 * This program 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "Parser.hpp"
#include "HLSSegment.hpp"
#include "Representation.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/tools/Retrieve.hpp"
#include "M3U8.hpp"
#include "Tags.hpp"

#include <vlc_strings.h>
#include <vlc_stream.h>
#include <cstdio>
#include <sstream>
#include <map>

using namespace adaptative;
using namespace adaptative::playlist;
using namespace hls::playlist;

Parser::Parser(stream_t *stream)
{
    p_stream = stream;
}

Parser::~Parser   ()
{
}

static std::list<Tag *> getTagsFromList(std::list<Tag *> &list, int tag)
{
    std::list<Tag *> ret;
    std::list<Tag *>::const_iterator it;
    for(it = list.begin(); it != list.end(); ++it)
    {
        if( (*it)->getType() == tag )
            ret.push_back(*it);
    }
    return ret;
}

static void releaseTagsList(std::list<Tag *> &list)
{
    std::list<Tag *>::const_iterator it;
    for(it = list.begin(); it != list.end(); ++it)
        delete *it;
    list.clear();
}

void Parser::parseAdaptationSet(BasePeriod *period, const AttributesTag *)
{
    BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
    if(adaptSet)
    {
        period->addAdaptationSet(adaptSet);
    }
}

void Parser::parseRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag)
{
    if(!tag->getAttributeByName("URI"))
        return;

    Url url;
    if(tag->getType() == AttributesTag::EXTXMEDIA)
    {
        url = Url(tag->getAttributeByName("URI")->quotedString());
    }
    else
    {
        url = Url(tag->getAttributeByName("URI")->value);
    }

    if(!url.hasScheme())
        url = url.prepend(adaptSet->getUrlSegment());

    void *p_data;
    const size_t i_data = Retrieve::HTTP((vlc_object_t*)p_stream, url.toString(), &p_data);
    if(p_data)
    {
        stream_t *substream = stream_MemoryNew((vlc_object_t *)p_stream, (uint8_t *)p_data, i_data, false);
        if(substream)
        {
            std::list<Tag *> tagslist = parseEntries(substream);
            stream_Delete(substream);

            parseRepresentation(adaptSet, tag, tagslist);

            releaseTagsList(tagslist);
        }
    }
}

void Parser::parseRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag,
                                 const std::list<Tag *> &tagslist)
{
    const Attribute *uriAttr = tag->getAttributeByName("URI");
    const Attribute *bwAttr = tag->getAttributeByName("BANDWIDTH");
    const Attribute *codecsAttr = tag->getAttributeByName("CODECS");

    Representation *rep = new (std::nothrow) Representation(adaptSet);
    if(rep)
    {
        if(uriAttr)
        {
            std::string uri;
            if(tag->getType() == AttributesTag::EXTXMEDIA)
            {
                uri = uriAttr->quotedString();
            }
            else
            {
                uri = uriAttr->value;
            }
            size_t pos = uri.find_last_of('/');
            if(pos != std::string::npos)
                rep->baseUrl.Set(new Url(uri.substr(0, pos+1)));
        }

        if(bwAttr)
            rep->setBandwidth(bwAttr->decimal());

        /* if more than 1 codec, don't probe, can't be packed audio */
        if(codecsAttr && codecsAttr->quotedString().find(',') != std::string::npos)
            rep->setMimeType("video/mp2t");

        parseSegments(rep, tagslist);

        adaptSet->addRepresentation(rep);
    }
}

void Parser::parseSegments(Representation *rep, const std::list<Tag *> &tagslist)
{
    SegmentList *segmentList = new (std::nothrow) SegmentList(rep);
    rep->setSegmentList(segmentList);

    rep->timescale.Set(100);

    int64_t totalduration = 0;
    int64_t nzStartTime = 0;
    uint64_t sequenceNumber = 0;
    std::size_t prevbyterangeoffset = 0;
    const SingleValueTag *ctx_byterange = NULL;
    SegmentEncryption encryption;

    std::list<Tag *>::const_iterator it;
    for(it = tagslist.begin(); it != tagslist.end(); ++it)
    {
        const Tag *tag = *it;
        switch(tag->getType())
        {
            /* using static cast as attribute type permits avoiding class check */
            case SingleValueTag::EXTXMEDIASEQUENCE:
            {
                sequenceNumber = (static_cast<const SingleValueTag*>(tag))->getValue().decimal();
            }
            break;

            case URITag::EXTINF:
            {
                const URITag *uritag = static_cast<const URITag *>(tag);
                HLSSegment *segment = new (std::nothrow) HLSSegment(rep, sequenceNumber++);
                if(!segment)
                    break;

                if(uritag->getAttributeByName("URI"))
                    segment->setSourceUrl(uritag->getAttributeByName("URI")->value);

                if(uritag->getAttributeByName("DURATION"))
                {
                    segment->duration.Set(uritag->getAttributeByName("DURATION")->floatingPoint() * rep->timescale.Get());
                    segment->startTime.Set(nzStartTime);
                    nzStartTime += segment->duration.Get();
                    totalduration += segment->duration.Get();
                }

                segmentList->addSegment(segment);

                if(ctx_byterange)
                {
                    std::pair<std::size_t,std::size_t> range = ctx_byterange->getValue().getByteRange();
                    if(range.first == 0)
                        range.first = prevbyterangeoffset;
                    prevbyterangeoffset = range.first + range.second;
                    segment->setByteRange(range.first, prevbyterangeoffset);
                    ctx_byterange = NULL;
                }

                if(encryption.method != SegmentEncryption::NONE)
                    segment->setEncryption(encryption);
            }
            break;

            case SingleValueTag::EXTXPLAYLISTTYPE:
                rep->b_live = (static_cast<const SingleValueTag *>(tag)->getValue().value != "VOD");
                break;

            case SingleValueTag::EXTXBYTERANGE:
                ctx_byterange = static_cast<const SingleValueTag *>(tag);
                break;

            case AttributesTag::EXTXKEY:
            {
                const AttributesTag *keytag = static_cast<const AttributesTag *>(tag);
                if( keytag->getAttributeByName("METHOD") &&
                    keytag->getAttributeByName("METHOD")->value == "AES-128" &&
                    keytag->getAttributeByName("URI") )
                {
                    encryption.method = SegmentEncryption::AES_128;
                    encryption.key.clear();
                    uint8_t *p_data;
                    const uint64_t read = Retrieve::HTTP(VLC_OBJECT(p_stream),
                                                         keytag->getAttributeByName("URI")->quotedString(),
                                                         (void **) &p_data);
                    if(p_data)
                    {
                        if(read == 16)
                        {
                            encryption.key.resize(16);
                            memcpy(&encryption.key[0], p_data, 16);
                        }
                        free(p_data);
                    }

                    if(keytag->getAttributeByName("IV"))
                    {
                        encryption.iv.clear();
                        encryption.iv = keytag->getAttributeByName("IV")->hexSequence();
                    }
                }
                else
                {
                    /* unsupported or invalid */
                    encryption.method = SegmentEncryption::NONE;
                    encryption.key.clear();
                    encryption.iv.clear();
                }
            }
            break;

            case Tag::EXTXENDLIST:
                rep->b_live = false;
                break;
        }
    }

    if(rep->isLive())
    {
        rep->getPlaylist()->duration.Set(0);
    }
    else if(totalduration > rep->getPlaylist()->duration.Get())
    {
        rep->getPlaylist()->duration.Set(CLOCK_FREQ * totalduration / rep->timescale.Get());
    }
}

M3U8 * Parser::parse(const std::string &playlisturl)
{
    char *psz_line = stream_ReadLine(p_stream);
    if(!psz_line || strcmp(psz_line, "#EXTM3U"))
    {
        free(psz_line);
        return NULL;
    }

    M3U8 *playlist = new (std::nothrow) M3U8(p_stream);
    if(!playlist)
        return NULL;

    if(!playlisturl.empty())
    {
        size_t pos = playlisturl.find_last_of('/');
        if(pos != std::string::npos)
            playlist->addBaseUrl(playlisturl.substr(0, pos + 1));
    }

    BasePeriod *period = new (std::nothrow) BasePeriod( playlist );
    if(!period)
        return playlist;

    std::list<Tag *> tagslist = parseEntries(p_stream);
    bool b_masterplaylist = !getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF).empty();
    if(b_masterplaylist)
    {
        std::list<Tag *>::const_iterator it;
        std::map<std::string, AttributesTag *> groupsmap;

        /* We'll need to create an adaptation set for each media group / alternative rendering
         * we create a list of playlist being and alternative/group */
        std::list<Tag *> mediainfotags = getTagsFromList(tagslist, AttributesTag::EXTXMEDIA);
        for(it = mediainfotags.begin(); it != mediainfotags.end(); ++it)
        {
            AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
            if(tag && tag->getAttributeByName("URI"))
            {
                std::pair<std::string, AttributesTag *> pair(tag->getAttributeByName("URI")->quotedString(), tag);
                groupsmap.insert(pair);
            }
        }

        /* Then we parse all playlists uri and add them, except when alternative */
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            std::list<Tag *> streaminfotags = getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF);
            for(it = streaminfotags.begin(); it != streaminfotags.end(); ++it)
            {
                AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
                if(tag && tag->getAttributeByName("URI"))
                {
                    if(groupsmap.find(tag->getAttributeByName("URI")->value) == groupsmap.end())
                    {
                        /* not a group, belong to default adaptation set */
                        parseRepresentation(adaptSet, tag);
                    }
                }
            }
            if(!adaptSet->getRepresentations().empty())
                period->addAdaptationSet(adaptSet);
            else
                delete adaptSet;
        }

        /* Finally add all groups */
        std::map<std::string, AttributesTag *>::const_iterator groupsit;
        for(groupsit = groupsmap.begin(); groupsit != groupsmap.end(); ++groupsit)
        {
            BaseAdaptationSet *altAdaptSet = new (std::nothrow) BaseAdaptationSet(period);
            if(altAdaptSet)
            {
                std::pair<std::string, AttributesTag *> pair = *groupsit;
                parseRepresentation(altAdaptSet, pair.second);
                if(!altAdaptSet->getRepresentations().empty())
                    period->addAdaptationSet(altAdaptSet);
                else
                    delete altAdaptSet;
            }
        }

    }
    else
    {
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            period->addAdaptationSet(adaptSet);
            AttributesTag *tag = new AttributesTag(AttributesTag::EXTXSTREAMINF, "");
            parseRepresentation(adaptSet, tag, tagslist);
            delete tag;
        }
    }

    playlist->addPeriod(period);

    releaseTagsList(tagslist);

    playlist->debug();
    return playlist;
}

std::list<Tag *> Parser::parseEntries(stream_t *stream)
{
    std::list<Tag *> entrieslist;
    Tag *lastTag = NULL;
    char *psz_line;

    while((psz_line = stream_ReadLine(stream)))
    {
        if(*psz_line == '#')
        {
            if(!strncmp(psz_line, "#EXT", 4)) //tag
            {
                std::string key;
                std::string attributes;
                const char *split = strchr(psz_line, ':');
                if(split)
                {
                    key = std::string(psz_line + 1, split - psz_line - 1);
                    attributes = std::string(split + 1);
                }
                else
                {
                    key = std::string(psz_line);
                }

                if(!key.empty())
                {
                    Tag *tag = TagFactory::createTagByName(key, attributes);
                    if(tag)
                        entrieslist.push_back(tag);
                    lastTag = tag;
                }
            }
        }
        else if(*psz_line && lastTag)
        {
            AttributesTag *attrTag = dynamic_cast<AttributesTag *>(lastTag);
            if(attrTag)
            {
                Attribute *uriAttr = new (std::nothrow) Attribute("URI", std::string(psz_line));
                if(uriAttr)
                    attrTag->addAttribute(uriAttr);
            }
            lastTag = NULL;
        }
        else // drop
        {
            lastTag = NULL;
        }

        free(psz_line);
    }

    return entrieslist;
}
<commit_msg>demux: hls: add media description<commit_after>/*
 * Parser.cpp
 *****************************************************************************
 * Copyright © 2015 - VideoLAN and VLC Authors
 *
 * This program 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "Parser.hpp"
#include "HLSSegment.hpp"
#include "Representation.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/tools/Retrieve.hpp"
#include "M3U8.hpp"
#include "Tags.hpp"

#include <vlc_strings.h>
#include <vlc_stream.h>
#include <cstdio>
#include <sstream>
#include <map>

using namespace adaptative;
using namespace adaptative::playlist;
using namespace hls::playlist;

Parser::Parser(stream_t *stream)
{
    p_stream = stream;
}

Parser::~Parser   ()
{
}

static std::list<Tag *> getTagsFromList(std::list<Tag *> &list, int tag)
{
    std::list<Tag *> ret;
    std::list<Tag *>::const_iterator it;
    for(it = list.begin(); it != list.end(); ++it)
    {
        if( (*it)->getType() == tag )
            ret.push_back(*it);
    }
    return ret;
}

static void releaseTagsList(std::list<Tag *> &list)
{
    std::list<Tag *>::const_iterator it;
    for(it = list.begin(); it != list.end(); ++it)
        delete *it;
    list.clear();
}

void Parser::parseAdaptationSet(BasePeriod *period, const AttributesTag *)
{
    BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
    if(adaptSet)
    {
        period->addAdaptationSet(adaptSet);
    }
}

void Parser::parseRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag)
{
    if(!tag->getAttributeByName("URI"))
        return;

    Url url;
    if(tag->getType() == AttributesTag::EXTXMEDIA)
    {
        url = Url(tag->getAttributeByName("URI")->quotedString());
    }
    else
    {
        url = Url(tag->getAttributeByName("URI")->value);
    }

    if(!url.hasScheme())
        url = url.prepend(adaptSet->getUrlSegment());

    void *p_data;
    const size_t i_data = Retrieve::HTTP((vlc_object_t*)p_stream, url.toString(), &p_data);
    if(p_data)
    {
        stream_t *substream = stream_MemoryNew((vlc_object_t *)p_stream, (uint8_t *)p_data, i_data, false);
        if(substream)
        {
            std::list<Tag *> tagslist = parseEntries(substream);
            stream_Delete(substream);

            parseRepresentation(adaptSet, tag, tagslist);

            releaseTagsList(tagslist);
        }
    }
}

void Parser::parseRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag,
                                 const std::list<Tag *> &tagslist)
{
    const Attribute *uriAttr = tag->getAttributeByName("URI");
    const Attribute *bwAttr = tag->getAttributeByName("BANDWIDTH");
    const Attribute *codecsAttr = tag->getAttributeByName("CODECS");

    Representation *rep = new (std::nothrow) Representation(adaptSet);
    if(rep)
    {
        if(uriAttr)
        {
            std::string uri;
            if(tag->getType() == AttributesTag::EXTXMEDIA)
            {
                uri = uriAttr->quotedString();
            }
            else
            {
                uri = uriAttr->value;
            }
            size_t pos = uri.find_last_of('/');
            if(pos != std::string::npos)
                rep->baseUrl.Set(new Url(uri.substr(0, pos+1)));
        }

        if(bwAttr)
            rep->setBandwidth(bwAttr->decimal());

        /* if more than 1 codec, don't probe, can't be packed audio */
        if(codecsAttr && codecsAttr->quotedString().find(',') != std::string::npos)
            rep->setMimeType("video/mp2t");

        parseSegments(rep, tagslist);

        adaptSet->addRepresentation(rep);
    }
}

void Parser::parseSegments(Representation *rep, const std::list<Tag *> &tagslist)
{
    SegmentList *segmentList = new (std::nothrow) SegmentList(rep);
    rep->setSegmentList(segmentList);

    rep->timescale.Set(100);

    int64_t totalduration = 0;
    int64_t nzStartTime = 0;
    uint64_t sequenceNumber = 0;
    std::size_t prevbyterangeoffset = 0;
    const SingleValueTag *ctx_byterange = NULL;
    SegmentEncryption encryption;

    std::list<Tag *>::const_iterator it;
    for(it = tagslist.begin(); it != tagslist.end(); ++it)
    {
        const Tag *tag = *it;
        switch(tag->getType())
        {
            /* using static cast as attribute type permits avoiding class check */
            case SingleValueTag::EXTXMEDIASEQUENCE:
            {
                sequenceNumber = (static_cast<const SingleValueTag*>(tag))->getValue().decimal();
            }
            break;

            case URITag::EXTINF:
            {
                const URITag *uritag = static_cast<const URITag *>(tag);
                HLSSegment *segment = new (std::nothrow) HLSSegment(rep, sequenceNumber++);
                if(!segment)
                    break;

                if(uritag->getAttributeByName("URI"))
                    segment->setSourceUrl(uritag->getAttributeByName("URI")->value);

                if(uritag->getAttributeByName("DURATION"))
                {
                    segment->duration.Set(uritag->getAttributeByName("DURATION")->floatingPoint() * rep->timescale.Get());
                    segment->startTime.Set(nzStartTime);
                    nzStartTime += segment->duration.Get();
                    totalduration += segment->duration.Get();
                }

                segmentList->addSegment(segment);

                if(ctx_byterange)
                {
                    std::pair<std::size_t,std::size_t> range = ctx_byterange->getValue().getByteRange();
                    if(range.first == 0)
                        range.first = prevbyterangeoffset;
                    prevbyterangeoffset = range.first + range.second;
                    segment->setByteRange(range.first, prevbyterangeoffset);
                    ctx_byterange = NULL;
                }

                if(encryption.method != SegmentEncryption::NONE)
                    segment->setEncryption(encryption);
            }
            break;

            case SingleValueTag::EXTXPLAYLISTTYPE:
                rep->b_live = (static_cast<const SingleValueTag *>(tag)->getValue().value != "VOD");
                break;

            case SingleValueTag::EXTXBYTERANGE:
                ctx_byterange = static_cast<const SingleValueTag *>(tag);
                break;

            case AttributesTag::EXTXKEY:
            {
                const AttributesTag *keytag = static_cast<const AttributesTag *>(tag);
                if( keytag->getAttributeByName("METHOD") &&
                    keytag->getAttributeByName("METHOD")->value == "AES-128" &&
                    keytag->getAttributeByName("URI") )
                {
                    encryption.method = SegmentEncryption::AES_128;
                    encryption.key.clear();
                    uint8_t *p_data;
                    const uint64_t read = Retrieve::HTTP(VLC_OBJECT(p_stream),
                                                         keytag->getAttributeByName("URI")->quotedString(),
                                                         (void **) &p_data);
                    if(p_data)
                    {
                        if(read == 16)
                        {
                            encryption.key.resize(16);
                            memcpy(&encryption.key[0], p_data, 16);
                        }
                        free(p_data);
                    }

                    if(keytag->getAttributeByName("IV"))
                    {
                        encryption.iv.clear();
                        encryption.iv = keytag->getAttributeByName("IV")->hexSequence();
                    }
                }
                else
                {
                    /* unsupported or invalid */
                    encryption.method = SegmentEncryption::NONE;
                    encryption.key.clear();
                    encryption.iv.clear();
                }
            }
            break;

            case Tag::EXTXENDLIST:
                rep->b_live = false;
                break;
        }
    }

    if(rep->isLive())
    {
        rep->getPlaylist()->duration.Set(0);
    }
    else if(totalduration > rep->getPlaylist()->duration.Get())
    {
        rep->getPlaylist()->duration.Set(CLOCK_FREQ * totalduration / rep->timescale.Get());
    }
}

M3U8 * Parser::parse(const std::string &playlisturl)
{
    char *psz_line = stream_ReadLine(p_stream);
    if(!psz_line || strcmp(psz_line, "#EXTM3U"))
    {
        free(psz_line);
        return NULL;
    }

    M3U8 *playlist = new (std::nothrow) M3U8(p_stream);
    if(!playlist)
        return NULL;

    if(!playlisturl.empty())
    {
        size_t pos = playlisturl.find_last_of('/');
        if(pos != std::string::npos)
            playlist->addBaseUrl(playlisturl.substr(0, pos + 1));
    }

    BasePeriod *period = new (std::nothrow) BasePeriod( playlist );
    if(!period)
        return playlist;

    std::list<Tag *> tagslist = parseEntries(p_stream);
    bool b_masterplaylist = !getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF).empty();
    if(b_masterplaylist)
    {
        std::list<Tag *>::const_iterator it;
        std::map<std::string, AttributesTag *> groupsmap;

        /* We'll need to create an adaptation set for each media group / alternative rendering
         * we create a list of playlist being and alternative/group */
        std::list<Tag *> mediainfotags = getTagsFromList(tagslist, AttributesTag::EXTXMEDIA);
        for(it = mediainfotags.begin(); it != mediainfotags.end(); ++it)
        {
            AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
            if(tag && tag->getAttributeByName("URI"))
            {
                std::pair<std::string, AttributesTag *> pair(tag->getAttributeByName("URI")->quotedString(), tag);
                groupsmap.insert(pair);
            }
        }

        /* Then we parse all playlists uri and add them, except when alternative */
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            std::list<Tag *> streaminfotags = getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF);
            for(it = streaminfotags.begin(); it != streaminfotags.end(); ++it)
            {
                AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
                if(tag && tag->getAttributeByName("URI"))
                {
                    if(groupsmap.find(tag->getAttributeByName("URI")->value) == groupsmap.end())
                    {
                        /* not a group, belong to default adaptation set */
                        parseRepresentation(adaptSet, tag);
                    }
                }
            }
            if(!adaptSet->getRepresentations().empty())
                period->addAdaptationSet(adaptSet);
            else
                delete adaptSet;
        }

        /* Finally add all groups */
        std::map<std::string, AttributesTag *>::const_iterator groupsit;
        for(groupsit = groupsmap.begin(); groupsit != groupsmap.end(); ++groupsit)
        {
            BaseAdaptationSet *altAdaptSet = new (std::nothrow) BaseAdaptationSet(period);
            if(altAdaptSet)
            {
                std::pair<std::string, AttributesTag *> pair = *groupsit;
                parseRepresentation(altAdaptSet, pair.second);

                if(pair.second->getAttributeByName("NAME"))
                   altAdaptSet->description.Set(pair.second->getAttributeByName("NAME")->quotedString());

                if(!altAdaptSet->getRepresentations().empty())
                    period->addAdaptationSet(altAdaptSet);
                else
                    delete altAdaptSet;
            }
        }

    }
    else
    {
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            period->addAdaptationSet(adaptSet);
            AttributesTag *tag = new AttributesTag(AttributesTag::EXTXSTREAMINF, "");
            parseRepresentation(adaptSet, tag, tagslist);
            delete tag;
        }
    }

    playlist->addPeriod(period);

    releaseTagsList(tagslist);

    playlist->debug();
    return playlist;
}

std::list<Tag *> Parser::parseEntries(stream_t *stream)
{
    std::list<Tag *> entrieslist;
    Tag *lastTag = NULL;
    char *psz_line;

    while((psz_line = stream_ReadLine(stream)))
    {
        if(*psz_line == '#')
        {
            if(!strncmp(psz_line, "#EXT", 4)) //tag
            {
                std::string key;
                std::string attributes;
                const char *split = strchr(psz_line, ':');
                if(split)
                {
                    key = std::string(psz_line + 1, split - psz_line - 1);
                    attributes = std::string(split + 1);
                }
                else
                {
                    key = std::string(psz_line);
                }

                if(!key.empty())
                {
                    Tag *tag = TagFactory::createTagByName(key, attributes);
                    if(tag)
                        entrieslist.push_back(tag);
                    lastTag = tag;
                }
            }
        }
        else if(*psz_line && lastTag)
        {
            AttributesTag *attrTag = dynamic_cast<AttributesTag *>(lastTag);
            if(attrTag)
            {
                Attribute *uriAttr = new (std::nothrow) Attribute("URI", std::string(psz_line));
                if(uriAttr)
                    attrTag->addAttribute(uriAttr);
            }
            lastTag = NULL;
        }
        else // drop
        {
            lastTag = NULL;
        }

        free(psz_line);
    }

    return entrieslist;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultivariateAlterationDetectorImageFilter.h"

typedef otb::VectorImage<unsigned short,2> ImageType;
typedef otb::VectorImage<double,2>         OutputImageType;
typedef otb::ImageFileReader<ImageType>    ReaderType;
typedef otb::ImageFileWriter<OutputImageType> WriterType;
typedef otb::MultivariateAlterationDetectorImageFilter<ImageType,OutputImageType> MADFilterType;

int otbMultivariateAlterationDetectorImageFilterNew(int argc, char* argv[])
{
  MADFilterType::Pointer  madFilter = MADFilterType::New();

  return EXIT_SUCCESS;
}

int otbMultivariateAlterationDetectorImageFilter(int argc, char* argv[])
{
  char * infname1 = argv[1];
  char * infname2 = argv[2];
  char * outfname = argv[3];

  ReaderType::Pointer reader1 = ReaderType::New();
  reader1->SetFileName(infname1);

  ReaderType::Pointer reader2 = ReaderType::New();
  reader2->SetFileName(infname2);

  MADFilterType::Pointer  madFilter = MADFilterType::New();
  madFilter->SetInput1(reader1->GetOutput());
  madFilter->SetInput2(reader2->GetOutput());

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(madFilter->GetOutput());
  writer->SetFileName(outfname);
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>TEST: Adding v1, v2 and rho output in test<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultivariateAlterationDetectorImageFilter.h"

typedef otb::VectorImage<unsigned short,2> ImageType;
typedef otb::VectorImage<double,2>         OutputImageType;
typedef otb::ImageFileReader<ImageType>    ReaderType;
typedef otb::ImageFileWriter<OutputImageType> WriterType;
typedef otb::MultivariateAlterationDetectorImageFilter<ImageType,OutputImageType> MADFilterType;

int otbMultivariateAlterationDetectorImageFilterNew(int argc, char* argv[])
{
  MADFilterType::Pointer  madFilter = MADFilterType::New();

  return EXIT_SUCCESS;
}

int otbMultivariateAlterationDetectorImageFilter(int argc, char* argv[])
{
  char * infname1 = argv[1];
  char * infname2 = argv[2];
  char * outfname = argv[3];

  ReaderType::Pointer reader1 = ReaderType::New();
  reader1->SetFileName(infname1);

  ReaderType::Pointer reader2 = ReaderType::New();
  reader2->SetFileName(infname2);

  MADFilterType::Pointer  madFilter = MADFilterType::New();
  madFilter->SetInput1(reader1->GetOutput());
  madFilter->SetInput2(reader2->GetOutput());

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(madFilter->GetOutput());
  writer->SetFileName(outfname);
  writer->Update();

  std::cout<<"V1: "<<std::endl;
  std::cout<<madFilter->GetV1()<<std::endl;

  std::cout<<"V2: "<<std::endl;
  std::cout<<madFilter->GetV2()<<std::endl;

  std::cout<<"Rho: "<<std::endl;
  std::cout<<madFilter->GetRho()<<std::endl;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <stan/math/error_handling/matrix/check_cov_matrix.hpp>
#include <gtest/gtest.h>

TEST(MathErrorHandlingMatrix, checkCovMatrix) {
  Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> y;
  double result;

  y.resize(3,3);
  y << 2, -1, 0, -1, 2, -1, 0, -1, 2;
  EXPECT_TRUE(stan::math::check_cov_matrix("checkCovMatrix(%1%)",
                                           y, "y", &result));

  y << 1, 2, 3, 2, 1, 2, 3, 2, 1;
  EXPECT_THROW(stan::math::check_cov_matrix("checkCovMatrix(%1%)", y, "y", &result),
               std::domain_error);
}
<commit_msg>added NaN test for check_cov_matrix<commit_after>#include <stan/math/error_handling/matrix/check_cov_matrix.hpp>
#include <gtest/gtest.h>

TEST(MathErrorHandlingMatrix, checkCovMatrix) {
  Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> y;
  double result;

  y.resize(3,3);
  y << 2, -1, 0, -1, 2, -1, 0, -1, 2;
  EXPECT_TRUE(stan::math::check_cov_matrix("checkCovMatrix(%1%)",
                                           y, "y", &result));

  y << 1, 2, 3, 2, 1, 2, 3, 2, 1;
  EXPECT_THROW(stan::math::check_cov_matrix("checkCovMatrix(%1%)", y, "y", &result),
               std::domain_error);
}

TEST(MathErrorHandlingMatrix, checkCovMatrix_nan) {
  Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> y;
  double result;
  double nan = std::numeric_limits<double>::quiet_NaN();

  y.resize(3,3);
  y << 2, -1, 0, -1, 2, -1, 0, -1, 2;
  EXPECT_TRUE(stan::math::check_cov_matrix("checkCovMatrix(%1%)",
                                           y, "y", &result));

  for (int i = 0; i < y.size(); i++) {
    y(i) = nan;
    EXPECT_THROW(stan::math::check_cov_matrix("checkCovMatrix(%1%)", y, "y", &result),
                 std::domain_error);
    y << 2, -1, 0, -1, 2, -1, 0, -1, 2;
  }
}
<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/compiler/xla/service/fusion_node_indexing_evaluation.h"

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/core/platform/logging.h"

namespace xla {

FusionNodeIndexingEvaluation::FusionNodeIndexingEvaluation(
    const HloInstruction* fusion)
    : fusion_(fusion) {
  total_emitted_instructions_ = 0;
  HloInstruction* root = fusion->fused_expression_root();
  indexing_users_[root].insert(fusion);
  index_usage_count_[fusion] = 1;
  RecomputeCache();
}

bool FusionNodeIndexingEvaluation::AverageCodeDuplicationTooHigh(
    const HloInstruction* producer) const {
  // This constant is arbitrarily chosen. Essentially we don't want to have too
  // much code duplication, because it slows down the compilation time. There is
  // a tradeoff between compilation time and runtime here.
  const int64 kAllowedCodeDuplication = 15;

  // index_usage_count_ contains an entry for each instruction in the fusion
  // computation (except parameter instructions), plus an entry for the 'fusion'
  // instruction. So the size of this map is already one bigger than the number
  // of instructions in the fusion node that are emitted, thus accounting for
  // the number of instructions after 'producer' is fused.
  return EvaluateTotalEmittedInstructions(producer) /
             index_usage_count_.size() >
         kAllowedCodeDuplication;
}

int64 FusionNodeIndexingEvaluation::EvaluateTotalEmittedInstructions(
    const HloInstruction* producer) const {
  int64 total = total_emitted_instructions_;
  for (const auto* user : indexing_users_.at(producer)) {
    total += index_usage_count_.at(user);
  }
  return total;
}

void FusionNodeIndexingEvaluation::UpdateEvaluationCache(
    const HloInstruction* producer,
    absl::flat_hash_set<const HloInstruction*> indexing_users_of_producer) {
  CHECK(!indexing_users_.contains(producer));
  indexing_users_[producer] = std::move(indexing_users_of_producer);
  UpdateIndexUsageCount(producer);
  UpdateIndexingUsersOfOperands(producer);
}

absl::flat_hash_set<const HloInstruction*>
FusionNodeIndexingEvaluation::RemoveFusionOperand(
    HloInstruction* fusion_operand) {
  auto indexing_users_of_operand =
      std::move(indexing_users_.at(fusion_operand));
  indexing_users_.erase(fusion_operand);
  CHECK(!index_usage_count_.contains(fusion_operand));
  return indexing_users_of_operand;
}

void FusionNodeIndexingEvaluation::RecomputeCache() {
  auto postorder =
      fusion_->fused_instructions_computation()->MakeInstructionPostOrder();
  std::reverse(postorder.begin(), postorder.end());
  for (const auto* instruction : postorder) {
    if (instruction->opcode() == HloOpcode::kParameter) {
      continue;
    }
    UpdateIndexUsageCount(instruction);
    UpdateIndexingUsersOfOperands(instruction);
  }
}

void FusionNodeIndexingEvaluation::UpdateIndexUsageCount(
    const HloInstruction* instruction) {
  int64 total = 0;
  for (const auto* user : indexing_users_[instruction]) {
    int64 weight = 1;
    // Concatenate is special: the index differs for each operand, so
    // in the worst case we have to deal with as many index values as
    // the number of operands of Concatenate. By considering the worst
    // case, we are more conservative than necessary regarding
    // counting the index usage.
    if (user->opcode() == HloOpcode::kConcatenate) {
      weight = user->operand_count();
    }
    total += index_usage_count_.at(user) * weight;
  }
  CHECK(index_usage_count_.emplace(instruction, total).second);
  total_emitted_instructions_ += total;
}

void FusionNodeIndexingEvaluation::UpdateIndexingUsersOfOperands(
    const HloInstruction* instruction) {
  for (const auto* operand : instruction->operands()) {
    if (operand->opcode() == HloOpcode::kParameter) {
      // Although actually the parameter gets indexed, we store it as indexing
      // of the corresponding fusion operand instead because parameter
      // instruction pointers can be invalidated when we fuse another
      // instruction into 'fusion_'.
      operand = fusion_->operand(operand->parameter_number());
    }
    // For simplicity we assume that all shape and layout changing
    // operations except Transposes invalidate index reuse. Transposes are
    // special: although they are shape changing, we can reuse the
    // multi-dimensional index for the operand by permuting it.
    if (instruction->opcode() == HloOpcode::kTranspose ||
        Shape::Equal().IgnoreElementType()(operand->shape(),
                                           instruction->shape())) {
      // If the index is reused, it means the operand gets index values
      // from the same set of (indirect) users as 'instruction' itself.
      indexing_users_[operand].insert(indexing_users_[instruction].begin(),
                                      indexing_users_[instruction].end());
    } else {
      // If the index is not reused, it means 'instruction' computes a
      // new index derived from the index it gets.
      indexing_users_[operand].insert(instruction);
    }
  }
}

}  // namespace xla
<commit_msg>We shouldn't take the worst case scenario for concatenate and fusion. This is the last step to make the new test pass.<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/compiler/xla/service/fusion_node_indexing_evaluation.h"

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/core/platform/logging.h"

namespace xla {

FusionNodeIndexingEvaluation::FusionNodeIndexingEvaluation(
    const HloInstruction* fusion)
    : fusion_(fusion) {
  total_emitted_instructions_ = 0;
  HloInstruction* root = fusion->fused_expression_root();
  indexing_users_[root].insert(fusion);
  index_usage_count_[fusion] = 1;
  RecomputeCache();
}

bool FusionNodeIndexingEvaluation::AverageCodeDuplicationTooHigh(
    const HloInstruction* producer) const {
  // This constant is arbitrarily chosen. Essentially we don't want to have too
  // much code duplication, because it slows down the compilation time. There is
  // a tradeoff between compilation time and runtime here.
  const int64 kAllowedCodeDuplication = 15;

  // index_usage_count_ contains an entry for each instruction in the fusion
  // computation (except parameter instructions), plus an entry for the 'fusion'
  // instruction. So the size of this map is already one bigger than the number
  // of instructions in the fusion node that are emitted, thus accounting for
  // the number of instructions after 'producer' is fused.
  return EvaluateTotalEmittedInstructions(producer) /
             index_usage_count_.size() >
         kAllowedCodeDuplication;
}

int64 FusionNodeIndexingEvaluation::EvaluateTotalEmittedInstructions(
    const HloInstruction* producer) const {
  int64 total = total_emitted_instructions_;
  for (const auto* user : indexing_users_.at(producer)) {
    total += index_usage_count_.at(user);
  }
  return total;
}

void FusionNodeIndexingEvaluation::UpdateEvaluationCache(
    const HloInstruction* producer,
    absl::flat_hash_set<const HloInstruction*> indexing_users_of_producer) {
  CHECK(!indexing_users_.contains(producer));
  indexing_users_[producer] = std::move(indexing_users_of_producer);
  UpdateIndexUsageCount(producer);
  UpdateIndexingUsersOfOperands(producer);
}

absl::flat_hash_set<const HloInstruction*>
FusionNodeIndexingEvaluation::RemoveFusionOperand(
    HloInstruction* fusion_operand) {
  auto indexing_users_of_operand =
      std::move(indexing_users_.at(fusion_operand));
  indexing_users_.erase(fusion_operand);
  CHECK(!index_usage_count_.contains(fusion_operand));
  return indexing_users_of_operand;
}

void FusionNodeIndexingEvaluation::RecomputeCache() {
  auto postorder =
      fusion_->fused_instructions_computation()->MakeInstructionPostOrder();
  std::reverse(postorder.begin(), postorder.end());
  for (const auto* instruction : postorder) {
    if (instruction->opcode() == HloOpcode::kParameter) {
      continue;
    }
    UpdateIndexUsageCount(instruction);
    UpdateIndexingUsersOfOperands(instruction);
  }
}

void FusionNodeIndexingEvaluation::UpdateIndexUsageCount(
    const HloInstruction* instruction) {
  int64 total = 0;
  for (const auto* user : indexing_users_[instruction]) {
    total += index_usage_count_.at(user);
  }
  CHECK(index_usage_count_.emplace(instruction, total).second);
  total_emitted_instructions_ += total;
}

void FusionNodeIndexingEvaluation::UpdateIndexingUsersOfOperands(
    const HloInstruction* instruction) {
  for (const auto* operand : instruction->operands()) {
    if (operand->opcode() == HloOpcode::kParameter) {
      // Although actually the parameter gets indexed, we store it as indexing
      // of the corresponding fusion operand instead because parameter
      // instruction pointers can be invalidated when we fuse another
      // instruction into 'fusion_'.
      operand = fusion_->operand(operand->parameter_number());
    }
    // For simplicity we assume that all shape and layout changing
    // operations except Transposes invalidate index reuse. Transposes are
    // special: although they are shape changing, we can reuse the
    // multi-dimensional index for the operand by permuting it.
    if (instruction->opcode() == HloOpcode::kTranspose ||
        Shape::Equal().IgnoreElementType()(operand->shape(),
                                           instruction->shape())) {
      // If the index is reused, it means the operand gets index values
      // from the same set of (indirect) users as 'instruction' itself.
      indexing_users_[operand].insert(indexing_users_[instruction].begin(),
                                      indexing_users_[instruction].end());
    } else {
      // If the index is not reused, it means 'instruction' computes a
      // new index derived from the index it gets.
      indexing_users_[operand].insert(instruction);
    }
  }
}

}  // namespace xla
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */
// PCL
#include <boost/thread/thread.hpp>
#include <Eigen/Geometry>
#include <pcl/common/common.h>
#define MEASURE_FUNCTION_TIME
#include <pcl/common/time.h> //fps calculations
#include <pcl/io/pcd_io.h>
#include <pcl/io/openni_grabber.h>
#include <cfloat>
#include <pcl/visualization/point_cloud_handlers.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>

#define SHOW_FPS 1
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    if (++count == 100) \
    { \
      double now = pcl::getTime (); \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

using pcl::console::print_color;
using pcl::console::print_error;
using pcl::console::print_error;
using pcl::console::print_warn;
using pcl::console::print_info;
using pcl::console::print_debug;
using pcl::console::print_value;
using pcl::console::print_highlight;
using pcl::console::TT_BRIGHT;
using pcl::console::TT_RED;
using pcl::console::TT_GREEN;
using pcl::console::TT_BLUE;

boost::mutex mutex_;
pcl::PointCloud<pcl::PointXYZ>::ConstPtr g_cloud;
bool new_cloud = false;

void
printHelp (int argc, char **argv)
{
  //print_error ("Syntax is: %s <file_name 1..N>.pcd <options>\n", argv[0]);
  print_error ("Syntax is: %s <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -dev device_id           = device to be used\n");
  print_info ("                                                maybe \"#n\", with n being the number of the device in device list.\n");
  print_info ("                                                maybe \"bus@addr\", with bus and addr being the usb bus and address where device is connected.\n");
  print_info ("                                                maybe \"serial\", with serial being the serial number of the device.\n");
  print_info ("\n");
}

// Create the PCLVisualizer object
boost::shared_ptr<pcl::visualization::PCLVisualizer> p;

struct EventHelper
{
  void
  cloud_cb (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud)
  {
    FPS_CALC ("callback");
    if (mutex_.try_lock ())
    {
      g_cloud = cloud;
      new_cloud = true;
      mutex_.unlock ();
    }
  }
};

/* ---[ */
int
main (int argc, char** argv)
{
  srand (time (0));

  if (argc > 1)
  {
    for (int i = 1; i < argc; i++)
    {
      if (std::string (argv[i]) == "-h")
      {
        printHelp (argc, argv);
        return (-1);
      }
    }
  }

  p.reset (new pcl::visualization::PCLVisualizer (argc, argv, "OpenNI Viewer"));

  std::string device_id = "";
  pcl::console::parse_argument (argc, argv, "-dev", device_id);

  pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id);

  EventHelper h;
  boost::function<void(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&) > f = boost::bind (&EventHelper::cloud_cb, &h, _1);
  boost::signals2::connection c1 = interface->registerCallback (f);

  interface->start ();
  while (!p->wasStopped ())
  {
    p->spinOnce ();
    if (new_cloud && mutex_.try_lock ())
    {
      new_cloud = false;
      if (g_cloud)
      {
        FPS_CALC ("drawing");
        if (!p->updatePointCloud<pcl::PointXYZ> (g_cloud, "OpenNICloud"))
        {
          p->addPointCloud<pcl::PointXYZ> (g_cloud, "OpenNICloud");
          p->resetCameraViewpoint ("OpenNICloud");
        }
      }
      mutex_.unlock ();
    }
    else
      boost::this_thread::sleep (boost::posix_time::microseconds (1000));
  }

  interface->stop ();
}
/* ]--- */
<commit_msg>openni_viewer now gets 30Hz XYZRGB<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */
// PCL
#include <boost/thread/thread.hpp>
#include <Eigen/Geometry>
#include <pcl/common/common.h>
#define MEASURE_FUNCTION_TIME
#include <pcl/common/time.h> //fps calculations
#include <pcl/io/pcd_io.h>
#include <pcl/io/openni_grabber.h>
#include <cfloat>
#include <pcl/visualization/point_cloud_handlers.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>

#define SHOW_FPS 1
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    if (++count == 100) \
    { \
      double now = pcl::getTime (); \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

using pcl::console::print_color;
using pcl::console::print_error;
using pcl::console::print_error;
using pcl::console::print_warn;
using pcl::console::print_info;
using pcl::console::print_debug;
using pcl::console::print_value;
using pcl::console::print_highlight;
using pcl::console::TT_BRIGHT;
using pcl::console::TT_RED;
using pcl::console::TT_GREEN;
using pcl::console::TT_BLUE;

boost::mutex mutex_;
pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr g_cloud;
bool new_cloud = false;

void
printHelp (int argc, char **argv)
{
  //print_error ("Syntax is: %s <file_name 1..N>.pcd <options>\n", argv[0]);
  print_error ("Syntax is: %s <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -dev device_id           = device to be used\n");
  print_info ("                                                maybe \"#n\", with n being the number of the device in device list.\n");
  print_info ("                                                maybe \"bus@addr\", with bus and addr being the usb bus and address where device is connected.\n");
  print_info ("                                                maybe \"serial\", with serial being the serial number of the device.\n");
  print_info ("\n");
}

// Create the PCLVisualizer object
boost::shared_ptr<pcl::visualization::PCLVisualizer> p;

struct EventHelper
{
  void
  cloud_cb (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr & cloud)
  {
    FPS_CALC ("callback");
    if (mutex_.try_lock ())
    {
      g_cloud = cloud;
      new_cloud = true;
      mutex_.unlock ();
    }
  }
};

/* ---[ */
int
main (int argc, char** argv)
{
  srand (time (0));

  if (argc > 1)
  {
    for (int i = 1; i < argc; i++)
    {
      if (std::string (argv[i]) == "-h")
      {
        printHelp (argc, argv);
        return (-1);
      }
    }
  }

  p.reset (new pcl::visualization::PCLVisualizer (argc, argv, "OpenNI Viewer"));

  std::string device_id = "";
  pcl::console::parse_argument (argc, argv, "-dev", device_id);

  pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id);

  EventHelper h;
  boost::function<void(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&) > f = boost::bind (&EventHelper::cloud_cb, &h, _1);
  boost::signals2::connection c1 = interface->registerCallback (f);

  interface->start ();
  while (!p->wasStopped ())
  {
    p->spinOnce ();
    if (new_cloud && mutex_.try_lock ())
    {
      new_cloud = false;
      if (g_cloud)
      {
        FPS_CALC ("drawing");
        pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> handler (g_cloud);
        if (!p->updatePointCloud<pcl::PointXYZRGB> (g_cloud, handler, "OpenNICloud"))
        {
          p->addPointCloud<pcl::PointXYZRGB> (g_cloud, handler, "OpenNICloud");
          p->resetCameraViewpoint ("OpenNICloud");
        }
      }
      mutex_.unlock ();
    }
    else
      boost::this_thread::sleep (boost::posix_time::microseconds (1000));
  }

  interface->stop ();
}
/* ]--- */
<|endoftext|>