<commit_before>#include "gridbuilder.h"

int GridBuilder::color = -1;

GridBuilder::GridBuilder()
{

}

Grid* GridBuilder::buildGrid(Grid* grid, int row, int col)
{
    int** adjacentPathMatrix = new int*[row];
    for(int i = 0; i < row; i++)
    {
        adjacentPathMatrix[i] = new int[col];
    }
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);

    while(!grid->isCompleted())
    {
        QPoint* pos;

        //If there is two adjacent free blocks that only connects to eachother do something
        pos = findPairOfLoneBlocks(grid, adjacentPathMatrix);
        if(pos->x() >= 0)
        {
            //TODO TRY TO FILL PAIR
            //try to fill pair of lone blocks, if you cant, restart
            destroyAdjacentPathMatrix(adjacentPathMatrix, row);
            return grid;
        }
        else
        {
            //If there is a standAlone free block, try to move an adjacent endPoint, otherwise impossible, restart from scratch
            pos = findLoneBlock(grid, adjacentPathMatrix);
            if(pos->x() >= 0)
            {
                //Move adjacent endPoint
                //if success keep on
                //else restart
                destroyAdjacentPathMatrix(adjacentPathMatrix, row);
                return grid;
            }
            else
            {
                //If there is a dead end, make it the start of a path
                pos = findDeadEnd(grid, adjacentPathMatrix);
                if(pos->x() >= 0)
                {
                    buildPathStartingPoint(pos, grid);
                }
                else
                {
                    //Start random path from here
                    QPoint* point = getRandomFreeBlock(grid);
                    if(point->x() < 0) return grid;
                    buildPathStartingPoint(point, grid);
                }
            }
        }
    }

    destroyAdjacentPathMatrix(adjacentPathMatrix, row);

    return grid;
}

Grid* GridBuilder::buildGrid(int row, int col)
{
    std::srand(std::time(0));
    Grid* grid = new Grid(row, col);

    while(!grid->isCompleted())
    {
        color = -1;
        delete grid;
        grid = new Grid(row, col);
        buildGrid(grid, row, col);
    }
}

void GridBuilder::buildPathStartingPoint(QPoint* startingPos, Grid* grid)
{
    color++;
    Path path = grid->getPath(startingPos->x(), startingPos->y());

    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);
    //path.setCovered(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);

    grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
    //path.setOrigin(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setFirstOrigin(true);
    //path.setFirstOrigin(true);

    buildPath(startingPos, grid);
}

//TODO build Path starting at startingPos
void GridBuilder::buildPath(QPoint* startingPos, Grid* grid)
{
    int possibleMoves = numberOfFreeAdjacentPositions(startingPos, grid);
    Path path = grid->getPath(startingPos->x(), startingPos->y());

    //path.setCovered(true);
    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);

    //setting color
    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);

    if(possibleMoves == 0)
    {
        //path.setOrigin(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
        //path.setPathComplete(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
    }
    else if(possibleMoves == 1)
    {
        QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
        Path nextPath = grid->getPath(nextPathPos->x(), nextPathPos->y());
        //nextPath.setCovered(true);
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);
        //nextPath.previous[0] = &path;
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(true);

        //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;
        grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);

        buildPath(nextPathPos, grid);
    }
    else
    {

        if(path.isOrigin() || getRandomNumberFrom0To(grid->getNbColumn() / 2) != 1)
        {

            QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
            Path nextPath = grid->getPath(nextPathPos->x(), nextPathPos->y());

            //nextPath.setCovered(true);
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);

            //nextPath.previous[0] = &path;
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

            grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);
            //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(color);

            buildPath(nextPathPos, grid);
        }
        else
        {
            grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);
            //path.setOrigin(true);
            //path.setPathComplete(true);
        }
    }

}

QPoint* GridBuilder::findDeadEnd(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 1, adjacentPathMatrix);
}

QPoint*  GridBuilder::findLoneBlock(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 0, adjacentPathMatrix);
}

int GridBuilder::numberOfFreeAdjacentPositions(QPoint* pos, Grid* grid)
{
    int count = 0;

    //up
    if(pos->x() - 1 >= 0 && !grid->getPath(pos->x() - 1, pos->y()).isCovered()) count++;
    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getPath(pos->x() + 1, pos->y()).isCovered()) count++;
    //left
    if(pos->y() - 1 >= 0 && !grid->getPath(pos->x(), pos->y() - 1).isCovered()) count++;
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getPath(pos->x(), pos->y() + 1).isCovered()) count++;

    return count;
}

QPoint*  GridBuilder::findXAdjacentFreeBlocks(Grid* grid, int x, int** adjacentPathMatrix)
{
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);
    int row = grid->getNbRow();
    int col = grid->getNbColumn();
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(adjacentPathMatrix[i][j] == x && !grid->getPath(i,j).isCovered())
            {
                return new QPoint(i,j);
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::fillAdjacentPathMatrix(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            QPoint* point = new QPoint(i,j);
            adjacentPathMatrix[i][j] = numberOfFreeAdjacentPositions(point, grid);

        }
    }
}

QPoint* GridBuilder::findPairOfLoneBlocks(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(adjacentPathMatrix[i][j] == 1 && !grid->getPath(i,j).isCovered())
            {
                //if there is another single one to the right or under we have a pair
                if((i + 1 < grid->getNbRow() && adjacentPathMatrix[i+1][j] == 1 && !grid->getPath(i+1,j).isCovered())
                        || (j + 1 < grid->getNbColumn() && adjacentPathMatrix[i][j+1] == 1 && !grid->getPath(i,j+1).isCovered()))
                {
                    return new QPoint(i,j);
                }
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::destroyAdjacentPathMatrix(int **adjacentPathMatrix, int row)
{
    for(int i = 0; i < row; ++i){
        delete[] adjacentPathMatrix[i];
    }

    delete[] adjacentPathMatrix;
}

QPoint* GridBuilder::getRandomFreeBlock(Grid* grid)
{
    int nbOfFreeBlocks = 0;
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getPath(i,j).isCovered()) nbOfFreeBlocks++;
        }
    }

    if(nbOfFreeBlocks == 0) nbOfFreeBlocks++;

    int pos = getRandomNumberFrom0To(nbOfFreeBlocks);

    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getPath(i,j).isCovered())
            {
                pos--;
                if(pos == 0)
                {
                    return new QPoint(i,j);
                }
            }
        }
    }

    //Should never hit this
    qDebug() << "\nERROR\nERROR\nERROR\nERROR\nERROR SHOULD NEVER HIT THIS\n";
    return new QPoint(-1,-1);
}

int GridBuilder::getRandomNumberFrom0To(int max)
{
     // use current time as seed for random generator
    return std::rand() % max;
}

QPoint* GridBuilder::getRandomAdjacentFreeBlock(QPoint* pos, Grid* grid)
{
    QPoint qp = QPoint(pos->x(), pos->y());
    int num = numberOfFreeAdjacentPositions(&qp, grid);
    int direction = getRandomNumberFrom0To(num);

    //up
    if(pos->x() - 1 >= 0 && !grid->getPath(pos->x() - 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() - 1, pos->y());
        --direction;
    }

    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getPath(pos->x() + 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() + 1, pos->y());
        --direction;
    }
    //left
    if(pos->y() - 1 >= 0 && !grid->getPath(pos->x(), pos->y() - 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() - 1);
        --direction;
    }
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getPath(pos->x(), pos->y() + 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() + 1);
        --direction;
    }

    //SHOULD NEVER HIT THIS
    qDebug() << "ERROR";
    return new QPoint(-1,-1);
}

bool GridBuilder::moveAdjacentEndPoint(QPoint* pos, Grid* grid)
{
    Path adjacentOrigin;
    //up
    if(pos->x() - 1 >= 0 && grid->getPath(pos->x() - 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x()-1, pos->y());
    }
    //down
    else if(pos->x() + 1 <= grid->getNbRow() - 1 && grid->getPath(pos->x() + 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x() + 1, pos->y());
    }
    //left
    else if(pos->y() - 1 >= 0 && grid->getPath(pos->x(), pos->y() - 1).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x(), pos->y() - 1);
    }
    //right
    else if(pos->y() + 1 <= grid->getNbColumn() - 1 && grid->getPath(pos->x(), pos->y() + 1).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x(), pos->y() + 1);
    }
    else
    {
        return false;
    }

    Path path = grid->getPath(pos->x(), pos->y());
    path.setOrigin(true);
    adjacentOrigin.setOrigin(false);
    adjacentOrigin.setPathComplete(false);
    if(adjacentOrigin.next == NULL)
    {
        path.setPathComplete(true);
        path.previous[0] = &adjacentOrigin;
        adjacentOrigin.next[0] = &path;
    }
    else
    {
        adjacentOrigin.previous[0] = &path;
        path.next[0] = &adjacentOrigin;
    }

    return true;
}
<commit_msg>Correction  d'une erreur, methode n'avais pas de return<commit_after>#include "gridbuilder.h"

int GridBuilder::color = -1;

GridBuilder::GridBuilder()
{

}

Grid* GridBuilder::buildGrid(Grid* grid, int row, int col)
{
    int** adjacentPathMatrix = new int*[row];
    for(int i = 0; i < row; i++)
    {
        adjacentPathMatrix[i] = new int[col];
    }
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);

    while(!grid->isCompleted())
    {
        QPoint* pos;

        //If there is two adjacent free blocks that only connects to eachother do something
        pos = findPairOfLoneBlocks(grid, adjacentPathMatrix);
        if(pos->x() >= 0)
        {
            //TODO TRY TO FILL PAIR
            //try to fill pair of lone blocks, if you cant, restart
            destroyAdjacentPathMatrix(adjacentPathMatrix, row);
            return grid;
        }
        else
        {
            //If there is a standAlone free block, try to move an adjacent endPoint, otherwise impossible, restart from scratch
            pos = findLoneBlock(grid, adjacentPathMatrix);
            if(pos->x() >= 0)
            {
                //Move adjacent endPoint
                //if success keep on
                //else restart
                destroyAdjacentPathMatrix(adjacentPathMatrix, row);
                return grid;
            }
            else
            {
                //If there is a dead end, make it the start of a path
                pos = findDeadEnd(grid, adjacentPathMatrix);
                if(pos->x() >= 0)
                {
                    buildPathStartingPoint(pos, grid);
                }
                else
                {
                    //Start random path from here
                    QPoint* point = getRandomFreeBlock(grid);
                    if(point->x() < 0) return grid;
                    buildPathStartingPoint(point, grid);
                }
            }
        }
    }

    destroyAdjacentPathMatrix(adjacentPathMatrix, row);

    return grid;
}

Grid* GridBuilder::buildGrid(int row, int col)
{
    std::srand(std::time(0));
    Grid* grid = new Grid(row, col);

    while(!grid->isCompleted())
    {
        color = -1;
        delete grid;
        grid = new Grid(row, col);
        buildGrid(grid, row, col);
    }

    return grid;
}

void GridBuilder::buildPathStartingPoint(QPoint* startingPos, Grid* grid)
{
    color++;
    //Path path = grid->getPath(startingPos->x(), startingPos->y());

    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);
    //path.setCovered(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);

    grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
    //path.setOrigin(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setFirstOrigin(true);
    //path.setFirstOrigin(true);

    buildPath(startingPos, grid);
}

//TODO build Path starting at startingPos
void GridBuilder::buildPath(QPoint* startingPos, Grid* grid)
{
    int possibleMoves = numberOfFreeAdjacentPositions(startingPos, grid);
    //Path path = grid->getPath(startingPos->x(), startingPos->y());

    //path.setCovered(true);
    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);

    //setting color
    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);

    if(possibleMoves == 0)
    {
        //path.setOrigin(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
        //path.setPathComplete(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
    }
    else if(possibleMoves == 1)
    {
        QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
        Path nextPath = grid->getPath(nextPathPos->x(), nextPathPos->y());
        //nextPath.setCovered(true);
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);
        //nextPath.previous[0] = &path;
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(true);

        //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;
        grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);

        buildPath(nextPathPos, grid);
    }
    else
    {

        if(grid->getGrid()[startingPos->x()][startingPos->y()].isOrigin() || getRandomNumberFrom0To(grid->getNbColumn() / 2) != 1)
        {

            QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
            //Path nextPath = grid->getPath(nextPathPos->x(), nextPathPos->y());

            //nextPath.setCovered(true);
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);

            //nextPath.previous[0] = &path;
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

            grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);
            //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(color);

            buildPath(nextPathPos, grid);
        }
        else
        {
            grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setColor(color);
            //path.setOrigin(true);
            //path.setPathComplete(true);
        }
    }

}

QPoint* GridBuilder::findDeadEnd(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 1, adjacentPathMatrix);
}

QPoint*  GridBuilder::findLoneBlock(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 0, adjacentPathMatrix);
}

int GridBuilder::numberOfFreeAdjacentPositions(QPoint* pos, Grid* grid)
{
    int count = 0;

    //up
    if(pos->x() - 1 >= 0 && !grid->getPath(pos->x() - 1, pos->y()).isCovered()) count++;
    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getPath(pos->x() + 1, pos->y()).isCovered()) count++;
    //left
    if(pos->y() - 1 >= 0 && !grid->getPath(pos->x(), pos->y() - 1).isCovered()) count++;
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getPath(pos->x(), pos->y() + 1).isCovered()) count++;

    return count;
}

QPoint*  GridBuilder::findXAdjacentFreeBlocks(Grid* grid, int x, int** adjacentPathMatrix)
{
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);
    int row = grid->getNbRow();
    int col = grid->getNbColumn();
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(adjacentPathMatrix[i][j] == x && !grid->getPath(i,j).isCovered())
            {
                return new QPoint(i,j);
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::fillAdjacentPathMatrix(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            QPoint* point = new QPoint(i,j);
            adjacentPathMatrix[i][j] = numberOfFreeAdjacentPositions(point, grid);

        }
    }
}

QPoint* GridBuilder::findPairOfLoneBlocks(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(adjacentPathMatrix[i][j] == 1 && !grid->getPath(i,j).isCovered())
            {
                //if there is another single one to the right or under we have a pair
                if((i + 1 < grid->getNbRow() && adjacentPathMatrix[i+1][j] == 1 && !grid->getPath(i+1,j).isCovered())
                        || (j + 1 < grid->getNbColumn() && adjacentPathMatrix[i][j+1] == 1 && !grid->getPath(i,j+1).isCovered()))
                {
                    return new QPoint(i,j);
                }
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::destroyAdjacentPathMatrix(int **adjacentPathMatrix, int row)
{
    for(int i = 0; i < row; ++i){
        delete[] adjacentPathMatrix[i];
    }

    delete[] adjacentPathMatrix;
}

QPoint* GridBuilder::getRandomFreeBlock(Grid* grid)
{
    int nbOfFreeBlocks = 0;
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getPath(i,j).isCovered()) nbOfFreeBlocks++;
        }
    }

    if(nbOfFreeBlocks == 0) nbOfFreeBlocks++;

    int pos = getRandomNumberFrom0To(nbOfFreeBlocks);

    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getPath(i,j).isCovered())
            {
                pos--;
                if(pos == 0)
                {
                    return new QPoint(i,j);
                }
            }
        }
    }

    //Should never hit this
    qDebug() << "\nERROR\nERROR\nERROR\nERROR\nERROR SHOULD NEVER HIT THIS\n";
    return new QPoint(-1,-1);
}

int GridBuilder::getRandomNumberFrom0To(int max)
{
     // use current time as seed for random generator
    return std::rand() % max;
}

QPoint* GridBuilder::getRandomAdjacentFreeBlock(QPoint* pos, Grid* grid)
{
    QPoint qp = QPoint(pos->x(), pos->y());
    int num = numberOfFreeAdjacentPositions(&qp, grid);
    int direction = getRandomNumberFrom0To(num);

    //up
    if(pos->x() - 1 >= 0 && !grid->getPath(pos->x() - 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() - 1, pos->y());
        --direction;
    }

    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getPath(pos->x() + 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() + 1, pos->y());
        --direction;
    }
    //left
    if(pos->y() - 1 >= 0 && !grid->getPath(pos->x(), pos->y() - 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() - 1);
        --direction;
    }
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getPath(pos->x(), pos->y() + 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() + 1);
        --direction;
    }

    //SHOULD NEVER HIT THIS
    qDebug() << "ERROR";
    return new QPoint(-1,-1);
}

bool GridBuilder::moveAdjacentEndPoint(QPoint* pos, Grid* grid)
{
    Path adjacentOrigin;
    //up
    if(pos->x() - 1 >= 0 && grid->getPath(pos->x() - 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x()-1, pos->y());
    }
    //down
    else if(pos->x() + 1 <= grid->getNbRow() - 1 && grid->getPath(pos->x() + 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x() + 1, pos->y());
    }
    //left
    else if(pos->y() - 1 >= 0 && grid->getPath(pos->x(), pos->y() - 1).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x(), pos->y() - 1);
    }
    //right
    else if(pos->y() + 1 <= grid->getNbColumn() - 1 && grid->getPath(pos->x(), pos->y() + 1).isOrigin())
    {
        adjacentOrigin = grid->getPath(pos->x(), pos->y() + 1);
    }
    else
    {
        return false;
    }

    Path path = grid->getPath(pos->x(), pos->y());
    path.setOrigin(true);
    adjacentOrigin.setOrigin(false);
    adjacentOrigin.setPathComplete(false);
    if(adjacentOrigin.next == NULL)
    {
        path.setPathComplete(true);
        path.previous[0] = &adjacentOrigin;
        adjacentOrigin.next[0] = &path;
    }
    else
    {
        adjacentOrigin.previous[0] = &path;
        path.next[0] = &adjacentOrigin;
    }

    return true;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
	File is modified to be merged with RingQt
	Updated by : Mahmoud Fayed <msfclipper@yahoo.com>
	Date	   : 2017.01.29
*/

#include <QtWidgets>

#include "codeeditor.h"
#include "ring.h"

CodeEditor::CodeEditor(QWidget *parent, VM *pVM) : GPlainTextEdit(parent,pVM) , c(0)
{
    lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));

    updateLineNumberAreaWidth(0);
}

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space*2;
}

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        lineNumberArea->scroll(0, dy);
    else
        lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{

    QPainter painter(lineNumberArea);

    QFont font = painter.font() ;
    font.setPointSize(fontMetrics().height());
    painter.setFont(font);

    painter.fillRect(event->rect(), Qt::cyan);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom()) {
        if (block.isVisible() && bottom >= event->rect().top()) {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, lineNumberArea->width(), bottom-top,
                             Qt::AlignCenter, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}

void CodeEditor::setCompleter(QCompleter *completer)
{
    if (c)
        QObject::disconnect(c, 0, this, 0);

    c = completer;

    if (!c)
        return;

    c->setWidget(this);
    c->setCompletionMode(QCompleter::PopupCompletion);
    c->setCaseSensitivity(Qt::CaseInsensitive);
    QObject::connect(c, SIGNAL(activated(QString)),
                     this, SLOT(insertCompletion(QString)));
}

QCompleter *CodeEditor::completer() const
{
    return c;
}

void CodeEditor::insertCompletion(const QString& completion)
{
    if (c->widget() != this)
        return;
    QTextCursor tc = textCursor();
    int extra = completion.length() - c->completionPrefix().length();
    tc.movePosition(QTextCursor::Left);
    tc.movePosition(QTextCursor::EndOfWord);
    tc.insertText(completion.right(extra));
    setTextCursor(tc);
}

QString CodeEditor::textUnderCursor() const
{
    QTextCursor tc = textCursor();
    tc.select(QTextCursor::WordUnderCursor);
    return tc.selectedText();
}

void CodeEditor::focusInEvent(QFocusEvent *e)
{
    if (c)
        c->setWidget(this);
    GPlainTextEdit::focusInEvent(e);
}

void CodeEditor::keyPressEvent(QKeyEvent *e)
{
    if (c && c->popup()->isVisible()) {
        // The following keys are forwarded by the completer to the widget
       switch (e->key()) {
       case Qt::Key_Enter:
       case Qt::Key_Return:
       case Qt::Key_Escape:
       case Qt::Key_Tab:
       case Qt::Key_Backtab:
            e->ignore();
            return; // let the completer do default behavior
       default:
           break;
       }
    }

    bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
    if (!c || !isShortcut) // do not process the shortcut when we have a completer
        GPlainTextEdit::keyPressEvent(e);

const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
    if (!c || (ctrlOrShift && e->text().isEmpty()))
        return;

    static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
    bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
    QString completionPrefix = textUnderCursor();

    if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
                      || eow.contains(e->text().right(1)))) {
        c->popup()->hide();
        return;
    }

    if (completionPrefix != c->completionPrefix()) {
        c->setCompletionPrefix(completionPrefix);
        c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
    }
    QRect cr = cursorRect();
    cr.setWidth(c->popup()->sizeHintForColumn(0)
                + c->popup()->verticalScrollBar()->sizeHint().width());
    c->complete(cr); // popup it up!
}<commit_msg>Update Ring for Android<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
	File is modified to be merged with RingQt
	Updated by : Mahmoud Fayed <msfclipper@yahoo.com>
	Date	   : 2017.01.29
*/

#include <QtWidgets>

#include "codeeditor.h"
#include "ring.h"

CodeEditor::CodeEditor(QWidget *parent, VM *pVM) : GPlainTextEdit(parent,pVM) , c(0)
{
    lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));

    updateLineNumberAreaWidth(0);
}

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space*2;
}

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        lineNumberArea->scroll(0, dy);
    else
        lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{

    QPainter painter(lineNumberArea);

    QFont font = painter.font() ;
    font.setPointSize(fontMetrics().height());
    painter.setFont(font);

    painter.fillRect(event->rect(), Qt::cyan);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom()) {
        if (block.isVisible() && bottom >= event->rect().top()) {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, lineNumberArea->width(), bottom-top,
                             Qt::AlignCenter, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}

void CodeEditor::setCompleter(QCompleter *completer)
{
    if (c)
        QObject::disconnect(c, 0, this, 0);

    c = completer;

    if (!c)
        return;

    c->setWidget(this);
    c->setCompletionMode(QCompleter::PopupCompletion);
    c->setCaseSensitivity(Qt::CaseInsensitive);
    QObject::connect(c, SIGNAL(activated(QString)),
                     this, SLOT(insertCompletion(QString)));
}

QCompleter *CodeEditor::completer() const
{
    return c;
}

void CodeEditor::insertCompletion(const QString& completion)
{
    if (c->widget() != this)
        return;
    QTextCursor tc = textCursor();
    int extra = completion.length() - c->completionPrefix().length();
    tc.movePosition(QTextCursor::Left);
    tc.movePosition(QTextCursor::EndOfWord);
    tc.insertText(completion.right(extra));
    setTextCursor(tc);
}

QString CodeEditor::textUnderCursor() const
{
    QTextCursor tc = textCursor();
    tc.select(QTextCursor::WordUnderCursor);
    return tc.selectedText();
}

void CodeEditor::focusInEvent(QFocusEvent *e)
{
    if (c)
        c->setWidget(this);
    GPlainTextEdit::focusInEvent(e);
}

void CodeEditor::keyPressEvent(QKeyEvent *e)
{
    if (c && c->popup()->isVisible()) {
        // The following keys are forwarded by the completer to the widget
       switch (e->key()) {
       case Qt::Key_Enter:
       case Qt::Key_Return:
       case Qt::Key_Escape:
       case Qt::Key_Tab:
       case Qt::Key_Backtab:
            e->ignore();
            return; // let the completer do default behavior
       default:
           break;
       }
    }

    bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
    if (!c || !isShortcut) // do not process the shortcut when we have a completer
        GPlainTextEdit::keyPressEvent(e);

const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
    if (!c || (ctrlOrShift && e->text().isEmpty()))
        return;

    static QString eow("~!#%^&*()+{}|:<>?,/;[]\\-="); // end of word
    bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
    QString completionPrefix = textUnderCursor();

    if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
                      || eow.contains(e->text().right(1)))) {
        c->popup()->hide();
        return;
    }

    if (completionPrefix != c->completionPrefix()) {
        c->setCompletionPrefix(completionPrefix);
        c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
    }
    QRect cr = cursorRect();
    cr.setWidth(c->popup()->sizeHintForColumn(0)
                + c->popup()->verticalScrollBar()->sizeHint().width());
    c->complete(cr); // popup it up!
}<|endoftext|>


<commit_before>//
// Created by Davide  Caroselli on 10/10/16.
//

#include <util/hashutils.h>
#include <iostream>
#include <algorithm>
#include "Collector.h"

using namespace mmt;
using namespace mmt::sapt;

Collector::Collector(CorpusStorage *storage, rocksdb::DB *db, length_t prefixLength, const context_t *context,
                     bool searchInBackground) : prefixLength(prefixLength), storage(storage) {
    phrase.reserve(20); // typical max phrase length

    if (context && !context->empty()) {
        inDomainStates.resize(context->size());

        for (size_t i = 0; i < context->size(); ++i) {
            inDomainStates[i].cursor.reset(
                    PrefixCursor::NewDomainCursor(db, prefixLength, context->at(i).domain)
            );
        }
    }

    if (searchInBackground) {
        backgroundState = new state_t();
        backgroundState->cursor.reset(PrefixCursor::NewGlobalCursor(db, prefixLength, context));
    }
}

void Collector::Extend(const vector<wid_t> &words, size_t limit, vector<sample_t> &outSamples) {
    phrase.insert(phrase.end(), words.begin(), words.end());
    unsigned int shuffleSeed = max(1U, words_hash(phrase));

    vector<location_t> locations;
    size_t availability = limit;

    // Get in-context samples

    for (auto state = inDomainStates.begin(); state != inDomainStates.end(); /* no increment */) {
        size_t collected = CollectLocations(state->cursor.get(), phrase, prefixLength, state->phraseOffset,
                                            state->postingList);

        state->phraseOffset = phrase.size();

        if (collected > 0) {
            bool breakLoop;

            if (limit == 0 || collected < availability) {
                state->postingList->GetLocations(locations);
                availability -= collected;
                breakLoop = false;
            } else {
                state->postingList->GetLocations(locations, availability, shuffleSeed);
                availability = 0;

                if (locations.size() > limit)
                    locations.resize(limit);

                breakLoop = true;
            }

            if (phrase.size() < prefixLength) {
                // No need to cache Posting Lists shorter than prefixLength
                state->postingList.reset();
            }

            if (breakLoop)
                break;

            ++state;
        } else {
            state = inDomainStates.erase(state);
        }
    }

    // Get out-context samples

    if (backgroundState && (limit == 0 || availability > 0)) {
        size_t collected = CollectLocations(backgroundState->cursor.get(), phrase, prefixLength,
                                            backgroundState->phraseOffset, backgroundState->postingList);
        backgroundState->phraseOffset = phrase.size();

        if (collected > 0) {
            backgroundState->postingList->GetLocations(locations, limit == 0 ? 0 : availability);

            if (phrase.size() < prefixLength) {
                // No need to cache Posting Lists shorter than prefixLength
                backgroundState->postingList.reset();
            }
        } else {
            delete backgroundState;
            backgroundState = NULL;
        }
    }

    // Retrieve samples

    outSamples.clear();

    if (locations.size() > 0) {
        sort(locations.begin(), locations.end(), [](const location_t &a, const location_t &b) {
            return a.pointer == b.pointer ? a.offset > b.offset : a.pointer > b.pointer;
        });

        Retrieve(locations, outSamples);
    }
}

size_t Collector::CollectLocations(PrefixCursor *cursor, const vector<wid_t> &phrase,
                                   length_t prefixLength, size_t offset, shared_ptr<PostingList> &postingList) {
    if (offset == 0)
        assert(postingList == NULL);

    // collect the locations
    size_t phraseLength = phrase.size();

    if (phraseLength < prefixLength) {
        CollectPhraseLocations(cursor, phrase, 0, phrase.size(), postingList);
    } else {
        size_t start = offset;

        while (start < phraseLength) {
            if (start + prefixLength > phraseLength)
                start = phraseLength - prefixLength;

            if (start == 0) {
                CollectPhraseLocations(cursor, phrase, start, prefixLength, postingList);
            } else {
                shared_ptr<PostingList> successors;
                CollectPhraseLocations(cursor, phrase, start, prefixLength, successors);

                postingList->Retain(successors.get(), start);
            }

            if (postingList->empty())
                break;

            start += prefixLength;
        }
    }

    return postingList == NULL ? 0 : postingList->size();
}

void Collector::CollectPhraseLocations(PrefixCursor *cursor, const vector<wid_t> &phrase, size_t offset, size_t length,
                                       shared_ptr<PostingList> &postingList) {
    if (postingList == NULL)
        postingList.reset(new PostingList());

    for (cursor->Seek(phrase, offset, length); cursor->HasNext(); cursor->Next())
        cursor->CollectValue(postingList.get());
}

void Collector::Retrieve(const vector<location_t> &locations, vector<sample_t> &outSamples) {
    outSamples.reserve(outSamples.size() + locations.size());

    sample_t *lastSample = NULL;
    int64_t lastPointer = -1;

    for (auto location = locations.begin(); location != locations.end(); ++location) {
        if (lastSample && lastPointer == location->pointer) {
            lastSample->offsets.push_back(location->offset);
        } else {
            sample_t sample;
            sample.domain = location->domain;
            sample.offsets.push_back(location->offset);
            storage->Retrieve(location->pointer, &sample.source, &sample.target, &sample.alignment);

            outSamples.push_back(sample);

            lastPointer = location->pointer;
            lastSample = &(outSamples[outSamples.size() - 1]);
        }
    }
}<commit_msg>get rid of non-determinism of translation; removed time-based random sampling<commit_after>//
// Created by Davide  Caroselli on 10/10/16.
//

#include <util/hashutils.h>
#include <iostream>
#include <algorithm>
#include "Collector.h"

using namespace mmt;
using namespace mmt::sapt;

Collector::Collector(CorpusStorage *storage, rocksdb::DB *db, length_t prefixLength, const context_t *context,
                     bool searchInBackground) : prefixLength(prefixLength), storage(storage) {
    phrase.reserve(20); // typical max phrase length

    if (context && !context->empty()) {
        inDomainStates.resize(context->size());

        for (size_t i = 0; i < context->size(); ++i) {
            inDomainStates[i].cursor.reset(
                    PrefixCursor::NewDomainCursor(db, prefixLength, context->at(i).domain)
            );
        }
    }

    if (searchInBackground) {
        backgroundState = new state_t();
        backgroundState->cursor.reset(PrefixCursor::NewGlobalCursor(db, prefixLength, context));
    }
}

void Collector::Extend(const vector<wid_t> &words, size_t limit, vector<sample_t> &outSamples) {
    phrase.insert(phrase.end(), words.begin(), words.end());
    unsigned int shuffleSeed = max(1U, words_hash(phrase));

    vector<location_t> locations;
    size_t availability = limit;

    // Get in-context samples

    for (auto state = inDomainStates.begin(); state != inDomainStates.end(); /* no increment */) {
        size_t collected = CollectLocations(state->cursor.get(), phrase, prefixLength, state->phraseOffset,
                                            state->postingList);

        state->phraseOffset = phrase.size();

        if (collected > 0) {
            bool breakLoop;

            if (limit == 0 || collected < availability) {
                state->postingList->GetLocations(locations);
                availability -= collected;
                breakLoop = false;
            } else {
                state->postingList->GetLocations(locations, availability, shuffleSeed);
                availability = 0;

                if (locations.size() > limit)
                    locations.resize(limit);

                breakLoop = true;
            }

            if (phrase.size() < prefixLength) {
                // No need to cache Posting Lists shorter than prefixLength
                state->postingList.reset();
            }

            if (breakLoop)
                break;

            ++state;
        } else {
            state = inDomainStates.erase(state);
        }
    }

    // Get out-context samples

    if (backgroundState && (limit == 0 || availability > 0)) {
        size_t collected = CollectLocations(backgroundState->cursor.get(), phrase, prefixLength,
                                            backgroundState->phraseOffset, backgroundState->postingList);
        backgroundState->phraseOffset = phrase.size();

        if (collected > 0) {
            backgroundState->postingList->GetLocations(locations, limit == 0 ? 0 : availability, shuffleSeed);

            if (phrase.size() < prefixLength) {
                // No need to cache Posting Lists shorter than prefixLength
                backgroundState->postingList.reset();
            }
        } else {
            delete backgroundState;
            backgroundState = NULL;
        }
    }

    // Retrieve samples

    outSamples.clear();

    if (locations.size() > 0) {
        sort(locations.begin(), locations.end(), [](const location_t &a, const location_t &b) {
            return a.pointer == b.pointer ? a.offset > b.offset : a.pointer > b.pointer;
        });

        Retrieve(locations, outSamples);
    }
}

size_t Collector::CollectLocations(PrefixCursor *cursor, const vector<wid_t> &phrase,
                                   length_t prefixLength, size_t offset, shared_ptr<PostingList> &postingList) {
    if (offset == 0)
        assert(postingList == NULL);

    // collect the locations
    size_t phraseLength = phrase.size();

    if (phraseLength < prefixLength) {
        CollectPhraseLocations(cursor, phrase, 0, phrase.size(), postingList);
    } else {
        size_t start = offset;

        while (start < phraseLength) {
            if (start + prefixLength > phraseLength)
                start = phraseLength - prefixLength;

            if (start == 0) {
                CollectPhraseLocations(cursor, phrase, start, prefixLength, postingList);
            } else {
                shared_ptr<PostingList> successors;
                CollectPhraseLocations(cursor, phrase, start, prefixLength, successors);

                postingList->Retain(successors.get(), start);
            }

            if (postingList->empty())
                break;

            start += prefixLength;
        }
    }

    return postingList == NULL ? 0 : postingList->size();
}

void Collector::CollectPhraseLocations(PrefixCursor *cursor, const vector<wid_t> &phrase, size_t offset, size_t length,
                                       shared_ptr<PostingList> &postingList) {
    if (postingList == NULL)
        postingList.reset(new PostingList());

    for (cursor->Seek(phrase, offset, length); cursor->HasNext(); cursor->Next())
        cursor->CollectValue(postingList.get());
}

void Collector::Retrieve(const vector<location_t> &locations, vector<sample_t> &outSamples) {
    outSamples.reserve(outSamples.size() + locations.size());

    sample_t *lastSample = NULL;
    int64_t lastPointer = -1;

    for (auto location = locations.begin(); location != locations.end(); ++location) {
        if (lastSample && lastPointer == location->pointer) {
            lastSample->offsets.push_back(location->offset);
        } else {
            sample_t sample;
            sample.domain = location->domain;
            sample.offsets.push_back(location->offset);
            storage->Retrieve(location->pointer, &sample.source, &sample.target, &sample.alignment);

            outSamples.push_back(sample);

            lastPointer = location->pointer;
            lastSample = &(outSamples[outSamples.size() - 1]);
        }
    }
}

<|endoftext|>


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

#include "monitor.h"

#include "monitor_p.h"
#include "monitoradaptor.h"

namespace QZeitgeist
{

// Monitor's DBus Object Path.
const QString objPath = "/org/gnome/zeitgeist/monitor";

// Monitor's DBus Service Name.
const QString serviceName = "org.gnome.zeitgeist.Monitor";

// Implements the private section. D pointer.
MonitorPrivate::MonitorPrivate(quint64 monitorId,
        QZeitgeist::DataModel::TimeRange monitorTimeRange,
        QZeitgeist::DataModel::EventList monitorTemplates,
        Monitor *parent)
    : QObject(parent),
    id(monitorId),
    timeRange(monitorTimeRange),
    eventTemplates(monitorTemplates),
    q(parent)
{
    // Create the needed DBus Monitor Adaptor.
    monitorAdaptor = new MonitorAdaptor(this);

    regObjPath = QString(objPath + "/%1").arg(id);

    QDBusConnection connection = QDBusConnection::sessionBus();
    connection.registerService(serviceName);
    connection.registerObject(regObjPath, this);
}

MonitorPrivate::~MonitorPrivate()
{
    // Free the interface.
    delete monitorAdaptor;
}

void MonitorPrivate::NotifyDelete(
        const QZeitgeist::DataModel::TimeRange &timeRange,
        const QZeitgeist::DataModel::EventIdList &eventIds)
{
    emit q->eventsDeleted(timeRange, eventIds);
}

void MonitorPrivate::NotifyInsert(
        const QZeitgeist::DataModel::TimeRange &timeRange,
        const QZeitgeist::DataModel::EventList &events)
{
    emit q->eventsInserted(timeRange, events);
}

// Implements the Monitor class.
Monitor::Monitor(quint64 id,
        QZeitgeist::DataModel::TimeRange timeRange,
        QZeitgeist::DataModel::EventList templates,
        QObject *parent)
    : QObject(parent),
    d(new MonitorPrivate(id, timeRange, templates, this))
{
    Q_ASSERT(d);
}

Monitor::~Monitor()
{
    delete d;
}

QString Monitor::objectPath() const
{
    return d->regObjPath;
}

quint64 Monitor::id() const
{
    return d->id;
}

QZeitgeist::DataModel::TimeRange Monitor::timeRange() const
{
    return d->timeRange;
}

QZeitgeist::DataModel::EventList Monitor::eventTemplates() const
{
    return d->eventTemplates;
}

};
<commit_msg>Don't register a global service<commit_after>/*
 * This file is part of QZeitgeist.
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "monitor.h"

#include "monitor_p.h"
#include "monitoradaptor.h"

namespace QZeitgeist
{

// Monitor's DBus Object Path.
const QString objPath = "/org/gnome/zeitgeist/monitor";

// Implements the private section. D pointer.
MonitorPrivate::MonitorPrivate(quint64 monitorId,
        QZeitgeist::DataModel::TimeRange monitorTimeRange,
        QZeitgeist::DataModel::EventList monitorTemplates,
        Monitor *parent)
    : QObject(parent),
    id(monitorId),
    timeRange(monitorTimeRange),
    eventTemplates(monitorTemplates),
    q(parent)
{
    // Create the needed DBus Monitor Adaptor.
    monitorAdaptor = new MonitorAdaptor(this);

    regObjPath = QString(objPath + "/%1").arg(id);

    QDBusConnection connection = QDBusConnection::sessionBus();
    connection.registerObject(regObjPath, this);
}

MonitorPrivate::~MonitorPrivate()
{
    // Free the interface.
    delete monitorAdaptor;
}

void MonitorPrivate::NotifyDelete(
        const QZeitgeist::DataModel::TimeRange &timeRange,
        const QZeitgeist::DataModel::EventIdList &eventIds)
{
    emit q->eventsDeleted(timeRange, eventIds);
}

void MonitorPrivate::NotifyInsert(
        const QZeitgeist::DataModel::TimeRange &timeRange,
        const QZeitgeist::DataModel::EventList &events)
{
    emit q->eventsInserted(timeRange, events);
}

// Implements the Monitor class.
Monitor::Monitor(quint64 id,
        QZeitgeist::DataModel::TimeRange timeRange,
        QZeitgeist::DataModel::EventList templates,
        QObject *parent)
    : QObject(parent),
    d(new MonitorPrivate(id, timeRange, templates, this))
{
    Q_ASSERT(d);
}

Monitor::~Monitor()
{
    delete d;
}

QString Monitor::objectPath() const
{
    return d->regObjPath;
}

quint64 Monitor::id() const
{
    return d->id;
}

QZeitgeist::DataModel::TimeRange Monitor::timeRange() const
{
    return d->timeRange;
}

QZeitgeist::DataModel::EventList Monitor::eventTemplates() const
{
    return d->eventTemplates;
}

};
<|endoftext|>


<commit_before>#define assert(x) __nop()

#include "types.cpp"

u64 PlatformGetFileSize(const char* path);
u32 PlatformLoadFile(const char* path, void* memory, u32 memorySize);
bool PlatformWriteFile(const char* path, void* memory, u32 bytesToWrite);

#ifdef GAME_PROJECT
#include "game.cpp"
#elif defined(RESOURCE_CONVERTER_PROJECT)
#include "resource_converter.cpp"
#else
#error "You did not specified project type!"
#endif

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <stdlib.h>
#include <stdio.h>

u64 PlatformGetFileSize(const char* path)
{
  struct stat fileStats;
  i32 statResult = stat(path, &fileStats);

  if (statResult != 0)
    return 0;

  return fileStats.st_size;
}

u32 PlatformLoadFile(const char* path, void* memory, u32 memorySize)
{
  i32 file = open(path, O_RDONLY);

  if (file == -1)
    return 0;

  ssize_t readResult = read(file, memory, memorySize);
  close(file);

  return readResult == -1 ? 0 : readResult;
}

bool PlatformWriteFile(const char* path, void* memory, u32 bytesToWrite)
{
  // TODO: handle directory creation

  i32 file = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0660);
  if (file == -1)
    return false;

  ssize_t writeResult = write(file, memory, bytesToWrite);
  close(file);

  return writeResult == bytesToWrite;
}

void Linux32SetupRenderingBuffers(
    RenderTarget* renderTarget,
    u32 width,
    u32 height,
    void* buffersMemory,
    u32 buffersMemorySize)
{
  u8* memory = (u8*)buffersMemory;
  renderTarget->texture = (Texture*)memory;
  memory += sizeof(Texture) + width * height * sizeof(Color32);
  renderTarget->texture->width = width;
  renderTarget->texture->height = height;

  renderTarget->zBuffer = (float*)memory;
  memory += sizeof(float) * width * height;
}

void DrawAQuad() {
}

int main(int argc, char** argv)
{
  //*****CREATING A WINDOW*****//
  Display* display = XOpenDisplay((char *)0);

  GLint glAttributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
  XVisualInfo* visualInfo = glXChooseVisual(display, 0, glAttributes);
  Window rootWindow = DefaultRootWindow(display);
  Colormap colorMap = XCreateColormap(display, rootWindow, visualInfo->visual, AllocNone);

  XSetWindowAttributes setWindowAttributes;
  setWindowAttributes.colormap = colorMap;
  setWindowAttributes.event_mask = ExposureMask | KeyPressMask;

  u32 windowWidth = 640;
  u32 windowHeight = 480;
  Window window = XCreateWindow(display, rootWindow, 0, 0, 600, 600, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWColormap | CWEventMask, &setWindowAttributes);
  XMapWindow(display, window);
  XSetStandardProperties(display, window,"Software Renderer","Hoi!",None,NULL,0,NULL);
  XSelectInput(display, window, ButtonPressMask | KeyPressMask | StructureNotifyMask);

  GLXContext glContext = glXCreateContext(display, visualInfo, NULL, GL_TRUE);
  glXMakeCurrent(display, window, glContext);

   //*****ALLOCATING MEMORY*****//
  u32 platformMemorySize = 128 * Mb;
  void* platformMemory = malloc(platformMemorySize);
  assert(platformMemory);

  u32 gameMemorySize = 512 * Mb;
  void* gameMemory = malloc(gameMemorySize);
  assert(gameMemory);

  //*****SETUP RENDERING STUFF*****//
  RenderTarget renderBuffer{};
  Linux32SetupRenderingBuffers(
      &renderBuffer,
      windowWidth,
      windowHeight,
      platformMemory,
      platformMemorySize);

  GLuint renderTexture;
  glGenTextures(1, &renderTexture);
  glBindTexture(GL_TEXTURE_2D, renderTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glEnable(GL_TEXTURE_2D);

  XEvent event;
  KeySym key;
  Input input{};

  GameInitialize(gameMemory, gameMemorySize);

  bool continueRunning = true;
  do
  {
    while (XPending(display))
    {
      XNextEvent(display, &event);
      switch (event.type)
      {
        case KeyPress:
        {
          char text[255];
          if (KeyPress && XLookupString(&event.xkey, text, 255, &key, 0) == 1)
          {
            if (text[0] == 'q')
              continueRunning = false;

          }
        } break;
        case ButtonPress:
        {
          printf("You pressed a button at (%i,%i)\n", event.xbutton.x,event.xbutton.y);
        } break;
        case ConfigureNotify:
        {
          XConfigureEvent xce = event.xconfigure;

          if (xce.width != windowWidth ||
              xce.height != windowHeight)
          {
            windowWidth = xce.width;
            windowHeight = xce.height;

            Linux32SetupRenderingBuffers(
                &renderBuffer,
                windowWidth,
                windowHeight,
                platformMemory,
                platformMemorySize);
          }
        } break;
      };
    }

    // GAME UPDATE
    bool gameWantsToContinue = GameUpdate(
        0.1f,
        gameMemory,
        gameMemorySize,
        &renderBuffer,
        &input);

    continueRunning &= gameWantsToContinue;

    // PUT FRAME ON THE SCREEN
    XWindowAttributes windowAttributes;
    XGetWindowAttributes(display, window, &windowAttributes);
    glViewport(0, 0, windowAttributes.width, windowAttributes.height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, 0.5f, 1.5f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);

    glBindTexture(GL_TEXTURE_2D, renderTexture);
    glTexImage2D(
      GL_TEXTURE_2D,
      0,
      GL_RGBA,
      renderBuffer.texture->width,
      renderBuffer.texture->height,
      0,
      GL_RGBA,
      GL_UNSIGNED_BYTE,
      ((u8*)renderBuffer.texture) + sizeof(Texture));

    glBegin(GL_QUADS);
      glTexCoord2f(0, 0);
      glVertex3f( 0, 0, 0);

      glTexCoord2f(1, 0);
      glVertex3f( 1, 0, 0);

      glTexCoord2f(1, 1);
      glVertex3f( 1, 1, 0);

      glTexCoord2f(0, 1);
      glVertex3f( 0, 1, 0);
    glEnd();

    glXSwapBuffers(display, window);

    GLenum glError;
    while ((glError = glGetError()) != GL_NO_ERROR)
    {
      printf("OpenGL error: %s\n", gluErrorString(glError));
    }
    //return 0;

  } while (continueRunning);

  glXMakeCurrent(display, None, NULL);
  glXDestroyContext(display, glContext);
  XDestroyWindow(display,window);
  XCloseDisplay(display);
  return 0;
}
<commit_msg>add frame time computation<commit_after>#define assert(x) __nop()

#include "types.cpp"

u64 PlatformGetFileSize(const char* path);
u32 PlatformLoadFile(const char* path, void* memory, u32 memorySize);
bool PlatformWriteFile(const char* path, void* memory, u32 bytesToWrite);

#ifdef GAME_PROJECT
#include "game.cpp"
#elif defined(RESOURCE_CONVERTER_PROJECT)
#include "resource_converter.cpp"
#else
#error "You did not specified project type!"
#endif

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

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

u64 PlatformGetFileSize(const char* path)
{
  struct stat fileStats;
  i32 statResult = stat(path, &fileStats);

  if (statResult != 0)
    return 0;

  return fileStats.st_size;
}

u32 PlatformLoadFile(const char* path, void* memory, u32 memorySize)
{
  i32 file = open(path, O_RDONLY);

  if (file == -1)
    return 0;

  ssize_t readResult = read(file, memory, memorySize);
  close(file);

  return readResult == -1 ? 0 : readResult;
}

bool PlatformWriteFile(const char* path, void* memory, u32 bytesToWrite)
{
  // TODO: handle directory creation

  i32 file = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0660);
  if (file == -1)
    return false;

  ssize_t writeResult = write(file, memory, bytesToWrite);
  close(file);

  return writeResult == bytesToWrite;
}

void Linux32SetupRenderingBuffers(
    RenderTarget* renderTarget,
    u32 width,
    u32 height,
    void* buffersMemory,
    u32 buffersMemorySize)
{
  u8* memory = (u8*)buffersMemory;
  renderTarget->texture = (Texture*)memory;
  memory += sizeof(Texture) + width * height * sizeof(Color32);
  renderTarget->texture->width = width;
  renderTarget->texture->height = height;

  renderTarget->zBuffer = (float*)memory;
  memory += sizeof(float) * width * height;
}

timespec TimespecDiff(timespec start, timespec end)
{
  timespec temp;
  if ((end.tv_nsec-start.tv_nsec)<0)
  {
    temp.tv_sec = end.tv_sec-start.tv_sec-1;
    temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
  }
  else
  {
    temp.tv_sec = end.tv_sec-start.tv_sec;
    temp.tv_nsec = end.tv_nsec-start.tv_nsec;
  }

  return temp;
}

int main(int argc, char** argv)
{
  //*****CREATING A WINDOW*****//
  Display* display = XOpenDisplay((char *)0);

  GLint glAttributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
  XVisualInfo* visualInfo = glXChooseVisual(display, 0, glAttributes);
  Window rootWindow = DefaultRootWindow(display);
  Colormap colorMap = XCreateColormap(display, rootWindow, visualInfo->visual, AllocNone);

  XSetWindowAttributes setWindowAttributes;
  setWindowAttributes.colormap = colorMap;
  setWindowAttributes.event_mask = ExposureMask | KeyPressMask;

  u32 windowWidth = 640;
  u32 windowHeight = 480;
  Window window = XCreateWindow(display, rootWindow, 0, 0, 600, 600, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWColormap | CWEventMask, &setWindowAttributes);
  XMapWindow(display, window);
  XSetStandardProperties(display, window,"Software Renderer","Hoi!",None,NULL,0,NULL);
  XSelectInput(display, window, ButtonPressMask | KeyPressMask | StructureNotifyMask);

  GLXContext glContext = glXCreateContext(display, visualInfo, NULL, GL_TRUE);
  glXMakeCurrent(display, window, glContext);

   //*****ALLOCATING MEMORY*****//
  u32 platformMemorySize = 128 * Mb;
  void* platformMemory = malloc(platformMemorySize);
  assert(platformMemory);

  u32 gameMemorySize = 512 * Mb;
  void* gameMemory = malloc(gameMemorySize);
  assert(gameMemory);

  //*****SETUP RENDERING STUFF*****//
  RenderTarget renderBuffer{};
  Linux32SetupRenderingBuffers(
      &renderBuffer,
      windowWidth,
      windowHeight,
      platformMemory,
      platformMemorySize);

  GLuint renderTexture;
  glGenTextures(1, &renderTexture);
  glBindTexture(GL_TEXTURE_2D, renderTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glEnable(GL_TEXTURE_2D);

  XEvent event;
  KeySym key;
  Input input{};

  GameInitialize(gameMemory, gameMemorySize);

  bool continueRunning = true;
  float deltaTime = 0;
  do
  {
    timespec startFrameTime;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &startFrameTime);

    while (XPending(display))
    {
      XNextEvent(display, &event);
      switch (event.type)
      {
        case KeyPress:
        {
          char text[255];
          if (KeyPress && XLookupString(&event.xkey, text, 255, &key, 0) == 1)
          {
            if (text[0] == 'q')
              continueRunning = false;

          }
        } break;
        case ButtonPress:
        {
          printf("You pressed a button at (%i,%i)\n", event.xbutton.x,event.xbutton.y);
        } break;
        case ConfigureNotify:
        {
          XConfigureEvent xce = event.xconfigure;

          if (xce.width != windowWidth ||
              xce.height != windowHeight)
          {
            windowWidth = xce.width;
            windowHeight = xce.height;

            Linux32SetupRenderingBuffers(
                &renderBuffer,
                windowWidth,
                windowHeight,
                platformMemory,
                platformMemorySize);
          }
        } break;
      };
    }

    // GAME UPDATE
    bool gameWantsToContinue = GameUpdate(
        deltaTime,
        gameMemory,
        gameMemorySize,
        &renderBuffer,
        &input);

    continueRunning &= gameWantsToContinue;

    // PUT FRAME ON THE SCREEN
    XWindowAttributes windowAttributes;
    XGetWindowAttributes(display, window, &windowAttributes);
    glViewport(0, 0, windowAttributes.width, windowAttributes.height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, 0.5f, 1.5f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);

    glBindTexture(GL_TEXTURE_2D, renderTexture);
    glTexImage2D(
      GL_TEXTURE_2D,
      0,
      GL_RGBA,
      renderBuffer.texture->width,
      renderBuffer.texture->height,
      0,
      GL_RGBA,
      GL_UNSIGNED_BYTE,
      ((u8*)renderBuffer.texture) + sizeof(Texture));

    glBegin(GL_QUADS);
      glTexCoord2f(0, 0);
      glVertex3f( 0, 0, 0);

      glTexCoord2f(1, 0);
      glVertex3f( 1, 0, 0);

      glTexCoord2f(1, 1);
      glVertex3f( 1, 1, 0);

      glTexCoord2f(0, 1);
      glVertex3f( 0, 1, 0);
    glEnd();

    glXSwapBuffers(display, window);

    GLenum glError;
    while ((glError = glGetError()) != GL_NO_ERROR)
    {
      printf("OpenGL error: %s\n", gluErrorString(glError));
    }

    timespec endFrameTime;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &endFrameTime);
    timespec elapsedTime = TimespecDiff(startFrameTime, endFrameTime);
    i32 elapsedMlsec = elapsedTime.tv_nsec / 1000 / 1000;
    elapsedMlsec += elapsedTime.tv_sec * 1000;
    deltaTime = float(elapsedMlsec) / 1000.0f;

    char windowTitle[255];
    snprintf(windowTitle, 255, "Software Renderer: %3dms", elapsedMlsec);
    XStoreName(display, window, windowTitle);

  } while (continueRunning);

  glXMakeCurrent(display, None, NULL);
  glXDestroyContext(display, glContext);
  XDestroyWindow(display,window);
  XCloseDisplay(display);
  return 0;
}
<|endoftext|>


<commit_before>#include "adapted.h"
#include <boost/date_time/posix_time/posix_time.hpp>

namespace nt = navitia::type;
namespace bg = boost::gregorian;
namespace pt = boost::posix_time;

namespace navimake{

void delete_vj(types::VehicleJourney* vehicle_journey, const nt::Message& message, Data& data){
    //TODO on duplique les validitypattern à tord et à travers la, va falloir les mutualiser
    types::ValidityPattern* vp = NULL;
    if(vehicle_journey->adapted_validity_pattern == NULL){//on duplique le validity pattern
        vp = new types::ValidityPattern(*vehicle_journey->validity_pattern);
    }else{
        vp = new types::ValidityPattern(*vehicle_journey->adapted_validity_pattern);
    }
    data.validity_patterns.push_back(vp);
    vehicle_journey->adapted_validity_pattern = vp;

    for(size_t i=0; i < vp->days.size(); ++i){
        bg::date current_date = vp->beginning_date + bg::days(i);
        if(!vp->check(i) || current_date < message.application_period.begin().date()
                || current_date > message.application_period.end().date()){
            continue;
        }
        pt::ptime begin(current_date, pt::seconds(vehicle_journey->stop_time_list.front()->departure_time));
        //si le départ du vj est dans la plage d'appliation du message, on le supprime
        if(message.is_applicable(pt::time_period(begin, pt::seconds(1)))){
            vp->remove(current_date);
        }

    }

}

void AtAdaptedLoader::init_map(const Data& data){
    for(auto* vj : data.vehicle_journeys){
        vj_map[vj->uri] = vj;
        if(vj->tmp_line != NULL){
            line_vj_map[vj->tmp_line->uri].push_back(vj);
            if(vj->tmp_line->network != NULL){
                network_vj_map[vj->tmp_line->network->uri].push_back(vj);
            }
        }
    }
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::reconcile_impact_with_vj(const navitia::type::Message& message, const Data& data){
    std::vector<types::VehicleJourney*> result;

    if(message.object_type == navitia::type::Type_e::VehicleJourney){
        if(vj_map.find(message.object_uri) != vj_map.end()){
            //cas simple; le message pointe sur un seul vj
            result.push_back(vj_map[message.object_uri]);
        }
    }
    if(message.object_type == navitia::type::Type_e::Line){
        if(line_vj_map.find(message.object_uri) != line_vj_map.end()){
            //on à deja le mapping line => vjs
            return line_vj_map[message.object_uri];
        }
    }
    if(message.object_type == navitia::type::Type_e::Network){
        if(network_vj_map.find(message.object_uri) != network_vj_map.end()){
            return network_vj_map[message.object_uri];
        }
    }
//
    return result;
}

void AtAdaptedLoader::apply(const std::map<std::string, std::vector<navitia::type::Message>>& messages, Data& data){
    init_map(data);
    //on construit la liste des impacts pour chacun des vj impacté
    std::map<types::VehicleJourney*, std::vector<navitia::type::Message>> vj_messages_mapping;
    for(const std::pair<std::string, std::vector<navitia::type::Message>> & message_list : messages){
        for(auto message : message_list.second){
            for(auto* vj : reconcile_impact_with_vj(message, data)){
                vj_messages_mapping[vj].push_back(message);
            }
        }
    }
    std::cout << "nombre de VJ impactés: " << vj_messages_mapping.size() << std::endl;
    for(auto pair : vj_messages_mapping){
        apply_on_vj(pair.first, pair.second, data);
    }

}

void AtAdaptedLoader::apply_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(m.object_type == nt::Type_e::VehicleJourney || m.object_type == nt::Type_e::Line
                || m.object_type == nt::Type_e::Route || m.object_type == nt::Type_e::Network){
            if(vehicle_journey->stop_time_list.size() > 0){
                delete_vj(vehicle_journey, m, data);

            }
        }
    }

}

}//namespace
<commit_msg>adapted : prise en compte du validitypattern adapté déjà crée<commit_after>#include "adapted.h"
#include <boost/date_time/posix_time/posix_time.hpp>

namespace nt = navitia::type;
namespace bg = boost::gregorian;
namespace pt = boost::posix_time;

namespace navimake{

void delete_vj(types::VehicleJourney* vehicle_journey, const nt::Message& message, Data& data){
    //TODO on duplique les validitypattern à tort et à travers la, va falloir les mutualiser
    types::ValidityPattern* vp = NULL;
//    if(vehicle_journey->adapted_validity_pattern == NULL){//on duplique le validity pattern
//        vp = new types::ValidityPattern(*vehicle_journey->validity_pattern);
//    }else{
    vp = new types::ValidityPattern(*vehicle_journey->adapted_validity_pattern);
//    }
    data.validity_patterns.push_back(vp);
    vehicle_journey->adapted_validity_pattern = vp;

    for(size_t i=0; i < vp->days.size(); ++i){
        bg::date current_date = vp->beginning_date + bg::days(i);
        if(!vp->check(i) || current_date < message.application_period.begin().date()
                || current_date > message.application_period.end().date()){
            continue;
        }
        pt::ptime begin(current_date, pt::seconds(vehicle_journey->stop_time_list.front()->departure_time));
        //si le départ du vj est dans la plage d'appliation du message, on le supprime
        if(message.is_applicable(pt::time_period(begin, pt::seconds(1)))){
            vp->remove(current_date);
        }

    }

}

void AtAdaptedLoader::init_map(const Data& data){
    for(auto* vj : data.vehicle_journeys){
        vj_map[vj->uri] = vj;
        if(vj->tmp_line != NULL){
            line_vj_map[vj->tmp_line->uri].push_back(vj);
            if(vj->tmp_line->network != NULL){
                network_vj_map[vj->tmp_line->network->uri].push_back(vj);
            }
        }
    }
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::reconcile_impact_with_vj(const navitia::type::Message& message, const Data& data){
    std::vector<types::VehicleJourney*> result;

    if(message.object_type == navitia::type::Type_e::VehicleJourney){
        if(vj_map.find(message.object_uri) != vj_map.end()){
            //cas simple; le message pointe sur un seul vj
            result.push_back(vj_map[message.object_uri]);
        }
    }
    if(message.object_type == navitia::type::Type_e::Line){
        if(line_vj_map.find(message.object_uri) != line_vj_map.end()){
            //on à deja le mapping line => vjs
            return line_vj_map[message.object_uri];
        }
    }
    if(message.object_type == navitia::type::Type_e::Network){
        if(network_vj_map.find(message.object_uri) != network_vj_map.end()){
            return network_vj_map[message.object_uri];
        }
    }
//
    return result;
}

void AtAdaptedLoader::apply(const std::map<std::string, std::vector<navitia::type::Message>>& messages, Data& data){
    init_map(data);
    //on construit la liste des impacts pour chacun des vj impacté
    std::map<types::VehicleJourney*, std::vector<navitia::type::Message>> vj_messages_mapping;
    for(const std::pair<std::string, std::vector<navitia::type::Message>> & message_list : messages){
        for(auto message : message_list.second){
            for(auto* vj : reconcile_impact_with_vj(message, data)){
                vj_messages_mapping[vj].push_back(message);
            }
        }
    }
    std::cout << "nombre de VJ impactés: " << vj_messages_mapping.size() << std::endl;
    for(auto pair : vj_messages_mapping){
        apply_on_vj(pair.first, pair.second, data);
    }

}

void AtAdaptedLoader::apply_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(m.object_type == nt::Type_e::VehicleJourney || m.object_type == nt::Type_e::Line
                || m.object_type == nt::Type_e::Route || m.object_type == nt::Type_e::Network){
            if(vehicle_journey->stop_time_list.size() > 0){
                delete_vj(vehicle_journey, m, data);

            }
        }
    }

}

}//namespace
<|endoftext|>