<commit_before>/* Copyright 2014 Dietrich Epp.
   This file is part of Legend of Feleria.  Legend of Feleria is
   licensed under the terms of the 2-clause BSD license.  For more
   information, see LICENSE.txt. */
#include "world.hpp"
#include "base/chunk.hpp"
#include <cstring>
namespace Game {

namespace {

const int MAX_TILE = 6;
const int SCAN_SIZE = 3;
const World::EdgeTrace TRACE_OUTSIDE((float) -(SCAN_SIZE + 1), Vec2::zero());
const World::EdgeTrace TRACE_INSIDE ((float) +(SCAN_SIZE + 1), Vec2::zero());

const unsigned char TILE_CONVERT[2][MAX_TILE + 1] = {
    { 0, 1, 2, 3, 4, 0 }, // not player
    { 0, 1, 2, 3, 4, 1 }, // player
};

const char WORLD_MAGIC[16] = "Feleria World";

struct SizeInfo {
    unsigned short w, h;
    float height_min, height_max;
    Vec3 vert_scale;
};

}

World::World()
    : m_data(),
      m_vertex_data(std::pair<const void *, std::size_t>(nullptr, 0)),
      m_size(IVec2::zero()),
      m_center(Vec2::zero()),
      m_height_min(-1.0f),
      m_height_max(+1.0f),
      m_height_scale(1.0f),
      m_vertex_scale{{ 1.0f, 1.0f, 1.0f }},
      m_heightmap(nullptr),
      m_tilemap(nullptr) { }

bool World::load() {
    World w;
    w.m_data.read("world.dat", 1u << 24);
    Base::ChunkReader chunks;
    if (!chunks.read(w.m_data) ||
        std::memcmp(chunks.magic(), WORLD_MAGIC, 16) ||
        chunks.version().first != 1) {
        return false;
    }

    {
        auto chunk = chunks.get("SIZE");
        if (chunk.second != sizeof(struct SizeInfo)) {
            return false;
        }
        const SizeInfo *sz =
            reinterpret_cast<const SizeInfo *>(chunk.first);
        w.m_size = IVec2{{ sz->w, sz->h }};
        w.m_center = Vec2{{ (float) sz->w * 0.5f, (float) sz->h * 0.5f }};
        w.m_height_min = sz->height_min;
        w.m_height_max = sz->height_max;
        w.m_height_scale =
            (sz->height_max - sz->height_min) * (1.0f / 255.0f);
        w.m_vertex_scale = sz->vert_scale;
    }

    {
        auto chunk = chunks.get("MESH");
        if (!chunk.second) {
            return false;
        }
        w.m_vertex_data = chunk;
    }

    std::size_t tilesz = (std::size_t) w.m_size[0] * w.m_size[1];

    {
        auto chunk = chunks.get("HGHT");
        if (chunk.second != tilesz) {
            return false;
        }
        w.m_heightmap = reinterpret_cast<const unsigned char *>(chunk.first);
    }

    {
        auto chunk = chunks.get("TILE");
        if (chunk.second != tilesz) {
            return false;
        }
        w.m_tilemap = reinterpret_cast<const unsigned char *>(chunk.first);
        for (const unsigned char *p = w.m_tilemap, *e = p + chunk.second;
             p != e; p++) {
            if (*p > MAX_TILE) {
                return false;
            }
        }
    }

    *this = std::move(w);
    return true;
}

float World::height_at(Vec2 pos) const {
    Vec2 rpos = pos + m_center;
    int x = (int) rpos[0], y = (int) rpos[1];
    int w = m_size[0], h = m_size[1];
    if (x < 0 || y < 0 || x >= w - 1 || y >= h - 1)
        return m_height_min;
    float v00 = m_heightmap[(y+0)*w+x+0];
    float v01 = m_heightmap[(y+0)*w+x+1];
    float v10 = m_heightmap[(y+1)*w+x+0];
    float v11 = m_heightmap[(y+1)*w+x+1];
    float fx = std::fmod(rpos[0], 1.0f), fy = std::fmod(rpos[1], 1.0f);
    float v0 = v00 + (v01 - v00) * fx;
    float v1 = v10 + (v11 - v10) * fx;
    return (v0 + (v1 - v0) * fy) * m_height_scale + m_height_min;
}

World::EdgeTrace World::edge_distance(Vec2 pos, bool is_player) const {
    Vec2 rpos = pos + m_center;
    int x = (int) rpos[0], y = (int) rpos[1];
    int w = m_size[0], h = m_size[1];
    if (x < 0 || x >= w || y < 0 || y >= h) {
        return TRACE_OUTSIDE;
    }
    float fx = std::fmod(rpos[0], 1.0f), fy = std::fmod(rpos[1], 1.0f);
    const unsigned char *tc = TILE_CONVERT[(int) is_player];
    int tile = tc[m_tilemap[y*w+x]];
    bool is_inside;
    switch (tile) {
    default:
    case 0: is_inside = false; break;
    case 1: is_inside = true; break;
    case 2: is_inside = fy > 1.0f - fx; break;
    case 3: is_inside = fy > fx; break;
    case 4: is_inside = fy < fx; break;
    case 5: is_inside = fy < 1.0f - fx; break;
    }

    int x0 = x - SCAN_SIZE, x1 = x + 1 + SCAN_SIZE;
    int y0 = y - SCAN_SIZE, y1 = y + 1 + SCAN_SIZE;
    if (x0 < 0) x0 = 0;
    if (x1 >= w) x1 = w;
    if (y0 < 0) y0 = 0;
    if (y1 >= h) y1 = h;
    int ignore = is_inside ? 1 : 0;
    EdgeTrace best = TRACE_INSIDE;
    float best2 = best.first * best.first;
    for (int yi = y0; yi < y1; yi++) {
        for (int xi = x0; xi < x1; xi++) {
            tile = tc[m_tilemap[yi*w+xi]];
            EdgeTrace ttrace;
            Vec2 vp;
            if (tile < 2) {
                if (tile == ignore) {
                    continue;
                }
                if (x == xi && false) {
                    if (y > yi) {
                        ttrace = EdgeTrace(
                            (float) (y - yi - 1) + fy,
                            Vec2 {{ 0.0f, -1.0f }});
                    } else {
                        ttrace = EdgeTrace(
                            (float) (yi - y) - fy,
                            Vec2 {{ 0.0f, +1.0f }});
                    }
                    goto have_trace;
                }
                if (y == yi && false) {
                    if (x > xi) {
                        ttrace = EdgeTrace(
                            (float) (x - xi - 1) + fx,
                            Vec2 {{ -1.0f, 0.0f }});
                    } else {
                        ttrace = EdgeTrace(
                            (float) (xi - x) - fx,
                            Vec2 {{ +1.0f, 0.0f }});
                    }
                    goto have_trace;
                }
                vp[0] = (float) (xi + (x > xi));
                vp[1] = (float) (yi + (y > yi));
                goto point_distance;
            } else {
                continue;
            }

        point_distance:
            {
                Vec2 dp = vp - rpos;
                float d2 = dp.mag2();
                if (d2 < best2) {
                    float d = std::sqrt(d2);
                    if (d < 1e-4) {
                        best = EdgeTrace(d, Vec2::zero());
                    } else {
                        best = EdgeTrace(d, dp * (1.0f / d));
                    }
                    best2 = d2;
                }
            }
            continue;

        have_trace:
            if (ttrace.first < best.first) {
                best = ttrace;
                best2 = ttrace.first * ttrace.first;
            }
        }
    }
    return is_inside ? best : EdgeTrace(-best.first, -best.second);
}

}
<commit_msg>Finish edge tracing function<commit_after>/* Copyright 2014 Dietrich Epp.
   This file is part of Legend of Feleria.  Legend of Feleria is
   licensed under the terms of the 2-clause BSD license.  For more
   information, see LICENSE.txt. */
#include "world.hpp"
#include "base/chunk.hpp"
#include <cstring>
namespace Game {

namespace {

const int MAX_TILE = 6;
const int SCAN_SIZE = 3;
const World::EdgeTrace TRACE_OUTSIDE((float) -(SCAN_SIZE + 1), Vec2::zero());
const World::EdgeTrace TRACE_INSIDE ((float) +(SCAN_SIZE + 1), Vec2::zero());

const unsigned char TILE_CONVERT[2][MAX_TILE + 1] = {
    { 0, 1, 2, 3, 4, 5, 0 }, // not player
    { 0, 1, 2, 3, 4, 5, 1 }, // player
};

const char WORLD_MAGIC[16] = "Feleria World";

struct SizeInfo {
    unsigned short w, h;
    float height_min, height_max;
    Vec3 vert_scale;
};

}

World::World()
    : m_data(),
      m_vertex_data(std::pair<const void *, std::size_t>(nullptr, 0)),
      m_size(IVec2::zero()),
      m_center(Vec2::zero()),
      m_height_min(-1.0f),
      m_height_max(+1.0f),
      m_height_scale(1.0f),
      m_vertex_scale{{ 1.0f, 1.0f, 1.0f }},
      m_heightmap(nullptr),
      m_tilemap(nullptr) { }

bool World::load() {
    World w;
    w.m_data.read("world.dat", 1u << 24);
    Base::ChunkReader chunks;
    if (!chunks.read(w.m_data) ||
        std::memcmp(chunks.magic(), WORLD_MAGIC, 16) ||
        chunks.version().first != 1) {
        return false;
    }

    {
        auto chunk = chunks.get("SIZE");
        if (chunk.second != sizeof(struct SizeInfo)) {
            return false;
        }
        const SizeInfo *sz =
            reinterpret_cast<const SizeInfo *>(chunk.first);
        w.m_size = IVec2{{ sz->w, sz->h }};
        w.m_center = Vec2{{ (float) sz->w * 0.5f, (float) sz->h * 0.5f }};
        w.m_height_min = sz->height_min;
        w.m_height_max = sz->height_max;
        w.m_height_scale =
            (sz->height_max - sz->height_min) * (1.0f / 255.0f);
        w.m_vertex_scale = sz->vert_scale;
    }

    {
        auto chunk = chunks.get("MESH");
        if (!chunk.second) {
            return false;
        }
        w.m_vertex_data = chunk;
    }

    std::size_t tilesz = (std::size_t) w.m_size[0] * w.m_size[1];

    {
        auto chunk = chunks.get("HGHT");
        if (chunk.second != tilesz) {
            return false;
        }
        w.m_heightmap = reinterpret_cast<const unsigned char *>(chunk.first);
    }

    {
        auto chunk = chunks.get("TILE");
        if (chunk.second != tilesz) {
            return false;
        }
        w.m_tilemap = reinterpret_cast<const unsigned char *>(chunk.first);
        for (const unsigned char *p = w.m_tilemap, *e = p + chunk.second;
             p != e; p++) {
            if (*p > MAX_TILE) {
                return false;
            }
        }
    }

    *this = std::move(w);
    return true;
}

float World::height_at(Vec2 pos) const {
    Vec2 rpos = pos + m_center;
    int x = (int) rpos[0], y = (int) rpos[1];
    int w = m_size[0], h = m_size[1];
    if (x < 0 || y < 0 || x >= w - 1 || y >= h - 1)
        return m_height_min;
    float v00 = m_heightmap[(y+0)*w+x+0];
    float v01 = m_heightmap[(y+0)*w+x+1];
    float v10 = m_heightmap[(y+1)*w+x+0];
    float v11 = m_heightmap[(y+1)*w+x+1];
    float fx = std::fmod(rpos[0], 1.0f), fy = std::fmod(rpos[1], 1.0f);
    float v0 = v00 + (v01 - v00) * fx;
    float v1 = v10 + (v11 - v10) * fx;
    return (v0 + (v1 - v0) * fy) * m_height_scale + m_height_min;
}

World::EdgeTrace World::edge_distance(Vec2 pos, bool is_player) const {
    Vec2 rpos = pos + m_center;
    int x = (int) rpos[0], y = (int) rpos[1];
    int w = m_size[0], h = m_size[1];
    if (x < 0 || x >= w || y < 0 || y >= h) {
        return TRACE_OUTSIDE;
    }
    float fx = std::fmod(rpos[0], 1.0f), fy = std::fmod(rpos[1], 1.0f);
    const unsigned char *tc = TILE_CONVERT[(int) is_player];
    int tile = tc[m_tilemap[y*w+x]];
    bool is_inside;
    switch (tile) {
    default:
    case 0: is_inside = false; break;
    case 1: is_inside = true; break;
    case 2: is_inside = fy > 1.0f - fx; break;
    case 3: is_inside = fy > fx; break;
    case 4: is_inside = fy < fx; break;
    case 5: is_inside = fy < 1.0f - fx; break;
    }

    int x0 = x - SCAN_SIZE, x1 = x + 1 + SCAN_SIZE;
    int y0 = y - SCAN_SIZE, y1 = y + 1 + SCAN_SIZE;
    if (x0 < 0) x0 = 0;
    if (x1 >= w) x1 = w;
    if (y0 < 0) y0 = 0;
    if (y1 >= h) y1 = h;
    int ignore = is_inside ? 1 : 0;
    EdgeTrace best = TRACE_INSIDE;
    float best2 = best.first * best.first;
    for (int yi = y0; yi < y1; yi++) {
        for (int xi = x0; xi < x1; xi++) {
            tile = tc[m_tilemap[yi*w+xi]];
            EdgeTrace ttrace;
            Vec2 vp;
            if (tile < 2) {
                if (tile == ignore) {
                    continue;
                }
                if (x == xi) {
                    if (y > yi) {
                        ttrace = EdgeTrace(
                            (float) (y - yi - 1) + fy,
                            Vec2 {{ 0.0f, -1.0f }});
                    } else {
                        ttrace = EdgeTrace(
                            (float) (yi - y) - fy,
                            Vec2 {{ 0.0f, +1.0f }});
                    }
                    goto have_trace;
                }
                if (y == yi) {
                    if (x > xi) {
                        ttrace = EdgeTrace(
                            (float) (x - xi - 1) + fx,
                            Vec2 {{ -1.0f, 0.0f }});
                    } else {
                        ttrace = EdgeTrace(
                            (float) (xi - x) - fx,
                            Vec2 {{ +1.0f, 0.0f }});
                    }
                    goto have_trace;
                }
                vp[0] = (float) (xi + (x > xi));
                vp[1] = (float) (yi + (y > yi));
                goto point_distance;
            } else {
                float a, b;
                Vec2 dp;
                switch (tile) {
                case 2:
                case 5:
                    vp[0] = (float) (xi + 1);
                    vp[1] = (float) yi;
                    dp = vp - rpos;
                    b = dp[1] - dp[0];
                    a = dp[1] + dp[0];
                    if (b > 0.0f) {
                        goto point_distance;
                    }
                    if (b < -2.0f) {
                        vp[0] += -1.0f;
                        vp[1] += +1.0f;
                        goto point_distance;
                    }
                    ttrace = EdgeTrace(
                        std::abs(a) * std::sqrt(0.5f),
                        Vec2 {{ 1.0f, 1.0f }} *
                        std::copysign(std::sqrt(0.5f), a));
                    goto have_trace;

                case 3:
                case 4:
                    vp[0] = (float) xi;
                    vp[1] = (float) yi;
                    dp = vp - rpos;
                    b = dp[1] + dp[0];
                    a = dp[1] - dp[0];
                    if (b > 0.0f) {
                        goto point_distance;
                    }
                    if (b < -2.0f) {
                        vp[0] += +1.0f;
                        vp[1] += +1.0f;
                        goto point_distance;
                    }
                    ttrace = EdgeTrace(
                        std::abs(a) * std::sqrt(0.5f),
                        Vec2 {{ -1.0f, 1.0f }} *
                        std::copysign(std::sqrt(0.5f), a));
                    goto have_trace;
                }
                (void) a;
                continue;
            }

        point_distance:
            {
                Vec2 dp = vp - rpos;
                float d2 = dp.mag2();
                if (d2 < best2) {
                    float d = std::sqrt(d2);
                    if (d < 1e-4) {
                        best = EdgeTrace(d, Vec2::zero());
                    } else {
                        best = EdgeTrace(d, dp * (1.0f / d));
                    }
                    best2 = d2;
                }
            }
            continue;

        have_trace:
            if (ttrace.first < best.first) {
                best = ttrace;
                best2 = ttrace.first * ttrace.first;
            }
        }
    }
    return is_inside ? best : EdgeTrace(-best.first, -best.second);
}

}
<|endoftext|>


<commit_before>/******************************************************************************

    SDL-based Sprite Blitting API

  Copyright (c) 2013 Jeffrey Carpenter

******************************************************************************/
#include "nomlib/gfx/Sprite.hpp"

namespace nom {

Sprite::Sprite ( void )
{
NOMLIB_LOG_INFO;

  this->state = 0;

  this->sheet.sprite_width = 0;
  this->sheet.sprite_height = 0;
  this->sheet.width = 0;
  this->sheet.height = 0;
  this->sheet.id = -1;
  this->sheet.spacing = 0;
  this->sheet.padding = 0;
}

Sprite::Sprite ( unsigned int width, unsigned int height )
{
NOMLIB_LOG_INFO;

  this->coords.setSize ( width, height );

  this->state = 0;

  this->sheet.id = -1;
  this->sheet.sprite_width = 0;
  this->sheet.sprite_height = 0;
  this->sheet.width = width = 0;
  this->sheet.height = height = 0;
  this->sheet.spacing = 0;
  this->sheet.padding = 0;
}

Sprite::~Sprite ( void )
{
NOMLIB_LOG_INFO;
}

unsigned int Sprite::getState ( void )
{
  return this->state;
}

void Sprite::setState ( unsigned int state )
{
  this->state = state;
}

signed int Sprite::getSheetID ( void )
{
  return this->sheet.id;
}

void Sprite::setSheetID ( signed int id )
{
  this->sheet.id = id;
}

void Sprite::setSheetDimensions ( unsigned int sheet_width, unsigned int sheet_height, unsigned int spacing, unsigned int padding )
{
  this->sheet.sprite_width = this->coords.width;
  this->sheet.sprite_height = this->coords.height;
  this->sheet.width = sheet_width;
  this->sheet.height = sheet_height;
  this->sheet.spacing = spacing;
  this->sheet.padding = padding;
}

bool Sprite::Load  ( std::string filename, Color colorkey,
                          bool use_cache, unsigned int flags
                        )
{
  this->sprite_buffer.loadFromImage ( filename, colorkey, use_cache, flags );

  if ( ! this->sprite_buffer.valid() )
  {
NOMLIB_LOG_ERR ( "Could not load sprite image file: " + filename );
    return false;
  }

  return true;
}

void Sprite::Update ( void )
{
  if ( this->sheet.id != -1 )
  {
    // FIXME: Presently, we assume every sprite on our sheet is on the same row
    this->offsets.setPosition ( this->sheet.id * this->sheet.sprite_width, 0 );
    this->offsets.setSize ( this->sheet.sprite_width, this->sheet.sprite_height );
    this->sprite_buffer.setOffsets ( this->offsets );
  }

  this->sprite_buffer.setPosition ( coords );
}

void Sprite::Draw ( void* video_buffer ) const
{
NOMLIB_ASSERT ( this->sprite_buffer.valid() );

  this->sprite_buffer.Draw ( video_buffer );
}

} // namespace nom
<commit_msg>Make sheet ID of 1 the default<commit_after>/******************************************************************************

    SDL-based Sprite Blitting API

  Copyright (c) 2013 Jeffrey Carpenter

******************************************************************************/
#include "nomlib/gfx/Sprite.hpp"

namespace nom {

Sprite::Sprite ( void )
{
NOMLIB_LOG_INFO;

  this->state = 0;

  this->sheet.sprite_width = 0;
  this->sheet.sprite_height = 0;
  this->sheet.width = 0;
  this->sheet.height = 0;
  this->sheet.id = 1;
  this->sheet.spacing = 0;
  this->sheet.padding = 0;
}

Sprite::Sprite ( unsigned int width, unsigned int height )
{
NOMLIB_LOG_INFO;

  this->coords.setSize ( width, height );

  this->state = 0;

  this->sheet.id = 1;
  this->sheet.sprite_width = 0;
  this->sheet.sprite_height = 0;
  this->sheet.width = width = 0;
  this->sheet.height = height = 0;
  this->sheet.spacing = 0;
  this->sheet.padding = 0;
}

Sprite::~Sprite ( void )
{
NOMLIB_LOG_INFO;
}

unsigned int Sprite::getState ( void )
{
  return this->state;
}

void Sprite::setState ( unsigned int state )
{
  this->state = state;
}

signed int Sprite::getSheetID ( void )
{
  return this->sheet.id;
}

void Sprite::setSheetID ( signed int id )
{
  this->sheet.id = id;
}

void Sprite::setSheetDimensions ( unsigned int sheet_width, unsigned int sheet_height, unsigned int spacing, unsigned int padding )
{
  this->sheet.sprite_width = this->coords.width;
  this->sheet.sprite_height = this->coords.height;
  this->sheet.width = sheet_width;
  this->sheet.height = sheet_height;
  this->sheet.spacing = spacing;
  this->sheet.padding = padding;
}

bool Sprite::Load  ( std::string filename, Color colorkey,
                          bool use_cache, unsigned int flags
                        )
{
  this->sprite_buffer.loadFromImage ( filename, colorkey, use_cache, flags );

  if ( ! this->sprite_buffer.valid() )
  {
NOMLIB_LOG_ERR ( "Could not load sprite image file: " + filename );
    return false;
  }

  return true;
}

void Sprite::Update ( void )
{
  // FIXME: Presently, we assume every sprite on our sheet is on the same row
  this->offsets.setPosition ( this->sheet.id * this->sheet.sprite_width, 0 );
  this->offsets.setSize ( this->sheet.sprite_width, this->sheet.sprite_height );
  this->sprite_buffer.setOffsets ( this->offsets );

  this->sprite_buffer.setPosition ( coords );
}

void Sprite::Draw ( void* video_buffer ) const
{
NOMLIB_ASSERT ( this->sprite_buffer.valid() );

  this->sprite_buffer.Draw ( video_buffer );
}

} // namespace nom
<|endoftext|>


<commit_before>#include "graphicstransition.h"

#include <math.h>

#include <QPen>
#include <QPainter>

const qreal PI = 3.14;

GraphicsTransition::GraphicsTransition(GraphicsStateItem *from, GraphicsStateItem *to, QGraphicsItem *parent)
    : QGraphicsLineItem(parent){

    mCurrentState = from;
    mNextState = to;
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setPen(QPen(Qt::white, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

}

QRectF GraphicsTransition::boundingRect(){
    qreal extra = (pen().width() + 20) / 2.0;

        return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(),
                                          line().p2().y() - line().p1().y()))
            .normalized()
                .adjusted(-extra, -extra, extra, extra);
}

QPainterPath GraphicsTransition::shape(){
    QPainterPath path = QGraphicsLineItem::shape();
    path.addPolygon(mArrowHead);
    return path;
}

void GraphicsTransition::setNextState(GraphicsStateItem *state){
    mNextState = state;

}

void GraphicsTransition::setCurrentState(GraphicsStateItem *state){
    mCurrentState = state;

}

void GraphicsTransition::updatePosition(){

    if(mCurrentState != nullptr && mNextState != nullptr){
        QLineF line(mapFromItem(mCurrentState, 20, 0), mapFromItem(mNextState, 0, 0));
        setLine(line);
    }
}

void GraphicsTransition::writeXml(QXmlStreamWriter &writer){

    writer.writeStartElement("transition");
    writer.writeAttribute("target", mNextState->getId());

    //TODO for Each condition
    writer.writeStartElement("conditions");
    mCondition->writeXml(writer);
    writer.writeEndElement();

    writer.writeEndElement();
}

void GraphicsTransition::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    if (mCurrentState->collidesWithItem(mNextState))
       return;

    QPen myPen = pen();
    myPen.setColor(Qt::white);
    qreal arrowSize = 20;
    painter->setPen(myPen);
    painter->setBrush(Qt::white);

    QLineF centerLine(mCurrentState->getCenterPoint(), mNextState->getCenterPoint());
    QPolygonF endPolygon = mNextState->boundingRect();
    QPointF p1 = endPolygon.first() + mNextState->getCenterPoint();
    QPointF p2;
    QPointF intersectPoint;
    QLineF polyLine;
    for (int i = 1; i < endPolygon.count(); ++i) {
    p2 = endPolygon.at(i) + mNextState->getCenterPoint();
    polyLine = QLineF(p1, p2);
    QLineF::IntersectType intersectType =
        polyLine.intersect(centerLine, &intersectPoint);
    if (intersectType == QLineF::BoundedIntersection)
        break;
        p1 = p2;
    }

    setLine(QLineF(intersectPoint, mCurrentState->getCenterPoint()));

    double angle = ::acos(line().dx() / line().length());
    if (line().dy() >= 0)
        angle = (PI * 2) - angle;

    QPointF arrowP1 = line().p1() + QPointF(sin(angle + PI / 3) * arrowSize,
                                    cos(angle + PI / 3) * arrowSize);
    QPointF arrowP2 = line().p1() + QPointF(sin(angle + PI - PI / 3) * arrowSize,
                                    cos(angle + PI - PI / 3) * arrowSize);

    mArrowHead.clear();
    mArrowHead << line().p1() << arrowP1 << arrowP2;

    painter->drawLine(line());
    painter->drawPolygon(mArrowHead);
    if (isSelected()) {
        painter->setPen(QPen(Qt::white, 1, Qt::DashLine));
        QLineF myLine = line();
        myLine.translate(0, 2.0);
        painter->drawLine(myLine);
        myLine.translate(0,-4.0);
        painter->drawLine(myLine);
    }

    QGraphicsLineItem::paint(painter, option, widget);

}

<commit_msg>Transition arrow following shape of state<commit_after>#include "graphicstransition.h"

#include <math.h>

#include <QPen>
#include <QPainter>

const qreal PI = 3.14;

GraphicsTransition::GraphicsTransition(GraphicsStateItem *from, GraphicsStateItem *to, QGraphicsItem *parent)
    : QGraphicsLineItem(parent){

    mCurrentState = from;
    mNextState = to;
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setPen(QPen(Qt::white, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

}

QRectF GraphicsTransition::boundingRect(){
    qreal extra = (pen().width() + 20) / 2.0;

        return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(),
                                          line().p2().y() - line().p1().y()))
            .normalized()
                .adjusted(-extra, -extra, extra, extra);
}

QPainterPath GraphicsTransition::shape(){
    QPainterPath path = QGraphicsLineItem::shape();
    path.addPolygon(mArrowHead);
    return path;
}

void GraphicsTransition::setNextState(GraphicsStateItem *state){
    mNextState = state;

}

void GraphicsTransition::setCurrentState(GraphicsStateItem *state){
    mCurrentState = state;

}

void GraphicsTransition::updatePosition(){

    if(mCurrentState != nullptr && mNextState != nullptr){
        QLineF line(mapFromItem(mCurrentState, 20, 0), mapFromItem(mNextState, 0, 0));
        setLine(line);
    }
}

void GraphicsTransition::writeXml(QXmlStreamWriter &writer){

    writer.writeStartElement("transition");
    writer.writeAttribute("target", mNextState->getId());

    //TODO for Each condition
    writer.writeStartElement("conditions");
    mCondition->writeXml(writer);
    writer.writeEndElement();

    writer.writeEndElement();
}

void GraphicsTransition::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    //If the collide no need to draw an arrow
    if (mCurrentState->collidesWithItem(mNextState))
       return;

    QPen myPen = pen();
    myPen.setColor(Qt::white);
    qreal arrowSize = 20;
    painter->setPen(myPen);
    painter->setBrush(Qt::white);

    QLineF centerLine(mCurrentState->getCenterPoint(), mNextState->getCenterPoint());
    QPolygonF endPolygon = mNextState->boundingRect();
    QPointF p1 = endPolygon.first() + mNextState->pos();
    QPointF p2;
    QPointF intersectPoint;
    QLineF polyLine;
    for (int i = 1; i < endPolygon.count(); ++i) {
    p2 = endPolygon.at(i) + mNextState->pos();
    polyLine = QLineF(p1, p2);
    QLineF::IntersectType intersectType =
        polyLine.intersect(centerLine, &intersectPoint);
    if (intersectType == QLineF::BoundedIntersection)
        break;
        p1 = p2;
    }

    setLine(QLineF(intersectPoint, mCurrentState->getCenterPoint()));

    double angle = ::acos(line().dx() / line().length());
    if (line().dy() >= 0)
        angle = (PI * 2) - angle;

    QPointF arrowP1 = line().p1() + QPointF(sin(angle + PI / 3) * arrowSize,
                                    cos(angle + PI / 3) * arrowSize);
    QPointF arrowP2 = line().p1() + QPointF(sin(angle + PI - PI / 3) * arrowSize,
                                    cos(angle + PI - PI / 3) * arrowSize);

    mArrowHead.clear();
    mArrowHead << line().p1() << arrowP1 << arrowP2;

    painter->drawLine(line());
    painter->drawPolygon(mArrowHead);
    if (isSelected()) {
        painter->setPen(QPen(Qt::white, 1, Qt::DashLine));
        QLineF myLine = line();
        myLine.translate(0, 2.0);
        painter->drawLine(myLine);
        myLine.translate(0,-4.0);
        painter->drawLine(myLine);
    }

    QGraphicsLineItem::paint(painter, option, widget);

}

<|endoftext|>


<commit_before>/*
 * The MIT License
 *
 * Copyright 2017-2018 Norwegian University of Technology
 *
 * 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.
 */

#ifndef FMI4CPP_SCALARVARIABLE_HPP
#define FMI4CPP_SCALARVARIABLE_HPP

#include <memory>
#include <optional>
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include <ostream>

#include "enums.hpp"
#include "../fmi2Functions.h"
#include "ScalarVariableAttributes.hpp"

using std::string;
using boost::property_tree::ptree;

namespace fmi4cpp::fmi2::xml {

    //forward declarations
    class IntegerVariable;

    class RealVariable;

    class StringVariable;

    class BooleanVariable;

    class EnumerationVariable;

    class ScalarVariable {

    private:
        string name_;
        string description_;
        fmi2ValueReference valueReference_;
        bool canHandleMultipleSetPerTimelnstant_;

        fmi2Causality causality_;
        fmi2Variability variability_;
        fmi2Initial initial_;

        std::shared_ptr<IntegerAttribute> integerAttribute_;
        std::shared_ptr<RealAttribute> realAttribute_;
        std::shared_ptr<StringAttribute> stringAttribute_;
        std::shared_ptr<BooleanAttribute> booleanAttribute_;
        std::shared_ptr<EnumerationAttribute> enumerationAttribute_;

    public:

        string getName() const;

        string getDescription() const;

        fmi2ValueReference getValueReference() const;

        bool canHandleMultipleSetPerTimelnstant() const;

        fmi2Causality getCausality() const;

        fmi2Variability getVariability() const;

        fmi2Initial getInitial() const;

        IntegerVariable asIntegerVariable() const;

        RealVariable asRealVariable() const;

        StringVariable asStringVariable() const;

        BooleanVariable asBooleanVariable() const;

        EnumerationVariable asEnumerationVariable() const;

        bool isIntegerVariable() const;

        bool isRealVariable() const;

        bool isStringVariable() const;

        bool isBooleanVariable() const;

        bool isEnumerationVariable() const;

        void load(const ptree &node);

        friend std::ostream &operator<<(std::ostream &os, const ScalarVariable &variable);

    };

    template <class T, class U>
    class TypedVariable {

    private:

        bool startChanged;
        std::optional<T> originalStart;

    protected:
        U &attribute_;

    public:

        TypedVariable(U &attribute_) : attribute_(attribute_) {
            originalStart = attribute_.start;
        }

        bool hasStartChanged() const {
            return startChanged;
        }

        std::optional<T> getStart() const {
            return attribute_.start;
        }

        void setStart(const T value) {
            if (attribute_.start) {
                attribute_.start = value;
                startChanged = true;
            } else if (attribute_.start.value() != value) {
                attribute_.start = value;
                startChanged = true;
            }
        }

        void resetStart() {
            if (startChanged) {
                attribute_.start = originalStart;
                startChanged = false;
            }
        }

    };

    class IntegerVariable : public ScalarVariable, public TypedVariable<int, IntegerAttribute> {

    public:
        IntegerVariable(const ScalarVariable &var, IntegerAttribute &attribute);

        std::optional<int> getMin() const;

        std::optional<int> getMax() const;

        void setStart(const int start);

        std::optional<string> getQuantity() const;

    };

    class RealVariable : public ScalarVariable, public TypedVariable<double, RealAttribute> {

    public:
        RealVariable(const ScalarVariable &var, RealAttribute &attribute);

        std::optional<double> getMin() const;

        std::optional<double> getMax() const;

        std::optional<double> getNominal() const;

        bool getReinit() const;

        bool getUnbounded() const;

        bool getRelativeQuantity() const;

        std::optional<string> getQuantity() const;

        std::optional<string> getUnit() const;

        std::optional<string> getDisplayUnit() const;

        std::optional<unsigned int> getDerivative() const;

    };

    class StringVariable : public ScalarVariable, public TypedVariable<string, StringAttribute> {

    public:
        StringVariable(const ScalarVariable &var, StringAttribute &attribute);
    };

    class BooleanVariable : public ScalarVariable, public TypedVariable<bool, BooleanAttribute> {

    public:
        BooleanVariable(const ScalarVariable &var, BooleanAttribute &attribute);
    };

    class EnumerationVariable : public ScalarVariable, public TypedVariable<int, EnumerationAttribute> {

    public:
        EnumerationVariable(const ScalarVariable &var, EnumerationAttribute &attribute);

        std::optional<int> getMin() const;

        std::optional<int> getMax() const;

        std::optional<string> getQuantity() const;

    };

}

#endif //FMI4CPP_SCALARVARIABLE_HPP
<commit_msg>return success flag on setStart<commit_after>/*
 * The MIT License
 *
 * Copyright 2017-2018 Norwegian University of Technology
 *
 * 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.
 */

#ifndef FMI4CPP_SCALARVARIABLE_HPP
#define FMI4CPP_SCALARVARIABLE_HPP

#include <memory>
#include <optional>
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include <ostream>

#include "enums.hpp"
#include "../fmi2Functions.h"
#include "ScalarVariableAttributes.hpp"

using std::string;
using boost::property_tree::ptree;

namespace fmi4cpp::fmi2::xml {

    //forward declarations
    class IntegerVariable;

    class RealVariable;

    class StringVariable;

    class BooleanVariable;

    class EnumerationVariable;

    class ScalarVariable {

    private:
        string name_;
        string description_;
        fmi2ValueReference valueReference_;
        bool canHandleMultipleSetPerTimelnstant_;

        fmi2Causality causality_;
        fmi2Variability variability_;
        fmi2Initial initial_;

        std::shared_ptr<IntegerAttribute> integerAttribute_;
        std::shared_ptr<RealAttribute> realAttribute_;
        std::shared_ptr<StringAttribute> stringAttribute_;
        std::shared_ptr<BooleanAttribute> booleanAttribute_;
        std::shared_ptr<EnumerationAttribute> enumerationAttribute_;

    public:

        string getName() const;

        string getDescription() const;

        fmi2ValueReference getValueReference() const;

        bool canHandleMultipleSetPerTimelnstant() const;

        fmi2Causality getCausality() const;

        fmi2Variability getVariability() const;

        fmi2Initial getInitial() const;

        IntegerVariable asIntegerVariable() const;

        RealVariable asRealVariable() const;

        StringVariable asStringVariable() const;

        BooleanVariable asBooleanVariable() const;

        EnumerationVariable asEnumerationVariable() const;

        bool isIntegerVariable() const;

        bool isRealVariable() const;

        bool isStringVariable() const;

        bool isBooleanVariable() const;

        bool isEnumerationVariable() const;

        void load(const ptree &node);

        friend std::ostream &operator<<(std::ostream &os, const ScalarVariable &variable);

    };

    template <class T, class U>
    class TypedVariable {

    private:

        bool startChanged;
        std::optional<T> originalStart;

    protected:
        U &attribute_;

    public:

        TypedVariable(U &attribute_) : attribute_(attribute_) {
            originalStart = attribute_.start;
        }

        bool hasStartChanged() const {
            return startChanged;
        }

        std::optional<T> getStart() const {
            return attribute_.start;
        }

        bool setStart(const T value) {
            if (attribute_.start) {
                attribute_.start = value;
                startChanged = true;
                return true;
            } else if (attribute_.start.value() != value) {
                attribute_.start = value;
                startChanged = true;
                return true;
            }
            return false;
        }

        void resetStart() {
            if (startChanged) {
                attribute_.start = originalStart;
                startChanged = false;
            }
        }

    };

    class IntegerVariable : public ScalarVariable, public TypedVariable<int, IntegerAttribute> {

    public:
        IntegerVariable(const ScalarVariable &var, IntegerAttribute &attribute);

        std::optional<int> getMin() const;

        std::optional<int> getMax() const;

        void setStart(const int start);

        std::optional<string> getQuantity() const;

    };

    class RealVariable : public ScalarVariable, public TypedVariable<double, RealAttribute> {

    public:
        RealVariable(const ScalarVariable &var, RealAttribute &attribute);

        std::optional<double> getMin() const;

        std::optional<double> getMax() const;

        std::optional<double> getNominal() const;

        bool getReinit() const;

        bool getUnbounded() const;

        bool getRelativeQuantity() const;

        std::optional<string> getQuantity() const;

        std::optional<string> getUnit() const;

        std::optional<string> getDisplayUnit() const;

        std::optional<unsigned int> getDerivative() const;

    };

    class StringVariable : public ScalarVariable, public TypedVariable<string, StringAttribute> {

    public:
        StringVariable(const ScalarVariable &var, StringAttribute &attribute);
    };

    class BooleanVariable : public ScalarVariable, public TypedVariable<bool, BooleanAttribute> {

    public:
        BooleanVariable(const ScalarVariable &var, BooleanAttribute &attribute);
    };

    class EnumerationVariable : public ScalarVariable, public TypedVariable<int, EnumerationAttribute> {

    public:
        EnumerationVariable(const ScalarVariable &var, EnumerationAttribute &attribute);

        std::optional<int> getMin() const;

        std::optional<int> getMax() const;

        std::optional<string> getQuantity() const;

    };

}

#endif //FMI4CPP_SCALARVARIABLE_HPP
<|endoftext|>


<commit_before>/*******************************************************************************
 * tests/api/io_test.cpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <thrill/api/allgather.hpp>
#include <thrill/api/generate.hpp>
#include <thrill/api/generate_from_file.hpp>
#include <thrill/api/read_binary.hpp>
#include <thrill/api/read_lines.hpp>
#include <thrill/api/size.hpp>
#include <thrill/api/write_binary.hpp>
#include <thrill/api/write_lines.hpp>
#include <thrill/api/write_lines_many.hpp>
#include <thrill/common/logger.hpp>
#include <thrill/common/system_exception.hpp>

#include <gtest/gtest.h>

#include <algorithm>
#include <cstdlib>
#include <functional>
#include <random>
#include <string>
#include <vector>

#include <dirent.h>
#include <glob.h>
#include <sys/stat.h>

using namespace thrill;
using thrill::api::Context;
using thrill::api::DIARef;

/*!
 * A class which creates a temporary directory in /tmp/ and returns it via
 * get(). When the object is destroyed the temporary directory is wiped
 * non-recursively.
 */
class TemporaryDirectory
{
public:
    //! Create a temporary directory, returns its name without trailing /.
    static std::string make_directory(
        const char* sample = "thrill-testsuite-") {

        std::string tmp_dir = std::string(sample) + "XXXXXX";
        // evil const_cast, but mkdtemp replaces the XXXXXX with something
        // unique. it also mkdirs.
        mkdtemp(const_cast<char*>(tmp_dir.c_str()));

        return tmp_dir;
    }

    //! wipe temporary directory NON RECURSIVELY!
    static void wipe_directory(const std::string& tmp_dir, bool do_rmdir) {
        DIR* d = opendir(tmp_dir.c_str());
        if (d == nullptr) {
            throw common::SystemException(
                      "Could open temporary directory " + tmp_dir, errno);
        }

        struct dirent* de, entry;
        while (readdir_r(d, &entry, &de) == 0 && de != nullptr) {
            // skip ".", "..", and also hidden files (don't create them).
            if (de->d_name[0] == '.') continue;

            std::string path = tmp_dir + "/" + de->d_name;
            int r = unlink(path.c_str());
            if (r != 0)
                sLOG1 << "Could not unlink temporary file " << path
                      << ": " << strerror(errno);
        }

        closedir(d);

        if (!do_rmdir) return;

        if (rmdir(tmp_dir.c_str()) != 0) {
            sLOG1 << "Could not unlink temporary directory " << tmp_dir
                  << ": " << strerror(errno);
        }
    }

    TemporaryDirectory()
        : dir_(make_directory())
    { }

    ~TemporaryDirectory() {
        wipe_directory(dir_, true);
    }

    //! non-copyable: delete copy-constructor
    TemporaryDirectory(const TemporaryDirectory&) = delete;
    //! non-copyable: delete assignment operator
    TemporaryDirectory& operator = (const TemporaryDirectory&) = delete;

    //! return the temporary directory name
    const std::string & get() const { return dir_; }

    //! wipe contents of directory
    void wipe() const {
        wipe_directory(dir_, false);
    }

protected:
    std::string dir_;
};

TEST(IO, ReadSingleFile) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 1;
            for (int element : out_vec) {
                ASSERT_EQ(element, i++);
            }

            ASSERT_EQ(16u, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadFolder) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            ASSERT_EQ(ReadLines(ctx, "read_folder/*").Size(), 20);
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadPartOfFolderCompressed) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            // folder read_ints contains compressed and non-compressed files
            // with integers from 25 to 1 and a file 'donotread', which contains
            // non int-castable strings
            auto integers = ReadLines(ctx, "read_ints/read*")
                            .Map([](const std::string& line) {
                                    return atoi(line.c_str());
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 25;
            for (int element : out_vec) {
                ASSERT_EQ(element, i--);
            }

            ASSERT_EQ(25u, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, GenerateFromFileRandomIntegers) {
    api::RunSameThread(
        [](api::Context& ctx) {
            std::default_random_engine generator({ std::random_device()() });
            std::uniform_int_distribution<int> distribution(1000, 10000);

            size_t generate_size = distribution(generator);

            auto input = GenerateFromFile(
                ctx,
                "test1",
                [](const std::string& line) {
                    return atoi(line.c_str());
                },
                generate_size);

            size_t writer_size = 0;

            input.Map(
                [&writer_size](const int& item) {
                    // file contains ints between 1  and 16
                    // fails if wrong integer is generated
                    EXPECT_GE(item, 1);
                    EXPECT_GE(16, item);
                    writer_size++;
                    return std::to_string(item) + "\n";
                })
            .WriteLinesMany("out1_");

            // DIA contains as many elements as we wanted to generate
            ASSERT_EQ(generate_size, writer_size);
        });
}

TEST(IO, WriteBinaryPatternFormatter) {

    using WriteBinaryNode = api::WriteBinaryNode<int, int>;

    std::string str1 = WriteBinaryNode::make_path("test-$$$$-########", 42, 10);
    ASSERT_EQ("test-0042-00000010", str1);

    std::string str2 = WriteBinaryNode::make_path("test", 42, 10);
    ASSERT_EQ("test00420000000010", str2);
}

TEST(IO, GenerateIntegerWriteReadBinary) {
    TemporaryDirectory tmpdir;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of integers and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) { return index + 42; },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.IntegerBinary",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the integers from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<size_t>(
                    ctx,
                    tmpdir.get() + "/IO.IntegerBinary*");

                std::vector<size_t> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(42 + i, vec[i]);
                }
            }
        });
}

TEST(IO, GenerateIntegerWriteReadBinaryCompressed) {
    TemporaryDirectory tmpdir;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of integers and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) { return index + 42; },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.IntegerBinary-$$$$-####.gz",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the integers from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<size_t>(
                    ctx,
                    tmpdir.get() + "/IO.IntegerBinary*");

                std::vector<size_t> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(42 + i, vec[i]);
                }
            }
        });
}

// make weird test strings of different lengths
std::string test_string(size_t index) {
    return std::string('0' + index % 100, (index * index) % 20);
}

TEST(IO, GenerateStringWriteBinary) {
    TemporaryDirectory tmpdir;

    // use pairs for easier checking and stranger string sizes.
    using Item = std::pair<size_t, std::string>;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of string Items and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) {
                        return Item(index, test_string(index));
                    },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.StringBinary",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the Items from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<Item>(
                    ctx,
                    tmpdir.get() + "/IO.StringBinary*");

                std::vector<Item> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(Item(i, test_string(i)), vec[i]);
                }
            }
        });
}

TEST(IO, WriteAndReadBinaryEqualDIAS) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            if (ctx.my_rank() == 0) {
                std::system("rm -r ./binary/*");
            }
            ctx.Barrier();

            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return atoi(line.c_str());
                                 });

            integers.WriteBinary("binary/output_");

            std::string path = "testsf.out";

            ctx.Barrier();

            auto integers2 = api::ReadBinary<int>(
                ctx, "./binary/*");

            integers2.Map(
                [](const int& item) {
                    return std::to_string(item);
                })
            .WriteLines(path);

            // Race condition as one worker might be finished while others are
            // still writing to output file.
            ctx.Barrier();

            std::ifstream file(path);
            size_t begin = file.tellg();
            file.seekg(0, std::ios::end);
            size_t end = file.tellg();
            ASSERT_EQ(end - begin, 39);
            file.seekg(0);
            for (int i = 1; i <= 16; i++) {
                std::string line;
                std::getline(file, line);
                ASSERT_EQ(line, std::to_string(i));
            }
        };

    api::RunLocalTests(start_func);
}

/******************************************************************************/
<commit_msg>Revert "Using atoi instead of std::stoi."<commit_after>/*******************************************************************************
 * tests/api/io_test.cpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <thrill/api/allgather.hpp>
#include <thrill/api/generate.hpp>
#include <thrill/api/generate_from_file.hpp>
#include <thrill/api/read_binary.hpp>
#include <thrill/api/read_lines.hpp>
#include <thrill/api/size.hpp>
#include <thrill/api/write_binary.hpp>
#include <thrill/api/write_lines.hpp>
#include <thrill/api/write_lines_many.hpp>
#include <thrill/common/logger.hpp>
#include <thrill/common/system_exception.hpp>

#include <gtest/gtest.h>

#include <algorithm>
#include <cstdlib>
#include <functional>
#include <random>
#include <string>
#include <vector>

#include <dirent.h>
#include <glob.h>
#include <sys/stat.h>

using namespace thrill;
using thrill::api::Context;
using thrill::api::DIARef;

/*!
 * A class which creates a temporary directory in /tmp/ and returns it via
 * get(). When the object is destroyed the temporary directory is wiped
 * non-recursively.
 */
class TemporaryDirectory
{
public:
    //! Create a temporary directory, returns its name without trailing /.
    static std::string make_directory(
        const char* sample = "thrill-testsuite-") {

        std::string tmp_dir = std::string(sample) + "XXXXXX";
        // evil const_cast, but mkdtemp replaces the XXXXXX with something
        // unique. it also mkdirs.
        mkdtemp(const_cast<char*>(tmp_dir.c_str()));

        return tmp_dir;
    }

    //! wipe temporary directory NON RECURSIVELY!
    static void wipe_directory(const std::string& tmp_dir, bool do_rmdir) {
        DIR* d = opendir(tmp_dir.c_str());
        if (d == nullptr) {
            throw common::SystemException(
                      "Could open temporary directory " + tmp_dir, errno);
        }

        struct dirent* de, entry;
        while (readdir_r(d, &entry, &de) == 0 && de != nullptr) {
            // skip ".", "..", and also hidden files (don't create them).
            if (de->d_name[0] == '.') continue;

            std::string path = tmp_dir + "/" + de->d_name;
            int r = unlink(path.c_str());
            if (r != 0)
                sLOG1 << "Could not unlink temporary file " << path
                      << ": " << strerror(errno);
        }

        closedir(d);

        if (!do_rmdir) return;

        if (rmdir(tmp_dir.c_str()) != 0) {
            sLOG1 << "Could not unlink temporary directory " << tmp_dir
                  << ": " << strerror(errno);
        }
    }

    TemporaryDirectory()
        : dir_(make_directory())
    { }

    ~TemporaryDirectory() {
        wipe_directory(dir_, true);
    }

    //! non-copyable: delete copy-constructor
    TemporaryDirectory(const TemporaryDirectory&) = delete;
    //! non-copyable: delete assignment operator
    TemporaryDirectory& operator = (const TemporaryDirectory&) = delete;

    //! return the temporary directory name
    const std::string & get() const { return dir_; }

    //! wipe contents of directory
    void wipe() const {
        wipe_directory(dir_, false);
    }

protected:
    std::string dir_;
};

TEST(IO, ReadSingleFile) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 1;
            for (int element : out_vec) {
                ASSERT_EQ(element, i++);
            }

            ASSERT_EQ(16u, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadFolder) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            ASSERT_EQ(ReadLines(ctx, "read_folder/*").Size(), 20);
        };

    api::RunLocalTests(start_func);
}

TEST(IO, ReadPartOfFolderCompressed) {
    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            // folder read_ints contains compressed and non-compressed files
            // with integers from 25 to 1 and a file 'donotread', which contains
            // non int-castable strings
            auto integers = ReadLines(ctx, "read_ints/read*")
                            .Map([](const std::string& line) {
                                    sLOG1 << "line:" << line;
                                    return std::stoi(line);
                                 });

            std::vector<int> out_vec = integers.AllGather();

            int i = 25;
            for (int element : out_vec) {
                ASSERT_EQ(element, i--);
            }

            ASSERT_EQ(25u, out_vec.size());
        };

    api::RunLocalTests(start_func);
}

TEST(IO, GenerateFromFileRandomIntegers) {
    api::RunSameThread(
        [](api::Context& ctx) {
            std::default_random_engine generator({ std::random_device()() });
            std::uniform_int_distribution<int> distribution(1000, 10000);

            size_t generate_size = distribution(generator);

            auto input = GenerateFromFile(
                ctx,
                "test1",
                [](const std::string& line) {
                    return std::stoi(line);
                },
                generate_size);

            size_t writer_size = 0;

            input.Map(
                [&writer_size](const int& item) {
                    // file contains ints between 1  and 16
                    // fails if wrong integer is generated
                    EXPECT_GE(item, 1);
                    EXPECT_GE(16, item);
                    writer_size++;
                    return std::to_string(item) + "\n";
                })
            .WriteLinesMany("out1_");

            // DIA contains as many elements as we wanted to generate
            ASSERT_EQ(generate_size, writer_size);
        });
}

TEST(IO, WriteBinaryPatternFormatter) {

    using WriteBinaryNode = api::WriteBinaryNode<int, int>;

    std::string str1 = WriteBinaryNode::make_path("test-$$$$-########", 42, 10);
    ASSERT_EQ("test-0042-00000010", str1);

    std::string str2 = WriteBinaryNode::make_path("test", 42, 10);
    ASSERT_EQ("test00420000000010", str2);
}

TEST(IO, GenerateIntegerWriteReadBinary) {
    TemporaryDirectory tmpdir;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of integers and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) { return index + 42; },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.IntegerBinary",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the integers from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<size_t>(
                    ctx,
                    tmpdir.get() + "/IO.IntegerBinary*");

                std::vector<size_t> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(42 + i, vec[i]);
                }
            }
        });
}

TEST(IO, GenerateIntegerWriteReadBinaryCompressed) {
    TemporaryDirectory tmpdir;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of integers and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) { return index + 42; },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.IntegerBinary-$$$$-####.gz",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the integers from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<size_t>(
                    ctx,
                    tmpdir.get() + "/IO.IntegerBinary*");

                std::vector<size_t> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(42 + i, vec[i]);
                }
            }
        });
}

// make weird test strings of different lengths
std::string test_string(size_t index) {
    return std::string('0' + index % 100, (index * index) % 20);
}

TEST(IO, GenerateStringWriteBinary) {
    TemporaryDirectory tmpdir;

    // use pairs for easier checking and stranger string sizes.
    using Item = std::pair<size_t, std::string>;

    api::RunLocalTests(
        [&tmpdir](api::Context& ctx) {

            // wipe directory from last test
            if (ctx.my_rank() == 0) {
                tmpdir.wipe();
            }
            ctx.Barrier();

            // generate a dia of string Items and write them to disk
            size_t generate_size = 32000;
            {
                auto dia = Generate(
                    ctx,
                    [](const size_t index) {
                        return Item(index, test_string(index));
                    },
                    generate_size);

                dia.WriteBinary(tmpdir.get() + "/IO.StringBinary",
                                16 * 1024);
            }
            ctx.Barrier();

            // read the Items from disk (collectively) and compare
            {
                auto dia = api::ReadBinary<Item>(
                    ctx,
                    tmpdir.get() + "/IO.StringBinary*");

                std::vector<Item> vec = dia.AllGather();

                ASSERT_EQ(generate_size, vec.size());
                // this is another action
                ASSERT_EQ(generate_size, dia.Size());

                for (size_t i = 0; i < vec.size(); ++i) {
                    ASSERT_EQ(Item(i, test_string(i)), vec[i]);
                }
            }
        });
}

TEST(IO, WriteAndReadBinaryEqualDIAS) {

    std::function<void(Context&)> start_func =
        [](Context& ctx) {
            if (ctx.my_rank() == 0) {
                std::system("rm -r ./binary/*");
            }
            ctx.Barrier();

            auto integers = ReadLines(ctx, "test1")
                            .Map([](const std::string& line) {
                                     return std::stoi(line);
                                 });

            integers.WriteBinary("binary/output_");

            std::string path = "testsf.out";

            ctx.Barrier();

            auto integers2 = api::ReadBinary<int>(
                ctx, "./binary/*");

            integers2.Map(
                [](const int& item) {
                    return std::to_string(item);
                })
            .WriteLines(path);

            // Race condition as one worker might be finished while others are
            // still writing to output file.
            ctx.Barrier();

            std::ifstream file(path);
            size_t begin = file.tellg();
            file.seekg(0, std::ios::end);
            size_t end = file.tellg();
            ASSERT_EQ(end - begin, 39);
            file.seekg(0);
            for (int i = 1; i <= 16; i++) {
                std::string line;
                std::getline(file, line);
                ASSERT_EQ(std::stoi(line), i);
            }
        };

    api::RunLocalTests(start_func);
}

/******************************************************************************/
<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file ScriptingPhotoModeView.cpp Scripting photo mode view
//

// includes
#include "stdafx.h"
#include "resource.h"
#include "ScriptingPhotoModeView.hpp"
#include "IPhotoModeViewHost.hpp"
#include "Lua.hpp"
#include "Path.hpp"
#include "Filesystem.hpp"
#include "Process.hpp"

/// file open filter for Lua scripting
LPCTSTR g_pszLuaScriptingFilter =
_T("Lua Files (*.lua)\0*.lua\0")
_T("All Files (*.*)\0*.*\0")
_T("");

ScriptingPhotoModeView::ScriptingPhotoModeView(IPhotoModeViewHost& host) throw()
:CSplitterWindowImpl<ScriptingPhotoModeView>(false), // horizontal
m_host(host)
{
   m_processor.SetOutputDebugStringHandler(
      std::bind(&ScriptingPhotoModeView::OnOutputDebugString, this, std::placeholders::_1));
}

HWND ScriptingPhotoModeView::CreateView(HWND hWndParent)
{
   HWND hWndClient = Create(hWndParent, CWindow::rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

   m_view.Create(hWndClient, CWindow::rcDefault, NULL,
      WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0);

   m_view.SetupSourceEditor();
   m_view.SetReadOnly(true);
   m_view.HideCaret();

   SetupOutputPane();

   SetSplitterPanes(m_view, m_pane);
   SetSinglePaneMode(SPLIT_PANE_NONE);

   SetSplitterPosPct(75);

   return hWndClient;
}

void ScriptingPhotoModeView::SetupOutputPane()
{
   m_pane.SetPaneContainerExtendedStyle(PANECNT_FLATBORDER | PANECNT_NOCLOSEBUTTON);
   m_pane.Create(m_hWnd, _T("Output"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

   m_ecOutputWindow.Create(CScintillaWindow::GetWndClassName(), m_pane, CWindow::rcDefault, NULL,
      WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0);

   m_pane.SetClient(m_ecOutputWindow);

   m_ecOutputWindow.StyleSetFont(STYLE_DEFAULT, "Courier New");
   m_ecOutputWindow.StyleSetSize(STYLE_DEFAULT, 11);
   m_ecOutputWindow.SetLexer(SCLEX_LUA);

   m_ecOutputWindow.SetText("Ready.\n");
}

void ScriptingPhotoModeView::OnOutputDebugString(const CString& cszText)
{
   CStringA cszaText(cszText);
   m_ecOutputWindow.AppendText(cszaText.GetString(), cszaText.GetLength());

   m_ecOutputWindow.ScrollToLine(m_ecOutputWindow.GetLineCount());
}

void ScriptingPhotoModeView::OpenScript()
{
   CFileDialog dlg(TRUE, NULL, _T(""), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, g_pszLuaScriptingFilter);
   int iRet = dlg.DoModal(m_hWnd);

   if (iRet != IDOK)
      return;

   m_view.SetReadOnly(false);

   bool bRet = m_view.Load(dlg.m_ofn.lpstrFile) != FALSE;
   if (!bRet)
      return;

   m_view.Init(dlg.m_ofn.lpstrFile);
   m_view.SetReadOnly(true);
   m_view.HideCaret();

   m_host.EnableUI(ID_SCRIPTING_RELOAD, true);
   m_host.EnableUI(ID_SCRIPTING_EDIT, true);
}

void ScriptingPhotoModeView::EditScript(const CString& cszFilename)
{
   if (cszFilename.IsEmpty())
      return;

   CString cszCommandLine;
   cszCommandLine.Format(_T("\"%s\" \"%s\""),
      Path::Combine(Path(App_GetFilename()).DirectoryName(), _T("RemoteScriptingEditor")),
      cszFilename);

   Process process;
   process.WorkingDirectory(Path(cszFilename).DirectoryName());
   bool bRet = process.Create(cszCommandLine);

   if (bRet)
      WaitForSingleObject(process.ProcessHandle(), INFINITE);
   else
      AtlMessageBox(m_hWnd, _T("Couldn't start Remote Scripting Editor."), IDR_MAINFRAME, MB_OK);

   return;
}

LRESULT ScriptingPhotoModeView::OnScriptingOpenScript(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   OpenScript();

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingReload(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   CString cszFilename = m_view.GetFilePath();
   m_view.Load(cszFilename);

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingRun(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   m_host.EnableUI(ID_SCRIPTING_RUN, false);
   m_host.EnableUI(ID_SCRIPTING_STOP, true);

   {
      CString cszText;
      cszText.Format(_T("Start executing file %s...\n\n"),
         m_view.GetFilePath().GetString());

      m_ecOutputWindow.SetText(CStringA(cszText));
   }

   m_processor.Stop();

   try
   {
      m_processor.LoadScript(m_view.GetFilePath());

      m_processor.Run();
   }
   catch (const Lua::Exception& ex)
   {
      CString cszText;
      cszText.Format(_T("%s(%u): %s"),
         ex.LuaSourceFile().GetString(),
         ex.LuaLineNumber(),
         ex.LuaErrorMessage().GetString());

      OnOutputDebugString(cszText);

      m_host.EnableUI(ID_SCRIPTING_RUN, TRUE);
      m_host.EnableUI(ID_SCRIPTING_STOP, FALSE);
   }

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingStop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   m_host.EnableUI(ID_SCRIPTING_RUN, TRUE);
   m_host.EnableUI(ID_SCRIPTING_STOP, FALSE);

   m_processor.Stop();

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingEditScript(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   CString cszFilename = m_view.GetFilePath();

   EditScript(cszFilename);

   m_view.Load(cszFilename);

   return 0;
}
<commit_msg>fixed code calling RemoteScriptingEditor<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file ScriptingPhotoModeView.cpp Scripting photo mode view
//

// includes
#include "stdafx.h"
#include "resource.h"
#include "ScriptingPhotoModeView.hpp"
#include "IPhotoModeViewHost.hpp"
#include "Lua.hpp"
#include "Path.hpp"
#include "Filesystem.hpp"
#include "Process.hpp"

/// file open filter for Lua scripting
LPCTSTR g_pszLuaScriptingFilter =
_T("Lua Files (*.lua)\0*.lua\0")
_T("All Files (*.*)\0*.*\0")
_T("");

ScriptingPhotoModeView::ScriptingPhotoModeView(IPhotoModeViewHost& host) throw()
:CSplitterWindowImpl<ScriptingPhotoModeView>(false), // horizontal
m_host(host)
{
   m_processor.SetOutputDebugStringHandler(
      std::bind(&ScriptingPhotoModeView::OnOutputDebugString, this, std::placeholders::_1));
}

HWND ScriptingPhotoModeView::CreateView(HWND hWndParent)
{
   HWND hWndClient = Create(hWndParent, CWindow::rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

   m_view.Create(hWndClient, CWindow::rcDefault, NULL,
      WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0);

   m_view.SetupSourceEditor();
   m_view.SetReadOnly(true);
   m_view.HideCaret();

   SetupOutputPane();

   SetSplitterPanes(m_view, m_pane);
   SetSinglePaneMode(SPLIT_PANE_NONE);

   SetSplitterPosPct(75);

   return hWndClient;
}

void ScriptingPhotoModeView::SetupOutputPane()
{
   m_pane.SetPaneContainerExtendedStyle(PANECNT_FLATBORDER | PANECNT_NOCLOSEBUTTON);
   m_pane.Create(m_hWnd, _T("Output"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

   m_ecOutputWindow.Create(CScintillaWindow::GetWndClassName(), m_pane, CWindow::rcDefault, NULL,
      WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0);

   m_pane.SetClient(m_ecOutputWindow);

   m_ecOutputWindow.StyleSetFont(STYLE_DEFAULT, "Courier New");
   m_ecOutputWindow.StyleSetSize(STYLE_DEFAULT, 11);
   m_ecOutputWindow.SetLexer(SCLEX_LUA);

   m_ecOutputWindow.SetText("Ready.\n");
}

void ScriptingPhotoModeView::OnOutputDebugString(const CString& cszText)
{
   CStringA cszaText(cszText);
   m_ecOutputWindow.AppendText(cszaText.GetString(), cszaText.GetLength());

   m_ecOutputWindow.ScrollToLine(m_ecOutputWindow.GetLineCount());
}

void ScriptingPhotoModeView::OpenScript()
{
   CFileDialog dlg(TRUE, NULL, _T(""), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, g_pszLuaScriptingFilter);
   int iRet = dlg.DoModal(m_hWnd);

   if (iRet != IDOK)
      return;

   m_view.SetReadOnly(false);

   bool bRet = m_view.Load(dlg.m_ofn.lpstrFile) != FALSE;
   if (!bRet)
      return;

   m_view.Init(dlg.m_ofn.lpstrFile);
   m_view.SetReadOnly(true);
   m_view.HideCaret();

   m_host.EnableUI(ID_SCRIPTING_RELOAD, true);
   m_host.EnableUI(ID_SCRIPTING_EDIT, true);
}

void ScriptingPhotoModeView::EditScript(const CString& cszFilename)
{
   if (cszFilename.IsEmpty())
      return;

   CString cszEditorFilename =
      Path::Combine(Path(App_GetFilename()).DirectoryName(), _T("RemoteScriptingEditor.exe")).ToString();

   CString cszCommandLine;
   cszCommandLine.Format(_T("\"%s\" \"%s\""),
      cszEditorFilename.GetString(),
      cszFilename.GetString());

   Process process;
   process.WorkingDirectory(Path(cszFilename).DirectoryName());
   bool bRet = process.Create(cszCommandLine);

   if (bRet)
      WaitForSingleObject(process.ProcessHandle(), INFINITE);
   else
      AtlMessageBox(m_hWnd, _T("Couldn't start Remote Scripting Editor."), IDR_MAINFRAME, MB_OK);

   return;
}

LRESULT ScriptingPhotoModeView::OnScriptingOpenScript(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   OpenScript();

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingReload(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   CString cszFilename = m_view.GetFilePath();
   m_view.Load(cszFilename);

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingRun(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   m_host.EnableUI(ID_SCRIPTING_RUN, false);
   m_host.EnableUI(ID_SCRIPTING_STOP, true);

   {
      CString cszText;
      cszText.Format(_T("Start executing file %s...\n\n"),
         m_view.GetFilePath().GetString());

      m_ecOutputWindow.SetText(CStringA(cszText));
   }

   m_processor.Stop();

   try
   {
      m_processor.LoadScript(m_view.GetFilePath());

      m_processor.Run();
   }
   catch (const Lua::Exception& ex)
   {
      CString cszText;
      cszText.Format(_T("%s(%u): %s"),
         ex.LuaSourceFile().GetString(),
         ex.LuaLineNumber(),
         ex.LuaErrorMessage().GetString());

      OnOutputDebugString(cszText);

      m_host.EnableUI(ID_SCRIPTING_RUN, TRUE);
      m_host.EnableUI(ID_SCRIPTING_STOP, FALSE);
   }

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingStop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   m_host.EnableUI(ID_SCRIPTING_RUN, TRUE);
   m_host.EnableUI(ID_SCRIPTING_STOP, FALSE);

   m_processor.Stop();

   return 0;
}

LRESULT ScriptingPhotoModeView::OnScriptingEditScript(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   CString cszFilename = m_view.GetFilePath();

   EditScript(cszFilename);

   m_view.Load(cszFilename);

   return 0;
}
<|endoftext|>


<commit_before>//      rpg.cpp
//

#include <iostream>
#include <vector>
#include <string>
#include "Utils.h"
#include "CommandFactory.h"
#include "Rpg.h"

using namespace std;

Rpg::Rpg(string login, string password, vector <string> action)
{
    //if the game is launched with login/password, the player is directly fetched
    if (login.compare("") != 0 && password.compare("") != 0) {
        _player = new Player(login, password);
        _authenticate = true;
    }
    //else an empty player is created
    else {
        _player = new Player();
        _authenticate = false;
    }
    _action = action;

}

Rpg::~Rpg()
{
    if (_player != NULL) {
        delete(_player);
    }
}

int Rpg::_runAction()
{
    CommandAbstract *command = CommandFactory::create(_player, _action);
    if (command != NULL) {
        cout << _action[0] << endl;
    }
    return 1;
}

void Rpg::run()
{
    //no login/password given, but an action given => not normal
    if (!_authenticate && _action.size() > 0) {
        cerr << "Command given but no player" << endl;
        return;
    }

    //we try to connect the member
    if (!_player->connect()) {
        return;
    }

    if (_action.size() > 0) {
        _runAction();
    }
    else {
        bool quit = false;
        string command;
        while (!quit) {
            cerr << "Command:" << endl;
            getline (cin, command);

            if (command.compare("quit") == 0) {
                quit = true;
            }
            else {
                _action = Utils::explode(command, ' ');
                _runAction();
            }
        }
    }
}
<commit_msg>test simplified<commit_after>//      rpg.cpp
//

#include <iostream>
#include <vector>
#include <string>
#include "Utils.h"
#include "CommandFactory.h"
#include "Rpg.h"

using namespace std;

Rpg::Rpg(string login, string password, vector <string> action)
{
    //if the game is launched with login/password, the player is directly fetched
    if (login.compare("") != 0 && password.compare("") != 0) {
        _player = new Player(login, password);
        _authenticate = true;
    }
    //else an empty player is created
    else {
        _player = new Player();
        _authenticate = false;
    }
    _action = action;

}

Rpg::~Rpg()
{
    if (_player != NULL) {
        delete(_player);
    }
}

int Rpg::_runAction()
{
    CommandAbstract *command = CommandFactory::create(_player, _action);
    if (command != NULL) {
        cout << _action[0] << endl;
    }
    return 1;
}

void Rpg::run()
{
    if (((!_authenticate && _action.size() == 0) || _authenticate) && !_player->connect()) {
        return;
    }

    if (_action.size() > 0) {
        _runAction();
    }
    else {
        bool quit = false;
        string command;
        while (!quit) {
            cerr << "Command:" << endl;
            getline (cin, command);

            if (command.compare("quit") == 0) {
                quit = true;
            }
            else {
                _action = Utils::explode(command, ' ');
                _runAction();
            }
        }
    }
}
<|endoftext|>


<commit_before>#include "Test.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkRect.h"

static inline const char* boolStr(bool value) {
    return value ? "true" : "false";
}

// these are in the same order as the SkBitmap::Config enum
static const char* gConfigName[] = {
    "None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8"
};

/** Returns -1 on success, else the x coord of the first bad pixel, return its
    value in bad
 */
typedef int (*Proc)(const void*, int width, uint32_t expected, uint32_t* bad);

static int proc_32(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_16(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const uint16_t* addr = static_cast<const uint16_t*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_8(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (SkGetPackedA32(addr[x]) != expected) {
            *bad = SkGetPackedA32(addr[x]);
            return x;
        }
    }
    return -1;
}

static int proc_bad(const void* ptr, int, uint32_t, uint32_t* bad) {
    *bad = 0;
    return 0;
}

static Proc find_proc(const SkBitmap& bm, SkPMColor expect32, uint16_t expect16,
                      uint8_t expect8, uint32_t* expect) {
    switch (bm.config()) {
        case SkBitmap::kARGB_8888_Config:
            *expect = expect32;
            return proc_32;
        case SkBitmap::kARGB_4444_Config:
        case SkBitmap::kRGB_565_Config:
            *expect = expect16;
            return proc_16;
        case SkBitmap::kA8_Config:
            *expect = expect8;
            return proc_8;
        default:
            *expect = 0;
            return proc_bad;
    }
}

static bool check_color(const SkBitmap& bm, SkPMColor expect32,
                        uint16_t expect16, uint8_t expect8,
                        skiatest::Reporter* reporter) {
    uint32_t expect;
    Proc proc = find_proc(bm, expect32, expect16, expect8, &expect);
    for (int y = 0; y < bm.height(); y++) {
        uint32_t bad;
        int x = proc(bm.getAddr(0, y), bm.width(), expect, &bad);
        if (x >= 0) {
            SkString str;
            str.printf("BlitRow config=%s [%d %d] expected %x got %x",
                       gConfigName[bm.config()], x, y, expect, bad);
            reporter->reportFailed(str);
            return false;
        }
    }
    return true;
}

static void TestBlitRow(skiatest::Reporter* reporter) {
    static const int W = 256;

    static const SkBitmap::Config gDstConfig[] = {
        SkBitmap::kARGB_8888_Config,
        SkBitmap::kRGB_565_Config,
//        SkBitmap::kARGB_4444_Config,
//        SkBitmap::kA8_Config,
    };

    static const struct {
        SkColor     fSrc;
        SkColor     fDst;
        SkPMColor   fResult32;
        uint16_t    fResult16;
        uint8_t     fResult8;
    } gSrcRec[] = {
        { 0,            0,          0,                                    0,      0 },
        { 0,            0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0,          SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
    };

    SkPaint paint;
    paint.setDither(true);

    SkBitmap srcBM;
    srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, 1);
    srcBM.allocPixels();

    for (size_t i = 0; i < SK_ARRAY_COUNT(gDstConfig); i++) {
        SkBitmap dstBM;
        dstBM.setConfig(gDstConfig[i], W, 1);
        dstBM.allocPixels();

        SkCanvas canvas(dstBM);
        for (size_t j = 0; j < SK_ARRAY_COUNT(gSrcRec); j++) {
            srcBM.eraseColor(gSrcRec[j].fSrc);
            dstBM.eraseColor(gSrcRec[j].fDst);

            for (int k = 0; k < 4; k++) {
                bool dither = (k & 1) != 0;
                bool blend = (k & 2) != 0;
                if (gSrcRec[j].fSrc != 0 && blend) {
                    // can't make a numerical promise about blending anything
                    // but 0
                 //   continue;
                }
                paint.setDither(dither);
                paint.setAlpha(blend ? 0x80 : 0xFF);
                canvas.drawBitmap(srcBM, 0, 0, &paint);
                if (!check_color(dstBM, gSrcRec[j].fResult32, gSrcRec[j].fResult16,
                                 gSrcRec[j].fResult8, reporter)) {
                    SkDebugf("--- src index %d dither %d blend %d\n", j, dither, blend);
                }
            }
        }
    }
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("BlitRow", TestBlitRowClass, TestBlitRow)
<commit_msg>update blitrow test to exercise different widths for blitrow<commit_after>#include "Test.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkGradientShader.h"
#include "SkRect.h"

static inline const char* boolStr(bool value) {
    return value ? "true" : "false";
}

// these are in the same order as the SkBitmap::Config enum
static const char* gConfigName[] = {
    "None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8"
};

/** Returns -1 on success, else the x coord of the first bad pixel, return its
    value in bad
 */
typedef int (*Proc)(const void*, int width, uint32_t expected, uint32_t* bad);

static int proc_32(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_16(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const uint16_t* addr = static_cast<const uint16_t*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_8(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (SkGetPackedA32(addr[x]) != expected) {
            *bad = SkGetPackedA32(addr[x]);
            return x;
        }
    }
    return -1;
}

static int proc_bad(const void* ptr, int, uint32_t, uint32_t* bad) {
    *bad = 0;
    return 0;
}

static Proc find_proc(const SkBitmap& bm, SkPMColor expect32, uint16_t expect16,
                      uint8_t expect8, uint32_t* expect) {
    switch (bm.config()) {
        case SkBitmap::kARGB_8888_Config:
            *expect = expect32;
            return proc_32;
        case SkBitmap::kARGB_4444_Config:
        case SkBitmap::kRGB_565_Config:
            *expect = expect16;
            return proc_16;
        case SkBitmap::kA8_Config:
            *expect = expect8;
            return proc_8;
        default:
            *expect = 0;
            return proc_bad;
    }
}

static bool check_color(const SkBitmap& bm, SkPMColor expect32,
                        uint16_t expect16, uint8_t expect8,
                        skiatest::Reporter* reporter) {
    uint32_t expect;
    Proc proc = find_proc(bm, expect32, expect16, expect8, &expect);
    for (int y = 0; y < bm.height(); y++) {
        uint32_t bad;
        int x = proc(bm.getAddr(0, y), bm.width(), expect, &bad);
        if (x >= 0) {
            SkString str;
            str.printf("BlitRow config=%s [%d %d] expected %x got %x",
                       gConfigName[bm.config()], x, y, expect, bad);
            reporter->reportFailed(str);
            return false;
        }
    }
    return true;
}

// Make sure our blits always map src==0 to a noop, and src==FF to full opaque
static void test_00_FF(skiatest::Reporter* reporter) {
    static const int W = 256;

    static const SkBitmap::Config gDstConfig[] = {
        SkBitmap::kARGB_8888_Config,
        SkBitmap::kRGB_565_Config,
//        SkBitmap::kARGB_4444_Config,
//        SkBitmap::kA8_Config,
    };

    static const struct {
        SkColor     fSrc;
        SkColor     fDst;
        SkPMColor   fResult32;
        uint16_t    fResult16;
        uint8_t     fResult8;
    } gSrcRec[] = {
        { 0,            0,          0,                                    0,      0 },
        { 0,            0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0,          SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
    };

    SkPaint paint;

    SkBitmap srcBM;
    srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, 1);
    srcBM.allocPixels();

    for (size_t i = 0; i < SK_ARRAY_COUNT(gDstConfig); i++) {
        SkBitmap dstBM;
        dstBM.setConfig(gDstConfig[i], W, 1);
        dstBM.allocPixels();

        SkCanvas canvas(dstBM);
        for (size_t j = 0; j < SK_ARRAY_COUNT(gSrcRec); j++) {
            srcBM.eraseColor(gSrcRec[j].fSrc);
            dstBM.eraseColor(gSrcRec[j].fDst);

            for (int k = 0; k < 4; k++) {
                bool dither = (k & 1) != 0;
                bool blend = (k & 2) != 0;
                if (gSrcRec[j].fSrc != 0 && blend) {
                    // can't make a numerical promise about blending anything
                    // but 0
                 //   continue;
                }
                paint.setDither(dither);
                paint.setAlpha(blend ? 0x80 : 0xFF);
                canvas.drawBitmap(srcBM, 0, 0, &paint);
                if (!check_color(dstBM, gSrcRec[j].fResult32, gSrcRec[j].fResult16,
                                 gSrcRec[j].fResult8, reporter)) {
                    SkDebugf("--- src index %d dither %d blend %d\n", j, dither, blend);
                }
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

struct Mesh {
    SkPoint     fPts[4];
    uint16_t    fIndices[6];

    Mesh(const SkBitmap& bm, SkPaint* paint) {
        const SkScalar w = SkIntToScalar(bm.width());
        const SkScalar h = SkIntToScalar(bm.height());
        fPts[0].set(0, 0);
        fPts[1].set(w, 0);
        fPts[2].set(w, h);
        fPts[3].set(0, h);
        SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode,
                                                   SkShader::kClamp_TileMode);
        paint->setShader(s)->unref();

    }

    void draw(SkCanvas* canvas, SkPaint* paint) {
        canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, fPts, fPts,
                             NULL, NULL, NULL, 0, *paint);
    }
};

#include "SkImageEncoder.h"
static void save_bm(const SkBitmap& bm, const char name[]) {
    SkImageEncoder::EncodeFile(name, bm, SkImageEncoder::kPNG_Type, 100);
}

static bool gOnce;

// Make sure our blits are invariant with the width of the blit (i.e. that
// special case for 8 at a time have the same results as narrower blits)
static void test_diagonal(skiatest::Reporter* reporter) {
    static const int W = 64;
    static const int H = W;

    static const SkBitmap::Config gDstConfig[] = {
        SkBitmap::kARGB_8888_Config,
        SkBitmap::kRGB_565_Config,
        //        SkBitmap::kARGB_4444_Config,
        //        SkBitmap::kA8_Config,
    };

    static const SkColor gDstBG[] = { 0, 0xFFFFFFFF };

    SkPaint paint;

    SkBitmap srcBM;
    srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, H);
    srcBM.allocPixels();
    SkRect srcR = { 0, 0, srcBM.width(), srcBM.height() };

    // cons up a mesh to draw the bitmap with
    Mesh mesh(srcBM, &paint);

    for (size_t i = 0; i < SK_ARRAY_COUNT(gDstConfig); i++) {
        SkBitmap dstBM0, dstBM1;
        dstBM0.setConfig(gDstConfig[i], W, H);
        dstBM1.setConfig(gDstConfig[i], W, H);
        dstBM0.allocPixels();
        dstBM1.allocPixels();

        SkCanvas canvas0(dstBM0);
        SkCanvas canvas1(dstBM1);
        SkColor bgColor;

        for (size_t j = 0; j < SK_ARRAY_COUNT(gDstBG); j++) {
            bgColor = gDstBG[j];

            for (int c = 0; c <= 0xFF; c++) {
                srcBM.eraseARGB(0xFF, c, c, c);

                for (int k = 0; k < 4; k++) {
                    bool dither = (k & 1) != 0;
                    uint8_t alpha = (k & 2) ? 0x80 : 0xFF;
                    paint.setDither(dither);
                    paint.setAlpha(alpha);

                    dstBM0.eraseColor(bgColor);
                    dstBM1.eraseColor(bgColor);

                    canvas0.drawRect(srcR, paint);
                    mesh.draw(&canvas1, &paint);

                    if (!gOnce && false) {
                        save_bm(dstBM0, "drawBitmap.png");
                        save_bm(dstBM1, "drawMesh.png");
                        gOnce = true;
                    }

                    if (memcmp(dstBM0.getPixels(), dstBM1.getPixels(), dstBM0.getSize())) {
                        SkString str;
                        str.printf("Diagonal config=%s bg=0x%x dither=%d alpha=0x%x src=0x%x",
                                   gConfigName[gDstConfig[i]], bgColor, dither, alpha, c);
                        reporter->reportFailed(str);
                    }
                }
            }
        }
    }
}

static void TestBlitRow(skiatest::Reporter* reporter) {
    test_00_FF(reporter);
    test_diagonal(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("BlitRow", TestBlitRowClass, TestBlitRow)
<|endoftext|>