<commit_before>/** @file propertyeditorproxymodel.cpp
 *	@brief Модель редактора свойств
 * */
#include <QtCore/QDebug>

#include "../../qrkernel/exception/exception.h"

#include "propertyEditorProxyModel.h"

using namespace qReal;

PropertyEditorModel::PropertyEditorModel(qReal::EditorManager const &editorManager,
		QObject *parent)
	: QAbstractTableModel(parent)
	, mTargetLogicalModel(NULL)
	, mTargetGraphicalModel(NULL)
	, mEditorManager(editorManager)
{
}

int PropertyEditorModel::rowCount(const QModelIndex&) const
{
	return mFields.size();
}

int PropertyEditorModel::columnCount(const QModelIndex&) const
{
	return 2;
}

Qt::ItemFlags PropertyEditorModel::flags(QModelIndex const &index) const
{
	// Property names
	if (index.column() == 0)
		return Qt::ItemIsEnabled;

	switch (mFields[index.row()].attributeClass) {
	case logicalAttribute:
	case graphicalAttribute:
	case namePseudoattribute:
		return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
	case graphicalIdPseudoattribute:
	case logicalIdPseudoattribute:
	case metatypePseudoattribute:
	default:
		return Qt::NoItemFlags;
	}
}

QVariant PropertyEditorModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
		return QString(section == 1 ? "value" : "name");
	else
		return QVariant();
}

QVariant PropertyEditorModel::data(QModelIndex const &index, int role) const
{
	if (!isValid())
		return QVariant();

	if (role == Qt::ToolTipRole) {
		if (index.column() == 0) {
			Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
			QString const description = mEditorManager.propertyDescription(id, mFields[index.row()].fieldName);
			if (!description.isEmpty())
				return "<body>" + description;
			else
				return QVariant();
		} else if (index.column() == 1)
			return data(index, Qt::DisplayRole);
		else
			return QVariant();
	}

	if (role != Qt::DisplayRole)
		return QVariant();

	if (index.column() == 0) {
		Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
		QString const displayedName = mEditorManager.propertyDisplayedName(id, mFields[index.row()].fieldName);
		return displayedName.isEmpty() ? mFields[index.row()].fieldName : displayedName;
	} else if (index.column() == 1) {
		switch (mFields[index.row()].attributeClass) {
		case logicalAttribute:
			return mTargetLogicalObject.data(mFields[index.row()].role);
		case graphicalAttribute:
			return mTargetGraphicalObject.data(mFields[index.row()].role);
		case graphicalIdPseudoattribute:
			return mTargetGraphicalObject.data(roles::idRole).value<Id>().id();
		case logicalIdPseudoattribute:
			return mTargetLogicalObject.data(roles::idRole).value<Id>().id();
		case metatypePseudoattribute: {
			Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
			return QVariant(id.editor() + "/" + id.diagram() + "/" + id.element());
		}
		case namePseudoattribute:
			return mTargetLogicalObject.data(Qt::DisplayRole);
		}
		return QVariant();
	} else
		return QVariant();
}

bool PropertyEditorModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	bool modelChanged = true;

	if (!isValid())
		return false;

	if ((role == Qt::DisplayRole || role == Qt::EditRole) && index.column() == 1) {
		switch (mFields[index.row()].attributeClass) {
		case logicalAttribute:
			mTargetLogicalModel->setData(mTargetLogicalObject, value, mFields[index.row()].role);
			break;
		case graphicalAttribute:
			mTargetGraphicalModel->setData(mTargetGraphicalObject, value, mFields[index.row()].role);
			break;
		case namePseudoattribute:
			mTargetLogicalModel->setData(mTargetLogicalObject, value, Qt::DisplayRole);
			break;
		default:
			modelChanged = false;
		}
	}
	else
		modelChanged = false;

	if (modelChanged)
		dataChanged(index, index);

	return modelChanged;
}

QStringList PropertyEditorModel::enumValues(const QModelIndex &index) const
{
	if (!index.isValid())
		return QStringList();

	AttributeClassEnum const attrClass = mFields[index.row()].attributeClass;
	if (attrClass != logicalAttribute && attrClass != graphicalAttribute)  // metatype, ids and name are definitely not enums
		return QStringList();

	Id const id = attrClass == logicalAttribute
			? mTargetLogicalObject.data(roles::idRole).value<Id>()
			: mTargetGraphicalObject.data(roles::idRole).value<Id>();

	return mEditorManager.getEnumValues(id, mFields[index.row()].fieldName);
}

//QString PropertyEditorModel::typeName(const QModelIndex &index) const
//{
//	model::Model *im = const_cast<model::Model *>(static_cast<model::Model const *>(targetModel));
//	if (im){
//		return im->getTypeName(targetObject, roleByIndex(index.row()));
//	}
//	return QString();
//}

void PropertyEditorModel::rereadData(QModelIndex const &topLeftIndex, QModelIndex const &bottomRightIndex)
{
	emit dataChanged(topLeftIndex, bottomRightIndex);
//	reset();
}

void PropertyEditorModel::setSourceModels(QAbstractItemModel * const sourceLogicalModel
		, QAbstractItemModel * const sourceGraphicalModel)
{
	mTargetLogicalModel = sourceLogicalModel;
	mTargetGraphicalModel = sourceGraphicalModel;

	mFields.clear();

	if (mTargetLogicalModel)
		connect(mTargetLogicalModel, SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)),
				this, SLOT(rereadData(QModelIndex const &, QModelIndex const &)));

	if (mTargetGraphicalModel)
		connect(mTargetGraphicalModel, SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)),
				this, SLOT(rereadData(QModelIndex const &, QModelIndex const &)));

	reset();
}

void PropertyEditorModel::setModelIndexes(QModelIndex const &logicalModelIndex
		, QModelIndex const &graphicalModelIndex)
{
	mFields.clear();

	mTargetLogicalObject = logicalModelIndex;
	mTargetGraphicalObject = graphicalModelIndex;

	if (!isValid()) {
		reset();
		return;
	}

	mFields << Field(tr("Name"), namePseudoattribute);

	if (logicalModelIndex != QModelIndex()) {
		Id const logicalId = mTargetLogicalObject.data(roles::idRole).value<Id>();
		QStringList const logicalProperties = mEditorManager.getPropertyNames(logicalId.type());
		int role = roles::customPropertiesBeginRole;
		foreach (QString property, logicalProperties) {
			mFields << Field(property, logicalAttribute, role);
			++role;
		}
		// Ids and metatype commented out as they shall not be visible to user, uncomment for debugging.
//		mFields << Field(tr("Logical Id"), logicalIdPseudoattribute);
	}

	// There are no custom attributes for graphical objects, but they shall be
	// added soon.
//	if (graphicalModelIndex != QModelIndex()) {
//		mFields << Field(tr("Graphical Id"), graphicalIdPseudoattribute);
//	}

//	mFields << Field(tr("Metatype"), metatypePseudoattribute);

	reset();
}

void PropertyEditorModel::clearModelIndexes()
{
	setModelIndexes(QModelIndex(), QModelIndex());
}

bool PropertyEditorModel::isCurrentIndex(QModelIndex const &index) const
{
	return index == mTargetLogicalObject || index == mTargetGraphicalObject;
}

bool PropertyEditorModel::isValid() const
{
	return mTargetGraphicalModel && mTargetLogicalModel
			&& (mTargetLogicalObject.isValid() || mTargetGraphicalObject.isValid());
}

QModelIndex PropertyEditorModel::modelIndex(int row) const
{
	switch (mFields[row].attributeClass) {
	case logicalAttribute:
		return mTargetLogicalObject;
	case graphicalAttribute:
		return mTargetGraphicalObject;
	default:
		throw Exception("PropertyEditorModel::modelIndex: called for incorrect field, which is not graphical nor logical attribute");
	}
	return QModelIndex();
}

int PropertyEditorModel::roleByIndex(int row) const
{
	return mFields[row].role;
}

QString PropertyEditorModel::typeName(QModelIndex const &index) const
{
	Id id;
	switch (mFields[index.row()].attributeClass) {
	case logicalAttribute:
		id = mTargetLogicalObject.data(roles::idRole).value<Id>();
		break;
	case graphicalAttribute:
		id = mTargetGraphicalObject.data(roles::idRole).value<Id>();
	default:
		return "";  // Non-logical and non-graphical attributes have no type by default
	}
	return mEditorManager.getTypeName(id, mFields[index.row()].fieldName);
}
<commit_msg>для единообразия свойство "Имя" в метаредакторе переименовано в "name"<commit_after>/** @file propertyeditorproxymodel.cpp
 *	@brief Модель редактора свойств
 * */
#include <QtCore/QDebug>

#include "../../qrkernel/exception/exception.h"

#include "propertyEditorProxyModel.h"

using namespace qReal;

PropertyEditorModel::PropertyEditorModel(qReal::EditorManager const &editorManager,
		QObject *parent)
	: QAbstractTableModel(parent)
	, mTargetLogicalModel(NULL)
	, mTargetGraphicalModel(NULL)
	, mEditorManager(editorManager)
{
}

int PropertyEditorModel::rowCount(const QModelIndex&) const
{
	return mFields.size();
}

int PropertyEditorModel::columnCount(const QModelIndex&) const
{
	return 2;
}

Qt::ItemFlags PropertyEditorModel::flags(QModelIndex const &index) const
{
	// Property names
	if (index.column() == 0)
		return Qt::ItemIsEnabled;

	switch (mFields[index.row()].attributeClass) {
	case logicalAttribute:
	case graphicalAttribute:
	case namePseudoattribute:
		return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
	case graphicalIdPseudoattribute:
	case logicalIdPseudoattribute:
	case metatypePseudoattribute:
	default:
		return Qt::NoItemFlags;
	}
}

QVariant PropertyEditorModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
		return QString(section == 1 ? "value" : "name");
	else
		return QVariant();
}

QVariant PropertyEditorModel::data(QModelIndex const &index, int role) const
{
	if (!isValid())
		return QVariant();

	if (role == Qt::ToolTipRole) {
		if (index.column() == 0) {
			Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
			QString const description = mEditorManager.propertyDescription(id, mFields[index.row()].fieldName);
			if (!description.isEmpty())
				return "<body>" + description;
			else
				return QVariant();
		} else if (index.column() == 1)
			return data(index, Qt::DisplayRole);
		else
			return QVariant();
	}

	if (role != Qt::DisplayRole)
		return QVariant();

	if (index.column() == 0) {
		Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
		QString const displayedName = mEditorManager.propertyDisplayedName(id, mFields[index.row()].fieldName);
		return displayedName.isEmpty() ? mFields[index.row()].fieldName : displayedName;
	} else if (index.column() == 1) {
		switch (mFields[index.row()].attributeClass) {
		case logicalAttribute:
			return mTargetLogicalObject.data(mFields[index.row()].role);
		case graphicalAttribute:
			return mTargetGraphicalObject.data(mFields[index.row()].role);
		case graphicalIdPseudoattribute:
			return mTargetGraphicalObject.data(roles::idRole).value<Id>().id();
		case logicalIdPseudoattribute:
			return mTargetLogicalObject.data(roles::idRole).value<Id>().id();
		case metatypePseudoattribute: {
			Id const id = mTargetLogicalObject.data(roles::idRole).value<Id>();
			return QVariant(id.editor() + "/" + id.diagram() + "/" + id.element());
		}
		case namePseudoattribute:
			return mTargetLogicalObject.data(Qt::DisplayRole);
		}
		return QVariant();
	} else
		return QVariant();
}

bool PropertyEditorModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	bool modelChanged = true;

	if (!isValid())
		return false;

	if ((role == Qt::DisplayRole || role == Qt::EditRole) && index.column() == 1) {
		switch (mFields[index.row()].attributeClass) {
		case logicalAttribute:
			mTargetLogicalModel->setData(mTargetLogicalObject, value, mFields[index.row()].role);
			break;
		case graphicalAttribute:
			mTargetGraphicalModel->setData(mTargetGraphicalObject, value, mFields[index.row()].role);
			break;
		case namePseudoattribute:
			mTargetLogicalModel->setData(mTargetLogicalObject, value, Qt::DisplayRole);
			break;
		default:
			modelChanged = false;
		}
	}
	else
		modelChanged = false;

	if (modelChanged)
		dataChanged(index, index);

	return modelChanged;
}

QStringList PropertyEditorModel::enumValues(const QModelIndex &index) const
{
	if (!index.isValid())
		return QStringList();

	AttributeClassEnum const attrClass = mFields[index.row()].attributeClass;
	if (attrClass != logicalAttribute && attrClass != graphicalAttribute)  // metatype, ids and name are definitely not enums
		return QStringList();

	Id const id = attrClass == logicalAttribute
			? mTargetLogicalObject.data(roles::idRole).value<Id>()
			: mTargetGraphicalObject.data(roles::idRole).value<Id>();

	return mEditorManager.getEnumValues(id, mFields[index.row()].fieldName);
}

//QString PropertyEditorModel::typeName(const QModelIndex &index) const
//{
//	model::Model *im = const_cast<model::Model *>(static_cast<model::Model const *>(targetModel));
//	if (im){
//		return im->getTypeName(targetObject, roleByIndex(index.row()));
//	}
//	return QString();
//}

void PropertyEditorModel::rereadData(QModelIndex const &topLeftIndex, QModelIndex const &bottomRightIndex)
{
	emit dataChanged(topLeftIndex, bottomRightIndex);
//	reset();
}

void PropertyEditorModel::setSourceModels(QAbstractItemModel * const sourceLogicalModel
		, QAbstractItemModel * const sourceGraphicalModel)
{
	mTargetLogicalModel = sourceLogicalModel;
	mTargetGraphicalModel = sourceGraphicalModel;

	mFields.clear();

	if (mTargetLogicalModel)
		connect(mTargetLogicalModel, SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)),
				this, SLOT(rereadData(QModelIndex const &, QModelIndex const &)));

	if (mTargetGraphicalModel)
		connect(mTargetGraphicalModel, SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)),
				this, SLOT(rereadData(QModelIndex const &, QModelIndex const &)));

	reset();
}

void PropertyEditorModel::setModelIndexes(QModelIndex const &logicalModelIndex
		, QModelIndex const &graphicalModelIndex)
{
	mFields.clear();

	mTargetLogicalObject = logicalModelIndex;
	mTargetGraphicalObject = graphicalModelIndex;

	if (!isValid()) {
		reset();
		return;
	}

	Id const logicalId = mTargetLogicalObject.data(roles::idRole).value<Id>();
	if (logicalId.editor() == "MetaEditor") {
		mFields << Field("name", namePseudoattribute);
	} else {
		mFields << Field(tr("Name"), namePseudoattribute);
	}

	if (logicalModelIndex != QModelIndex()) {
		QStringList const logicalProperties = mEditorManager.getPropertyNames(logicalId.type());
		int role = roles::customPropertiesBeginRole;
		foreach (QString property, logicalProperties) {
			mFields << Field(property, logicalAttribute, role);
			++role;
		}
		// Ids and metatype commented out as they shall not be visible to user, uncomment for debugging.
//		mFields << Field(tr("Logical Id"), logicalIdPseudoattribute);
	}

	// There are no custom attributes for graphical objects, but they shall be
	// added soon.
//	if (graphicalModelIndex != QModelIndex()) {
//		mFields << Field(tr("Graphical Id"), graphicalIdPseudoattribute);
//	}

//	mFields << Field(tr("Metatype"), metatypePseudoattribute);

	reset();
}

void PropertyEditorModel::clearModelIndexes()
{
	setModelIndexes(QModelIndex(), QModelIndex());
}

bool PropertyEditorModel::isCurrentIndex(QModelIndex const &index) const
{
	return index == mTargetLogicalObject || index == mTargetGraphicalObject;
}

bool PropertyEditorModel::isValid() const
{
	return mTargetGraphicalModel && mTargetLogicalModel
			&& (mTargetLogicalObject.isValid() || mTargetGraphicalObject.isValid());
}

QModelIndex PropertyEditorModel::modelIndex(int row) const
{
	switch (mFields[row].attributeClass) {
	case logicalAttribute:
		return mTargetLogicalObject;
	case graphicalAttribute:
		return mTargetGraphicalObject;
	default:
		throw Exception("PropertyEditorModel::modelIndex: called for incorrect field, which is not graphical nor logical attribute");
	}
	return QModelIndex();
}

int PropertyEditorModel::roleByIndex(int row) const
{
	return mFields[row].role;
}

QString PropertyEditorModel::typeName(QModelIndex const &index) const
{
	Id id;
	switch (mFields[index.row()].attributeClass) {
	case logicalAttribute:
		id = mTargetLogicalObject.data(roles::idRole).value<Id>();
		break;
	case graphicalAttribute:
		id = mTargetGraphicalObject.data(roles::idRole).value<Id>();
	default:
		return "";  // Non-logical and non-graphical attributes have no type by default
	}
	return mEditorManager.getTypeName(id, mFields[index.row()].fieldName);
}
<|endoftext|>


<commit_before>//
//  GameEngine.cpp
//  yamiHikariGame
//
//  Created by slightair on 2013/07/28.
//
//

#include "GameEngine.h"
#include "SimpleAudioEngine.h"
#include "Constants.h"
#include "TitleScene.h"
#include "GameScene.h"
#include "ResultScene.h"
#include "ItemListScene.h"
#include "Item.h"
#include "NotificationLayer.h"

#define kTransitionDuration 1.0
#define kGameTickInterval 0.1
#define kSurvivePoint 1
#define kStaminaConsumption 3
#define kWaitForResultDuration 3

#define kSavefileName "savedata.db"

static GameEngine *__sharedEngine = NULL;

GameEngine *GameEngine::sharedEngine()
{
    if (!__sharedEngine) {
        __sharedEngine = new GameEngine();
        __sharedEngine->init();
    }

    return __sharedEngine;
}

bool GameEngine::init()
{
    return true;
}

void GameEngine::startNewGame()
{
    _score = 0;
    _stamina = StaminaMax;
    _foundItems.clear();

    CCDirector *director = CCDirector::sharedDirector();
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, GameScene::scene());
    director->replaceScene(transition);

    director->getScheduler()->scheduleSelector(schedule_selector(GameEngine::tick), this, kGameTickInterval, false);
}

void GameEngine::finishGame()
{
    CCDirector *director = CCDirector::sharedDirector();

    director->getScheduler()->unscheduleSelector(schedule_selector(GameEngine::tick), this);

    GameScene *gameScene = (GameScene *)director->getRunningScene()->getChildren()->objectAtIndex(0);
    gameScene->finishAnimations();

    CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(SEGameOver);

    registerFoundItemCount();

    director->getScheduler()->scheduleSelector(schedule_selector(GameEngine::showResult), this, 0, 0, kWaitForResultDuration, false);
}

void GameEngine::tick()
{
    _stamina -= kStaminaConsumption;
    _score += kSurvivePoint;

    if (_stamina <= 0) {
        this->finishGame();
    }
}

void GameEngine::registerFoundItemCount()
{
    map<hiberlite::sqlid_t, int>::iterator iterator = _foundItems.begin();

    while (iterator != _foundItems.end()) {
        hiberlite::sqlid_t itemID = (*iterator).first;
        Item item = _items.at(itemID - 1);
        int count = (*iterator).second;

        item->updateCount(item->count + count);
        item.save();

        iterator++;
    }
}

void GameEngine::showResult()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, ResultScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

void GameEngine::showItemList()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, ItemListScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

void GameEngine::showRanking()
{

}

void GameEngine::showTitle()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, TitleScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

int GameEngine::getScore()
{
    return _score;
}

int GameEngine::getStamina()
{
    return _stamina;
}

void GameEngine::addScore(int score)
{
    _score += score;
}

void GameEngine::addStamina(int stamina)
{
    if (_stamina + stamina > StaminaMax) {
        _stamina = StaminaMax;
    }
    else {
        _stamina += stamina;
    }
}

void GameEngine::loadSaveData()
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();
    bool forceRebuildSaveData = false;

    string saveFilePath = fileUtils->getWritablePath().append(kSavefileName);
    if (forceRebuildSaveData || !fileUtils->isFileExist(saveFilePath)) {
        copyInitialData(saveFilePath);
    }

    _db.open(saveFilePath);

    _items = _db.getAllBeans<_Item>();
    for (int i=0; i<_items.size(); i++) {
        if (!_items.at(i)->validate()) {
            CCLog("validation error!!");

            GameEngine::sharedEngine()->rebuildSaveData();

            NotificationLayer *noticeLayer = NotificationLayer::create();
            noticeLayer->setTitle(MessageInvalidDataTitle);
            noticeLayer->setNoticeMessage(MessageInvalidDataText);
            noticeLayer->setNotificationType(NOTIFICATION_LAYER_OK_ONLY);
            noticeLayer->setActionTarget(NOTIFICATION_LAYER_ACTION_OK, CCDirector::sharedDirector(), menu_selector(CCDirector::popScene));

            CCScene *scene = CCScene::create();
            scene->addChild(noticeLayer);
            CCDirector::sharedDirector()->pushScene(scene);

            return;
        }
    }
}

void GameEngine::rebuildSaveData()
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    _db.close();
    _items.clear();

    string saveFilePath = fileUtils->getWritablePath().append(kSavefileName);
    copyInitialData(saveFilePath);

    _db.open(saveFilePath);
    _items = _db.getAllBeans<_Item>();
}

void GameEngine::copyInitialData(string saveFilePath)
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    string initDBFilePath = fileUtils->fullPathForFilename("init.db");

    FILE *src, *dest;
    char buffer[128];
    src = fopen(initDBFilePath.c_str(), "rb");
    dest = fopen(saveFilePath.c_str(), "wb");

    while (feof(src) == 0) {
        int read = fread(buffer, sizeof(char), 128, src);
        fwrite(buffer, sizeof(char), read, dest);
    }

    fclose(src);
    fclose(dest);
}

void GameEngine::foundItem(hiberlite::sqlid_t itemID)
{
    Item item = _items.at(itemID - 1);

    addScore(item->score);
    addStamina(item->stamina);

    if (_foundItems.find(itemID) == _foundItems.end()) {
        _foundItems[itemID] = 1;
    }
    else {
        _foundItems[itemID] += 1;
    }
}

vector<Item> *GameEngine::getItems()
{
    return &_items;
}

map<hiberlite::sqlid_t, int> *GameEngine::getFoundItems()
{
    return &_foundItems;
}<commit_msg>Fix call style that call method in itself.<commit_after>//
//  GameEngine.cpp
//  yamiHikariGame
//
//  Created by slightair on 2013/07/28.
//
//

#include "GameEngine.h"
#include "SimpleAudioEngine.h"
#include "Constants.h"
#include "TitleScene.h"
#include "GameScene.h"
#include "ResultScene.h"
#include "ItemListScene.h"
#include "Item.h"
#include "NotificationLayer.h"

#define kTransitionDuration 1.0
#define kGameTickInterval 0.1
#define kSurvivePoint 1
#define kStaminaConsumption 3
#define kWaitForResultDuration 3

#define kSavefileName "savedata.db"

static GameEngine *__sharedEngine = NULL;

GameEngine *GameEngine::sharedEngine()
{
    if (!__sharedEngine) {
        __sharedEngine = new GameEngine();
        __sharedEngine->init();
    }

    return __sharedEngine;
}

bool GameEngine::init()
{
    return true;
}

void GameEngine::startNewGame()
{
    _score = 0;
    _stamina = StaminaMax;
    _foundItems.clear();

    CCDirector *director = CCDirector::sharedDirector();
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, GameScene::scene());
    director->replaceScene(transition);

    director->getScheduler()->scheduleSelector(schedule_selector(GameEngine::tick), this, kGameTickInterval, false);
}

void GameEngine::finishGame()
{
    CCDirector *director = CCDirector::sharedDirector();

    director->getScheduler()->unscheduleSelector(schedule_selector(GameEngine::tick), this);

    GameScene *gameScene = (GameScene *)director->getRunningScene()->getChildren()->objectAtIndex(0);
    gameScene->finishAnimations();

    CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(SEGameOver);

    registerFoundItemCount();

    director->getScheduler()->scheduleSelector(schedule_selector(GameEngine::showResult), this, 0, 0, kWaitForResultDuration, false);
}

void GameEngine::tick()
{
    _stamina -= kStaminaConsumption;
    _score += kSurvivePoint;

    if (_stamina <= 0) {
        this->finishGame();
    }
}

void GameEngine::registerFoundItemCount()
{
    map<hiberlite::sqlid_t, int>::iterator iterator = _foundItems.begin();

    while (iterator != _foundItems.end()) {
        hiberlite::sqlid_t itemID = (*iterator).first;
        Item item = _items.at(itemID - 1);
        int count = (*iterator).second;

        item->updateCount(item->count + count);
        item.save();

        iterator++;
    }
}

void GameEngine::showResult()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, ResultScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

void GameEngine::showItemList()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, ItemListScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

void GameEngine::showRanking()
{

}

void GameEngine::showTitle()
{
    CCTransitionFade *transition = CCTransitionFade::create(kTransitionDuration, TitleScene::scene());
    CCDirector::sharedDirector()->replaceScene(transition);
}

int GameEngine::getScore()
{
    return _score;
}

int GameEngine::getStamina()
{
    return _stamina;
}

void GameEngine::addScore(int score)
{
    _score += score;
}

void GameEngine::addStamina(int stamina)
{
    if (_stamina + stamina > StaminaMax) {
        _stamina = StaminaMax;
    }
    else {
        _stamina += stamina;
    }
}

void GameEngine::loadSaveData()
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();
    bool forceRebuildSaveData = false;

    string saveFilePath = fileUtils->getWritablePath().append(kSavefileName);
    if (forceRebuildSaveData || !fileUtils->isFileExist(saveFilePath)) {
        copyInitialData(saveFilePath);
    }

    _db.open(saveFilePath);

    _items = _db.getAllBeans<_Item>();
    for (int i=0; i<_items.size(); i++) {
        if (!_items.at(i)->validate()) {
            CCLog("validation error!!");

            rebuildSaveData();

            NotificationLayer *noticeLayer = NotificationLayer::create();
            noticeLayer->setTitle(MessageInvalidDataTitle);
            noticeLayer->setNoticeMessage(MessageInvalidDataText);
            noticeLayer->setNotificationType(NOTIFICATION_LAYER_OK_ONLY);
            noticeLayer->setActionTarget(NOTIFICATION_LAYER_ACTION_OK, CCDirector::sharedDirector(), menu_selector(CCDirector::popScene));

            CCScene *scene = CCScene::create();
            scene->addChild(noticeLayer);
            CCDirector::sharedDirector()->pushScene(scene);

            return;
        }
    }
}

void GameEngine::rebuildSaveData()
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    _db.close();
    _items.clear();

    string saveFilePath = fileUtils->getWritablePath().append(kSavefileName);
    copyInitialData(saveFilePath);

    _db.open(saveFilePath);
    _items = _db.getAllBeans<_Item>();
}

void GameEngine::copyInitialData(string saveFilePath)
{
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    string initDBFilePath = fileUtils->fullPathForFilename("init.db");

    FILE *src, *dest;
    char buffer[128];
    src = fopen(initDBFilePath.c_str(), "rb");
    dest = fopen(saveFilePath.c_str(), "wb");

    while (feof(src) == 0) {
        int read = fread(buffer, sizeof(char), 128, src);
        fwrite(buffer, sizeof(char), read, dest);
    }

    fclose(src);
    fclose(dest);
}

void GameEngine::foundItem(hiberlite::sqlid_t itemID)
{
    Item item = _items.at(itemID - 1);

    addScore(item->score);
    addStamina(item->stamina);

    if (_foundItems.find(itemID) == _foundItems.end()) {
        _foundItems[itemID] = 1;
    }
    else {
        _foundItems[itemID] += 1;
    }
}

vector<Item> *GameEngine::getItems()
{
    return &_items;
}

map<hiberlite::sqlid_t, int> *GameEngine::getFoundItems()
{
    return &_foundItems;
}<|endoftext|>


<commit_before>// Copyright (c) 2017 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "umc_defs.h"

#ifdef MFX_ENABLE_H265_VIDEO_DECODE

#include "umc_h265_frame_info.h"

namespace UMC_HEVC_DECODER
{

bool H265DecoderFrameInfo::IsCompleted() const
{
    if (GetStatus() == H265DecoderFrameInfo::STATUS_COMPLETED)
        return true;

    return false;
}

void H265DecoderFrameInfo::Reset()
{
    Free();

    m_hasTiles = false;

    m_isNeedDeblocking = false;
    m_isNeedSAO = false;

    m_isIntraAU = true;
    m_hasDependentSliceSegments = false;
    m_WA_different_disable_deblocking = false;

    m_nextAU = 0;
    m_prevAU = 0;
    m_refAU = 0;

    m_Status = STATUS_NONE;
    m_prepared = 0;
    m_IsIDR = false;

    if (m_sps)
    {
        m_sps->DecrementReference();
        m_sps = 0;
    }
}

void H265DecoderFrameInfo::Free()
{
    size_t count = m_pSliceQueue.size();
    for (size_t i = 0; i < count; i ++)
    {
        H265Slice * pCurSlice = m_pSliceQueue[i];
        pCurSlice->Release();
        pCurSlice->DecrementReference();
    }

    m_SliceCount = 0;

    m_pSliceQueue.clear();
    m_prepared = 0;
}

void H265DecoderFrameInfo::RemoveSlice(int32_t num)
{
    H265Slice * pCurSlice = GetSlice(num);

    if (!pCurSlice) // nothing to do
        return;

    for (int32_t i = num; i < m_SliceCount - 1; i++)
    {
        m_pSliceQueue[i] = m_pSliceQueue[i + 1];
    }

    m_SliceCount--;
    m_pSliceQueue[m_SliceCount] = pCurSlice;
}

// Function works with a list of slices sorted by slice_segment_address
void H265DecoderFrameInfo::EliminateErrors()
{
    if (!GetSlice(0))
        return;

    // Remove dependent slices without a corresponding independent slice
    for (uint32_t sliceId = 0; sliceId < GetSliceCount(); sliceId++)
    {
        H265Slice * slice = GetSlice(sliceId);

        if (slice->GetSliceHeader()->dependent_slice_segment_flag)
        {
            RemoveSlice(sliceId);
            sliceId = uint32_t(-1);
            continue;
        }
        else
            break;
    }

    {
        // HEVC 7.4.7.1 General slice segment header semantics
        H265Slice *baseSlice = GetSlice(0); // after the for() loop above ,the first slice is treated as 'base' slice

        bool bIndepSliceMissing = false;
        for (uint32_t sliceId = 1; sliceId < GetSliceCount(); sliceId++)
        {
            H265SliceHeader *sliceHeader = GetSlice(sliceId)->GetSliceHeader();

            if (!sliceHeader->dependent_slice_segment_flag)
                bIndepSliceMissing = false;

            bool bSpecViolation = sliceHeader->slice_temporal_mvp_enabled_flag !=
                  baseSlice->GetSliceHeader()->slice_temporal_mvp_enabled_flag;

            bool bRemoveDependent = bIndepSliceMissing && sliceHeader->dependent_slice_segment_flag;

            if (bSpecViolation || bRemoveDependent)
            {
                RemoveSlice(sliceId);
                sliceId--;
                if (false == bIndepSliceMissing)
                    bIndepSliceMissing = !sliceHeader->dependent_slice_segment_flag;
            }
        }
    }

    // Remove slices with duplicated slice_segment_address syntax
    for (uint32_t sliceId = 0; sliceId < GetSliceCount(); sliceId++)
    {
        H265Slice * slice = GetSlice(sliceId);
        H265Slice * nextSlice = GetSlice(sliceId + 1);

        if (!nextSlice)
            break;

        if (slice->GetFirstMB() == slice->GetMaxMB())
        {
            uint32_t sliceIdToRemove;

            // Heuristic logic:
            if (slice->GetSliceHeader()->dependent_slice_segment_flag && !nextSlice->GetSliceHeader()->dependent_slice_segment_flag)
            {
                // dependent slices are prone to errors
                sliceIdToRemove = sliceId;
            }
            else
            {
                // among two independent or dependent slices, prefer to keep the first slice
                sliceIdToRemove = sliceId + 1;
            }
            RemoveSlice(sliceIdToRemove);
            sliceId = uint32_t(-1);
            continue;
        }
    }
}

void H265DecoderFrameInfo::EliminateASO()
{
    static int32_t MAX_MB_NUMBER = 0x7fffffff;

    if (!GetSlice(0))
        return;

    uint32_t count = GetSliceCount();
    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * curSlice = GetSlice(sliceId);
        int32_t minFirst = MAX_MB_NUMBER;
        uint32_t minSlice = 0;

        for (uint32_t j = sliceId; j < count; j++)
        {
            H265Slice * slice = GetSlice(j);
            if (slice->GetFirstMB() < curSlice->GetFirstMB() && minFirst > slice->GetFirstMB())
            {
                minFirst = slice->GetFirstMB();
                minSlice = j;
            }
        }

        if (minFirst != MAX_MB_NUMBER)
        {
            H265Slice * temp = m_pSliceQueue[sliceId];
            m_pSliceQueue[sliceId] = m_pSliceQueue[minSlice];
            m_pSliceQueue[minSlice] = temp;
        }
    }

    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * slice = GetSlice(sliceId);
        H265Slice * nextSlice = GetSlice(sliceId + 1);

        if (!nextSlice)
            break;

        slice->SetMaxMB(nextSlice->GetFirstMB());
    }
}

} // namespace UMC_HEVC_DECODER
#endif // MFX_ENABLE_H265_VIDEO_DECODE
<commit_msg>[h265d_umc] Use m_pSliceQueue directly w/o GetSlice<commit_after>// Copyright (c) 2017-2018 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "umc_defs.h"

#ifdef MFX_ENABLE_H265_VIDEO_DECODE

#include "umc_h265_frame_info.h"

namespace UMC_HEVC_DECODER
{

bool H265DecoderFrameInfo::IsCompleted() const
{
    if (GetStatus() == H265DecoderFrameInfo::STATUS_COMPLETED)
        return true;

    return false;
}

void H265DecoderFrameInfo::Reset()
{
    Free();

    m_hasTiles = false;

    m_isNeedDeblocking = false;
    m_isNeedSAO = false;

    m_isIntraAU = true;
    m_hasDependentSliceSegments = false;
    m_WA_different_disable_deblocking = false;

    m_nextAU = 0;
    m_prevAU = 0;
    m_refAU = 0;

    m_Status = STATUS_NONE;
    m_prepared = 0;
    m_IsIDR = false;

    if (m_sps)
    {
        m_sps->DecrementReference();
        m_sps = 0;
    }
}

void H265DecoderFrameInfo::Free()
{
    size_t count = m_pSliceQueue.size();
    for (size_t i = 0; i < count; i ++)
    {
        H265Slice * pCurSlice = m_pSliceQueue[i];
        pCurSlice->Release();
        pCurSlice->DecrementReference();
    }

    m_SliceCount = 0;

    m_pSliceQueue.clear();
    m_prepared = 0;
}

void H265DecoderFrameInfo::RemoveSlice(int32_t num)
{
    H265Slice * pCurSlice = GetSlice(num);

    if (!pCurSlice) // nothing to do
        return;

    for (int32_t i = num; i < m_SliceCount - 1; i++)
    {
        m_pSliceQueue[i] = m_pSliceQueue[i + 1];
    }

    m_SliceCount--;
    m_pSliceQueue[m_SliceCount] = pCurSlice;
}

// Function works with a list of slices sorted by slice_segment_address
void H265DecoderFrameInfo::EliminateErrors()
{
    if (!GetSlice(0))
        return;

    uint32_t count = m_SliceCount;

    // Remove dependent slices without a corresponding independent slice
    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * slice = GetSlice(sliceId);

        if (slice->GetSliceHeader()->dependent_slice_segment_flag)
        {
            RemoveSlice(sliceId);
            sliceId = uint32_t(-1);
            continue;
        }
        else
            break;
    }

    {
        // HEVC 7.4.7.1 General slice segment header semantics
        H265Slice *baseSlice = GetSlice(0); // after the for() loop above ,the first slice is treated as 'base' slice

        bool bIndepSliceMissing = false;
        for (uint32_t sliceId = 1; sliceId < count; sliceId++)
        {
            H265SliceHeader *sliceHeader = GetSlice(sliceId)->GetSliceHeader();

            if (!sliceHeader->dependent_slice_segment_flag)
                bIndepSliceMissing = false;

            bool bSpecViolation = sliceHeader->slice_temporal_mvp_enabled_flag !=
                  baseSlice->GetSliceHeader()->slice_temporal_mvp_enabled_flag;

            bool bRemoveDependent = bIndepSliceMissing && sliceHeader->dependent_slice_segment_flag;

            if (bSpecViolation || bRemoveDependent)
            {
                RemoveSlice(sliceId);
                sliceId--;
                if (false == bIndepSliceMissing)
                    bIndepSliceMissing = !sliceHeader->dependent_slice_segment_flag;
            }
        }
    }

    // Remove slices with duplicated slice_segment_address syntax
    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * slice     = m_pSliceQueue[sliceId];
        H265Slice * nextSlice = GetSlice(sliceId + 1);

        if (!nextSlice)
            break;

        if (slice->GetFirstMB() == slice->GetMaxMB())
        {
            uint32_t sliceIdToRemove;

            // Heuristic logic:
            if (slice->GetSliceHeader()->dependent_slice_segment_flag && !nextSlice->GetSliceHeader()->dependent_slice_segment_flag)
            {
                // dependent slices are prone to errors
                sliceIdToRemove = sliceId;
            }
            else
            {
                // among two independent or dependent slices, prefer to keep the first slice
                sliceIdToRemove = sliceId + 1;
            }
            RemoveSlice(sliceIdToRemove);
            sliceId = uint32_t(-1);
            continue;
        }
    }
}

void H265DecoderFrameInfo::EliminateASO()
{
    static int32_t MAX_MB_NUMBER = 0x7fffffff;

    if (!GetSlice(0))
        return;

    uint32_t count = m_SliceCount;
    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * curSlice = m_pSliceQueue[sliceId];
        int32_t minFirst = MAX_MB_NUMBER;
        uint32_t minSlice = 0;

        for (uint32_t j = sliceId; j < count; j++)
        {
            H265Slice * slice = m_pSliceQueue[j];
            if (slice->GetFirstMB() < curSlice->GetFirstMB() && minFirst > slice->GetFirstMB())
            {
                minFirst = slice->GetFirstMB();
                minSlice = j;
            }
        }

        if (minFirst != MAX_MB_NUMBER)
        {
            H265Slice * temp = m_pSliceQueue[sliceId];
            m_pSliceQueue[sliceId] = m_pSliceQueue[minSlice];
            m_pSliceQueue[minSlice] = temp;
        }
    }

    for (uint32_t sliceId = 0; sliceId < count; sliceId++)
    {
        H265Slice * slice     = m_pSliceQueue[sliceId];
        H265Slice * nextSlice = GetSlice(sliceId + 1);

        if (!nextSlice)
            break;

        slice->SetMaxMB(nextSlice->GetFirstMB());
    }
}

} // namespace UMC_HEVC_DECODER
#endif // MFX_ENABLE_H265_VIDEO_DECODE
<|endoftext|>


<commit_before><commit_msg>Update Suffix Automaton.cpp<commit_after><|endoftext|>


<commit_before>// Copyright 2014 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <sstream>
#include <vector>

#include "elang/compiler/syntax/parser.h"

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "elang/compiler/ast/expressions.h"
#include "elang/compiler/ast/field.h"
#include "elang/compiler/ast/node_factory.h"
#include "elang/compiler/compilation_session.h"
#include "elang/compiler/compilation_unit.h"
#include "elang/compiler/public/compiler_error_code.h"
#include "elang/compiler/source_code.h"
#include "elang/compiler/token.h"
#include "elang/compiler/token_type.h"

namespace elang {
namespace compiler {

// Just an alias of |ConsumeExpression()| for improving readability.
ast::Expression* Parser::ConsumeType() {
  auto const type = ConsumeExpression();
  if (!MaybeType(type))
    Error(ErrorCode::SyntaxExpressionType);
  return type;
}

bool Parser::MaybeType(ast::Expression* maybe_type) const {
  return maybe_type->is<ast::ArrayType>() ||
         maybe_type->is<ast::ConstructedType>() ||
         maybe_type->is<ast::MemberAccess>() ||
         maybe_type->is<ast::NameReference>();
}

// ArrayType ::= Type ('[' ','* ']')+
void Parser::ParseArrayType(Token* bracket) {
  auto const element_type = ConsumeType();
  std::vector<int> ranks;
  do {
    auto rank = 1;
    while (AdvanceIf(TokenType::Comma))
      ++rank;
    if (!AdvanceIf(TokenType::RightSquareBracket))
      Error(ErrorCode::SyntaxTypeRightSquareBracket);
    ranks.push_back(rank);
  } while (AdvanceIf(TokenType::LeftSquareBracket));
  ProduceType(factory()->NewArrayType(bracket, element_type, ranks));
}

// NamespaceOrTypeName ::=
//   Name TypeArgumentList |
//   QualifiedAliasMember |
//   NamespaceOrTypeName '.' Name TypeArgumentList
bool Parser::ParseNamespaceOrTypeName() {
  enum class State {
    ConstructedType,
    Dot,
    Finish,
    Name,
    Start,
  };

  if (!PeekToken()->is_name()) {
    Error(ErrorCode::SyntaxTypeName);
    return false;
  }
  std::vector<ast::Expression*> names;
  auto state = State::Start;
  for (;;) {
    switch (state) {
      case State::ConstructedType:
        if (AdvanceIf(TokenType::Dot)) {
          state = State::Dot;
          continue;
        }
        state = State::Finish;
        continue;
      case State::Dot:
      case State::Start:
        if (!PeekToken()->is_name()) {
          Error(ErrorCode::SyntaxTypeName);
          return false;
        }
        names.push_back(factory()->NewNameReference(ConsumeToken()));
        state = State::Name;
        continue;
      case State::Name:
        if (AdvanceIf(TokenType::Dot)) {
          state = State::Dot;
          continue;
        }
        if (AdvanceIf(TokenType::LeftAngleBracket)) {
          // TypeArgumentList ::= '<' Type (',' TypeName)* '>'
          std::vector<ast::Expression*> type_args;
          do {
            if (!ParseType())
              return false;
            type_args.push_back(ConsumeType());
          } while (AdvanceIf(TokenType::Comma));
          if (!AdvanceIf(TokenType::RightAngleBracket))
            Error(ErrorCode::SyntaxTypeRightAngleBracket);
          if (names.empty()) {
            Error(ErrorCode::SyntaxTypeTypeArgument);
          } else {
            ProduceMemberAccess(names);
            names.clear();
            names.push_back(
                factory()->NewConstructedType(ConsumeType(), type_args));
          }
          state = State::ConstructedType;
          continue;
        }
        state = State::Finish;
        break;
      case State::Finish:
        DCHECK(!names.empty());
        ProduceMemberAccess(names);
        return true;
    }
  }
}

// Type ::= ValueType | ReferenceType | TypeParameter
//
// TypeName ::= NamespaceOrTypeName
// ValueType ::= StructType | EnumType
// StructType ::= TypeName | SimpleType | NullableType
// SimpleType ::= NumericType | 'bool'
// NumericType ::= IntegralType | FloatingPointType
// IntegralType ::= 'int8' | 'int16' | 'int32' | 'int64' |
//                  'uint8' | 'uint16' | 'uint32' | 'uint64' | 'char'
// FloatingPointType ::= 'float32' | 'float64'
// EnumType ::= TypeName
// ReferenceType ::= ClassType | InterfaceType | ArrayType | FunctionType
bool Parser::ParseType() {
  if (PeekToken() == TokenType::Var) {
    // |var| isn't valid type name. Caller of |ParseType()| should handle |var|.
    return false;
  }

  if (PeekToken()->is_type_name()) {
    ProduceType(factory()->NewNameReference(ConsumeToken()));
    return ParseTypePost();
  }

  if (!ParseNamespaceOrTypeName())
    return false;
  return ParseTypePost();
}

// NullableType ::= NonNullableValueType '?'
// NonNullableValueType ::= EnumType | TypeName | SimpleType
//
// ArrayType ::= NonArrayType RankSpecifier*
// NonArrayType ::= ValueType | ClassType | InterfaceType | FunctionType |
//                  TypeParameter
// RankSpecifier ::= '[' ','* ']'
bool Parser::ParseTypePost() {
  if (auto const optional_marker = ConsumeTokenIf(TokenType::OptionalType))
    ProduceType(factory()->NewUnaryOperation(optional_marker, ConsumeType()));
  if (auto const bracket = ConsumeTokenIf(TokenType::LeftSquareBracket))
    ParseArrayType(bracket);
  return true;
}

// TypeParameterList ::= '<' TypeParameter (',' TypeParameter)* '>'
// TypeParameter ::= Attribute? Name
std::vector<Token*> Parser::ParseTypeParameterList() {
  std::vector<Token*> type_params;
  for (;;) {
    if (!PeekToken()->is_name())
      break;
    // TODO(eval1749) We should use |ast::TypeParameter| with |in|, |out| and
    // attribute list.
    type_params.push_back(ConsumeToken());
    if (AdvanceIf(TokenType::RightAngleBracket))
      break;
    if (!AdvanceIf(TokenType::Comma))
      Error(ErrorCode::SyntaxClassDeclTypeParamInvalid);
  }
  return type_params;
}

ast::Expression* Parser::ProduceMemberAccess(
    const std::vector<ast::Expression*>& names) {
  DCHECK(!names.empty());
  if (names.size() == 1)
    return ProduceType(names.back());
  // TODO(eval1749) We should use |base::string16| for creating name for
  // |MemberAccess|
  std::stringstream buffer;
  const char* separator = "";
  for (auto const name : names) {
    buffer << separator << name->token();
    separator = ".";
  }
  auto const name_token = session_->NewToken(
      SourceCodeRange(compilation_unit_->source_code(),
                      names.front()->token()->location().start_offset(),
                      names.back()->token()->location().end_offset()),
      TokenData(TokenType::SimpleName,
                session_->NewAtomicString(base::UTF8ToUTF16(buffer.str()))));
  return ProduceType(factory()->NewMemberAccess(name_token, names));
}

ast::Expression* Parser::ProduceType(ast::Expression* type) {
  return ProduceExpression(type);
}

}  // namespace compiler
}  // namespace elang
<commit_msg>elang/compiler: Remove redundant include of "field.h" from "parser_type.cc".<commit_after>// Copyright 2014 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <sstream>
#include <vector>

#include "elang/compiler/syntax/parser.h"

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "elang/compiler/ast/expressions.h"
#include "elang/compiler/ast/node_factory.h"
#include "elang/compiler/compilation_session.h"
#include "elang/compiler/compilation_unit.h"
#include "elang/compiler/public/compiler_error_code.h"
#include "elang/compiler/source_code.h"
#include "elang/compiler/token.h"
#include "elang/compiler/token_type.h"

namespace elang {
namespace compiler {

// Just an alias of |ConsumeExpression()| for improving readability.
ast::Expression* Parser::ConsumeType() {
  auto const type = ConsumeExpression();
  if (!MaybeType(type))
    Error(ErrorCode::SyntaxExpressionType);
  return type;
}

bool Parser::MaybeType(ast::Expression* maybe_type) const {
  return maybe_type->is<ast::ArrayType>() ||
         maybe_type->is<ast::ConstructedType>() ||
         maybe_type->is<ast::MemberAccess>() ||
         maybe_type->is<ast::NameReference>();
}

// ArrayType ::= Type ('[' ','* ']')+
void Parser::ParseArrayType(Token* bracket) {
  auto const element_type = ConsumeType();
  std::vector<int> ranks;
  do {
    auto rank = 1;
    while (AdvanceIf(TokenType::Comma))
      ++rank;
    if (!AdvanceIf(TokenType::RightSquareBracket))
      Error(ErrorCode::SyntaxTypeRightSquareBracket);
    ranks.push_back(rank);
  } while (AdvanceIf(TokenType::LeftSquareBracket));
  ProduceType(factory()->NewArrayType(bracket, element_type, ranks));
}

// NamespaceOrTypeName ::=
//   Name TypeArgumentList |
//   QualifiedAliasMember |
//   NamespaceOrTypeName '.' Name TypeArgumentList
bool Parser::ParseNamespaceOrTypeName() {
  enum class State {
    ConstructedType,
    Dot,
    Finish,
    Name,
    Start,
  };

  if (!PeekToken()->is_name()) {
    Error(ErrorCode::SyntaxTypeName);
    return false;
  }
  std::vector<ast::Expression*> names;
  auto state = State::Start;
  for (;;) {
    switch (state) {
      case State::ConstructedType:
        if (AdvanceIf(TokenType::Dot)) {
          state = State::Dot;
          continue;
        }
        state = State::Finish;
        continue;
      case State::Dot:
      case State::Start:
        if (!PeekToken()->is_name()) {
          Error(ErrorCode::SyntaxTypeName);
          return false;
        }
        names.push_back(factory()->NewNameReference(ConsumeToken()));
        state = State::Name;
        continue;
      case State::Name:
        if (AdvanceIf(TokenType::Dot)) {
          state = State::Dot;
          continue;
        }
        if (AdvanceIf(TokenType::LeftAngleBracket)) {
          // TypeArgumentList ::= '<' Type (',' TypeName)* '>'
          std::vector<ast::Expression*> type_args;
          do {
            if (!ParseType())
              return false;
            type_args.push_back(ConsumeType());
          } while (AdvanceIf(TokenType::Comma));
          if (!AdvanceIf(TokenType::RightAngleBracket))
            Error(ErrorCode::SyntaxTypeRightAngleBracket);
          if (names.empty()) {
            Error(ErrorCode::SyntaxTypeTypeArgument);
          } else {
            ProduceMemberAccess(names);
            names.clear();
            names.push_back(
                factory()->NewConstructedType(ConsumeType(), type_args));
          }
          state = State::ConstructedType;
          continue;
        }
        state = State::Finish;
        break;
      case State::Finish:
        DCHECK(!names.empty());
        ProduceMemberAccess(names);
        return true;
    }
  }
}

// Type ::= ValueType | ReferenceType | TypeParameter
//
// TypeName ::= NamespaceOrTypeName
// ValueType ::= StructType | EnumType
// StructType ::= TypeName | SimpleType | NullableType
// SimpleType ::= NumericType | 'bool'
// NumericType ::= IntegralType | FloatingPointType
// IntegralType ::= 'int8' | 'int16' | 'int32' | 'int64' |
//                  'uint8' | 'uint16' | 'uint32' | 'uint64' | 'char'
// FloatingPointType ::= 'float32' | 'float64'
// EnumType ::= TypeName
// ReferenceType ::= ClassType | InterfaceType | ArrayType | FunctionType
bool Parser::ParseType() {
  if (PeekToken() == TokenType::Var) {
    // |var| isn't valid type name. Caller of |ParseType()| should handle |var|.
    return false;
  }

  if (PeekToken()->is_type_name()) {
    ProduceType(factory()->NewNameReference(ConsumeToken()));
    return ParseTypePost();
  }

  if (!ParseNamespaceOrTypeName())
    return false;
  return ParseTypePost();
}

// NullableType ::= NonNullableValueType '?'
// NonNullableValueType ::= EnumType | TypeName | SimpleType
//
// ArrayType ::= NonArrayType RankSpecifier*
// NonArrayType ::= ValueType | ClassType | InterfaceType | FunctionType |
//                  TypeParameter
// RankSpecifier ::= '[' ','* ']'
bool Parser::ParseTypePost() {
  if (auto const optional_marker = ConsumeTokenIf(TokenType::OptionalType))
    ProduceType(factory()->NewUnaryOperation(optional_marker, ConsumeType()));
  if (auto const bracket = ConsumeTokenIf(TokenType::LeftSquareBracket))
    ParseArrayType(bracket);
  return true;
}

// TypeParameterList ::= '<' TypeParameter (',' TypeParameter)* '>'
// TypeParameter ::= Attribute? Name
std::vector<Token*> Parser::ParseTypeParameterList() {
  std::vector<Token*> type_params;
  for (;;) {
    if (!PeekToken()->is_name())
      break;
    // TODO(eval1749) We should use |ast::TypeParameter| with |in|, |out| and
    // attribute list.
    type_params.push_back(ConsumeToken());
    if (AdvanceIf(TokenType::RightAngleBracket))
      break;
    if (!AdvanceIf(TokenType::Comma))
      Error(ErrorCode::SyntaxClassDeclTypeParamInvalid);
  }
  return type_params;
}

ast::Expression* Parser::ProduceMemberAccess(
    const std::vector<ast::Expression*>& names) {
  DCHECK(!names.empty());
  if (names.size() == 1)
    return ProduceType(names.back());
  // TODO(eval1749) We should use |base::string16| for creating name for
  // |MemberAccess|
  std::stringstream buffer;
  const char* separator = "";
  for (auto const name : names) {
    buffer << separator << name->token();
    separator = ".";
  }
  auto const name_token = session_->NewToken(
      SourceCodeRange(compilation_unit_->source_code(),
                      names.front()->token()->location().start_offset(),
                      names.back()->token()->location().end_offset()),
      TokenData(TokenType::SimpleName,
                session_->NewAtomicString(base::UTF8ToUTF16(buffer.str()))));
  return ProduceType(factory()->NewMemberAccess(name_token, names));
}

ast::Expression* Parser::ProduceType(ast::Expression* type) {
  return ProduceExpression(type);
}

}  // namespace compiler
}  // namespace elang
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dtint.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: pl $ $Date: 2001-08-20 11:05:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SV_DTINT_HXX
#define _SV_DTINT_HXX

#include <cstdio>
#include <dlfcn.h>

#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif
#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#include <tools/color.hxx>

class SalFrame;
class SalBitmap;
class String;
class SalDisplay;
class FastItemInfo;

#ifndef _XLIB_H_
// forwards from X
struct Display;
struct XEvent;
#define Atom UINT32
#define XLIB_Window UINT32
#endif

#define XDND_PROTOCOL_VERSION 3

// NETBSD has no RTLD_GLOBAL
#ifndef RTLD_GLOBAL
#define DLOPEN_MODE (RTLD_LAZY)
#else
#define DLOPEN_MODE (RTLD_GLOBAL | RTLD_LAZY)
#endif

class DtIntegrator;

DECLARE_LIST( DtIntegratorList, DtIntegrator* );

struct SystemLookInfo
{
    /** system foreground color */
    Color                           foreground;
    /** system background color */
    Color                           background;
    /** system foreground color for a selection */
    Color                           selectForeground;
    /** system background color for a selection */
    Color                           selectBackground;

    /** gradient for an active window */
    Color                           windowActiveStart;
    Color                           windowActiveEnd;
    /** border color for active window */
    Color                           activeBorder;
    /** text color for active window bar */
    Color                           activeForeground;
    /** gradient of an inactive window */
    Color                           windowInactiveStart;
    Color                           windowInactiveEnd;
    /** border color for inactive window */
    Color                           inactiveBorder;
    /** text color for inactive window bar */
    Color                           inactiveForeground;

    /** font to use for controls. Empty if not set. */
    String                          controlFont;
    /** font to use for dragbars. Empty if not set. */
    String                          windowFont;

    SystemLookInfo()
        {
            foreground.SetColor( COL_TRANSPARENT );
            background.SetColor( COL_TRANSPARENT );
            selectBackground.SetColor( COL_TRANSPARENT );
            selectForeground.SetColor( COL_TRANSPARENT );

            windowActiveStart.SetColor( COL_TRANSPARENT );
            windowActiveEnd.SetColor( COL_TRANSPARENT );
            activeBorder.SetColor( COL_TRANSPARENT );
            activeForeground.SetColor( COL_TRANSPARENT );

            windowInactiveStart.SetColor( COL_TRANSPARENT );
            windowInactiveEnd.SetColor( COL_TRANSPARENT );
            inactiveBorder.SetColor( COL_TRANSPARENT );
            inactiveForeground.SetColor( COL_TRANSPARENT );
        }
};

enum DtType {
    DtGeneric,
    DtCDE,
    DtKDE,
    DtGNOME,
    DtSCO,
    DtIRIX
};

class DtIntegrator
{
protected:
    DtType              meType;
    Display*            mpDisplay;
    SalDisplay*         mpSalDisplay;
    SalFrame*           mpSalFrame;
    int                 mnRefCount;

    DtIntegrator( SalFrame* );

    static DtIntegratorList aIntegratorList;
    static String           aHomeDir;

public:
    static DtIntegrator* CreateDtIntegrator( SalFrame* );

    virtual ~DtIntegrator();

    // SystemLook
    virtual BOOL GetSystemLook( SystemLookInfo& rInfo );

    DtType          GetDtType() { return meType; }
    SalFrame*       GetFrame() { return mpSalFrame; }
    SalDisplay*     GetSalDisplay() { return mpSalDisplay; }
    Display*        GetDisplay() { return mpDisplay; }

    void Acquire() { mnRefCount++; }
    inline void Release();
};

inline void DtIntegrator::Release()
{
    mnRefCount--;
    if( ! mnRefCount )
    {
        aIntegratorList.Remove( this );
        delete this;
    }
}

// helper funktions for dynamic loading
extern BOOL bSymbolLoadFailed;

inline void* _LoadSymbol( void* pLibrary, char* pSymbolname )
{
    void *pRet = dlsym( pLibrary, pSymbolname );
    if( ! pRet )
    {
        fprintf( stderr, "Could not load symbol %s: %s\n",
                 pSymbolname, dlerror() );
        bSymbolLoadFailed = TRUE;
    }
    return pRet;
}
inline void* _LoadLibrary( char* pLibname )
{
    bSymbolLoadFailed = FALSE;
    void *pRet = dlopen( pLibname, DLOPEN_MODE );
    if( ! pRet )
    {
#ifdef DEBUG
        fprintf( stderr, "%s could not be opened: %s\n",
                 pLibname, dlerror() );
#endif
        bSymbolLoadFailed = TRUE;
    }
    return pRet;
}

#endif
<commit_msg>#65293#: syntax<commit_after>/*************************************************************************
 *
 *  $RCSfile: dtint.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2002-02-21 14:38:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SV_DTINT_HXX
#define _SV_DTINT_HXX

#include <cstdio>
#include <dlfcn.h>

#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif
#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#include <tools/color.hxx>

class SalFrame;
class SalBitmap;
class String;
class SalDisplay;
class FastItemInfo;

#ifndef _XLIB_H_
// forwards from X
struct Display;
struct XEvent;
#define Atom UINT32
#define XLIB_Window UINT32
#endif

#define XDND_PROTOCOL_VERSION 3

// NETBSD has no RTLD_GLOBAL
#ifndef RTLD_GLOBAL
#define DLOPEN_MODE (RTLD_LAZY)
#else
#define DLOPEN_MODE (RTLD_GLOBAL | RTLD_LAZY)
#endif

class DtIntegrator;

DECLARE_LIST( DtIntegratorList, DtIntegrator* );

struct SystemLookInfo
{
    /** system foreground color */
    Color                           foreground;
    /** system background color */
    Color                           background;
    /** system foreground color for a selection */
    Color                           selectForeground;
    /** system background color for a selection */
    Color                           selectBackground;

    /** gradient for an active window */
    Color                           windowActiveStart;
    Color                           windowActiveEnd;
    /** border color for active window */
    Color                           activeBorder;
    /** text color for active window bar */
    Color                           activeForeground;
    /** gradient of an inactive window */
    Color                           windowInactiveStart;
    Color                           windowInactiveEnd;
    /** border color for inactive window */
    Color                           inactiveBorder;
    /** text color for inactive window bar */
    Color                           inactiveForeground;

    /** font to use for controls. Empty if not set. */
    String                          controlFont;
    /** font to use for dragbars. Empty if not set. */
    String                          windowFont;

    SystemLookInfo()
        {
            foreground.SetColor( COL_TRANSPARENT );
            background.SetColor( COL_TRANSPARENT );
            selectBackground.SetColor( COL_TRANSPARENT );
            selectForeground.SetColor( COL_TRANSPARENT );

            windowActiveStart.SetColor( COL_TRANSPARENT );
            windowActiveEnd.SetColor( COL_TRANSPARENT );
            activeBorder.SetColor( COL_TRANSPARENT );
            activeForeground.SetColor( COL_TRANSPARENT );

            windowInactiveStart.SetColor( COL_TRANSPARENT );
            windowInactiveEnd.SetColor( COL_TRANSPARENT );
            inactiveBorder.SetColor( COL_TRANSPARENT );
            inactiveForeground.SetColor( COL_TRANSPARENT );
        }
};

enum DtType {
    DtGeneric,
    DtCDE,
    DtKDE,
    DtGNOME,
    DtSCO,
    DtIRIX
};

class DtIntegrator
{
protected:
    DtType              meType;
    Display*            mpDisplay;
    SalDisplay*         mpSalDisplay;
    SalFrame*           mpSalFrame;
    int                 mnRefCount;

    DtIntegrator( SalFrame* );

    static DtIntegratorList aIntegratorList;
    static String           aHomeDir;

public:
    static DtIntegrator* CreateDtIntegrator( SalFrame* );

    virtual ~DtIntegrator();

    // SystemLook
    virtual BOOL GetSystemLook( SystemLookInfo& rInfo );

    DtType          GetDtType() { return meType; }
    SalFrame*       GetFrame() { return mpSalFrame; }
    SalDisplay*     GetSalDisplay() { return mpSalDisplay; }
    Display*        GetDisplay() { return mpDisplay; }

    void Acquire() { mnRefCount++; }
    inline void Release();
};

inline void DtIntegrator::Release()
{
    mnRefCount--;
    if( ! mnRefCount )
    {
        aIntegratorList.Remove( this );
        delete this;
    }
}

// helper funktions for dynamic loading
extern BOOL bSymbolLoadFailed;

inline void* _LoadSymbol( void* pLibrary, char* pSymbolname )
{
    void *pRet = dlsym( pLibrary, pSymbolname );
    if( ! pRet )
    {
        std::fprintf( stderr, "Could not load symbol %s: %s\n",
                 pSymbolname, dlerror() );
        bSymbolLoadFailed = TRUE;
    }
    return pRet;
}
inline void* _LoadLibrary( char* pLibname )
{
    bSymbolLoadFailed = FALSE;
    void *pRet = dlopen( pLibname, DLOPEN_MODE );
    if( ! pRet )
    {
#ifdef DEBUG
        std::fprintf( stderr, "%s could not be opened: %s\n",
                 pLibname, dlerror() );
#endif
        bSymbolLoadFailed = TRUE;
    }
    return pRet;
}

#endif
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2008, Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Carnegie Mellon University nor the names of
 *    other contributors may be used to endorse or promote products
 *    derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * (This is the Modified BSD License.  See also
 * http://www.opensource.org/licenses/bsd-license.php )
 */

/**
 * This is C++ porting codes of direct/src/task/task.py
 */

#include <asyncTaskCollection.h>

#include <boost/optional.hpp>

#include <render_pipeline/rpcore/config.hpp>
#include <render_pipeline/rppanda/task/functional_task.hpp>

class AsyncTaskManager;
class ClockObject;

namespace rppanda {

class RENDER_PIPELINE_DECL TaskManager : public TypedObject
{
public:
    static TaskManager* get_global_instance();

    TaskManager();

    AsyncTaskManager* get_mgr() const;
    ClockObject* get_global_clock() const;

    bool has_task_named(const std::string& task_name) const;

    AsyncTaskCollection get_task_named(const std::string& task_name) const;

    /**
     * Add a task to be performed at some time in the future.
     *
     * @see add(const std::string&, GenericAsyncTask::TaskFunc*, void*, boost::optional<int>,
     * boost::optional<int>, const boost::optional<std::string>&, GenericAsyncTask::DeathFunc*);
     */
    AsyncTask* do_method_later(float delay_time,
        AsyncTask* task, const std::string& name,
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    /**
     * Add a new task to be performed at some time in the future.
     *
     * @see add(const std::string&, GenericAsyncTask::TaskFunc*, void*, boost::optional<int>,
     * boost::optional<int>, const boost::optional<std::string>&, GenericAsyncTask::DeathFunc*);
     */
    FunctionalTask* do_method_later(float delay_time,
        const FunctionalTask::TaskFunc& func, const std::string& name,
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {},
        const FunctionalTask::DeathFunc& upon_death=nullptr);

    /**
     * Add a task to the task manager.
     *
     * @param   task        AsyncTask pointer.
     * @param   name        the name to assign to the Task.
     *
     * @param   sort        the sort value to assign the task.  The default sort is 0.
     *                      Within a particular task chain, it is guaranteed that the
     *                      tasks with a lower sort value will all run before tasks with a
     *                      higher sort value run.
     *
     * @param   priority    the priority at which to run the task.  The default
     *                      priority is 0.  Higher priority tasks are run sooner, and/or
     *                      more often.
     *
     * @param   task_chain  the name of the task chain to assign the task to.
     *
     * @return  pointer of the task object
     */
    AsyncTask* add(AsyncTask* task, const std::string& name = {},
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    /**
     * Add a new task to the task manager.
     *
     * @see add(const std::string&, AsyncTask*, boost::optional<int>, boost::optional<int>, const boost::optional<std::string>&)
     *
     * @param   func        GenericAsyncTask function.
     * @param   user_data   argument to pass to the task function.
     *
     * @param   upon_death  a function to call when the task terminates,
     *                      either because it has run to completion, or because it has
     *                      been explicitly removed.
     *
     * @return  pointer of a new task object
     */
    FunctionalTask* add(const FunctionalTask::TaskFunc& func, const std::string& name = {},
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {},
        const FunctionalTask::DeathFunc& upon_death = nullptr);

    int remove(const std::string& task_name);
    int remove(AsyncTask* task);

private:
    AsyncTask* setup_task(AsyncTask* task, const std::string& name = {},
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    AsyncTaskManager* mgr_;
    ClockObject* global_clock_;

public:
    static TypeHandle get_class_type();
    static void init_type();
    virtual TypeHandle get_type() const;
    virtual TypeHandle force_init_type();

private:
    static TypeHandle type_handle_;
};

// ************************************************************************************************

inline AsyncTaskManager* TaskManager::get_mgr() const
{
    return mgr_;
}

inline ClockObject* TaskManager::get_global_clock() const
{
    return global_clock_;
}

inline TypeHandle TaskManager::get_class_type()
{
    return type_handle_;
}

inline void TaskManager::init_type()
{
    TypedObject::init_type();
    register_type(type_handle_, "rppanda::TaskManager", TypedObject::get_class_type());
}

inline TypeHandle TaskManager::get_type() const
{
    return get_class_type();
}

inline TypeHandle TaskManager::force_init_type()
{
    init_type();
    return get_class_type();
}

}
<commit_msg>Remove default argument<commit_after>/**
 * Copyright (c) 2008, Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Carnegie Mellon University nor the names of
 *    other contributors may be used to endorse or promote products
 *    derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * (This is the Modified BSD License.  See also
 * http://www.opensource.org/licenses/bsd-license.php )
 */

/**
 * This is C++ porting codes of direct/src/task/task.py
 */

#include <asyncTaskCollection.h>

#include <boost/optional.hpp>

#include <render_pipeline/rpcore/config.hpp>
#include <render_pipeline/rppanda/task/functional_task.hpp>

class AsyncTaskManager;
class ClockObject;

namespace rppanda {

class RENDER_PIPELINE_DECL TaskManager : public TypedObject
{
public:
    static TaskManager* get_global_instance();

    TaskManager();

    AsyncTaskManager* get_mgr() const;
    ClockObject* get_global_clock() const;

    bool has_task_named(const std::string& task_name) const;

    AsyncTaskCollection get_task_named(const std::string& task_name) const;

    /**
     * Add a task to be performed at some time in the future.
     *
     * @see add(const std::string&, GenericAsyncTask::TaskFunc*, void*, boost::optional<int>,
     * boost::optional<int>, const boost::optional<std::string>&, GenericAsyncTask::DeathFunc*);
     */
    AsyncTask* do_method_later(float delay_time,
        AsyncTask* task, const std::string& name,
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    /**
     * Add a new task to be performed at some time in the future.
     *
     * @see add(const std::string&, GenericAsyncTask::TaskFunc*, void*, boost::optional<int>,
     * boost::optional<int>, const boost::optional<std::string>&, GenericAsyncTask::DeathFunc*);
     */
    FunctionalTask* do_method_later(float delay_time,
        const FunctionalTask::TaskFunc& func, const std::string& name,
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {},
        const FunctionalTask::DeathFunc& upon_death=nullptr);

    /**
     * Add a task to the task manager.
     *
     * @param   task        AsyncTask pointer.
     * @param   name        the name to assign to the Task.
     *                      This is required unless the task has already name.
     *
     * @param   sort        the sort value to assign the task.  The default sort is 0.
     *                      Within a particular task chain, it is guaranteed that the
     *                      tasks with a lower sort value will all run before tasks with a
     *                      higher sort value run.
     *
     * @param   priority    the priority at which to run the task.  The default
     *                      priority is 0.  Higher priority tasks are run sooner, and/or
     *                      more often.
     *
     * @param   task_chain  the name of the task chain to assign the task to.
     *
     * @return  pointer of the task object
     */
    AsyncTask* add(AsyncTask* task, const std::string& name = {},
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    /**
     * Add a new task to the task manager.
     *
     * @see add(const std::string&, AsyncTask*, boost::optional<int>, boost::optional<int>, const boost::optional<std::string>&)
     *
     * @param   func        GenericAsyncTask function.
     * @param   user_data   argument to pass to the task function.
     *
     * @param   upon_death  a function to call when the task terminates,
     *                      either because it has run to completion, or because it has
     *                      been explicitly removed.
     *
     * @return  pointer of a new task object
     */
    FunctionalTask* add(const FunctionalTask::TaskFunc& func, const std::string& name,
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {},
        const FunctionalTask::DeathFunc& upon_death = nullptr);

    int remove(const std::string& task_name);
    int remove(AsyncTask* task);

private:
    AsyncTask* setup_task(AsyncTask* task, const std::string& name = {},
        boost::optional<int> sort = {}, boost::optional<int> priority = {},
        const boost::optional<std::string>& task_chain = {});

    AsyncTaskManager* mgr_;
    ClockObject* global_clock_;

public:
    static TypeHandle get_class_type();
    static void init_type();
    virtual TypeHandle get_type() const;
    virtual TypeHandle force_init_type();

private:
    static TypeHandle type_handle_;
};

// ************************************************************************************************

inline AsyncTaskManager* TaskManager::get_mgr() const
{
    return mgr_;
}

inline ClockObject* TaskManager::get_global_clock() const
{
    return global_clock_;
}

inline TypeHandle TaskManager::get_class_type()
{
    return type_handle_;
}

inline void TaskManager::init_type()
{
    TypedObject::init_type();
    register_type(type_handle_, "rppanda::TaskManager", TypedObject::get_class_type());
}

inline TypeHandle TaskManager::get_type() const
{
    return get_class_type();
}

inline TypeHandle TaskManager::force_init_type()
{
    init_type();
    return get_class_type();
}

}
<|endoftext|>