<commit_before>#include <sched.h>

#include "shared_mem.h"
#include "lock.h"
#include "net_thread_runner.h"
#include "mcp.h"
#include "chip.h"

UInt32 g_shared_mem_active_threads;
Lock* g_shared_mem_threads_lock;

NetThreadRunner *SimSharedMemStartThreads()
{
   g_shared_mem_threads_lock = Lock::create();
   g_shared_mem_active_threads = 0;

   unsigned int num_shared_mem_threads = g_chip->getNumModules();
   NetThreadRunner * runners = new NetThreadRunner[num_shared_mem_threads];
   for(unsigned int i = 0; i < num_shared_mem_threads; i++)
   {
      OS_SERVICES::ITHREAD *my_thread_p;
      my_thread_p = OS_SERVICES::ITHREADS::GetSingleton()->Spawn(4096, &runners[i]);
      assert(my_thread_p);
   }

   return runners;
}

void SimSharedMemQuit()
{
   NetPacket pkt;
   pkt.type = SHARED_MEM_TERMINATE_THREADS;
   pkt.length = 0;
   pkt.data = 0;

   g_MCP->broadcastPacket(pkt);

   fprintf(stderr, "SimSharedMemQuit : Send quit message.\n");

   // Only quit when all threads have terminated. Lock shouldn't be
   // necessary here.
   while (g_shared_mem_active_threads > 0)
      sched_yield();

   fprintf(stderr, "SimSharedMemQuit : All shared mem threads have terminated.\n");

   delete g_shared_mem_threads_lock;
}

void SimSharedMemTerminateFunc(void *vp, NetPacket pkt)
{
   bool *pcont = (bool*) vp;
   *pcont = false;
}

void* SimSharedMemThreadFunc(void *)
{
    int core_id = g_chip->registerSharedMemThread();
    Network *net = g_chip->getCore(core_id)->getNetwork();
    bool cont = true;

    // Bookkeeping for SimSharedMemQuit
    g_shared_mem_threads_lock->acquire();
    ++g_shared_mem_active_threads;
    g_shared_mem_threads_lock->release();

    // Turn off cont when we receive a quit message
    net->registerCallback(SHARED_MEM_TERMINATE_THREADS,
                          SimSharedMemTerminateFunc,
                          &cont);

    // Actual work gets done here
    while(cont)
       net->netPullFromTransport();

    // Bookkeeping for SimSharedMemQuit
    g_shared_mem_threads_lock->acquire();
    --g_shared_mem_active_threads;
    g_shared_mem_threads_lock->release();

    return 0;
}
<commit_msg>[threads/shared_mem] Add warning about distribution of shared mem thread clean up code.<commit_after>#include <sched.h>

#include "shared_mem.h"
#include "lock.h"
#include "net_thread_runner.h"
#include "mcp.h"
#include "chip.h"

// FIXME: Right now the termination code using shared globals only
// works within a single process. For distribution this will not
// work. Fortunately, it *SHOULD* be possible to remove
// synchronization, as the race condition with MCP termination is
// already handled in MCP::finish().

UInt32 g_shared_mem_active_threads;
Lock* g_shared_mem_threads_lock;

NetThreadRunner *SimSharedMemStartThreads()
{
   g_shared_mem_threads_lock = Lock::create();
   g_shared_mem_active_threads = 0;

   unsigned int num_shared_mem_threads = g_chip->getNumModules();
   NetThreadRunner * runners = new NetThreadRunner[num_shared_mem_threads];
   for(unsigned int i = 0; i < num_shared_mem_threads; i++)
   {
      OS_SERVICES::ITHREAD *my_thread_p;
      my_thread_p = OS_SERVICES::ITHREADS::GetSingleton()->Spawn(4096, &runners[i]);
      assert(my_thread_p);
   }

   return runners;
}

void SimSharedMemQuit()
{
   NetPacket pkt;
   pkt.type = SHARED_MEM_TERMINATE_THREADS;
   pkt.length = 0;
   pkt.data = 0;

   g_MCP->broadcastPacket(pkt);

   fprintf(stderr, "SimSharedMemQuit : Send quit message.\n");

   // Only quit when all threads have terminated. Lock shouldn't be
   // necessary here.
   while (g_shared_mem_active_threads > 0)
      sched_yield();

   fprintf(stderr, "SimSharedMemQuit : All shared mem threads have terminated.\n");

   delete g_shared_mem_threads_lock;
}

void SimSharedMemTerminateFunc(void *vp, NetPacket pkt)
{
   bool *pcont = (bool*) vp;
   *pcont = false;
}

void* SimSharedMemThreadFunc(void *)
{
    int core_id = g_chip->registerSharedMemThread();
    Network *net = g_chip->getCore(core_id)->getNetwork();
    bool cont = true;

    // Bookkeeping for SimSharedMemQuit
    g_shared_mem_threads_lock->acquire();
    ++g_shared_mem_active_threads;
    g_shared_mem_threads_lock->release();

    // Turn off cont when we receive a quit message
    net->registerCallback(SHARED_MEM_TERMINATE_THREADS,
                          SimSharedMemTerminateFunc,
                          &cont);

    // Actual work gets done here
    while(cont)
       net->netPullFromTransport();

    // Bookkeeping for SimSharedMemQuit
    g_shared_mem_threads_lock->acquire();
    --g_shared_mem_active_threads;
    g_shared_mem_threads_lock->release();

    return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2007 by Opsidao,,,   *
 *   opsi@ka-tet   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "ventana.h"
#include <QTimer>
#include <QInputDialog>
#include <QMessageBox>
#include <QDebug>

Ventana::Ventana(QWidget* parent, Qt::WFlags fl)
: QMainWindow( parent, fl )
{
	setupUi(this);
	control.start();
	//TODO Enumerate ports more cleanly, with really available ports
	QStringList puertos;
#ifdef Q_WS_WIN
	puertos << "COM1" << "COM2"<< "COM3"<< "COM4";
#else
	puertos << "/dev/ttyS0" << "/dev/ttyS1"<< "/dev/ttyS2"<< "/dev/ttyS3";
#endif
	puertos << "Otro";
	puerto->addItems(puertos);

	QObject::connect(puerto,SIGNAL(activated( const QString& )),
			 this,SLOT(slotPuertoSeleccionado(const QString&)));
	QObject::connect(tipoDeTarjeta,SIGNAL(currentIndexChanged( const QString& )),
			 this,SLOT(slotUpdateCardType(const QString&)));

	QObject::connect(botonAbrirPuerto,SIGNAL(clicked()),
			 this,SLOT(slotAbrirPuerto()));

	QObject::connect(botonTestNodo,SIGNAL(clicked()),
			 this,SLOT(slotTestNodeLink()));
	QObject::connect(&control,SIGNAL(testNodeLinkDone(int)),
			 this,SLOT(slotTestNodeLinkDone(int)));

	QObject::connect(botonVersion,SIGNAL(clicked()),
			 this,SLOT(slotGetFirmwareVersion()));
	QObject::connect(&control,SIGNAL(getFirmwareVersionDone(bool, QPair< int, int >)),
			 this,SLOT(slotGetFirmwareVersionDone(bool, QPair< int, int >)));

	QObject::connect(botonLeerTarjeta,SIGNAL(clicked()),
			 this,SLOT(slotReadPublicMode()));
	QObject::connect(&control,SIGNAL(readPublicModeDone(int, const QString&, const QString&)),
			 this,SLOT(slotReadPublicModeDone(int, const QString&, const QString&)));

	QObject::connect(bloquearTarjeta,SIGNAL(toggled(bool)),this,SLOT(slotLockChanged(bool )));

	QObject::connect(paraEscribir,SIGNAL(textChanged( const QString& )),this,SLOT(validateData2Write(const QString&)));

	QObject::connect(botonEscribirTarjeta,SIGNAL(clicked()),
			 this,SLOT(slotWritePublicMode()));
	QObject::connect(&control,SIGNAL(writePublicModeDone(int)),
			  this,SLOT(slotWritePublicModeDone(int)));
}

Ventana::~Ventana()
{
}

/*$SPECIALIZATION$*/
void Ventana::slotPuertoSeleccionado(const QString& seleccionado)
{
	if (seleccionado == "Otro") {
		QString nPuerto = QInputDialog::getText(this,"Puerto personalizado","Introduzca el nombre del puerto a utilizar");
		if (!nPuerto.isEmpty()) {
			puerto->insertItem(puerto->count()-1,nPuerto);
			puerto->setCurrentIndex(puerto->count()-2);
		}
	}
}

void Ventana::slotUpdateCardType(const QString &value)
{
	statusBar()->showMessage(QString("Tipo de tarjeta cambiado a : %1").arg(value));
	if (value=="V0") {
		control.setCardType(KRW125ctl::V0);
	} else {
		control.setCardType(KRW125ctl::V1);
	}
}

void Ventana::slotAbrirPuerto()
{
	framePadre->setEnabled(false);
	if (control.isOpen()) {
		puerto->setEnabled(true);
		botonAbrirPuerto->setText("&Abrir puerto");
		control.close();
	} else {
		control.setName(puerto->currentText());
		QString msg;
		if (control.open()) {
			msg = "Se ha abierto el puerto correctamente";
			botonAbrirPuerto->setText("&Cerrar puerto");
			puerto->setEnabled(false);
			framePadre->setEnabled(true);
		} else {
			msg = "Imposible abrir puerto";
			puerto->setEnabled(true);
			framePadre->setEnabled(false);
		}
		statusBar()->showMessage(msg,0);
	}
}

void Ventana::slotTestNodeLink()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.testNodeLink();
}

void Ventana::slotTestNodeLinkDone(int result)
{
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	QString msg;
	switch(result)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Test del nodo correcto",0);
			msg = "Test correcto";
			break;
		case KRW125ctl::Failed:
		case KRW125ctl::NotOpen:
		case KRW125ctl::OperationError:
			statusBar()->showMessage("Ha fallado el test del nodo",0);
			msg = "Test incorrecto";
	}
	resultadoTest->setText(msg);
}

void Ventana::slotGetFirmwareVersion()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.getFirmwareVersion();
}

void Ventana::slotGetFirmwareVersionDone(bool correct, QPair< int, int > version)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	if (correct) {
		statusBar()->showMessage(QString::fromUtf8("Versión del firmware obtenida correctamente"),0);
		version0->setValue(version.first);
		version1->setValue(version.second);
	} else {
		statusBar()->showMessage(QString::fromUtf8("Ha fallado la obtención de la versión del firmware"),0);
		version0->setValue(-1);
		version1->setValue(-1);
	}
}

void Ventana::slotReadPublicMode()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.readPublicModeA();
}

void Ventana::slotReadPublicModeDone(int correct, const QString & hexData, const QString & decData)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	switch(correct)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Tarjeta leida correctamente",0);
			leidoHex->setText(hexData);
			leidoDec->setText(decData);
			break;
		default:
			statusBar()->showMessage("No se pudo leer la tarjeta",0);
			leidoHex->setText("");
			leidoDec->setText("");
			break;
	}
}

void Ventana::slotLockChanged(bool lock)
{
	if (lock) {
		if(QMessageBox::question(this,"Habilitar bloqueo de tarjetas",QString::fromUtf8("
¿Esta seguro de que quiere activar el bloqueo de tarjetas?

Recuerde que las tarjetas bloqueadas no pueden ser sobreescritas
"),QMessageBox::Ok,QMessageBox::Cancel) == QMessageBox::Ok) {
			control.setLockCard(lock);
		} else {
			bloquearTarjeta->setChecked(false);
		}
	} else {
		control.setLockCard(lock);
	}
}

void Ventana::slotWritePublicMode()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.setData(QByteArray::fromHex(paraEscribir->text().toAscii()));
	control.writePublicModeA();
}

void Ventana::slotWritePublicModeDone(int correct)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	switch(correct)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Tarjeta escrita correctamente",0);
			break;
		default:
			statusBar()->showMessage("No se pudo escribir la tarjeta",0);
			break;
	}
}

void Ventana::validateData2Write(const QString &newText)
{
	QRegExp reg("[0-9aAbBcCdDeEfF]{10}");
	if (reg.exactMatch(newText)) {
		wrongData2Write->setVisible(false);
		botonEscribirTarjeta->setEnabled(true);
	} else {
		wrongData2Write->setVisible(true);
		botonEscribirTarjeta->setEnabled(false);
	}
}

<commit_msg>finish the working thread<commit_after>/***************************************************************************
 *   Copyright (C) 2007 by Opsidao,,,   *
 *   opsi@ka-tet   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "ventana.h"
#include <QTimer>
#include <QInputDialog>
#include <QMessageBox>
#include <QDebug>

Ventana::Ventana(QWidget* parent, Qt::WFlags fl)
: QMainWindow( parent, fl )
{
	setupUi(this);
	control.start();
	//TODO Enumerate ports more cleanly, with really available ports
	QStringList puertos;
#ifdef Q_WS_WIN
	puertos << "COM1" << "COM2"<< "COM3"<< "COM4";
#else
	puertos << "/dev/ttyS0" << "/dev/ttyS1"<< "/dev/ttyS2"<< "/dev/ttyS3";
#endif
	puertos << "Otro";
	puerto->addItems(puertos);

	QObject::connect(puerto,SIGNAL(activated( const QString& )),
			 this,SLOT(slotPuertoSeleccionado(const QString&)));
	QObject::connect(tipoDeTarjeta,SIGNAL(currentIndexChanged( const QString& )),
			 this,SLOT(slotUpdateCardType(const QString&)));

	QObject::connect(botonAbrirPuerto,SIGNAL(clicked()),
			 this,SLOT(slotAbrirPuerto()));

	QObject::connect(botonTestNodo,SIGNAL(clicked()),
			 this,SLOT(slotTestNodeLink()));
	QObject::connect(&control,SIGNAL(testNodeLinkDone(int)),
			 this,SLOT(slotTestNodeLinkDone(int)));

	QObject::connect(botonVersion,SIGNAL(clicked()),
			 this,SLOT(slotGetFirmwareVersion()));
	QObject::connect(&control,SIGNAL(getFirmwareVersionDone(bool, QPair< int, int >)),
			 this,SLOT(slotGetFirmwareVersionDone(bool, QPair< int, int >)));

	QObject::connect(botonLeerTarjeta,SIGNAL(clicked()),
			 this,SLOT(slotReadPublicMode()));
	QObject::connect(&control,SIGNAL(readPublicModeDone(int, const QString&, const QString&)),
			 this,SLOT(slotReadPublicModeDone(int, const QString&, const QString&)));

	QObject::connect(bloquearTarjeta,SIGNAL(toggled(bool)),this,SLOT(slotLockChanged(bool )));

	QObject::connect(paraEscribir,SIGNAL(textChanged( const QString& )),this,SLOT(validateData2Write(const QString&)));

	QObject::connect(botonEscribirTarjeta,SIGNAL(clicked()),
			 this,SLOT(slotWritePublicMode()));
	QObject::connect(&control,SIGNAL(writePublicModeDone(int)),
			  this,SLOT(slotWritePublicModeDone(int)));
}

Ventana::~Ventana()
{
	control.end();
	control.wait();
}

/*$SPECIALIZATION$*/
void Ventana::slotPuertoSeleccionado(const QString& seleccionado)
{
	if (seleccionado == "Otro") {
		QString nPuerto = QInputDialog::getText(this,"Puerto personalizado","Introduzca el nombre del puerto a utilizar");
		if (!nPuerto.isEmpty()) {
			puerto->insertItem(puerto->count()-1,nPuerto);
			puerto->setCurrentIndex(puerto->count()-2);
		}
	}
}

void Ventana::slotUpdateCardType(const QString &value)
{
	statusBar()->showMessage(QString("Tipo de tarjeta cambiado a : %1").arg(value));
	if (value=="V0") {
		control.setCardType(KRW125ctl::V0);
	} else {
		control.setCardType(KRW125ctl::V1);
	}
}

void Ventana::slotAbrirPuerto()
{
	framePadre->setEnabled(false);
	if (control.isOpen()) {
		puerto->setEnabled(true);
		botonAbrirPuerto->setText("&Abrir puerto");
		control.close();
	} else {
		control.setName(puerto->currentText());
		QString msg;
		if (control.open()) {
			msg = "Se ha abierto el puerto correctamente";
			botonAbrirPuerto->setText("&Cerrar puerto");
			puerto->setEnabled(false);
			framePadre->setEnabled(true);
		} else {
			msg = "Imposible abrir puerto";
			puerto->setEnabled(true);
			framePadre->setEnabled(false);
		}
		statusBar()->showMessage(msg,0);
	}
}

void Ventana::slotTestNodeLink()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.testNodeLink();
}

void Ventana::slotTestNodeLinkDone(int result)
{
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	QString msg;
	switch(result)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Test del nodo correcto",0);
			msg = "Test correcto";
			break;
		case KRW125ctl::Failed:
		case KRW125ctl::NotOpen:
		case KRW125ctl::OperationError:
			statusBar()->showMessage("Ha fallado el test del nodo",0);
			msg = "Test incorrecto";
	}
	resultadoTest->setText(msg);
}

void Ventana::slotGetFirmwareVersion()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.getFirmwareVersion();
}

void Ventana::slotGetFirmwareVersionDone(bool correct, QPair< int, int > version)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	if (correct) {
		statusBar()->showMessage(QString::fromUtf8("Versión del firmware obtenida correctamente"),0);
		version0->setValue(version.first);
		version1->setValue(version.second);
	} else {
		statusBar()->showMessage(QString::fromUtf8("Ha fallado la obtención de la versión del firmware"),0);
		version0->setValue(-1);
		version1->setValue(-1);
	}
}

void Ventana::slotReadPublicMode()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.readPublicModeA();
}

void Ventana::slotReadPublicModeDone(int correct, const QString & hexData, const QString & decData)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	switch(correct)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Tarjeta leida correctamente",0);
			leidoHex->setText(hexData);
			leidoDec->setText(decData);
			break;
		default:
			statusBar()->showMessage("No se pudo leer la tarjeta",0);
			leidoHex->setText("");
			leidoDec->setText("");
			break;
	}
}

void Ventana::slotLockChanged(bool lock)
{
	if (lock) {
		if(QMessageBox::question(this,"Habilitar bloqueo de tarjetas",QString::fromUtf8("
¿Esta seguro de que quiere activar el bloqueo de tarjetas?

Recuerde que las tarjetas bloqueadas no pueden ser sobreescritas
"),QMessageBox::Ok,QMessageBox::Cancel) == QMessageBox::Ok) {
			control.setLockCard(lock);
		} else {
			bloquearTarjeta->setChecked(false);
		}
	} else {
		control.setLockCard(lock);
	}
}

void Ventana::slotWritePublicMode()
{
	feedbackBar->setMaximum(0);
	framePadre->setEnabled(false);
	botonAbrirPuerto->setEnabled(false);
	control.setData(paraEscribir->text().toAscii());
	control.writePublicModeA();
}

void Ventana::slotWritePublicModeDone(int correct)
{
	feedbackBar->setMaximum(1);
	feedbackBar->setValue(1);
	framePadre->setEnabled(true);
	botonAbrirPuerto->setEnabled(true);
	switch(correct)
	{
		case KRW125ctl::Ok:
			statusBar()->showMessage("Tarjeta escrita correctamente",0);
			break;
		default:
			statusBar()->showMessage("No se pudo escribir la tarjeta",0);
			break;
	}
}

void Ventana::validateData2Write(const QString &newText)
{
	QRegExp reg("[0-9aAbBcCdDeEfF]{10}");
	if (reg.exactMatch(newText)) {
		wrongData2Write->setVisible(false);
		botonEscribirTarjeta->setEnabled(true);
	} else {
		wrongData2Write->setVisible(true);
		botonEscribirTarjeta->setEnabled(false);
	}
}

<|endoftext|>


<commit_before>/*
 * This is a demo to show off GL goodnees
 */

#include <iostream>
#include <string>

#include "SDL4Cpp.h"
#include <GL/gl.h>
#include <GL/glu.h>

void Extensions()
{
	char *extensions = (char *)glGetString(GL_EXTENSIONS);

	if(!extensions)
	{
		std::cout << "No Extensions" << std::endl;
		return;
	}

	std::cout << "Extensions: " << std::endl;
	while(*extensions)
	{
		unsigned int len = strcspn(extensions, " ");
		char *temp = new char[len + 30];
		strncpy(temp, extensions, len);
		std::cout << "\t" << temp << std::endl;
		delete [] temp;
		extensions += len + 1;
	}
}

void DisplayTriangle(GLfloat angle)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();

	glRotatef(angle, 0.0f, 0.0f, 1.0f);

	glBegin(GL_TRIANGLES);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex3f(0.5f,  -0.5f, 0.0f);
		glColor3f(0.0f, 1.0f, 0.0f);
		glVertex3f(0.0f, 0.5f, 0.0f);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-0.5f, -0.5f, 0.0f);
	glEnd();

	SDL::GL::SwapBuffers();
}

int main(int argv, char *args[])
{
	SDL::Init(SDL_INIT_VIDEO);
	atexit(SDL::Quit);
	SDL::Screen screen;
	SDL::Event events;
	SDL::Timer timer;

	class Handler : public SDL::Handle
	{
		private:
			bool m_Stop;
		public:
			Handler() { m_Stop = false; }
			bool KeyPressed(SDL::KeySym &keysym)
			{
				if(keysym.sym != 0)
					m_Stop = true;

				return true;
			}

			operator bool() { return m_Stop; }
	} handler;

	SDL::WM::SetCaption("OpenGL Test");

	// Lets do some illegal things first and catch the errors
	try
	{
		void *test;
		test = SDL::GL::GetProcAddress("glNormalPointer");
	}
	catch(SDL::LogicError e)
	{
		std::cout << "Caught a throw: " << e.what() << std::endl;
	}

	try
	{
		int x;
		SDL::GL::GetAttribute(SDL_GL_DOUBLEBUFFER, x);
	}
	catch(SDL::LogicError e)
	{
		std::cout  << "I'm on a roll: " << e.what() << std::endl;
	}

	// And that's (almost) it for the illegal GL function calls, cool huh?
	// These aren't actually needed, but we'll set them anyways
	// Just like SDL these have to be set before the SetVideoMode to have an effect
	// Unlike SDL, SDL4Cpp will check if SetVideoMode has been called and throw if it has
	SDL::GL::SetAttribute(SDL_GL_RED_SIZE,   1);
	SDL::GL::SetAttribute(SDL_GL_GREEN_SIZE, 1);
	SDL::GL::SetAttribute(SDL_GL_BLUE_SIZE,  1);
	SDL::GL::SetAttribute(SDL_GL_DOUBLEBUFFER, true);
	screen.SetVideoMode(640, 480, 32, SDL_OPENGL);

	// Query some OpenGL version info
	std::cout << "----------------------------------" << std::endl
			<< "GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl
			<< "GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl
			<< "GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
	Extensions();
	std::cout  << "---------------------------------" << std::endl;

	// Couple more
	try
	{
		SDL::GL::LoadLibrary("libglib.so");
	}
	catch(SDL::LogicError e)
	{
		std::cout << "Not loading an external GL Library: " << e.what()
				<< std::endl;
	}

	// SetAttribute throws if the video mode is already setup
	try
	{
		SDL::GL::SetAttribute(SDL_GL_DOUBLEBUFFER, true);
	}
	// Here we'll use the standard logic_error
	catch(std::logic_error e)
	{
		std::cout  << "Caught a throw using std::logic_error instead: "
				<< e.what() << std::endl;
	}

	// Ok, let's do a little bit of OpenGL fun
	// How about a rotating triangle (ok, not as fun, but it'll
	// give beginers an idea how to do it.
	int now, ticks = 0;
	GLfloat angle = 0;
	while(!handler)
	{
		now = SDL::GetTicks();
		if((now - ticks) < 10)
			SDL::Delay(5);

		ticks = now;

		events.Poll(handler);
		DisplayTriangle(angle);
		angle += 0.2f;
	}

	return 0;
}

<commit_msg>Made TestGL more platform agnostic by including SDL_opengl.h Because different platforms use different conventions for OpenGL, it's best (at least for this) to include SDL's so that all the platform dependant includes are done for us.<commit_after>/*
 * This is a demo to show off GL goodnees
 */

#include <iostream>
#include <string>

#include "SDL4Cpp.h"
#include "SDL_opengl.h"

void Extensions()
{
	char *extensions = (char *)glGetString(GL_EXTENSIONS);

	if(!extensions)
	{
		std::cout << "No Extensions" << std::endl;
		return;
	}

	std::cout << "Extensions: " << std::endl;
	while(*extensions)
	{
		unsigned int len = strcspn(extensions, " ");
		char *temp = new char[len + 30];
		strncpy(temp, extensions, len);
		std::cout << "\t" << temp << std::endl;
		delete [] temp;
		extensions += len + 1;
	}
}

void DisplayTriangle(GLfloat angle)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();

	glRotatef(angle, 0.0f, 0.0f, 1.0f);

	glBegin(GL_TRIANGLES);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex3f(0.5f,  -0.5f, 0.0f);
		glColor3f(0.0f, 1.0f, 0.0f);
		glVertex3f(0.0f, 0.5f, 0.0f);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-0.5f, -0.5f, 0.0f);
	glEnd();

	SDL::GL::SwapBuffers();
}

int main(int argv, char *args[])
{
	SDL::Init(SDL_INIT_VIDEO);
	atexit(SDL::Quit);
	SDL::Screen screen;
	SDL::Event events;
	SDL::Timer timer;

	class Handler : public SDL::Handle
	{
		private:
			bool m_Stop;
		public:
			Handler() { m_Stop = false; }
			bool KeyPressed(SDL::KeySym &keysym)
			{
				if(keysym.sym != 0)
					m_Stop = true;

				return true;
			}

			operator bool() { return m_Stop; }
	} handler;

	SDL::WM::SetCaption("OpenGL Test");

	// Lets do some illegal things first and catch the errors
	try
	{
		void *test;
		test = SDL::GL::GetProcAddress("glNormalPointer");
	}
	catch(SDL::LogicError e)
	{
		std::cout << "Caught a throw: " << e.what() << std::endl;
	}

	try
	{
		int x;
		SDL::GL::GetAttribute(SDL_GL_DOUBLEBUFFER, x);
	}
	catch(SDL::LogicError e)
	{
		std::cout  << "I'm on a roll: " << e.what() << std::endl;
	}

	// And that's (almost) it for the illegal GL function calls, cool huh?
	// These aren't actually needed, but we'll set them anyways
	// Just like SDL these have to be set before the SetVideoMode to have an effect
	// Unlike SDL, SDL4Cpp will check if SetVideoMode has been called and throw if it has
	SDL::GL::SetAttribute(SDL_GL_RED_SIZE,   1);
	SDL::GL::SetAttribute(SDL_GL_GREEN_SIZE, 1);
	SDL::GL::SetAttribute(SDL_GL_BLUE_SIZE,  1);
	SDL::GL::SetAttribute(SDL_GL_DOUBLEBUFFER, true);
	screen.SetVideoMode(640, 480, 32, SDL_OPENGL);

	// Query some OpenGL version info
	std::cout << "----------------------------------" << std::endl
			<< "GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl
			<< "GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl
			<< "GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
	Extensions();
	std::cout  << "---------------------------------" << std::endl;

	// Couple more
	try
	{
		SDL::GL::LoadLibrary("libglib.so");
	}
	catch(SDL::LogicError e)
	{
		std::cout << "Not loading an external GL Library: " << e.what()
				<< std::endl;
	}

	// SetAttribute throws if the video mode is already setup
	try
	{
		SDL::GL::SetAttribute(SDL_GL_DOUBLEBUFFER, true);
	}
	// Here we'll use the standard logic_error
	catch(std::logic_error e)
	{
		std::cout  << "Caught a throw using std::logic_error instead: "
				<< e.what() << std::endl;
	}

	// Ok, let's do a little bit of OpenGL fun
	// How about a rotating triangle (ok, not as fun, but it'll
	// give beginers an idea how to do it.
	int now, ticks = 0;
	GLfloat angle = 0;
	while(!handler)
	{
		now = SDL::GetTicks();
		if((now - ticks) < 10)
			SDL::Delay(5);

		ticks = now;

		events.Poll(handler);
		DisplayTriangle(angle);
		angle += 0.2f;
	}

	return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE relativeMotion
#include <boost/test/included/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>

#include <boost/shared_ptr.hpp>

#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/configuration.hh>

#include <hpp/constraints/generic-transformation.hh>

#include <hpp/core/config-projector.hh>
#include <hpp/core/relative-motion.hh>
#include <hpp/core/constraint-set.hh>
#include <hpp/core/locked-joint.hh>
#include <hpp/core/numerical-constraint.hh>
#include <hpp/core/explicit-relative-transformation.hh>
#include <pinocchio/multibody/joint/joint-variant.hpp>
#include <pinocchio/multibody/geometry.hpp>

using hpp::pinocchio::Device;
using hpp::pinocchio::DevicePtr_t;
using hpp::pinocchio::JointPtr_t;

using hpp::constraints::RelativeTransformation;

using namespace hpp::core;
using namespace hpp::pinocchio;

using ::se3::JointModelPX;
using ::se3::JointModelPY;
using ::se3::JointModelPZ;
using ::se3::JointIndex;

bool verbose = false;

#define TOSTR( x ) static_cast< std::ostringstream & >( ( std::ostringstream() << x ) ).str()

DevicePtr_t createRobot ()
{

  DevicePtr_t robot = Device::create ("test");
  const std::string& name = robot->name ();
  ModelPtr_t m = ModelPtr_t(new ::se3::Model());
  GeomModelPtr_t gm = GeomModelPtr_t(new ::se3::GeometryModel());
  robot->model(m);
  robot->geomModel(gm);
  Transform3f mat; mat.setIdentity ();
  std::string jointName = name + "_x";

  JointModelPX::TangentVector_t max_effort = JointModelPX::TangentVector_t::Constant(JointModelPX::NV,std::numeric_limits<double>::max());
  JointModelPX::TangentVector_t max_velocity = JointModelPX::TangentVector_t::Constant(JointModelPX::NV,std::numeric_limits<double>::max());
  JointModelPX::ConfigVector_t lower_position = JointModelPY::ConfigVector_t::Constant(-4);
  JointModelPX::ConfigVector_t upper_position = JointModelPY::ConfigVector_t::Constant(4);

  JointIndex idJoint = robot->model().addJoint(0,JointModelPX(), mat,jointName,max_effort,max_velocity,lower_position,upper_position);

  std::string bname = "joint_a";
  for (int i = 0; i < 2; ++i) {
    idJoint = robot->model().addJoint(idJoint,JointModelPX(), mat,bname+TOSTR(i),max_effort,max_velocity,lower_position,upper_position);
  }
  bname = "joint_b";
  for (int i = 0; i < 3; ++i) {
    idJoint = robot->model().addJoint(idJoint,JointModelPX(), mat,bname+TOSTR(i),max_effort,max_velocity,lower_position,upper_position);
  }

  robot->createData();
  robot->createGeomData();
  return robot;
 /* DevicePtr_t robot = Device::create ("test");

  const std::string& name = robot->name ();
  fcl::Transform3f mat; mat.setIdentity ();
  JointPtr_t joint, root, parent;
  std::string jointName = name + "_x";
  // Translation along x
  root = objectFactory.createJointTranslation (mat);
  root->name (jointName);

  root->isBounded (0, 1);
  root->lowerBound (0, -4);
  root->upperBound (0, +4);

  robot->rootJoint (root);

  std::string bname = "joint_a";
  parent = root;
  for (int i = 0; i < 2; ++i) {
    joint = objectFactory.createJointTranslation (mat);
    std::stringstream ss; ss << bname << i;
    joint->name (ss.str());

    joint->isBounded (0, 1);
    joint->lowerBound (0, -4);
    joint->upperBound (0, +4);

    parent->addChildJoint (joint);
    parent = joint;
  }
  parent = root;
  bname = "joint_b";
  for (int i = 0; i < 3; ++i) {
    joint = objectFactory.createJointTranslation (mat);
    std::stringstream ss; ss << bname << i;
    joint->name (ss.str());

    joint->isBounded (0, 1);
    joint->lowerBound (0, -4);
    joint->upperBound (0, +4);

    parent->addChildJoint (joint);
    parent = joint;
  }
  return robot;*/
}

void lockJoint (ConfigProjectorPtr_t proj, DevicePtr_t dev, std::string name)
{
  JointPtr_t j = dev->getJointByName (name);
  Configuration_t q = dev->currentConfiguration();
  proj->add (
      LockedJoint::create(
        dev->getJointByName(name),
        q.segment(j->rankInConfiguration(), j->configSize()))
      );
}

struct Jidx {
  DevicePtr_t dev;
  size_type operator() (const std::string& jointname)
  {
    return RelativeMotion::idx(dev->getJointByName (jointname));
  }
};

BOOST_AUTO_TEST_CASE (relativeMotion)
{
  DevicePtr_t dev = createRobot();
  BOOST_REQUIRE (dev);
  Jidx jointid;
  jointid.dev = dev;

  JointConstPtr_t ja1 = dev->getJointByName ("joint_a1"),
                  jb2 = dev->getJointByName ("joint_b2");

  RelativeMotion::matrix_type m;

  ConfigProjectorPtr_t proj = ConfigProjector::create (dev, "test", 1e-3, 10);
  ConstraintSetPtr_t constraints = ConstraintSet::create (dev, "test");
  constraints->addConstraint(proj);

  // root, x, a0, a1, b0, b1, b2
  // 0,    1,  2,  3,  4,  5,  6
  BOOST_CHECK(jointid("universe") == 0);
  BOOST_CHECK(jointid("test_x")   == 1);
  BOOST_CHECK(jointid("joint_a0") == 2);
  BOOST_CHECK(jointid("joint_a1") == 3);
  BOOST_CHECK(jointid("joint_b0") == 4);
  BOOST_CHECK(jointid("joint_b1") == 5);
  BOOST_CHECK(jointid("joint_b2") == 6);

  // Lock some joints
  lockJoint (proj, dev, "joint_b1");

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b1")) == RelativeMotion::Parameterized); // lock b1

  if (verbose) std::cout << '\n' << m << std::endl;

  // Lock some joints
  lockJoint (proj, dev, "joint_b2");
  lockJoint (proj, dev, "joint_a1");

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_a0"),jointid("joint_a1")) == RelativeMotion::Parameterized); // lock a1
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b1")) == RelativeMotion::Parameterized); // lock b1
  BOOST_CHECK(m(jointid("joint_b1"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock b2

  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock b1+b2

  if (verbose) std::cout << '\n' << m << std::endl;

  // Add a relative transformation
  Configuration_t q = dev->neutralConfiguration();
  dev->currentConfiguration (q);
  dev->computeForwardKinematics ();
  Transform3f tf1 (ja1->currentTransformation ());
  Transform3f tf2 (jb2->currentTransformation ());
  proj->add (NumericalConstraint::create (
        RelativeTransformation::create ("", dev, ja1, jb2, tf1, tf2)));

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);
  BOOST_CHECK(m(jointid("joint_a1"),jointid("joint_b2")) == RelativeMotion::Constrained);   // lock rt
  BOOST_CHECK(m(jointid("joint_a0"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock a1 + rt
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_a1")) == RelativeMotion::Parameterized); // lock b1+b2+rt
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_a0")) == RelativeMotion::Parameterized); // lock b1+b2+rt+a1

  proj = ConfigProjector::create (dev, "test", 1e-3, 10);
  constraints = ConstraintSet::create (dev, "test");
  constraints->addConstraint(proj);
  proj->add (ExplicitRelativeTransformation::create ("", dev, ja1, jb2, tf1, tf2));
  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_a1"),jointid("joint_b2")) == RelativeMotion::Constrained);   // lock ert

  if (verbose) std::cout << '\n' << m << std::endl;
}

<commit_msg>[WIP] Update tests/relative-motion.cc<commit_after>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE relativeMotion
#include <boost/test/included/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>

#include <boost/shared_ptr.hpp>

#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/configuration.hh>

#include <hpp/constraints/generic-transformation.hh>

#include <hpp/core/config-projector.hh>
#include <hpp/core/relative-motion.hh>
#include <hpp/core/constraint-set.hh>
#include <hpp/core/locked-joint.hh>
#include <hpp/core/numerical-constraint.hh>
#include <hpp/core/explicit-relative-transformation.hh>
#include <pinocchio/multibody/joint/joint-variant.hpp>
#include <pinocchio/multibody/geometry.hpp>

using hpp::pinocchio::Device;
using hpp::pinocchio::DevicePtr_t;
using hpp::pinocchio::JointPtr_t;

using hpp::constraints::RelativeTransformation;

using namespace hpp::core;
using namespace hpp::pinocchio;

using ::se3::JointModelPX;
using ::se3::JointModelPY;
using ::se3::JointModelPZ;
using ::se3::JointIndex;

bool verbose = false;

#define TOSTR( x ) static_cast< std::ostringstream & >( ( std::ostringstream() << x ) ).str()

DevicePtr_t createRobot ()
{

  DevicePtr_t robot = Device::create ("test");
  const std::string& name = robot->name ();
  ModelPtr_t m = ModelPtr_t(new ::se3::Model());
  GeomModelPtr_t gm = GeomModelPtr_t(new ::se3::GeometryModel());
  robot->model(m);
  robot->geomModel(gm);
  Transform3f mat; mat.setIdentity ();
  std::string jointName = name + "_x";

  JointModelPX::TangentVector_t max_effort = JointModelPX::TangentVector_t::Constant(JointModelPX::NV,std::numeric_limits<double>::max());
  JointModelPX::TangentVector_t max_velocity = JointModelPX::TangentVector_t::Constant(JointModelPX::NV,std::numeric_limits<double>::max());
  JointModelPX::ConfigVector_t lower_position = JointModelPY::ConfigVector_t::Constant(-4);
  JointModelPX::ConfigVector_t upper_position = JointModelPY::ConfigVector_t::Constant(4);

  JointIndex idJoint = robot->model().addJoint(0,JointModelPX(), mat,jointName,max_effort,max_velocity,lower_position,upper_position);

  std::string bname = "joint_a";
  for (int i = 0; i < 2; ++i) {
    idJoint = robot->model().addJoint(idJoint,JointModelPX(), mat,bname+TOSTR(i),max_effort,max_velocity,lower_position,upper_position);
  }
  bname = "joint_b";
  for (int i = 0; i < 3; ++i) {
    idJoint = robot->model().addJoint(idJoint,JointModelPX(), mat,bname+TOSTR(i),max_effort,max_velocity,lower_position,upper_position);
  }

  robot->createData();
  robot->createGeomData();
  return robot;
 /* DevicePtr_t robot = Device::create ("test");

  const std::string& name = robot->name ();
  fcl::Transform3f mat; mat.setIdentity ();
  JointPtr_t joint, root, parent;
  std::string jointName = name + "_x";
  // Translation along x
  root = objectFactory.createJointTranslation (mat);
  root->name (jointName);

  root->isBounded (0, 1);
  root->lowerBound (0, -4);
  root->upperBound (0, +4);

  robot->rootJoint (root);

  std::string bname = "joint_a";
  parent = root;
  for (int i = 0; i < 2; ++i) {
    joint = objectFactory.createJointTranslation (mat);
    std::stringstream ss; ss << bname << i;
    joint->name (ss.str());

    joint->isBounded (0, 1);
    joint->lowerBound (0, -4);
    joint->upperBound (0, +4);

    parent->addChildJoint (joint);
    parent = joint;
  }
  parent = root;
  bname = "joint_b";
  for (int i = 0; i < 3; ++i) {
    joint = objectFactory.createJointTranslation (mat);
    std::stringstream ss; ss << bname << i;
    joint->name (ss.str());

    joint->isBounded (0, 1);
    joint->lowerBound (0, -4);
    joint->upperBound (0, +4);

    parent->addChildJoint (joint);
    parent = joint;
  }
  return robot;*/
}

void lockJoint (ConfigProjectorPtr_t proj, DevicePtr_t dev, std::string name)
{
  JointPtr_t j = dev->getJointByName (name);
  Configuration_t q = dev->currentConfiguration();
  proj->add (
      LockedJoint::create(
        dev->getJointByName(name),
        q.segment(j->rankInConfiguration(), j->configSize()))
      );
}

struct Jidx {
  DevicePtr_t dev;
  size_type operator() (const std::string& jointname)
  {
    return RelativeMotion::idx(dev->getJointByName (jointname));
  }
};

BOOST_AUTO_TEST_CASE (relativeMotion)
{
  DevicePtr_t dev = createRobot();
  BOOST_REQUIRE (dev);
  Jidx jointid;
  jointid.dev = dev;

  JointConstPtr_t ja1 = dev->getJointByName ("joint_a1"),
                  jb2 = dev->getJointByName ("joint_b2");

  RelativeMotion::matrix_type m;

  ConfigProjectorPtr_t proj = ConfigProjector::create (dev, "test", 1e-3, 10);
  ConstraintSetPtr_t constraints = ConstraintSet::create (dev, "test");
  constraints->addConstraint(proj);

  // root, x, a0, a1, b0, b1, b2
  // 0,    1,  2,  3,  4,  5,  6
  BOOST_CHECK(jointid("universe") == 0);
  BOOST_CHECK(jointid("test_x")   == 1);
  BOOST_CHECK(jointid("joint_a0") == 2);
  BOOST_CHECK(jointid("joint_a1") == 3);
  BOOST_CHECK(jointid("joint_b0") == 4);
  BOOST_CHECK(jointid("joint_b1") == 5);
  BOOST_CHECK(jointid("joint_b2") == 6);

  // Lock some joints
  lockJoint (proj, dev, "joint_b1");

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b1")) == RelativeMotion::Parameterized); // lock b1

  if (verbose) std::cout << '\n' << m << std::endl;

  // Lock some joints
  lockJoint (proj, dev, "joint_b2");
  lockJoint (proj, dev, "joint_a1");

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_a0"),jointid("joint_a1")) == RelativeMotion::Parameterized); // lock a1
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b1")) == RelativeMotion::Parameterized); // lock b1
  BOOST_CHECK(m(jointid("joint_b1"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock b2

  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock b1+b2

  if (verbose) std::cout << '\n' << m << std::endl;

  // Add a relative transformation
  Configuration_t q = dev->neutralConfiguration();
  dev->currentConfiguration (q);
  dev->computeForwardKinematics ();
  Transform3f tf1 (ja1->currentTransformation ());
  Transform3f tf2 (jb2->currentTransformation ());
  proj->add (NumericalConstraint::create (
        RelativeTransformation::create ("", dev, ja1, jb2, tf1, tf2)));

  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);
  BOOST_CHECK(m(jointid("joint_a1"),jointid("joint_b2")) == RelativeMotion::Constrained);   // lock rt
  BOOST_CHECK(m(jointid("joint_a0"),jointid("joint_b2")) == RelativeMotion::Parameterized); // lock a1 + rt
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_a1")) == RelativeMotion::Parameterized); // lock b1+b2+rt
  BOOST_CHECK(m(jointid("joint_b0"),jointid("joint_a0")) == RelativeMotion::Parameterized); // lock b1+b2+rt+a1

  proj = ConfigProjector::create (dev, "test", 1e-3, 10);
  constraints = ConstraintSet::create (dev, "test");
  constraints->addConstraint(proj);
  proj->add (ExplicitRelativeTransformation::create ("", dev, ja1, jb2, tf1, tf2)->createNumericalConstraint());
  m = RelativeMotion::matrix(dev);
  RelativeMotion::fromConstraint (m, dev, constraints);

  BOOST_CHECK(m(jointid("joint_a1"),jointid("joint_b2")) == RelativeMotion::Constrained);   // lock ert

  if (verbose) std::cout << '\n' << m << std::endl;
}

<|endoftext|>


<commit_before>/*
 * App Communication over Bluetooth LE using GATT Profile
 *
 * Copyright (C)2015-2017 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "app_interface.h"

extern AppInterface app;

AppInterface::AppInterface(Adafruit_BluefruitLE_SPI& ble, PanoSettings& settings, PanoState& state)
:settings(settings), state(state), ble(ble)
{}

/*
 * Set up some redirects from BLE callbacks in global scope to app singleton methods
 */
void callbackGattRX(int32_t char_id, uint8_t* data, uint16_t len){
    //{ debug
    Serial.print("BLE GATT RX char=");
    Serial.print(char_id);
    Serial.print(" len=");
    Serial.print(len);
    Serial.print(" data=");
    for (int i = 0; i < len; i++) { Serial.print(data[i], HEX); Serial.print("-"); };
    Serial.println("");
    //} debug
    app.gattRX(char_id, data, len);
}
void callbackUartRX(char data[], uint16_t len){
    //{ debug
        Serial.print("BLE UART RX len=");
        Serial.print(len);
        Serial.print(" data=");
        for (int i = 0; i < len; i++) { Serial.print(data[i], HEX); Serial.print("-"); };
        Serial.println("");
        //} debug
        app.uartRX((uint8_t *)data, len);
}
void callbackDidConnect(void){
    app.didConnect();
}
void callbackDidDisconnect(void){
    app.didDisconnect();
}

void AppInterface::begin(){
    ble.sendCommandCheckOK("AT+BAUDRATE=921600");
    // LED Activity command is only supported from 0.6.6
    ble.sendCommandCheckOK("AT+HWMODELED=BLEUART");
    ble.sendCommandCheckOK("AT+GAPDEVNAME=Pano Controller");

    gatt = new Adafruit_BLEGatt(ble);
    service_id = gatt->addService(SERVICE_UUID);
    config_char_id = gatt->addCharacteristic(CONFIG_CHAR_UUID, GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_WRITE | GATT_CHARS_PROPERTIES_WRITE_WO_RESP,
                                             5, 20, BLE_DATATYPE_BYTEARRAY, "Configuration");
    status_char_id = gatt->addCharacteristic(STATUS_CHAR_UUID, GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_NOTIFY,
                                             sizeof(PanoState), sizeof(PanoState), BLE_DATATYPE_BYTEARRAY, "Status");
    cmd_char_id = gatt->addCharacteristic(CMD_CHAR_UUID, GATT_CHARS_PROPERTIES_WRITE,
                                          1, 20, BLE_DATATYPE_BYTEARRAY, "Command");
    ble.sendCommandCheckOK("AT+GAPSETADVDATA=07-02-17-20-0A-18-0F-18"); // 7=number of bytes following, 02-flag for 16-bit service uuids, 17-20 = 0x2017, 0x180A, 0x180F
    ble.sendCommandCheckOK("AT+GAPCONNECTABLE=1");
    ble.reset();
    ble.sendCommandCheckOK("AT+GATTLIST");
    ble.setConnectCallback(callbackDidConnect);
    ble.setDisconnectCallback(callbackDidDisconnect);
    ble.setBleGattRxCallback(config_char_id, callbackGattRX);
    ble.setBleGattRxCallback(cmd_char_id, callbackGattRX);
    ble.setBleUartRxCallback(callbackUartRX);
}

void AppInterface::sendStatus(){
    //Serial.println("Send status");
    gatt->setChar(status_char_id, (uint8_t*)&state, sizeof(state));
}

void AppInterface::gattRX(int32_t char_id, uint8_t* data, uint16_t len){
    if (char_id == config_char_id || char_id == cmd_char_id){
        uartRX(data, len);
    }
}
static bool unpack(settings_t& variable, uint8_t* &data, uint16_t& len){
    if (len >= 2*sizeof(variable)){
        len -= 2*sizeof(variable);
        variable = 0;
        for (int i=2*sizeof(variable); i; i--){
            variable = (variable <<= 4) + (*data++ - 0x30);
        }
        return true;
    }
    return false;
}
void AppInterface::uartRX(uint8_t* data, uint16_t len){
    static uint8_t keyCode;
    bool updateConfig = false;
    while (len-- >= 1){
        keyCode = *data++;
        switch (keyCode){

            // Configs
            case 0x41: updateConfig |= unpack(settings.focal, data, len); break;
            case 0x42: updateConfig |= unpack(settings.shutter, data, len); break;
            case 0x43: updateConfig |= unpack(settings.pre_shutter, data, len); break;
            case 0x44: updateConfig |= unpack(settings.post_wait, data, len); break;
            case 0x45: updateConfig |= unpack(settings.long_pulse, data, len); break;
            case 0x46: updateConfig |= unpack(settings.aspect, data, len); break;
            case 0x47: updateConfig |= unpack(settings.shots, data, len); break;
            case 0x48: updateConfig |= unpack(settings.motors_enable, data, len); break;
            case 0x49: updateConfig |= unpack(settings.motors_on, data, len); break;
            case 0x4A: updateConfig |= unpack(settings.display_invert, data, len); break;
            case 0x4B: updateConfig |= unpack(settings.horiz, data, len); break;
            case 0x4C: updateConfig |= unpack(settings.vert, data, len); break;

            // Commands
            case 0x61: callbacks.start(); break;
            case 0x62: callbacks.cancel(); break;
            case 0x63: callbacks.pause(); break;
            case 0x64: callbacks.shutter(); break;
            case 0x65: callbacks.setHome(); break;
            case 0x66: callbacks.goHome(); break;
            case 0x67: sendStatus(); break;
            case 0x68: // free move
                if (len >= 2 * 2 * sizeof(settings_t)){
                    settings_t horiz_move, vert_move;
                    unpack(horiz_move, data, len);
                    unpack(vert_move, data, len);
                    callbacks.freeMove(horiz_move/100, vert_move/100);
                }
                break;
            case 0x69: // incremental move (forward or backward)
                // TODO: check that len=2
                if (len >= 2){
                    callbacks.gridMove((char)data[0]);
                    len--;
                    data++;
                }
                break;
            default:
                Serial.print("Unknown code received: "); Serial.println(keyCode, HEX);
        }
    }
    if (updateConfig){
        callbacks.config();
    }
}

void AppInterface::didConnect(void){
    Serial.println("BLE connected");
    connected = true;
}

void AppInterface::didDisconnect(void){
    Serial.println("BLE disconnected");
    connected = false;
}

bool AppInterface::isConnected(void){
    return connected;
}

void AppInterface::poll(uint32_t timeout){
    ble.update(timeout);
}
<commit_msg>gridMove was ignored because of wrong length check<commit_after>/*
 * App Communication over Bluetooth LE using GATT Profile
 *
 * Copyright (C)2015-2017 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "app_interface.h"

extern AppInterface app;

AppInterface::AppInterface(Adafruit_BluefruitLE_SPI& ble, PanoSettings& settings, PanoState& state)
:settings(settings), state(state), ble(ble)
{}

/*
 * Set up some redirects from BLE callbacks in global scope to app singleton methods
 */
void callbackGattRX(int32_t char_id, uint8_t* data, uint16_t len){
    //{ debug
    Serial.print("BLE GATT RX char=");
    Serial.print(char_id);
    Serial.print(" len=");
    Serial.print(len);
    Serial.print(" data=");
    for (int i = 0; i < len; i++) { Serial.print(data[i], HEX); Serial.print("-"); };
    Serial.println("");
    //} debug
    app.gattRX(char_id, data, len);
}
void callbackUartRX(char data[], uint16_t len){
    //{ debug
        Serial.print("BLE UART RX len=");
        Serial.print(len);
        Serial.print(" data=");
        for (int i = 0; i < len; i++) { Serial.print(data[i], HEX); Serial.print("-"); };
        Serial.println("");
        //} debug
        app.uartRX((uint8_t *)data, len);
}
void callbackDidConnect(void){
    app.didConnect();
}
void callbackDidDisconnect(void){
    app.didDisconnect();
}

void AppInterface::begin(){
    ble.sendCommandCheckOK("AT+BAUDRATE=921600");
    // LED Activity command is only supported from 0.6.6
    ble.sendCommandCheckOK("AT+HWMODELED=BLEUART");
    ble.sendCommandCheckOK("AT+GAPDEVNAME=Pano Controller");

    gatt = new Adafruit_BLEGatt(ble);
    service_id = gatt->addService(SERVICE_UUID);
    config_char_id = gatt->addCharacteristic(CONFIG_CHAR_UUID, GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_WRITE | GATT_CHARS_PROPERTIES_WRITE_WO_RESP,
                                             5, 20, BLE_DATATYPE_BYTEARRAY, "Configuration");
    status_char_id = gatt->addCharacteristic(STATUS_CHAR_UUID, GATT_CHARS_PROPERTIES_READ | GATT_CHARS_PROPERTIES_NOTIFY,
                                             sizeof(PanoState), sizeof(PanoState), BLE_DATATYPE_BYTEARRAY, "Status");
    cmd_char_id = gatt->addCharacteristic(CMD_CHAR_UUID, GATT_CHARS_PROPERTIES_WRITE,
                                          1, 20, BLE_DATATYPE_BYTEARRAY, "Command");
    ble.sendCommandCheckOK("AT+GAPSETADVDATA=07-02-17-20-0A-18-0F-18"); // 7=number of bytes following, 02-flag for 16-bit service uuids, 17-20 = 0x2017, 0x180A, 0x180F
    ble.sendCommandCheckOK("AT+GAPCONNECTABLE=1");
    ble.reset();
    ble.sendCommandCheckOK("AT+GATTLIST");
    ble.setConnectCallback(callbackDidConnect);
    ble.setDisconnectCallback(callbackDidDisconnect);
    ble.setBleGattRxCallback(config_char_id, callbackGattRX);
    ble.setBleGattRxCallback(cmd_char_id, callbackGattRX);
    ble.setBleUartRxCallback(callbackUartRX);
}

void AppInterface::sendStatus(){
    //Serial.println("Send status");
    gatt->setChar(status_char_id, (uint8_t*)&state, sizeof(state));
}

void AppInterface::gattRX(int32_t char_id, uint8_t* data, uint16_t len){
    if (char_id == config_char_id || char_id == cmd_char_id){
        uartRX(data, len);
    }
}
static bool unpack(settings_t& variable, uint8_t* &data, uint16_t& len){
    if (len >= 2*sizeof(variable)){
        len -= 2*sizeof(variable);
        variable = 0;
        for (int i=2*sizeof(variable); i; i--){
            variable = (variable <<= 4) + (*data++ - 0x30);
        }
        return true;
    }
    return false;
}
void AppInterface::uartRX(uint8_t* data, uint16_t len){
    static uint8_t keyCode;
    bool updateConfig = false;
    while (len-- >= 1){
        keyCode = *data++;
        switch (keyCode){

            // Configs
            case 0x41: updateConfig |= unpack(settings.focal, data, len); break;
            case 0x42: updateConfig |= unpack(settings.shutter, data, len); break;
            case 0x43: updateConfig |= unpack(settings.pre_shutter, data, len); break;
            case 0x44: updateConfig |= unpack(settings.post_wait, data, len); break;
            case 0x45: updateConfig |= unpack(settings.long_pulse, data, len); break;
            case 0x46: updateConfig |= unpack(settings.aspect, data, len); break;
            case 0x47: updateConfig |= unpack(settings.shots, data, len); break;
            case 0x48: updateConfig |= unpack(settings.motors_enable, data, len); break;
            case 0x49: updateConfig |= unpack(settings.motors_on, data, len); break;
            case 0x4A: updateConfig |= unpack(settings.display_invert, data, len); break;
            case 0x4B: updateConfig |= unpack(settings.horiz, data, len); break;
            case 0x4C: updateConfig |= unpack(settings.vert, data, len); break;

            // Commands
            case 0x61: callbacks.start(); break;
            case 0x62: callbacks.cancel(); break;
            case 0x63: callbacks.pause(); break;
            case 0x64: callbacks.shutter(); break;
            case 0x65: callbacks.setHome(); break;
            case 0x66: callbacks.goHome(); break;
            case 0x67: sendStatus(); break;
            case 0x68: // free move
                if (len >= 2 * 2 * sizeof(settings_t)){
                    settings_t horiz_move, vert_move;
                    unpack(horiz_move, data, len);
                    unpack(vert_move, data, len);
                    callbacks.freeMove(horiz_move/100, vert_move/100);
                }
                break;
            case 0x69: // incremental move (forward or backward)
                if (len >= 1){
                    callbacks.gridMove((char)data[0]);
                    len--;
                    data++;
                }
                break;
            default:
                Serial.print("Unknown code received: "); Serial.println(keyCode, HEX);
        }
    }
    if (updateConfig){
        callbacks.config();
    }
}

void AppInterface::didConnect(void){
    Serial.println("BLE connected");
    connected = true;
}

void AppInterface::didDisconnect(void){
    Serial.println("BLE disconnected");
    connected = false;
}

bool AppInterface::isConnected(void){
    return connected;
}

void AppInterface::poll(uint32_t timeout){
    ble.update(timeout);
}
<|endoftext|>


<commit_before>#include "menu.h"
#include <QDebug>
#include <QString>
#include <QPainter>
#include <QPaintEvent>
#include <QBrush>
#include <QColor>
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>

#include "showcaseview.h"

Menu::Menu()
{
    initializeMenu();

}

void Menu::initializeMenu()
{
    // setMouseTracking(true);
     buttonRectSize = QSize(150,50);
     setWindowTitle("Sub Menu");
     this->setFixedSize(800,600);

     //Welcome
     welcomeMessage = new QLabel();

         //Sizingprivate:
     welcomeMessage->setFixedSize(400,300);

         //Font
     welcomeFont = QFont("Calibri",15);
     welcomeFont.setItalic(true);
     welcomeFont.setBold(true);

         //Set Text
     welcomeMessage->setFont(welcomeFont);
     welcomeMessage->setText("Welcome to the menu\nPlease select your view");

     //Making the Buttons
     guiButton = new QPushButton();
     simButton = new QPushButton();
     autButton = new QPushButton();

          //Connecting
     connect(guiButton, SIGNAL(clicked()), this, SLOT(makeView()));

          //Sizing
     guiButton->setFixedSize(buttonRectSize);
     simButton->setFixedSize(buttonRectSize);
     autButton->setFixedSize(buttonRectSize);

         //Text Sizing and Font
     menuItemFont = QFont("Times New Roman",12);
     menuItemFont.setItalic(true);

     guiButton->setFont(menuItemFont);
     simButton->setFont(menuItemFont);
     autButton->setFont(menuItemFont);

        //Change Color when mouse hovers over a menu setMouseTrack item
     guiButton->setStyleSheet("QPushButton:hover{ background-color : lightGrey; color:black}");
     simButton->setStyleSheet("QPushButton:hover{ background-color : lightGrey; color:black}");
     autButton->setStyleSheet("QPushButton:hover{ background-color : lightGrey; color:black}");

         //Text
     guiButton->setText("Gui Mode");
     simButton->setText("Simulation Mode");
     autButton->setText("Autonomous Mode");

     //Layout

         //Sizing
     mainLayout = new QGridLayout();

     mainLayout->setSpacing(10);

     for (int i = 0; i<10; i++)
    {
         mainLayout->setRowStretch(i,1); //Setting max size relative to minimum for the first 10 rows
    }

     for (int i = 0; i<10; i++)
    {
     mainLayout->setRowMinimumHeight(i,100); //Setting 10 rows of equal "size" 100
     }

     for (int i = 0; i<10; i++)
    {
         mainLayout->setColumnStretch(i,1); //Setting max size relative to minimum for the first 10 Columns
    }

     for (int i = 0; i<10; i++)
    {
     mainLayout->setColumnMinimumWidth(i,100); //Setting 10 Columns of equal "size" 100
     }

         //Positioning      *note that the widgets span multiple rows and columns
     mainLayout->addWidget(welcomeMessage,0,5);
     mainLayout->addWidget(guiButton,3,6);
     mainLayout->addWidget(simButton,4,6);
     mainLayout->addWidget(autButton,5,6);
     this->setLayout(mainLayout);

     //Leave only the button text visible

     guiButton->setFlat(true);
     simButton->setFlat(true);
     autButton->setFlat(true);

}

void Menu::paintEvent(QPaintEvent *event)
{

     QImage background(":/img/MDA.jpg");
     background = background.scaled(800,700);

    QPainter painter;

     painter.begin(this);
    painter.fillRect(event->rect(), background);

    painter.end();
}

void Menu::makeView()
{
    ShowCaseView *view = new ShowCaseView;
    view->show();

    Controller *controller = new Controller();
    controller->initialize();

    view->initialize_VC_Connection(controller);//Connect the controller to the view

    this->close();
}
<commit_msg>Delete menu.cpp<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Lua scripting module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Error.hpp>
#include <Nazara/Lua/Debug.hpp>

template<class T>
NzLuaClass<T>::NzLuaClass(const NzString& name) :
m_info(new ClassInfo)
{
	m_info->name = name;
}
/*
template<class T>
void NzLuaClass<T>::Inherit(NzLuaClass<P>& parent)
{
	static_assert(std::is_base_of<P, T>::value, "P must be a base of T");

	m_info->parentInfo = parent.m_info;
}
*/
template<class T>
void NzLuaClass<T>::Register(NzLuaInstance& lua)
{
	// Le ClassInfo doit rester en vie jusqu'à la fin du script
	// Obliger l'instance de LuaClass à rester en vie dans cette fin serait contraignant pour l'utilisateur
	// J'utilise donc une astuce, la stocker dans une UserData associée avec chaque fonction de la metatable du type,
	// cette UserData disposera d'un finalizer qui libérera le ClassInfo
	// Ainsi c'est Lua qui va s'occuper de la destruction pour nous :-)
	// De même, l'utilisation d'un shared_ptr permet de garder la structure en vie même si l'instance est libérée avant le LuaClass
	void* info = lua.PushUserdata(sizeof(std::shared_ptr<ClassInfo>));
	new (info) std::shared_ptr<ClassInfo>(m_info);

	// On créé la table qui contiendra une méthode (Le finalizer) pour libérer le ClassInfo
	lua.PushTable(0, 1);
		lua.PushLightUserdata(info);
		lua.PushCFunction(InfoDestructor, 1);
		lua.SetField("__gc");
	lua.SetMetatable(-2); // La table devient la metatable de l'UserData

	// Maintenant, nous allons associer l'UserData avec chaque fonction, de sorte qu'il reste en vie
	// aussi longtemps que nécessaire, et que le pointeur soit transmis à chaque méthode

	if (!lua.NewMetatable(m_info->name))
		NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance");
	{
		lua.PushValue(1); // On associe l'UserData avec la fonction
		lua.PushCFunction(FinalizerProxy, 1);
		lua.SetField("__gc"); // Finalizer

		if (m_info->getter)
		{
			lua.PushValue(1);
			lua.PushCFunction(GetterProxy, 1);
		}
		else
			// Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher
			// dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche
			// Ceci n'est possible que si nous n'avons ni getter, ni parent
			lua.PushValue(-1);

		lua.SetField("__index"); // Getter

		if (m_info->setter)
		{
			lua.PushValue(1);
			lua.PushCFunction(SetterProxy, 1);
			lua.SetField("__newindex"); // Setter
		}

		m_info->methods.resize(m_methods.size());

		unsigned int index = 0;
		for (auto& pair : m_methods)
		{
			m_info->methods[index] = pair.second;

			lua.PushValue(1);
			lua.PushInteger(index);

			lua.PushCFunction(MethodProxy, 2);
			lua.SetField(pair.first); // Méthode

			index++;
		}
	}
	lua.Pop(); // On pop la metatable

	if (m_info->constructor)
	{
		lua.PushValue(1);
		lua.PushCFunction(ConstructorProxy, 1);
		lua.SetGlobal(m_info->name);
	}
	lua.Pop(); // On pop l'Userdata (contenant nos informations)
}

template<class T>
void NzLuaClass<T>::SetConstructor(ConstructorFunc constructor)
{
	m_info->constructor = constructor;
}

template<class T>
void NzLuaClass<T>::SetFinalizer(FinalizerFunc finalizer)
{
	m_info->finalizer = finalizer;
}

template<class T>
void NzLuaClass<T>::SetGetter(ClassIndexFunc getter)
{
	m_info->getter = getter;
}

template<class T>
void NzLuaClass<T>::SetMethod(const NzString& name, ClassFunc method)
{
	m_methods[name] = method;
}

template<class T>
void NzLuaClass<T>::SetSetter(ClassIndexFunc setter)
{
	m_info->setter = setter;
}

template<class T>
int NzLuaClass<T>::ConstructorProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ConstructorFunc constructor = info->constructor;

	T* instance = constructor(lua);
	if (!instance)
	{
		lua.Error("Constructor failed");
		return 0; // Normalement jamais exécuté (l'erreur provoquant une exception)
	}

	T** ud = static_cast<T**>(lua.PushUserdata(sizeof(T*)));
	*ud = instance;
	lua.SetMetatable(info->name);

	return 1;
}

template<class T>
int NzLuaClass<T>::FinalizerProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	FinalizerFunc finalizer = info->finalizer;

	T* instance = *static_cast<T**>(lua.CheckUserdata(1, info->name));

	if (!finalizer || finalizer(lua, *instance))
		delete instance;

	return 0;
}

template<class T>
int NzLuaClass<T>::InfoDestructor(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	std::shared_ptr<ClassInfo>* infoPtr = static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));

	using namespace std; // Obligatoire pour le destructeur
	infoPtr->~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur

	return 0;
}

template<class T>
int NzLuaClass<T>::GetterProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ClassIndexFunc getter = info->getter;

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	if (!getter(lua, instance))
	{
		// On accède alors à la table
		lua.PushMetatable(info->name);
		lua.PushValue(-2);
		lua.GetTable();
	}

	return 1;
}

template<class T>
int NzLuaClass<T>::MethodProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	int index = lua.ToInteger(lua.GetIndexOfUpValue(2));
	ClassFunc method = info->methods[index];

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	return method(lua, instance);
}

template<class T>
int NzLuaClass<T>::SetterProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ClassIndexFunc setter = info->setter;

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	if (!setter(lua, instance))
	{
		std::size_t length;
		const char* str = lua.Tostring(2, &length);

		lua.Error("Class "\"" + info->name + "\" has no field \"" + NzString(str, length) + ')');
	}

	return 1;
}

#include <Nazara/Lua/DebugOff.hpp>
<commit_msg>Fixed LuaClass code<commit_after>// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Lua scripting module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Error.hpp>
#include <Nazara/Lua/Debug.hpp>

template<class T>
NzLuaClass<T>::NzLuaClass(const NzString& name) :
m_info(new ClassInfo)
{
	m_info->name = name;
}
/*
template<class T>
void NzLuaClass<T>::Inherit(NzLuaClass<P>& parent)
{
	static_assert(std::is_base_of<P, T>::value, "P must be a base of T");

	m_info->parentInfo = parent.m_info;
}
*/
template<class T>
void NzLuaClass<T>::Register(NzLuaInstance& lua)
{
	// Le ClassInfo doit rester en vie jusqu'à la fin du script
	// Obliger l'instance de LuaClass à rester en vie dans cette fin serait contraignant pour l'utilisateur
	// J'utilise donc une astuce, la stocker dans une UserData associée avec chaque fonction de la metatable du type,
	// cette UserData disposera d'un finalizer qui libérera le ClassInfo
	// Ainsi c'est Lua qui va s'occuper de la destruction pour nous :-)
	// De même, l'utilisation d'un shared_ptr permet de garder la structure en vie même si l'instance est libérée avant le LuaClass
	void* info = lua.PushUserdata(sizeof(std::shared_ptr<ClassInfo>));
	new (info) std::shared_ptr<ClassInfo>(m_info);

	// On créé la table qui contiendra une méthode (Le finalizer) pour libérer le ClassInfo
	lua.PushTable(0, 1);
		lua.PushLightUserdata(info);
		lua.PushCFunction(InfoDestructor, 1);
		lua.SetField("__gc");
	lua.SetMetatable(-2); // La table devient la metatable de l'UserData

	// Maintenant, nous allons associer l'UserData avec chaque fonction, de sorte qu'il reste en vie
	// aussi longtemps que nécessaire, et que le pointeur soit transmis à chaque méthode

	if (!lua.NewMetatable(m_info->name))
		NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance");
	{
		lua.PushValue(1); // On associe l'UserData avec la fonction
		lua.PushCFunction(FinalizerProxy, 1);
		lua.SetField("__gc"); // Finalizer

		if (m_info->getter)
		{
			lua.PushValue(1);
			lua.PushCFunction(GetterProxy, 1);
		}
		else
			// Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher
			// dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche
			// Ceci n'est possible que si nous n'avons ni getter, ni parent
			lua.PushValue(-1);

		lua.SetField("__index"); // Getter

		if (m_info->setter)
		{
			lua.PushValue(1);
			lua.PushCFunction(SetterProxy, 1);
			lua.SetField("__newindex"); // Setter
		}

		m_info->methods.resize(m_methods.size());

		unsigned int index = 0;
		for (auto& pair : m_methods)
		{
			m_info->methods[index] = pair.second;

			lua.PushValue(1);
			lua.PushInteger(index);

			lua.PushCFunction(MethodProxy, 2);
			lua.SetField(pair.first); // Méthode

			index++;
		}
	}
	lua.Pop(); // On pop la metatable

	if (m_info->constructor)
	{
		lua.PushValue(1);
		lua.PushCFunction(ConstructorProxy, 1);
		lua.SetGlobal(m_info->name);
	}
	lua.Pop(); // On pop l'Userdata (contenant nos informations)
}

template<class T>
void NzLuaClass<T>::SetConstructor(ConstructorFunc constructor)
{
	m_info->constructor = constructor;
}

template<class T>
void NzLuaClass<T>::SetFinalizer(FinalizerFunc finalizer)
{
	m_info->finalizer = finalizer;
}

template<class T>
void NzLuaClass<T>::SetGetter(ClassIndexFunc getter)
{
	m_info->getter = getter;
}

template<class T>
void NzLuaClass<T>::SetMethod(const NzString& name, ClassFunc method)
{
	m_methods[name] = method;
}

template<class T>
void NzLuaClass<T>::SetSetter(ClassIndexFunc setter)
{
	m_info->setter = setter;
}

template<class T>
int NzLuaClass<T>::ConstructorProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ConstructorFunc constructor = info->constructor;

	T* instance = constructor(lua);
	if (!instance)
	{
		lua.Error("Constructor failed");
		return 0; // Normalement jamais exécuté (l'erreur provoquant une exception)
	}

	T** ud = static_cast<T**>(lua.PushUserdata(sizeof(T*)));
	*ud = instance;
	lua.SetMetatable(info->name);

	return 1;
}

template<class T>
int NzLuaClass<T>::FinalizerProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	FinalizerFunc finalizer = info->finalizer;

	T* instance = *static_cast<T**>(lua.CheckUserdata(1, info->name));

	if (!finalizer || finalizer(lua, *instance))
		delete instance;

	return 0;
}

template<class T>
int NzLuaClass<T>::InfoDestructor(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	std::shared_ptr<ClassInfo>* infoPtr = static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));

	using namespace std; // Obligatoire pour le destructeur
	infoPtr->~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur

	return 0;
}

template<class T>
int NzLuaClass<T>::GetterProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ClassIndexFunc getter = info->getter;

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	if (!getter(lua, instance))
	{
		// On accède alors à la table
		lua.PushMetatable(info->name);
		lua.PushValue(-2);
		lua.GetTable();
	}

	return 1;
}

template<class T>
int NzLuaClass<T>::MethodProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	int index = lua.ToInteger(lua.GetIndexOfUpValue(2));
	ClassFunc method = info->methods[index];

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	return method(lua, instance);
}

template<class T>
int NzLuaClass<T>::SetterProxy(lua_State* state)
{
	NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);

	ClassInfo* info = *static_cast<ClassInfo**>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
	ClassIndexFunc setter = info->setter;

	T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));

	if (!setter(lua, instance))
	{
		std::size_t length;
		const char* str = lua.ToString(2, &length);

		lua.Error("Class \"" + info->name + "\" has no field \"" + NzString(str, length) + ')');
	}

	return 1;
}

#include <Nazara/Lua/DebugOff.hpp>
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * 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 the copyright holders 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.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#ifndef __ALPHA_MEMORY_HH__
#define __ALPHA_MEMORY_HH__

#include <map>

#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/pagetable.hh"
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
#include "sim/sim_object.hh"

class ThreadContext;

namespace AlphaISA
{
    class PTE;

    class TLB : public SimObject
    {
      protected:
        typedef std::multimap<Addr, int> PageTable;
        PageTable lookupTable;	// Quick lookup into page table

        PTE *table;	// the Page Table
        int size;			// TLB Size
        int nlu;			// not last used entry (for replacement)

        void nextnlu() { if (++nlu >= size) nlu = 0; }
        PTE *lookup(Addr vpn, uint8_t asn) const;

      public:
        TLB(const std::string &name, int size);
        virtual ~TLB();

        int getsize() const { return size; }

        PTE &index(bool advance = true);
        void insert(Addr vaddr, PTE &pte);

        void flushAll();
        void flushProcesses();
        void flushAddr(Addr addr, uint8_t asn);

        // static helper functions... really EV5 VM traits
        static bool validVirtualAddress(Addr vaddr) {
            // unimplemented bits must be all 0 or all 1
            Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
            return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
        }

        static Fault checkCacheability(RequestPtr &req);

        // Checkpointing
        virtual void serialize(std::ostream &os);
        virtual void unserialize(Checkpoint *cp, const std::string &section);

        // Most recently used page table entries
        PTE *PTECache[2];
        inline void flushCache() { memset(PTECache, 0, 2 * sizeof(PTE*)); }
    };

    class ITB : public TLB
    {
      protected:
        mutable Stats::Scalar<> hits;
        mutable Stats::Scalar<> misses;
        mutable Stats::Scalar<> acv;
        mutable Stats::Formula accesses;

      public:
        ITB(const std::string &name, int size);
        virtual void regStats();

        Fault translate(RequestPtr &req, ThreadContext *tc) const;
    };

    class DTB : public TLB
    {
      protected:
        mutable Stats::Scalar<> read_hits;
        mutable Stats::Scalar<> read_misses;
        mutable Stats::Scalar<> read_acv;
        mutable Stats::Scalar<> read_accesses;
        mutable Stats::Scalar<> write_hits;
        mutable Stats::Scalar<> write_misses;
        mutable Stats::Scalar<> write_acv;
        mutable Stats::Scalar<> write_accesses;
        Stats::Formula hits;
        Stats::Formula misses;
        Stats::Formula acv;
        Stats::Formula accesses;

      public:
        DTB(const std::string &name, int size);
        virtual void regStats();

        Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const;
    };
}

#endif // __ALPHA_MEMORY_HH__
<commit_msg>Alpha: Fix an off by one error with the tlb caching mechanism.<commit_after>/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * 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 the copyright holders 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.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#ifndef __ALPHA_MEMORY_HH__
#define __ALPHA_MEMORY_HH__

#include <map>

#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/pagetable.hh"
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
#include "sim/sim_object.hh"

class ThreadContext;

namespace AlphaISA
{
    class PTE;

    class TLB : public SimObject
    {
      protected:
        typedef std::multimap<Addr, int> PageTable;
        PageTable lookupTable;	// Quick lookup into page table

        PTE *table;	// the Page Table
        int size;			// TLB Size
        int nlu;			// not last used entry (for replacement)

        void nextnlu() { if (++nlu >= size) nlu = 0; }
        PTE *lookup(Addr vpn, uint8_t asn) const;

      public:
        TLB(const std::string &name, int size);
        virtual ~TLB();

        int getsize() const { return size; }

        PTE &index(bool advance = true);
        void insert(Addr vaddr, PTE &pte);

        void flushAll();
        void flushProcesses();
        void flushAddr(Addr addr, uint8_t asn);

        // static helper functions... really EV5 VM traits
        static bool validVirtualAddress(Addr vaddr) {
            // unimplemented bits must be all 0 or all 1
            Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
            return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
        }

        static Fault checkCacheability(RequestPtr &req);

        // Checkpointing
        virtual void serialize(std::ostream &os);
        virtual void unserialize(Checkpoint *cp, const std::string &section);

        // Most recently used page table entries
        PTE *PTECache[3];
        inline void flushCache() { memset(PTECache, 0, 3 * sizeof(PTE*)); }
    };

    class ITB : public TLB
    {
      protected:
        mutable Stats::Scalar<> hits;
        mutable Stats::Scalar<> misses;
        mutable Stats::Scalar<> acv;
        mutable Stats::Formula accesses;

      public:
        ITB(const std::string &name, int size);
        virtual void regStats();

        Fault translate(RequestPtr &req, ThreadContext *tc) const;
    };

    class DTB : public TLB
    {
      protected:
        mutable Stats::Scalar<> read_hits;
        mutable Stats::Scalar<> read_misses;
        mutable Stats::Scalar<> read_acv;
        mutable Stats::Scalar<> read_accesses;
        mutable Stats::Scalar<> write_hits;
        mutable Stats::Scalar<> write_misses;
        mutable Stats::Scalar<> write_acv;
        mutable Stats::Scalar<> write_accesses;
        Stats::Formula hits;
        Stats::Formula misses;
        Stats::Formula acv;
        Stats::Formula accesses;

      public:
        DTB(const std::string &name, int size);
        virtual void regStats();

        Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const;
    };
}

#endif // __ALPHA_MEMORY_HH__
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2009 The Regents of The University of Michigan
 * Copyright (c) 2009 The University of Edinburgh
 * Copyright (c) 2014 Sven Karlsson
 * Copyright (c) 2016 RISC-V Foundation
 * Copyright (c) 2016 The University of Virginia
 * 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 the copyright holders 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.
 */

#ifndef __ARCH_RISCV_ISA_HH__
#define __ARCH_RISCV_ISA_HH__

#include <map>
#include <string>

#include "arch/generic/isa.hh"
#include "arch/riscv/registers.hh"
#include "arch/riscv/types.hh"
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "cpu/reg_class.hh"
#include "sim/sim_object.hh"

struct RiscvISAParams;
class ThreadContext;
class Checkpoint;
class EventManager;

namespace RiscvISA
{

enum PrivilegeMode {
    PRV_U = 0,
    PRV_S = 1,
    PRV_M = 3
};

class ISA : public BaseISA
{
  protected:
    std::vector<RegVal> miscRegFile;

    bool hpmCounterEnabled(int counter) const;

  public:
    typedef RiscvISAParams Params;

    void clear(ThreadContext *tc) { clear(); }

  protected:
    void clear();

  public:
    RegVal readMiscRegNoEffect(int misc_reg) const;
    RegVal readMiscReg(int misc_reg, ThreadContext *tc);
    void setMiscRegNoEffect(int misc_reg, RegVal val);
    void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);

    RegId flattenRegId(const RegId &regId) const { return regId; }
    int flattenIntIndex(int reg) const { return reg; }
    int flattenFloatIndex(int reg) const { return reg; }
    int flattenVecIndex(int reg) const { return reg; }
    int flattenVecElemIndex(int reg) const { return reg; }
    int flattenVecPredIndex(int reg) const { return reg; }
    int flattenCCIndex(int reg) const { return reg; }
    int flattenMiscIndex(int reg) const { return reg; }

    void startup(ThreadContext *tc) {}

    /// Explicitly import the otherwise hidden startup
    using BaseISA::startup;

    const Params *params() const;

    ISA(Params *p);
};

} // namespace RiscvISA

#endif // __ARCH_RISCV_ISA_HH__
<commit_msg>arch-riscv: fixed formatting.<commit_after>/*
 * Copyright (c) 2009 The Regents of The University of Michigan
 * Copyright (c) 2009 The University of Edinburgh
 * Copyright (c) 2014 Sven Karlsson
 * Copyright (c) 2016 RISC-V Foundation
 * Copyright (c) 2016 The University of Virginia
 * Copyright (c) 2020 Barkhausen Institut
 * 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 the copyright holders 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.
 */

#ifndef __ARCH_RISCV_ISA_HH__
#define __ARCH_RISCV_ISA_HH__

#include <map>
#include <string>

#include "arch/generic/isa.hh"
#include "arch/riscv/registers.hh"
#include "arch/riscv/types.hh"
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "cpu/reg_class.hh"
#include "sim/sim_object.hh"

struct RiscvISAParams;
class ThreadContext;
class Checkpoint;
class EventManager;

namespace RiscvISA
{

enum PrivilegeMode
{
    PRV_U = 0,
    PRV_S = 1,
    PRV_M = 3
};

class ISA : public BaseISA
{
  protected:
    std::vector<RegVal> miscRegFile;

    bool hpmCounterEnabled(int counter) const;

  public:
    typedef RiscvISAParams Params;

    void clear(ThreadContext *tc) { clear(); }

  protected:
    void clear();

  public:
    RegVal readMiscRegNoEffect(int misc_reg) const;
    RegVal readMiscReg(int misc_reg, ThreadContext *tc);
    void setMiscRegNoEffect(int misc_reg, RegVal val);
    void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);

    RegId flattenRegId(const RegId &regId) const { return regId; }
    int flattenIntIndex(int reg) const { return reg; }
    int flattenFloatIndex(int reg) const { return reg; }
    int flattenVecIndex(int reg) const { return reg; }
    int flattenVecElemIndex(int reg) const { return reg; }
    int flattenVecPredIndex(int reg) const { return reg; }
    int flattenCCIndex(int reg) const { return reg; }
    int flattenMiscIndex(int reg) const { return reg; }

    void startup(ThreadContext *tc) {}

    /// Explicitly import the otherwise hidden startup
    using BaseISA::startup;

    const Params *params() const;

    ISA(Params *p);
};

} // namespace RiscvISA

#endif // __ARCH_RISCV_ISA_HH__
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_CONFIG_ERROR_INCLUDED
#define MAPNIK_CONFIG_ERROR_INCLUDED

#include <iostream>
#include <sstream>

namespace mapnik {

    class config_error : public std::exception
    {
        public:
            config_error() {}

            config_error( const std::string & what ) :
                what_( what )
            {
            }
            virtual ~config_error() throw() {};

            virtual const char * what() const throw()
            {
                std::ostringstream os;
                os << what_;
                if ( ! context_.empty() )
                {
                    os << std::endl << context_;
                }
                os << ".";
                return os.str().c_str();
            }

            void append_context(const std::string & ctx) const
            {
                if ( ! context_.empty() )
                {
                    context_ += " ";
                }
                context_ += ctx;
            }

        protected:
            std::string what_;
            mutable std::string context_;
    };
}

#endif // MAPNIK_CONFIG_ERROR_INCLUDED
<commit_msg> - found and fixed another wild pointer<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_CONFIG_ERROR_INCLUDED
#define MAPNIK_CONFIG_ERROR_INCLUDED

#include <iostream>
#include <sstream>

namespace mapnik {

    class config_error : public std::exception
    {
        public:
            config_error() {}

            config_error( const std::string & what ) :
                what_( what )
            {
            }
            virtual ~config_error() throw() {};

            virtual const char * what() const throw()
            {
                return what_.c_str();
            }

            void append_context(const std::string & ctx) const
            {
                what_ += " " + ctx;
            }

        protected:
            mutable std::string what_;
    };
}

#endif // MAPNIK_CONFIG_ERROR_INCLUDED
<|endoftext|>