<commit_before>#include <sge/engine.hpp>
#include <sge/node.hpp>
#include <sstream>
#include <string>
#include <list>

using namespace std;

namespace sge
{
    Node::Node(const string &name, Engine &engine) : name(name), engine(engine)
    {
    }

    const char *Node::get_name() const
    {
        return name.c_str();
    }

    vector<string> Node::mro() const
    {
        return {"Node"};
    }

    bool Node::is_of(const string &nodetype) const
    {
        for (auto &_nodetype : mro())
        {
            if (_nodetype == nodetype)
            {
                return true;
            }
        }

        return false;
    }

    shared_ptr<Node> Node::get_root()
    {
        shared_ptr<Node> root = shared_from_this();

        while (root->get_parent() != nullptr)
        {
            root = root->get_parent();
        }

        return root;
    }

    shared_ptr<Node> Node::get_parent() const
    {
        return parent.lock();
    }

    shared_ptr<Node> Node::get_node(const string &path)
    {
        if (path.empty())
        {
            return shared_from_this();
        }
        else if (path[0] == '/')
        {
            return get_root()->get_node(path.substr(1));
        }
        else
        {
            size_t pos = path.find("/");
            string childpath = path.substr(0, pos);

            if (childpath == ".")
            {
                if (pos == string::npos)
                {
                    return shared_from_this();
                }
                else
                {
                    return get_node(path.substr(pos + 1));
                }
            }
            else if (childpath == "..")
            {
                if (pos == string::npos)
                {
                    return get_parent();
                }
                else
                {
                    return get_parent()->get_node(path.substr(pos + 1));
                }
            }
            else
            {
                shared_ptr<Node> child = nullptr;

                for (auto &_child : children)
                {
                    if (_child->get_name() == childpath)
                    {
                        child = _child;
                        break;
                    }
                }

                if (pos == string::npos)
                {
                    return child;
                }
                else
                {
                    return child->get_node(path.substr(pos + 1));
                }
            }
        }
    }

    vector<shared_ptr<Node>> Node::find_children_by_type(const vector<string> &types) const
    {
        vector<shared_ptr<Node>> result;

        for (auto &child : children)
        {
            for (auto &nodetype : types)
            {
                if (child->is_of(nodetype))
                {
                    result.push_back(child);
                    break;
                }
            }

            auto child_result = child->find_children_by_type(types);

            if (!child_result.empty())
            {
                result.insert(result.end(), child_result.begin(), child_result.end());
            }
        }

        return result;
    }

    shared_ptr<Node> Node::find_first_ancestor_by_type(const string &type) const
    {
        shared_ptr<Node> result = get_parent();

        if (result == nullptr)
        {
            return nullptr;
        }
        else if (result->is_of(type))
        {
            return result;
        }
        else
        {
            return result->find_first_ancestor_by_type(type);
        }
    }

    void Node::add_child(shared_ptr<Node> child, bool reparent)
    {
        children.push_back(child);

        if (reparent)
        {
            child->reparent(shared_from_this(), true, false);
        }
    }

    void Node::remove_child(shared_ptr<Node> child, bool reparent)
    {
        for (auto it = children.begin(); it != children.end(); it++)
        {
            if (*it == child)
            {
                children.erase(it);
                break;
            }
        }

        if (reparent)
        {
            child->reparent(nullptr, false, true);
        }
    }

    void Node::reparent(shared_ptr<Node> newparent, bool remove, bool add)
    {
        if (get_parent() != nullptr)
        {
            if (is_in_tree())
            {
                send_exit_tree();
            }

            if (remove)
            {
                get_parent()->remove_child(shared_from_this(), false);
            }
        }

        parent = newparent;

        if (get_parent() != nullptr)
        {
            if (add)
            {
                get_parent()->add_child(shared_from_this(), false);
            }

            if (!is_in_tree())
            {
                send_enter_tree();
            }
        }
    }

    bool Node::has_input() const
    {
        return input_enabled;
    }

    void Node::set_input(bool enabled)
    {
        input_enabled = enabled;
    }

    bool Node::send_input(SDL_Event *event)
    {
        bool result = true;

        if (has_input())
        {
            result = result && input(event);
        }

        for (auto &child : children)
        {
            result = result && child->send_input(event);
        }

        return result;
    }

    bool Node::input(SDL_Event *)
    {
        return true;
    }

    bool Node::has_process() const
    {
        return process_enabled;
    }

    void Node::set_process(bool enabled)
    {
        process_enabled = enabled;
    }

    void Node::send_process(Uint32 delta)
    {
        if (has_process())
        {
            process(delta);
        }

        for (auto &child : children)
        {
            child->send_process(delta);
        }
    }

    void Node::process(Uint32) {}

    bool Node::has_draw() const
    {
        return draw_enabled;
    }

    void Node::set_draw(bool enabled)
    {
        draw_enabled = enabled;
    }

    void Node::send_draw()
    {
        if (has_draw())
        {
            draw();
        }

        for (auto &child : children)
        {
            child->send_draw();
        }
    }

    void Node::draw() {}

    void Node::send_enter_tree()
    {
        enter_tree();

        for (auto &child : children)
        {
            child->send_enter_tree();
        }

        in_tree = true;

        ready ();
    }

    void Node::enter_tree() {}
    void Node::ready() {}

    void Node::send_exit_tree()
    {
        for (auto &child : children)
        {
            child->send_exit_tree();
        }

        exit_tree();

        in_tree = false;
    }

    void Node::exit_tree() {}

    bool Node::is_in_tree() const
    {
        return in_tree;
    }
}
<commit_msg>check if node is still in tree before passing message to children<commit_after>#include <sge/engine.hpp>
#include <sge/node.hpp>
#include <sstream>
#include <string>
#include <list>

using namespace std;

namespace sge
{
    Node::Node(const string &name, Engine &engine) : name(name), engine(engine)
    {
    }

    const char *Node::get_name() const
    {
        return name.c_str();
    }

    vector<string> Node::mro() const
    {
        return {"Node"};
    }

    bool Node::is_of(const string &nodetype) const
    {
        for (auto &_nodetype : mro())
        {
            if (_nodetype == nodetype)
            {
                return true;
            }
        }

        return false;
    }

    shared_ptr<Node> Node::get_root()
    {
        shared_ptr<Node> root = shared_from_this();

        while (root->get_parent() != nullptr)
        {
            root = root->get_parent();
        }

        return root;
    }

    shared_ptr<Node> Node::get_parent() const
    {
        return parent.lock();
    }

    shared_ptr<Node> Node::get_node(const string &path)
    {
        if (path.empty())
        {
            return shared_from_this();
        }
        else if (path[0] == '/')
        {
            return get_root()->get_node(path.substr(1));
        }
        else
        {
            size_t pos = path.find("/");
            string childpath = path.substr(0, pos);

            if (childpath == ".")
            {
                if (pos == string::npos)
                {
                    return shared_from_this();
                }
                else
                {
                    return get_node(path.substr(pos + 1));
                }
            }
            else if (childpath == "..")
            {
                if (pos == string::npos)
                {
                    return get_parent();
                }
                else
                {
                    return get_parent()->get_node(path.substr(pos + 1));
                }
            }
            else
            {
                shared_ptr<Node> child = nullptr;

                for (auto &_child : children)
                {
                    if (_child->get_name() == childpath)
                    {
                        child = _child;
                        break;
                    }
                }

                if (pos == string::npos)
                {
                    return child;
                }
                else
                {
                    return child->get_node(path.substr(pos + 1));
                }
            }
        }
    }

    vector<shared_ptr<Node>> Node::find_children_by_type(const vector<string> &types) const
    {
        vector<shared_ptr<Node>> result;

        for (auto &child : children)
        {
            for (auto &nodetype : types)
            {
                if (child->is_of(nodetype))
                {
                    result.push_back(child);
                    break;
                }
            }

            auto child_result = child->find_children_by_type(types);

            if (!child_result.empty())
            {
                result.insert(result.end(), child_result.begin(), child_result.end());
            }
        }

        return result;
    }

    shared_ptr<Node> Node::find_first_ancestor_by_type(const string &type) const
    {
        shared_ptr<Node> result = get_parent();

        if (result == nullptr)
        {
            return nullptr;
        }
        else if (result->is_of(type))
        {
            return result;
        }
        else
        {
            return result->find_first_ancestor_by_type(type);
        }
    }

    void Node::add_child(shared_ptr<Node> child, bool reparent)
    {
        children.push_back(child);

        if (reparent)
        {
            child->reparent(shared_from_this(), true, false);
        }
    }

    void Node::remove_child(shared_ptr<Node> child, bool reparent)
    {
        for (auto it = children.begin(); it != children.end(); it++)
        {
            if (*it == child)
            {
                children.erase(it);
                break;
            }
        }

        if (reparent)
        {
            child->reparent(nullptr, false, true);
        }
    }

    void Node::reparent(shared_ptr<Node> newparent, bool remove, bool add)
    {
        if (get_parent() != nullptr)
        {
            if (is_in_tree())
            {
                send_exit_tree();
            }

            if (remove)
            {
                get_parent()->remove_child(shared_from_this(), false);
            }
        }

        parent = newparent;

        if (get_parent() != nullptr)
        {
            if (add)
            {
                get_parent()->add_child(shared_from_this(), false);
            }

            if (!is_in_tree())
            {
                send_enter_tree();
            }
        }
    }

    bool Node::has_input() const
    {
        return input_enabled;
    }

    void Node::set_input(bool enabled)
    {
        input_enabled = enabled;
    }

    bool Node::send_input(SDL_Event *event)
    {
        bool result = true;

        if (has_input())
        {
            result = result && input(event);
        }

        if (is_in_tree())
        {
            for (auto &child : children)
            {
                result = result && child->send_input(event);
            }
        }

        return result;
    }

    bool Node::input(SDL_Event *)
    {
        return true;
    }

    bool Node::has_process() const
    {
        return process_enabled;
    }

    void Node::set_process(bool enabled)
    {
        process_enabled = enabled;
    }

    void Node::send_process(Uint32 delta)
    {
        if (has_process())
        {
            process(delta);
        }

        if (is_in_tree())
        {
            for (auto &child : children)
            {
                child->send_process(delta);
            }
        }
    }

    void Node::process(Uint32) {}

    bool Node::has_draw() const
    {
        return draw_enabled;
    }

    void Node::set_draw(bool enabled)
    {
        draw_enabled = enabled;
    }

    void Node::send_draw()
    {
        if (has_draw())
        {
            draw();
        }

        if (is_in_tree())
        {
            for (auto &child : children)
            {
                child->send_draw();
            }
        }
    }

    void Node::draw() {}

    void Node::send_enter_tree()
    {
        enter_tree();

        for (auto &child : children)
        {
            child->send_enter_tree();
        }

        in_tree = true;

        ready ();
    }

    void Node::enter_tree() {}
    void Node::ready() {}

    void Node::send_exit_tree()
    {
        for (auto &child : children)
        {
            child->send_exit_tree();
        }

        exit_tree();

        in_tree = false;
    }

    void Node::exit_tree() {}

    bool Node::is_in_tree() const
    {
        return in_tree;
    }
}
<|endoftext|>


<commit_before>/*
 * Pano engine
 *
 * Copyright (C)2016 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "pano.h"

PanoSetup::PanoSetup(Camera& camera)
:camera(camera)
{
}

void PanoSetup::setFOV(int horiz_angle, int vert_angle){
    if (horiz_angle && vert_angle && horiz_angle <= 360 && vert_angle <= 180){
        horiz_fov = horiz_angle;
        vert_fov = vert_angle;
    }
}

void PanoSetup::setShutter(unsigned speed, unsigned pre_delay, unsigned post_wait, bool long_pulse){
    shutter_delay = speed;
    pre_shutter_delay = pre_delay;
    post_shutter_delay = post_wait;
    shutter_long_pulse = long_pulse;
}

void PanoSetup::setShots(unsigned shots){
    shots_per_position = shots;
}

void PanoSetup::setMode(unsigned mode){

}

unsigned PanoSetup::getHorizShots(void){
    return horiz_count;
}

unsigned PanoSetup::getVertShots(void){
    return vert_count;
}

int PanoSetup::getCurRow(void){
    return position / horiz_count;
}

int PanoSetup::getCurCol(void){
    return position % horiz_count;
}

/*
 * Calculate time left to complete pano.
 */
unsigned PanoSetup::getTimeLeft(void){
    int photos = getHorizShots() * getVertShots() - position + 1;
    int seconds = photos * shots_per_position * (pre_shutter_delay + steady_delay_avg + shots_per_position * (shutter_delay + post_shutter_delay)) / 1000 +
        // time needed to move the platform
        // each photo requires a horizontal move (except last one in each row)
        (photos - photos/horiz_count) * camera.getHorizFOV() * HORIZ_GEAR_RATIO * 60 / DYNAMIC_RPM(HORIZ_MOTOR_RPM, camera.getHorizFOV()) / 360 +
        // row-to-row movement
        photos / horiz_count * camera.getVertFOV() * VERT_GEAR_RATIO * 60 / DYNAMIC_RPM(VERT_MOTOR_RPM, camera.getVertFOV()) / 360 +
        // row return horizontal movement
        photos / horiz_count * horiz_fov * 60 / HORIZ_MOTOR_RPM / 360;
    return seconds;
}

/*
 * Helper to calculate grid fit with overlap
 * @param total_size: entire grid size (1-360 degrees)
 * @param overlap: min required overlap in percent (1-99)
 * @param block_size: ref to initial (max) block size (will be updated)
 * @param count: ref to image count (will be updated)
 */
void PanoSetup::gridFit(int total_size, int overlap, float& block_size, int& count){
    if (block_size <= total_size){
        /*
         * For 360 pano, we need to cover entire circle plus overlap.
         * For smaller panos, we cover the requested size only.
         */
        if (total_size != 360){
            total_size = ceil(total_size - block_size * overlap/100);
        }
        block_size = block_size * (100-overlap) / 100;
        count = ceil(total_size / block_size);
        block_size = float(total_size) / count;
    } else {
        count = 1;
    }
}

/*
 * Calculate shot-to-shot horizontal/vertical head movement,
 * taking overlap into account
 * Must be called every time focal distance or panorama dimensions change.
 */
void PanoSetup::computeGrid(void){
    horiz_move = camera.getHorizFOV();
    gridFit(horiz_fov, MIN_OVERLAP, horiz_move, horiz_count);
    vert_move = camera.getVertFOV();
    gridFit(vert_fov, MIN_OVERLAP, vert_move, vert_count);
}

/*
 * Actual platform driver part
 */
Pano::Pano(Motor& horiz_motor, Motor& vert_motor, Camera& camera, MPU& mpu)
:PanoSetup(camera),
 horiz_motor(horiz_motor),
 vert_motor(vert_motor),
 mpu(mpu)
{
    motorsEnable(false);

    setFOV(360,180);
}

void Pano::start(void){
    computeGrid();
    motorsEnable(true);
    horiz_motor.setRPM(HORIZ_MOTOR_RPM);
    vert_motor.setRPM(VERT_MOTOR_RPM);
    // set start position
    setMotorsHomePosition();
    position = 0;
}

void Pano::shutter(void){
    int start = millis();
    delay(pre_shutter_delay);
    mpu.zeroMotionWait(STEADY_TARGET(camera.getVertFOV(), shutter_delay, CAMERA_RESOLUTION), STEADY_TIMEOUT);
    steady_delay_avg = (steady_delay_avg * position + millis() - start) / (position + 1);
    for (unsigned i=shots_per_position; i; i--){
        camera.shutter(shutter_delay, shutter_long_pulse);
        delay(post_shutter_delay);
    }
}
/*
 * Move to grid position by photo index (0-number of photos)
 */
bool Pano::moveTo(int new_position){
    int new_row = new_position / horiz_count;
    int new_col = new_position % horiz_count;
    return moveTo(new_row, new_col);
}
/*
 * Move to specified grid position
 * @param new_row: requested row position [0 - vert_count)
 * @param new_col: requested col position [0 - horiz_count)
 */
bool Pano::moveTo(int new_row, int new_col){
    int cur_row = getCurRow();
    int cur_col = getCurCol();

    if (cur_row >= vert_count ||
        new_row >= vert_count ||
        new_col >= horiz_count ||
        new_col < 0 ||
        new_row < 0){
        // beyond last/first row or column, cannot move there.
        return false;
    }

    if (cur_col != new_col){
        // horizontal adjustment needed
        // figure out shortest path around the circle
        // good idea if on batteries, bad idea when power cable in use
        float move = (new_col-cur_col) * horiz_move;
        if (abs(move) > 180){
            if (move < 0){
                move = 360 + move;
            } else {
                move = move - 360;
            }
        }
        moveMotorsAdaptive(move, 0);
    }
    if (cur_row != new_row){
        // vertical adjustment needed
        moveMotorsAdaptive(0, -(new_row-cur_row)*vert_move);
    }

    position = new_row * horiz_count + new_col;
    return true;
}
bool Pano::next(void){
    return moveTo(position+1);
}
bool Pano::prev(void){
    return (position > 0) ? moveTo(position-1) : false;
}
void Pano::end(void){
    // move to home position
    moveTo(0, 0);
}
/*
 * Execute a full pano run.
 */
void Pano::run(void){
    start();
    do {
        shutter();
    } while(next());
    end();
}

/*
 * Remember current position as "home"
 * (start tracking platform movement to be able to return to it)
 */
void Pano::setMotorsHomePosition(void){
    horiz_home_offset = 0;
    vert_home_offset = 0;
}

/*
 * Move head requested number of degrees at an adaptive speed
 */
void Pano::moveMotorsAdaptive(float h, float v){
    if (h){
        horiz_motor.setRPM(DYNAMIC_HORIZ_RPM(h));
    }
    if (v){
        vert_motor.setRPM(DYNAMIC_VERT_RPM(v));
    }
    moveMotors(h, v);
}
/*
 * Move head requested number of degrees, fixed predefined speed
 */
void Pano::moveMotors(float h, float v){
    if (h){
        horiz_motor.rotate(h * HORIZ_GEAR_RATIO);
        horiz_home_offset += h;
    }
    if (v){
        vert_motor.rotate(v * VERT_GEAR_RATIO);
        vert_home_offset += v;
    }
}

/*
 * Move head back to home position
 */
void Pano::moveMotorsHome(void){
    moveMotorsAdaptive(-horiz_home_offset, -vert_home_offset);
}

void Pano::motorsEnable(bool on){
    (on) ? horiz_motor.enable() : horiz_motor.disable();
    delay(1);
}
<commit_msg>hacky speed increase for continuous free movement<commit_after>/*
 * Pano engine
 *
 * Copyright (C)2016 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "pano.h"

PanoSetup::PanoSetup(Camera& camera)
:camera(camera)
{
}

void PanoSetup::setFOV(int horiz_angle, int vert_angle){
    if (horiz_angle && vert_angle && horiz_angle <= 360 && vert_angle <= 180){
        horiz_fov = horiz_angle;
        vert_fov = vert_angle;
    }
}

void PanoSetup::setShutter(unsigned speed, unsigned pre_delay, unsigned post_wait, bool long_pulse){
    shutter_delay = speed;
    pre_shutter_delay = pre_delay;
    post_shutter_delay = post_wait;
    shutter_long_pulse = long_pulse;
}

void PanoSetup::setShots(unsigned shots){
    shots_per_position = shots;
}

void PanoSetup::setMode(unsigned mode){

}

unsigned PanoSetup::getHorizShots(void){
    return horiz_count;
}

unsigned PanoSetup::getVertShots(void){
    return vert_count;
}

int PanoSetup::getCurRow(void){
    return position / horiz_count;
}

int PanoSetup::getCurCol(void){
    return position % horiz_count;
}

/*
 * Calculate time left to complete pano.
 */
unsigned PanoSetup::getTimeLeft(void){
    int photos = getHorizShots() * getVertShots() - position + 1;
    int seconds = photos * shots_per_position * (pre_shutter_delay + steady_delay_avg + shots_per_position * (shutter_delay + post_shutter_delay)) / 1000 +
        // time needed to move the platform
        // each photo requires a horizontal move (except last one in each row)
        (photos - photos/horiz_count) * camera.getHorizFOV() * HORIZ_GEAR_RATIO * 60 / DYNAMIC_RPM(HORIZ_MOTOR_RPM, camera.getHorizFOV()) / 360 +
        // row-to-row movement
        photos / horiz_count * camera.getVertFOV() * VERT_GEAR_RATIO * 60 / DYNAMIC_RPM(VERT_MOTOR_RPM, camera.getVertFOV()) / 360 +
        // row return horizontal movement
        photos / horiz_count * horiz_fov * 60 / HORIZ_MOTOR_RPM / 360;
    return seconds;
}

/*
 * Helper to calculate grid fit with overlap
 * @param total_size: entire grid size (1-360 degrees)
 * @param overlap: min required overlap in percent (1-99)
 * @param block_size: ref to initial (max) block size (will be updated)
 * @param count: ref to image count (will be updated)
 */
void PanoSetup::gridFit(int total_size, int overlap, float& block_size, int& count){
    if (block_size <= total_size){
        /*
         * For 360 pano, we need to cover entire circle plus overlap.
         * For smaller panos, we cover the requested size only.
         */
        if (total_size != 360){
            total_size = ceil(total_size - block_size * overlap/100);
        }
        block_size = block_size * (100-overlap) / 100;
        count = ceil(total_size / block_size);
        block_size = float(total_size) / count;
    } else {
        count = 1;
    }
}

/*
 * Calculate shot-to-shot horizontal/vertical head movement,
 * taking overlap into account
 * Must be called every time focal distance or panorama dimensions change.
 */
void PanoSetup::computeGrid(void){
    horiz_move = camera.getHorizFOV();
    gridFit(horiz_fov, MIN_OVERLAP, horiz_move, horiz_count);
    vert_move = camera.getVertFOV();
    gridFit(vert_fov, MIN_OVERLAP, vert_move, vert_count);
}

/*
 * Actual platform driver part
 */
Pano::Pano(Motor& horiz_motor, Motor& vert_motor, Camera& camera, MPU& mpu)
:PanoSetup(camera),
 horiz_motor(horiz_motor),
 vert_motor(vert_motor),
 mpu(mpu)
{
    motorsEnable(false);

    setFOV(360,180);
}

void Pano::start(void){
    computeGrid();
    motorsEnable(true);
    horiz_motor.setRPM(HORIZ_MOTOR_RPM);
    vert_motor.setRPM(VERT_MOTOR_RPM);
    // set start position
    setMotorsHomePosition();
    position = 0;
}

void Pano::shutter(void){
    int start = millis();
    delay(pre_shutter_delay);
    mpu.zeroMotionWait(STEADY_TARGET(camera.getVertFOV(), shutter_delay, CAMERA_RESOLUTION), STEADY_TIMEOUT);
    steady_delay_avg = (steady_delay_avg * position + millis() - start) / (position + 1);
    for (unsigned i=shots_per_position; i; i--){
        camera.shutter(shutter_delay, shutter_long_pulse);
        delay(post_shutter_delay);
    }
}
/*
 * Move to grid position by photo index (0-number of photos)
 */
bool Pano::moveTo(int new_position){
    int new_row = new_position / horiz_count;
    int new_col = new_position % horiz_count;
    return moveTo(new_row, new_col);
}
/*
 * Move to specified grid position
 * @param new_row: requested row position [0 - vert_count)
 * @param new_col: requested col position [0 - horiz_count)
 */
bool Pano::moveTo(int new_row, int new_col){
    int cur_row = getCurRow();
    int cur_col = getCurCol();

    if (cur_row >= vert_count ||
        new_row >= vert_count ||
        new_col >= horiz_count ||
        new_col < 0 ||
        new_row < 0){
        // beyond last/first row or column, cannot move there.
        return false;
    }

    if (cur_col != new_col){
        // horizontal adjustment needed
        // figure out shortest path around the circle
        // good idea if on batteries, bad idea when power cable in use
        float move = (new_col-cur_col) * horiz_move;
        if (abs(move) > 180){
            if (move < 0){
                move = 360 + move;
            } else {
                move = move - 360;
            }
        }
        moveMotorsAdaptive(move, 0);
    }
    if (cur_row != new_row){
        // vertical adjustment needed
        moveMotorsAdaptive(0, -(new_row-cur_row)*vert_move);
    }

    position = new_row * horiz_count + new_col;
    return true;
}
bool Pano::next(void){
    return moveTo(position+1);
}
bool Pano::prev(void){
    return (position > 0) ? moveTo(position-1) : false;
}
void Pano::end(void){
    // move to home position
    moveTo(0, 0);
}
/*
 * Execute a full pano run.
 */
void Pano::run(void){
    start();
    do {
        shutter();
    } while(next());
    end();
}

/*
 * Remember current position as "home"
 * (start tracking platform movement to be able to return to it)
 */
void Pano::setMotorsHomePosition(void){
    horiz_home_offset = 0;
    vert_home_offset = 0;
}

/*
 * Move head requested number of degrees at an adaptive speed
 */
void Pano::moveMotorsAdaptive(float h, float v){
    static unsigned last_call = 0;
    static float last_move_h, last_move_v;
    if (millis() < last_call + 10){
        last_move_h *= 1.5;
        last_move_v *= 1.5;
    } else {
        last_move_h = h;
        last_move_v = v;
    }
    if (h){
        horiz_motor.setRPM(DYNAMIC_HORIZ_RPM(last_move_h));
    }
    if (v){
        vert_motor.setRPM(DYNAMIC_VERT_RPM(last_move_v));
    }
    moveMotors(h, v);
    last_call = millis();
}
/*
 * Move head requested number of degrees, fixed predefined speed
 */
void Pano::moveMotors(float h, float v){
    if (h){
        horiz_motor.rotate(h * HORIZ_GEAR_RATIO);
        horiz_home_offset += h;
    }
    if (v){
        vert_motor.rotate(v * VERT_GEAR_RATIO);
        vert_home_offset += v;
    }
}

/*
 * Move head back to home position
 */
void Pano::moveMotorsHome(void){
    moveMotorsAdaptive(-horiz_home_offset, -vert_home_offset);
}

void Pano::motorsEnable(bool on){
    (on) ? horiz_motor.enable() : horiz_motor.disable();
    delay(1);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>

using namespace std;

//ONCE YOU ARE DONE, MERGE THIS FILE WITH RSHELL AND DELETE TARGET IN MAKEFILE

/* function1: prints out any type */
#define printVec(x) for(unsigned int i = 0; i < x.size(); i++) \
                        cout << x.at(i) << ' '; \
                    cout << endl;

/* function2: prints out any regular variable */
template<typename T>
void printReg(T &sample){
    cout << sample << endl;
    return;
}

/* function3: extract componenets in a vector using strtok */
vector<char*> getParts(string &wut){
    /* vector of each piece to return*/
    vector<char*> brokenParts;

    /* convert to const char* to allow for parameter match*/
    const char* wut_cstring = wut.c_str();

    /* cast it to allow char* paramter cabability*/
    char* wut_cstring_2 = const_cast<char*>(wut_cstring);

    /* each individual command will be stored here temporarily*/
    char* token;

    /* extract with delimeters*/
    token = strtok(wut_cstring_2, " ");

    /* counter for list of argument parameters*/
    int pos = 0;

    /*extract until end of line*/
    while(token != NULL){
        /* output each token */
        //cout << "token" << pos << ": " << token << endl;

        /* push each token onto vector */
        brokenParts.push_back(token);

        /* keep tokenizing*/
        token = strtok(NULL, " ");

        /*increment counter */
        pos++;
    }

    /* return vector of char* */
    return brokenParts;
}

/* function4: performs input redirection */
/* parmeter1: file you want to open*/
/* parmeter2: command you want to run*/
/* parmeter3: list of all arguments (needed for execvp) */
void inputRedirection(char* command, char* file, char **argv){
    /* pid gets the value of fork*/
    int pid = fork();

    /* based on the value of fork, perform the following operations */
    if(pid == -1){ //fork straight up failed you...
        perror("fork() failed");
        exit(1);
    }
    else if(pid == 0){ //child process = good *thumbs up*
        /* flush standard in so that, if the forked child writes to standard
         * error because of a problem, there will be no extraneous duplicated
         * output.*/
        fflush(STDIN_FILENO);

        /* open the file passed in */
        int fd0 = open(file, O_RDONLY);
        if(fd0 == -1){
            perror(file);
            exit(1);
        }

        /* duplicate the file descriptor */
        /* use STDIN_FILENO as standard input*/
        dup2(fd0, STDIN_FILENO);

        /* close the file descriptor*/
        close(fd0);

        /* run the command passed in */
        if( execvp(command, argv) == -1){
            perror("error running execvp");
            exit(1);
        }
    }
    else if(pid > 0){ //we have to wait for the child process to die
        if ( -1 == wait(0)){
            perror("there was an error with wait");
        }
    }
    return;
}

/* function5: performs input redirection */
/* parmeter1: file you want to open*/
/* parmeter2: command you want to run*/
/* parmeter3: list of all arguments (needed for execvp) */

void outputRedirection(char* command, char* file, char** argv){
    /* pid gets the value of fork*/
    int pid = fork();

    /* based on the value of fork, perform the following operations */
    if(pid == -1){ //fork straight up failed you...
        perror("fork() failed");
        exit(1);
    }
    else if(pid == 0){ //child process = good *thumbs up*
        /* flush standard out so that, if the forked child writes to standard
         * error because of a problem, there will be no extraneous duplicated
         * output.*/
        fflush(stdout);

        /* open the file passed in */
        int fd1 = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRGRP | S_IWGRP
                                       | S_IWUSR);
        if(fd1 == -1){
            perror(file);
            exit(1);
        }

        /* duplicate the file descriptor */
        /* use STDIN_FILENO as standard input*/
        dup2(fd1, STDOUT_FILENO);

        /* close the file descriptor*/
        close(fd1);

        /* run the command passed in */
        if( execvp(command, argv) == -1){
            perror("error running execvp");
            exit(1);
        }
    }
    else if(pid > 0){ //we have to wait for the child process to die
        if ( -1 == wait(0)){
            perror("there was an error with wait");
        }
    }
    return;
}

/* function6: perform logic - IO/pipe */
void logic(vector<char*> &parts, char **argv){
    /* loop through vector and determine each case */
    for(unsigned int i = 0; i < parts.size(); i++){
        if(*(parts.at(i)) == '<'){
            /* check if ' < ' is not the first or last token */
            if(i > 0 && i < parts.size() - 1){
                /* 1.perform input redirection assuming "i" is in a
                 * position*/

                /* 2.you pass in parts.at(i-1) because that SHOULD
                 * be the command preceding the ' < ' sign*/

                /* 3.you pass in parts.at(i+1) because you getting information
                 * from the file AFTER the ' < ' sign */
                inputRedirection(parts.at(i-1), parts.at(i+1), argv);
            }
        }
        else if(*(parts.at(i)) == '>'){
            /* check if ' > ' is not the first or last token */
            if(i > 0 && i < parts.size() - 1){
                /* 1.perform ouput redirection assuming "i" is in an
                 * appopriate position*/

                /* 2.you pass in parts.at(i-1) because that SHOULD
                 * be the command/file preceding the ' > ' sign*/

                /* 3.you pass in parts.at(i+1) because you getting information
                 * from the file AFTER the ' > ' sign */
                outputRedirection(parts.at(i-1), parts.at(i+1), argv);
            }
        }
    }
    return;
}

/* function5: input redirection */

int main(int argc, char** argv){
    /* user input */
    string input;

    /* get user input */
    getline(cin, input);

    /* extract components */
    vector<char*> components;
    components = getParts(input);

    /*perform appropriate logic*/
    logic(components, argv);
    return 0;
}
<commit_msg>fixed some comment errors<commit_after>#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>

using namespace std;

//ONCE YOU ARE DONE, MERGE THIS FILE WITH RSHELL AND DELETE TARGET IN MAKEFILE

/* function1: prints out any type */
#define printVec(x) for(unsigned int i = 0; i < x.size(); i++) \
                        cout << x.at(i) << ' '; \
                    cout << endl;

/* function2: prints out any regular variable */
template<typename T>
void printReg(T &sample){
    cout << sample << endl;
    return;
}

/* function3: extract componenets in a vector using strtok */
vector<char*> getParts(string &wut){
    /* vector of each piece to return*/
    vector<char*> brokenParts;

    /* convert to const char* to allow for parameter match*/
    const char* wut_cstring = wut.c_str();

    /* cast it to allow char* paramter cabability*/
    char* wut_cstring_2 = const_cast<char*>(wut_cstring);

    /* each individual command will be stored here temporarily*/
    char* token;

    /* extract with delimeters*/
    token = strtok(wut_cstring_2, " ");

    /* counter for list of argument parameters*/
    int pos = 0;

    /*extract until end of line*/
    while(token != NULL){
        /* output each token */
        //cout << "token" << pos << ": " << token << endl;

        /* push each token onto vector */
        brokenParts.push_back(token);

        /* keep tokenizing*/
        token = strtok(NULL, " ");

        /*increment counter */
        pos++;
    }

    /* return vector of char* */
    return brokenParts;
}

/* function4: performs input redirection */
/* parmeter1: file you want to open*/
/* parmeter2: command you want to run*/
/* parmeter3: list of all arguments (needed for execvp) */
void inputRedirection(char* command, char* file, char **argv){
    /* pid gets the value of fork*/
    int pid = fork();

    /* based on the value of fork, perform the following operations */
    if(pid == -1){ //fork straight up failed you...
        perror("fork() failed");
        exit(1);
    }
    else if(pid == 0){ //child process = good *thumbs up*
        /* flush standard in so that, if the forked child writes to standard
         * error because of a problem, there will be no extraneous duplicated
         * output.*/
        fflush(STDIN_FILENO);

        /* open the file passed in */
        int fd0 = open(file, O_RDONLY);
        if(fd0 == -1){
            perror(file);
            exit(1);
        }

        /* duplicate the file descriptor */
        /* use STDIN_FILENO as standard input*/
        dup2(fd0, STDIN_FILENO);

        /* close the file descriptor*/
        close(fd0);

        /* run the command passed in */
        if( execvp(command, argv) == -1){
            perror("error running execvp");
            exit(1);
        }
    }
    else if(pid > 0){ //we have to wait for the child process to die
        if ( -1 == wait(0)){
            perror("there was an error with wait");
        }
    }
    return;
}

/* function5: performs output redirection */
/* parmeter1: file you want to open*/
/* parmeter2: command you want to run*/
/* parmeter3: list of all arguments (needed for execvp) */

void outputRedirection(char* command, char* file, char** argv){
    /* pid gets the value of fork*/
    int pid = fork();

    /* based on the value of fork, perform the following operations */
    if(pid == -1){ //fork straight up failed you...
        perror("fork() failed");
        exit(1);
    }
    else if(pid == 0){ //child process = good *thumbs up*
        /* flush standard out so that, if the forked child writes to standard
         * error because of a problem, there will be no extraneous duplicated
         * output.*/
        fflush(stdout);

        /* open the file passed in */
        int fd1 = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRGRP | S_IWGRP
                                       | S_IWUSR);
        if(fd1 == -1){
            perror(file);
            exit(1);
        }

        /* duplicate the file descriptor */
        /* use STDOUT_FILENO as standard input*/
        dup2(fd1, STDOUT_FILENO);

        /* close the file descriptor*/
        close(fd1);

        /* run the command passed in */
        if( execvp(command, argv) == -1){
            perror("error running execvp");
            exit(1);
        }
    }
    else if(pid > 0){ //we have to wait for the child process to die
        if ( -1 == wait(0)){
            perror("there was an error with wait");
        }
    }
    return;
}

/* function6: perform logic - IO/pipe */
void logic(vector<char*> &parts, char **argv){
    /* loop through vector and determine each case */
    for(unsigned int i = 0; i < parts.size(); i++){
        if(*(parts.at(i)) == '<'){
            /* check if ' < ' is not the first or last token */
            if(i > 0 && i < parts.size() - 1){
                /* 1.perform input redirection assuming "i" is in a
                 * position*/

                /* 2.you pass in parts.at(i-1) because that SHOULD
                 * be the command preceding the ' < ' sign*/

                /* 3.you pass in parts.at(i+1) because you getting information
                 * from the file AFTER the ' < ' sign */
                inputRedirection(parts.at(i-1), parts.at(i+1), argv);
            }
        }
        else if(*(parts.at(i)) == '>'){
            /* check if ' > ' is not the first or last token */
            if(i > 0 && i < parts.size() - 1){
                /* 1.perform ouput redirection assuming "i" is in an
                 * appopriate position*/

                /* 2.you pass in parts.at(i-1) because that SHOULD
                 * be the command/file preceding the ' > ' sign*/

                /* 3.you pass in parts.at(i+1) because you getting information
                 * from the file AFTER the ' > ' sign */
                outputRedirection(parts.at(i-1), parts.at(i+1), argv);
            }
        }
    }
    return;
}

/* function5: input redirection */

int main(int argc, char** argv){
    /* user input */
    string input;

    /* get user input */
    getline(cin, input);

    /* extract components */
    vector<char*> components;
    components = getParts(input);

    /*perform appropriate logic*/
    logic(components, argv);
    return 0;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <iostream>
#include <vector>
#include <unistd.h>
#include <dirent.h>
#include <omp.h>

void helpCheck(char *argv[]) {
	if (argv[1] == std::string("-h") || argv[1] == std::string("--help")) {
		std::cout << "\nptxv - Parallel Tar XZ by Ryan Chui (2017)\n" << std::endl;
		exit(0);
	}
}

void findAll(int *numFiles, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					findAll(numFiles, filePath.c_str());
				} else {
					*numFiles += 1;
				}
			}
		}
		closedir(dir);
	}
}

void getPaths(std::vector<std::string> *filePaths, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					getPaths(filePaths, filePath.c_str());
				} else {
					filePaths->push_back(filePath);
				}
			}
		}
		closedir(dir);
	}
}

char cwd [PATH_MAX];

int main(int argc, char *argv[]) {
	int *numFiles = new int(0);

	if (argc > 1) {
		helpCheck(argv);
	}

	getcwd(cwd, PATH_MAX);
	findAll(numFiles, cwd);

	std::vector<std::string> *filePaths = new std::vector<std::string>();

	getPaths(filePaths, cwd);

	system("echo 'Hello World'");

	delete(numFiles);
	return 0;
}
<commit_msg>Testing different echo<commit_after>#include <stdlib.h>
#include <iostream>
#include <vector>
#include <unistd.h>
#include <dirent.h>
#include <omp.h>

void helpCheck(char *argv[]) {
	if (argv[1] == std::string("-h") || argv[1] == std::string("--help")) {
		std::cout << "\nptxv - Parallel Tar XZ by Ryan Chui (2017)\n" << std::endl;
		exit(0);
	}
}

void findAll(int *numFiles, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					findAll(numFiles, filePath.c_str());
				} else {
					*numFiles += 1;
				}
			}
		}
		closedir(dir);
	}
}

void getPaths(std::vector<std::string> *filePaths, const char *cwd) {
	DIR *dir;
	struct dirent *ent;

	// Check if cwd is a directory
	if ((dir = opendir(cwd)) != NULL) {
		// Get all file paths within directory.
		while ((ent = readdir (dir)) != NULL) {
			std::string fileBuff = std::string(ent -> d_name);
			if (fileBuff != "." && fileBuff != "..") {
				DIR *dir2;
				std::string filePath = std::string(cwd) + "/" + fileBuff;
				// Check if file path is a directory.
				if ((dir2 = opendir(filePath.c_str())) != NULL) {
					closedir(dir2);
					getPaths(filePaths, filePath.c_str());
				} else {
					filePaths->push_back(filePath);
				}
			}
		}
		closedir(dir);
	}
}

char cwd [PATH_MAX];

int main(int argc, char *argv[]) {
	int *numFiles = new int(0);

	if (argc > 1) {
		helpCheck(argv);
	}

	getcwd(cwd, PATH_MAX);
	findAll(numFiles, cwd);

	std::vector<std::string> *filePaths = new std::vector<std::string>();

	getPaths(filePaths, cwd);

	system("echo Hello World");

	delete(numFiles);
	return 0;
}
<|endoftext|>


<commit_before>#include <ge/input_subsystem.hpp>
#include <ge/mesh_actor.hpp>
#include <ge/rocket_subsystem.hpp>
#include <ge/runtime.hpp>
#include <ge/sdl_subsystem.hpp>
#include <ge/timer_subsystem.hpp>

#include <glm/glm.hpp>

#include <memory>

#include "grid.hpp"
#include "piece.hpp"
#include "turret.hpp"
#include "zombie.hpp"

#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif

using namespace ge;

int main()
{
	runtime r;

	r.m_asset_manager.add_asset_path("data/");
	r.add_subsystem<input_subsystem>({});
	r.add_subsystem<timer_subsystem>({});
	auto& sdl = r.add_subsystem<sdl_subsystem>(sdl_subsystem::config{"Example!", {1024, 720}});
	r.add_subsystem<rocket_subsystem>({});

	auto root = actor::root_factory(&r);

	auto camera = actor::factory<camera_actor>(root.get(), 11);

	sdl.set_background_color({.2f, .2f, .2f});
	sdl.set_camera(camera.get());
	r.set_root_actor(root.get());

	// initialize the grid
	auto g = actor::factory<grid>(root.get(), glm::uvec2{11, 11}, 2.f);

	actor::factory<turret>(g.get(), glm::uvec3(0, 1, 2));
	actor::factory<turret>(g.get(), glm::uvec3(1, 0, 2));
	actor::factory<turret>(g.get(), glm::uvec3(1, 2, 2));
	actor::factory<turret>(g.get(), glm::uvec3(3, 2, 2));
	actor::factory<turret>(g.get(), glm::uvec3(2, 0, 2));
	actor::factory<turret>(g.get(), glm::uvec3(3, 1, 2));
	actor::factory<turret>(g.get(), glm::uvec3(2, 3, 2));
	actor::factory<zombie>(g.get(), glm::uvec3(1, 1, 2));

#ifdef EMSCRIPTEN
	emscripten_set_main_loop_arg(
		[](void* run_ptr) {
			runtime* runt = (runtime*)run_ptr;

			runt->tick();
		},
		&r, 0, true);
#else
	while (r.tick())
		;
#endif
}
<commit_msg>added another zombie<commit_after>#include <ge/input_subsystem.hpp>
#include <ge/mesh_actor.hpp>
#include <ge/rocket_subsystem.hpp>
#include <ge/runtime.hpp>
#include <ge/sdl_subsystem.hpp>
#include <ge/timer_subsystem.hpp>

#include <glm/glm.hpp>

#include <memory>

#include "grid.hpp"
#include "piece.hpp"
#include "turret.hpp"
#include "zombie.hpp"

#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif

using namespace ge;

int main()
{
	runtime r;

	r.m_asset_manager.add_asset_path("data/");
	r.add_subsystem<input_subsystem>({});
	r.add_subsystem<timer_subsystem>({});
	auto& sdl = r.add_subsystem<sdl_subsystem>(sdl_subsystem::config{"Example!", {1024, 720}});
	r.add_subsystem<rocket_subsystem>({});

	auto root = actor::root_factory(&r);

	auto camera = actor::factory<camera_actor>(root.get(), 11);

	sdl.set_background_color({.2f, .2f, .2f});
	sdl.set_camera(camera.get());
	r.set_root_actor(root.get());

	// initialize the grid
	auto g = actor::factory<grid>(root.get(), glm::uvec2{11, 11}, 2.f);

	actor::factory<turret>(g.get(), glm::uvec3(0, 1, 2));
	actor::factory<turret>(g.get(), glm::uvec3(1, 0, 2));
	actor::factory<turret>(g.get(), glm::uvec3(1, 2, 2));
	actor::factory<turret>(g.get(), glm::uvec3(3, 2, 2));
	actor::factory<turret>(g.get(), glm::uvec3(2, 0, 2));
	actor::factory<turret>(g.get(), glm::uvec3(3, 1, 2));
	actor::factory<turret>(g.get(), glm::uvec3(2, 3, 2));
	actor::factory<zombie>(g.get(), glm::uvec3(1, 1, 2));
	actor::factory<zombie>(g.get(), glm::uvec3(0, 0, 2));

#ifdef EMSCRIPTEN
	emscripten_set_main_loop_arg(
		[](void* run_ptr) {
			runtime* runt = (runtime*)run_ptr;

			runt->tick();
		},
		&r, 0, true);
#else
	while (r.tick())
		;
#endif
}
<|endoftext|>


<commit_before>#ifndef HMLIB_LATTICES_INC
#define HMLIB_LATTICES_INC 200
#
#include "lattices/lattice_view.hpp"
#include "lattices/torus_lattice_view.hpp"
#include "lattices/lattice.hpp"
#include "lattices/torus_lattice.hpp"
#
#endif
<commit_msg>Add include files in lattices.hpp<commit_after>#ifndef HMLIB_LATTICES_INC
#define HMLIB_LATTICES_INC 200
#
#include "lattices/lattice.hpp"
#include "lattices/lattice_view.hpp"
#include "lattices/torus_lattice.hpp"
#include "lattices/torus_lattice_view.hpp"
#include "lattices/block_lattice.hpp"
#include "lattices/zip_lattice.hpp"
#include "lattices/keep_if.hpp"
#
#endif
<|endoftext|>


<commit_before>/*
    Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "monitortest.h"

#include <libakonadi/monitor.h>
#include <libakonadi/collectioncreatejob.h>
#include <libakonadi/collectiondeletejob.h>
#include <libakonadi/itemappendjob.h>
#include <libakonadi/itemstorejob.h>
#include <libakonadi/itemdeletejob.h>

#include <QSignalSpy>
#include <qtest_kde.h>

using namespace PIM;

QTEST_KDEMAIN( MonitorTest, NoGUI )

void MonitorTest::testMonitor()
{
  Monitor *monitor = new Monitor( this );
  monitor->monitorCollection( "res3", true );

  // monitor signals
  qRegisterMetaType<PIM::DataReference>("PIM::DataReference");
  QSignalSpy caspy( monitor, SIGNAL(collectionAdded(QByteArray)) );
  QSignalSpy cmspy( monitor, SIGNAL(collectionChanged(QByteArray)) );
  QSignalSpy crspy( monitor, SIGNAL(collectionRemoved(QByteArray)) );
  QSignalSpy iaspy( monitor, SIGNAL(itemAdded(PIM::DataReference)) );
  QSignalSpy imspy( monitor, SIGNAL(itemChanged(PIM::DataReference)) );
  QSignalSpy irspy( monitor, SIGNAL(itemRemoved(PIM::DataReference)) );

  QVERIFY( caspy.isValid() );
  QVERIFY( cmspy.isValid() );
  QVERIFY( crspy.isValid() );
  QVERIFY( iaspy.isValid() );
  QVERIFY( imspy.isValid() );
  QVERIFY( irspy.isValid() );

  // create a collection
  CollectionCreateJob *create = new CollectionCreateJob( "res3/monitor", this );
  QVERIFY( create->exec() );

  QCOMPARE( caspy.count(), 1 );
  QList<QVariant> arg = caspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QVERIFY( cmspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // add an item
  ItemAppendJob *append = new ItemAppendJob( "res3/monitor", QByteArray(), "message/rfc822", this );
  QVERIFY( append->exec() );

  QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( iaspy.count(), 1 );
  arg = iaspy.takeFirst();
  DataReference ref = qvariant_cast<DataReference>( arg.at(0) );
  QVERIFY( !ref.isNull() );

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // modify an item
  ItemStoreJob *store = new ItemStoreJob( ref, this );
  store->setData( QByteArray( "some new content" ) );
  QVERIFY( store->exec() );

  // ### no yet implemented
  /*QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( imspy.count(), 1 );
  arg = imspy.takeFirst();
  DataReference ref2 = qvariant_cast<DataReference>( arg.at(0) );
  QCOMPARE( ref, ref2 );*/

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // delete an item
  ItemDeleteJob *del = new ItemDeleteJob( ref, this );
  QVERIFY( del->exec() );

  // ### not yet implemented
  /*QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( irspy.count(), 1 );
  arg = imspy.takeFirst();
  DataReference ref2 = qvariant_cast<DataReference>( arg.at(0) );
  QCOMPARE( ref, ref2 );*/

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );

  // delete a collection
  CollectionDeleteJob *cdel = new CollectionDeleteJob( "res3/monitor", this );
  QVERIFY( cdel->exec() );

  QCOMPARE( crspy.count(), 1 );
  arg = crspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QVERIFY( caspy.isEmpty() );
  QVERIFY( cmspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );
}

#include "monitortest.moc"
<commit_msg>Deterministic tests are preferred.<commit_after>/*
    Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "monitortest.h"

#include <libakonadi/monitor.h>
#include <libakonadi/collectioncreatejob.h>
#include <libakonadi/collectiondeletejob.h>
#include <libakonadi/itemappendjob.h>
#include <libakonadi/itemstorejob.h>
#include <libakonadi/itemdeletejob.h>

#include <QApplication>
#include <QSignalSpy>
#include <qtest_kde.h>

using namespace PIM;

QTEST_KDEMAIN( MonitorTest, NoGUI )

void MonitorTest::testMonitor()
{
  Monitor *monitor = new Monitor( this );
  monitor->monitorCollection( "res3", true );

  // monitor signals
  qRegisterMetaType<PIM::DataReference>("PIM::DataReference");
  QSignalSpy caspy( monitor, SIGNAL(collectionAdded(QByteArray)) );
  QSignalSpy cmspy( monitor, SIGNAL(collectionChanged(QByteArray)) );
  QSignalSpy crspy( monitor, SIGNAL(collectionRemoved(QByteArray)) );
  QSignalSpy iaspy( monitor, SIGNAL(itemAdded(PIM::DataReference)) );
  QSignalSpy imspy( monitor, SIGNAL(itemChanged(PIM::DataReference)) );
  QSignalSpy irspy( monitor, SIGNAL(itemRemoved(PIM::DataReference)) );

  QVERIFY( caspy.isValid() );
  QVERIFY( cmspy.isValid() );
  QVERIFY( crspy.isValid() );
  QVERIFY( iaspy.isValid() );
  QVERIFY( imspy.isValid() );
  QVERIFY( irspy.isValid() );

  // create a collection
  CollectionCreateJob *create = new CollectionCreateJob( "res3/monitor", this );
  QVERIFY( create->exec() );
  qApp->processEvents(); // make sure the DBus signal has been processed

  QCOMPARE( caspy.count(), 1 );
  QList<QVariant> arg = caspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QVERIFY( cmspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // add an item
  ItemAppendJob *append = new ItemAppendJob( "res3/monitor", QByteArray(), "message/rfc822", this );
  QVERIFY( append->exec() );
  qApp->processEvents();

  QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( iaspy.count(), 1 );
  arg = iaspy.takeFirst();
  DataReference ref = qvariant_cast<DataReference>( arg.at(0) );
  QVERIFY( !ref.isNull() );

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // modify an item
  ItemStoreJob *store = new ItemStoreJob( ref, this );
  store->setData( QByteArray( "some new content" ) );
  QVERIFY( store->exec() );
  qApp->processEvents();

  // ### no yet implemented
  /*QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( imspy.count(), 1 );
  arg = imspy.takeFirst();
  DataReference ref2 = qvariant_cast<DataReference>( arg.at(0) );
  QCOMPARE( ref, ref2 );*/

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );

  // delete an item
  ItemDeleteJob *del = new ItemDeleteJob( ref, this );
  QVERIFY( del->exec() );
  qApp->processEvents();

  // ### not yet implemented
  /*QCOMPARE( cmspy.count(), 1 );
  arg = cmspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QCOMPARE( irspy.count(), 1 );
  arg = imspy.takeFirst();
  DataReference ref2 = qvariant_cast<DataReference>( arg.at(0) );
  QCOMPARE( ref, ref2 );*/

  QVERIFY( caspy.isEmpty() );
  QVERIFY( crspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );

  // delete a collection
  CollectionDeleteJob *cdel = new CollectionDeleteJob( "res3/monitor", this );
  QVERIFY( cdel->exec() );
  qApp->processEvents();

  QCOMPARE( crspy.count(), 1 );
  arg = crspy.takeFirst();
  QCOMPARE( arg.at(0).toByteArray(), QByteArray( "res3/monitor" ) );

  QVERIFY( caspy.isEmpty() );
  QVERIFY( cmspy.isEmpty() );
  QVERIFY( iaspy.isEmpty() );
  QVERIFY( imspy.isEmpty() );
  QVERIFY( irspy.isEmpty() );
}

#include "monitortest.moc"
<|endoftext|>


<commit_before>//
// Created by xiaohe on 4/3/16.
//
#include "main.h"

//#include "parseCommandLine.h"

using namespace std;

char* allPairsShortestPath(wghEdgeArray<intT> Gr) {
    intT n = Gr.n;
    wghEdge<intT> * edgeList = Gr.E;

    cout << "n is " << n << ", and m is " << Gr.m << "." << endl;
}

int main (int argc, char** argv) {
//    commandLine P(argc,argv,"-o <outFile>");
//    char* iFile = P.getArgument(0);
//    char* oFile = P.getOptionValue("-o");

    char * iFile = argv[1];
    wghEdgeArray<intT> G = benchIO::readWghEdgeArrayFromFile<intT>(iFile);

    allPairsShortestPath(G);
}

<commit_msg>use command line<commit_after>//
// Created by xiaohe on 4/3/16.
//
#include "main.h"

#include "parseCommandLine.h"

using namespace std;

char* allPairsShortestPath(wghEdgeArray<intT> Gr) {
    intT n = Gr.n;
    wghEdge<intT> * edgeList = Gr.E;

    cout << "n is " << n << ", and m is " << Gr.m << "." << endl;
}

int main (int argc, char** argv) {
    commandLine P(argc,argv,"-o <outFile>");
    char* iFile = P.getArgument(0);
    char* oFile = P.getOptionValue("-o");

    wghEdgeArray<intT> G = benchIO::readWghEdgeArrayFromFile<intT>(iFile);

    allPairsShortestPath(G);
}

<|endoftext|>


<commit_before>#ifndef INCLUDE_AL_GRAPHICS_SHAPES_HPP
#define INCLUDE_AL_GRAPHICS_SHAPES_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	Factory methods for standard geometries

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include "allocore/graphics/al_Mesh.hpp"

namespace al{

/// Add tetrahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (4)
///
/// @ingroup allocore
int addTetrahedron(Mesh& m, float radius=1);

/// Add cube as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (8)
///
/// @ingroup allocore
int addCube(Mesh& m, bool withNormalsAndTexcoords = false, float radius=M_SQRT_1_3);

/// Add octahedron as triangle vertices and indices

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (6)
///
/// @ingroup allocore
int addOctahedron(Mesh& m, float radius=1);

/// Add dodecahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (20)
///
/// @ingroup allocore
int addDodecahedron(Mesh& m, float radius=1);

/// Add icosahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (12)
///
/// @ingroup allocore
int addIcosahedron(Mesh& m, float radius=1);

/// Add sphere produced from subdivided icosahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of sphere
/// @param[in]		divisions Number of recursive subdivisions
/// \returns number of vertices added
int addIcosphere(Mesh& m, double radius=1, int divisions=2);

/// Add sphere as indexed triangles

/// Vertices go stack-by-stack, then slice-by-slice. The stacks start at the
/// north pole (0,0,radius) and end at the south pole (0,0,-radius).
/// The slices start on the x axis and go counter-clockwise on the xy plane.
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of sphere
/// @param[in]		slices	Number of slices around z axis
/// @param[in]		stacks	Number of stacks on xy plane
/// \returns number of vertices added
///
/// @ingroup allocore
int addSphere(Mesh& m, double radius=1, int slices=16, int stacks=16);
int addSphereWithTexcoords(Mesh& m, double radius=1, int bands=16 );

/// Add wireframe box as indexed lines

/// The box is centered at (0,0,0).
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		width	Total width (along x)
/// @param[in]		height	Total height (along y)
/// @param[in]		depth	Total depth (along z)
/// \returns number of vertices added
///
/// @ingroup allocore
int addWireBox(Mesh& m, float width, float height, float depth);
inline int addWireBox(Mesh& m, float size=1){ return addWireBox(m,size,size,size); }

/// Add a cone/pyramid as indexed triangles

/// Note that the base lies on the xy plane, thus the shape is not "centered"
/// on the z axis.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius of base (on xy plane)
/// @param[in] apex			Position of apex
/// @param[in] slices		Number of points going around base
/// @param[in] cycles		Number of cycles to go around base
///							(should be relatively prime to slices)
/// \returns number of vertices added
///
/// @ingroup allocore
int addCone(
	Mesh& m, float radius=1, const Vec3f& apex=Vec3f(0,0,2),
	unsigned slices=16,
	unsigned cycles=1
);

/// Add a disc/regular polygon as indexed triangles

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius of disc (on xy plane)
/// @param[in] slices		Number of points going around base
/// \returns number of vertices added
///
/// @ingroup allocore
int addDisc(Mesh& m, float radius=1, unsigned slices=16);

/// Add a rectangle as indexed triangles

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] width		Total width (along x)
/// @param[in] height		Total height (along y)
/// @param[in] x			Position of center along x
/// @param[in] y			Position of center along y
/// \returns number of vertices added
///
/// @ingroup allocore
int addRect(Mesh& m, float width=2, float height=2, float x=0, float y=0);

/// Add a quadrilateral as indexed triangles

/// Input points should be co-planar and in counter-clockwise winding order.
///
/// \returns number of vertices added
template <class Vec>
int addQuad(Mesh& m, const Vec& a, const Vec& b, const Vec& c, const Vec& d);

int addQuad(
	Mesh& m,
	float x1, float y1, float z1,
	float x2, float y2, float z2,
	float x3, float y3, float z3,
	float x4, float y4, float z4
);

/// Add a prism as an indexed triangle strip

/// A prism is formed from a triangle strip between two parallel regular
/// polygons.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] btmRadius	Radius of bottom polygon (on xy plane)
/// @param[in] topRadius	Radius of top polygon (on xy plane)
/// @param[in] height		Distance between planes (along z axis)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons;
///							a value of 0.5 produces an antiprism
/// \returns number of vertices added
///
/// @ingroup allocore
int addPrism(
	Mesh& m, float btmRadius=1, float topRadius=1, float height=2,
	unsigned slices=16,
	float twist=0
);

/// Add an annulus ("little ring") as an indexed triangle strip

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] inRadius		Radius of inner circle (on xy plane)
/// @param[in] outRadius	Radius of outer circle (on xy plane)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons
/// \returns number of vertices added
///
/// @ingroup allocore
int addAnnulus(
	Mesh& m, float inRadius=0.5, float outRadius=1,
	unsigned slices=16,
	float twist=0
);

/// Add an open cylinder as an indexed triangle strip

/// To create a cylinder with different radii for the top and bottom, /see
/// addPrism.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius (on xy plane)
/// @param[in] height		Height (along z axis)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons
/// \returns number of vertices added
///
/// @ingroup allocore
int addCylinder(
	Mesh& m, float radius=1, float height=2,
	unsigned slices=16,
	float twist=0
);

/// Add a tessellated rectangular surface as an indexed triangle strip

/// This creates a flat, regularly-tesselated surface lying on the xy plane.
/// This shape can be used as a starting point for more complex meshes such as
/// height maps/terrains and texture-mapped spheres and torii.
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		Nx		Number of vertices along x
/// @param[in]		Ny		Number of vertices along y
/// @param[in]		width	Total width (along x)
/// @param[in]		height	Total height (along y)
/// @param[in]		x		Position of center along x
/// @param[in]		y		Position of center along y
/// \returns number of vertices added
///
/// @ingroup allocore
int addSurface(
	Mesh& m, int Nx, int Ny,
	double width=2, double height=2, double x=0, double y=0
);

/// Add a tessellated rectangular surface with connected edges

/// This adds a rectangular surface whose edges are connected. The resulting
/// surface is suitable for warping into cylindrical or toroidal shapes.
/// Given D as the width or height, the interval of position values along a
/// particular dimension is closed-opened, [-D/2, D/2), if that dimension loops
/// or closed, [-D/2, D/2], if that dimension does not loop.
/// The drawing primitive is assumed to be a triangle strip.
///
/// @param[in,out] m	Mesh to add vertices and indices to
/// @param[in] Nx		Number of vertices along x
/// @param[in] Ny		Number of vertices along y
/// @param[in] loopMode	1: connect edges perpendicular to x (cylindrical),
///						2: connect edges perpendicular to x and y (toroidal)
/// @param[in] width	Total width (along x)
/// @param[in] height	Total height (along y)
/// @param[in] x		Position of center along x
/// @param[in] y		Position of center along y
/// \returns number of vertices added
///
/// @ingroup allocore
int addSurfaceLoop(
	Mesh& m, int Nx, int Ny, int loopMode,
	double width=2, double height=2, double x=0, double y=0
);

/// Add a torus as an indexed triangle strip

/// If you need a texture-mapped torus, /see addSurface.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] minRadius	Radius of minor ring
/// @param[in] majRadius	Radius of major ring
/// @param[in] Nmin			Number of vertices around minor ring
/// @param[in] Nmaj			Number of vertices around major ring
/// @param[in] minPhase		Starting phase along minor ring, in [0,1]
/// \returns number of vertices added
///
/// @ingroup allocore
int addTorus(
	Mesh& m, double minRadius=0.3, double majRadius=0.7,
	int Nmin=16, int Nmaj=16, double minPhase=0
);

/// Fill array with ellipse (using fast recursion method)
template <class Vec2>
void ellipse(Vec2 * dst, int len, float radx=1, float rady=1);

/// Fill array with circle (using fast recursion method)
template <class Vec2>
void circle(Vec2 * dst, int len, float rad=1){ ellipse(dst,len, rad,rad); }

// Implementation only below
template <class Vec>
int addQuad(Mesh& m, const Vec& a, const Vec& b, const Vec& c, const Vec& d){
	return addQuad(m, a[0],a[1],a[2], b[0],b[1],b[2], c[0],c[1],c[2], d[0],d[1],d[2]);
}

template <class Vec2>
void ellipse(Vec2 * dst, int len, float radx, float rady){
	struct RSin{
		float mul,val,val2;
		RSin(float f=1, float a=1, float p=0){
			f *= M_2PI, p *= M_2PI;
			mul  = 2. * cos(f);
			val2 = sin(p - f * 2.)*a;
			val  = sin(p - f     )*a;
		}
		float operator()(){
			auto v0 = mul * val - val2;
			val2 = val;
			return val = v0;
		}
	};
	RSin x(1./len, radx, 0.25), y(1./len, rady);
	for(int i=0; i<len; ++i){
		dst[i][0] = x();
		dst[i][1] = y();
	}
}

} // al::

#endif
<commit_msg>Doxygen bulk grouping<commit_after>#ifndef INCLUDE_AL_GRAPHICS_SHAPES_HPP
#define INCLUDE_AL_GRAPHICS_SHAPES_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	Factory methods for standard geometries

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include "allocore/graphics/al_Mesh.hpp"

namespace al{
/// @addtogroup allocore
/// @{

/// Add tetrahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (4)
int addTetrahedron(Mesh& m, float radius=1);

/// Add cube as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (8)
int addCube(Mesh& m, bool withNormalsAndTexcoords = false, float radius=M_SQRT_1_3);

/// Add octahedron as triangle vertices and indices

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (6)
int addOctahedron(Mesh& m, float radius=1);

/// Add dodecahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (20)
int addDodecahedron(Mesh& m, float radius=1);

/// Add icosahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of enclosing sphere
/// \returns number of vertices added (12)
int addIcosahedron(Mesh& m, float radius=1);

/// Add sphere produced from subdivided icosahedron as indexed triangles

/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of sphere
/// @param[in]		divisions Number of recursive subdivisions
/// \returns number of vertices added
int addIcosphere(Mesh& m, double radius=1, int divisions=2);

/// Add sphere as indexed triangles

/// Vertices go stack-by-stack, then slice-by-slice. The stacks start at the
/// north pole (0,0,radius) and end at the south pole (0,0,-radius).
/// The slices start on the x axis and go counter-clockwise on the xy plane.
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		radius	Radius of sphere
/// @param[in]		slices	Number of slices around z axis
/// @param[in]		stacks	Number of stacks on xy plane
/// \returns number of vertices added
int addSphere(Mesh& m, double radius=1, int slices=16, int stacks=16);
int addSphereWithTexcoords(Mesh& m, double radius=1, int bands=16 );

/// Add wireframe box as indexed lines

/// The box is centered at (0,0,0).
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		width	Total width (along x)
/// @param[in]		height	Total height (along y)
/// @param[in]		depth	Total depth (along z)
/// \returns number of vertices added
int addWireBox(Mesh& m, float width, float height, float depth);
inline int addWireBox(Mesh& m, float size=1){ return addWireBox(m,size,size,size); }

/// Add a cone/pyramid as indexed triangles

/// Note that the base lies on the xy plane, thus the shape is not "centered"
/// on the z axis.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius of base (on xy plane)
/// @param[in] apex			Position of apex
/// @param[in] slices		Number of points going around base
/// @param[in] cycles		Number of cycles to go around base
///							(should be relatively prime to slices)
/// \returns number of vertices added
int addCone(
	Mesh& m, float radius=1, const Vec3f& apex=Vec3f(0,0,2),
	unsigned slices=16,
	unsigned cycles=1
);

/// Add a disc/regular polygon as indexed triangles

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius of disc (on xy plane)
/// @param[in] slices		Number of points going around base
/// \returns number of vertices added
int addDisc(Mesh& m, float radius=1, unsigned slices=16);

/// Add a rectangle as indexed triangles

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] width		Total width (along x)
/// @param[in] height		Total height (along y)
/// @param[in] x			Position of center along x
/// @param[in] y			Position of center along y
/// \returns number of vertices added
int addRect(Mesh& m, float width=2, float height=2, float x=0, float y=0);

/// Add a quadrilateral as indexed triangles

/// Input points should be co-planar and in counter-clockwise winding order.
///
/// \returns number of vertices added
template <class Vec>
int addQuad(Mesh& m, const Vec& a, const Vec& b, const Vec& c, const Vec& d);

int addQuad(
	Mesh& m,
	float x1, float y1, float z1,
	float x2, float y2, float z2,
	float x3, float y3, float z3,
	float x4, float y4, float z4
);

/// Add a prism as an indexed triangle strip

/// A prism is formed from a triangle strip between two parallel regular
/// polygons.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] btmRadius	Radius of bottom polygon (on xy plane)
/// @param[in] topRadius	Radius of top polygon (on xy plane)
/// @param[in] height		Distance between planes (along z axis)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons;
///							a value of 0.5 produces an antiprism
/// \returns number of vertices added
int addPrism(
	Mesh& m, float btmRadius=1, float topRadius=1, float height=2,
	unsigned slices=16,
	float twist=0
);

/// Add an annulus ("little ring") as an indexed triangle strip

/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] inRadius		Radius of inner circle (on xy plane)
/// @param[in] outRadius	Radius of outer circle (on xy plane)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons
/// \returns number of vertices added
int addAnnulus(
	Mesh& m, float inRadius=0.5, float outRadius=1,
	unsigned slices=16,
	float twist=0
);

/// Add an open cylinder as an indexed triangle strip

/// To create a cylinder with different radii for the top and bottom, /see
/// addPrism.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] radius		Radius (on xy plane)
/// @param[in] height		Height (along z axis)
/// @param[in] slices		Number of polygon vertices
/// @param[in] twist		Rotation factor between polygons
/// \returns number of vertices added
int addCylinder(
	Mesh& m, float radius=1, float height=2,
	unsigned slices=16,
	float twist=0
);

/// Add a tessellated rectangular surface as an indexed triangle strip

/// This creates a flat, regularly-tesselated surface lying on the xy plane.
/// This shape can be used as a starting point for more complex meshes such as
/// height maps/terrains and texture-mapped spheres and torii.
///
/// @param[in,out]	m		Mesh to add vertices and indices to
/// @param[in]		Nx		Number of vertices along x
/// @param[in]		Ny		Number of vertices along y
/// @param[in]		width	Total width (along x)
/// @param[in]		height	Total height (along y)
/// @param[in]		x		Position of center along x
/// @param[in]		y		Position of center along y
/// \returns number of vertices added
int addSurface(
	Mesh& m, int Nx, int Ny,
	double width=2, double height=2, double x=0, double y=0
);

/// Add a tessellated rectangular surface with connected edges

/// This adds a rectangular surface whose edges are connected. The resulting
/// surface is suitable for warping into cylindrical or toroidal shapes.
/// Given D as the width or height, the interval of position values along a
/// particular dimension is closed-opened, [-D/2, D/2), if that dimension loops
/// or closed, [-D/2, D/2], if that dimension does not loop.
/// The drawing primitive is assumed to be a triangle strip.
///
/// @param[in,out] m	Mesh to add vertices and indices to
/// @param[in] Nx		Number of vertices along x
/// @param[in] Ny		Number of vertices along y
/// @param[in] loopMode	1: connect edges perpendicular to x (cylindrical),
///						2: connect edges perpendicular to x and y (toroidal)
/// @param[in] width	Total width (along x)
/// @param[in] height	Total height (along y)
/// @param[in] x		Position of center along x
/// @param[in] y		Position of center along y
/// \returns number of vertices added
int addSurfaceLoop(
	Mesh& m, int Nx, int Ny, int loopMode,
	double width=2, double height=2, double x=0, double y=0
);

/// Add a torus as an indexed triangle strip

/// If you need a texture-mapped torus, /see addSurface.
///
/// @param[in,out] m		Mesh to add vertices and indices to
/// @param[in] minRadius	Radius of minor ring
/// @param[in] majRadius	Radius of major ring
/// @param[in] Nmin			Number of vertices around minor ring
/// @param[in] Nmaj			Number of vertices around major ring
/// @param[in] minPhase		Starting phase along minor ring, in [0,1]
/// \returns number of vertices added
int addTorus(
	Mesh& m, double minRadius=0.3, double majRadius=0.7,
	int Nmin=16, int Nmaj=16, double minPhase=0
);

/// Fill array with ellipse (using fast recursion method)
template <class Vec2>
void ellipse(Vec2 * dst, int len, float radx=1, float rady=1);

/// Fill array with circle (using fast recursion method)
template <class Vec2>
void circle(Vec2 * dst, int len, float rad=1){ ellipse(dst,len, rad,rad); }

/// @} // end allocore group

// Implementation only below
template <class Vec>
int addQuad(Mesh& m, const Vec& a, const Vec& b, const Vec& c, const Vec& d){
	return addQuad(m, a[0],a[1],a[2], b[0],b[1],b[2], c[0],c[1],c[2], d[0],d[1],d[2]);
}

template <class Vec2>
void ellipse(Vec2 * dst, int len, float radx, float rady){
	struct RSin{
		float mul,val,val2;
		RSin(float f=1, float a=1, float p=0){
			f *= M_2PI, p *= M_2PI;
			mul  = 2. * cos(f);
			val2 = sin(p - f * 2.)*a;
			val  = sin(p - f     )*a;
		}
		float operator()(){
			auto v0 = mul * val - val2;
			val2 = val;
			return val = v0;
		}
	};
	RSin x(1./len, radx, 0.25), y(1./len, rady);
	for(int i=0; i<len; ++i){
		dst[i][0] = x();
		dst[i][1] = y();
	}
}

} // al::

#endif
<|endoftext|>


<commit_before>#include <string>

#ifdef _MSC_VER
#include <windows.h>
#include <shellapi.h>

std::wstring u8towstring(const std::string& utf8)
{
	std::wstring wcs;

	int req = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), NULL, 0);
	wcs.resize(req);
	MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), &wcs[0], req);
	return wcs;
}

bool rmrf(const std::string& directory)
{
	std::wstring wdirectory = u8towstring(directory);
	wdirectory.push_back(0);
	wdirectory.push_back(0);

	SHFILEOPSTRUCT fileop;
	fileop.hwnd = NULL;    // no status display
	fileop.wFunc = FO_DELETE;  // delete operation
	fileop.pFrom = &wdirectory[0];  // source file name as double null terminated string
	fileop.pTo = NULL;    // no destination needed
	fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;  // do not prompt the user
	fileop.fAnyOperationsAborted = FALSE;
	fileop.lpszProgressTitle = NULL;
	fileop.hNameMappings = NULL;

	return SHFileOperation(&fileop) == 0;
}

#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

bool rmrf(const std::string& directory)
{
	DIR *d = opendir(directory.data());
	if (!d)
		return false;

	struct dirent *p;
	while ((p=readdir(d)) != NULL)
	{
		/* Skip the names "." and ".." as we don't want to recurse on them. */
		if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
			continue;

		std::string entity(directory + "/" + p->d_name);

		struct stat info;
		if (stat(entity.data(), &info) != 0)
			return false;
		int rv = (S_ISDIR(info.st_mode)) ? rmrf(entity) : unlink(entity.data());
		if (rv != 0)
			return false;
	}

	closedir(d);
	return rmdir(path) == 0;
}

#endif

<commit_msg>Fixes code again.<commit_after>#include <string>

#ifdef _MSC_VER
#include <windows.h>
#include <shellapi.h>

std::wstring u8towstring(const std::string& utf8)
{
	std::wstring wcs;

	int req = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), NULL, 0);
	wcs.resize(req);
	MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), &wcs[0], req);
	return wcs;
}

bool rmrf(const std::string& directory)
{
	std::wstring wdirectory = u8towstring(directory);
	wdirectory.push_back(0);
	wdirectory.push_back(0);

	SHFILEOPSTRUCT fileop;
	fileop.hwnd = NULL;    // no status display
	fileop.wFunc = FO_DELETE;  // delete operation
	fileop.pFrom = &wdirectory[0];  // source file name as double null terminated string
	fileop.pTo = NULL;    // no destination needed
	fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;  // do not prompt the user
	fileop.fAnyOperationsAborted = FALSE;
	fileop.lpszProgressTitle = NULL;
	fileop.hNameMappings = NULL;

	return SHFileOperation(&fileop) == 0;
}

#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

bool rmrf(const std::string& directory)
{
	DIR *d = opendir(directory.data());
	if (!d)
		return false;

	struct dirent *p;
	while ((p=readdir(d)) != NULL)
	{
		/* Skip the names "." and ".." as we don't want to recurse on them. */
		if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
			continue;

		std::string entity(directory + "/" + p->d_name);

		struct stat info;
		if (stat(entity.data(), &info) != 0)
			return false;
		int rv = (S_ISDIR(info.st_mode)) ? rmrf(entity) : unlink(entity.data());
		if (rv != 0)
			return false;
	}

	closedir(d);
	return rmdir(directory.data()) == 0;
}

#endif

<|endoftext|>