<commit_before>#include "Background.hpp"

Background::Background() {
}

Background::Background(std::string lvlDesc) {
    init(lvlDesc);
}

Background::~Background() {

}

void Background::init(std::string lvlDesc) {
    readLevel(lvlDesc);
    _doors.setPosition(0,0);
    _background.setPosition(0,0);
    _background.setTexture(_bTexture);
}

bool Background::colision(float x, float y){
    return colision(sf::Vector2f(x,y));
}

bool Background::colision(sf::Vector2f pos) {
    for(int i = 0; i < _boundaries.size(); ++i){
        if(_boundaries[i].contains(pos)) return true;
    }
    return false;
}

void Background::draw(sf::RenderTarget *target){
    target->draw(_background);

    if(_doorOpenedL && _doorOpenedR){
        _doors.setTexture(Resources::doors_OO);
    }
    else if( _doorOpenedL && ! _doorOpenedR){
        _doors.setTexture(Resources::doors_OX);
    }
    else if(! _doorOpenedL && ! _doorOpenedR){
        _doors.setTexture(Resources::doors_XX);
    }
    target->draw(_doors);

    //DEBUG DRAW RED RECTANGLES
  /*  for(int i = 0; i < _boundaries.size(); ++i){
        sf::RectangleShape RS(sf::Vector2f(_boundaries[i].width,_boundaries[i].height));
        RS.setPosition(sf::Vector2f(_boundaries[i].left,_boundaries[i].top));
        RS.setFillColor(sf::Color::Red);
        target->draw(RS);
    }
*/
}

bool Background::circleColision(sf::Vector2f pos, float rad) {
    for(int i = 0; i < _boundaries.size(); ++i){

        if(    _boundaries[i].contains(pos.x+rad, pos.y)
            || _boundaries[i].contains(pos.x-rad, pos.y)
            || _boundaries[i].contains(pos.x, pos.y+rad)
            || _boundaries[i].contains(pos.x, pos.y-rad)
                                                                    ){
            return true;
        }
        else if(       getModule(pos, sf::Vector2f(_boundaries[i].left,_boundaries[i].top)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left+_boundaries[i].width,_boundaries[i].top)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left,_boundaries[i].top+_boundaries[i].height)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left+_boundaries[i].width,_boundaries[i].top+_boundaries[i].height)) < rad
                       ){
            return true;
        }
    }
    return false;
}

//#include <iostream>
#include <complex>

using namespace std;

typedef complex<double> point;

double error=1e-7;

double prodesc(point p1,point p2)
{
  return real(conj(p1)*p2);
}

double prodvec(point p1,point p2)
{
  return imag(conj(p1)*p2);
}

point calculainterseccio(point p1,point v1,point p2,point v2)
{
  return p1+(prodvec(p2-p1,v2)/prodvec(v1,v2))*v1;
}

pair<bool,point> intersecciosemirectasegment(point p1,point v1,point a,point b)
{
  point p2=a;
  point v2=b-a;

  if (abs(prodvec(v1,v2))<error) return pair<bool,point> (false,0.0);

  point interseccio=calculainterseccio(p1,v1,p2,v2);

  if (prodesc(interseccio-p1,v1)<-error) return pair<bool,point> (false,0.0);
  if (prodesc(interseccio-p2,v2)<-error) return pair<bool,point> (false,0.0);
  if (prodesc(interseccio-b,v2)>error) return pair<bool,point> (false,0.0);
  return pair<bool,point> (true,interseccio);
}

sf::Vector2i Background::getIntersection(sf::Vector2i position, sf::Vector2i mousePos){

    sf::Vector2i ret(0,0);

    pair <bool,point> result;
    result.second.real(0);
    result.second.imag(0);
    result.first = false;

    point pos(position.x, position.y);
    point vec(mousePos.x - position.x, mousePos.y - position.y);
    for(int i = 0; i < _boundaries.size(); ++i){

        point a, b;

        //TOP
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top));
        b.real( double( _boundaries[i].left + _boundaries[i].width));
        b.imag( double( _boundaries[i].top));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first &&
                (abs(pos-result.second) > abs(pos- point(ret.x, ret.y))))
                    ret = sf::Vector2i(result.second.real(),result.second.imag());

/*
        //LEFT
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top));
        b.real( double( _boundaries[i].left));
        b.imag( double( _boundaries[i].top - _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first) ret = sf::Vector2i(result.second.real(),result.second.imag());

        //BOT
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top - _boundaries[i].height));
        b.real( double( _boundaries[i].left+ _boundaries[i].width));
        b.imag( double( _boundaries[i].top - _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first) ret = sf::Vector2i(result.second.real(),result.second.imag());

        //RIGHT
        result.first = false;
        a.real( double( _boundaries[i].left+ _boundaries[i].width));
        a.imag( double( _boundaries[i].top ));
        b.real( double( _boundaries[i].left+ _boundaries[i].width));
        b.imag( double( _boundaries[i].top - _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first) ret = sf::Vector2i(result.second.real(),result.second.imag());
*/

    }

    if(ret.x != 0) ret.x = mousePos.x;
    if(ret.y != 0) ret.y = mousePos.y;
    //retorna minim
    return ret;

}

sf::Vector2i Background::getIntersection(sf::Vector2i mousePos){

    sf::Vector2i ret(1,1);

    for(int i = 0; i < _boundaries.size(); ++i){
        if(_boundaries[i].contains(sf::Vector2f(mousePos.x,mousePos.y))){
            ret.x = _boundaries[i].left;
            ret.y = _boundaries[i].top;
      //      ret.x = mousePos.x;
      //      ret.y = mousePos.y;
        }

    }

    return ret;

}

void Background::readLevel(std::string lvlDesc) {
    std::string line;
    std::ifstream myfile (LVLDESCIPTPATH+lvlDesc+".txt");

    if (myfile.is_open()) {

        std::getline (myfile,line);
        while(line[0] == '#') std::getline (myfile,line);
        if(! _bTexture.loadFromFile(TEXTURETPATH+line) ) std::cout << "error on loading bacground texture" << std::endl;

        std::getline (myfile,line);
        while (line[0] != '$') {
            if(line[0] != '#'){
                if(line == "doors"){
                    std::getline (myfile,line);
                    while(line[0] == '#') std::getline (myfile,line);
                    if(line == "OO"){
                        _doorOpenedL = _doorOpenedR = true;
                    }
                    else if(line == "OX"){
                        _doorOpenedL = true;
                        _doorOpenedR = false;
                    }
                    else if(line == "XX"){
                        _doorOpenedL = _doorOpenedR = false;
                    }

                }

                if(line == "boundaries"){
                    //log("boundaries");

                    std::getline (myfile,line);
                    while(line[0] == '#') std::getline (myfile,line);

                    while(line == "next"){

                        sf::FloatRect fr;
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.left = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.top = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.width = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.height = myStoi(line);

                        _boundaries.push_back(fr);

                        //read next that would be next if ther are more or end (or something else ) if it is done
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);

                    }

                }
            }
            std::getline (myfile,line);
            while(line[0] == '#') std::getline (myfile,line);
        }
        //std::cout << "bg finishes with line  " << line << std::endl;
        myfile.close();
    } else std::cout << "not oppened backgroound file " << lvlDesc << std::endl;
}
<commit_msg>fixed colisions omg so goood<commit_after>#include "Background.hpp"

Background::Background() {
}

Background::Background(std::string lvlDesc) {
    init(lvlDesc);
}

Background::~Background() {

}

void Background::init(std::string lvlDesc) {
    readLevel(lvlDesc);
    _doors.setPosition(0,0);
    _background.setPosition(0,0);
    _background.setTexture(_bTexture);
}

bool Background::colision(float x, float y){
    return colision(sf::Vector2f(x,y));
}

bool Background::colision(sf::Vector2f pos) {
    for(int i = 0; i < _boundaries.size(); ++i){
        if(_boundaries[i].contains(pos)) return true;
    }
    return false;
}

void Background::draw(sf::RenderTarget *target){
    target->draw(_background);

    if(_doorOpenedL && _doorOpenedR){
        _doors.setTexture(Resources::doors_OO);
    }
    else if( _doorOpenedL && ! _doorOpenedR){
        _doors.setTexture(Resources::doors_OX);
    }
    else if(! _doorOpenedL && ! _doorOpenedR){
        _doors.setTexture(Resources::doors_XX);
    }
    target->draw(_doors);

    //DEBUG DRAW RED RECTANGLES
  /*  for(int i = 0; i < _boundaries.size(); ++i){
        sf::RectangleShape RS(sf::Vector2f(_boundaries[i].width,_boundaries[i].height));
        RS.setPosition(sf::Vector2f(_boundaries[i].left,_boundaries[i].top));
        RS.setFillColor(sf::Color::Red);
        target->draw(RS);
    }
*/
}

bool Background::circleColision(sf::Vector2f pos, float rad) {
    for(int i = 0; i < _boundaries.size(); ++i){

        if(    _boundaries[i].contains(pos.x+rad, pos.y)
            || _boundaries[i].contains(pos.x-rad, pos.y)
            || _boundaries[i].contains(pos.x, pos.y+rad)
            || _boundaries[i].contains(pos.x, pos.y-rad)
                                                                    ){
            return true;
        }
        else if(       getModule(pos, sf::Vector2f(_boundaries[i].left,_boundaries[i].top)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left+_boundaries[i].width,_boundaries[i].top)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left,_boundaries[i].top+_boundaries[i].height)) < rad
                    || getModule(pos, sf::Vector2f(_boundaries[i].left+_boundaries[i].width,_boundaries[i].top+_boundaries[i].height)) < rad
                       ){
            return true;
        }
    }
    return false;
}

//#include <iostream>
#include <complex>

using namespace std;

typedef complex<double> point;

double error=1e-7;

double prodesc(point p1,point p2)
{
  return real(conj(p1)*p2);
}

double prodvec(point p1,point p2)
{
  return imag(conj(p1)*p2);
}

point calculainterseccio(point p1,point v1,point p2,point v2)
{
  return p1+(prodvec(p2-p1,v2)/prodvec(v1,v2))*v1;
}

pair<bool,point> intersecciosemirectasegment(point p1,point v1,point a,point b)
{
  point p2=a;
  point v2=b-a;

  if (abs(prodvec(v1,v2))<error) return pair<bool,point> (false,0.0);

  point interseccio=calculainterseccio(p1,v1,p2,v2);

  if (prodesc(interseccio-p1,v1)<-error) return pair<bool,point> (false,0.0);
  if (prodesc(interseccio-p2,v2)<-error) return pair<bool,point> (false,0.0);
  if (prodesc(interseccio-b,v2)>error) return pair<bool,point> (false,0.0);
  return pair<bool,point> (true,interseccio);
}

sf::Vector2i Background::getIntersection(sf::Vector2i position, sf::Vector2i mousePos){

    sf::Vector2i ret(-2000,-2000);

    pair <bool,point> result;
    result.second.real(0);
    result.second.imag(0);
    result.first = false;

    point pos(position.x, position.y);
    point vec(mousePos.x - position.x, mousePos.y - position.y);
    for(int i = 0; i < _boundaries.size(); ++i){

        point a, b;

        //TOP
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top));
        b.real( double( _boundaries[i].left + _boundaries[i].width));
        b.imag( double( _boundaries[i].top));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first &&
                (abs(pos-result.second) < abs(pos- point(ret.x, ret.y))))
                    ret = sf::Vector2i(result.second.real(),result.second.imag());

        //LEFT
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top));
        b.real( double( _boundaries[i].left));
        b.imag( double( _boundaries[i].top + _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first &&
                (abs(pos-result.second) < abs(pos- point(ret.x, ret.y))))
                    ret = sf::Vector2i(result.second.real(),result.second.imag());

        //BOT
        result.first = false;
        a.real( double( _boundaries[i].left));
        a.imag( double( _boundaries[i].top + _boundaries[i].height));
        b.real( double( _boundaries[i].left+ _boundaries[i].width));
        b.imag( double( _boundaries[i].top + _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first &&
                (abs(pos-result.second) < abs(pos- point(ret.x, ret.y))))
                    ret = sf::Vector2i(result.second.real(),result.second.imag());

        //RIGHT
        result.first = false;
        a.real( double( _boundaries[i].left+ _boundaries[i].width));
        a.imag( double( _boundaries[i].top ));
        b.real( double( _boundaries[i].left+ _boundaries[i].width));
        b.imag( double( _boundaries[i].top + _boundaries[i].height));
        result = intersecciosemirectasegment(pos, vec, a, b);
        if(result.first &&
                (abs(pos-result.second) < abs(pos- point(ret.x, ret.y))))
                    ret = sf::Vector2i(result.second.real(),result.second.imag());

    }

//    if(ret.x != 0) ret.x = mousePos.x;
  //  if(ret.y != 0) ret.y = mousePos.y;
    //retorna minim
    return ret;

}

sf::Vector2i Background::getIntersection(sf::Vector2i mousePos){

    sf::Vector2i ret(1,1);

    for(int i = 0; i < _boundaries.size(); ++i){
        if(_boundaries[i].contains(sf::Vector2f(mousePos.x,mousePos.y))){
            ret.x = _boundaries[i].left;
            ret.y = _boundaries[i].top;
      //      ret.x = mousePos.x;
      //      ret.y = mousePos.y;
        }

    }

    return ret;

}

void Background::readLevel(std::string lvlDesc) {
    std::string line;
    std::ifstream myfile (LVLDESCIPTPATH+lvlDesc+".txt");

    if (myfile.is_open()) {

        std::getline (myfile,line);
        while(line[0] == '#') std::getline (myfile,line);
        if(! _bTexture.loadFromFile(TEXTURETPATH+line) ) std::cout << "error on loading bacground texture" << std::endl;

        std::getline (myfile,line);
        while (line[0] != '$') {
            if(line[0] != '#'){
                if(line == "doors"){
                    std::getline (myfile,line);
                    while(line[0] == '#') std::getline (myfile,line);
                    if(line == "OO"){
                        _doorOpenedL = _doorOpenedR = true;
                    }
                    else if(line == "OX"){
                        _doorOpenedL = true;
                        _doorOpenedR = false;
                    }
                    else if(line == "XX"){
                        _doorOpenedL = _doorOpenedR = false;
                    }

                }

                if(line == "boundaries"){
                    //log("boundaries");

                    std::getline (myfile,line);
                    while(line[0] == '#') std::getline (myfile,line);

                    while(line == "next"){

                        sf::FloatRect fr;
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.left = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.top = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.width = myStoi(line);
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);
                        fr.height = myStoi(line);

                        _boundaries.push_back(fr);

                        //read next that would be next if ther are more or end (or something else ) if it is done
                        std::getline (myfile,line);
                        while(line[0] == '#') std::getline (myfile,line);

                    }

                }
            }
            std::getline (myfile,line);
            while(line[0] == '#') std::getline (myfile,line);
        }
        //std::cout << "bg finishes with line  " << line << std::endl;
        myfile.close();
    } else std::cout << "not oppened backgroound file " << lvlDesc << std::endl;
}
<|endoftext|>


<commit_before>/*
 * Based on The New Chronotext Toolkit
 * Copyright (C) 2014, Ariel Malka - All rights reserved.
 *
 * Adaption to Alfons
 * Copyright (C) 2015, Hannes Janetzek
 *
 * The following source-code is distributed under the Simplified BSD License.
 */

#include "textBatch.h"
#include "font.h"
#include "alfons.h"
#include "atlas.h"
#include "utils.h"

#include "logger.h"

#include <glm/vec2.hpp>

namespace alfons {

LineMetrics NO_METRICS;

TextBatch::TextBatch(GlyphAtlas& _atlas, MeshCallback& _mesh)
    : m_atlas(_atlas), m_mesh(_mesh) {
    m_clip.x1 = 0;
    m_clip.y1 = 0;
    m_clip.x2 = 0;
    m_clip.y2 = 0;
}

void TextBatch::setClip(const Rect& _clipRect) {
    m_clip = _clipRect;
    m_hasClip = true;
}

void TextBatch::setClip(float x1, float y1, float x2, float y2) {
    m_clip.x1 = x1;
    m_clip.y1 = y1;
    m_clip.x2 = x2;
    m_clip.y2 = y2;

    m_hasClip = true;
}

bool TextBatch::clip(Rect& _rect) const {
    if (_rect.x1 > m_clip.x2 || _rect.x2 < m_clip.x1 ||
        _rect.y1 > m_clip.y2 || _rect.y2 < m_clip.y1) {
        return true;
    }
    return false;
}

bool TextBatch::clip(Quad& _quad) const {
    return ((_quad.x1 > m_clip.x2 && _quad.x2 > m_clip.x2 &&
             _quad.x3 > m_clip.x2 && _quad.x4 > m_clip.x2) ||
            (_quad.y1 > m_clip.y2 && _quad.y2 > m_clip.y2 &&
             _quad.y3 > m_clip.y2 && _quad.y4 > m_clip.y2) ||
            (_quad.x1 < m_clip.x1 && _quad.x2 < m_clip.x1 &&
             _quad.x3 < m_clip.x1 && _quad.x4 < m_clip.x1) ||
            (_quad.y1 < m_clip.y1 && _quad.y2 < m_clip.y1 &&
             _quad.y3 < m_clip.y1 && _quad.y4 < m_clip.y1));
    return false;

}

void TextBatch::setupRect(const Shape& _shape, const glm::vec2& _position,
                          float _sizeRatio, Rect& _rect, AtlasGlyph& _atlasGlyph) {

    glm::vec2 ul = _position + (_shape.position + _atlasGlyph.glyph->offset) * _sizeRatio;
    _rect.x1 = ul.x;
    _rect.y1 = ul.y;
    _rect.x2 = ul.x + _atlasGlyph.glyph->size.x * _sizeRatio;
    _rect.y2 = ul.y + _atlasGlyph.glyph->size.y * _sizeRatio;
}

void TextBatch::drawShape(const Font& _font, const Shape& _shape,
                          const glm::vec2& _position, float _scale,
                          LineMetrics& _metrics) {

    AtlasGlyph atlasGlyph;
    if (!m_atlas.getGlyph(_font, {_shape.face, _shape.codepoint}, atlasGlyph)) {
        return;
    }

    Rect rect;
    setupRect(_shape, _position, _scale, rect, atlasGlyph);

    if (m_hasClip && clip(rect)) {
        return;
    }

    m_mesh.drawGlyph(rect, atlasGlyph);

    if (&_metrics != &NO_METRICS) {
        _metrics.addExtents({rect.x1, rect.y1, rect.x2, rect.y2});
    }
}

void TextBatch::drawTransformedShape(const Font& _font, const Shape& _shape,
                                     const glm::vec2& _position, float _scale,
                                     LineMetrics& _metrics) {
    AtlasGlyph atlasGlyph;
    if (!m_atlas.getGlyph(_font, {_shape.face, _shape.codepoint}, atlasGlyph)) {
        return;
    }

    Rect rect;
    setupRect(_shape, _position, _scale, rect, atlasGlyph);

    Quad quad;
    m_matrix.transformRect(rect, quad);

    if (m_hasClip && clip(quad)) {
        return;
    }

    m_mesh.drawGlyph(quad, atlasGlyph);

    // FIXME: account for matrix transform
    // return glm::vec4(atlasGlyph.glyph->u1,
    //     atlasGlyph.glyph->u2,
    //     atlasGlyph.glyph->v1,
    //     atlasGlyph.glyph->v2);
}

glm::vec2 TextBatch::draw(const LineLayout& _line, glm::vec2 _position, LineMetrics& _metrics) {
    return draw(_line, 0, _line.shapes().size(), _position, _metrics);
}

glm::vec2 TextBatch::drawShapeRange(const LineLayout& _line, size_t _start, size_t _end,
                                    glm::vec2 _position, LineMetrics& _metrics) {

    for (size_t j = _start; j < _end; j++) {
        auto& c = _line.shapes()[j];
        if (!c.isSpace) {
            drawShape(_line.font(), c, _position, _line.scale(), _metrics);
        }

        _position.x += _line.advance(c);
    }
    return _position;
}

glm::vec2 TextBatch::draw(const LineLayout& _line, size_t _start, size_t _end,
                          glm::vec2 _position, LineMetrics& _metrics) {

    float startX = _position.x;

    for (size_t j = _start; j < _end; j++) {
        auto& c = _line.shapes()[j];
        if (!c.isSpace) {
            drawShape(_line.font(), c, _position, _line.scale(), _metrics);
        }

        _position.x += _line.advance(c);
        if (c.mustBreak) {
            _position.x = startX;
            _position.y += _line.height();
        }
    }

    _position.y += _line.height();

    return _position;
}

glm::vec2 TextBatch::draw(const LineLayout& _line, glm::vec2 _position, float _width, LineMetrics& _metrics) {

    if (_line.shapes().empty()) { return _position; }

    float lineWidth = 0;
    float startX = _position.x;

    float adv = 0;
    size_t shapeCount = 0;

    float lastWidth = 0;
    size_t lastShape = 0;
    size_t startShape = 0;

    for (auto& shape : _line.shapes()) {

        if (!shape.cluster) {
            shapeCount++;
            lineWidth += _line.advance(shape);
            continue;
        }

        shapeCount++;
        lineWidth += _line.advance(shape);

        // is break - or must break?
        if (shape.canBreak || shape.mustBreak) {
            lastShape = shapeCount;
            lastWidth = lineWidth;
        }

        if (lastShape != 0 && (lineWidth > _width || shape.mustBreak)) {
            auto& endShape = _line.shapes()[lastShape-1];
            if (endShape.isSpace) {
                lineWidth -= _line.advance(endShape);
                lastWidth -= _line.advance(endShape);
            }

            adv = std::max(adv, drawShapeRange(_line, startShape, lastShape,
                                               _position, _metrics).x);

            lineWidth -= lastWidth;

            startShape = lastShape;
            lastShape = 0;

            _position.y += _line.height();
            _position.x = startX;
            lineWidth = 0;
        }
    }

    if (startShape < _line.shapes().size()-1) {
        adv = std::max(adv, drawShapeRange(_line, startShape,
                                           _line.shapes().size()-1,
                                           _position, _metrics).x);
        _position.y += _line.height();
    }

    _position.x = adv;
    return _position;
}

float TextBatch::draw(const LineLayout& _line, const LineSampler& _path,
                      float _offsetX, float _offsetY) {

    bool reverse = false; //(line.direction() == HB_DIRECTION_RTL);
    float direction = reverse ? -1 : 1;
    // float sampleSize = 0.1 * line.height();

    auto& font = _line.font();
    float scale = _line.scale();

    glm::vec2 position;
    float angle;

    for (auto& shape : DirectionalRange(_line.shapes(), reverse)) {
        //float half = 0.5f * line.advance(shape) * direction;
        float half = 0.5f * shape.advance * scale * direction;
        _offsetX += half;

        if (!shape.isSpace) {
            _path.get(_offsetX, position, angle);

            m_matrix.setTranslation(position);

            //m_matrix.rotateZ(path.offset2SampledAngle(offsetX, sampleSize));
            m_matrix.rotateZ(angle);

            drawTransformedShape(font, shape, -half, _offsetY, scale);
        }
        _offsetX += half;
    }
    return _offsetX;
}

}
<commit_msg>Fix linewrapping bug<commit_after>/*
 * Based on The New Chronotext Toolkit
 * Copyright (C) 2014, Ariel Malka - All rights reserved.
 *
 * Adaption to Alfons
 * Copyright (C) 2015, Hannes Janetzek
 *
 * The following source-code is distributed under the Simplified BSD License.
 */

#include "textBatch.h"
#include "font.h"
#include "alfons.h"
#include "atlas.h"
#include "utils.h"

#include "logger.h"

#include <glm/vec2.hpp>

namespace alfons {

LineMetrics NO_METRICS;

TextBatch::TextBatch(GlyphAtlas& _atlas, MeshCallback& _mesh)
    : m_atlas(_atlas), m_mesh(_mesh) {
    m_clip.x1 = 0;
    m_clip.y1 = 0;
    m_clip.x2 = 0;
    m_clip.y2 = 0;
}

void TextBatch::setClip(const Rect& _clipRect) {
    m_clip = _clipRect;
    m_hasClip = true;
}

void TextBatch::setClip(float x1, float y1, float x2, float y2) {
    m_clip.x1 = x1;
    m_clip.y1 = y1;
    m_clip.x2 = x2;
    m_clip.y2 = y2;

    m_hasClip = true;
}

bool TextBatch::clip(Rect& _rect) const {
    if (_rect.x1 > m_clip.x2 || _rect.x2 < m_clip.x1 ||
        _rect.y1 > m_clip.y2 || _rect.y2 < m_clip.y1) {
        return true;
    }
    return false;
}

bool TextBatch::clip(Quad& _quad) const {
    return ((_quad.x1 > m_clip.x2 && _quad.x2 > m_clip.x2 &&
             _quad.x3 > m_clip.x2 && _quad.x4 > m_clip.x2) ||
            (_quad.y1 > m_clip.y2 && _quad.y2 > m_clip.y2 &&
             _quad.y3 > m_clip.y2 && _quad.y4 > m_clip.y2) ||
            (_quad.x1 < m_clip.x1 && _quad.x2 < m_clip.x1 &&
             _quad.x3 < m_clip.x1 && _quad.x4 < m_clip.x1) ||
            (_quad.y1 < m_clip.y1 && _quad.y2 < m_clip.y1 &&
             _quad.y3 < m_clip.y1 && _quad.y4 < m_clip.y1));
    return false;

}

void TextBatch::setupRect(const Shape& _shape, const glm::vec2& _position,
                          float _sizeRatio, Rect& _rect, AtlasGlyph& _atlasGlyph) {

    glm::vec2 ul = _position + (_shape.position + _atlasGlyph.glyph->offset) * _sizeRatio;
    _rect.x1 = ul.x;
    _rect.y1 = ul.y;
    _rect.x2 = ul.x + _atlasGlyph.glyph->size.x * _sizeRatio;
    _rect.y2 = ul.y + _atlasGlyph.glyph->size.y * _sizeRatio;
}

void TextBatch::drawShape(const Font& _font, const Shape& _shape,
                          const glm::vec2& _position, float _scale,
                          LineMetrics& _metrics) {

    AtlasGlyph atlasGlyph;
    if (!m_atlas.getGlyph(_font, {_shape.face, _shape.codepoint}, atlasGlyph)) {
        return;
    }

    Rect rect;
    setupRect(_shape, _position, _scale, rect, atlasGlyph);

    if (m_hasClip && clip(rect)) {
        return;
    }

    m_mesh.drawGlyph(rect, atlasGlyph);

    if (&_metrics != &NO_METRICS) {
        _metrics.addExtents({rect.x1, rect.y1, rect.x2, rect.y2});
    }
}

void TextBatch::drawTransformedShape(const Font& _font, const Shape& _shape,
                                     const glm::vec2& _position, float _scale,
                                     LineMetrics& _metrics) {
    AtlasGlyph atlasGlyph;
    if (!m_atlas.getGlyph(_font, {_shape.face, _shape.codepoint}, atlasGlyph)) {
        return;
    }

    Rect rect;
    setupRect(_shape, _position, _scale, rect, atlasGlyph);

    Quad quad;
    m_matrix.transformRect(rect, quad);

    if (m_hasClip && clip(quad)) {
        return;
    }

    m_mesh.drawGlyph(quad, atlasGlyph);

    // FIXME: account for matrix transform
    // return glm::vec4(atlasGlyph.glyph->u1,
    //     atlasGlyph.glyph->u2,
    //     atlasGlyph.glyph->v1,
    //     atlasGlyph.glyph->v2);
}

glm::vec2 TextBatch::draw(const LineLayout& _line, glm::vec2 _position, LineMetrics& _metrics) {
    return draw(_line, 0, _line.shapes().size(), _position, _metrics);
}

glm::vec2 TextBatch::drawShapeRange(const LineLayout& _line, size_t _start, size_t _end,
                                    glm::vec2 _position, LineMetrics& _metrics) {

    for (size_t j = _start; j < _end; j++) {
        auto& c = _line.shapes()[j];
        if (!c.isSpace) {
            drawShape(_line.font(), c, _position, _line.scale(), _metrics);
        }

        _position.x += _line.advance(c);
    }
    return _position;
}

glm::vec2 TextBatch::draw(const LineLayout& _line, size_t _start, size_t _end,
                          glm::vec2 _position, LineMetrics& _metrics) {

    float startX = _position.x;

    for (size_t j = _start; j < _end; j++) {
        auto& c = _line.shapes()[j];
        if (!c.isSpace) {
            drawShape(_line.font(), c, _position, _line.scale(), _metrics);
        }

        _position.x += _line.advance(c);
        if (c.mustBreak) {
            _position.x = startX;
            _position.y += _line.height();
        }
    }

    _position.y += _line.height();

    return _position;
}

glm::vec2 TextBatch::draw(const LineLayout& _line, glm::vec2 _position, float _width, LineMetrics& _metrics) {

    if (_line.shapes().empty()) { return _position; }

    float lineWidth = 0;
    float startX = _position.x;

    float adv = 0;
    size_t shapeCount = 0;

    float lastWidth = 0;
    size_t lastShape = 0;
    size_t startShape = 0;

    for (auto& shape : _line.shapes()) {

        if (!shape.cluster) {
            shapeCount++;
            lineWidth += _line.advance(shape);
            continue;
        }

        shapeCount++;
        lineWidth += _line.advance(shape);

        // is break - or must break?
        if (shape.canBreak || shape.mustBreak) {
            lastShape = shapeCount;
            lastWidth = lineWidth;
        }

        if (lastShape != 0 && (lineWidth > _width || shape.mustBreak)) {
            auto& endShape = _line.shapes()[lastShape-1];
            if (endShape.isSpace) {
                lineWidth -= _line.advance(endShape);
                lastWidth -= _line.advance(endShape);
            }

            adv = std::max(adv, drawShapeRange(_line, startShape, lastShape,
                                               _position, _metrics).x);

            lineWidth -= lastWidth;

            startShape = lastShape;
            lastShape = 0;

            _position.y += _line.height();
            _position.x = startX;
        }
    }

    if (startShape < _line.shapes().size()-1) {
        adv = std::max(adv, drawShapeRange(_line, startShape,
                                           _line.shapes().size()-1,
                                           _position, _metrics).x);
        _position.y += _line.height();
    }

    _position.x = adv;
    return _position;
}

float TextBatch::draw(const LineLayout& _line, const LineSampler& _path,
                      float _offsetX, float _offsetY) {

    bool reverse = false; //(line.direction() == HB_DIRECTION_RTL);
    float direction = reverse ? -1 : 1;
    // float sampleSize = 0.1 * line.height();

    auto& font = _line.font();
    float scale = _line.scale();

    glm::vec2 position;
    float angle;

    for (auto& shape : DirectionalRange(_line.shapes(), reverse)) {
        //float half = 0.5f * line.advance(shape) * direction;
        float half = 0.5f * shape.advance * scale * direction;
        _offsetX += half;

        if (!shape.isSpace) {
            _path.get(_offsetX, position, angle);

            m_matrix.setTranslation(position);

            //m_matrix.rotateZ(path.offset2SampledAngle(offsetX, sampleSize));
            m_matrix.rotateZ(angle);

            drawTransformedShape(font, shape, -half, _offsetY, scale);
        }
        _offsetX += half;
    }
    return _offsetX;
}

}
<|endoftext|>


<commit_before>#include <QApplication>
#include <QDeclarativeView>
#include <QUrl>
#include <qplatformdefs.h>

#include <LunaWebView.h>

#if defined(MEEGO_EDITION_HARMATTAN)
    #include <MDeclarativeCache>
    #define NEW_QAPPLICATION(x, y) MDeclarativeCache::qApplication((x), (y))
    Q_DECL_EXPORT
#else
    #define NEW_QAPPLICATION(x, y) new QApplication((x), (y))
#endif

int main(int argc, char** argv)
{
    QApplication* app = NEW_QAPPLICATION(argc, argv);

    qmlRegisterType<LunaWebView>("Luna", 1, 0, "LunaWebView");

    QDeclarativeView viewer;
#if defined(MEEGO_EDITION_HARMATTAN)
    viewer.setSource(QUrl("qrc:/qml/main-harmattan.qml"));
    viewer.showFullScreen();
#else
    viewer.setSource(QUrl("qrc:/qml/main-desktop.qml"));
    viewer.show();
#endif

    return app->exec();
}
<commit_msg>Delete qApp instance on exit.<commit_after>#include <QApplication>
#include <QDeclarativeView>
#include <QUrl>
#include <QScopedPointer>
#include <qplatformdefs.h>

#include <LunaWebView.h>

#if defined(MEEGO_EDITION_HARMATTAN)
    #include <MDeclarativeCache>
    #define NEW_QAPPLICATION(x, y) MDeclarativeCache::qApplication((x), (y))
    Q_DECL_EXPORT
#else
    #define NEW_QAPPLICATION(x, y) new QApplication((x), (y))
#endif

int main(int argc, char** argv)
{
    QScopedPointer<QApplication> app(NEW_QAPPLICATION(argc, argv));

    qmlRegisterType<LunaWebView>("Luna", 1, 0, "LunaWebView");

    QDeclarativeView viewer;
#if defined(MEEGO_EDITION_HARMATTAN)
    viewer.setSource(QUrl("qrc:/qml/main-harmattan.qml"));
    viewer.showFullScreen();
#else
    viewer.setSource(QUrl("qrc:/qml/main-desktop.qml"));
    viewer.show();
#endif

    return app->exec();
}
<|endoftext|>


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

#include "rtkCudaFFTRampImageFilter.h"
#include "rtkCudaFFTRampImageFilter.hcu"

#include "rtkCudaCropImageFilter.h"
#include "rtkCudaCropImageFilter.hcu"

#include <itkMacro.h>

rtk::CudaFFTRampImageFilter
 ::CudaFFTRampImageFilter()
 {
   // We use FFTW for the kernel so we need to do the same thing as in the parent
 #if defined(USE_FFTWF)
   this->SetGreatestPrimeFactor(13);
 #endif
 }

void
rtk::CudaFFTRampImageFilter
::GPUGenerateData()
{
  // Cuda typedefs
  typedef itk::CudaImage<float,
                         ImageType::ImageDimension > FFTInputImageType;
  typedef FFTInputImageType::Pointer                 FFTInputImagePointer;
  typedef itk::CudaImage<std::complex<float>,
                         ImageType::ImageDimension > FFTOutputImageType;
  typedef FFTOutputImageType::Pointer                FFTOutputImagePointer;

  // Non-cuda typedefs
  typedef itk::Image<float,
                     ImageType::ImageDimension >     FFTInputCPUImageType;
  typedef FFTInputCPUImageType::Pointer              FFTInputCPUImagePointer;
  typedef itk::Image<std::complex<float>,
                     ImageType::ImageDimension >     FFTOutputCPUImageType;
  typedef FFTOutputCPUImageType::Pointer             FFTOutputCPUImagePointer;

  //this->AllocateOutputs();

  // Pad image region
  FFTInputImagePointer paddedImage;
  paddedImage = PadInputImageRegion<FFTInputImageType, FFTOutputImageType>(this->GetInput()->GetRequestedRegion());

  int3 inputDimension;
  inputDimension.x = paddedImage->GetBufferedRegion().GetSize()[0];
  inputDimension.y = paddedImage->GetBufferedRegion().GetSize()[1];
  inputDimension.z = paddedImage->GetBufferedRegion().GetSize()[2];
  if(inputDimension.y==1 && inputDimension.z>1) // Troubles cuda 3.2 and 4.0
    std::swap(inputDimension.y, inputDimension.z);

  // Get FFT ramp kernel. Must be itk::Image because GetFFTRampKernel is not
  // compatible with itk::CudaImage + ITK 3.20.
  FFTOutputCPUImagePointer fftK;
  FFTOutputImageType::SizeType s = paddedImage->GetLargestPossibleRegion().GetSize();
  fftK = this->GetFFTRampKernel<FFTInputCPUImageType, FFTOutputCPUImageType>(s[0], s[1]);

  // Create the itk::CudaImage holding the kernel
  FFTOutputImagePointer fftKCUDA = FFTOutputImageType::New();
  fftKCUDA->SetRegions(fftK->GetLargestPossibleRegion());
  fftKCUDA->Allocate();

  // CUFFT scales by the number of element, correct for it in kernel.
  // Also transfer the kernel from the itk::Image to the itk::CudaImage.
  itk::ImageRegionIterator<FFTOutputCPUImageType> itKI(fftK, fftK->GetBufferedRegion() );
  itk::ImageRegionIterator<FFTOutputImageType>    itKO(fftKCUDA, fftKCUDA->GetBufferedRegion() );
  FFTPrecisionType invNPixels = 1 / double(paddedImage->GetBufferedRegion().GetNumberOfPixels() );
  while(!itKO.IsAtEnd() )
    {
    itKO.Set(itKI.Get() * invNPixels );
    ++itKI;
    ++itKO;
    }

  int2 kernelDimension;
  kernelDimension.x = fftK->GetBufferedRegion().GetSize()[0];
  kernelDimension.y = fftK->GetBufferedRegion().GetSize()[1];
  CUDA_fft_convolution(inputDimension,
                       kernelDimension,
                       *(float**)(paddedImage->GetCudaDataManager()->GetGPUBufferPointer()),
                       *(float2**)(fftKCUDA->GetCudaDataManager()->GetGPUBufferPointer()));

  // CUDA Cropping and Graft Output
  typedef rtk::CudaCropImageFilter CropFilter;
  CropFilter::Pointer cf = CropFilter::New();
  OutputImageType::SizeType upCropSize, lowCropSize;
  for(unsigned int i=0; i<OutputImageType::ImageDimension; i++)
    {
    lowCropSize[i] = this->GetOutput()->GetRequestedRegion().GetIndex()[i] -
                     paddedImage->GetLargestPossibleRegion().GetIndex()[i];
    upCropSize[i]  = paddedImage->GetLargestPossibleRegion().GetSize()[i] -
                     this->GetOutput()->GetRequestedRegion().GetSize()[i] -
                     lowCropSize[i];
    }
  cf->SetUpperBoundaryCropSize(upCropSize);
  cf->SetLowerBoundaryCropSize(lowCropSize);
  cf->SetInput(paddedImage);
  cf->Update();

  // We only want to graft the data. To do so, we copy the rest before grafting.
  cf->GetOutput()->CopyInformation(this->GetOutput());
  cf->GetOutput()->SetBufferedRegion(this->GetOutput()->GetBufferedRegion());
  cf->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
  this->GraftOutput(cf->GetOutput());
}
<commit_msg>ITK3 without FFTW has a kernel size that is too large for cufft, crop it in this case<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "rtkCudaFFTRampImageFilter.h"
#include "rtkCudaFFTRampImageFilter.hcu"

#include "rtkCudaCropImageFilter.h"
#include "rtkCudaCropImageFilter.hcu"

#include <itkMacro.h>

rtk::CudaFFTRampImageFilter
 ::CudaFFTRampImageFilter()
 {
   // We use FFTW for the kernel so we need to do the same thing as in the parent
 #if defined(USE_FFTWF)
   this->SetGreatestPrimeFactor(13);
 #endif
 }

void
rtk::CudaFFTRampImageFilter
::GPUGenerateData()
{
  // Cuda typedefs
  typedef itk::CudaImage<float,
                         ImageType::ImageDimension > FFTInputImageType;
  typedef FFTInputImageType::Pointer                 FFTInputImagePointer;
  typedef itk::CudaImage<std::complex<float>,
                         ImageType::ImageDimension > FFTOutputImageType;
  typedef FFTOutputImageType::Pointer                FFTOutputImagePointer;

  // Non-cuda typedefs
  typedef itk::Image<float,
                     ImageType::ImageDimension >     FFTInputCPUImageType;
  typedef FFTInputCPUImageType::Pointer              FFTInputCPUImagePointer;
  typedef itk::Image<std::complex<float>,
                     ImageType::ImageDimension >     FFTOutputCPUImageType;
  typedef FFTOutputCPUImageType::Pointer             FFTOutputCPUImagePointer;

  //this->AllocateOutputs();

  // Pad image region
  FFTInputImagePointer paddedImage;
  paddedImage = PadInputImageRegion<FFTInputImageType, FFTOutputImageType>(this->GetInput()->GetRequestedRegion());

  int3 inputDimension;
  inputDimension.x = paddedImage->GetBufferedRegion().GetSize()[0];
  inputDimension.y = paddedImage->GetBufferedRegion().GetSize()[1];
  inputDimension.z = paddedImage->GetBufferedRegion().GetSize()[2];
  if(inputDimension.y==1 && inputDimension.z>1) // Troubles cuda 3.2 and 4.0
    std::swap(inputDimension.y, inputDimension.z);

  // Get FFT ramp kernel. Must be itk::Image because GetFFTRampKernel is not
  // compatible with itk::CudaImage + ITK 3.20.
  FFTOutputCPUImagePointer fftK;
  FFTOutputImageType::SizeType s = paddedImage->GetLargestPossibleRegion().GetSize();
  fftK = this->GetFFTRampKernel<FFTInputCPUImageType, FFTOutputCPUImageType>(s[0], s[1]);

  // Create the itk::CudaImage holding the kernel
  FFTOutputImageType::RegionType kreg = fftK->GetLargestPossibleRegion();
#if ITK_VERSION_MAJOR <= 3 && !defined(USE_FFTWF)
  kreg.SetSize(0, kreg.GetSize(0)/2+1);
#endif
  FFTOutputImagePointer fftKCUDA = FFTOutputImageType::New();
  fftKCUDA->SetRegions(kreg);
  fftKCUDA->Allocate();

  // CUFFT scales by the number of element, correct for it in kernel.
  // Also transfer the kernel from the itk::Image to the itk::CudaImage.
  itk::ImageRegionIterator<FFTOutputCPUImageType> itKI(fftK, kreg);
  itk::ImageRegionIterator<FFTOutputImageType>    itKO(fftKCUDA, kreg);
  FFTPrecisionType invNPixels = 1 / double(paddedImage->GetBufferedRegion().GetNumberOfPixels() );
  while(!itKO.IsAtEnd() )
    {
    itKO.Set(itKI.Get() * invNPixels );
    ++itKI;
    ++itKO;
    }

  int2 kernelDimension;
  kernelDimension.x = fftK->GetBufferedRegion().GetSize()[0];
  kernelDimension.y = fftK->GetBufferedRegion().GetSize()[1];
  CUDA_fft_convolution(inputDimension,
                       kernelDimension,
                       *(float**)(paddedImage->GetCudaDataManager()->GetGPUBufferPointer()),
                       *(float2**)(fftKCUDA->GetCudaDataManager()->GetGPUBufferPointer()));

  // CUDA Cropping and Graft Output
  typedef rtk::CudaCropImageFilter CropFilter;
  CropFilter::Pointer cf = CropFilter::New();
  OutputImageType::SizeType upCropSize, lowCropSize;
  for(unsigned int i=0; i<OutputImageType::ImageDimension; i++)
    {
    lowCropSize[i] = this->GetOutput()->GetRequestedRegion().GetIndex()[i] -
                     paddedImage->GetLargestPossibleRegion().GetIndex()[i];
    upCropSize[i]  = paddedImage->GetLargestPossibleRegion().GetSize()[i] -
                     this->GetOutput()->GetRequestedRegion().GetSize()[i] -
                     lowCropSize[i];
    }
  cf->SetUpperBoundaryCropSize(upCropSize);
  cf->SetLowerBoundaryCropSize(lowCropSize);
  cf->SetInput(paddedImage);
  cf->Update();

  // We only want to graft the data. To do so, we copy the rest before grafting.
  cf->GetOutput()->CopyInformation(this->GetOutput());
  cf->GetOutput()->SetBufferedRegion(this->GetOutput()->GetBufferedRegion());
  cf->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
  this->GraftOutput(cf->GetOutput());
}
<|endoftext|>


<commit_before>/*
 * This file is part of the Micro Python project, http://micropython.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Damien P. George
 *
 * 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 <stdio.h>
#include "MicroBit.h"

extern "C" {

#include "py/obj.h"

STATIC mp_obj_t this__init__(void) {
    STATIC const char *this_text =
"The Zen of MicroPython, by Nicholas H.Tollervey\n"
"\n"
"Code,\n"
"Hack it,\n"
"Less is more,\n"
"Keep it simple,\n"
"Small is beautiful,\n"
"\n"
"Be brave! Break things! Learn and have fun!\n"
"Express yourself with MicroPython.\n"
"\n"
"Happy hacking! :-)\n";
    mp_printf(&mp_plat_print, "%s", this_text);
    return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(this___init___obj, this__init__);

STATIC mp_obj_t this_authors(void) {
    /*
    If you contribute code to this project, add your name here.
    */
    STATIC const char *authors_text =
"MicroPython on the micro:bit is brought to you by:\n"
"Damien P.George and Nicholas H.Tollervey\n";
    mp_printf(&mp_plat_print, "%s", authors_text);
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(this_authors_obj, this_authors);

STATIC const mp_map_elem_t this_module_globals_table[] = {
    { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_this) },
    { MP_OBJ_NEW_QSTR(MP_QSTR___init__), (mp_obj_t)&this___init___obj },
    { MP_OBJ_NEW_QSTR(MP_QSTR_authors), (mp_obj_t)&this_authors_obj },
};

STATIC MP_DEFINE_CONST_DICT(this_module_globals, this_module_globals_table);

const mp_obj_module_t this_module = {
    .base = { &mp_type_module },
    .name = MP_QSTR_this,
    .globals = (mp_obj_dict_t*)&this_module_globals,
};

}
<commit_msg>Add Matthew Else to the author credits.<commit_after>/*
 * This file is part of the Micro Python project, http://micropython.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Damien P. George
 *
 * 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 <stdio.h>
#include "MicroBit.h"

extern "C" {

#include "py/obj.h"

STATIC mp_obj_t this__init__(void) {
    STATIC const char *this_text =
"The Zen of MicroPython, by Nicholas H.Tollervey\n"
"\n"
"Code,\n"
"Hack it,\n"
"Less is more,\n"
"Keep it simple,\n"
"Small is beautiful,\n"
"\n"
"Be brave! Break things! Learn and have fun!\n"
"Express yourself with MicroPython.\n"
"\n"
"Happy hacking! :-)\n";
    mp_printf(&mp_plat_print, "%s", this_text);
    return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(this___init___obj, this__init__);

STATIC mp_obj_t this_authors(void) {
    /*
    If you contribute code to this project, add your name here.
    */
    STATIC const char *authors_text =
"MicroPython on the micro:bit is brought to you by:\n"
"Damien P.George, Matthew Else and Nicholas H.Tollervey.\n";
    mp_printf(&mp_plat_print, "%s", authors_text);
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(this_authors_obj, this_authors);

STATIC const mp_map_elem_t this_module_globals_table[] = {
    { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_this) },
    { MP_OBJ_NEW_QSTR(MP_QSTR___init__), (mp_obj_t)&this___init___obj },
    { MP_OBJ_NEW_QSTR(MP_QSTR_authors), (mp_obj_t)&this_authors_obj },
};

STATIC MP_DEFINE_CONST_DICT(this_module_globals, this_module_globals_table);

const mp_obj_module_t this_module = {
    .base = { &mp_type_module },
    .name = MP_QSTR_this,
    .globals = (mp_obj_dict_t*)&this_module_globals,
};

}
<|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 à 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);
        }

    }

}

std::vector<types::StopTime*> get_stop_from_impact(const navitia::type::Message& message, bg::date current_date, std::vector<types::StopTime*> stoplist){
    std::vector<types::StopTime*> result;
    pt::ptime currenttime;
    if(message.object_type == navitia::type::Type_e::StopPoint){
        for(auto stop : stoplist){
            currenttime = pt::ptime(current_date, pt::seconds(stop->departure_time));
            if((stop->tmp_stop_point->uri == message.object_uri) && (message.is_applicable(pt::time_period(currenttime, pt::seconds(1))))){
                result.push_back(stop);
            }
        }
    }
    if(message.object_type == navitia::type::Type_e::StopArea){
        for(auto stop : stoplist){
            currenttime = pt::ptime(current_date, pt::seconds(stop->departure_time));
            if((stop->tmp_stop_point->stop_area->uri == message.object_uri)&& (message.is_applicable(pt::time_period(currenttime, pt::seconds(1))))){
                result.push_back(stop);
            }
        }
    }
    return result;
}

void duplicate_vj(types::VehicleJourney* vehicle_journey, const nt::Message& message, Data& data){
    types::VehicleJourney* vjadapted = NULL;
    //on teste le validitypattern adapté car si le VJ est déjà supprimé le traitement n'est pas nécessaire
    //faux car on ne pas appilquer 2 messages différent sur un même jour, mais comment détecter le vj supprimé
    for(size_t i=0; i < vehicle_journey->validity_pattern->days.size(); ++i){
        bg::date current_date = vehicle_journey->validity_pattern->beginning_date + bg::days(i);
        if(!vehicle_journey->validity_pattern->check(i) || current_date < message.application_period.begin().date()
                || current_date > message.application_period.end().date()){
            continue;
        }

        std::vector<types::StopTime*> impacted_stop = get_stop_from_impact(message, current_date, vehicle_journey->stop_time_list);
        //ICI il faut récupérer la liste des vjadapted déjà crées actif sur current_date afin de leur appliquer le nouveau message
        if((vjadapted == NULL) && (impacted_stop.size()!=0)){
            vjadapted = new types::VehicleJourney(*vehicle_journey);
            data.vehicle_journeys.push_back(vjadapted);
            vjadapted->is_adapted = true;
            vjadapted->theoric_vehicle_journey = vehicle_journey;
            vehicle_journey->adapted_vehicle_journey_list.push_back(vjadapted);
            vjadapted->validity_pattern = new types::ValidityPattern(vehicle_journey->validity_pattern->beginning_date);
            data.validity_patterns.push_back(vjadapted->validity_pattern);

            vjadapted->adapted_validity_pattern = new types::ValidityPattern(vjadapted->validity_pattern->beginning_date);
            data.validity_patterns.push_back(vjadapted->adapted_validity_pattern);
        }
        for(auto stoptmp : impacted_stop){
            std::vector<types::StopTime*>::iterator it = std::find(vjadapted->stop_time_list.begin(), vjadapted->stop_time_list.end(), stoptmp);
            if(it != vjadapted->stop_time_list.end()){
                vjadapted->stop_time_list.erase(it);
            }
        }
        if(impacted_stop.size()!=0){
            vjadapted->adapted_validity_pattern->add(current_date);
            vehicle_journey->adapted_validity_pattern->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_deletion_on_vj(pair.first, pair.second, data);
    }

}

void AtAdaptedLoader::apply_deletion_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(vehicle_journey->stop_time_list.size() > 0){
            delete_vj(vehicle_journey, m, data);
        }
    }
}

void AtAdaptedLoader::apply_update_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(vehicle_journey->stop_time_list.size() > 0){
            duplicate_vj(vehicle_journey, m, data);
        }
    }
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::get_vj_from_stoppoint(std::string stoppoint_uri, const Data& data){
    std::vector<types::VehicleJourney*> result;
    for(navimake::types::JourneyPatternPoint* jpp : data.journey_pattern_points){
        if(jpp->stop_point->uri == stoppoint_uri){
            //le journeypattern posséde le StopPoint
            navimake::types::JourneyPattern* jp = jpp->journey_pattern;
            //on récupere tous les vj qui posséde ce journeypattern
            for(navimake::types::VehicleJourney* vj : data.vehicle_journeys){
                if(vj->journey_pattern == jp){
                    result.push_back(vj);
                }
            }
        }
    }
    return result;
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::get_vj_from_impact(const navitia::type::Message& message, const Data& data){
    std::vector<types::VehicleJourney*> result;
    if(message.object_type == navitia::type::Type_e::StopPoint){
        auto tmp = get_vj_from_stoppoint(message.object_uri, data);
        std::vector<types::VehicleJourney*>::iterator it;
        result.insert(it, tmp.begin(), tmp.end());
    }
    if(message.object_type == navitia::type::Type_e::StopArea){
        for(navimake::types::StopPoint* stp : data.stop_points){
            if(message.object_uri == stp->stop_area->uri){
                auto tmp = get_vj_from_stoppoint(stp->uri, data);
                std::vector<types::VehicleJourney*>::iterator it;
                result.insert(it, tmp.begin(), tmp.end());
            }
        }
    }
    return result;
}

void AtAdaptedLoader::dispatch_message(const std::map<std::string, std::vector<navitia::type::Message>>& messages, const Data& data){
    for(const std::pair<std::string, std::vector<navitia::type::Message>> & message_list : messages){
        for(auto m : message_list.second){
            //on recupére la liste des VJ associé(s) a l'uri du message
            if(m.object_type == nt::Type_e::VehicleJourney || m.object_type == nt::Type_e::Route
               || m.object_type == nt::Type_e::Line || m.object_type == nt::Type_e::Network){
                std::vector<navimake::types::VehicleJourney*> vj_list = reconcile_impact_with_vj(m, data);
                //on parcourt la liste des VJ associée au message
                //et on associe le message au vehiclejourney
                for(auto vj  : vj_list){
                    update_vj_map[vj].push_back(m);
                }

            }else{
                if(m.object_type == nt::Type_e::JourneyPatternPoint || m.object_type == nt::Type_e::StopPoint
                   || m.object_type == nt::Type_e::StopArea){
                    std::vector<navimake::types::VehicleJourney*> vj_list = get_vj_from_impact(m, data);
                    for(auto vj  : vj_list){
                        duplicate_vj_map[vj].push_back(m);
                    }
                }
            }
        }
    }
}

void AtAdaptedLoader::apply_b(const std::map<std::string, std::vector<navitia::type::Message>>& messages, Data& data){
    init_map(data);

    dispatch_message(messages, data);

    std::cout << "nombre de VJ adaptés: " << update_vj_map.size() << std::endl;
    for(auto pair : update_vj_map){
        apply_deletion_on_vj(pair.first, pair.second, data);
    }
    for(auto pair : duplicate_vj_map){
        apply_update_on_vj(pair.first, pair.second, data);
    }
}

}//namespace
<commit_msg>adapted : non application des messages sur vehiclejourney déjà supprimé<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);
        }

    }

}

std::vector<types::StopTime*> get_stop_from_impact(const navitia::type::Message& message, bg::date current_date, std::vector<types::StopTime*> stoplist){
    std::vector<types::StopTime*> result;
    pt::ptime currenttime;
    if(message.object_type == navitia::type::Type_e::StopPoint){
        for(auto stop : stoplist){
            currenttime = pt::ptime(current_date, pt::seconds(stop->departure_time));
            if((stop->tmp_stop_point->uri == message.object_uri) && (message.is_applicable(pt::time_period(currenttime, pt::seconds(1))))){
                result.push_back(stop);
            }
        }
    }
    if(message.object_type == navitia::type::Type_e::StopArea){
        for(auto stop : stoplist){
            currenttime = pt::ptime(current_date, pt::seconds(stop->departure_time));
            if((stop->tmp_stop_point->stop_area->uri == message.object_uri)&& (message.is_applicable(pt::time_period(currenttime, pt::seconds(1))))){
                result.push_back(stop);
            }
        }
    }
    return result;
}

void duplicate_vj(types::VehicleJourney* vehicle_journey, const nt::Message& message, Data& data){
    types::VehicleJourney* vjadapted = NULL;
    //on teste le validitypattern adapté car si le VJ est déjà supprimé le traitement n'est pas nécessaire
    //faux car on ne pas appilquer 2 messages différent sur un même jour, mais comment détecter le vj supprimé
    for(size_t i=0; i < vehicle_journey->validity_pattern->days.size(); ++i){
        bg::date current_date = vehicle_journey->validity_pattern->beginning_date + bg::days(i);
        if(!vehicle_journey->validity_pattern->check(i) ||
                //le vj a été supprimé par un message de suppression
                (!vehicle_journey->adapted_validity_pattern->check((current_date- vehicle_journey->adapted_validity_pattern->beginning_date).days()) && (vehicle_journey->adapted_vehicle_journey_list.size()==0))
                || current_date < message.application_period.begin().date()
                || current_date > message.application_period.end().date()){
            continue;
        }

        std::vector<types::StopTime*> impacted_stop = get_stop_from_impact(message, current_date, vehicle_journey->stop_time_list);
        //ICI il faut récupérer la liste des vjadapted déjà crées actif sur current_date afin de leur appliquer le nouveau message
        if((vjadapted == NULL) && (impacted_stop.size()!=0)){
            vjadapted = new types::VehicleJourney(*vehicle_journey);
            data.vehicle_journeys.push_back(vjadapted);
            vjadapted->is_adapted = true;
            vjadapted->theoric_vehicle_journey = vehicle_journey;
            vehicle_journey->adapted_vehicle_journey_list.push_back(vjadapted);
            vjadapted->validity_pattern = new types::ValidityPattern(vehicle_journey->validity_pattern->beginning_date);
            data.validity_patterns.push_back(vjadapted->validity_pattern);

            vjadapted->adapted_validity_pattern = new types::ValidityPattern(vjadapted->validity_pattern->beginning_date);
            data.validity_patterns.push_back(vjadapted->adapted_validity_pattern);
        }
        for(auto stoptmp : impacted_stop){
            std::vector<types::StopTime*>::iterator it = std::find(vjadapted->stop_time_list.begin(), vjadapted->stop_time_list.end(), stoptmp);
            if(it != vjadapted->stop_time_list.end()){
                vjadapted->stop_time_list.erase(it);
            }
        }
        if(impacted_stop.size()!=0){
            vjadapted->adapted_validity_pattern->add(current_date);
            vehicle_journey->adapted_validity_pattern->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_deletion_on_vj(pair.first, pair.second, data);
    }

}

void AtAdaptedLoader::apply_deletion_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(vehicle_journey->stop_time_list.size() > 0){
            delete_vj(vehicle_journey, m, data);
        }
    }
}

void AtAdaptedLoader::apply_update_on_vj(types::VehicleJourney* vehicle_journey, const std::vector<navitia::type::Message>& messages, Data& data){
    for(nt::Message m : messages){
        if(vehicle_journey->stop_time_list.size() > 0){
            duplicate_vj(vehicle_journey, m, data);
        }
    }
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::get_vj_from_stoppoint(std::string stoppoint_uri, const Data& data){
    std::vector<types::VehicleJourney*> result;
    for(navimake::types::JourneyPatternPoint* jpp : data.journey_pattern_points){
        if(jpp->stop_point->uri == stoppoint_uri){
            //le journeypattern posséde le StopPoint
            navimake::types::JourneyPattern* jp = jpp->journey_pattern;
            //on récupere tous les vj qui posséde ce journeypattern
            for(navimake::types::VehicleJourney* vj : data.vehicle_journeys){
                if(vj->journey_pattern == jp){
                    result.push_back(vj);
                }
            }
        }
    }
    return result;
}

std::vector<types::VehicleJourney*> AtAdaptedLoader::get_vj_from_impact(const navitia::type::Message& message, const Data& data){
    std::vector<types::VehicleJourney*> result;
    if(message.object_type == navitia::type::Type_e::StopPoint){
        auto tmp = get_vj_from_stoppoint(message.object_uri, data);
        std::vector<types::VehicleJourney*>::iterator it;
        result.insert(it, tmp.begin(), tmp.end());
    }
    if(message.object_type == navitia::type::Type_e::StopArea){
        for(navimake::types::StopPoint* stp : data.stop_points){
            if(message.object_uri == stp->stop_area->uri){
                auto tmp = get_vj_from_stoppoint(stp->uri, data);
                std::vector<types::VehicleJourney*>::iterator it;
                result.insert(it, tmp.begin(), tmp.end());
            }
        }
    }
    return result;
}

void AtAdaptedLoader::dispatch_message(const std::map<std::string, std::vector<navitia::type::Message>>& messages, const Data& data){
    for(const std::pair<std::string, std::vector<navitia::type::Message>> & message_list : messages){
        for(auto m : message_list.second){
            //on recupére la liste des VJ associé(s) a l'uri du message
            if(m.object_type == nt::Type_e::VehicleJourney || m.object_type == nt::Type_e::Route
               || m.object_type == nt::Type_e::Line || m.object_type == nt::Type_e::Network){
                std::vector<navimake::types::VehicleJourney*> vj_list = reconcile_impact_with_vj(m, data);
                //on parcourt la liste des VJ associée au message
                //et on associe le message au vehiclejourney
                for(auto vj  : vj_list){
                    update_vj_map[vj].push_back(m);
                }

            }else{
                if(m.object_type == nt::Type_e::JourneyPatternPoint || m.object_type == nt::Type_e::StopPoint
                   || m.object_type == nt::Type_e::StopArea){
                    std::vector<navimake::types::VehicleJourney*> vj_list = get_vj_from_impact(m, data);
                    for(auto vj  : vj_list){
                        duplicate_vj_map[vj].push_back(m);
                    }
                }
            }
        }
    }
}

void AtAdaptedLoader::apply_b(const std::map<std::string, std::vector<navitia::type::Message>>& messages, Data& data){
    init_map(data);

    dispatch_message(messages, data);

    std::cout << "nombre de VJ adaptés: " << update_vj_map.size() << std::endl;
    for(auto pair : update_vj_map){
        apply_deletion_on_vj(pair.first, pair.second, data);
    }
    for(auto pair : duplicate_vj_map){
        apply_update_on_vj(pair.first, pair.second, data);
    }
}

}//namespace
<|endoftext|>


<commit_before>#include "BigFont.h"
#include "BigCrystal.h"

BigCrystal::BigCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) :
    LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) :
    LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
    LiquidCrystal(rs, rw, enable, d0, d1, d2, d3) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs,  uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
    LiquidCrystal(rs, enable, d0, d1, d2, d3) {
  init();
}

/* Creates custom font shapes for LCD characters 0 through to 7
 * used in displaying big fonts
 */
void BigCrystal::init() {
  for (uint8_t i = 0; i < 8; i++) {
    uint8_t customChar[8];
    for (uint8_t j = 0; j < 8; j++) {
      customChar[j] = pgm_read_byte(BF_fontShapes + (i * 8) + j);
    }
    createChar(i, customChar);
  }
}

uint8_t BigCrystal::widthBig(char c) {
  if (!supported(c)) {
    return 0; // we don't support characters outside this range
  }
  char ch = toUpperCase(c);

  uint8_t tableCode;
  uint8_t index;
  getTableCodeAndIndex(ch, tableCode, index);

  uint8_t width = getWidthFromTableCode(tableCode);
  if (width == 0) {
    return 0;
  }

  return width + 1; // add one for space after character
}

uint8_t BigCrystal::writeBig(char c, uint8_t col, uint8_t row) {
  if (!supported(c)) {
    return 0; // we don't support characters outside this range
  }
  char ch = toUpperCase(c);

  uint8_t tableCode;
  uint8_t index;
  getTableCodeAndIndex(ch, tableCode, index);

  uint8_t* table = getTable(tableCode);
  uint8_t width = getWidthFromTableCode(tableCode);

  int tableOffset = (width * 2) * index;

  // Write first row
  setCursor(col, row);
  for (uint8_t i = 0; i < width; i++) {
    write(pgm_read_byte_near(table + tableOffset + i));
  }

  // Write second row
  setCursor(col, row + 1);
  for (uint8_t i = 0; i < width; i++) {
    write(pgm_read_byte_near(table + tableOffset + width + i));
  }

  // Clear last column
  clearColumn(col + width, row);

  return width + 1; // add one for the cleared column
}

uint8_t BigCrystal::printBig(char *str, uint8_t col, uint8_t row) {
  uint8_t width = 0;
  char *c = str;
  while (*c != '\0') {
    width += writeBig(*c, col + width, row);
    *c++;
  }
  return width;
}

void BigCrystal::getTableCodeAndIndex(char c, uint8_t& tableCode, uint8_t& index) {
  uint8_t tableAndIndex = pgm_read_byte_near(BF_characters + c - ' ');
  // Top 3 bits are the table, bottom 5 are index into table
  tableCode = (uint8_t) ((tableAndIndex & 0xE0) >> 5);
  index = (uint8_t) (tableAndIndex & 0x1F);
}

uint8_t* BigCrystal::getTable(uint8_t tableCode) {
  switch (tableCode) {
    case BF_WIDTH1_TABLE:
      return BF_width1;
    case BF_WIDTH2_TABLE:
      return BF_width2;
    case BF_WIDTH3_TABLE:
      return BF_width3;
    case BF_WIDTH4_TABLE:
      return BF_width4;
    case BF_WIDTH5_TABLE:
      return BF_width5;
    case BF_WIDTH3_SYMBOLS_TABLE:
      return BF_width3Symbols;
    default:
      return NULL;
  }
}

uint8_t BigCrystal::getWidthFromTableCode(uint8_t tableCode) {
  if (tableCode == BF_WIDTH3_SYMBOLS_TABLE) {
    return 3;
  }
  return tableCode;
}

bool BigCrystal::supported(char c) {
  return (c >= ' ' && c <= 'Z') || (c >= 'a' && c <= 'z');
}

char BigCrystal::toUpperCase(char c) {
  if (c >= 'a' && c <= 'z') {
    return c &0x5f;
  }
  return  c;
}

void BigCrystal::clearColumn(uint8_t col, uint8_t row) {
  setCursor(col, row);
  write(0x20);
  setCursor(col, row + 1);
  write(0x20);
}
<commit_msg>Gracefully handle the case if the character table is null.<commit_after>#include "BigFont.h"
#include "BigCrystal.h"

BigCrystal::BigCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) :
    LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) :
    LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
    LiquidCrystal(rs, rw, enable, d0, d1, d2, d3) {
  init();
}

BigCrystal::BigCrystal(uint8_t rs,  uint8_t enable,
    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
    LiquidCrystal(rs, enable, d0, d1, d2, d3) {
  init();
}

/* Creates custom font shapes for LCD characters 0 through to 7
 * used in displaying big fonts
 */
void BigCrystal::init() {
  for (uint8_t i = 0; i < 8; i++) {
    uint8_t customChar[8];
    for (uint8_t j = 0; j < 8; j++) {
      customChar[j] = pgm_read_byte(BF_fontShapes + (i * 8) + j);
    }
    createChar(i, customChar);
  }
}

uint8_t BigCrystal::widthBig(char c) {
  if (!supported(c)) {
    return 0; // we don't support characters outside this range
  }
  char ch = toUpperCase(c);

  uint8_t tableCode;
  uint8_t index;
  getTableCodeAndIndex(ch, tableCode, index);

  uint8_t width = getWidthFromTableCode(tableCode);
  if (width == 0) {
    return 0;
  }

  return width + 1; // add one for space after character
}

uint8_t BigCrystal::writeBig(char c, uint8_t col, uint8_t row) {
  if (!supported(c)) {
    return 0; // we don't support characters outside this range
  }
  char ch = toUpperCase(c);

  uint8_t tableCode;
  uint8_t index;
  getTableCodeAndIndex(ch, tableCode, index);

  uint8_t* table = getTable(tableCode);
  if (table == NULL) {
    return 0;
  }
  uint8_t width = getWidthFromTableCode(tableCode);

  int tableOffset = (width * 2) * index;

  // Write first row
  setCursor(col, row);
  for (uint8_t i = 0; i < width; i++) {
    write(pgm_read_byte_near(table + tableOffset + i));
  }

  // Write second row
  setCursor(col, row + 1);
  for (uint8_t i = 0; i < width; i++) {
    write(pgm_read_byte_near(table + tableOffset + width + i));
  }

  // Clear last column
  clearColumn(col + width, row);

  return width + 1; // add one for the cleared column
}

uint8_t BigCrystal::printBig(char *str, uint8_t col, uint8_t row) {
  uint8_t width = 0;
  char *c = str;
  while (*c != '\0') {
    width += writeBig(*c, col + width, row);
    *c++;
  }
  return width;
}

void BigCrystal::getTableCodeAndIndex(char c, uint8_t& tableCode, uint8_t& index) {
  uint8_t tableAndIndex = pgm_read_byte_near(BF_characters + c - ' ');
  // Top 3 bits are the table, bottom 5 are index into table
  tableCode = (uint8_t) ((tableAndIndex & 0xE0) >> 5);
  index = (uint8_t) (tableAndIndex & 0x1F);
}

uint8_t* BigCrystal::getTable(uint8_t tableCode) {
  switch (tableCode) {
    case BF_WIDTH1_TABLE:
      return BF_width1;
    case BF_WIDTH2_TABLE:
      return BF_width2;
    case BF_WIDTH3_TABLE:
      return BF_width3;
    case BF_WIDTH4_TABLE:
      return BF_width4;
    case BF_WIDTH5_TABLE:
      return BF_width5;
    case BF_WIDTH3_SYMBOLS_TABLE:
      return BF_width3Symbols;
    default:
      return NULL;
  }
}

uint8_t BigCrystal::getWidthFromTableCode(uint8_t tableCode) {
  if (tableCode == BF_WIDTH3_SYMBOLS_TABLE) {
    return 3;
  }
  return tableCode;
}

bool BigCrystal::supported(char c) {
  return (c >= ' ' && c <= 'Z') || (c >= 'a' && c <= 'z');
}

char BigCrystal::toUpperCase(char c) {
  if (c >= 'a' && c <= 'z') {
    return c &0x5f;
  }
  return  c;
}

void BigCrystal::clearColumn(uint8_t col, uint8_t row) {
  setCursor(col, row);
  write(0x20);
  setCursor(col, row + 1);
  write(0x20);
}
<|endoftext|>


<commit_before>#include <UnitTest++.h>

#include "stdio_fixture.h"
#include <string.h>

SUITE(FGets)
{
    TEST_FIXTURE(StdIOFixture, FGetsToEofTest)
    {
        istring.str("Hello");

        char text_read[10];

        char *str = fslc_fgets(text_read, 10, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("Hello", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsNewLineTest)
    {
        istring.str("Hello\nWorld");

        char text_read[20];

        char *str = fslc_fgets(text_read, 20, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[6]);
        CHECK_EQUAL(6, strlen(str));
        CHECK_EQUAL("Hello\n", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsBufSizeTest)
    {
        istring.str("Hello World");

        char text_read[20];

        char *str = fslc_fgets(text_read, 5, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("Hello", std::string(str));
    }
}
<commit_msg>Additional fgets() tests CRLF handling and reading second line<commit_after>#include <UnitTest++.h>

#include "stdio_fixture.h"
#include <string.h>

SUITE(FGets)
{
    TEST_FIXTURE(StdIOFixture, FGetsToEofTest)
    {
        istring.str("Hello");

        char text_read[10];

        char *str = fslc_fgets(text_read, 10, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("Hello", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsNewLineTest)
    {
        istring.str("Hello\nWorld");

        char text_read[20];

        char *str = fslc_fgets(text_read, 20, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[6]);
        CHECK_EQUAL(6, strlen(str));
        CHECK_EQUAL("Hello\n", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsBufSizeTest)
    {
        istring.str("Hello World");

        char text_read[20];

        char *str = fslc_fgets(text_read, 5, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("Hello", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsCrLfLineTest)
    {
        istring.str("Hello\r\nWorld");

        char text_read[20];

        char *str = fslc_fgets(text_read, 20, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[7]);
        CHECK_EQUAL(7, strlen(str));
        CHECK_EQUAL("Hello\r\n", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsAfterNewLineTest)
    {
        istring.str("Hello\nWorld");

        char text_read[20];

        fslc_fgets(text_read, 20, &stream);
        char *str = fslc_fgets(text_read, 20, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("World", std::string(str));
    }

    TEST_FIXTURE(StdIOFixture, FGetsAfterCrLfLineTest)
    {
        istring.str("Hello\r\nWorld");

        char text_read[20];

        fslc_fgets(text_read, 20, &stream);
        char *str = fslc_fgets(text_read, 20, &stream);

        CHECK_EQUAL(text_read, str);
        CHECK_EQUAL(0, str[5]);
        CHECK_EQUAL(5, strlen(str));
        CHECK_EQUAL("World", std::string(str));
    }
}
<|endoftext|>