<commit_before>#include <QCoreApplication>
#include <QtGui/QAction>

#include "interpreter.h"

#include "details/autoconfigurer.h"
#include "details/robotImplementations/unrealRobotModelImplementation.h"
#include "details/robotCommunication/bluetoothRobotCommunicationThread.h"
#include "details/robotCommunication/usbRobotCommunicationThread.h"
#include "details/tracer.h"
#include "details/debugHelper.h"

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mRobotCommunication(new RobotCommunicator(SettingsManager::value("valueOfCommunication").toString()))
	, mImplementationType(robotModelType::null)
	, mWatchListWindow(NULL)
	, mActionConnectToRobot(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();

	connect(mRobotModel, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
	connect(mRobotModel, SIGNAL(sensorsConfigured()), this, SLOT(sensorsConfiguredSlot()));
	connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
	connect(mD2ModelWidget, SIGNAL(d2WasClosed()), this, SLOT(stopRobot()));
	connect(mRobotCommunication, SIGNAL(errorOccured(QString)), this, SLOT(reportError(QString)));
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel").toInt());
	Tracer::debug(tracer::initialization, "Interpreter::init", "Going to set robot implementation, model type is " + DebugHelper::toString(modelType));
	setRobotImplementation(modelType);

	mWatchListWindow = new WatchListWindow(mParser, mInterpretersInterface->windowWidget());
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads) {
		delete thread;
	}
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	Tracer::debug(tracer::initialization, "Interpreter::interpret", "Preparing for interpretation");

	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState != idle) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = waitingForSensorsConfiguredToLaunch;
	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		mState = idle;
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId)) {
		return;
	}

	runTimer();
}

void Interpreter::stopRobot()
{
	mTimer->stop();
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads) {
		delete thread;
		mThreads.removeAll(thread);
	}
	mBlocksTable->setFailure();
}

void Interpreter::showWatchList()
{
	mWatchListWindow->show();
}

void Interpreter::closeWatchList()
{
	if (mWatchListWindow) {
		mWatchListWindow->setVisible(false);
	}
}

void Interpreter::closeD2ModelWidget()
{
	if (mD2ModelWidget) {
		mD2ModelWidget->close();
	}
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
	if (isVisible) {
		mD2ModelWidget->activateWindow();
		mD2ModelWidget->showNormal();
	}
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::enableD2ModelWidgetRunStopButtons()
{
	mD2ModelWidget->enableRunStopButtons();
}

void Interpreter::disableD2ModelWidgetRunStopButtons()
{
	mD2ModelWidget->disableRunStopButtons();
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType)
{
	mConnected = false;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, mRobotCommunication, mD2RobotModel);
	setRobotImplementation(robotImpl);
	mImplementationType = implementationType;
	if (mImplementationType != robotModelType::real) {
		mRobotModel->init();
	}
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		if (mRobotModel->needsConnection()) {
			mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
		}
	} else {
		Tracer::debug(tracer::initialization, "Interpreter::connectedSlot", "Robot connection status: " + QString::number(success));
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
	mConnected = success;
	mActionConnectToRobot->setChecked(success);
}

void Interpreter::sensorsConfiguredSlot()
{
	Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Sensors are configured");

	mConnected = true;
	mActionConnectToRobot->setChecked(mConnected);

	resetVariables();

	mRobotModel->nextBlockAfterInitial(mConnected);

	if (mState == waitingForSensorsConfiguredToLaunch) {
		mState = interpreting;

		Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Starting interpretation");
		mRobotModel->startInterpretation();

		Id const &currentDiagramId = mInterpretersInterface->activeDiagram();
		Id const startingElement = findStartingElement(currentDiagramId);
		Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
		addThread(initialThread);
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1) {
			return child;
		}
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty()) {
		stopRobot();
	}
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	if (mConnected) {
		mRobotModel->configureSensors(port1, port2, port3, port4);
	}
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	QCoreApplication::processEvents();
	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl) {
		connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(runTimer()));
	}
}

void Interpreter::runTimer()
{
	mTimer->start(200);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle) {
		return;
	}

	if (mRobotModel->sensor(inputPort::port1)) {
		mRobotModel->sensor(inputPort::port1)->read();
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		mRobotModel->sensor(inputPort::port2)->read();
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		mRobotModel->sensor(inputPort::port3)->read();
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		mRobotModel->sensor(inputPort::port4)->read();
	}
}

void Interpreter::slotFailure()
{
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::slotFailure", "");
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues("Sensor1", sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues("Sensor2", sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues("Sensor3", sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues("Sensor4", sensorValue);
}

void Interpreter::updateSensorValues(QString const &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = utils::Number(sensorValue, utils::Number::intType);
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::updateSensorValues", sensorVariableName + QString::number(sensorValue));
}

void Interpreter::resetVariables()
{
	int const resetValue = 0;
	responseSlot1(resetValue);
	responseSlot2(resetValue);
	responseSlot3(resetValue);
	responseSlot4(resetValue);
}

void Interpreter::connectToRobot()
{
	if (mConnected) {
		mRobotModel->stopRobot();
		mRobotModel->disconnectFromRobot();
	} else {
		mRobotModel->init();
		configureSensors(static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port1SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port2SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port3SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port4SensorType").toInt()));
	}
	mActionConnectToRobot->setChecked(mConnected);
}

void Interpreter::disconnectSlot()
{
	mActionConnectToRobot->setChecked(false);
	mConnected = false;
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType);
}

void Interpreter::setCommunicator(QString const &valueOfCommunication, QString const &portName)
{
	if (valueOfCommunication == mLastCommunicationValue) {
		return;
	}
	RobotCommunicationThreadInterface *communicator = NULL;
	if (valueOfCommunication == "bluetooth") {
		communicator = new BluetoothRobotCommunicationThread();
	} else {
		communicator = new UsbRobotCommunicationThread();
	}
	mLastCommunicationValue = valueOfCommunication;

	mRobotCommunication->setRobotCommunicationThreadObject(communicator);
	mRobotCommunication->setPortName(portName);
	connectToRobot();
}

void Interpreter::setConnectRobotAction(QAction *actionConnect)
{
	mActionConnectToRobot = actionConnect;
}

void Interpreter::reportError(QString const &message)
{
	mInterpretersInterface->errorReporter()->addError(message);
}

WatchListWindow *Interpreter::watchWindow() const
{
	return mWatchListWindow;
}

void Interpreter::connectSensorConfigurer(details::SensorsConfigurationWidget *configurer) const
{
	connect(configurer, SIGNAL(saved()), mD2ModelWidget, SLOT(syncronizeSensors()));
}
<commit_msg>Fixed terribelly large sensor rereading interval<commit_after>#include <QCoreApplication>
#include <QtGui/QAction>

#include "interpreter.h"

#include "details/autoconfigurer.h"
#include "details/robotImplementations/unrealRobotModelImplementation.h"
#include "details/robotCommunication/bluetoothRobotCommunicationThread.h"
#include "details/robotCommunication/usbRobotCommunicationThread.h"
#include "details/tracer.h"
#include "details/debugHelper.h"

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mRobotCommunication(new RobotCommunicator(SettingsManager::value("valueOfCommunication").toString()))
	, mImplementationType(robotModelType::null)
	, mWatchListWindow(NULL)
	, mActionConnectToRobot(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();

	connect(mRobotModel, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
	connect(mRobotModel, SIGNAL(sensorsConfigured()), this, SLOT(sensorsConfiguredSlot()));
	connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
	connect(mD2ModelWidget, SIGNAL(d2WasClosed()), this, SLOT(stopRobot()));
	connect(mRobotCommunication, SIGNAL(errorOccured(QString)), this, SLOT(reportError(QString)));
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel").toInt());
	Tracer::debug(tracer::initialization, "Interpreter::init", "Going to set robot implementation, model type is " + DebugHelper::toString(modelType));
	setRobotImplementation(modelType);

	mWatchListWindow = new WatchListWindow(mParser, mInterpretersInterface->windowWidget());
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads) {
		delete thread;
	}
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	Tracer::debug(tracer::initialization, "Interpreter::interpret", "Preparing for interpretation");

	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState != idle) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = waitingForSensorsConfiguredToLaunch;
	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		mState = idle;
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId)) {
		return;
	}

	runTimer();
}

void Interpreter::stopRobot()
{
	mTimer->stop();
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads) {
		delete thread;
		mThreads.removeAll(thread);
	}
	mBlocksTable->setFailure();
}

void Interpreter::showWatchList()
{
	mWatchListWindow->show();
}

void Interpreter::closeWatchList()
{
	if (mWatchListWindow) {
		mWatchListWindow->setVisible(false);
	}
}

void Interpreter::closeD2ModelWidget()
{
	if (mD2ModelWidget) {
		mD2ModelWidget->close();
	}
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
	if (isVisible) {
		mD2ModelWidget->activateWindow();
		mD2ModelWidget->showNormal();
	}
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::enableD2ModelWidgetRunStopButtons()
{
	mD2ModelWidget->enableRunStopButtons();
}

void Interpreter::disableD2ModelWidgetRunStopButtons()
{
	mD2ModelWidget->disableRunStopButtons();
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType)
{
	mConnected = false;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, mRobotCommunication, mD2RobotModel);
	setRobotImplementation(robotImpl);
	mImplementationType = implementationType;
	if (mImplementationType != robotModelType::real) {
		mRobotModel->init();
	}
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		if (mRobotModel->needsConnection()) {
			mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
		}
	} else {
		Tracer::debug(tracer::initialization, "Interpreter::connectedSlot", "Robot connection status: " + QString::number(success));
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
	mConnected = success;
	mActionConnectToRobot->setChecked(success);
}

void Interpreter::sensorsConfiguredSlot()
{
	Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Sensors are configured");

	mConnected = true;
	mActionConnectToRobot->setChecked(mConnected);

	resetVariables();

	mRobotModel->nextBlockAfterInitial(mConnected);

	if (mState == waitingForSensorsConfiguredToLaunch) {
		mState = interpreting;

		Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Starting interpretation");
		mRobotModel->startInterpretation();

		Id const &currentDiagramId = mInterpretersInterface->activeDiagram();
		Id const startingElement = findStartingElement(currentDiagramId);
		Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
		addThread(initialThread);
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1) {
			return child;
		}
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty()) {
		stopRobot();
	}
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	if (mConnected) {
		mRobotModel->configureSensors(port1, port2, port3, port4);
	}
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	QCoreApplication::processEvents();
	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl) {
		connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(runTimer()));
	}
}

void Interpreter::runTimer()
{
	mTimer->start(1);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle) {
		return;
	}

	if (mRobotModel->sensor(inputPort::port1)) {
		mRobotModel->sensor(inputPort::port1)->read();
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		mRobotModel->sensor(inputPort::port2)->read();
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		mRobotModel->sensor(inputPort::port3)->read();
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		mRobotModel->sensor(inputPort::port4)->read();
	}
}

void Interpreter::slotFailure()
{
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::slotFailure", "");
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues("Sensor1", sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues("Sensor2", sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues("Sensor3", sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues("Sensor4", sensorValue);
}

void Interpreter::updateSensorValues(QString const &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = utils::Number(sensorValue, utils::Number::intType);
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::updateSensorValues", sensorVariableName + QString::number(sensorValue));
}

void Interpreter::resetVariables()
{
	int const resetValue = 0;
	responseSlot1(resetValue);
	responseSlot2(resetValue);
	responseSlot3(resetValue);
	responseSlot4(resetValue);
}

void Interpreter::connectToRobot()
{
	if (mConnected) {
		mRobotModel->stopRobot();
		mRobotModel->disconnectFromRobot();
	} else {
		mRobotModel->init();
		configureSensors(static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port1SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port2SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port3SensorType").toInt())
						 , static_cast<sensorType::SensorTypeEnum>(SettingsManager::instance()->value("port4SensorType").toInt()));
	}
	mActionConnectToRobot->setChecked(mConnected);
}

void Interpreter::disconnectSlot()
{
	mActionConnectToRobot->setChecked(false);
	mConnected = false;
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType);
}

void Interpreter::setCommunicator(QString const &valueOfCommunication, QString const &portName)
{
	if (valueOfCommunication == mLastCommunicationValue) {
		return;
	}
	RobotCommunicationThreadInterface *communicator = NULL;
	if (valueOfCommunication == "bluetooth") {
		communicator = new BluetoothRobotCommunicationThread();
	} else {
		communicator = new UsbRobotCommunicationThread();
	}
	mLastCommunicationValue = valueOfCommunication;

	mRobotCommunication->setRobotCommunicationThreadObject(communicator);
	mRobotCommunication->setPortName(portName);
	connectToRobot();
}

void Interpreter::setConnectRobotAction(QAction *actionConnect)
{
	mActionConnectToRobot = actionConnect;
}

void Interpreter::reportError(QString const &message)
{
	mInterpretersInterface->errorReporter()->addError(message);
}

WatchListWindow *Interpreter::watchWindow() const
{
	return mWatchListWindow;
}

void Interpreter::connectSensorConfigurer(details::SensorsConfigurationWidget *configurer) const
{
	connect(configurer, SIGNAL(saved()), mD2ModelWidget, SLOT(syncronizeSensors()));
}
<|endoftext|>


<commit_before>#include "../notification.h"
#include "../cef_handler.h"
#include "main_window.h"

bool
MainWindow::SetFocus(bool focused) {
  BaseWindow::SetFocus(focused);

  if (!focused)
    return false;

  CefRefPtr<ClientHandler> handler = ClientHandler::GetInstance();
  if (!handler)
    return false;

  CefRefPtr<CefBrowser> browser = handler->GetBrowser();
  if (!browser)
    return false;

  // Give focus to the browser window.
  browser->GetHost()->SetFocus(true);

  // Hide previously  showed notification
  Notification::Hide();
  return true;
}<commit_msg>Пробуем обогнуть странное поведение событий onblur/onfocus в CEF<commit_after>#include "../notification.h"
#include "../cef_handler.h"
#include "main_window.h"

bool
MainWindow::SetFocus(bool focused) {
  BaseWindow::SetFocus(focused);

  CefRefPtr<ClientHandler> handler = ClientHandler::GetInstance();
  if (!handler)
    return false;

  CefRefPtr<CefBrowser> browser = handler->GetBrowser();
  if (!browser)
    return false;

  // Give focus to the browser window.
  browser->GetHost()->SetFocus(focused);

  if (focused) {
    // Hide previously  showed notification
    Notification::Hide();
  }

  // Hack: CEF have strange behaviour for onfocus/onblur event, so we send custom event
  // ToDo: Research
  handler->SendJSEvent(browser, "BXForegroundChanged", focused? "[true]": "[false]");

  return true;
}<|endoftext|>


<commit_before>#include "docks/favorites-dock.h"
#include <QEvent>
#include <QStringList>
#include <ui_favorites-dock.h>
#include "functions.h"
#include "helpers.h"
#include "models/favorite.h"
#include "models/profile.h"
#include "ui/QAffiche.h"

FavoritesDock::FavoritesDock(Profile *profile, QWidget *parent)
	: Dock(parent), ui(new Ui::FavoritesDock), m_favorites(profile->getFavorites())
{
	ui->setupUi(this);

	connect(profile, &Profile::favoritesChanged, this, &FavoritesDock::refresh);

	refresh();

}

FavoritesDock::~FavoritesDock()
{
	close();
	delete ui;
}

void FavoritesDock::changeEvent(QEvent *event)
{
	if (event->type() == QEvent::LanguageChange) {
		ui->retranslateUi(this);
	}

	QWidget::changeEvent(event);
}

void FavoritesDock::changeSortDirection()
{
	m_descending = !m_descending;

	static const QIcon asc(":/images/icons/arrow-down.png");
	static const QIcon desc(":/images/icons/arrow-up.png");
	ui->buttonSortDirection->setIcon(m_descending ? desc : asc);

	refresh();
}

void FavoritesDock::refresh()
{
	clearLayout(ui->layoutFavorites);

	// Sort
	static const QStringList assoc { "name", "note", "lastviewed" };
	const QString order = assoc[qMax(ui->comboSortBy->currentIndex(), 0)];
	if (order == "note") {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByNote);
	} else if (order == "lastviewed") {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByLastViewed);
	} else {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByName);
	}

	// Reverse
	if (m_descending) {
		m_favorites = reversed(m_favorites);
	}

	for (const Favorite &fav : qAsConst(m_favorites)) {
		QAffiche *lab = new QAffiche(QString(fav.getName()), 0, QColor(), this);
		lab->setText(fav.getName());
		lab->setToolTip("
" + tr("Name: %1
Note: %2 %%
Last view: %3").arg(fav.getName(), QString::number(fav.getNote()), fav.getLastViewed().toString(Qt::DefaultLocaleShortDate)));
		lab->setCursor(Qt::PointingHandCursor);

		connect(lab, SIGNAL(clicked(QString)), this, SIGNAL(open(QString)));
		connect(lab, SIGNAL(middleClicked(QString)), this, SIGNAL(openInNewTab(QString)));

		ui->layoutFavorites->addWidget(lab);
	}
}
<commit_msg>Make favorites alternate background in favorites dock (issue #1957)<commit_after>#include "docks/favorites-dock.h"
#include <QEvent>
#include <QStringList>
#include <ui_favorites-dock.h>
#include "functions.h"
#include "helpers.h"
#include "models/favorite.h"
#include "models/profile.h"
#include "ui/QAffiche.h"

FavoritesDock::FavoritesDock(Profile *profile, QWidget *parent)
	: Dock(parent), ui(new Ui::FavoritesDock), m_favorites(profile->getFavorites())
{
	ui->setupUi(this);

	connect(profile, &Profile::favoritesChanged, this, &FavoritesDock::refresh);

	refresh();

}

FavoritesDock::~FavoritesDock()
{
	close();
	delete ui;
}

void FavoritesDock::changeEvent(QEvent *event)
{
	if (event->type() == QEvent::LanguageChange) {
		ui->retranslateUi(this);
	}

	QWidget::changeEvent(event);
}

void FavoritesDock::changeSortDirection()
{
	m_descending = !m_descending;

	static const QIcon asc(":/images/icons/arrow-down.png");
	static const QIcon desc(":/images/icons/arrow-up.png");
	ui->buttonSortDirection->setIcon(m_descending ? desc : asc);

	refresh();
}

void FavoritesDock::refresh()
{
	clearLayout(ui->layoutFavorites);

	// Sort
	static const QStringList assoc { "name", "note", "lastviewed" };
	const QString order = assoc[qMax(ui->comboSortBy->currentIndex(), 0)];
	if (order == "note") {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByNote);
	} else if (order == "lastviewed") {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByLastViewed);
	} else {
		std::sort(m_favorites.begin(), m_favorites.end(), Favorite::sortByName);
	}

	// Reverse
	if (m_descending) {
		m_favorites = reversed(m_favorites);
	}

	int i = 0;
	for (const Favorite &fav : qAsConst(m_favorites)) {
		QAffiche *lab = new QAffiche(QString(fav.getName()), 0, QColor(), this);
		lab->setText(fav.getName());
		lab->setToolTip("
" + tr("Name: %1
Note: %2 %%
Last view: %3").arg(fav.getName(), QString::number(fav.getNote()), fav.getLastViewed().toString(Qt::DefaultLocaleShortDate)));
		lab->setCursor(Qt::PointingHandCursor);

		if (i++ % 2 == 1) {
			lab->setStyleSheet("QAffiche { background-color: rgba(128, 128, 128, 10%); }");
		}

		connect(lab, SIGNAL(clicked(QString)), this, SIGNAL(open(QString)));
		connect(lab, SIGNAL(middleClicked(QString)), this, SIGNAL(openInNewTab(QString)));

		ui->layoutFavorites->addWidget(lab);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include "common.h"
#include "bgfx_utils.h"
#include <entry/cmd.h>
#include <entry/input.h>

#include <camera.h>
#include <debugdraw/debugdraw.h>
#include <imgui/imgui.h>

#include <bx/rng.h>
#include <bx/easing.h>

#include <ps/particle_system.h>

static const char* s_shapeNames[] =
{
	"Sphere",
	"Hemisphere",
	"Circle",
	"Disc",
	"Rect",
};

static const char* s_directionName[] =
{
	"Up",
	"Outward",
};

static const char* s_easeFuncName[] =
{
	"Linear",
	"InQuad",
	"OutQuad",
	"InOutQuad",
	"OutInQuad",
	"InCubic",
	"OutCubic",
	"InOutCubic",
	"OutInCubic",
	"InQuart",
	"OutQuart",
	"InOutQuart",
	"OutInQuart",
	"InQuint",
	"OutQuint",
	"InOutQuint",
	"OutInQuint",
	"InSine",
	"OutSine",
	"InOutSine",
	"OutInSine",
	"InExpo",
	"OutExpo",
	"InOutExpo",
	"OutInExpo",
	"InCirc",
	"OutCirc",
	"InOutCirc",
	"OutInCirc",
	"InElastic",
	"OutElastic",
	"InOutElastic",
	"OutInElastic",
	"InBack",
	"OutBack",
	"InOutBack",
	"OutInBack",
	"InBounce",
	"OutBounce",
	"InOutBounce",
	"OutInBounce",
};
BX_STATIC_ASSERT(BX_COUNTOF(s_easeFuncName) == bx::Easing::Count);

struct Emitter
{
	EmitterUniforms m_uniforms;
	EmitterHandle   m_handle;

	EmitterShape::Enum     m_shape;
	EmitterDirection::Enum m_direction;

	void create()
	{
		m_shape      = EmitterShape::Sphere;
		m_direction  = EmitterDirection::Outward;

		m_handle = psCreateEmitter(m_shape, m_direction, 1024);
		m_uniforms.reset();
	}

	void destroy()
	{
		psDestroyEmitter(m_handle);
	}

	void update()
	{
		psUpdateEmitter(m_handle, &m_uniforms);
	}

	void imgui(const float* _view, const float* _proj)
	{
//		if (ImGui::CollapsingHeader("General") )
		{
			if (ImGui::Combo("Shape", (int*)&m_shape, s_shapeNames, BX_COUNTOF(s_shapeNames) )
			||  ImGui::Combo("Direction", (int*)&m_direction, s_directionName, BX_COUNTOF(s_directionName) ) )
			{
				psDestroyEmitter(m_handle);
				m_handle = psCreateEmitter(m_shape, m_direction, 1024);
			}

			ImGui::SliderInt("particles / s", (int*)&m_uniforms.m_particlesPerSecond, 0, 1024);

			ImGui::SliderFloat("Gravity scale"
					, &m_uniforms.m_gravityScale
					, -2.0f
					,  2.0f
					);

			ImGui::RangeSliderFloat("Life span"
					, &m_uniforms.m_lifeSpan[0]
					, &m_uniforms.m_lifeSpan[1]
					, 0.1f
					, 5.0f
					);

			if (ImGui::Button("Reset") )
			{
				psUpdateEmitter(m_handle);
			}
		}

		if (ImGui::CollapsingHeader("Position and scale") )
		{
			ImGui::Combo("Position Ease", (int*)&m_uniforms.m_easePos, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Start offset"
					, &m_uniforms.m_offsetStart[0]
					, &m_uniforms.m_offsetStart[1]
					, 0.0f
					, 10.0f
					);
			ImGui::RangeSliderFloat("End offset"
					, &m_uniforms.m_offsetEnd[0]
					, &m_uniforms.m_offsetEnd[1]
					, 0.0f
					, 10.0f
					);

			ImGui::Text("Scale:");

			ImGui::Combo("Scale Ease", (int*)&m_uniforms.m_easeScale, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Scale Start"
					, &m_uniforms.m_scaleStart[0]
					, &m_uniforms.m_scaleStart[1]
					, 0.0f
					, 3.0f
					);
			ImGui::RangeSliderFloat("Scale End"
					, &m_uniforms.m_scaleEnd[0]
					, &m_uniforms.m_scaleEnd[1]
					, 0.0f
					, 3.0f
					);
		}

		if (ImGui::CollapsingHeader("Blending and color") )
		{
			ImGui::Combo("Blend Ease", (int*)&m_uniforms.m_easeBlend, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::RangeSliderFloat("Blend Start"
					, &m_uniforms.m_blendStart[0]
					, &m_uniforms.m_blendStart[1]
					, 0.0f
					, 1.0f
					);
			ImGui::RangeSliderFloat("Blend End"
					, &m_uniforms.m_blendEnd[0]
					, &m_uniforms.m_blendEnd[1]
					, 0.0f
					, 1.0f
					);

			ImGui::Text("Color:");

			ImGui::Combo("RGBA Ease", (int*)&m_uniforms.m_easeRgba, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::ColorEdit4("RGBA0", &m_uniforms.m_rgba[0], true);
			ImGui::ColorEdit4("RGBA1", &m_uniforms.m_rgba[1], true);
			ImGui::ColorEdit4("RGBA2", &m_uniforms.m_rgba[2], true);
			ImGui::ColorEdit4("RGBA3", &m_uniforms.m_rgba[3], true);
			ImGui::ColorEdit4("RGBA4", &m_uniforms.m_rgba[4], true);
		}

		ImGui::End();

		float mtx[16];
		bx::mtxSRT(mtx
				, 1.0f, 1.0f, 1.0f
				, m_uniforms.m_angle[0],    m_uniforms.m_angle[1],    m_uniforms.m_angle[2]
				, m_uniforms.m_position[0], m_uniforms.m_position[1], m_uniforms.m_position[2]
				);

		ImGuizmo::Manipulate(
				_view
				, _proj
				, ImGuizmo::OPERATION::TRANSLATE
				, ImGuizmo::MODE::LOCAL
				, mtx
				);

		float scale[3];
		ImGuizmo::DecomposeMatrixToComponents(mtx, m_uniforms.m_position, m_uniforms.m_angle, scale);
	}
};

class Particles : public entry::AppI
{
	void init(int _argc, char** _argv) BX_OVERRIDE
	{
		Args args(_argc, _argv);

		m_width  = 1280;
		m_height = 720;
		m_debug  = BGFX_DEBUG_TEXT;
		m_reset  = BGFX_RESET_VSYNC;

		bgfx::init(args.m_type, args.m_pciId);
		bgfx::reset(m_width, m_height, m_reset);

		// Enable m_debug text.
		bgfx::setDebug(m_debug);

		// Set view 0 clear state.
		bgfx::setViewClear(0
				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
				, 0x202020ff
				, 1.0f
				, 0
				);

		ddInit();

		psInit();

		for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
		{
			m_emitter[ii].create();
		}

		imguiCreate();

		cameraCreate();

		const float initialPos[3] = { 0.0f, 2.0f, -12.0f };
		cameraSetPosition(initialPos);
		cameraSetVerticalAngle(0.0f);

		m_timeOffset = bx::getHPCounter();
	}

	virtual int shutdown() BX_OVERRIDE
	{
		for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
		{
			m_emitter[ii].destroy();
		}

		psShutdown();

		ddShutdown();

		imguiDestroy();

		cameraDestroy();

		// Shutdown bgfx.
		bgfx::shutdown();

		return 0;
	}

	bool update() BX_OVERRIDE
	{
		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
		{
			// Set view 0 default viewport.
			bgfx::setViewRect(0, 0, 0, m_width, m_height);

			bgfx::touch(0);

			int64_t now = bx::getHPCounter() - m_timeOffset;
			static int64_t last = now;
			const int64_t frameTime = now - last;
			last = now;
			const double freq = double(bx::getHPFrequency() );
			const double toMs = 1000.0/freq;
			const float deltaTime = float(frameTime/freq);

			// Use debug font to print information about this example.
			bgfx::dbgTextClear();
			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/32-particles");
			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Particles.");
			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

			// Update camera.George RR Martin
			cameraUpdate(deltaTime, m_mouseState);

			float view[16];
			cameraGetViewMtx(view);

			float proj[16];

			// Set view and projection matrix for view 0.
			const bgfx::HMD* hmd = bgfx::getHMD();
			if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
			{
				float eye[3];
				cameraGetPosition(eye);
				bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
				bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
				bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
			}
			else
			{
				bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f);

				bgfx::setViewTransform(0, view, proj);
				bgfx::setViewRect(0, 0, 0, m_width, m_height);
			}

			imguiBeginFrame(
				   m_mouseState.m_mx
				,  m_mouseState.m_my
				, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
				| (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT  : 0)
				| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
				,  m_mouseState.m_mz
				, m_width
				, m_height
				);

			ImGui::Begin("Properties"
				, NULL
				, ImVec2(400.0f, 600.0f)
				, ImGuiWindowFlags_AlwaysAutoResize
				);

			static float timeScale = 1.0f;
			ImGui::SliderFloat("Time scale"
				, &timeScale
				, 0.0f
				, 1.0f
				);

			static bool showBounds;
			ImGui::Checkbox("Show bounds", &showBounds);

			ImGui::Text("Emitter:");
			static int currentEmitter = 0;
			for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
			{
				ImGui::SameLine();

				char name[16];
				bx::snprintf(name, BX_COUNTOF(name), "%d", ii);

				ImGui::RadioButton(name, &currentEmitter, ii);
			}

			m_emitter[currentEmitter].imgui(view, proj);

			imguiEndFrame();

			ddBegin(0);

			float center[3] = { 0.0f, 0.0f, 0.0f };
			ddDrawGrid(Axis::Y, center);

			float eye[3];
			cameraGetPosition(eye);

			m_emitter[currentEmitter].update();

			psUpdate(deltaTime * timeScale);
			psRender(0, view, eye);

			if (showBounds)
			{
				Aabb aabb;
				psGetAabb(m_emitter[currentEmitter].m_handle, aabb);
				ddSetColor(0xff0000ff);
				ddDraw(aabb);
			}

			ddEnd();

			// Advance to next frame. Rendering thread will be kicked to
			// process submitted rendering primitives.
			bgfx::frame();

			return true;
		}

		return false;
	}

	entry::MouseState m_mouseState;

	int64_t m_timeOffset;

	uint32_t m_width;
	uint32_t m_height;
	uint32_t m_debug;
	uint32_t m_reset;

	Emitter m_emitter[4];
};

ENTRY_IMPLEMENT_MAIN(Particles);
<commit_msg>Cleanup.<commit_after>/*
 * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include "common.h"
#include "bgfx_utils.h"
#include <entry/cmd.h>
#include <entry/input.h>

#include <camera.h>
#include <debugdraw/debugdraw.h>
#include <imgui/imgui.h>

#include <bx/rng.h>
#include <bx/easing.h>

#include <ps/particle_system.h>

static const char* s_shapeNames[] =
{
	"Sphere",
	"Hemisphere",
	"Circle",
	"Disc",
	"Rect",
};

static const char* s_directionName[] =
{
	"Up",
	"Outward",
};

static const char* s_easeFuncName[] =
{
	"Linear",
	"InQuad",
	"OutQuad",
	"InOutQuad",
	"OutInQuad",
	"InCubic",
	"OutCubic",
	"InOutCubic",
	"OutInCubic",
	"InQuart",
	"OutQuart",
	"InOutQuart",
	"OutInQuart",
	"InQuint",
	"OutQuint",
	"InOutQuint",
	"OutInQuint",
	"InSine",
	"OutSine",
	"InOutSine",
	"OutInSine",
	"InExpo",
	"OutExpo",
	"InOutExpo",
	"OutInExpo",
	"InCirc",
	"OutCirc",
	"InOutCirc",
	"OutInCirc",
	"InElastic",
	"OutElastic",
	"InOutElastic",
	"OutInElastic",
	"InBack",
	"OutBack",
	"InOutBack",
	"OutInBack",
	"InBounce",
	"OutBounce",
	"InOutBounce",
	"OutInBounce",
};
BX_STATIC_ASSERT(BX_COUNTOF(s_easeFuncName) == bx::Easing::Count);

struct Emitter
{
	EmitterUniforms m_uniforms;
	EmitterHandle   m_handle;

	EmitterShape::Enum     m_shape;
	EmitterDirection::Enum m_direction;

	void create()
	{
		m_shape      = EmitterShape::Sphere;
		m_direction  = EmitterDirection::Outward;

		m_handle = psCreateEmitter(m_shape, m_direction, 1024);
		m_uniforms.reset();
	}

	void destroy()
	{
		psDestroyEmitter(m_handle);
	}

	void update()
	{
		psUpdateEmitter(m_handle, &m_uniforms);
	}

	void imgui(const float* _view, const float* _proj)
	{
//		if (ImGui::CollapsingHeader("General") )
		{
			if (ImGui::Combo("Shape", (int*)&m_shape, s_shapeNames, BX_COUNTOF(s_shapeNames) )
			||  ImGui::Combo("Direction", (int*)&m_direction, s_directionName, BX_COUNTOF(s_directionName) ) )
			{
				psDestroyEmitter(m_handle);
				m_handle = psCreateEmitter(m_shape, m_direction, 1024);
			}

			ImGui::SliderInt("particles / s", (int*)&m_uniforms.m_particlesPerSecond, 0, 1024);

			ImGui::SliderFloat("Gravity scale"
					, &m_uniforms.m_gravityScale
					, -2.0f
					,  2.0f
					);

			ImGui::RangeSliderFloat("Life span"
					, &m_uniforms.m_lifeSpan[0]
					, &m_uniforms.m_lifeSpan[1]
					, 0.1f
					, 5.0f
					);

			if (ImGui::Button("Reset") )
			{
				psUpdateEmitter(m_handle);
			}
		}

		if (ImGui::CollapsingHeader("Position and scale") )
		{
			ImGui::Combo("Position Ease", (int*)&m_uniforms.m_easePos, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Start offset"
					, &m_uniforms.m_offsetStart[0]
					, &m_uniforms.m_offsetStart[1]
					, 0.0f
					, 10.0f
					);
			ImGui::RangeSliderFloat("End offset"
					, &m_uniforms.m_offsetEnd[0]
					, &m_uniforms.m_offsetEnd[1]
					, 0.0f
					, 10.0f
					);

			ImGui::Text("Scale:");

			ImGui::Combo("Scale Ease", (int*)&m_uniforms.m_easeScale, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Scale Start"
					, &m_uniforms.m_scaleStart[0]
					, &m_uniforms.m_scaleStart[1]
					, 0.0f
					, 3.0f
					);
			ImGui::RangeSliderFloat("Scale End"
					, &m_uniforms.m_scaleEnd[0]
					, &m_uniforms.m_scaleEnd[1]
					, 0.0f
					, 3.0f
					);
		}

		if (ImGui::CollapsingHeader("Blending and color") )
		{
			ImGui::Combo("Blend Ease", (int*)&m_uniforms.m_easeBlend, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::RangeSliderFloat("Blend Start"
					, &m_uniforms.m_blendStart[0]
					, &m_uniforms.m_blendStart[1]
					, 0.0f
					, 1.0f
					);
			ImGui::RangeSliderFloat("Blend End"
					, &m_uniforms.m_blendEnd[0]
					, &m_uniforms.m_blendEnd[1]
					, 0.0f
					, 1.0f
					);

			ImGui::Text("Color:");

			ImGui::Combo("RGBA Ease", (int*)&m_uniforms.m_easeRgba, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::ColorEdit4("RGBA0", &m_uniforms.m_rgba[0], true);
			ImGui::ColorEdit4("RGBA1", &m_uniforms.m_rgba[1], true);
			ImGui::ColorEdit4("RGBA2", &m_uniforms.m_rgba[2], true);
			ImGui::ColorEdit4("RGBA3", &m_uniforms.m_rgba[3], true);
			ImGui::ColorEdit4("RGBA4", &m_uniforms.m_rgba[4], true);
		}

		ImGui::End();

		float mtx[16];
		bx::mtxSRT(mtx
				, 1.0f, 1.0f, 1.0f
				, m_uniforms.m_angle[0],    m_uniforms.m_angle[1],    m_uniforms.m_angle[2]
				, m_uniforms.m_position[0], m_uniforms.m_position[1], m_uniforms.m_position[2]
				);

		ImGuizmo::Manipulate(
				_view
				, _proj
				, ImGuizmo::OPERATION::TRANSLATE
				, ImGuizmo::MODE::LOCAL
				, mtx
				);

		float scale[3];
		ImGuizmo::DecomposeMatrixToComponents(mtx, m_uniforms.m_position, m_uniforms.m_angle, scale);
	}
};

class Particles : public entry::AppI
{
	void init(int _argc, char** _argv) BX_OVERRIDE
	{
		Args args(_argc, _argv);

		m_width  = 1280;
		m_height = 720;
		m_debug  = BGFX_DEBUG_TEXT;
		m_reset  = BGFX_RESET_VSYNC;

		bgfx::init(args.m_type, args.m_pciId);
		bgfx::reset(m_width, m_height, m_reset);

		// Enable m_debug text.
		bgfx::setDebug(m_debug);

		// Set view 0 clear state.
		bgfx::setViewClear(0
				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
				, 0x202020ff
				, 1.0f
				, 0
				);

		ddInit();

		psInit();

		for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
		{
			m_emitter[ii].create();
		}

		imguiCreate();

		cameraCreate();

		const float initialPos[3] = { 0.0f, 2.0f, -12.0f };
		cameraSetPosition(initialPos);
		cameraSetVerticalAngle(0.0f);

		m_timeOffset = bx::getHPCounter();
	}

	virtual int shutdown() BX_OVERRIDE
	{
		for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
		{
			m_emitter[ii].destroy();
		}

		psShutdown();

		ddShutdown();

		imguiDestroy();

		cameraDestroy();

		// Shutdown bgfx.
		bgfx::shutdown();

		return 0;
	}

	bool update() BX_OVERRIDE
	{
		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
		{
			// Set view 0 default viewport.
			bgfx::setViewRect(0, 0, 0, m_width, m_height);

			bgfx::touch(0);

			int64_t now = bx::getHPCounter() - m_timeOffset;
			static int64_t last = now;
			const int64_t frameTime = now - last;
			last = now;
			const double freq = double(bx::getHPFrequency() );
			const double toMs = 1000.0/freq;
			const float deltaTime = float(frameTime/freq);

			// Use debug font to print information about this example.
			bgfx::dbgTextClear();
			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/32-particles");
			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Particles.");
			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

			// Update camera.George RR Martin
			cameraUpdate(deltaTime, m_mouseState);

			float view[16];
			cameraGetViewMtx(view);

			float proj[16];

			// Set view and projection matrix for view 0.
			const bgfx::HMD* hmd = bgfx::getHMD();
			if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
			{
				float eye[3];
				cameraGetPosition(eye);
				bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
				bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
				bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
			}
			else
			{
				bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f);

				bgfx::setViewTransform(0, view, proj);
				bgfx::setViewRect(0, 0, 0, m_width, m_height);
			}

			imguiBeginFrame(
				   m_mouseState.m_mx
				,  m_mouseState.m_my
				, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
				| (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT  : 0)
				| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
				,  m_mouseState.m_mz
				, m_width
				, m_height
				);

			ImGui::Begin("Properties"
				, NULL
				, ImVec2(400.0f, 600.0f)
				, ImGuiWindowFlags_AlwaysAutoResize
				);

			static float timeScale = 1.0f;
			ImGui::SliderFloat("Time scale"
				, &timeScale
				, 0.0f
				, 1.0f
				);

			static bool showBounds;
			ImGui::Checkbox("Show bounds", &showBounds);

			ImGui::Text("Emitter:");
			static int currentEmitter = 0;
			for (uint32_t ii = 0; ii < BX_COUNTOF(m_emitter); ++ii)
			{
				ImGui::SameLine();

				char name[16];
				bx::snprintf(name, BX_COUNTOF(name), "%d", ii);

				ImGui::RadioButton(name, &currentEmitter, ii);
			}

			m_emitter[currentEmitter].imgui(view, proj);

			imguiEndFrame();

			ddBegin(0);

			float center[3] = { 0.0f, 0.0f, 0.0f };
			ddDrawGrid(Axis::Y, center);

			float eye[3];
			cameraGetPosition(eye);

			m_emitter[currentEmitter].update();

			psUpdate(deltaTime * timeScale);
			psRender(0, view, eye);

			if (showBounds)
			{
				Aabb aabb;
				psGetAabb(m_emitter[currentEmitter].m_handle, aabb);
				ddSetColor(0xff0000ff);
				ddDraw(aabb);
			}

			ddEnd();

			// Advance to next frame. Rendering thread will be kicked to
			// process submitted rendering primitives.
			bgfx::frame();

			return true;
		}

		return false;
	}

	entry::MouseState m_mouseState;

	int64_t m_timeOffset;

	uint32_t m_width;
	uint32_t m_height;
	uint32_t m_debug;
	uint32_t m_reset;

	Emitter m_emitter[4];
};

ENTRY_IMPLEMENT_MAIN(Particles);
<|endoftext|>


<commit_before>#include "TestRcGen.h"
#include "Render/Renderable/StaticRenderable.h"
#include "Render/Renderable/StaticRenderableContainer.h"
#include "Render/Shader/Shader.h"
#include "Render/RenderCommand/RenderCommand.h"
#include "Render/Camera.h"
#include "Render/Shader/ShaderUniformUpdater.h"

namespace ve
{

class TestRenderCommand : public RenderCommand
{
public:
	TestRenderCommand(const std::shared_ptr<ShaderUniformUpdater>& uniformUpdater,
	                  const ShaderProgram& shaderProgram,
	                  const GpuMesh& gpuMesh);
	virtual ~TestRenderCommand() override;

	virtual void execute() override;

private:
	std::shared_ptr<ShaderUniformUpdater> m_uniformUpdater;
	ShaderProgram m_shaderProgram;
	GpuMesh m_gpuMesh;
};

class TestUniformUpdater : public ShaderUniformUpdater
{
public:
	TestUniformUpdater(const Camera& camera, const Matrix4f& modelMatrix);
	virtual ~TestUniformUpdater() override;

	virtual void updateUniforms(ShaderProgram& shaderProgram) const override;

private:
	Camera m_camera;
	Matrix4f m_modelMatrix;
};

}

using namespace ve;

TestRenderCommand::TestRenderCommand(const std::shared_ptr<ShaderUniformUpdater>& uniformUpdater,
                                     const ShaderProgram& shaderProgram,
                                     const GpuMesh& gpuMesh) :
	m_uniformUpdater(uniformUpdater), m_shaderProgram(shaderProgram), m_gpuMesh(gpuMesh)
{

}

TestRenderCommand::~TestRenderCommand()
{

}

void TestRenderCommand::execute()
{
	m_shaderProgram.use();

	m_uniformUpdater->updateUniforms(m_shaderProgram);

	m_gpuMesh.bind();
	m_gpuMesh.draw();
}

TestUniformUpdater::TestUniformUpdater(const Camera& camera, const Matrix4f& modelMatrix) :
	m_camera(camera), m_modelMatrix(modelMatrix)
{

}

TestUniformUpdater::~TestUniformUpdater()
{

}

void TestUniformUpdater::updateUniforms(ShaderProgram& shaderProgram) const
{
	shaderProgram.updateUniform("u_viewMatrix", m_camera.getViewMatrix());
	shaderProgram.updateUniform("u_projectionMatrix", m_camera.getProjectionMatrix());
	shaderProgram.updateUniform("u_modelMatrix", m_modelMatrix);
}

bool TestRcGen::init()
{
	m_shaderProgram.createProgram();

	Shader vertShader("./Shader/TestShader.vs");
	Shader fragShader("./Shader/TestShader.fs");
	vertShader.compile();
	fragShader.compile();

	m_shaderProgram.completeProgram(vertShader, fragShader);

	m_shaderProgram.registerUniform("u_viewMatrix");
	m_shaderProgram.registerUniform("u_projectionMatrix");
	m_shaderProgram.registerUniform("u_modelMatrix");

	return true;
}

void TestRcGen::genRenderCommands(const Camera& camera,
                                  const StaticRenderableContainer& renderables,
                                  std::vector<std::shared_ptr<RenderCommand>>* out_renderCommands) const
{
	for(uint32 x = 0; x < renderables.numStaticRenderables(); x++)
	{
		const auto& renderable = renderables.getStaticRenderable(x);
		for(uint32 i = 0; i < renderable.numMeshMaterialPairs(); i++)
		{
			const auto& meshMatlPair = renderable.getMeshMaterialPair(i);

			out_renderCommands->push_back(std::make_shared<TestRenderCommand>(std::make_shared<TestUniformUpdater>(camera, renderable.getModelMatrix()),
			                              m_shaderProgram,
			                              meshMatlPair.first));
		}
	}
}<commit_msg>lambda based uniform updater<commit_after>#include "TestRcGen.h"
#include "Render/Renderable/StaticRenderable.h"
#include "Render/Renderable/StaticRenderableContainer.h"
#include "Render/Shader/Shader.h"
#include "Render/RenderCommand/RenderCommand.h"
#include "Render/Camera.h"
#include "Render/Shader/ShaderUniformUpdater.h"

#include <functional>

namespace ve
{

class TestRenderCommand : public RenderCommand
{
public:
	TestRenderCommand(const std::function<void(ShaderProgram&)>& uniformUpdater,
	                  const ShaderProgram& shaderProgram,
	                  const GpuMesh& gpuMesh);
	virtual ~TestRenderCommand() override;

	virtual void execute() override;

private:
	std::function<void (ShaderProgram&)> m_uniformUpdater;
	ShaderProgram m_shaderProgram;
	GpuMesh m_gpuMesh;
};

}

using namespace ve;

TestRenderCommand::TestRenderCommand(const std::function<void(ShaderProgram&)>& uniformUpdater,
                                     const ShaderProgram& shaderProgram,
                                     const GpuMesh& gpuMesh) :
	m_uniformUpdater(uniformUpdater), m_shaderProgram(shaderProgram), m_gpuMesh(gpuMesh)
{

}

TestRenderCommand::~TestRenderCommand()
{

}

void TestRenderCommand::execute()
{
	m_shaderProgram.use();

	m_uniformUpdater(m_shaderProgram);

	m_gpuMesh.bind();
	m_gpuMesh.draw();
}

bool TestRcGen::init()
{
	m_shaderProgram.createProgram();

	Shader vertShader("./Shader/TestShader.vs");
	Shader fragShader("./Shader/TestShader.fs");
	vertShader.compile();
	fragShader.compile();

	m_shaderProgram.completeProgram(vertShader, fragShader);

	m_shaderProgram.registerUniform("u_viewMatrix");
	m_shaderProgram.registerUniform("u_projectionMatrix");
	m_shaderProgram.registerUniform("u_modelMatrix");

	return true;
}

void TestRcGen::genRenderCommands(const Camera& camera,
                                  const StaticRenderableContainer& renderables,
                                  std::vector<std::shared_ptr<RenderCommand>>* out_renderCommands) const
{
	for(uint32 x = 0; x < renderables.numStaticRenderables(); x++)
	{
		const auto& renderable = renderables.getStaticRenderable(x);
		for(uint32 i = 0; i < renderable.numMeshMaterialPairs(); i++)
		{
			const auto& meshMatlPair = renderable.getMeshMaterialPair(i);
			const auto& uniformUpdater = [&camera, &renderable](ShaderProgram& shaderProgram)
			{
				shaderProgram.updateUniform("u_viewMatrix", camera.getViewMatrix());
				shaderProgram.updateUniform("u_projectionMatrix", camera.getProjectionMatrix());
				shaderProgram.updateUniform("u_modelMatrix", renderable.getModelMatrix());
			};

			const auto& renderCommand = std::make_shared<TestRenderCommand>(uniformUpdater, m_shaderProgram, meshMatlPair.first);
			out_renderCommands->push_back(renderCommand);
		}
	}
}<|endoftext|>


<commit_before>/*
Copyright (C) 2015,2018 Rodrigo Jose Hernandez Cordoba

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

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

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

#include <QIcon>
#include <QFile>
#include <QMimeData>
#include <QDataStream>
#include <QByteArray>
#include <QXmlStreamWriter>
#include <QTextStream>
#include "SceneModel.h"
#include "aeongames/Tree.h"

namespace AeonGames
{
    SceneModel::SceneModel ( QObject *parent ) :
        QAbstractItemModel ( parent )
    {
    }

    SceneModel::~SceneModel() = default;

    QVariant SceneModel::headerData ( int section, Qt::Orientation orientation, int role ) const
    {
        if ( ( orientation == Qt::Horizontal ) && ( role == Qt::DisplayRole ) )
        {
            switch ( section )
            {
            case 0:
                return QString ( "Node" );
            default:
                return QVariant();
            }
        }
        return QVariant();
    }

    QModelIndex SceneModel::index ( int row, int column, const QModelIndex & parent ) const
    {
        if ( !parent.isValid() )
        {
            if ( row < static_cast<int> ( mScene.GetChildrenCount() ) )
            {
                if ( row < mScene.GetChildrenCount() )
                {
                    return createIndex ( row, column, &const_cast<SceneModel*> ( this )->mScene[row] );
                }
            }
        }
        else
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( parent.internalPointer() );
            if ( row < node->GetChildrenCount() )
            {
                return createIndex ( row, column, & ( node->GetChild ( row ) ) );
            }
        }
        return QModelIndex();
    }

    QModelIndex SceneModel::parent ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
            Tree::Node* node_parent = node->GetParent();
            if ( node_parent != nullptr )
            {
                return createIndex ( static_cast<int> ( node->GetIndex() ), 0, node_parent );
            }
        }
        return QModelIndex();
    }

    int SceneModel::rowCount ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return static_cast<int> ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetChildrenCount() );
        }
        return static_cast<int> ( mScene.GetChildrenCount() );
    }

    int SceneModel::columnCount ( const QModelIndex & index ) const
    {
        return 1;
    }

    bool SceneModel::hasChildren ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetChildrenCount() > 0 );
        }
        return ( mScene.GetChildrenCount() > 0 );
    }

    QVariant SceneModel::data ( const QModelIndex & index, int role ) const
    {
        if ( ( role == Qt::DisplayRole ) || ( role == Qt::EditRole ) )
        {
            if ( index.isValid() )
            {
                switch ( index.column() )
                {
                case 0:
                    return QString ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetName().c_str() );
                    break;
                }
            }
        }
        else if ( role == Qt::DecorationRole )
        {
            return QIcon ( ":/icons/icon_node" );
        }
        else if ( role == Qt::UserRole )
        {
            return qVariantFromValue ( index.internalPointer() );
        }
        return QVariant();
    }

    Qt::ItemFlags SceneModel::flags ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return QAbstractItemModel::flags ( index ) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
        }
        return QAbstractItemModel::flags ( index ) | Qt::ItemIsDropEnabled;
    }

    bool SceneModel::setData ( const QModelIndex & index, const QVariant & value, int role )
    {
        Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
        if  ( role == Qt::EditRole )
        {
            node->SetName ( value.toString().toUtf8().constData() );
            emit dataChanged ( index, index );
            return true;
        }
        return false;
    }

    bool SceneModel::moveRows ( const QModelIndex & sourceParent, int sourceRow, int count, const QModelIndex & destinationParent, int destinationRow )
    {
        if ( sourceParent.isValid() && destinationParent.isValid() )
        {
            // Moving between nodes
            Tree::Node* source = reinterpret_cast<Tree::Node*> ( sourceParent.internalPointer() );
            Tree::Node* destination = reinterpret_cast<Tree::Node*> ( destinationParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    auto node = source->GetChild ( sourceRow );
                    destination->Move ( destinationRow + i, std::move ( *source ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else if ( sourceParent.isValid() )
        {
            // Moving from a node to the scene
            Tree::Node* source = reinterpret_cast<Tree::Node*> ( sourceParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    auto node = source->GetChild ( sourceRow );
                    mScene.Move ( destinationRow, std::move ( *source ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else if ( destinationParent.isValid() )
        {
            // Moving from the scene to a node
            Tree::Node* destination = reinterpret_cast<Tree::Node*> ( destinationParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    Tree::Node* node = &mScene.GetChild ( sourceRow );
                    destination->Move ( destinationRow, std::move ( *node ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else
        {
            /* This is the case when a row is moved up or down directly at the scene*/
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    Tree::Node* node = &mScene.GetChild ( sourceRow );
                    mScene.Move ( destinationRow, std::move ( *node ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        return true;
    }

    Qt::DropActions SceneModel::supportedDropActions() const
    {
        return Qt::MoveAction;
    }

    bool SceneModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
    {
        QString format ( "application/x-aeon-editor-node" );
        // check if the action is supported
        if ( !data || ( action != Qt::MoveAction ) )
        {
            return false;
        }
        // check if the format is supported
        if ( !data->hasFormat ( format ) )
        {
            return false;
        }
        if ( ( row > rowCount ( parent ) ) || ( row < 0 ) )
        {
            row = rowCount ( parent );
        }
        QByteArray byteArray = data->data ( format );
        QDataStream dataStream ( &byteArray, QIODevice::ReadOnly );
        int count;
        dataStream >> count;
        for ( int i = 0; i < count; ++i )
        {
            Tree::Node* pointer;
            dataStream.readRawData ( reinterpret_cast<char*> ( &pointer ), sizeof ( void* ) );
            QModelIndex model_index = createIndex ( static_cast<int> ( pointer->GetIndex() ), 0, pointer );
            moveRow ( this->parent ( model_index ), static_cast<int> ( pointer->GetIndex() ), parent, row );
        }
        return true;
    }

    QMimeData * SceneModel::mimeData ( const QModelIndexList & indexes ) const
    {
        QMimeData* data = nullptr;
        if ( !indexes.isEmpty() )
        {
            QByteArray byteArray;
            byteArray.reserve ( ( indexes.count() + 1 ) *sizeof ( void* ) );
            QDataStream dataStream ( &byteArray, QIODevice::WriteOnly );
            dataStream << indexes.count();
            for ( auto i = indexes.cbegin(); i != indexes.cend(); ++i )
            {
                void* pointer = ( *i ).internalPointer();
                dataStream.writeRawData ( reinterpret_cast<char*> ( &pointer ), sizeof ( void* ) );
            }
            QStringList types = mimeTypes();
            data = new QMimeData();
            data->setData ( types[0], byteArray );
        }
        return data;
    }

    QStringList SceneModel::mimeTypes() const
    {
        QStringList types;
        types << "application/x-aeon-editor-node";
        return types;
    }

    void SceneModel::InsertNode ( int row, const QModelIndex & parent )
    {
        beginResetModel();
        if ( parent.isValid() )
        {
            reinterpret_cast<Tree::Node*> ( parent.internalPointer() )->Insert ( row, {} );
        }
        else
        {
            mScene.Insert ( row, {} );
        }
        endResetModel();
    }

    void SceneModel::RemoveNode ( const QModelIndex & index )
    {
        beginResetModel();
        if ( index.isValid() )
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
            Tree::Node* parent = node->GetParent();
            if ( parent )
            {
                parent->Erase ( *node );
            }
            else
            {
                mScene.Erase ( *node );
            }
        }
        endResetModel();
    }

    const Tree& SceneModel::GetScene() const
    {
        return mScene;
    }
}
<commit_msg>Fix Linux build.<commit_after>/*
Copyright (C) 2015,2018 Rodrigo Jose Hernandez Cordoba

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

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

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

#include <QIcon>
#include <QFile>
#include <QMimeData>
#include <QDataStream>
#include <QByteArray>
#include <QXmlStreamWriter>
#include <QTextStream>
#include "SceneModel.h"
#include "aeongames/Tree.h"

namespace AeonGames
{
    SceneModel::SceneModel ( QObject *parent ) :
        QAbstractItemModel ( parent )
    {
    }

    SceneModel::~SceneModel() = default;

    QVariant SceneModel::headerData ( int section, Qt::Orientation orientation, int role ) const
    {
        if ( ( orientation == Qt::Horizontal ) && ( role == Qt::DisplayRole ) )
        {
            switch ( section )
            {
            case 0:
                return QString ( "Node" );
            default:
                return QVariant();
            }
        }
        return QVariant();
    }

    QModelIndex SceneModel::index ( int row, int column, const QModelIndex & parent ) const
    {
        if ( !parent.isValid() )
        {
            if ( row < static_cast<int> ( mScene.GetChildrenCount() ) )
            {
                return createIndex ( row, column, &const_cast<SceneModel*> ( this )->mScene[row] );
            }
        }
        else
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( parent.internalPointer() );
            if ( row < static_cast<int> ( node->GetChildrenCount() ) )
            {
                return createIndex ( row, column, & ( node->GetChild ( row ) ) );
            }
        }
        return QModelIndex();
    }

    QModelIndex SceneModel::parent ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
            Tree::Node* node_parent = node->GetParent();
            if ( node_parent != nullptr )
            {
                return createIndex ( static_cast<int> ( node->GetIndex() ), 0, node_parent );
            }
        }
        return QModelIndex();
    }

    int SceneModel::rowCount ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return static_cast<int> ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetChildrenCount() );
        }
        return static_cast<int> ( mScene.GetChildrenCount() );
    }

    int SceneModel::columnCount ( const QModelIndex & index ) const
    {
        return 1;
    }

    bool SceneModel::hasChildren ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetChildrenCount() > 0 );
        }
        return ( mScene.GetChildrenCount() > 0 );
    }

    QVariant SceneModel::data ( const QModelIndex & index, int role ) const
    {
        if ( ( role == Qt::DisplayRole ) || ( role == Qt::EditRole ) )
        {
            if ( index.isValid() )
            {
                switch ( index.column() )
                {
                case 0:
                    return QString ( reinterpret_cast<Tree::Node*> ( index.internalPointer() )->GetName().c_str() );
                    break;
                }
            }
        }
        else if ( role == Qt::DecorationRole )
        {
            return QIcon ( ":/icons/icon_node" );
        }
        else if ( role == Qt::UserRole )
        {
            return qVariantFromValue ( index.internalPointer() );
        }
        return QVariant();
    }

    Qt::ItemFlags SceneModel::flags ( const QModelIndex & index ) const
    {
        if ( index.isValid() )
        {
            return QAbstractItemModel::flags ( index ) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
        }
        return QAbstractItemModel::flags ( index ) | Qt::ItemIsDropEnabled;
    }

    bool SceneModel::setData ( const QModelIndex & index, const QVariant & value, int role )
    {
        Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
        if  ( role == Qt::EditRole )
        {
            node->SetName ( value.toString().toUtf8().constData() );
            emit dataChanged ( index, index );
            return true;
        }
        return false;
    }

    bool SceneModel::moveRows ( const QModelIndex & sourceParent, int sourceRow, int count, const QModelIndex & destinationParent, int destinationRow )
    {
        if ( sourceParent.isValid() && destinationParent.isValid() )
        {
            // Moving between nodes
            Tree::Node* source = reinterpret_cast<Tree::Node*> ( sourceParent.internalPointer() );
            Tree::Node* destination = reinterpret_cast<Tree::Node*> ( destinationParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    auto node = source->GetChild ( sourceRow );
                    destination->Move ( destinationRow + i, std::move ( *source ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else if ( sourceParent.isValid() )
        {
            // Moving from a node to the scene
            Tree::Node* source = reinterpret_cast<Tree::Node*> ( sourceParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    auto node = source->GetChild ( sourceRow );
                    mScene.Move ( destinationRow, std::move ( *source ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else if ( destinationParent.isValid() )
        {
            // Moving from the scene to a node
            Tree::Node* destination = reinterpret_cast<Tree::Node*> ( destinationParent.internalPointer() );
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    Tree::Node* node = &mScene.GetChild ( sourceRow );
                    destination->Move ( destinationRow, std::move ( *node ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        else
        {
            /* This is the case when a row is moved up or down directly at the scene*/
            if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
            {
                for ( int i = 0; i < count; ++i )
                {
                    Tree::Node* node = &mScene.GetChild ( sourceRow );
                    mScene.Move ( destinationRow, std::move ( *node ) );
                }
                endMoveRows();
            }
            else
            {
                return false;
            }
        }
        return true;
    }

    Qt::DropActions SceneModel::supportedDropActions() const
    {
        return Qt::MoveAction;
    }

    bool SceneModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
    {
        QString format ( "application/x-aeon-editor-node" );
        // check if the action is supported
        if ( !data || ( action != Qt::MoveAction ) )
        {
            return false;
        }
        // check if the format is supported
        if ( !data->hasFormat ( format ) )
        {
            return false;
        }
        if ( ( row > rowCount ( parent ) ) || ( row < 0 ) )
        {
            row = rowCount ( parent );
        }
        QByteArray byteArray = data->data ( format );
        QDataStream dataStream ( &byteArray, QIODevice::ReadOnly );
        int count;
        dataStream >> count;
        for ( int i = 0; i < count; ++i )
        {
            Tree::Node* pointer;
            dataStream.readRawData ( reinterpret_cast<char*> ( &pointer ), sizeof ( void* ) );
            QModelIndex model_index = createIndex ( static_cast<int> ( pointer->GetIndex() ), 0, pointer );
            moveRow ( this->parent ( model_index ), static_cast<int> ( pointer->GetIndex() ), parent, row );
        }
        return true;
    }

    QMimeData * SceneModel::mimeData ( const QModelIndexList & indexes ) const
    {
        QMimeData* data = nullptr;
        if ( !indexes.isEmpty() )
        {
            QByteArray byteArray;
            byteArray.reserve ( ( indexes.count() + 1 ) *sizeof ( void* ) );
            QDataStream dataStream ( &byteArray, QIODevice::WriteOnly );
            dataStream << indexes.count();
            for ( auto i = indexes.cbegin(); i != indexes.cend(); ++i )
            {
                void* pointer = ( *i ).internalPointer();
                dataStream.writeRawData ( reinterpret_cast<char*> ( &pointer ), sizeof ( void* ) );
            }
            QStringList types = mimeTypes();
            data = new QMimeData();
            data->setData ( types[0], byteArray );
        }
        return data;
    }

    QStringList SceneModel::mimeTypes() const
    {
        QStringList types;
        types << "application/x-aeon-editor-node";
        return types;
    }

    void SceneModel::InsertNode ( int row, const QModelIndex & parent )
    {
        beginResetModel();
        if ( parent.isValid() )
        {
            reinterpret_cast<Tree::Node*> ( parent.internalPointer() )->Insert ( row, {} );
        }
        else
        {
            mScene.Insert ( row, {} );
        }
        endResetModel();
    }

    void SceneModel::RemoveNode ( const QModelIndex & index )
    {
        beginResetModel();
        if ( index.isValid() )
        {
            Tree::Node* node = reinterpret_cast<Tree::Node*> ( index.internalPointer() );
            Tree::Node* parent = node->GetParent();
            if ( parent )
            {
                parent->Erase ( *node );
            }
            else
            {
                mScene.Erase ( *node );
            }
        }
        endResetModel();
    }

    const Tree& SceneModel::GetScene() const
    {
        return mScene;
    }
}
<|endoftext|>


<commit_before><commit_msg>found typo, gave false positive results - triangles no longer work<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cppdep.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:28:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <unistd.h>

#include <sys/stat.h>
#include <stream.hxx>
#include "cppdep.hxx"

//#define TEST

CppDep::CppDep( ByteString aFileName )
{
    aSourceFile = aFileName;

    pSearchPath = new ByteStringList;
    pFileList = new ByteStringList;
}

CppDep::CppDep()
{
    pSources = new ByteStringList;
    pSearchPath = new ByteStringList;
    pFileList = new ByteStringList;
}

CppDep::~CppDep()
{
    delete pSearchPath;
    delete pFileList;
}

void CppDep::Execute()
{
    ULONG nCount = pSources->Count();
    for ( ULONG n=0; n<nCount;n++)
    {
        ByteString *pStr = pSources->GetObject(n);
        Search( *pStr );
    }
}

BOOL CppDep::AddSearchPath( const char* aPath )
{
    ByteString *pStr = new ByteString( aPath );
    pSearchPath->Insert( pStr, LIST_APPEND );
    return FALSE;
}

BOOL CppDep::AddSource( const char* aSource )
{
    ByteString *pStr = new ByteString( aSource );
    pSources->Insert( pStr, LIST_APPEND );
    return FALSE;
}

BOOL CppDep::Search( ByteString aFileName )
{
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "SEARCH : %s\n", aFileName.GetBuffer());
#endif
    BOOL bRet = FALSE;

    SvFileStream aFile;
    ByteString aReadLine;

    UniString suFileName( aFileName, gsl_getSystemTextEncoding());

    aFile.Open( suFileName, STREAM_READ );
    while ( aFile.ReadLine( aReadLine ))
    {
        USHORT nPos;
        if ( nPos = aReadLine.Search( "include" ) != STRING_NOTFOUND  )
        {
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "found : %d %s\n", nPos, aReadLine.GetBuffer() );
#endif
            ByteString aResult = IsIncludeStatement( aReadLine );
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "Result : %s\n", aResult.GetBuffer() );
#endif

            ByteString aNewFile;
            if ( aResult !="")
            if ( (aNewFile = Exists( aResult )) != "" )
            {
                BOOL bFound = FALSE;
                ULONG nCount = pFileList->Count();
                for ( ULONG i=0; i<nCount; i++ )
                {
                    ByteString *pStr = pFileList->GetObject(i);
                    if ( *pStr == aNewFile )
                        bFound = TRUE;
                }
#ifdef DEBUG_VERBOSE
                fprintf( stderr, "not in list : %d %s\n", nPos, aReadLine.GetBuffer() );
#endif
                if ( !bFound )
                {
                    pFileList->Insert( new ByteString( aNewFile ), LIST_APPEND );
#ifdef DEBUG_VERBOSE
                    fprintf( stderr, " CppDep %s\\\n", aNewFile.GetBuffer() );
#endif
                    Search(aNewFile);
                }
            }
        }
    }
    aFile.Close();

    return bRet;
}

ByteString CppDep::Exists( ByteString aFileName )
{
    char pFullName[1023];
    ByteString aString;

#ifdef DEBUG_VERBOSE
    fprintf( stderr, "Searching %s \n", aFileName.GetBuffer() );
#endif

    ULONG nCount = pSearchPath->Count();
    for ( ULONG n=0; n<nCount; n++)
    {
        struct stat aBuf;
        ByteString *pPathName = pSearchPath->GetObject(n);

        strcpy( pFullName, pPathName->GetBuffer());
        strcat( pFullName, DIR_SEP );
        strcat( pFullName, aFileName.GetBuffer());

#ifdef DEBUG_VERBOSE
        fprintf( stderr, "looking for %s\t ", pFullName );
#endif
        if ( stat( pFullName, &aBuf ) == 0 )
        {
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "Got Dependency ", pFullName );
#endif
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "%s \\\n", pFullName );
#endif

            return ByteString(pFullName);
        }
    }
    return aString;
}

ByteString CppDep::IsIncludeStatement( ByteString aLine )
{
    ByteString aRetStr;
    // WhiteSpacesfressen
    aLine.EraseAllChars(' ');
    aLine.EraseAllChars('\t');
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "now : %s\n", aLine.GetBuffer() );
#endif
    // ist der erste Teil ein #include ?
    ByteString aTmpStr;
    aTmpStr = aLine.Copy( 0, 8 );
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "is include : %s\n", aTmpStr.GetBuffer() );
#endif
    if ( aTmpStr.Equals("#include") )
    {
        aTmpStr = aLine.Erase( 0, 8 );
        USHORT nLen = aLine.Len();
        aLine.Erase( nLen-1, 1 );
        aLine.Erase( 0, 1 );
#ifdef DEBUG_VERBOSE
        fprintf( stderr, "Gotcha : %s\n", aLine.GetBuffer() );
#endif
        aRetStr = aLine;
    }
    return aRetStr;
}

#ifdef TEST

int main( int argc, char **argv )
{
    CppDep *pDep = new CppDep( "cppdep.cxx" );
    pDep->AddSearchPath(".");
    pDep->AddSearchPath("/usr/include");
    pDep->AddSearchPath("/usr/local/include");
    pDep->AddSearchPath("/usr/include/sys");
    pDep->AddSearchPath("/usr/include/X11");
    pDep->Execute();
    delete pDep;
    return 0;
}

#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.11.8); FILE MERGED 2006/02/24 14:48:16 sb 1.11.8.1: #i53898# Made code warning-free; removed dead code.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cppdep.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 13:19:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <unistd.h>

#include <sys/stat.h>
#include <stream.hxx>
#include "cppdep.hxx"

//#define TEST

CppDep::CppDep( ByteString aFileName )
{
    aSourceFile = aFileName;

    pSearchPath = new ByteStringList;
    pFileList = new ByteStringList;
}

CppDep::CppDep()
{
    pSources = new ByteStringList;
    pSearchPath = new ByteStringList;
    pFileList = new ByteStringList;
}

CppDep::~CppDep()
{
    delete pSearchPath;
    delete pFileList;
}

void CppDep::Execute()
{
    ULONG nCount = pSources->Count();
    for ( ULONG n=0; n<nCount;n++)
    {
        ByteString *pStr = pSources->GetObject(n);
        Search( *pStr );
    }
}

BOOL CppDep::AddSearchPath( const char* aPath )
{
    ByteString *pStr = new ByteString( aPath );
    pSearchPath->Insert( pStr, LIST_APPEND );
    return FALSE;
}

BOOL CppDep::AddSource( const char* aSource )
{
    ByteString *pStr = new ByteString( aSource );
    pSources->Insert( pStr, LIST_APPEND );
    return FALSE;
}

BOOL CppDep::Search( ByteString aFileName )
{
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "SEARCH : %s\n", aFileName.GetBuffer());
#endif
    BOOL bRet = FALSE;

    SvFileStream aFile;
    ByteString aReadLine;

    UniString suFileName( aFileName, gsl_getSystemTextEncoding());

    aFile.Open( suFileName, STREAM_READ );
    while ( aFile.ReadLine( aReadLine ))
    {
        USHORT nPos = aReadLine.Search( "include" );
        if ( nPos != STRING_NOTFOUND  )
        {
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "found : %d %s\n", nPos, aReadLine.GetBuffer() );
#endif
            ByteString aResult = IsIncludeStatement( aReadLine );
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "Result : %s\n", aResult.GetBuffer() );
#endif

            ByteString aNewFile;
            if ( aResult !="")
            if ( (aNewFile = Exists( aResult )) != "" )
            {
                BOOL bFound = FALSE;
                ULONG nCount = pFileList->Count();
                for ( ULONG i=0; i<nCount; i++ )
                {
                    ByteString *pStr = pFileList->GetObject(i);
                    if ( *pStr == aNewFile )
                        bFound = TRUE;
                }
#ifdef DEBUG_VERBOSE
                fprintf( stderr, "not in list : %d %s\n", nPos, aReadLine.GetBuffer() );
#endif
                if ( !bFound )
                {
                    pFileList->Insert( new ByteString( aNewFile ), LIST_APPEND );
#ifdef DEBUG_VERBOSE
                    fprintf( stderr, " CppDep %s\\\n", aNewFile.GetBuffer() );
#endif
                    Search(aNewFile);
                }
            }
        }
    }
    aFile.Close();

    return bRet;
}

ByteString CppDep::Exists( ByteString aFileName )
{
    char pFullName[1023];
    ByteString aString;

#ifdef DEBUG_VERBOSE
    fprintf( stderr, "Searching %s \n", aFileName.GetBuffer() );
#endif

    ULONG nCount = pSearchPath->Count();
    for ( ULONG n=0; n<nCount; n++)
    {
        struct stat aBuf;
        ByteString *pPathName = pSearchPath->GetObject(n);

        strcpy( pFullName, pPathName->GetBuffer());
        strcat( pFullName, DIR_SEP );
        strcat( pFullName, aFileName.GetBuffer());

#ifdef DEBUG_VERBOSE
        fprintf( stderr, "looking for %s\t ", pFullName );
#endif
        if ( stat( pFullName, &aBuf ) == 0 )
        {
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "Got Dependency ", pFullName );
#endif
#ifdef DEBUG_VERBOSE
            fprintf( stderr, "%s \\\n", pFullName );
#endif

            return ByteString(pFullName);
        }
    }
    return aString;
}

ByteString CppDep::IsIncludeStatement( ByteString aLine )
{
    ByteString aRetStr;
    // WhiteSpacesfressen
    aLine.EraseAllChars(' ');
    aLine.EraseAllChars('\t');
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "now : %s\n", aLine.GetBuffer() );
#endif
    // ist der erste Teil ein #include ?
    ByteString aTmpStr;
    aTmpStr = aLine.Copy( 0, 8 );
#ifdef DEBUG_VERBOSE
    fprintf( stderr, "is include : %s\n", aTmpStr.GetBuffer() );
#endif
    if ( aTmpStr.Equals("#include") )
    {
        aTmpStr = aLine.Erase( 0, 8 );
        USHORT nLen = aLine.Len();
        aLine.Erase( nLen-1, 1 );
        aLine.Erase( 0, 1 );
#ifdef DEBUG_VERBOSE
        fprintf( stderr, "Gotcha : %s\n", aLine.GetBuffer() );
#endif
        aRetStr = aLine;
    }
    return aRetStr;
}

#ifdef TEST

int main( int argc, char **argv )
{
    CppDep *pDep = new CppDep( "cppdep.cxx" );
    pDep->AddSearchPath(".");
    pDep->AddSearchPath("/usr/include");
    pDep->AddSearchPath("/usr/local/include");
    pDep->AddSearchPath("/usr/include/sys");
    pDep->AddSearchPath("/usr/include/X11");
    pDep->Execute();
    delete pDep;
    return 0;
}

#endif
<|endoftext|>