<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2016 LXQt team
 * Authors:
 *   Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "nosdtimedatectl.h"
#include <LXQt/Globals>
#include <QProcess>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusConnection>
#include <QMessageBox>

NOSDTimeDateCtl::NOSDTimeDateCtl()
{
}

NOSDTimeDateCtl::~NOSDTimeDateCtl()
{

}

QString NOSDTimeDateCtl::timeZone() const
{
    QFile tzFile(QSL("/etc/timezone"));
         if (!tzFile.open(QFile::ReadOnly | QFile::Text)) return QSL("Unknown");
         QTextStream in(&tzFile);
             QString lastTZone = in.readLine();
                 return lastTZone;
}

bool NOSDTimeDateCtl::setTimeZone(QString timeZone, QString& errorMessage)
{
    mHelperArgs << QSL("-t") << timeZone;
    return true;
}

bool NOSDTimeDateCtl::setDateTime(QDateTime dateTime, QString& errorMessage)
{
    qint64 epochsec = dateTime.toSecsSinceEpoch();
    mHelperArgs << QSL("-d") << QString::number(epochsec);
    mHelperArgs << QString::number(QDateTime::currentDateTime().toSecsSinceEpoch());
    return true;
}

bool NOSDTimeDateCtl::useNtp() const
{
    /*
    QProcess process;
    QStringList args = QStringList();
    args  << QSL("/etc/rc.d/ntpd") << QSL("rcvar");
    process.start(QSL("/bin/sh"),args);
    process.waitForFinished(-1);
    QString t = QString::fromLatin1(process.readAllStandardOutput());
    QStringList o = t.split(QSL("\n"));
    for (QStringList::iterator it = o.begin();
         it != o.end(); ++it) {
        QString current = *it;
        if(!current.startsWith(QSL("#")) && current.contains(QSL("ntpd_enable"),Qt::CaseInsensitive) && current.contains(QSL("yes"),Qt::CaseInsensitive)) {
            return true;
        }
    }
    */
    return false;
}

bool NOSDTimeDateCtl::setUseNtp(bool value, QString& errorMessage)
{
    /*
    mHelperArgs << QSL("-n") << (value ? QSL("true") : QSL("false"));
    */
    return false;
}

bool NOSDTimeDateCtl::localRtc() const
{
    QFile tzFile(QSL("/etc/sysconfig/clock"));
    if (!tzFile.open(QFile::ReadOnly | QFile::Text))
	return false;
    QTextStream in(&tzFile);
    QString all = in.readAll();
    QStringList sl = all.split(QSL("\n"));
    for (QStringList::iterator it = sl.begin(); it != sl.end(); it++) {
	QString current = *it;
	if(current.startsWith(QSL("#")))
	    continue;
	if(current.startsWith(QSL("UTC=1")) || current.startsWith(QSL("UTC=true")))
            return false;
	if(current.startsWith(QSL("UTC=0")) || current.startsWith(QSL("UTC=false")))
            return true;
    }
    return false;
}

bool NOSDTimeDateCtl::setLocalRtc(bool value, QString& errorMessage)
{
    mHelperArgs << QSL("-l") << (value ? QSL("true") : QSL("false"));
    return true;
}

bool NOSDTimeDateCtl::pkexec()
{
    if(mHelperArgs.isEmpty()) {
        return true;
    }
    QProcess process;
    QStringList args;
    args << QSL("--disable-internal-agent")
        << QSL("/usr/bin/lxqt-admin-time-helper")
        << mHelperArgs;
    process.start(QSL("pkexec"), args);
    process.waitForFinished(-1);
    QByteArray pkexec_error = process.readAllStandardError();
    //qDebug() << pkexec_error;
    const bool succeeded = process.exitCode() == 0;
    if (!succeeded)
    {
        QMessageBox * msg = new QMessageBox{QMessageBox::Critical, QObject::tr("lxqt-admin-time-helper")
            , QObject::tr("Action (%1) failed:

%2
").arg(args[0]).arg(QString::fromLatin1(pkexec_error))};
        msg->setAttribute(Qt::WA_DeleteOnClose, true);
        msg->show();
    }
    return succeeded;
}
<commit_msg>Silent compiler warnings about unused parameters<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2016 LXQt team
 * Authors:
 *   Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "nosdtimedatectl.h"
#include <LXQt/Globals>
#include <QProcess>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusConnection>
#include <QMessageBox>

NOSDTimeDateCtl::NOSDTimeDateCtl()
{
}

NOSDTimeDateCtl::~NOSDTimeDateCtl()
{

}

QString NOSDTimeDateCtl::timeZone() const
{
    QFile tzFile(QSL("/etc/timezone"));
         if (!tzFile.open(QFile::ReadOnly | QFile::Text)) return QSL("Unknown");
         QTextStream in(&tzFile);
             QString lastTZone = in.readLine();
                 return lastTZone;
}

bool NOSDTimeDateCtl::setTimeZone(QString timeZone, QString& /*errorMessage*/)
{
    mHelperArgs << QSL("-t") << timeZone;
    return true;
}

bool NOSDTimeDateCtl::setDateTime(QDateTime dateTime, QString& /*errorMessage*/)
{
    qint64 epochsec = dateTime.toSecsSinceEpoch();
    mHelperArgs << QSL("-d") << QString::number(epochsec);
    mHelperArgs << QString::number(QDateTime::currentDateTime().toSecsSinceEpoch());
    return true;
}

bool NOSDTimeDateCtl::useNtp() const
{
    /*
    QProcess process;
    QStringList args = QStringList();
    args  << QSL("/etc/rc.d/ntpd") << QSL("rcvar");
    process.start(QSL("/bin/sh"),args);
    process.waitForFinished(-1);
    QString t = QString::fromLatin1(process.readAllStandardOutput());
    QStringList o = t.split(QSL("\n"));
    for (QStringList::iterator it = o.begin();
         it != o.end(); ++it) {
        QString current = *it;
        if(!current.startsWith(QSL("#")) && current.contains(QSL("ntpd_enable"),Qt::CaseInsensitive) && current.contains(QSL("yes"),Qt::CaseInsensitive)) {
            return true;
        }
    }
    */
    return false;
}

bool NOSDTimeDateCtl::setUseNtp(bool /*value*/, QString& /*errorMessage*/)
{
    /*
    mHelperArgs << QSL("-n") << (value ? QSL("true") : QSL("false"));
    */
    return false;
}

bool NOSDTimeDateCtl::localRtc() const
{
    QFile tzFile(QSL("/etc/sysconfig/clock"));
    if (!tzFile.open(QFile::ReadOnly | QFile::Text))
	return false;
    QTextStream in(&tzFile);
    QString all = in.readAll();
    QStringList sl = all.split(QSL("\n"));
    for (QStringList::iterator it = sl.begin(); it != sl.end(); it++) {
	QString current = *it;
	if(current.startsWith(QSL("#")))
	    continue;
	if(current.startsWith(QSL("UTC=1")) || current.startsWith(QSL("UTC=true")))
            return false;
	if(current.startsWith(QSL("UTC=0")) || current.startsWith(QSL("UTC=false")))
            return true;
    }
    return false;
}

bool NOSDTimeDateCtl::setLocalRtc(bool value, QString& /*errorMessage*/)
{
    mHelperArgs << QSL("-l") << (value ? QSL("true") : QSL("false"));
    return true;
}

bool NOSDTimeDateCtl::pkexec()
{
    if(mHelperArgs.isEmpty()) {
        return true;
    }
    QProcess process;
    QStringList args;
    args << QSL("--disable-internal-agent")
        << QSL("/usr/bin/lxqt-admin-time-helper")
        << mHelperArgs;
    process.start(QSL("pkexec"), args);
    process.waitForFinished(-1);
    QByteArray pkexec_error = process.readAllStandardError();
    //qDebug() << pkexec_error;
    const bool succeeded = process.exitCode() == 0;
    if (!succeeded)
    {
        QMessageBox * msg = new QMessageBox{QMessageBox::Critical, QObject::tr("lxqt-admin-time-helper")
            , QObject::tr("Action (%1) failed:

%2
").arg(args[0]).arg(QString::fromLatin1(pkexec_error))};
        msg->setAttribute(Qt::WA_DeleteOnClose, true);
        msg->show();
    }
    return succeeded;
}
<|endoftext|>


<commit_before>#pragma warning(disable : 4786)

#include "..\\memcheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <iostream>
#include <functional>
#include <vector>
#include <list>
#include <map>
#include <math.h>
#include <sstream>

#include "rdosimwin.h"
#include "rdokernel.h"
#include "rdorepository.h"

#include "rdoparser.h"
#include "rdoruntime.h"
#include "rdosmr.h"
#include "rdofrm.h"

namespace RDOSimulatorNS
{

class RDORuntimeTracer: public RDOTrace, public RDOEndL
{
	LPVOID pParam;
  	TracerCallBack tracerCallBack;
	stringstream stream;
public:
   ostream &getOStream() { return stream; }
   RDOEndL& getEOL() { return *this; }
	void onEndl()
	{
		tracerCallBack(&stream.str(), pParam);
		stream.str("");
	}
	RDORuntimeTracer(TracerCallBack _tracerCallBack, LPVOID _pParam):
		tracerCallBack(_tracerCallBack), pParam(_pParam) { isNullTracer = false; }
};

const vector<RDOFrame *>& RdoSimulator::getFrames()
{
	return frames;
}

void RdoSimulator::addKeyPressed(int scanCode)
{
	scanCodes.push_back(scanCode);
}

void RdoSimulator::addAreaPressed(string& areaName)
{
	areasActivated.push_back(areaName);
}

void frameCallBack(rdoRuntime::RDOConfig *config, void *param)
{
	RdoSimulator *simulator = (RdoSimulator *)param;
	if((config->showAnimation == SM_Animation) && (config->showAnimation == SM_Animation))
	{
		Sleep(config->realTimeDelay);

		simulator->frames = config->frames;

		kernel.notify(RDOKernel::showFrame);

		config->keysPressed.insert(config->keysPressed.end(), simulator->scanCodes.begin(), simulator->scanCodes.end());
		simulator->scanCodes.clear();

		config->activeAreasMouseClicked.insert(config->activeAreasMouseClicked.end(), simulator->areasActivated.begin(), simulator->areasActivated.end());
		simulator->areasActivated.clear();

		for(int i = 0; i < config->frames.size(); i++)
			delete config->frames.at(i);
		config->frames.clear();
	}
	else
	{
		simulator->frames.clear();
		kernel.notify(RDOKernel::showFrame);
	}

	config->showRate = simulator->getShowRate();
	config->showAnimation = simulator->getShowMode();
}

void tracerCallBack(string *newString, void *param)
{
	RdoSimulator *simulator = (RdoSimulator *)param;
//	kernel.notifyString(RDOKernel.traceString, newString->c_str());
	int pos = 0;
	for(;;)
	{
		int next = newString->find('\n', pos);
		string str = newString->substr(pos, next-pos);
		kernel.notifyString(RDOKernel.traceString, str.c_str());
		if(next == string::npos)
			break;
		pos = next + 1;
		if(pos >= newString->length())
			break;

		int aa = 0;
	}
}

RdoSimulator::RdoSimulator():
	runtime(NULL),
	parser(NULL),
	th(NULL)
{}

RdoSimulator::~RdoSimulator()
{
	terminateModel();
	closeModel();
}

class RDOSimResulter: public RDOResult
{
	ostream &stream;
public:
	RDOSimResulter(ostream &_stream): stream(_stream) {isNullResult = false;}
   virtual std::ostream &getOStream() { return stream; }
};

UINT RunningThreadControllingFunction( LPVOID pParam )
{
	RdoSimulator *simulator = (RdoSimulator *)pParam;

	RDOTrace *tracer;
	rdoRuntime::RDOResult *resulter;

/////////////////   Creating tracer and resulter //////////////////////////////////
		if(simulator->parser->smr->traceFileName == NULL)
			tracer = new RDOTrace();
		else
			tracer = new RDORuntimeTracer(tracerCallBack, pParam);
//			tracer = new RDOTrace(*simulator->parser->smr->traceFileName + ".trc");
//			tracer = new RDOTrace("trace.trc");

		resulter;
		if(simulator->parser->smr->resultsFileName == NULL)
			resulter = new rdoRuntime::RDOResult();
		else
//			resulter = new rdoRuntime::RDOResult((*simulator->parser->smr->resultsFileName + ".pmv").c_str());
			resulter = new RDOSimResulter(simulator->resultString);

/////////  RDO config initialization ////////////////////////
		simulator->runtime->config.showAnimation = simulator->parser->smr->showMode;
		int size = simulator->runtime->allFrames.size();
		for(int i = 0; i < size; i++)
			simulator->runtime->config.allFrameNames.push_back(*simulator->runtime->allFrames.at(i)->getName());

		simulator->runtime->config.currFrameToShow = simulator->parser->smr->frameNumber - 1;
		simulator->runtime->config.keysPressed.clear();
		simulator->runtime->config.mouseClicked = false;
		simulator->runtime->config.activeAreasMouseClicked.clear();
		simulator->runtime->config.frames.clear();
		simulator->runtime->config.currTime = 0;
		simulator->runtime->config.newTime = 0;
		if(simulator->parser->smr->showRate)
			simulator->runtime->config.showRate = *simulator->parser->smr->showRate;
		else
			simulator->runtime->config.showRate = 60;	// default
		simulator->runtime->config.realTimeDelay = 0;

////////////////////////////////////////////////////////////////
/////////////////   Modelling	//////////////////////////////////
////////////////////////////////////////////////////////////////

	simulator->runtime->tracerCallBack = tracerCallBack;
	simulator->runtime->param = pParam;
	simulator->runtime->frameCallBack = frameCallBack;

	try
	{
		simulator->runtime->rdoInit(tracer, resulter);
		simulator->runtime->rdoRun();
		simulator->runtime->rdoDestroy();
		kernel.notify(RDOKernel::endExecuteModel);
		kernel.debug("End executing\n");
	}
	catch(RDOSyntaxException &)
	{
		kernel.notify(RDOKernel::executeError);
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.debug(mess.c_str());
		kernel.notify(RDOKernel::executeError);
	}

	simulator->th = NULL;

	return 0;
}

bool RdoSimulator::parseModel()
{
//	kernel.notifyString(RDOKernel::buildString, "Start parsing\n");
	terminateModel();
	closeModel();

	parser = new rdoParse::RDOParser();
	runtime = parser->runTime;

	ostringstream consol;

	try {
/////////////////   SMR file //////////////////////////////////
		stringstream SMRstream;
		kernel.getRepository()->loadSMR(SMRstream);
		if(SMRstream.good())
			parser->parseSMR1(&SMRstream, &consol);

/////////////////   RTP file //////////////////////////////////
		stringstream RTPstream1;
		kernel.getRepository()->loadRTP(RTPstream1);
		if(RTPstream1.good())
			parser->parseRTP(&RTPstream1, &consol);

/////////////////   RSS file //////////////////////////////////
		stringstream RSSstream;
		kernel.getRepository()->loadRSS(RSSstream);
		if(RSSstream.good())
			parser->parseRSS(&RSSstream, &consol);

/////////////////   FUN file //////////////////////////////////
		stringstream FUNstream;
		kernel.getRepository()->loadFUN(FUNstream);
		if(FUNstream.good())
			parser->parseFUN(&FUNstream, &consol);

/////////////////   PAT file //////////////////////////////////
		stringstream PATstream;
		kernel.getRepository()->loadPAT(PATstream);
		if(PATstream.good())
			parser->parsePAT(&PATstream, &consol);

/////////////////   OPR file //////////////////////////////////
		stringstream OPRstream;
		kernel.getRepository()->loadOPR(OPRstream);
		if(OPRstream.good())
			parser->parseOPR(&OPRstream, &consol);

/////////////////   DPT file //////////////////////////////////
		stringstream DPTstream;
		kernel.getRepository()->loadDPT(DPTstream);
		if(DPTstream.good())
			parser->parseDPT(&DPTstream, &consol);

/////////////////   PMD file //////////////////////////////////
		stringstream PMDstream;
		kernel.getRepository()->loadPMD(PMDstream);
		if(PMDstream.good())
			parser->parsePMD(&PMDstream, &consol);

/////////////////   FRM file //////////////////////////////////
		stringstream FRMstream;
		kernel.getRepository()->loadFRM(FRMstream);
		if(FRMstream.good())
			parser->parseFRM(&FRMstream, &consol);

/////////////////   SMR file //////////////////////////////////
		stringstream SMRstream2;
		kernel.getRepository()->loadSMR(SMRstream2);
		if(SMRstream2.good())
			parser->parseSMR2(&SMRstream2, &consol);
	}
	catch(RDOSyntaxException &)
	{
//		string mess = ex.getType() + " : " + ex.mess;
//		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseError);
		closeModel();
		return false;
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseError);
		closeModel();
		return false;
	}

	showMode = getInitialShowMode();
	showRate = getInitialShowRate();

/*
	if(parser->errors.size() > 0)
	{
		for(int i = 0; i < parser->errors.size(); i++)
		{
			kernel.notifyString(RDOKernel::buildString, parser->errors.at(i).message);
		}

		return false;
	}
*/

	kernel.notify(RDOKernel::parseSuccess);
//	kernel.notifyString(RDOKernel::buildString, "End parsing\n");

//	kernel.notifyString(RDOKernel::buildString, getModelStructure().str().c_str());

	return true;
}

void RdoSimulator::runModel()
{
	bool res = parseModel();
	if(res)
	{
		kernel.notify(RDOKernel::beforeModelStart);
		kernel.debug("Start executing\n");
		th = AfxBeginThread(RunningThreadControllingFunction, (LPVOID)this);
		kernel.notify(RDOKernel::afterModelStart);
	}
}

void RdoSimulator::stopModel()
{
	terminateModel();
	kernel.notify(RDOKernel::modelStopped);
}

void RdoSimulator::terminateModel()
{
	if(th != NULL)
	{
		TerminateThread(th->m_hThread, -1);
		delete th;
		th = NULL;
	}
}

void RdoSimulator::closeModel()
{
	if(runtime)
		delete runtime;
	runtime = NULL;

	if(parser)
		delete parser;
	parser = NULL;
}

void RdoSimulator::parseSMRFileInfo( stringstream& smr, rdoModelObjects::RDOSMRFileInfo& info )
{
	terminateModel();
	closeModel();

	parser = new rdoParse::RDOParser();
	runtime = parser->runTime;

	stringstream consol;

	try {
		parser->parseSMR1(&smr, &consol);
	}
	catch(RDOSyntaxException &)
	{
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}

	if(!parser->smr)
	{
		kernel.notifyString(RDOKernel::buildString, "SMR File seems to be empty\n");
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}

//	kernel.notifyString(RDOKernel::buildString, "SMR File read successfully\n");

	if(parser->smr->modelName)
		info.model_name = *parser->smr->modelName;

	if(parser->smr->resourceFileName)
		info.resource_file = *parser->smr->resourceFileName;

	if(parser->smr->oprIevFileName)
		info.oprIev_file = *parser->smr->oprIevFileName;

	if(parser->smr->frameFileName)
		info.frame_file = *parser->smr->frameFileName;

	if(parser->smr->statisticFileName)
		info.statistic_file = *parser->smr->statisticFileName;

	if(parser->smr->resultsFileName)
		info.results_file = *parser->smr->resultsFileName;

	if(parser->smr->traceFileName)
		info.trace_file = *parser->smr->traceFileName;

	closeModel();
}

vector<RDOSyntaxError>* RdoSimulator::getErrors()
{
	vector<RDOSyntaxError>* res = NULL;

	if(!parser)
		return NULL;

	res = &parser->errors;
	if(res->size() > 0)
		return res;

	res = &runtime->errors;
	return res;
}

double RdoSimulator::getModelTime()
{
	if(runtime)
		return runtime->getTimeNow();
	else
		return 0.;
}

vector<const string *> RdoSimulator::getAllFrames()
{
	vector<const string *> vect;
	if(!runtime)
		return vect;

	int size = runtime->allFrames.size();
	for(int i = 0; i < size; i++)
	{
		RDOFRMFrame *frame = runtime->allFrames.at(i);
		vect.push_back(frame->getName());
	}

	return vect;
}

vector<const string *> RdoSimulator::getAllBitmaps()
{
	vector<const string *> vect;
	if(!runtime)
		return vect;

	int size = runtime->allFrames.size();
	for(int i = 0; i < size; i++)
	{
		RDOFRMFrame *frame = runtime->allFrames.at(i);
		frame->getAllBitmaps(vect);
	}

	return vect;
}

ShowMode RdoSimulator::getInitialShowMode()
{
	return parser->smr->showMode;
}

int RdoSimulator::getInitialFrameNumber()
{
	return parser->smr->frameNumber;
}

double RdoSimulator::getInitialShowRate()
{
	return *parser->smr->showRate;
}

stringstream &RdoSimulator::getModelStructure()
{
	return parser->modelStructure;
}

stringstream &RdoSimulator::getResults()
{
	return resultString;
}

}// namespace RDOSimulatorNS
<commit_msg>memory leak<commit_after>#pragma warning(disable : 4786)

#include "..\\memcheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <iostream>
#include <functional>
#include <vector>
#include <list>
#include <map>
#include <math.h>
#include <sstream>

#include "rdosimwin.h"
#include "rdokernel.h"
#include "rdorepository.h"

#include "rdoparser.h"
#include "rdoruntime.h"
#include "rdosmr.h"
#include "rdofrm.h"

namespace RDOSimulatorNS
{

class RDORuntimeTracer: public RDOTrace, public RDOEndL
{
	LPVOID pParam;
  	TracerCallBack tracerCallBack;
	stringstream stream;
public:
   ostream &getOStream() { return stream; }
   RDOEndL& getEOL() { return *this; }
	void onEndl()
	{
		tracerCallBack(&stream.str(), pParam);
		stream.str("");
	}
	RDORuntimeTracer(TracerCallBack _tracerCallBack, LPVOID _pParam):
		tracerCallBack(_tracerCallBack), pParam(_pParam) { isNullTracer = false; }
};

const vector<RDOFrame *>& RdoSimulator::getFrames()
{
	return frames;
}

void RdoSimulator::addKeyPressed(int scanCode)
{
	scanCodes.push_back(scanCode);
}

void RdoSimulator::addAreaPressed(string& areaName)
{
	areasActivated.push_back(areaName);
}

void frameCallBack(rdoRuntime::RDOConfig *config, void *param)
{
	RdoSimulator *simulator = (RdoSimulator *)param;
	if((config->showAnimation == SM_Animation) && (config->showAnimation == SM_Animation))
	{
		Sleep(config->realTimeDelay);

		simulator->frames = config->frames;

		kernel.notify(RDOKernel::showFrame);

		config->keysPressed.insert(config->keysPressed.end(), simulator->scanCodes.begin(), simulator->scanCodes.end());
		simulator->scanCodes.clear();

		config->activeAreasMouseClicked.insert(config->activeAreasMouseClicked.end(), simulator->areasActivated.begin(), simulator->areasActivated.end());
		simulator->areasActivated.clear();

		for(int i = 0; i < config->frames.size(); i++)
			delete config->frames.at(i);
		config->frames.clear();
	}
	else
	{
		simulator->frames.clear();
		kernel.notify(RDOKernel::showFrame);
	}

	config->showRate = simulator->getShowRate();
	config->showAnimation = simulator->getShowMode();
}

void tracerCallBack(string *newString, void *param)
{
	RdoSimulator *simulator = (RdoSimulator *)param;
//	kernel.notifyString(RDOKernel.traceString, newString->c_str());
	int pos = 0;
	for(;;)
	{
		int next = newString->find('\n', pos);
		string str = newString->substr(pos, next-pos);
		kernel.notifyString(RDOKernel.traceString, str.c_str());
		if(next == string::npos)
			break;
		pos = next + 1;
		if(pos >= newString->length())
			break;

		int aa = 0;
	}
}

RdoSimulator::RdoSimulator():
	runtime(NULL),
	parser(NULL),
	th(NULL)
{}

RdoSimulator::~RdoSimulator()
{
	terminateModel();
	closeModel();
}

class RDOSimResulter: public RDOResult
{
	ostream &stream;
public:
	RDOSimResulter(ostream &_stream): stream(_stream) {isNullResult = false;}
   virtual std::ostream &getOStream() { return stream; }
};

UINT RunningThreadControllingFunction( LPVOID pParam )
{
	RdoSimulator *simulator = (RdoSimulator *)pParam;

	RDOTrace *tracer;
	rdoRuntime::RDOResult *resulter;

/////////////////   Creating tracer and resulter //////////////////////////////////
		if(simulator->parser->smr->traceFileName == NULL)
			tracer = new RDOTrace();
		else
			tracer = new RDORuntimeTracer(tracerCallBack, pParam);
//			tracer = new RDOTrace(*simulator->parser->smr->traceFileName + ".trc");
//			tracer = new RDOTrace("trace.trc");

		resulter;
		if(simulator->parser->smr->resultsFileName == NULL)
			resulter = new rdoRuntime::RDOResult();
		else
//			resulter = new rdoRuntime::RDOResult((*simulator->parser->smr->resultsFileName + ".pmv").c_str());
			resulter = new RDOSimResulter(simulator->resultString);

/////////  RDO config initialization ////////////////////////
		simulator->runtime->config.showAnimation = simulator->parser->smr->showMode;
		int size = simulator->runtime->allFrames.size();
		for(int i = 0; i < size; i++)
			simulator->runtime->config.allFrameNames.push_back(*simulator->runtime->allFrames.at(i)->getName());

		simulator->runtime->config.currFrameToShow = simulator->parser->smr->frameNumber - 1;
		simulator->runtime->config.keysPressed.clear();
		simulator->runtime->config.mouseClicked = false;
		simulator->runtime->config.activeAreasMouseClicked.clear();
		simulator->runtime->config.frames.clear();
		simulator->runtime->config.currTime = 0;
		simulator->runtime->config.newTime = 0;
		if(simulator->parser->smr->showRate)
			simulator->runtime->config.showRate = *simulator->parser->smr->showRate;
		else
			simulator->runtime->config.showRate = 60;	// default
		simulator->runtime->config.realTimeDelay = 0;

////////////////////////////////////////////////////////////////
/////////////////   Modelling	//////////////////////////////////
////////////////////////////////////////////////////////////////

	simulator->runtime->tracerCallBack = tracerCallBack;
	simulator->runtime->param = pParam;
	simulator->runtime->frameCallBack = frameCallBack;

	try
	{
		simulator->runtime->rdoInit(tracer, resulter);
		simulator->runtime->rdoRun();
		simulator->runtime->rdoDestroy();
		kernel.notify(RDOKernel::endExecuteModel);
		kernel.debug("End executing\n");
	}
	catch(RDOSyntaxException &)
	{
		kernel.notify(RDOKernel::executeError);
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.debug(mess.c_str());
		kernel.notify(RDOKernel::executeError);
	}

	try
	{
		simulator->runtime->rdoDestroy();
	}
	catch(RDOSyntaxException &)
	{
		kernel.notify(RDOKernel::executeError);
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.debug(mess.c_str());
		kernel.notify(RDOKernel::executeError);
	}

	simulator->th = NULL;

	return 0;
}

bool RdoSimulator::parseModel()
{
//	kernel.notifyString(RDOKernel::buildString, "Start parsing\n");
	terminateModel();
	closeModel();

	parser = new rdoParse::RDOParser();
	runtime = parser->runTime;

	ostringstream consol;

	try {
/////////////////   SMR file //////////////////////////////////
		stringstream SMRstream;
		kernel.getRepository()->loadSMR(SMRstream);
		if(SMRstream.good())
			parser->parseSMR1(&SMRstream, &consol);

/////////////////   RTP file //////////////////////////////////
		stringstream RTPstream1;
		kernel.getRepository()->loadRTP(RTPstream1);
		if(RTPstream1.good())
			parser->parseRTP(&RTPstream1, &consol);

/////////////////   RSS file //////////////////////////////////
		stringstream RSSstream;
		kernel.getRepository()->loadRSS(RSSstream);
		if(RSSstream.good())
			parser->parseRSS(&RSSstream, &consol);

/////////////////   FUN file //////////////////////////////////
		stringstream FUNstream;
		kernel.getRepository()->loadFUN(FUNstream);
		if(FUNstream.good())
			parser->parseFUN(&FUNstream, &consol);

/////////////////   PAT file //////////////////////////////////
		stringstream PATstream;
		kernel.getRepository()->loadPAT(PATstream);
		if(PATstream.good())
			parser->parsePAT(&PATstream, &consol);

/////////////////   OPR file //////////////////////////////////
		stringstream OPRstream;
		kernel.getRepository()->loadOPR(OPRstream);
		if(OPRstream.good())
			parser->parseOPR(&OPRstream, &consol);

/////////////////   DPT file //////////////////////////////////
		stringstream DPTstream;
		kernel.getRepository()->loadDPT(DPTstream);
		if(DPTstream.good())
			parser->parseDPT(&DPTstream, &consol);

/////////////////   PMD file //////////////////////////////////
		stringstream PMDstream;
		kernel.getRepository()->loadPMD(PMDstream);
		if(PMDstream.good())
			parser->parsePMD(&PMDstream, &consol);

/////////////////   FRM file //////////////////////////////////
		stringstream FRMstream;
		kernel.getRepository()->loadFRM(FRMstream);
		if(FRMstream.good())
			parser->parseFRM(&FRMstream, &consol);

/////////////////   SMR file //////////////////////////////////
		stringstream SMRstream2;
		kernel.getRepository()->loadSMR(SMRstream2);
		if(SMRstream2.good())
			parser->parseSMR2(&SMRstream2, &consol);
	}
	catch(RDOSyntaxException &)
	{
//		string mess = ex.getType() + " : " + ex.mess;
//		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseError);
		closeModel();
		return false;
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseError);
		closeModel();
		return false;
	}

	showMode = getInitialShowMode();
	showRate = getInitialShowRate();

/*
	if(parser->errors.size() > 0)
	{
		for(int i = 0; i < parser->errors.size(); i++)
		{
			kernel.notifyString(RDOKernel::buildString, parser->errors.at(i).message);
		}

		return false;
	}
*/

	kernel.notify(RDOKernel::parseSuccess);
//	kernel.notifyString(RDOKernel::buildString, "End parsing\n");

//	kernel.notifyString(RDOKernel::buildString, getModelStructure().str().c_str());

	return true;
}

void RdoSimulator::runModel()
{
	bool res = parseModel();
	if(res)
	{
		kernel.notify(RDOKernel::beforeModelStart);
		kernel.debug("Start executing\n");
		th = AfxBeginThread(RunningThreadControllingFunction, (LPVOID)this);
		kernel.notify(RDOKernel::afterModelStart);
	}
}

void RdoSimulator::stopModel()
{
	terminateModel();
	kernel.notify(RDOKernel::modelStopped);
}

void RdoSimulator::terminateModel()
{
	if(th != NULL)
	{
		TerminateThread(th->m_hThread, -1);
		delete th;
		th = NULL;
	}
}

void RdoSimulator::closeModel()
{
	if(runtime)
		delete runtime;
	runtime = NULL;

	if(parser)
		delete parser;
	parser = NULL;
}

void RdoSimulator::parseSMRFileInfo( stringstream& smr, rdoModelObjects::RDOSMRFileInfo& info )
{
	terminateModel();
	closeModel();

	parser = new rdoParse::RDOParser();
	runtime = parser->runTime;

	stringstream consol;

	try {
		parser->parseSMR1(&smr, &consol);
	}
	catch(RDOSyntaxException &)
	{
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}
	catch(RDOInternalException &ex)
	{
		string mess = "Internal exception: " + ex.mess;
		kernel.notifyString(RDOKernel::buildString, mess);
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}

	if(!parser->smr)
	{
		kernel.notifyString(RDOKernel::buildString, "SMR File seems to be empty\n");
		kernel.notify(RDOKernel::parseSMRError);
		closeModel();
		return;
	}

//	kernel.notifyString(RDOKernel::buildString, "SMR File read successfully\n");

	if(parser->smr->modelName)
		info.model_name = *parser->smr->modelName;

	if(parser->smr->resourceFileName)
		info.resource_file = *parser->smr->resourceFileName;

	if(parser->smr->oprIevFileName)
		info.oprIev_file = *parser->smr->oprIevFileName;

	if(parser->smr->frameFileName)
		info.frame_file = *parser->smr->frameFileName;

	if(parser->smr->statisticFileName)
		info.statistic_file = *parser->smr->statisticFileName;

	if(parser->smr->resultsFileName)
		info.results_file = *parser->smr->resultsFileName;

	if(parser->smr->traceFileName)
		info.trace_file = *parser->smr->traceFileName;

	closeModel();
}

vector<RDOSyntaxError>* RdoSimulator::getErrors()
{
	vector<RDOSyntaxError>* res = NULL;

	if(!parser)
		return NULL;

	res = &parser->errors;
	if(res->size() > 0)
		return res;

	res = &runtime->errors;
	return res;
}

double RdoSimulator::getModelTime()
{
	if(runtime)
		return runtime->getTimeNow();
	else
		return 0.;
}

vector<const string *> RdoSimulator::getAllFrames()
{
	vector<const string *> vect;
	if(!runtime)
		return vect;

	int size = runtime->allFrames.size();
	for(int i = 0; i < size; i++)
	{
		RDOFRMFrame *frame = runtime->allFrames.at(i);
		vect.push_back(frame->getName());
	}

	return vect;
}

vector<const string *> RdoSimulator::getAllBitmaps()
{
	vector<const string *> vect;
	if(!runtime)
		return vect;

	int size = runtime->allFrames.size();
	for(int i = 0; i < size; i++)
	{
		RDOFRMFrame *frame = runtime->allFrames.at(i);
		frame->getAllBitmaps(vect);
	}

	return vect;
}

ShowMode RdoSimulator::getInitialShowMode()
{
	return parser->smr->showMode;
}

int RdoSimulator::getInitialFrameNumber()
{
	return parser->smr->frameNumber;
}

double RdoSimulator::getInitialShowRate()
{
	return *parser->smr->showRate;
}

stringstream &RdoSimulator::getModelStructure()
{
	return parser->modelStructure;
}

stringstream &RdoSimulator::getResults()
{
	return resultString;
}

}// namespace RDOSimulatorNS
<|endoftext|>


<commit_before>// Conventions:
//  O is the stack pointer (post-decrement)
//  B is the (so far only) return register
//  C is the (so far only) argument register
//  N is the relative-jump temp register

#include "common.th"

#define bare_metal_init() \
    b <- a ; c <- a ; d <- a ; e <- a ; f <- a ; g <- a ; h <- a ; \
    i <- a ; j <- a ; k <- a ; l <- a ; m <- a ; n <- a ; o <- a ; \
    //

_start:
    bare_metal_init()   // TODO this shouldn't be necessary
    c <- 1              // argument
    o <- 1              // stack pointer
    o <- o << 14

    call(init_display)
    call(disable_cursor)

    j <- 0              // multiplier (0 -> 0x26)
    k <- 0              // multiplicand (0 -> 0x12)

    // write the top row first
loop_top:
    f <- 4              // field width
    e <- k * f + 3      // column is multiplicand * field width + header width
    d <- 0              // row is 0
    c <- k              // number to print is multiplicand
    call(putnum)
    k <- k + 1
    c <- k < 0x13
    jnzrel(c,loop_top)

    // outer loop is j (multiplier, corresponds to row)
loop_j:
    k <- 0
    // print row header
    f <- 2              // field width 2
    e <- 0              // column is 0
    d <- j + 1          // row (J + 1)
    c <- j
    call(putnum)

loop_k:
    f <- 4              // field width 3
    e <- k * f + 3      // E is column (0 - 79)
    d <- j + 1
    c <- j * k
    call(putnum)
    k <- k + 1
    c <- k < 0x13
    jnzrel(c,loop_k)

    c <- j << 8
    c <- c | k
    c -> [0x100]        // write {J,K} to LEDs
    c <- 0b0100         // decimal point between J and K
    c -> [0x101]

    j <- j + 1          // increment N
    c <- j < 0x27
    jnzrel(c,loop_j)
    illegal

    // putnum takes number in C, (row,col) in D,E, and field width in F
putnum:
    pushall(h,i,j,k,l,m)
    h <- 0x100
    h <- h << 8         // h is video base
    k <- d * 80
    k <- e + k          // k is offset into display
    k <- k + f          // start at right side of field
    i <- rel(hexes)     // i is base of hex transform

putnumloop:
    m <- h + k + 0x10   // m is k characters past start of text region
    j <- [c & 0xf + i]  // j is character for bottom 4 bits of c
    [m] <- j            // write character to display
    k <- k - 1          // go to the left one character
    c <- c >> 4         // shift down for next iteration
    l <- c == 0         // shall we loop ?
    jzrel(l,putnumloop)

putnumdone:
    popall(h,i,j,k,l,m)
    ret

init_display:
    pushall(h,k,l,m);
    h <- 0x100
    h <- h << 8         // h is video base
    k <- 0              // k is offset into text region

init_display_loop:
    m <- h + k + 0x10   // m is k characters past start of text region
    [m] <- ' '          // write space to display
    k <- k + 1          // go to the right one character
    l <- k > 0x20       // shall we loop ?
    jzrel(l,init_display_loop)

init_display_done:
    popall(h,k,l,m);
    ret

disable_cursor:
    pushall(g,h)
    h <- 0x100
    g <- [h << 8]
    g <- g &~ (1 << 6)  // unset cursor-enable bit
    g -> [h << 8]
    popall(g,h)
    ret

hexes:
    .word '0', '1', '2', '3', '4', '5', '6', '7'
    .word '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'

<commit_msg>Reduce static and dynamic instruction count<commit_after>// Conventions:
//  O is the stack pointer (post-decrement)
//  B is the (so far only) return register
//  C is the (so far only) argument register
//  N is the relative-jump temp register

#include "common.th"

#define bare_metal_init() \
    b <- a ; c <- a ; d <- a ; e <- a ; f <- a ; g <- a ; h <- a ; \
    i <- a ; j <- a ; k <- a ; l <- a ; m <- a ; n <- a ; o <- a ; \
    //

_start:
    bare_metal_init()   // TODO this shouldn't be necessary
    c <- 1              // argument
    o <- 1              // stack pointer
    o <- o << 14

    call(init_display)
    call(disable_cursor)

    j <- 0              // multiplier (0 -> 0x26)
    k <- 0              // multiplicand (0 -> 0x12)

    c <- 0b0100         // decimal point between J and K
    c -> [0x101]

    // write the top row first
loop_top:
    f <- 4              // field width
    e <- k * f + 3      // column is multiplicand * field width + header width
    d <- 0              // row is 0
    c <- k              // number to print is multiplicand
    call(putnum)
    k <- k + 1
    c <- k < 0x13
    jnzrel(c,loop_top)

    // outer loop is j (multiplier, corresponds to row)
loop_j:
    k <- 0
    // print row header
    f <- 2              // field width 2
    e <- 0              // column is 0
    d <- j + 1          // row (J + 1)
    c <- j
    call(putnum)

loop_k:
    f <- 4              // field width 3
    e <- k * f + 3      // E is column (0 - 79)
    d <- j + 1
    c <- j * k
    call(putnum)
    k <- k + 1
    c <- k < 0x13
    jnzrel(c,loop_k)

    c <- 0x100          // write {J,K} to LEDs
    [c] <- j << 8 + k

    j <- j + 1          // increment N
    c <- j < 0x27
    jnzrel(c,loop_j)
    illegal

    // putnum takes number in C, (row,col) in D,E, and field width in F
putnum:
    pushall(h,i,j,k,l,m)
    h <- 0x100
    h <- h << 8         // h is video base
    k <- d * 80 + e     // k is offset into display
    k <- k + f          // start at right side of field
    i <- rel(hexes)     // i is base of hex transform

putnumloop:
    m <- h + k + 0x10   // m is k characters past start of text region
    j <- [c & 0xf + i]  // j is character for bottom 4 bits of c
    [m] <- j            // write character to display
    k <- k - 1          // go to the left one character
    c <- c >> 4         // shift down for next iteration
    l <- c <> 0         // shall we loop ?
    jnzrel(l,putnumloop)

putnumdone:
    popall(h,i,j,k,l,m)
    ret

init_display:
    pushall(h,k,l,m);
    h <- 0x100
    h <- h << 8         // h is video base
    k <- 0              // k is offset into text region

init_display_loop:
    m <- h + k + 0x10   // m is k characters past start of text region
    [m] <- ' '          // write space to display
    k <- k + 1          // go to the right one character
    l <- k < 0x21       // shall we loop ?
    jnzrel(l,init_display_loop)

init_display_done:
    popall(h,k,l,m);
    ret

disable_cursor:
    pushall(g,h)
    h <- 0x100
    h <- h << 8
    g <- [h]
    [h] <- g &~ (1 << 6)  // unset cursor-enable bit
    popall(g,h)
    ret

hexes:
    .word '0', '1', '2', '3', '4', '5', '6', '7'
    .word '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'

<|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SceneView
// example that provides the user with control over view position with support for
// enabling the osgDB::DatabasePager as required by the PagedLOD and TXP databases.

#include <Producer/RenderSurface>
#include <Producer/KeyboardMouse>
#include <Producer/Trackball>

#include <osg/Timer>

#include <osgUtil/SceneView>
#include <osgUtil/IntersectVisitor>

#include <osgDB/ReadFile>

#include <osgFX/Scribe>

class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
public:

    MyKeyboardMouseCallback(osgUtil::SceneView* sceneView) :
        Producer::KeyboardMouseCallback(),
        _mx(0.0f),_my(0.0f),_mbutton(0),
        _done(false),
        _trackBall(new Producer::Trackball),
        _sceneView(sceneView)
    {
        resetTrackball();
    }

    virtual void specialKeyPress( Producer::KeyCharacter key )
    {
        if (key==Producer::KeyChar_Escape)
            shutdown();
    }

    virtual void shutdown()
    {
        _done = true;
    }

    virtual void keyPress( Producer::KeyCharacter key)
    {
        if (key==' ') resetTrackball();
    }

    virtual void mouseMotion( float mx, float my )
    {
        _mx = mx;
        _my = my;
    }

    virtual void buttonPress( float mx, float my, unsigned int mbutton )
    {
         _mx = mx;
         _my = my;
         _mbutton |= (1<<(mbutton-1));

         _mx_buttonPress = _mx;
         _my_buttonPress = _my;
    }
    virtual void buttonRelease( float mx, float my, unsigned int mbutton )
    {
        _mx = mx;
        _my = my;
        _mbutton &= ~(1<<(mbutton-1));
    }

    bool done() { return _done; }
    float mx()  { return _mx; }
    float my()  { return _my; }
    unsigned int mbutton()  { return _mbutton; }

    void resetTrackball()
    {
        osg::Node* scene = _sceneView->getSceneData();
        if (scene)
        {
            const osg::BoundingSphere& bs = scene->getBound();
            _trackBall->reset();
            _trackBall->setOrientation( Producer::Trackball::Z_UP );
            _trackBall->setDistance(bs.radius()*2.0f);
            _trackBall->translate(-bs.center().x(),-bs.center().y(),-bs.center().z());
        }
    }

    osg::Matrixd getViewMatrix()
    {
	_trackBall->input( mx(), my(), mbutton() );
        return osg::Matrixd(_trackBall->getMatrix().ptr());
    }

private:

    float                               _mx, _my;
    float                               _mx_buttonPress, _my_buttonPress;
    unsigned int                        _mbutton;

    bool                                _done;

    osg::ref_ptr<Producer::Trackball>   _trackBall;
    osg::ref_ptr<osgUtil::SceneView>    _sceneView;
};

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // When numTimesToRun>1 allow the user to test opening and closing graphics contexts whilst
    // still keep scene graph around.
    unsigned int numTimesToRun = 1;
    if (argc>2)
    {
        numTimesToRun = atoi(argv[2]);
    }

    // create the view of the scene.
    osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
    sceneView->setDefaults();
    sceneView->setSceneData(loadedModel.get());
    sceneView->setLightingMode(osgUtil::SceneView::SKY_LIGHT);

    // do the set up of the DatabasePager...
    // create the database pager via the osgDB::Registry
    osgDB::DatabasePager* databasePager = osgDB::Registry::instance()->getOrCreateDatabasePager();

    // set wether the DatabasePager thread should be blocked while the scene graph is being used to render a frame
    // setting frame block to true can help achieve constant frame rates on single CPU systems.
    databasePager->setUseFrameBlock(false);

    // set whether to pre compile GL objects before merging new subgraphs with main scene graph
    // databasePager->setCompileGLObjectsForContextID(sceneView->getState()->getContextID(),true);

    // register any PagedLOD that need to be tracked in the scene graph
    databasePager->registerPagedLODs(sceneView->getSceneData());

    // need to register the DatabasePager with the SceneView's CullVisitor so it can pass on request
    // for files to be loaded.
    sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager);

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    // set the frame number count.  Note, this is outside the window loop, so that
    // frame numbers increment even a graphics context is closed down and another opened
    // this is to ensure the record of the frame numbers in the scene graph are kept valid.
    unsigned int frameNum = 0;

    if (numTimesToRun>1)
    {
        // make sure the database pager doesn't unref images as otherwise they won't be around the next time
        // they are needed when the a new graphics context comes up.
        databasePager->setUnrefImageDataAfterApplyPolicy(true,false);
    }

    for(unsigned int i=0;i<numTimesToRun;++i)
    {
        // create the window to draw to.
        osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
        renderSurface->setWindowName("osgsimplepager");
        renderSurface->setWindowRectangle(100,100,800,600);
        renderSurface->useBorder(true);
        renderSurface->realize();

        // set up a KeyboardMouse to manage the events comming in from the RenderSurface
        osg::ref_ptr<Producer::KeyboardMouse>  kbm = new Producer::KeyboardMouse(renderSurface.get());

        // create a KeyboardMouseCallback to handle the mouse events within this applications
        osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(sceneView.get());

        // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
        while( renderSurface->isRealized() && !kbmcb->done())
        {

            // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
            osg::FrameStamp* frameStamp = new osg::FrameStamp;
            frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
            frameStamp->setFrameNumber(frameNum++);

            // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp
            sceneView->setFrameStamp(frameStamp);

            // pass any keyboard mouse events onto the local keyboard mouse callback.
            kbm->update( *kbmcb );

            // set the view
            sceneView->setViewMatrix(kbmcb->getViewMatrix());

            // update the viewport dimensions, incase the window has been resized.
            sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight());

            // tell the DatabasePager the frame number of that the scene graph is being actively used to render a frame
            databasePager->signalBeginFrame(frameStamp);

            // syncronize changes required by the DatabasePager thread to the scene graph
            databasePager->updateSceneGraph(frameStamp->getReferenceTime());

            // do the update traversal the scene graph - such as updating animations
            sceneView->update();

            // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins
            sceneView->cull();

            // draw the rendering bins.
            sceneView->draw();

            // tell the DatabasePager that the frame is complete and that scene graph is no longer be activity traversed.
            databasePager->signalEndFrame();

            // Swap Buffers
            renderSurface->swapBuffers();

            // clean up  and compile gl objects with a specified limit
            double availableTime = 0.0025; // 2.5 ms

            // compile any GL objects that are required.
            databasePager->compileGLObjects(*(sceneView->getState()),availableTime);

            // flush deleted GL objects.
            sceneView->flushDeletedGLObjects(availableTime);

        }

        // clear the database pager so its starts a fresh on the next update/cull/draw traversals
        databasePager->clear();

        // release the GL objects stored in the scene graph.
        sceneView->releaseAllGLObjects();

        // do a flush to delete all the OpenGL objects that have been deleted or released from the scene graph.
        sceneView->flushAllDeletedGLObjects();

        // reset the osg::State so that next time its used its in a cleaned state.
        sceneView->getState()->reset();

    }

    // switch off the database pager by unreferencing it.
    osgDB::Registry::instance()->setDatabasePager(0);

    return 0;
}

<commit_msg>Moved the SceneView to local to the contruction/destruction of the RenderSurface<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SceneView
// example that provides the user with control over view position with support for
// enabling the osgDB::DatabasePager as required by the PagedLOD and TXP databases.

#include <Producer/RenderSurface>
#include <Producer/KeyboardMouse>
#include <Producer/Trackball>

#include <osg/Timer>

#include <osgUtil/SceneView>
#include <osgUtil/IntersectVisitor>

#include <osgDB/ReadFile>

#include <osgFX/Scribe>

class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
public:

    MyKeyboardMouseCallback(osgUtil::SceneView* sceneView) :
        Producer::KeyboardMouseCallback(),
        _mx(0.0f),_my(0.0f),_mbutton(0),
        _done(false),
        _trackBall(new Producer::Trackball),
        _sceneView(sceneView)
    {
        resetTrackball();
    }

    virtual void specialKeyPress( Producer::KeyCharacter key )
    {
        if (key==Producer::KeyChar_Escape)
            shutdown();
    }

    virtual void shutdown()
    {
        _done = true;
    }

    virtual void keyPress( Producer::KeyCharacter key)
    {
        if (key==' ') resetTrackball();
    }

    virtual void mouseMotion( float mx, float my )
    {
        _mx = mx;
        _my = my;
    }

    virtual void buttonPress( float mx, float my, unsigned int mbutton )
    {
         _mx = mx;
         _my = my;
         _mbutton |= (1<<(mbutton-1));

         _mx_buttonPress = _mx;
         _my_buttonPress = _my;
    }
    virtual void buttonRelease( float mx, float my, unsigned int mbutton )
    {
        _mx = mx;
        _my = my;
        _mbutton &= ~(1<<(mbutton-1));
    }

    bool done() { return _done; }
    float mx()  { return _mx; }
    float my()  { return _my; }
    unsigned int mbutton()  { return _mbutton; }

    void resetTrackball()
    {
        osg::Node* scene = _sceneView->getSceneData();
        if (scene)
        {
            const osg::BoundingSphere& bs = scene->getBound();
            _trackBall->reset();
            _trackBall->setOrientation( Producer::Trackball::Z_UP );
            _trackBall->setDistance(bs.radius()*2.0f);
            _trackBall->translate(-bs.center().x(),-bs.center().y(),-bs.center().z());
        }
    }

    osg::Matrixd getViewMatrix()
    {
	_trackBall->input( mx(), my(), mbutton() );
        return osg::Matrixd(_trackBall->getMatrix().ptr());
    }

private:

    float                               _mx, _my;
    float                               _mx_buttonPress, _my_buttonPress;
    unsigned int                        _mbutton;

    bool                                _done;

    osg::ref_ptr<Producer::Trackball>   _trackBall;
    osg::ref_ptr<osgUtil::SceneView>    _sceneView;
};

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // When numTimesToRun>1 allow the user to test opening and closing graphics contexts whilst
    // still keep scene graph around.
    unsigned int numTimesToRun = 1;
    if (argc>2)
    {
        numTimesToRun = atoi(argv[2]);
    }

    // do the set up of the DatabasePager...
    // create the database pager via the osgDB::Registry
    osgDB::DatabasePager* databasePager = osgDB::Registry::instance()->getOrCreateDatabasePager();

    // set wether the DatabasePager thread should be blocked while the scene graph is being used to render a frame
    // setting frame block to true can help achieve constant frame rates on single CPU systems.
    databasePager->setUseFrameBlock(false);

    // set whether to pre compile GL objects before merging new subgraphs with main scene graph
    // databasePager->setCompileGLObjectsForContextID(sceneView->getState()->getContextID(),true);

    // register any PagedLOD that need to be tracked in the scene graph
    databasePager->registerPagedLODs(loadedModel.get());

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    // set the frame number count.  Note, this is outside the window loop, so that
    // frame numbers increment even a graphics context is closed down and another opened
    // this is to ensure the record of the frame numbers in the scene graph are kept valid.
    unsigned int frameNum = 0;

    if (numTimesToRun>1)
    {
        // make sure the database pager doesn't unref images as otherwise they won't be around the next time
        // they are needed when the a new graphics context comes up.
        databasePager->setUnrefImageDataAfterApplyPolicy(true,false);
    }

    for(unsigned int i=0;i<numTimesToRun;++i)
    {
        // create the view of the scene.
        osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
        sceneView->setDefaults();
        sceneView->setSceneData(loadedModel.get());
        sceneView->setLightingMode(osgUtil::SceneView::SKY_LIGHT);

        // need to register the DatabasePager with the SceneView's CullVisitor so it can pass on request
        // for files to be loaded.
        sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager);

        // create the window to draw to.
        osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
        renderSurface->setWindowName("osgsimplepager");
        renderSurface->setWindowRectangle(100,100,800,600);
        renderSurface->useBorder(true);
        renderSurface->realize();

        // set up a KeyboardMouse to manage the events comming in from the RenderSurface
        osg::ref_ptr<Producer::KeyboardMouse>  kbm = new Producer::KeyboardMouse(renderSurface.get());

        // create a KeyboardMouseCallback to handle the mouse events within this applications
        osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(sceneView.get());

        // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
        while( renderSurface->isRealized() && !kbmcb->done())
        {

            // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
            osg::FrameStamp* frameStamp = new osg::FrameStamp;
            frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
            frameStamp->setFrameNumber(frameNum++);

            // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp
            sceneView->setFrameStamp(frameStamp);

            // pass any keyboard mouse events onto the local keyboard mouse callback.
            kbm->update( *kbmcb );

            // set the view
            sceneView->setViewMatrix(kbmcb->getViewMatrix());

            // update the viewport dimensions, incase the window has been resized.
            sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight());

            // tell the DatabasePager the frame number of that the scene graph is being actively used to render a frame
            databasePager->signalBeginFrame(frameStamp);

            // syncronize changes required by the DatabasePager thread to the scene graph
            databasePager->updateSceneGraph(frameStamp->getReferenceTime());

            // do the update traversal the scene graph - such as updating animations
            sceneView->update();

            // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins
            sceneView->cull();

            // draw the rendering bins.
            sceneView->draw();

            // tell the DatabasePager that the frame is complete and that scene graph is no longer be activity traversed.
            databasePager->signalEndFrame();

            // Swap Buffers
            renderSurface->swapBuffers();

            // clean up  and compile gl objects with a specified limit
            double availableTime = 0.0025; // 2.5 ms

            // compile any GL objects that are required.
            databasePager->compileGLObjects(*(sceneView->getState()),availableTime);

            // flush deleted GL objects.
            sceneView->flushDeletedGLObjects(availableTime);

        }

        // clear the database pager so its starts a fresh on the next update/cull/draw traversals
        databasePager->clear();

        // release the GL objects stored in the scene graph.
        sceneView->releaseAllGLObjects();

        // do a flush to delete all the OpenGL objects that have been deleted or released from the scene graph.
        sceneView->flushAllDeletedGLObjects();

        // reset the osg::State so that next time its used its in a cleaned state.
        // sceneView->getState()->reset();

    }

    // switch off the database pager by unreferencing it.
    osgDB::Registry::instance()->setDatabasePager(0);

    return 0;
}

<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
// Copyright 2018-present Open Networking Foundation
// SPDX-License-Identifier: Apache-2.0

#include "stratum/glue/status/posix_error_space.h"

#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <string>

#include "stratum/glue/logging.h"

using google::StrError;

namespace util {

namespace internal {

class PosixErrorSpace : public util::ErrorSpace {
 public:
  PosixErrorSpace();
  virtual ~PosixErrorSpace();

  // Returns the message associated with the given code in this error
  // space. This is basically a call to strerror_r.
  std::string String(int code) const final;

  ::util::error::Code CanonicalCode(const ::util::Status& status) const final;

  // PosixErrorSpace is neither copyable nor movable.
  PosixErrorSpace(const PosixErrorSpace&) = delete;
  PosixErrorSpace& operator=(const PosixErrorSpace&) = delete;
};

PosixErrorSpace::PosixErrorSpace() : ErrorSpace("util::PosixErrorSpace") {}

PosixErrorSpace::~PosixErrorSpace() {}

// TODO(unknown): Move to glog/StrError().
std::string PosixErrorSpace::String(int code) const { return StrError(code); }

::util::error::Code PosixErrorSpace::CanonicalCode(
    const ::util::Status& status) const {
  ::util::error::Code code;

  switch (status.error_code()) {
    case 0:
      code = ::util::error::OK;
      break;
    case EINVAL:        // Invalid argument
    case ENAMETOOLONG:  // Filename too long
    case E2BIG:         // Argument list too long
    case EDESTADDRREQ:  // Destination address required
    case EDOM:          // Mathematics argument out of domain of function
    case EFAULT:        // Bad address
    case EILSEQ:        // Illegal byte sequence
    case ENOPROTOOPT:   // Protocol not available
    case ENOSTR:        // Not a STREAM
    case ENOTSOCK:      // Not a socket
    case ENOTTY:        // Inappropriate I/O control operation
    case EPROTOTYPE:    // Protocol wrong type for socket
    case ESPIPE:        // Invalid seek
      code = ::util::error::INVALID_ARGUMENT;
      break;
    case ETIMEDOUT:  // Connection timed out
    case ETIME:      // Timer expired
      code = ::util::error::DEADLINE_EXCEEDED;
      break;
    case ENODEV:     // No such device
    case ENOENT:     // No such file or directory
    case ENOMEDIUM:  // No medium found
    case ENXIO:      // No such device or address
    case ESRCH:      // No such process
      code = ::util::error::NOT_FOUND;
      break;
    case EEXIST:         // File exists
    case EADDRNOTAVAIL:  // Address not available
    case EALREADY:       // Connection already in progress
    case ENOTUNIQ:       // Name not unique on network
      code = ::util::error::ALREADY_EXISTS;
      break;
    case EPERM:   // Operation not permitted
    case EACCES:  // Permission denied
    case ENOKEY:  // Required key not available
    case EROFS:   // Read only file system
      code = ::util::error::PERMISSION_DENIED;
      break;
    case ENOTEMPTY:   // Directory not empty
    case EISDIR:      // Is a directory
    case ENOTDIR:     // Not a directory
    case EADDRINUSE:  // Address already in use
    case EBADF:       // Invalid file descriptor
    case EBADFD:      // File descriptor in bad state
    case EBUSY:       // Device or resource busy
    case ECHILD:      // No child processes
    case EISCONN:     // Socket is connected
    case EISNAM:      // Is a named type file
    case ENOTBLK:     // Block device required
    case ENOTCONN:    // The socket is not connected
    case EPIPE:       // Broken pipe
    case ESHUTDOWN:   // Cannot send after transport endpoint shutdown
    case ETXTBSY:     // Text file busy
    case EUNATCH:     // Protocol driver not attached
      code = ::util::error::FAILED_PRECONDITION;
      break;
    case ENOSPC:   // No space left on device
    case EDQUOT:   // Disk quota exceeded
    case EMFILE:   // Too many open files
    case EMLINK:   // Too many links
    case ENFILE:   // Too many open files in system
    case ENOBUFS:  // No buffer space available
    case ENODATA:  // No message is available on the STREAM read queue
    case ENOMEM:   // Not enough space
    case ENOSR:    // No STREAM resources
    case EUSERS:   // Too many users
      code = ::util::error::RESOURCE_EXHAUSTED;
      break;
    case ECHRNG:     // Channel number out of range
    case EFBIG:      // File too large
    case EOVERFLOW:  // Value too large to be stored in data type
    case ERANGE:     // Result too large
      code = ::util::error::OUT_OF_RANGE;
      break;
    case ENOPKG:           // Package not installed
    case ENOSYS:           // Function not implemented
    case ENOTSUP:          // Operation not supported
    case EAFNOSUPPORT:     // Address family not supported
    case EPFNOSUPPORT:     // Protocol family not supported
    case EPROTONOSUPPORT:  // Protocol not supported
    case ESOCKTNOSUPPORT:  // Socket type not supported
    case EXDEV:            // Improper link
      code = ::util::error::UNIMPLEMENTED;
      break;
    case EAGAIN:        // Resource temporarily unavailable
    case ECOMM:         // Communication error on send
    case ECONNREFUSED:  // Connection refused
    case ECONNABORTED:  // Connection aborted
    case ECONNRESET:    // Connection reset
    case EINTR:         // Interrupted function call
    case EHOSTDOWN:     // Host is down
    case EHOSTUNREACH:  // Host is unreachable
    case ENETDOWN:      // Network is down
    case ENETRESET:     // Connection aborted by network
    case ENETUNREACH:   // Network unreachable
    case ENOLCK:        // No locks available
    case ENOLINK:       // Link has been severed
    case ENONET:        // Machine is not on the network
      code = ::util::error::UNAVAILABLE;
      break;
    case EDEADLK:  // Resource deadlock avoided
    case ESTALE:   // Stale file handle
      code = ::util::error::ABORTED;
      break;
    case ECANCELED:  // Operation cancelled
      code = ::util::error::CANCELLED;
      break;
    // NOTE: If you get any of the following (especially in a
    // reproducable way) and can propose a better mapping,
    // please email the owners about updating this mapping.
    case EBADE:         // Bad exchange
    case EBADMSG:       // Bad message
    case EBADR:         // Invalid request descriptor
    case EBADRQC:       // Invalid request code
    case EBADSLT:       // Invalid slot
    case EIDRM:         // Identifier removed
    case EINPROGRESS:   // Operation in progress
    case EIO:           // I/O error
    case EKEYEXPIRED:   // Key has expired
    case EKEYREJECTED:  // Key was rejected by service
    case EKEYREVOKED:   // Key has been revoked
    case EL2HLT:        // Level 2 halted
    case EL2NSYNC:      // Level 2 not synchronised
    case EL3HLT:        // Level 3 halted
    case EL3RST:        // Level 3 reset
    case ELIBACC:       // Cannot access a needed shared library
    case ELIBBAD:       // Acccessing a corrupted shared library
    case ELIBMAX:       // Attempting to link in too many shared libraries
    case ELIBSCN:       // lib section in a.out corrupted
    case ELIBEXEC:      // Cannot exec a shared library directly
    case ELOOP:         // Too many levels of symbolic links
    case EMEDIUMTYPE:   // Wrong medium type
    case ENOEXEC:       // Exec format error
    case ENOMSG:        // No message of the desired type
    case EPROTO:        // Protocol error
    case EREMOTE:       // Object is remote
    case EREMOTEIO:     // Remote I/O error
    case ERESTART:      // Interrupted system call should be restarted
    case ESTRPIPE:      // Streams pipe error
    case EUCLEAN:       // Structure needs cleaning
    case EXFULL:        // Exchange full
      code = ::util::error::UNKNOWN;
      break;
    default: {
      code = ::util::error::UNKNOWN;
      break;
    }
  }
  return code;
}

}  // namespace internal

const ErrorSpace* PosixErrorSpace() {
  static const ErrorSpace* space = new internal::PosixErrorSpace();
  return space;
}

// Force accessor to run at load time, which registers the errorspace.
static const ErrorSpace* dummy __attribute__((unused)) =
    util::PosixErrorSpace();

}  // namespace util
<commit_msg>Add compat code to enable basic MacOS support (#303)<commit_after>// Copyright 2018 Google LLC
// Copyright 2018-present Open Networking Foundation
// SPDX-License-Identifier: Apache-2.0

#include "stratum/glue/status/posix_error_space.h"

#include <errno.h>
#include <stddef.h>
#include <stdio.h>

#include <string>

#include "stratum/glue/logging.h"

// Fake missing error codes on MacOS. Note, that they still have to be unique
// and must not overlap with existing ones.
#ifdef __APPLE__
#ifndef ENOMEDIUM
#define ENOMEDIUM (ELAST + __COUNTER__)
#endif

#ifndef ENOTUNIQ
#define ENOTUNIQ (ELAST + __COUNTER__)
#endif

#ifndef ENOKEY
#define ENOKEY (ELAST + __COUNTER__)
#endif

#ifndef EBADFD
#define EBADFD (ELAST + __COUNTER__)
#endif

#ifndef EISNAM
#define EISNAM (ELAST + __COUNTER__)
#endif

#ifndef EUNATCH
#define EUNATCH (ELAST + __COUNTER__)
#endif

#ifndef ECHRNG
#define ECHRNG (ELAST + __COUNTER__)
#endif

#ifndef ENOPKG
#define ENOPKG (ELAST + __COUNTER__)
#endif

#ifndef ECOMM
#define ECOMM (ELAST + __COUNTER__)
#endif

#ifndef ENONET
#define ENONET (ELAST + __COUNTER__)
#endif

#ifndef EBADE
#define EBADE (ELAST + __COUNTER__)
#endif

#ifndef EBADR
#define EBADR (ELAST + __COUNTER__)
#endif

#ifndef EBADRQC
#define EBADRQC (ELAST + __COUNTER__)
#endif

#ifndef EBADSLT
#define EBADSLT (ELAST + __COUNTER__)
#endif

#ifndef EKEYEXPIRED
#define EKEYEXPIRED (ELAST + __COUNTER__)
#endif

#ifndef EKEYREJECTED
#define EKEYREJECTED (ELAST + __COUNTER__)
#endif

#ifndef EKEYREVOKED
#define EKEYREVOKED (ELAST + __COUNTER__)
#endif

#ifndef EL2HLT
#define EL2HLT (ELAST + __COUNTER__)
#endif

#ifndef EL2NSYNC
#define EL2NSYNC (ELAST + __COUNTER__)
#endif

#ifndef EL3HLT
#define EL3HLT (ELAST + __COUNTER__)
#endif

#ifndef EL3RST
#define EL3RST (ELAST + __COUNTER__)
#endif

#ifndef ELIBACC
#define ELIBACC (ELAST + __COUNTER__)
#endif

#ifndef ELIBBAD
#define ELIBBAD (ELAST + __COUNTER__)
#endif

#ifndef ELIBMAX
#define ELIBMAX (ELAST + __COUNTER__)
#endif

#ifndef ELIBSCN
#define ELIBSCN (ELAST + __COUNTER__)
#endif

#ifndef ELIBEXEC
#define ELIBEXEC (ELAST + __COUNTER__)
#endif

#ifndef EMEDIUMTYPE
#define EMEDIUMTYPE (ELAST + __COUNTER__)
#endif

#ifndef EREMOTEIO
#define EREMOTEIO (ELAST + __COUNTER__)
#endif

#ifndef ERESTART
#define ERESTART (ELAST + __COUNTER__)
#endif

#ifndef ESTRPIPE
#define ESTRPIPE (ELAST + __COUNTER__)
#endif

#ifndef EUCLEAN
#define EUCLEAN (ELAST + __COUNTER__)
#endif

#ifndef EXFULL
#define EXFULL (ELAST + __COUNTER__)
#endif
#endif  // __APPLE__

using google::StrError;

namespace util {

namespace internal {

class PosixErrorSpace : public util::ErrorSpace {
 public:
  PosixErrorSpace();
  virtual ~PosixErrorSpace();

  // Returns the message associated with the given code in this error
  // space. This is basically a call to strerror_r.
  std::string String(int code) const final;

  ::util::error::Code CanonicalCode(const ::util::Status& status) const final;

  // PosixErrorSpace is neither copyable nor movable.
  PosixErrorSpace(const PosixErrorSpace&) = delete;
  PosixErrorSpace& operator=(const PosixErrorSpace&) = delete;
};

PosixErrorSpace::PosixErrorSpace() : ErrorSpace("util::PosixErrorSpace") {}

PosixErrorSpace::~PosixErrorSpace() {}

// TODO(unknown): Move to glog/StrError().
std::string PosixErrorSpace::String(int code) const { return StrError(code); }

::util::error::Code PosixErrorSpace::CanonicalCode(
    const ::util::Status& status) const {
  ::util::error::Code code;

  switch (status.error_code()) {
    case 0:
      code = ::util::error::OK;
      break;
    case EINVAL:        // Invalid argument
    case ENAMETOOLONG:  // Filename too long
    case E2BIG:         // Argument list too long
    case EDESTADDRREQ:  // Destination address required
    case EDOM:          // Mathematics argument out of domain of function
    case EFAULT:        // Bad address
    case EILSEQ:        // Illegal byte sequence
    case ENOPROTOOPT:   // Protocol not available
    case ENOSTR:        // Not a STREAM
    case ENOTSOCK:      // Not a socket
    case ENOTTY:        // Inappropriate I/O control operation
    case EPROTOTYPE:    // Protocol wrong type for socket
    case ESPIPE:        // Invalid seek
      code = ::util::error::INVALID_ARGUMENT;
      break;
    case ETIMEDOUT:  // Connection timed out
    case ETIME:      // Timer expired
      code = ::util::error::DEADLINE_EXCEEDED;
      break;
    case ENODEV:     // No such device
    case ENOENT:     // No such file or directory
    case ENOMEDIUM:  // No medium found
    case ENXIO:      // No such device or address
    case ESRCH:      // No such process
      code = ::util::error::NOT_FOUND;
      break;
    case EEXIST:         // File exists
    case EADDRNOTAVAIL:  // Address not available
    case EALREADY:       // Connection already in progress
    case ENOTUNIQ:       // Name not unique on network
      code = ::util::error::ALREADY_EXISTS;
      break;
    case EPERM:   // Operation not permitted
    case EACCES:  // Permission denied
    case ENOKEY:  // Required key not available
    case EROFS:   // Read only file system
      code = ::util::error::PERMISSION_DENIED;
      break;
    case ENOTEMPTY:   // Directory not empty
    case EISDIR:      // Is a directory
    case ENOTDIR:     // Not a directory
    case EADDRINUSE:  // Address already in use
    case EBADF:       // Invalid file descriptor
    case EBADFD:      // File descriptor in bad state
    case EBUSY:       // Device or resource busy
    case ECHILD:      // No child processes
    case EISCONN:     // Socket is connected
    case EISNAM:      // Is a named type file
    case ENOTBLK:     // Block device required
    case ENOTCONN:    // The socket is not connected
    case EPIPE:       // Broken pipe
    case ESHUTDOWN:   // Cannot send after transport endpoint shutdown
    case ETXTBSY:     // Text file busy
    case EUNATCH:     // Protocol driver not attached
      code = ::util::error::FAILED_PRECONDITION;
      break;
    case ENOSPC:   // No space left on device
    case EDQUOT:   // Disk quota exceeded
    case EMFILE:   // Too many open files
    case EMLINK:   // Too many links
    case ENFILE:   // Too many open files in system
    case ENOBUFS:  // No buffer space available
    case ENODATA:  // No message is available on the STREAM read queue
    case ENOMEM:   // Not enough space
    case ENOSR:    // No STREAM resources
    case EUSERS:   // Too many users
      code = ::util::error::RESOURCE_EXHAUSTED;
      break;
    case ECHRNG:     // Channel number out of range
    case EFBIG:      // File too large
    case EOVERFLOW:  // Value too large to be stored in data type
    case ERANGE:     // Result too large
      code = ::util::error::OUT_OF_RANGE;
      break;
    case ENOPKG:           // Package not installed
    case ENOSYS:           // Function not implemented
    case ENOTSUP:          // Operation not supported
    case EAFNOSUPPORT:     // Address family not supported
    case EPFNOSUPPORT:     // Protocol family not supported
    case EPROTONOSUPPORT:  // Protocol not supported
    case ESOCKTNOSUPPORT:  // Socket type not supported
    case EXDEV:            // Improper link
      code = ::util::error::UNIMPLEMENTED;
      break;
    case EAGAIN:        // Resource temporarily unavailable
    case ECOMM:         // Communication error on send
    case ECONNREFUSED:  // Connection refused
    case ECONNABORTED:  // Connection aborted
    case ECONNRESET:    // Connection reset
    case EINTR:         // Interrupted function call
    case EHOSTDOWN:     // Host is down
    case EHOSTUNREACH:  // Host is unreachable
    case ENETDOWN:      // Network is down
    case ENETRESET:     // Connection aborted by network
    case ENETUNREACH:   // Network unreachable
    case ENOLCK:        // No locks available
    case ENOLINK:       // Link has been severed
    case ENONET:        // Machine is not on the network
      code = ::util::error::UNAVAILABLE;
      break;
    case EDEADLK:  // Resource deadlock avoided
    case ESTALE:   // Stale file handle
      code = ::util::error::ABORTED;
      break;
    case ECANCELED:  // Operation cancelled
      code = ::util::error::CANCELLED;
      break;
    // NOTE: If you get any of the following (especially in a
    // reproducable way) and can propose a better mapping,
    // please email the owners about updating this mapping.
    case EBADE:         // Bad exchange
    case EBADMSG:       // Bad message
    case EBADR:         // Invalid request descriptor
    case EBADRQC:       // Invalid request code
    case EBADSLT:       // Invalid slot
    case EIDRM:         // Identifier removed
    case EINPROGRESS:   // Operation in progress
    case EIO:           // I/O error
    case EKEYEXPIRED:   // Key has expired
    case EKEYREJECTED:  // Key was rejected by service
    case EKEYREVOKED:   // Key has been revoked
    case EL2HLT:        // Level 2 halted
    case EL2NSYNC:      // Level 2 not synchronised
    case EL3HLT:        // Level 3 halted
    case EL3RST:        // Level 3 reset
    case ELIBACC:       // Cannot access a needed shared library
    case ELIBBAD:       // Acccessing a corrupted shared library
    case ELIBMAX:       // Attempting to link in too many shared libraries
    case ELIBSCN:       // lib section in a.out corrupted
    case ELIBEXEC:      // Cannot exec a shared library directly
    case ELOOP:         // Too many levels of symbolic links
    case EMEDIUMTYPE:   // Wrong medium type
    case ENOEXEC:       // Exec format error
    case ENOMSG:        // No message of the desired type
    case EPROTO:        // Protocol error
    case EREMOTE:       // Object is remote
    case EREMOTEIO:     // Remote I/O error
    case ERESTART:      // Interrupted system call should be restarted
    case ESTRPIPE:      // Streams pipe error
    case EUCLEAN:       // Structure needs cleaning
    case EXFULL:        // Exchange full
      code = ::util::error::UNKNOWN;
      break;
    default: {
      code = ::util::error::UNKNOWN;
      break;
    }
  }
  return code;
}

}  // namespace internal

const ErrorSpace* PosixErrorSpace() {
  static const ErrorSpace* space = new internal::PosixErrorSpace();
  return space;
}

// Force accessor to run at load time, which registers the errorspace.
static const ErrorSpace* dummy __attribute__((unused)) =
    util::PosixErrorSpace();

}  // namespace util
<|endoftext|>


<commit_before>// Copyright 2017 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx.h"

namespace Intrinsic
{
namespace Core
{
namespace Components
{
// Static members
NodeRefArray NodeManager::_rootNodes;
NodeRefArray NodeManager::_sortedNodes;

void NodeManager::init()
{
  _INTR_LOG_INFO("Inititializing Node Component Manager...");

  Dod::Components::ComponentManagerBase<
      NodeData, _INTR_MAX_NODE_COMPONENT_COUNT>::_initComponentManager();

  _sortedNodes.reserve(_INTR_MAX_NODE_COMPONENT_COUNT);
  _rootNodes.reserve(_INTR_MAX_NODE_COMPONENT_COUNT);

  Dod::Components::ComponentManagerEntry nodeEntry;
  {
    nodeEntry.createFunction = Components::NodeManager::createNode;
    nodeEntry.destroyFunction = Components::NodeManager::destroyNode;
    nodeEntry.getComponentForEntityFunction =
        Components::NodeManager::getComponentForEntity;
    nodeEntry.onPropertyUpdateFinishedFunction =
        Components::NodeManager::updateTransforms;
    nodeEntry.onInsertionDeletionFinishedAction =
        Components::NodeManager::rebuildTreeAndUpdateTransforms;

    Application::_componentManagerMapping[_N(Node)] = nodeEntry;
    Application::_orderedComponentManagers.push_back(nodeEntry);
  }

  Dod::PropertyCompilerEntry propCompilerNode;
  {
    propCompilerNode.compileFunction =
        Components::NodeManager::compileDescriptor;
    propCompilerNode.initFunction = Components::NodeManager::initFromDescriptor;
    propCompilerNode.ref = Dod::Ref();

    Application::_componentPropertyCompilerMapping[_N(Node)] = propCompilerNode;
  }
}

void NodeManager::updateTransforms(const NodeRefArray& p_Nodes)
{
  for (uint32_t nodeIdx = 0u; nodeIdx < p_Nodes.size(); ++nodeIdx)
  {
    NodeRef nodeRef = p_Nodes[nodeIdx];
    NodeRef parentNodeRef = _parent(nodeRef);

    if (!parentNodeRef.isValid())
    {
      _worldPosition(nodeRef) = _position(nodeRef);
      _worldOrientation(nodeRef) = _orientation(nodeRef);
      _worldSize(nodeRef) = _size(nodeRef);
    }
    else
    {
      const glm::vec3& parentPos = _worldPosition(parentNodeRef);
      const glm::quat& parentOrient = _worldOrientation(parentNodeRef);
      const glm::vec3& parentSize = _worldSize(parentNodeRef);

      const glm::vec3& localPos = _position(nodeRef);
      const glm::quat& localOrient = _orientation(nodeRef);
      const glm::vec3& localSize = _size(nodeRef);

      const glm::vec3 worldPos = parentPos + (parentOrient * localPos);
      const glm::quat worldOrient = parentOrient * localOrient;
      const glm::vec3 worldSize = parentSize * localSize;

      _worldPosition(nodeRef) = worldPos;
      _worldOrientation(nodeRef) = worldOrient;
      _worldSize(nodeRef) = worldSize;
    }

    glm::mat4 rot = glm::mat4_cast(NodeManager::_worldOrientation(nodeRef));
    glm::mat4 trans =
        glm::translate(glm::mat4(1.0f), NodeManager::_worldPosition(nodeRef));
    glm::mat4 scale =
        glm::scale(glm::mat4(1.0f), NodeManager::_worldSize(nodeRef));

    _worldMatrix(nodeRef) = trans * rot * scale;
    _inverseWorldMatrix(nodeRef) = glm::inverse(_worldMatrix(nodeRef));

    // Update AABB
    // TODO: Merge sub meshes
    Components::MeshRef meshCompRef =
        Components::MeshManager::getComponentForEntity(_entity(nodeRef));
    if (meshCompRef.isValid())
    {
      Name& meshName = Components::MeshManager::_descMeshName(meshCompRef);
      Resources::MeshRef meshRef =
          Resources::MeshManager::_getResourceByName(meshName);

      if (meshRef.isValid())
      {
        const uint32_t aabbCount =
            (uint32_t)Resources::MeshManager::_aabbPerSubMesh(meshRef).size();

        if (aabbCount > 0u)
        {
          _localAABB(nodeRef) =
              Resources::MeshManager::_aabbPerSubMesh(meshRef)[0u];
          _worldAABB(nodeRef) = _localAABB(nodeRef);
          Math::transformAABBAffine(_worldAABB(nodeRef), _worldMatrix(nodeRef));

          _worldBoundingSphere(nodeRef) = {
              Math::calcAABBCenter(_worldAABB(nodeRef)),
              glm::length(Math::calcAABBHalfExtent(_worldAABB(nodeRef)))};
        }
      }
    }
    else
    {
      _worldAABB(nodeRef) =
          Math::AABB(_worldPosition(nodeRef) - glm::vec3(0.5f),
                     _worldPosition(nodeRef) + glm::vec3(0.5f));
    }
  }
}
}
}
}
<commit_msg>Fix: Apply rotation after scale<commit_after>// Copyright 2017 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx.h"

namespace Intrinsic
{
namespace Core
{
namespace Components
{
// Static members
NodeRefArray NodeManager::_rootNodes;
NodeRefArray NodeManager::_sortedNodes;

void NodeManager::init()
{
  _INTR_LOG_INFO("Inititializing Node Component Manager...");

  Dod::Components::ComponentManagerBase<
      NodeData, _INTR_MAX_NODE_COMPONENT_COUNT>::_initComponentManager();

  _sortedNodes.reserve(_INTR_MAX_NODE_COMPONENT_COUNT);
  _rootNodes.reserve(_INTR_MAX_NODE_COMPONENT_COUNT);

  Dod::Components::ComponentManagerEntry nodeEntry;
  {
    nodeEntry.createFunction = Components::NodeManager::createNode;
    nodeEntry.destroyFunction = Components::NodeManager::destroyNode;
    nodeEntry.getComponentForEntityFunction =
        Components::NodeManager::getComponentForEntity;
    nodeEntry.onPropertyUpdateFinishedFunction =
        Components::NodeManager::updateTransforms;
    nodeEntry.onInsertionDeletionFinishedAction =
        Components::NodeManager::rebuildTreeAndUpdateTransforms;

    Application::_componentManagerMapping[_N(Node)] = nodeEntry;
    Application::_orderedComponentManagers.push_back(nodeEntry);
  }

  Dod::PropertyCompilerEntry propCompilerNode;
  {
    propCompilerNode.compileFunction =
        Components::NodeManager::compileDescriptor;
    propCompilerNode.initFunction = Components::NodeManager::initFromDescriptor;
    propCompilerNode.ref = Dod::Ref();

    Application::_componentPropertyCompilerMapping[_N(Node)] = propCompilerNode;
  }
}

void NodeManager::updateTransforms(const NodeRefArray& p_Nodes)
{
  for (uint32_t nodeIdx = 0u; nodeIdx < p_Nodes.size(); ++nodeIdx)
  {
    NodeRef nodeRef = p_Nodes[nodeIdx];
    NodeRef parentNodeRef = _parent(nodeRef);

    if (!parentNodeRef.isValid())
    {
      _worldPosition(nodeRef) = _position(nodeRef);
      _worldOrientation(nodeRef) = _orientation(nodeRef);
      _worldSize(nodeRef) = _size(nodeRef);
    }
    else
    {
      const glm::vec3& parentPos = _worldPosition(parentNodeRef);
      const glm::quat& parentOrient = _worldOrientation(parentNodeRef);
      const glm::vec3& parentSize = _worldSize(parentNodeRef);

      const glm::vec3& localPos = _position(nodeRef);
      const glm::quat& localOrient = _orientation(nodeRef);
      const glm::vec3& localSize = _size(nodeRef);

      const glm::vec3 worldPos = parentPos + (parentOrient * localPos);
      const glm::quat worldOrient = parentOrient * localOrient;
      const glm::vec3 worldSize = parentSize * localSize;

      _worldPosition(nodeRef) = worldPos;
      _worldOrientation(nodeRef) = worldOrient;
      _worldSize(nodeRef) = worldSize;
    }

    glm::mat4 rot = glm::mat4_cast(NodeManager::_worldOrientation(nodeRef));
    glm::mat4 trans =
        glm::translate(glm::mat4(1.0f), NodeManager::_worldPosition(nodeRef));
    glm::mat4 scale =
        glm::scale(glm::mat4(1.0f), NodeManager::_worldSize(nodeRef));

    _worldMatrix(nodeRef) = trans * scale * rot;
    _inverseWorldMatrix(nodeRef) = glm::inverse(_worldMatrix(nodeRef));

    // Update AABB
    // TODO: Merge sub meshes
    Components::MeshRef meshCompRef =
        Components::MeshManager::getComponentForEntity(_entity(nodeRef));
    if (meshCompRef.isValid())
    {
      Name& meshName = Components::MeshManager::_descMeshName(meshCompRef);
      Resources::MeshRef meshRef =
          Resources::MeshManager::_getResourceByName(meshName);

      if (meshRef.isValid())
      {
        const uint32_t aabbCount =
            (uint32_t)Resources::MeshManager::_aabbPerSubMesh(meshRef).size();

        if (aabbCount > 0u)
        {
          _localAABB(nodeRef) =
              Resources::MeshManager::_aabbPerSubMesh(meshRef)[0u];
          _worldAABB(nodeRef) = _localAABB(nodeRef);
          Math::transformAABBAffine(_worldAABB(nodeRef), _worldMatrix(nodeRef));

          _worldBoundingSphere(nodeRef) = {
              Math::calcAABBCenter(_worldAABB(nodeRef)),
              glm::length(Math::calcAABBHalfExtent(_worldAABB(nodeRef)))};
        }
      }
    }
    else
    {
      _worldAABB(nodeRef) =
          Math::AABB(_worldPosition(nodeRef) - glm::vec3(0.5f),
                     _worldPosition(nodeRef) + glm::vec3(0.5f));
    }
  }
}
}
}
}
<|endoftext|>