<commit_before>#pragma once

#include <vector>
#include <iterator>
#include <functional>

namespace helene
{

template <class NodeType, class EdgeType>
class dag;

template <class NodeType, class EdgeType>
class persistent_iterator_
{
public:
    typedef typename dag<NodeType, EdgeType>::size_type size_type;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef NodeType value_type;
    typedef NodeType* pointer;
    typedef NodeType& reference;

public:
    persistent_iterator_(size_type current_index, std::vector<NodeType>& nodes)
        : current_index_(current_index), nodes_ref_(nodes)
    {
    }

public:
    // CopyConstructible
    persistent_iterator_(const persistent_iterator_& other)
        : current_index_(other.current_index_), nodes_ref_(other.nodes_ref_)
    {
    }

    // Iterator concept member functions
    reference operator*()
    {
        return nodes_ref_.get()[current_index_];
    }

    persistent_iterator_& operator++()
    {
        ++current_index_;
        return *this;
    }

private:
    std::reference_wrapper<std::vector<NodeType>> nodes_ref_;
    size_type current_index_;
};

class start_node_iterator_
{
};

template <class NodeType, class EdgeType>
class dag
{
public:
    ////////////////////////////////////////////////////////////////////////////
    // public typedefs

    // node typedefs
    typedef NodeType value_type;
    typedef NodeType& reference;
    typedef const NodeType& const_reference;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef typename std::vector<NodeType>::size_type size_type;

    typedef typename std::vector<NodeType>::iterator iterator;
    typedef typename std::vector<NodeType>::const_iterator const_iterator;

    // edge typedefs
    typedef EdgeType edge_value_type;
    typedef EdgeType& edge_reference;
    typedef const EdgeType& const_edge_reference;

    typedef typename std::vector<EdgeType>::size_type edge_size_type;
    typedef
        typename std::vector<EdgeType>::difference_type edge_difference_type;

    typedef typename std::vector<EdgeType>::iterator edge_iterator;
    typedef typename std::vector<EdgeType>::const_iterator edge_const_iterator;

    // iterator typedefs
    typedef start_node_iterator_ start_node_iterator;
    typedef const start_node_iterator const_start_node_iterator;

private:
    ////////////////////////////////////////////////////////////////////////////
    // internal classes

    // indices to properties of the associated edge
    struct edge
    {
        edge(size_type from, size_type to)
            : from_property(from), to_property(to)
        {
        }

        size_type from_property;
        size_type to_property;

        bool
        operator==(const edge& other) const
        {
            return (from_property == other.from_property) &&
                   (to_property == other.to_property);
        }
    };

public:
    ////////////////////////////////////////////////////////////////////////////
    // Container concept member functions

    dag() = default;
    dag(const dag&) = default;

    dag& operator=(const dag&) = default;

    iterator
    begin()
    {
        return node_properties_.begin();
    }

    iterator
    end()
    {
        return node_properties_.end();
    }

    const_iterator
    cbegin() const
    {
        return node_properties_.cbegin();
    }

    const_iterator
    cend() const
    {
        return node_properties_.cend();
    }

    edge_iterator
    edge_begin()
    {
        return edge_properties_.begin();
    }

    edge_iterator
    edge_end()
    {
        return edge_properties_.end();
    }

    edge_const_iterator
    edge_cbegin() const
    {
        return edge_properties_.cbegin();
    }

    edge_const_iterator
    edge_cend() const
    {
        return edge_properties_.cend();
    }

    bool
    operator==(const dag& other) const
    {
        return (node_properties_ == other.node_properties_) &&
               (edge_properties_ == other.edge_properties_) &&
               (edges_ == other.edges_);
    }

    bool
    operator!=(const dag& other) const
    {
        return !(*this == other);
    }

    void
    swap(dag& other)
    {
        node_properties_.swap(other.node_properties_);
        edge_properties_.swap(other.edge_properties_);
        edges_.swap(other.edges_);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // dag specific member functions

    // Add node
    iterator
    add_node(const NodeType& prop)
    {
        node_properties_.push_back(prop);
        return std::prev(node_properties_.end());
    }

    // Add edge between nodes.
    // If edge introduces cycle edge will not be inserted.
    // Returns iterator to edge property or edge_end() if edge was prevented
    // from being inserted.
    edge_iterator
    add_edge(const_iterator from, const_iterator to, const EdgeType& prop)
    {
        // TODO: check for cycle
        edges_.emplace_back(from - cbegin(), to - cbegin());
        edge_properties_.push_back(prop);
        return std::prev(edge_properties_.end());
    }

    std::pair<iterator, iterator>
    end_nodes(edge_const_iterator edge)
    {
        // index of edge property
        auto edge_property_index = edge - edge_properties_.begin();

        // find
    }

private:
    std::vector<NodeType> node_properties_;
    std::vector<EdgeType> edge_properties_;

    std::vector<edge> edges_;
};
}
<commit_msg>Remove operator, will use implicit operators. 	modified:   include/dag.hpp<commit_after>#pragma once

#include <vector>
#include <iterator>
#include <functional>

namespace helene
{

template <class NodeType, class EdgeType>
class dag;

template <class NodeType, class EdgeType>
class persistent_iterator_
{
public:
    typedef typename dag<NodeType, EdgeType>::size_type size_type;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef NodeType value_type;
    typedef NodeType* pointer;
    typedef NodeType& reference;

public:
    persistent_iterator_(size_type current_index, std::vector<NodeType>& nodes)
        : current_index_(current_index), nodes_ref_(nodes)
    {
    }

public:
    // Iterator concept member functions
    reference operator*()
    {
        return nodes_ref_.get()[current_index_];
    }

    persistent_iterator_& operator++()
    {
        ++current_index_;
        return *this;
    }

private:
    std::reference_wrapper<std::vector<NodeType>> nodes_ref_;
    size_type current_index_;
};

class start_node_iterator_
{
};

template <class NodeType, class EdgeType>
class dag
{
public:
    ////////////////////////////////////////////////////////////////////////////
    // public typedefs

    // node typedefs
    typedef NodeType value_type;
    typedef NodeType& reference;
    typedef const NodeType& const_reference;

    typedef typename std::vector<NodeType>::difference_type difference_type;
    typedef typename std::vector<NodeType>::size_type size_type;

    typedef typename std::vector<NodeType>::iterator iterator;
    typedef typename std::vector<NodeType>::const_iterator const_iterator;

    // edge typedefs
    typedef EdgeType edge_value_type;
    typedef EdgeType& edge_reference;
    typedef const EdgeType& const_edge_reference;

    typedef typename std::vector<EdgeType>::size_type edge_size_type;
    typedef
        typename std::vector<EdgeType>::difference_type edge_difference_type;

    typedef typename std::vector<EdgeType>::iterator edge_iterator;
    typedef typename std::vector<EdgeType>::const_iterator edge_const_iterator;

    // iterator typedefs
    typedef start_node_iterator_ start_node_iterator;
    typedef const start_node_iterator const_start_node_iterator;

private:
    ////////////////////////////////////////////////////////////////////////////
    // internal classes

    // indices to properties of the associated edge
    struct edge
    {
        edge(size_type from, size_type to)
            : from_property(from), to_property(to)
        {
        }

        size_type from_property;
        size_type to_property;

        bool
        operator==(const edge& other) const
        {
            return (from_property == other.from_property) &&
                   (to_property == other.to_property);
        }
    };

public:
    ////////////////////////////////////////////////////////////////////////////
    // Container concept member functions

    dag() = default;
    dag(const dag&) = default;

    dag& operator=(const dag&) = default;

    iterator
    begin()
    {
        return node_properties_.begin();
    }

    iterator
    end()
    {
        return node_properties_.end();
    }

    const_iterator
    cbegin() const
    {
        return node_properties_.cbegin();
    }

    const_iterator
    cend() const
    {
        return node_properties_.cend();
    }

    edge_iterator
    edge_begin()
    {
        return edge_properties_.begin();
    }

    edge_iterator
    edge_end()
    {
        return edge_properties_.end();
    }

    edge_const_iterator
    edge_cbegin() const
    {
        return edge_properties_.cbegin();
    }

    edge_const_iterator
    edge_cend() const
    {
        return edge_properties_.cend();
    }

    bool
    operator==(const dag& other) const
    {
        return (node_properties_ == other.node_properties_) &&
               (edge_properties_ == other.edge_properties_) &&
               (edges_ == other.edges_);
    }

    bool
    operator!=(const dag& other) const
    {
        return !(*this == other);
    }

    void
    swap(dag& other)
    {
        node_properties_.swap(other.node_properties_);
        edge_properties_.swap(other.edge_properties_);
        edges_.swap(other.edges_);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // dag specific member functions

    // Add node
    iterator
    add_node(const NodeType& prop)
    {
        node_properties_.push_back(prop);
        return std::prev(node_properties_.end());
    }

    // Add edge between nodes.
    // If edge introduces cycle edge will not be inserted.
    // Returns iterator to edge property or edge_end() if edge was prevented
    // from being inserted.
    edge_iterator
    add_edge(const_iterator from, const_iterator to, const EdgeType& prop)
    {
        // TODO: check for cycle
        edges_.emplace_back(from - cbegin(), to - cbegin());
        edge_properties_.push_back(prop);
        return std::prev(edge_properties_.end());
    }

    std::pair<iterator, iterator>
    end_nodes(edge_const_iterator edge)
    {
        // index of edge property
        auto edge_property_index = edge - edge_properties_.begin();

        // find
    }

private:
    std::vector<NodeType> node_properties_;
    std::vector<EdgeType> edge_properties_;

    std::vector<edge> edges_;
};
}
<|endoftext|>


<commit_before>
#include "do_sort.h"

#define DATA_SIZE 20
#define DUMP_DATA 0

using namespace std;

// Check whether the list is correctly sorted.
bool is_sorted(do_sort::sort* ss) {
  for (int i = 0; i < ss->size() - 1; ++i)
    if ((*ss)[i] > (*ss)[i + 1])
      return false;

  return true;
}

// Report the testing results.
void report_test_result(do_sort::sort* ss, string sorting_method) {
  string test_result = (is_sorted(ss)) ? "\033[32mPASSED" : "\033[31mFAILED";
  cout << sorting_method << " test --> " << "[" << test_result << "\033[39m]" << endl;;
}

int main() {
  string test_result = "";

  // Unit test for the bubble sort.
  do_sort::selection_sort *ss = new do_sort::selection_sort();
  ss->init(DATA_SIZE);
  ss->do_sort();
  report_test_result(static_cast<do_sort::sort*>(ss), "Selection sort");
#if DUMP_DATA
  ss->dump("Bubble Sort");
#endif
  delete ss;

  // Unit test for the insertion sort.
  do_sort::insertion_sort *is = new do_sort::insertion_sort();
  is->init(DATA_SIZE);
  is->do_sort();
  report_test_result(static_cast<do_sort::sort*>(is), "Insertion sort");
#if DUMP_DATA
  is->dump("Insertion Sort");
#endif
  delete is;

  // Unit test for the merge sort.
  do_sort::merge_sort *ms = new do_sort::merge_sort();
  ms->init(DATA_SIZE);
  ms->do_sort();
  report_test_result(static_cast<do_sort::sort*>(ms), "Merge sort");
#if DUMP_DATA
  ms->dump("Merge Sort");
#endif
  delete ms;

  // Unit test for the quick sort.
  do_sort::quick_sort *qs = new do_sort::quick_sort();
  qs->init(DATA_SIZE);
  qs->do_sort();
  report_test_result(static_cast<do_sort::sort*>(qs), "Quick sort");
#if DUMP_DATA
  qs->dump("Merge Sort");
#endif
  delete qs;

  return 0;
}

<commit_msg>Fixed some typos.<commit_after>
#include "do_sort.h"

#define DATA_SIZE 20
#define DUMP_DATA 0

using namespace std;

// Check whether the list is correctly sorted.
bool is_sorted(do_sort::sort* ss) {
  for (int i = 0; i < ss->size() - 1; ++i)
    if ((*ss)[i] > (*ss)[i + 1])
      return false;

  return true;
}

// Report the testing results.
void report_test_result(do_sort::sort* ss, string sorting_method) {
  string test_result = (is_sorted(ss)) ? "\033[32mPASSED" : "\033[31mFAILED";
  cout << sorting_method << " test --> " << "[" << test_result << "\033[39m]" << endl;;
}

int main() {
  string test_result = "";

  // Unit test for the selection sort.
  do_sort::selection_sort *ss = new do_sort::selection_sort();
  ss->init(DATA_SIZE);
  ss->do_sort();
  report_test_result(static_cast<do_sort::sort*>(ss), "Selection sort");
#if DUMP_DATA
  ss->dump("Selection Sort");
#endif
  delete ss;

  // Unit test for the insertion sort.
  do_sort::insertion_sort *is = new do_sort::insertion_sort();
  is->init(DATA_SIZE);
  is->do_sort();
  report_test_result(static_cast<do_sort::sort*>(is), "Insertion sort");
#if DUMP_DATA
  is->dump("Insertion Sort");
#endif
  delete is;

  // Unit test for the merge sort.
  do_sort::merge_sort *ms = new do_sort::merge_sort();
  ms->init(DATA_SIZE);
  ms->do_sort();
  report_test_result(static_cast<do_sort::sort*>(ms), "Merge sort");
#if DUMP_DATA
  ms->dump("Merge Sort");
#endif
  delete ms;

  // Unit test for the quick sort.
  do_sort::quick_sort *qs = new do_sort::quick_sort();
  qs->init(DATA_SIZE);
  qs->do_sort();
  report_test_result(static_cast<do_sort::sort*>(qs), "Quick sort");
#if DUMP_DATA
  qs->dump("Quick Sort");
#endif
  delete qs;

  return 0;
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "spline.h"

#include "asdf_multiplat/data/gl_vertex_spec.h"

namespace asdf {
    using namespace vertex_attrib;
namespace hexmap {
namespace data
{

    /* --Save Format--
        write the number of nodes (64-bit unsigned integer)
            write the nodes
        write the number of control nodes (64-bit unsigned integer)
            write the control nodes
    */
    void spline_t::save_to_file(SDL_RWops* io) const
    {
        ASSERT(io, "");
        {
            LOG("offset when writing spline node count: %zu", SDL_RWtell(io));
            uint64_t sz = nodes.size();
            SDL_RWwrite(io, reinterpret_cast<const void*>(&sz), sizeof(uint64_t), 1);
            LOG("wrote node count (%zu bytes)", sizeof(uint64_t));
            LOG("offset after writing spline node count: %zu", SDL_RWtell(io));

            size_t n = SDL_RWwrite(io, nodes.data(), sizeof(line_node_t), nodes.size());
            ASSERT(n == nodes.size(), "error writing spline_t::nodes");
            LOG("wrote %zu spline nodes (%zu bytes)", n, n * sizeof(line_node_t));
        }
        {
            uint64_t sz = control_nodes.size();
            SDL_RWwrite(io, reinterpret_cast<const void*>(&sz), sizeof(uint64_t), 1);
            LOG("wrote control_node count (%zu bytes)", sizeof(uint64_t));

            size_t n = SDL_RWwrite(io, control_nodes.data(), sizeof(control_node_t), control_nodes.size());
            ASSERT(n == control_nodes.size(), "error writing spline_t::control_nodes");
            LOG("wrote %zu control_nodes nodes (%zu bytes)", n, n * sizeof(control_node_t));
        }

        size_t sz = SDL_RWwrite(io, reinterpret_cast<const void*>(&spline_type), sizeof(interpolation_e), 1);
        ASSERT(sz == 1, "");
    }

    void spline_t::load_from_file(SDL_RWops* io)
    {
        ASSERT(io, "");
        {
            {
                LOG("offset when loading spline node count: %zu", SDL_RWtell(io));
                uint64_t sz = 0;
                size_t n = SDL_RWread(io, reinterpret_cast<void*>(&sz), sizeof(uint64_t), 1);
                ASSERT(n == 1, "Error writing spline node count");
                LOG("offset after loading spline node count: %zu", SDL_RWtell(io));

                nodes.resize(sz);
                n = SDL_RWread(io, nodes.data(), sizeof(line_node_t), sz);
                ASSERT(n == sz, "Error loading spline nodes");
            }
            {
                uint64_t sz =   0;
                SDL_RWread(io, reinterpret_cast<void*>(&sz), sizeof(uint64_t), 1);

                control_nodes.resize(sz);
                size_t n = SDL_RWread(io, control_nodes.data(), sizeof(line_node_t), sz);
                ASSERT(n == sz, "Error loading spline control nodes");
            }

            size_t n = SDL_RWread(io, reinterpret_cast<void*>(&spline_type), sizeof(interpolation_e), 1);
            ASSERT(n == 1, "Error reading spline interpolation type");
        }
    }

    bool point_intersects_spline(glm::vec2 const& world_pos, spline_t const& spline, float dist_threshold)
    {
        if(spline.nodes.size() == 0)
        {
            return false;
        }
        else if(spline.nodes.size() == 1)
        {
            auto dist = glm::length(spline.nodes[0].position - world_pos);
            return dist <= dist_threshold;
        }
        else
        {
            //get two closest point
            spline_node_index_t closest = 0;
            auto cv = spline.nodes[0].position - world_pos;
            auto closest_dist_sq = (cv.x*cv.x)+(cv.y+cv.y);

            for(size_t i = 0; i < spline.nodes.size(); ++i)
            {
                auto v = spline.nodes[i].position - world_pos;
                auto dsq = (v.x*v.x)+(v.y+v.y);

                if(dsq < closest_dist_sq)
                {
                    closest = i;
                    closest_dist_sq = dsq;
                }
            }

            auto n1 = spline.nodes[closest].position;
            //TODO: get prev or next node, whichever is closest (and exists)

            switch(spline.spline_type)
            {
                case spline_t::linear:
                    //return circle_intersects_line(world_pos, dist_threshold, n1, n2);
                case spline_t::bezier:
                {
                    //auto c1 = spline.control_nodes[2*inds[0]+0].position;
                    //auto c2 = spline.control_nodes[2*inds[0]+1].position;
                    //return circle_intersects_bezier(world_pos, dist_threshold
                    //                                n1.position, c1, c2, n2.position);
                }
                default: EXPLODE("TODO: implement intersection with %s splines", spline_interpolation_names[spline.spline_type]);
                    break;
            }
        }
    }

    bool circle_intersects_line(glm::vec2 const& circle_pos, float radius, glm::vec2 const& p0, glm::vec2 const& p1)
    {
        return false;
    }

    bool circle_intersects_bezier(glm::vec2 circle_pos, float radius, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3)
    {
        EXPLODE("todo");
        return false;
    }

    void spline_selection_t::select_spline(spline_t& spline)
    {
        std::vector<size_t> new_inds;
        new_inds.reserve(spline.size());
        for(size_t i = 0; i < spline.size(); ++i)
        {
            new_inds.push_back(i);
        }

        select_spline_nodes(spline, std::move(new_inds));
    }

    void spline_selection_t::select_spline_nodes(spline_t& spline, std::vector<size_t> node_inds)
    {
        if(is_control_node)
        {
            deselect_all();
            is_control_node = false;
        }

        splines.push_back(&spline);
        node_indices.push_back(std::move(node_inds));
    }

    void spline_selection_t::select_control_node(spline_t& spline, size_t control_node_index)
    {
        deselect_all();
        is_control_node = true;

        splines.push_back(&spline);

        node_indices.resize(1);
        node_indices[0].push_back(control_node_index);
    }

    void spline_selection_t::deselect_all()
    {
        splines.clear();
        node_indices.clear();
    }
}
}
}
<commit_msg>implemented code to get the second closest spline node for testing intersections (still a WIP)<commit_after>#include "stdafx.h"
#include "spline.h"

#include <glm/gtx/norm.hpp>

#include "asdf_multiplat/data/gl_vertex_spec.h"

namespace asdf {
    using namespace vertex_attrib;
namespace hexmap {
namespace data
{

    /* --Save Format--
        write the number of nodes (64-bit unsigned integer)
            write the nodes
        write the number of control nodes (64-bit unsigned integer)
            write the control nodes
    */
    void spline_t::save_to_file(SDL_RWops* io) const
    {
        ASSERT(io, "");
        {
            LOG("offset when writing spline node count: %zu", SDL_RWtell(io));
            uint64_t sz = nodes.size();
            SDL_RWwrite(io, reinterpret_cast<const void*>(&sz), sizeof(uint64_t), 1);
            LOG("wrote node count (%zu bytes)", sizeof(uint64_t));
            LOG("offset after writing spline node count: %zu", SDL_RWtell(io));

            size_t n = SDL_RWwrite(io, nodes.data(), sizeof(line_node_t), nodes.size());
            ASSERT(n == nodes.size(), "error writing spline_t::nodes");
            LOG("wrote %zu spline nodes (%zu bytes)", n, n * sizeof(line_node_t));
        }
        {
            uint64_t sz = control_nodes.size();
            SDL_RWwrite(io, reinterpret_cast<const void*>(&sz), sizeof(uint64_t), 1);
            LOG("wrote control_node count (%zu bytes)", sizeof(uint64_t));

            size_t n = SDL_RWwrite(io, control_nodes.data(), sizeof(control_node_t), control_nodes.size());
            ASSERT(n == control_nodes.size(), "error writing spline_t::control_nodes");
            LOG("wrote %zu control_nodes nodes (%zu bytes)", n, n * sizeof(control_node_t));
        }

        size_t sz = SDL_RWwrite(io, reinterpret_cast<const void*>(&spline_type), sizeof(interpolation_e), 1);
        ASSERT(sz == 1, "");
    }

    void spline_t::load_from_file(SDL_RWops* io)
    {
        ASSERT(io, "");
        {
            {
                LOG("offset when loading spline node count: %zu", SDL_RWtell(io));
                uint64_t sz = 0;
                size_t n = SDL_RWread(io, reinterpret_cast<void*>(&sz), sizeof(uint64_t), 1);
                ASSERT(n == 1, "Error writing spline node count");
                LOG("offset after loading spline node count: %zu", SDL_RWtell(io));

                nodes.resize(sz);
                n = SDL_RWread(io, nodes.data(), sizeof(line_node_t), sz);
                ASSERT(n == sz, "Error loading spline nodes");
            }
            {
                uint64_t sz =   0;
                SDL_RWread(io, reinterpret_cast<void*>(&sz), sizeof(uint64_t), 1);

                control_nodes.resize(sz);
                size_t n = SDL_RWread(io, control_nodes.data(), sizeof(line_node_t), sz);
                ASSERT(n == sz, "Error loading spline control nodes");
            }

            size_t n = SDL_RWread(io, reinterpret_cast<void*>(&spline_type), sizeof(interpolation_e), 1);
            ASSERT(n == 1, "Error reading spline interpolation type");
        }
    }

    bool point_intersects_spline(glm::vec2 const& world_pos, spline_t const& spline, float dist_threshold)
    {
        if(spline.nodes.size() == 0)
        {
            return false;
        }
        else if(spline.nodes.size() == 1)
        {
            auto dist = glm::length(spline.nodes[0].position - world_pos);
            return dist <= dist_threshold;
        }
        else
        {
            //get closest point to world_pos
            spline_node_index_t closest = 0;
            auto cv = spline.nodes[0].position - world_pos;
            auto closest_dist_sq = glm::length2(cv);

            for(size_t i = 1; i < spline.nodes.size(); ++i)
            {
                auto v = spline.nodes[i].position - world_pos;
                auto dsq = glm::length2(v);

                if(dsq < closest_dist_sq)
                {
                    closest = i;
                    closest_dist_sq = dsq;
                }
            }

            auto const& p0 = spline.nodes[closest].position;

            // get prev or next node, whichever is closest to world_pos (and exists)
            line_node_t const* prev = nullptr;
            line_node_t const* next = nullptr;

            if(spline.loops)
            {
                prev = (closest == 0) ? &(*spline.nodes.end())  : &(spline.nodes[closest-1]);
                next = (closest+1 == spline.nodes.size()) ?  &(spline.nodes[0])     : &(spline.nodes[closest+1]);
            }
            else
            {
                prev = (closest==0)                       ? nullptr : &(spline.nodes[closest-1]);
                next = (closest+1 == spline.nodes.size()) ? nullptr : &(spline.nodes[closest+1]);
            }

            ASSERT(next || prev, "somehow both next and prev are null");

            //if prev is null, use next, else use prev
            auto* second_closest = (prev != nullptr) ? prev : next;

            //if both are not-null, grab the closest one
            if(prev && next)
            {
                auto d_prev = glm::length2(prev->position - p0);
                auto d_next = glm::length2(next->position - p0);

                second_closest = (d_prev > d_next) ? next : prev;
            }

            auto p1 = second_closest->position;

            switch(spline.spline_type)
            {
                case spline_t::linear:
                    return circle_intersects_line(world_pos, dist_threshold, p0, p1);
                // case spline_t::bezier:
                {
                    //auto c1 = spline.control_nodes[2*inds[0]+0].position;
                    //auto c2 = spline.control_nodes[2*inds[0]+1].position;
                    //return circle_intersects_bezier(world_pos, dist_threshold
                    //                                n1.position, c1, c2, n2.position);
                }
                default: EXPLODE("TODO: implement intersection with %s splines", spline_interpolation_names[spline.spline_type]);
                    return false;
            }
        }
    }

    bool circle_intersects_line(glm::vec2 const& circle_pos, float radius, glm::vec2 const& p0, glm::vec2 const& p1)
    {

        return false;
    }

    bool circle_intersects_bezier(glm::vec2 circle_pos, float radius, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3)
    {
        EXPLODE("todo");
        return false;
    }

    void spline_selection_t::select_spline(spline_t& spline)
    {
        std::vector<size_t> new_inds;
        new_inds.reserve(spline.size());
        for(size_t i = 0; i < spline.size(); ++i)
        {
            new_inds.push_back(i);
        }

        select_spline_nodes(spline, std::move(new_inds));
    }

    void spline_selection_t::select_spline_nodes(spline_t& spline, std::vector<size_t> node_inds)
    {
        if(is_control_node)
        {
            deselect_all();
            is_control_node = false;
        }

        splines.push_back(&spline);
        node_indices.push_back(std::move(node_inds));
    }

    void spline_selection_t::select_control_node(spline_t& spline, size_t control_node_index)
    {
        deselect_all();
        is_control_node = true;

        splines.push_back(&spline);

        node_indices.resize(1);
        node_indices[0].push_back(control_node_index);
    }

    void spline_selection_t::deselect_all()
    {
        splines.clear();
        node_indices.clear();
    }
}
}
}
<|endoftext|>


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

#pragma once
#ifndef FS_DISK_HPP
#define FS_DISK_HPP

#include "common.hpp"
#include "dirent.hpp"
#include "filesystem.hpp"
#include "partition.hpp"
#include <common>
#include <hw/block_device.hpp>
#include <deque>
#include <vector>

namespace fs
{
  /**
   * Class to initialize file systems on block devices / partitions
   **/
  class Disk {
  public:
    class Err_not_mounted : public std::runtime_error {
      using runtime_error::runtime_error;
    };

    using on_init_func  = delegate<void(fs::error_t, File_system&)>;
    using on_parts_func = delegate<void(fs::error_t, std::vector<fs::Partition>&)>;

    enum partition_t {
      MBR = 0, //< Master Boot Record (0)
      VBR1,   //> extended partitions (1-4)
      VBR2,
      VBR3,
      VBR4,
    };

    // construct a disk with a given block-device
    explicit Disk(hw::Block_device&);

    std::string name() const {
      return device.device_name();
    }

    auto device_id() const {
      return device.id();
    }

    // Returns true if the disk has no sectors
    bool empty() const noexcept
    { return device.size() == 0; }

    // Initializes file system on the first partition detected (MBR -> VBR1-4 -> ext)
    // NOTE: Always detects and instantiates a FAT filesystem
    void init_fs(on_init_func func);

    // Initialize file system on specified partition
    // NOTE: Always detects and instantiates a FAT filesystem
    void init_fs(partition_t part, on_init_func func);

    // mount custom filesystem on MBR or VBRn
    template <class T, class... Args>
    void init_fs(Args&&... args, partition_t part, on_init_func func)
    {
      // construct custom filesystem
      filesys.reset(new T(args...));
      internal_init(part, func);
    }

    // returns true if a filesystem is initialized
    bool fs_ready() const noexcept
    { return filesys != nullptr; }

    // Returns a reference to an initialized filesystem
    // If no filesystem is initialized it will throw an error
    File_system& fs() noexcept
    {
      if(UNLIKELY(not fs_ready()))
      {
        throw Err_not_mounted{"Filesystem not ready - make sure to init_fs before accessing"};
      }
      return *filesys;
    }

    // Creates a vector of the partitions on disk (see: on_parts_func)
    // Note: No file system needs to be initialized beforehand
    void partitions(on_parts_func func);

    // returns the device the disk is using
    hw::Block_device& dev() noexcept
    { return device; }

  private:
    void internal_init(partition_t part, on_init_func func);

    hw::Block_device& device;
    std::unique_ptr<File_system> filesys;
  }; //< class Disk

  using Disk_ptr = std::shared_ptr<Disk>;

} //< namespace fs

#endif //< FS_DISK_HPP
<commit_msg>fs: Remove noexcept on function that clearly throws<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef FS_DISK_HPP
#define FS_DISK_HPP

#include "common.hpp"
#include "dirent.hpp"
#include "filesystem.hpp"
#include "partition.hpp"
#include <common>
#include <hw/block_device.hpp>
#include <deque>
#include <vector>

namespace fs
{
  /**
   * Class to initialize file systems on block devices / partitions
   **/
  class Disk {
  public:
    class Err_not_mounted : public std::runtime_error {
      using runtime_error::runtime_error;
    };

    using on_init_func  = delegate<void(fs::error_t, File_system&)>;
    using on_parts_func = delegate<void(fs::error_t, std::vector<fs::Partition>&)>;

    enum partition_t {
      MBR = 0, //< Master Boot Record (0)
      VBR1,   //> extended partitions (1-4)
      VBR2,
      VBR3,
      VBR4,
    };

    // construct a disk with a given block-device
    explicit Disk(hw::Block_device&);

    std::string name() const {
      return device.device_name();
    }

    auto device_id() const {
      return device.id();
    }

    // Returns true if the disk has no sectors
    bool empty() const noexcept
    { return device.size() == 0; }

    // Initializes file system on the first partition detected (MBR -> VBR1-4 -> ext)
    // NOTE: Always detects and instantiates a FAT filesystem
    void init_fs(on_init_func func);

    // Initialize file system on specified partition
    // NOTE: Always detects and instantiates a FAT filesystem
    void init_fs(partition_t part, on_init_func func);

    // mount custom filesystem on MBR or VBRn
    template <class T, class... Args>
    void init_fs(Args&&... args, partition_t part, on_init_func func)
    {
      // construct custom filesystem
      filesys.reset(new T(args...));
      internal_init(part, func);
    }

    // returns true if a filesystem is initialized
    bool fs_ready() const noexcept
    { return filesys != nullptr; }

    // Returns a reference to an initialized filesystem
    // If no filesystem is initialized it will throw an error
    File_system& fs()
    {
      if(UNLIKELY(not fs_ready()))
      {
        throw Err_not_mounted{"Filesystem not ready - make sure to init_fs before accessing"};
      }
      return *filesys;
    }

    // Creates a vector of the partitions on disk (see: on_parts_func)
    // Note: No file system needs to be initialized beforehand
    void partitions(on_parts_func func);

    // returns the device the disk is using
    hw::Block_device& dev() noexcept
    { return device; }

  private:
    void internal_init(partition_t part, on_init_func func);

    hw::Block_device& device;
    std::unique_ptr<File_system> filesys;
  }; //< class Disk

  using Disk_ptr = std::shared_ptr<Disk>;

} //< namespace fs

#endif //< FS_DISK_HPP
<|endoftext|>


<commit_before>/*
  DueTimer.cpp - Implementation of Timers defined on DueTimer.h
  For instructions, go to https://github.com/ivanseidel/DueTimer

  Created by Ivan Seidel Gomes, March, 2013.
  Thanks to stimmer (from Arduino forum), for coding the "timer soul" (Register stuff)
  Released into the public domain.
*/

#include "DueTimer.h"

const DueTimer::Timer DueTimer::Timers[9] = {
	{TC0,0,TC0_IRQn},
	{TC0,1,TC1_IRQn},
	{TC0,2,TC2_IRQn},
	{TC1,0,TC3_IRQn},
	{TC1,1,TC4_IRQn},
	{TC1,2,TC5_IRQn},
	{TC2,0,TC6_IRQn},
	{TC2,1,TC7_IRQn},
	{TC2,2,TC8_IRQn},
};

void (*DueTimer::callbacks[9])() = {};
double DueTimer::_frequency[9] = {1,1,1,1,1,1,1,1,1};

/*
	Initialize all timers, so you can use it like: Timer0.start();
*/
DueTimer Timer(0);

DueTimer Timer0(0);
DueTimer Timer1(1);
DueTimer Timer2(2);
DueTimer Timer3(3);
DueTimer Timer4(4);
DueTimer Timer5(5);
DueTimer Timer6(6);
DueTimer Timer7(7);
DueTimer Timer8(8);

// Constructor
DueTimer::DueTimer(int _timer){
	timer = _timer;

	// Initialize Default frequency
	setFrequency(_frequency[_timer]);
}

// Get the first timer without any callbacks
DueTimer DueTimer::getAvailable(){
	for(int i = 0; i < 9; i++){
		if(!callbacks[i])
			return DueTimer(i);
	}
	// Default, return Timer0;
	return DueTimer(0);
}

// Links the function passed as argument to the timer of the object
DueTimer DueTimer::attachInterrupt(void (*isr)()){
	callbacks[timer] = isr;

	return *this;
}

// Links the function passed as argument to the timer of the object
DueTimer DueTimer::detachInterrupt(){
	// Stop running timer
	stop();

	callbacks[timer] = NULL;

	return *this;
}

// Start the timer
// If a period is set, then sets the period and start the timer
DueTimer DueTimer::start(long microseconds){
	if(microseconds > 0)
		setPeriod(microseconds);

    NVIC_EnableIRQ(Timers[timer].irq);

	return *this;
}

// Stop the timer
DueTimer DueTimer::stop(){
	NVIC_DisableIRQ(Timers[timer].irq);

	return *this;
}

// Pick the best Clock
// It uses Black magic to do this, thanks to Ogle Basil Hall!
uint8_t DueTimer::bestClock(double frequency, uint32_t& retRC){
	/*
	    Timer		Definition
	    TIMER_CLOCK1	MCK/2
	    TIMER_CLOCK2	MCK/8
	    TIMER_CLOCK3	MCK/32
	    TIMER_CLOCK4	MCK/128
	*/
	struct {
		uint8_t flag;
		uint8_t divisor;
	} clockConfig[] = {
		{ TC_CMR_TCCLKS_TIMER_CLOCK1, 2 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK2, 8 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK3, 32 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK4, 128 }
	};
	float ticks;
	float error;
	int clkId = 3;
	int bestClock = 3;
	float bestError = 1.0;
	do
	{
		ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[clkId].divisor;
		error = abs(ticks - round(ticks));
		if (abs(error) < bestError)
		{
			bestClock = clkId;
			bestError = error;
		}
	} while (clkId-- > 0);
	ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[bestClock].divisor;
	retRC = (uint32_t) round(ticks);
	return clockConfig[bestClock].flag;
}

// Set the frequency (in Hz)
DueTimer DueTimer::setFrequency(double frequency){
	//prevent negative frequencies
	if(frequency < 0) { frequency = 1; }

	// Saves current frequency
	_frequency[timer] = frequency;

	// Get current timer configurations
	Timer t = Timers[timer];

	uint32_t rc = 0;
	uint8_t clock;

	// Yes, we don't want pmc protected!
	pmc_set_writeprotect(false);

	// Enable clock for the timer
	pmc_enable_periph_clk((uint32_t)Timers[timer].irq);

	// Do magic, and find's best clock
	clock = bestClock(frequency, rc);
    TC_Configure(t.tc, t.channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | clock);

    // Pwm stuff
    TC_SetRA(t.tc, t.channel, rc/2); //50% high, 50% low
    TC_SetRC(t.tc, t.channel, rc);
    TC_Start(t.tc, t.channel);
    t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS;
    t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS;

	return *this;
}

// Set the period of the timer (in microseconds)
DueTimer DueTimer::setPeriod(long microseconds){
	double frequency = 1000000.0 / microseconds;
	setFrequency(frequency); // Convert from period in microseconds to frequency in Hz
	return *this;
}

// Get current time frequency
double DueTimer::getFrequency(){
	return _frequency[timer];
}

// Get current time period
long DueTimer::getPeriod(){
	return 1.0/getFrequency()*1000000;
}

/*
	Default timers callbacks
	DO NOT CHANGE!
*/
void TC0_Handler(){
	TC_GetStatus(TC0, 0);
	DueTimer::callbacks[0]();
}
void TC1_Handler(){
	TC_GetStatus(TC0, 1);
	DueTimer::callbacks[1]();
}
void TC2_Handler(){
	TC_GetStatus(TC0, 2);
	DueTimer::callbacks[2]();
}
void TC3_Handler(){
	TC_GetStatus(TC1, 0);
	DueTimer::callbacks[3]();
}
void TC4_Handler(){
	TC_GetStatus(TC1, 1);
	DueTimer::callbacks[4]();
}
void TC5_Handler(){
	TC_GetStatus(TC1, 2);
	DueTimer::callbacks[5]();
}
void TC6_Handler(){
	TC_GetStatus(TC2, 0);
	DueTimer::callbacks[6]();
}
void TC7_Handler(){
	TC_GetStatus(TC2, 1);
	DueTimer::callbacks[7]();
}
void TC8_Handler(){
	TC_GetStatus(TC2, 2);
	DueTimer::callbacks[8]();
}
<commit_msg>Include frequency=0 in illegal frequency check<commit_after>/*
  DueTimer.cpp - Implementation of Timers defined on DueTimer.h
  For instructions, go to https://github.com/ivanseidel/DueTimer

  Created by Ivan Seidel Gomes, March, 2013.
  Thanks to stimmer (from Arduino forum), for coding the "timer soul" (Register stuff)
  Released into the public domain.
*/

#include "DueTimer.h"

const DueTimer::Timer DueTimer::Timers[9] = {
	{TC0,0,TC0_IRQn},
	{TC0,1,TC1_IRQn},
	{TC0,2,TC2_IRQn},
	{TC1,0,TC3_IRQn},
	{TC1,1,TC4_IRQn},
	{TC1,2,TC5_IRQn},
	{TC2,0,TC6_IRQn},
	{TC2,1,TC7_IRQn},
	{TC2,2,TC8_IRQn},
};

void (*DueTimer::callbacks[9])() = {};
double DueTimer::_frequency[9] = {1,1,1,1,1,1,1,1,1};

/*
	Initialize all timers, so you can use it like: Timer0.start();
*/
DueTimer Timer(0);

DueTimer Timer0(0);
DueTimer Timer1(1);
DueTimer Timer2(2);
DueTimer Timer3(3);
DueTimer Timer4(4);
DueTimer Timer5(5);
DueTimer Timer6(6);
DueTimer Timer7(7);
DueTimer Timer8(8);

// Constructor
DueTimer::DueTimer(int _timer){
	timer = _timer;

	// Initialize Default frequency
	setFrequency(_frequency[_timer]);
}

// Get the first timer without any callbacks
DueTimer DueTimer::getAvailable(){
	for(int i = 0; i < 9; i++){
		if(!callbacks[i])
			return DueTimer(i);
	}
	// Default, return Timer0;
	return DueTimer(0);
}

// Links the function passed as argument to the timer of the object
DueTimer DueTimer::attachInterrupt(void (*isr)()){
	callbacks[timer] = isr;

	return *this;
}

// Links the function passed as argument to the timer of the object
DueTimer DueTimer::detachInterrupt(){
	// Stop running timer
	stop();

	callbacks[timer] = NULL;

	return *this;
}

// Start the timer
// If a period is set, then sets the period and start the timer
DueTimer DueTimer::start(long microseconds){
	if(microseconds > 0)
		setPeriod(microseconds);

    NVIC_EnableIRQ(Timers[timer].irq);

	return *this;
}

// Stop the timer
DueTimer DueTimer::stop(){
	NVIC_DisableIRQ(Timers[timer].irq);

	return *this;
}

// Pick the best Clock
// It uses Black magic to do this, thanks to Ogle Basil Hall!
uint8_t DueTimer::bestClock(double frequency, uint32_t& retRC){
	/*
	    Timer		Definition
	    TIMER_CLOCK1	MCK/2
	    TIMER_CLOCK2	MCK/8
	    TIMER_CLOCK3	MCK/32
	    TIMER_CLOCK4	MCK/128
	*/
	struct {
		uint8_t flag;
		uint8_t divisor;
	} clockConfig[] = {
		{ TC_CMR_TCCLKS_TIMER_CLOCK1, 2 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK2, 8 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK3, 32 },
		{ TC_CMR_TCCLKS_TIMER_CLOCK4, 128 }
	};
	float ticks;
	float error;
	int clkId = 3;
	int bestClock = 3;
	float bestError = 1.0;
	do
	{
		ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[clkId].divisor;
		error = abs(ticks - round(ticks));
		if (abs(error) < bestError)
		{
			bestClock = clkId;
			bestError = error;
		}
	} while (clkId-- > 0);
	ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[bestClock].divisor;
	retRC = (uint32_t) round(ticks);
	return clockConfig[bestClock].flag;
}

// Set the frequency (in Hz)
DueTimer DueTimer::setFrequency(double frequency){
	//prevent negative frequencies
	if(frequency <= 0) { frequency = 1; }

	// Saves current frequency
	_frequency[timer] = frequency;

	// Get current timer configurations
	Timer t = Timers[timer];

	uint32_t rc = 0;
	uint8_t clock;

	// Yes, we don't want pmc protected!
	pmc_set_writeprotect(false);

	// Enable clock for the timer
	pmc_enable_periph_clk((uint32_t)Timers[timer].irq);

	// Do magic, and find's best clock
	clock = bestClock(frequency, rc);
    TC_Configure(t.tc, t.channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | clock);

    // Pwm stuff
    TC_SetRA(t.tc, t.channel, rc/2); //50% high, 50% low
    TC_SetRC(t.tc, t.channel, rc);
    TC_Start(t.tc, t.channel);
    t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS;
    t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS;

	return *this;
}

// Set the period of the timer (in microseconds)
DueTimer DueTimer::setPeriod(long microseconds){
	double frequency = 1000000.0 / microseconds;
	setFrequency(frequency); // Convert from period in microseconds to frequency in Hz
	return *this;
}

// Get current time frequency
double DueTimer::getFrequency(){
	return _frequency[timer];
}

// Get current time period
long DueTimer::getPeriod(){
	return 1.0/getFrequency()*1000000;
}

/*
	Default timers callbacks
	DO NOT CHANGE!
*/
void TC0_Handler(){
	TC_GetStatus(TC0, 0);
	DueTimer::callbacks[0]();
}
void TC1_Handler(){
	TC_GetStatus(TC0, 1);
	DueTimer::callbacks[1]();
}
void TC2_Handler(){
	TC_GetStatus(TC0, 2);
	DueTimer::callbacks[2]();
}
void TC3_Handler(){
	TC_GetStatus(TC1, 0);
	DueTimer::callbacks[3]();
}
void TC4_Handler(){
	TC_GetStatus(TC1, 1);
	DueTimer::callbacks[4]();
}
void TC5_Handler(){
	TC_GetStatus(TC1, 2);
	DueTimer::callbacks[5]();
}
void TC6_Handler(){
	TC_GetStatus(TC2, 0);
	DueTimer::callbacks[6]();
}
void TC7_Handler(){
	TC_GetStatus(TC2, 1);
	DueTimer::callbacks[7]();
}
void TC8_Handler(){
	TC_GetStatus(TC2, 2);
	DueTimer::callbacks[8]();
}
<|endoftext|>


<commit_before>#include <boost/test/unit_test.hpp>

#include "common.h"
#include "attr.inl"
#include "datablock.inl"
#include "metadata.inl"

struct TestStruct {
	bool operator == (const TestStruct& ts) const { return true; }
};

BOOST_AUTO_TEST_CASE(input_attr_instantiation) {
	Metadata meta("test_type");

	{
		// in attribute instantiation -> not initialised
		InAttr<float> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kInput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(float));

		// instantiation
		meta.addAttribute(attr, "first");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "first");
		BOOST_CHECK_EQUAL(attr.offset(), 0u);
	}

	{
		// in attribute instantiation -> not initialised
		InAttr<TestStruct> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kInput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(TestStruct));

		// instantiation
		meta.addAttribute(attr, "second");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "second");
		BOOST_CHECK_EQUAL(attr.offset(), 1u);
	}

	{
		// out attribute instantiation -> not initialised
		OutAttr<float> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kOutput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(float));

		// instantiation
		meta.addAttribute(attr, "third");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "third");
		BOOST_CHECK_EQUAL(attr.offset(), 2u);
	}

	{
		// out attribute instantiation -> not initialised
		OutAttr<TestStruct> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kOutput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(TestStruct));

		// instantiation
		meta.addAttribute(attr, "fourth");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "fourth");
		BOOST_CHECK_EQUAL(attr.offset(), 3u);
	}
}
<commit_msg>Testing the registration of attributes to a Metadata instance<commit_after>#include <boost/test/unit_test.hpp>

#include "common.h"
#include "attr.inl"
#include "datablock.inl"
#include "metadata.inl"

struct TestStruct {
	bool operator == (const TestStruct& ts) const { return true; }
};

BOOST_AUTO_TEST_CASE(input_attr_instantiation) {
	Metadata meta("test_type");

	{
		// in attribute instantiation -> not initialised
		static InAttr<float> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kInput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(float));

		// instantiation
		meta.addAttribute(attr, "first");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "first");
		BOOST_CHECK_EQUAL(attr.offset(), 0u);
	}

	{
		// in attribute instantiation -> not initialised
		static InAttr<TestStruct> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kInput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(TestStruct));

		// instantiation
		meta.addAttribute(attr, "second");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "second");
		BOOST_CHECK_EQUAL(attr.offset(), 1u);
	}

	{
		// out attribute instantiation -> not initialised
		static OutAttr<float> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kOutput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(float));

		// instantiation
		meta.addAttribute(attr, "third");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "third");
		BOOST_CHECK_EQUAL(attr.offset(), 2u);
	}

	{
		// out attribute instantiation -> not initialised
		static OutAttr<TestStruct> attr;

		BOOST_CHECK(not attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "");
		BOOST_CHECK_EQUAL(attr.category(), Attr::kOutput);
		BOOST_CHECK_EQUAL(attr.type(), typeid(TestStruct));

		// instantiation
		meta.addAttribute(attr, "fourth");
		BOOST_CHECK(attr.isValid());
		BOOST_CHECK_EQUAL(attr.name(), "fourth");
		BOOST_CHECK_EQUAL(attr.offset(), 3u);
	}

	//////////////
	// testing the result

	BOOST_CHECK_EQUAL(meta.attributeCount(), 4u);

	BOOST_CHECK_EQUAL(meta.attr(0).name(), "first");
	BOOST_CHECK_EQUAL(meta.attr(0).category(), Attr::kInput);
	BOOST_CHECK_EQUAL(meta.attr(0).offset(), 0u);
	BOOST_CHECK_EQUAL(meta.attr(0).type(), typeid(float));

	BOOST_CHECK_EQUAL(meta.attr(1).name(), "second");
	BOOST_CHECK_EQUAL(meta.attr(1).category(), Attr::kInput);
	BOOST_CHECK_EQUAL(meta.attr(1).offset(), 1u);
	BOOST_CHECK_EQUAL(meta.attr(1).type(), typeid(TestStruct));

	BOOST_CHECK_EQUAL(meta.attr(2).name(), "third");
	BOOST_CHECK_EQUAL(meta.attr(2).category(), Attr::kOutput);
	BOOST_CHECK_EQUAL(meta.attr(2).offset(), 2u);
	BOOST_CHECK_EQUAL(meta.attr(2).type(), typeid(float));

	BOOST_CHECK_EQUAL(meta.attr(3).name(), "fourth");
	BOOST_CHECK_EQUAL(meta.attr(3).category(), Attr::kOutput);
	BOOST_CHECK_EQUAL(meta.attr(3).offset(), 3u);
	BOOST_CHECK_EQUAL(meta.attr(3).type(), typeid(TestStruct));
}
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

/*
 * BigInteger has a array for saving big value.
 * Most Significant index of array is used for sign value.
 * 0 is positive, 1 is negative.
 */

#define DEFAULT_NUM_LENGTH  64
#define BASE    10
#define CHARTONUM(type, x)  ((type)((x) - '0'))
#define NUMTOCHAR(x)  ((x) + '0')

class BigInteger {
public:
    BigInteger(long num) {
        numLength = DEFAULT_NUM_LENGTH;
        bigNumber = NULL;

        setNumber(num);
    }

    BigInteger() {
        numLength = DEFAULT_NUM_LENGTH;
        bigNumber = NULL;
    }

    ~BigInteger() {
        if (bigNumber != NULL)
            delete [] bigNumber;
        bigNumber = NULL;
    }

    void showNumber() {
        if (CHARTONUM(int, bigNumber[numLength - 1]) != 0)
            cout << "-";

        for (int i = curMaxIndex - 1; i >= 0; i--) {
            cout << bigNumber[i];
        }
        cout << endl;
    }

    void addAndSave(const BigInteger Big1, const BigInteger Big2)
    {
        setNumber(0);
        curMaxIndex = internalAdd(Big1.bigNumber, Big1.curMaxIndex, Big1.bigNumber[Big1.numLength - 1],
                                  Big2.bigNumber, Big2.curMaxIndex, Big2.bigNumber[Big2.numLength - 1],
                                  bigNumber);
    }

private:
    unsigned int numLength;
    char *bigNumber;
    int curMaxIndex;

protected:
    void setAllZero() {
        for (int i = 0; i < numLength; i++) {
            bigNumber[i] = NUMTOCHAR(0);
        }
    }

    void setNumber(long number) {
        if (bigNumber == NULL)
            allocNumberRoom();

        clearNumber();

        if (number < 0)
            bigNumber[numLength - 1] = NUMTOCHAR(1);

        do {
            bigNumber[curMaxIndex++] = NUMTOCHAR(number % BASE);
            number /= BASE;
        } while(number && curMaxIndex < numLength - 1);
    }

    void allocNumberRoom() {
        bigNumber = new char[numLength];

        setAllZero();
        curMaxIndex = 0;
    }

    void clearNumber() {
        if (curMaxIndex != 0) {
            setAllZero();
            curMaxIndex = 0;
        }
    }

    int internalAdd(const char* op1, const int op1CurMax, const char op1Sign,
                    const char* op2, const int op2CurMax, const char op2Sign,
                    char* result)
    {
        int calMax = op1CurMax > op2CurMax ? op1CurMax : op2CurMax;
        int carry = 0;
        int i = 0;

        for (i = 0; i < calMax; i++) {
            int op1Num = (CHARTONUM(int, op1Sign)) != 0 ? (-1) * CHARTONUM(int, op1[i]) :
                                                     CHARTONUM(int, op1[i]);
            int op2Num = (CHARTONUM(int, op2Sign)) != 0 ? (-1) * CHARTONUM(int, op2[i]) :
                                                     CHARTONUM(int, op2[i]);

            int temp = op1Num + op2Num + carry;

            carry = temp / 10;

            result[i] = NUMTOCHAR(temp);
        }

        if (carry != 0) {
            result[i] = carry;
            calMax++;
        }

        return calMax;
    }
};

int main(void)
{
    BigInteger bi(123456);
    BigInteger bi1(23);
    BigInteger added;

    bi.showNumber();

    bi1.showNumber();

    cout << "ADD --------------" << endl;
    added.addAndSave(bi, bi1);
    added.showNumber();

    return 0;
}
<commit_msg>[LIB] BigInteger: Support to add value with nagative one.<commit_after>#include <iostream>

using namespace std;

/*
 * BigInteger has a array for saving big value.
 * Most Significant index of array is used for sign value.
 * 0 is positive, 1 is negative.
 */

#undef DEBUG

#define DEFAULT_NUM_LENGTH  64
#define BASE    10
#define CHARTONUM(type, x)  ((type)((x) - '0'))
#define NUMTOCHAR(x)  ((x) + '0')

class BigInteger {
public:
    BigInteger(long num) {
        numLength = DEFAULT_NUM_LENGTH;
        bigNumber = NULL;

        setNumber(num);
    }

    BigInteger() {
        numLength = DEFAULT_NUM_LENGTH;
        bigNumber = NULL;
    }

    ~BigInteger() {
        if (bigNumber != NULL)
            delete [] bigNumber;
        bigNumber = NULL;
    }

    void showNumber() {
        if (CHARTONUM(int, bigNumber[numLength - 1]) != 0)
            cout << "-";

        for (int i = curMaxIndex - 1; i >= 0; i--) {
            cout << bigNumber[i];
        }
        cout << endl;
    }

    void addAndSave(const BigInteger Big1, const BigInteger Big2)
    {
        setNumber(0);
        curMaxIndex = internalAdd(Big1.bigNumber, Big1.curMaxIndex, Big1.bigNumber[Big1.numLength - 1],
                                  Big2.bigNumber, Big2.curMaxIndex, Big2.bigNumber[Big2.numLength - 1],
                                  bigNumber);
    }

    void setNumber(long number) {
        int signMul = 1;

        if (bigNumber == NULL)
            allocNumberRoom();

        clearNumber();

        if (number < 0) {
            bigNumber[numLength - 1] = NUMTOCHAR(1);
            signMul = -1;
        }

        do {
            bigNumber[curMaxIndex++] = NUMTOCHAR((signMul * number) % BASE);
            number /= BASE;
        } while(number && curMaxIndex < numLength - 1);
    }

private:
    unsigned int numLength;
    char *bigNumber;
    int curMaxIndex;

protected:
    void setAllZero() {
        for (int i = 0; i < numLength; i++) {
            bigNumber[i] = NUMTOCHAR(0);
        }
    }

    void allocNumberRoom() {
        bigNumber = new char[numLength];

        setAllZero();
        curMaxIndex = 0;
    }

    void clearNumber() {
        if (curMaxIndex != 0) {
            setAllZero();
            curMaxIndex = 0;
        }
    }

    int internalAdd(const char* op1, const int op1CurMax, const char op1Sign,
                    const char* op2, const int op2CurMax, const char op2Sign,
                    char* result)
    {
        int calMax = op1CurMax > op2CurMax ? op1CurMax : op2CurMax;
        int carry = 0;
        int i = 0;
        //cout << "sign(op1) : " << op1Sign << " sign(op2) : " << op2Sign << endl;
        if (op1Sign == op2Sign) {
            for (i = 0; i < calMax; i++) {
                int op1Num = CHARTONUM(int, op1[i]);
                int op2Num = CHARTONUM(int, op2[i]);

                int temp = op1Num + op2Num + carry;

                carry = temp / BASE;

                result[i] = NUMTOCHAR(temp % 10);
            }

            if (carry != 0) {
                result[i]++;
                calMax++;
            }

            result[numLength - 1] = op1Sign;
        } else {
            // which is the bigger value without sign?
            const char *big = NULL, *small = NULL;
            char signValue = 0;

            for (i = calMax; i >= 0; i--) {
                if (op1[i] < op2[i]) {
                    big = op2;
                    small = op1;
                    signValue = op2Sign;
                } else {
                    big = op1;
                    small = op2;
                    signValue = op1Sign;
                }

                if (big != NULL)
                    break;
            }

            if (big == NULL) {
            }

            for (i = 0; i < calMax; i++) {
                int op1Num = CHARTONUM(int, big[i]);
                int op2Num = CHARTONUM(int, small[i]);

                int temp = op1Num - op2Num + carry;
                cout << "op1Num : " << op1Num << " op2Num : " << op2Num << " result : " << temp << endl;
                cout << "carry : " << carry << endl;
                if (temp < 0) {
                    temp = BASE + temp;
                    carry = -1;
                } else {
                    carry = 0;
                }

                result[i] = NUMTOCHAR(temp);
            }

            if (carry != 0) {
                result[i]--;
                if (CHARTONUM(int, result[i]) == 0)
                    calMax--;
            }

            result[numLength - 1] = signValue;

        }

        return calMax;
    }
};

#ifdef DEBUG
int main(void)
{
    BigInteger bi(123456);
    BigInteger bi1(82323);
    BigInteger added;

    bi.showNumber();

    bi1.showNumber();

    cout << "ADD --------------" << endl;
    added.addAndSave(bi, bi1);
    added.showNumber();

    bi.setNumber(-543);
    bi1.setNumber(-1837);

    cout << "ADD2 --------------" << endl;
    added.addAndSave(bi, bi1);
    added.showNumber();

    return 0;
}
#endif
<|endoftext|>


<commit_before>#include "debug.h"
#include "himan_common.h"

#include <execinfo.h>
#include <cxxabi.h>
#include <cstdio>
#include <cstdlib>
#include <signal.h>
#include <sys/ptrace.h>
#include <dlfcn.h>

namespace himan
{

static bool DebuggerAttached()
{
	// Other possibilities:
	// - look at /proc/{PID or self}/status to get TracerPid.
	// - fork, try to PTRACE_ATTACH
	if (ptrace(PTRACE_TRACEME, 0, NULL, 0) < 0)
	{
		return true;
	}
	return false;
}

static void SignalHandler(int signum)
{
	switch (signum)
	{
	case SIGINT:
		// No stack trace since this was requested by the user.
		_Exit(1);
		break;
	case SIGQUIT:
		// 'dump core signal'
		printf("Received SIGQUIT, aborting\n");
		himan::Abort();
		break;
	case SIGSEGV:
		printf("Received SIGSEGV, aborting\n");
		himan::Abort();
		break;
	default:
		// We haven't registered any other handlers.
		break;
	}
}

void SignalHandlerInit()
{
	struct sigaction act;
	act.sa_handler = SignalHandler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;

	int ret;
	if ((ret = sigaction(SIGINT, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGINT\n");
		himan::Abort();
	}
	if ((ret = sigaction(SIGQUIT, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGQUIT\n");
		himan::Abort();
	}
	if ((ret = sigaction(SIGSEGV, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGSEGV\n");
		himan::Abort();
	}
}

static void PrintBacktrace();

bool AssertionFailed(const char* expr, long line, const char* fn, const char* file)
{
	printf("Assertion (%s) failed at: %s::%s:%ld\n\n", expr, file, fn, line);
	PrintBacktrace();
	return DebuggerAttached();
}

//
// https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
// https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.
//
static const int kMaxReturnAddresses = 128;

void PrintBacktrace()
{
	void* retAddreses[kMaxReturnAddresses];

	const int size = backtrace(retAddreses, kMaxReturnAddresses);
	char** symbols = backtrace_symbols(retAddreses, size);

	if (symbols)
	{
		for (int i = 0; i < size; i++)
		{
			// XXX Of course this doesn't work with pathnames including '('!
			const std::string symbol = std::string(symbols[i]);
			// Symbol start '('
			size_t start = std::string::npos; // '('
			// Stop at the start of the offset, like in:
			// `_Z13ExecutePluginSt10shared_ptrIN5himan20plugin_configurationEE+0x2a0`
			size_t end = std::string::npos;   // '+'
			size_t closingParen = std::string::npos;
			size_t addrStart = std::string::npos; // '['

			// Make only one pass through the string.
			for (size_t i = 0; i < symbol.size(); i++)
			{
				switch(symbol[i])
				{
					case '(':
						start = i;
						break;
					case '+':
						end = i;
						break;
					case ')':
						closingParen = i;
						break;
					case '[':
						addrStart = i;
						break;
					default:
						break;
				}
			}

			if (start == std::string::npos || end == std::string::npos || closingParen == std::string::npos ||
				addrStart == std::string::npos)
			{
				continue;
			}

			const std::string cppSymbol = symbol.substr(start + 1, end - start - 1);
			const std::string offset = symbol.substr(end, closingParen - end);
			const std::string addr = symbol.substr(addrStart);

			int status;
			char* demangledName = abi::__cxa_demangle(cppSymbol.c_str(), 0, 0, &status);
			// failed to demangle
			if (status < 0)
			{
				if (cppSymbol.empty())
				{
					// Since we failed to demangle the symbol and there's no actual symbol associated with
					// this address, get the address' originating shared object.
					Dl_info info;

					if (dladdr(retAddreses[i], &info) == 0)
					{
						printf("%d: <no symbol> (%s) %s\n", i, offset.c_str(), addr.c_str());
					}
					else
					{
						printf("%d: %s: (%s) %s\n", i, info.dli_fname, offset.c_str(), addr.c_str());
					}
				}
				else
				{
					printf("%d: %s (%s) %s\n", i, cppSymbol.c_str(), offset.c_str(), addr.c_str());
				}
			}
			else
			{
				printf("%d: %s (%s) %s\n", i, demangledName, offset.c_str(), addr.c_str());
				free(demangledName);
			}
		}
		free(symbols);
	}
}

void Abort()
{
	PrintBacktrace();
	abort();
}
} // namespace himan
<commit_msg>Use another method to check if debugger is attached to avoid hang after ASSERT firing<commit_after>#include "debug.h"
#include "himan_common.h"

#include <cstdio>
#include <cstdlib>
#include <cxxabi.h>
#include <dlfcn.h>
#include <execinfo.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ptrace.h>
namespace himan
{
static bool DebuggerAttached()
{
	// (https://stackoverflow.com/a/24969863)
	// - look at /proc/{PID or self}/status to get TracerPid. (current)
	// - fork, try to PTRACE_ATTACH (previous, hanged in some occasions)

	char buf[1024];
	int debugger_present = 0;

	int status_fd = open("/proc/self/status", O_RDONLY);
	if (status_fd == -1) return 0;

	ssize_t num_read = read(status_fd, buf, sizeof(buf) - 1);

	if (num_read > 0)
	{
		static const char TracerPid[] = "TracerPid:";
		char* tracer_pid;

		buf[num_read] = '\0';
		tracer_pid = strstr(buf, TracerPid);
		if (tracer_pid) debugger_present = !!atoi(tracer_pid + sizeof(TracerPid) - 1);
	}

	return debugger_present;
}

static void SignalHandler(int signum)
{
	switch (signum)
	{
		case SIGINT:
			// No stack trace since this was requested by the user.
			_Exit(1);
			break;
		case SIGQUIT:
			// 'dump core signal'
			printf("Received SIGQUIT, aborting\n");
			himan::Abort();
			break;
		case SIGSEGV:
			printf("Received SIGSEGV, aborting\n");
			himan::Abort();
			break;
		default:
			// We haven't registered any other handlers.
			break;
	}
}

void SignalHandlerInit()
{
	struct sigaction act;
	act.sa_handler = SignalHandler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;

	int ret;
	if ((ret = sigaction(SIGINT, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGINT\n");
		himan::Abort();
	}
	if ((ret = sigaction(SIGQUIT, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGQUIT\n");
		himan::Abort();
	}
	if ((ret = sigaction(SIGSEGV, &act, nullptr)) == -1)
	{
		printf("Failed to initialize signal handler for SIGSEGV\n");
		himan::Abort();
	}
}

static void PrintBacktrace();

bool AssertionFailed(const char* expr, long line, const char* fn, const char* file)
{
	printf("Assertion (%s) failed at: %s::%s:%ld\n\n", expr, file, fn, line);
	PrintBacktrace();
	return DebuggerAttached();
}

//
// https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
// https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.
//
static const int kMaxReturnAddresses = 128;

void PrintBacktrace()
{
	void* retAddreses[kMaxReturnAddresses];

	const int size = backtrace(retAddreses, kMaxReturnAddresses);
	char** symbols = backtrace_symbols(retAddreses, size);

	if (symbols)
	{
		for (int i = 0; i < size; i++)
		{
			// XXX Of course this doesn't work with pathnames including '('!
			const std::string symbol = std::string(symbols[i]);
			// Symbol start '('
			size_t start = std::string::npos;  // '('
			// Stop at the start of the offset, like in:
			// `_Z13ExecutePluginSt10shared_ptrIN5himan20plugin_configurationEE+0x2a0`
			size_t end = std::string::npos;  // '+'
			size_t closingParen = std::string::npos;
			size_t addrStart = std::string::npos;  // '['

			// Make only one pass through the string.
			for (size_t i = 0; i < symbol.size(); i++)
			{
				switch (symbol[i])
				{
					case '(':
						start = i;
						break;
					case '+':
						end = i;
						break;
					case ')':
						closingParen = i;
						break;
					case '[':
						addrStart = i;
						break;
					default:
						break;
				}
			}

			if (start == std::string::npos || end == std::string::npos || closingParen == std::string::npos ||
			    addrStart == std::string::npos)
			{
				continue;
			}

			const std::string cppSymbol = symbol.substr(start + 1, end - start - 1);
			const std::string offset = symbol.substr(end, closingParen - end);
			const std::string addr = symbol.substr(addrStart);

			int status;
			char* demangledName = abi::__cxa_demangle(cppSymbol.c_str(), 0, 0, &status);
			// failed to demangle
			if (status < 0)
			{
				if (cppSymbol.empty())
				{
					// Since we failed to demangle the symbol and there's no actual symbol associated with
					// this address, get the address' originating shared object.
					Dl_info info;

					if (dladdr(retAddreses[i], &info) == 0)
					{
						printf("%d: <no symbol> (%s) %s\n", i, offset.c_str(), addr.c_str());
					}
					else
					{
						printf("%d: %s: (%s) %s\n", i, info.dli_fname, offset.c_str(), addr.c_str());
					}
				}
				else
				{
					printf("%d: %s (%s) %s\n", i, cppSymbol.c_str(), offset.c_str(), addr.c_str());
				}
			}
			else
			{
				printf("%d: %s (%s) %s\n", i, demangledName, offset.c_str(), addr.c_str());
				free(demangledName);
			}
		}
		free(symbols);
	}
}

void Abort()
{
	PrintBacktrace();
	abort();
}
}  // namespace himan
<|endoftext|>


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

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
_INTR_ARRAY(VkPipelineDepthStencilStateCreateInfo)
RenderStates::depthStencilStates;
_INTR_ARRAY(VkPipelineInputAssemblyStateCreateInfo)
RenderStates::inputAssemblyStates;
_INTR_ARRAY(VkPipelineRasterizationStateCreateInfo)
RenderStates::rasterizationStates;
_INTR_ARRAY(VkPipelineColorBlendAttachmentState) RenderStates::blendStates;

void initDepthStencilStates()
{
  {
    VkPipelineDepthStencilStateCreateInfo& ds =
        RenderStates::depthStencilStates[DepthStencilStates::kDefault];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
    ds.depthWriteEnable = VK_TRUE;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds = RenderStates::depthStencilStates
        [DepthStencilStates::kDefaultNoDepthTestAndWrite];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds =
        RenderStates::depthStencilStates[DepthStencilStates::kDefaultNoWrite];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds = RenderStates::depthStencilStates
        [DepthStencilStates::kDefaultNoDepthTest];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_ALWAYS;
    ds.depthWriteEnable = VK_TRUE;
  }
}

void initInputAssemblyStates()
{
  {
    VkPipelineInputAssemblyStateCreateInfo& ia =
        RenderStates::inputAssemblyStates[InputAssemblyStates::kTriangleList];
    ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    ia.pNext = nullptr;
    ia.flags = 0u;
    ia.primitiveRestartEnable = VK_FALSE;
    ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  }

  {
    VkPipelineInputAssemblyStateCreateInfo& ia =
        RenderStates::inputAssemblyStates[InputAssemblyStates::kLineList];
    ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    ia.pNext = nullptr;
    ia.flags = 0u;
    ia.primitiveRestartEnable = VK_FALSE;
    ia.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
  }
}

void initRasterizationStates()
{
  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kDefault];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_BACK_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = 1.0f;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs = RenderStates::
        rasterizationStates[RasterizationStates::kInvertedCulling];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_FRONT_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = 1.0f;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kDoubleSided];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_NONE;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = 1.0f;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kWireframe];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_LINE;
    rs.cullMode = VK_CULL_MODE_BACK_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_TRUE;
    rs.depthBiasConstantFactor = -2.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = 3.0f;
  }
}

void initBlendStates()
{
  {
    VkPipelineColorBlendAttachmentState& bs =
        RenderStates::blendStates[BlendStates::kDefault];
    bs.colorWriteMask = 0xf;
    bs.blendEnable = VK_FALSE;
    bs.alphaBlendOp = VK_BLEND_OP_ADD;
    bs.colorBlendOp = VK_BLEND_OP_ADD;
    bs.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
  }

  {
    VkPipelineColorBlendAttachmentState& bs =
        RenderStates::blendStates[BlendStates::kAlphaBlend];
    bs.colorWriteMask = 0xf;
    bs.blendEnable = VK_TRUE;
    bs.alphaBlendOp = VK_BLEND_OP_ADD;
    bs.colorBlendOp = VK_BLEND_OP_ADD;
    bs.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
    bs.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
    bs.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
    bs.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  }
}

void RenderStates::init()
{
  {
    depthStencilStates.resize(DepthStencilStates::kCount);
    initDepthStencilStates();

    inputAssemblyStates.resize(InputAssemblyStates::kCount);
    initInputAssemblyStates();

    rasterizationStates.resize(RasterizationStates::kCount);
    initRasterizationStates();

    blendStates.resize(BlendStates::kCount);
    initBlendStates();
  }
}
}
}
}
<commit_msg>Adjusted line width<commit_after>// Copyright 2016 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
_INTR_ARRAY(VkPipelineDepthStencilStateCreateInfo)
RenderStates::depthStencilStates;
_INTR_ARRAY(VkPipelineInputAssemblyStateCreateInfo)
RenderStates::inputAssemblyStates;
_INTR_ARRAY(VkPipelineRasterizationStateCreateInfo)
RenderStates::rasterizationStates;
_INTR_ARRAY(VkPipelineColorBlendAttachmentState) RenderStates::blendStates;

void initDepthStencilStates()
{
  {
    VkPipelineDepthStencilStateCreateInfo& ds =
        RenderStates::depthStencilStates[DepthStencilStates::kDefault];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
    ds.depthWriteEnable = VK_TRUE;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds = RenderStates::depthStencilStates
        [DepthStencilStates::kDefaultNoDepthTestAndWrite];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds =
        RenderStates::depthStencilStates[DepthStencilStates::kDefaultNoWrite];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
  }

  {
    VkPipelineDepthStencilStateCreateInfo& ds = RenderStates::depthStencilStates
        [DepthStencilStates::kDefaultNoDepthTest];
    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    ds.pNext = nullptr;
    ds.flags = 0u;
    ds.depthTestEnable = VK_TRUE;
    ds.depthCompareOp = VK_COMPARE_OP_ALWAYS;
    ds.depthWriteEnable = VK_TRUE;
  }
}

void initInputAssemblyStates()
{
  {
    VkPipelineInputAssemblyStateCreateInfo& ia =
        RenderStates::inputAssemblyStates[InputAssemblyStates::kTriangleList];
    ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    ia.pNext = nullptr;
    ia.flags = 0u;
    ia.primitiveRestartEnable = VK_FALSE;
    ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  }

  {
    VkPipelineInputAssemblyStateCreateInfo& ia =
        RenderStates::inputAssemblyStates[InputAssemblyStates::kLineList];
    ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    ia.pNext = nullptr;
    ia.flags = 0u;
    ia.primitiveRestartEnable = VK_FALSE;
    ia.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
  }
}

void initRasterizationStates()
{
  static const float lineWidth = 3.0f;

  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kDefault];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_BACK_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = lineWidth;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs = RenderStates::
        rasterizationStates[RasterizationStates::kInvertedCulling];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_FRONT_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = lineWidth;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kDoubleSided];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_FILL;
    rs.cullMode = VK_CULL_MODE_NONE;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_FALSE;
    rs.depthBiasConstantFactor = 0.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = lineWidth;
  }

  {
    VkPipelineRasterizationStateCreateInfo& rs =
        RenderStates::rasterizationStates[RasterizationStates::kWireframe];
    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rs.pNext = nullptr;
    rs.flags = 0;
    rs.polygonMode = VK_POLYGON_MODE_LINE;
    rs.cullMode = VK_CULL_MODE_BACK_BIT;
    rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rs.depthClampEnable = VK_FALSE;
    rs.rasterizerDiscardEnable = VK_FALSE;
    rs.depthBiasEnable = VK_TRUE;
    rs.depthBiasConstantFactor = -2.0f;
    rs.depthBiasClamp = 0.0f;
    rs.depthBiasSlopeFactor = 0.0f;
    rs.lineWidth = lineWidth;
  }
}

void initBlendStates()
{
  {
    VkPipelineColorBlendAttachmentState& bs =
        RenderStates::blendStates[BlendStates::kDefault];
    bs.colorWriteMask = 0xf;
    bs.blendEnable = VK_FALSE;
    bs.alphaBlendOp = VK_BLEND_OP_ADD;
    bs.colorBlendOp = VK_BLEND_OP_ADD;
    bs.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
    bs.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
  }

  {
    VkPipelineColorBlendAttachmentState& bs =
        RenderStates::blendStates[BlendStates::kAlphaBlend];
    bs.colorWriteMask = 0xf;
    bs.blendEnable = VK_TRUE;
    bs.alphaBlendOp = VK_BLEND_OP_ADD;
    bs.colorBlendOp = VK_BLEND_OP_ADD;
    bs.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
    bs.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
    bs.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
    bs.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  }
}

void RenderStates::init()
{
  {
    depthStencilStates.resize(DepthStencilStates::kCount);
    initDepthStencilStates();

    inputAssemblyStates.resize(InputAssemblyStates::kCount);
    initInputAssemblyStates();

    rasterizationStates.resize(RasterizationStates::kCount);
    initRasterizationStates();

    blendStates.resize(BlendStates::kCount);
    initBlendStates();
  }
}
}
}
}
<|endoftext|>


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

const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;

Firebase::Firebase(const String& host) : _host(host) {
  _http.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  _auth = auth;
  return *this;
}

Firebase& Firebase::child(const String& key) {
  _path = key;
  return *this;
}

String Firebase::val() {
  return sendRequest("GET");
}

String Firebase::push(const String& value) {
  return sendRequest("POST", (uint8_t*)value.c_str(), value.length());
}

Firebase& Firebase::stream() {
  _error.reset();
  String url = "/" + _path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  const char* headers[] = {"Location"};
  _http.setReuse(true);
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  _http.collectHeaders(headers, 1);
  _http.addHeader("Accept", "text/event-stream");
  int statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
  String location;
  while (statusCode == 307) {
    location = _http.header("Location");
    _http.setReuse(false);
    _http.end();
    _http.setReuse(true);
    _http.begin(location, firebaseFingerprint);
    statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
  }
  if (statusCode != 200) {
    _error.set(statusCode,
	       "stream " + location + ": "
	       + HTTPClient::errorToString(statusCode));
  }
  return *this;
}

String Firebase::sendRequest(const char* method, uint8_t* value, size_t size) {
  _error.reset();
  String url = "/" + _path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  int statusCode = _http.sendRequest(method, value, size);
  if (statusCode < 0) {
    _error.set(statusCode,
	       String(method) + " " + url + ": "
	       + HTTPClient::errorToString(statusCode));
    return "";
  }
  // no _http.end() because of connection reuse.
  return _http.getString();
}

bool Firebase::connected() {
  return _http.connected();
}

bool Firebase::available() {
  return _http.getStreamPtr()->available();
}

Firebase::Event Firebase::read(String& event) {
  auto client = _http.getStreamPtr();
  Event type;;
  String typeStr = client->readStringUntil('\n').substring(7);
  if (typeStr == "put") {
    type = Firebase::Event::PUT;
  } else if (typeStr == "patch") {
    type = Firebase::Event::PATCH;
  } else {
    type = Firebase::Event::UNKNOWN;
  }
  event = client->readStringUntil('\n').substring(6);
  client->readStringUntil('\n'); // consume separator
  return type;
}
<commit_msg>Firebase/stream: add TODO<commit_after>//
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "Firebase.h"

const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;

Firebase::Firebase(const String& host) : _host(host) {
  _http.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  _auth = auth;
  return *this;
}

Firebase& Firebase::child(const String& key) {
  _path = key;
  return *this;
}

String Firebase::val() {
  return sendRequest("GET");
}

String Firebase::push(const String& value) {
  return sendRequest("POST", (uint8_t*)value.c_str(), value.length());
}

Firebase& Firebase::stream() {
  _error.reset();
  String url = "/" + _path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  const char* headers[] = {"Location"};
  _http.setReuse(true);
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  _http.collectHeaders(headers, 1);
  _http.addHeader("Accept", "text/event-stream");
  int statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
  String location;
  // TODO(proppy): Add a max redirect check
  while (statusCode == 307) {
    location = _http.header("Location");
    _http.setReuse(false);
    _http.end();
    _http.setReuse(true);
    _http.begin(location, firebaseFingerprint);
    statusCode = _http.sendRequest("GET", (uint8_t*)NULL, 0);
  }
  if (statusCode != 200) {
    _error.set(statusCode,
	       "stream " + location + ": "
	       + HTTPClient::errorToString(statusCode));
  }
  return *this;
}

String Firebase::sendRequest(const char* method, uint8_t* value, size_t size) {
  _error.reset();
  String url = "/" + _path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  int statusCode = _http.sendRequest(method, value, size);
  if (statusCode < 0) {
    _error.set(statusCode,
	       String(method) + " " + url + ": "
	       + HTTPClient::errorToString(statusCode));
    return "";
  }
  // no _http.end() because of connection reuse.
  return _http.getString();
}

bool Firebase::connected() {
  return _http.connected();
}

bool Firebase::available() {
  return _http.getStreamPtr()->available();
}

Firebase::Event Firebase::read(String& event) {
  auto client = _http.getStreamPtr();
  Event type;;
  String typeStr = client->readStringUntil('\n').substring(7);
  if (typeStr == "put") {
    type = Firebase::Event::PUT;
  } else if (typeStr == "patch") {
    type = Firebase::Event::PATCH;
  } else {
    type = Firebase::Event::UNKNOWN;
  }
  event = client->readStringUntil('\n').substring(6);
  client->readStringUntil('\n'); // consume separator
  return type;
}
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * mapper_seq_scan.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/dml/mapper/mapper_seq_scan.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/planner/nested_loop_join_node.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Nested Loop Join
//===--------------------------------------------------------------------===//

/**
 * @brief Convert a Postgres NestLoop into a Peloton SeqScanNode.
 * @return Pointer to the constructed AbstractPlanNode.
 */
planner::AbstractPlanNode* PlanTransformer::TransformNestLoop(
    const NestLoopState* nl_plan_state) {

  const JoinState *js = &(nl_plan_state->js);
  PelotonJoinType jointype = PlanTransformer::TransformJoinType(js->jointype);
  if (jointype == JOIN_TYPE_INVALID) {
    LOG_ERROR("unsupported join type: %d", js->jointype);
    return nullptr;
  }

  expression::AbstractExpression *join_filter = ExprTransformer::TransformExpr(
      reinterpret_cast<ExprState *>(js->joinqual));

  expression::AbstractExpression *plan_filter = ExprTransformer::TransformExpr(
      reinterpret_cast<ExprState *>(js->ps.qual));

  /* TODO: do we need to consider target list here? */

  planner::AbstractPlanNode *outer = PlanTransformer::TransformPlan(outerPlanState(nl_plan_state));
  planner::AbstractPlanNode *inner = PlanTransformer::TransformPlan(innerPlanState(nl_plan_state));

  /* Construct and return the Peloton plan node */
  auto plan_node = new planner::NestedLoopJoinNode(
      expression::ConjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND,
                                     join_filter, plan_filter));
  plan_node->SetJoinType(jointype);
  plan_node->AddChild(outer);
  plan_node->AddChild(inner);
  return plan_node;
}

}  // namespace bridge
}  // namespace peloton
<commit_msg>do not create null conjunction predicate if no qulifier exists in the original plan<commit_after>/*-------------------------------------------------------------------------
 *
 * mapper_seq_scan.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/dml/mapper/mapper_seq_scan.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/planner/nested_loop_join_node.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Nested Loop Join
//===--------------------------------------------------------------------===//

/**
 * @brief Convert a Postgres NestLoop into a Peloton SeqScanNode.
 * @return Pointer to the constructed AbstractPlanNode.
 */
planner::AbstractPlanNode* PlanTransformer::TransformNestLoop(
    const NestLoopState* nl_plan_state) {

  const JoinState *js = &(nl_plan_state->js);
  PelotonJoinType join_type = PlanTransformer::TransformJoinType(js->jointype);
  if (join_type == JOIN_TYPE_INVALID) {
    LOG_ERROR("unsupported join type: %d", js->jointype);
    return nullptr;
  }

  expression::AbstractExpression *join_filter = ExprTransformer::TransformExpr(
      reinterpret_cast<ExprState *>(js->joinqual));

  expression::AbstractExpression *plan_filter = ExprTransformer::TransformExpr(
      reinterpret_cast<ExprState *>(js->ps.qual));

  expression::AbstractExpression *predicate = nullptr;
  if (join_filter && plan_filter) {
    predicate = expression::ConjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND,
                                     join_filter, plan_filter);
  } else if (join_filter) {
    predicate = join_filter;
  } else {
    predicate = plan_filter;
  }

  /* TODO: do we need to consider target list here? */

  planner::AbstractPlanNode *outer = PlanTransformer::TransformPlan(outerPlanState(nl_plan_state));
  planner::AbstractPlanNode *inner = PlanTransformer::TransformPlan(innerPlanState(nl_plan_state));

  /* Construct and return the Peloton plan node */
  auto plan_node = new planner::NestedLoopJoinNode(predicate);
  plan_node->SetJoinType(join_type);
  plan_node->AddChild(outer);
  plan_node->AddChild(inner);
  LOG_INFO("Handle Nested loop join, JoinType: %d", join_type);
  return plan_node;
}

}  // namespace bridge
}  // namespace peloton
<|endoftext|>