<commit_before>
#include <cstdio>
#include <string.h>
#include <strings.h>
#include <stdio.h> // for file output
#include <fstream>

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>

#include <boost/polygon/voronoi.hpp>

#include "utils/SVG.h"

// Boost.Polygon library voronoi_basic_tutorial.cpp file

//                    Copyright Andrii Sydorchuk 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
//        (See accompanying file LICENSE_1_0.txt or copy at
//                    http://www.boost.org/LICENSE_1_0.txt)

// See http://www.boost.org for updates, documentation, and revision history.

#include <cstdio>
#include <vector>

#include <boost/polygon/voronoi.hpp>
using boost::polygon::voronoi_builder;
using boost::polygon::voronoi_diagram;
using boost::polygon::x;
using boost::polygon::y;
using boost::polygon::low;
using boost::polygon::high;

#include "voronoi_visual_utils.hpp"

#include "utils/IntPoint.h"

#include "utils/Coord_t.h"

using pos_t = double;
using vd_t = voronoi_diagram<pos_t>;

using Point = arachne::Point;
/*
struct Point {
    int a;
    int b;
    Point(int x, int y) : a(x), b(y) {}
};
*/

struct Segment {
    Point p0;
    Point p1;
    Segment(int x1, int y1, int x2, int y2) : p0(x1, y1), p1(x2, y2) {}
};

namespace boost {
namespace polygon {

template <>
struct geometry_concept<Point> {
    typedef point_concept type;
};

template <>
struct point_traits<Point> {
    typedef int coordinate_type;

    static inline coordinate_type get(
            const Point& point, orientation_2d orient) {
        return (orient == HORIZONTAL) ? point.X : point.Y;
    }
};

template <>
struct geometry_concept<Segment> {
    typedef segment_concept type;
};

template <>
struct segment_traits<Segment> {
    typedef int coordinate_type;
    typedef Point point_type;

    static inline point_type get(const Segment& segment, direction_1d dir) {
        return dir.to_int() ? segment.p1 : segment.p0;
    }
};
}    // polygon
}    // boost

// Traversing Voronoi edges using edge iterator.
int iterate_primary_edges1(const voronoi_diagram<pos_t>& vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_edge_iterator it = vd.edges().begin();
             it != vd.edges().end(); ++it) {
        if (it->is_primary())
            ++result;
    }
    return result;
}

// Traversing Voronoi edges using cell iterator.
int iterate_primary_edges2(const voronoi_diagram<pos_t> &vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
             it != vd.cells().end(); ++it) {
        const voronoi_diagram<pos_t>::cell_type& cell = *it;
        const voronoi_diagram<pos_t>::edge_type* edge = cell.incident_edge();
        // This is convenient way to iterate edges around Voronoi cell.
        do {
            if (edge->is_primary())
                ++result;
            edge = edge->next();
        } while (edge != cell.incident_edge());
    }
    return result;
}

// Traversing Voronoi edges using vertex iterator.
// As opposite to the above two functions this one will not iterate through
// edges without finite endpoints and will iterate only once through edges
// with single finite endpoint.
int iterate_primary_edges3(const voronoi_diagram<pos_t> &vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_vertex_iterator it =
             vd.vertices().begin(); it != vd.vertices().end(); ++it) {
        const voronoi_diagram<pos_t>::vertex_type& vertex = *it;
        const voronoi_diagram<pos_t>::edge_type* edge = vertex.incident_edge();
        // This is convenient way to iterate edges around Voronoi vertex.
        do {
            if (edge->is_primary())
                ++result;
            edge = edge->rot_next();
        } while (edge != vertex.incident_edge());
    }
    return result;
}

/*
  point_type retrieve_point(const cell_type& cell) {
    source_index_type index = cell.source_index();
    source_category_type category = cell.source_category();
    if (category == SOURCE_CATEGORY_SINGLE_POINT) {
      return point_data_[index];
    }
    index -= point_data_.size();
    if (category == SOURCE_CATEGORY_SEGMENT_START_POINT) {
      return low(segment_data_[index]);
    } else {
      return high(segment_data_[index]);
    }
  }

  segment_type retrieve_segment(const cell_type& cell) {
    source_index_type index = cell.source_index() - point_data_.size();
    return segment_data_[index];
  }
*/

namespace arachne
{
void try1(voronoi_diagram<pos_t>& vd, std::vector<Point>& points, std::vector<Segment>& segments)
{
    AABB aabb;
    for (const voronoi_diagram<pos_t>::vertex_type& vert : vd.vertices())
    {
        aabb.include(Point(vert.x(), vert.y()));
    }
    for (const Point& p : points)
    {
        aabb.include(p);
    }
    for (const Segment& s : segments)
    {
        aabb.include(s.p0);
        aabb.include(s.p1);
    }

    SVG svg("output/try.svg", aabb);

    for (const Point& p : points)
    {
        svg.writePoint(p);
    }
    for (const Segment& s : segments)
    {
        svg.writeLine(s.p0, s.p1);
        svg.writePoint(s.p0);
        svg.writePoint(s.p1);
    }

    for (const vd_t::edge_type& edge : vd.edges())
    {
        const vd_t::vertex_type* from = edge.vertex0();
        const vd_t::vertex_type* to = edge.vertex1();
        if (from && to)
        {
            if (edge.is_linear())
            {
                svg.writeLine(Point(from->x(), from->y()), Point(to->x(), to->y()), SVG::Color::RED);
            }
            else
            {
                const vd_t::cell_type& left_cell = *edge.cell();
                const vd_t::cell_type& right_cell = *edge.twin()->cell();

                const vd_t::cell_type& segment_cell = (boost::polygon::belongs(left_cell.source_category(), boost::polygon::GEOMETRY_CATEGORY_SEGMENT))? left_cell : right_cell;
                const vd_t::cell_type& point_cell = (boost::polygon::belongs(left_cell.source_category(), boost::polygon::GEOMETRY_CATEGORY_POINT))? left_cell : right_cell;

                Point* point = nullptr;
                Segment& segment = segments[segment_cell.source_index()];

                switch (point_cell.source_category())
                {
                case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
                    point = &points[point_cell.source_index()];
                    break;
                case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
                    point = &segments[point_cell.source_index()].p0;
                    break;
                case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
                    point = &segments[point_cell.source_index()].p1;
                    break;
                default:
                    break;
                }
                if (!point)
                {
                    printf("Cannot make arc!\n");
                    continue;
                }
                Point mid = *point / 2 + (segment.p0 + segment.p1) / 4;
                svg.writeLine(Point(from->x(), from->y()), mid, SVG::Color::BLUE);
                svg.writeLine(mid, Point(to->x(), to->y()), SVG::Color::BLUE);
                //std::vector<Point> discretization;
                //boost::polygon::voronoi_visual_utils<pos_t>::discretize(*point, *segment, 10, &discretization)
            }
        }
    }

    for (const vd_t::vertex_type& vert : vd.vertices())
    {
        svg.writePoint(Point(vert.x(), vert.y()), false, 3, SVG::Color::RED);
    }

    for (const vd_t::cell_type& cell : vd.cells())
    {

    }
}
} // namespace arachne

int main() {
    // Preparing Input Geometries.
    std::vector<Point> points;
    points.push_back(Point(0, 0));
    points.push_back(Point(100, 600));
    std::vector<Segment> segments;
    segments.push_back(Segment(-400, 500, 500, -100));
    segments.push_back(Segment(300, -1100, 1300, -100));

    // Construction of the Voronoi Diagram.
    voronoi_diagram<pos_t> vd;
    construct_voronoi(points.begin(), points.end(),
                                        segments.begin(), segments.end(),
                                        &vd);

    // Traversing Voronoi Graph.
    {
        printf("Traversing Voronoi graph.\n");
        printf("Number of visited primary edges using edge iterator: %d\n",
                iterate_primary_edges1(vd));
        printf("Number of visited primary edges using cell iterator: %d\n",
                iterate_primary_edges2(vd));
        printf("Number of visited primary edges using vertex iterator: %d\n",
                iterate_primary_edges3(vd));
        printf("\n");
    }

    // Using color member of the Voronoi primitives to store the average number
    // of edges around each cell (including secondary edges).
    {
        printf("Number of edges (including secondary) around the Voronoi cells:\n");
        for (voronoi_diagram<pos_t>::const_edge_iterator it = vd.edges().begin();
                 it != vd.edges().end(); ++it) {
            std::size_t cnt = it->cell()->color();
            it->cell()->color(cnt + 1);
        }
        for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
                 it != vd.cells().end(); ++it) {
            printf("%lu ", it->color());
        }
        printf("\n");
        printf("\n");
    }

    // Linking Voronoi cells with input geometries.
    {
        unsigned int cell_index = 0;
        for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
                 it != vd.cells().end(); ++it) {
            if (it->contains_point()) {
                std::size_t index = it->source_index();
                Point p = points[index];
                printf("Cell #%ud contains a point: (%d, %d).\n",
                             cell_index, x(p), y(p));
            } else {
                std::size_t index = it->source_index() - points.size();
                Point p0 = low(segments[index]);
                Point p1 = high(segments[index]);
                if (it->source_category() ==
                        boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) {
                    printf("Cell #%ud contains segment start point: (%d, %d).\n",
                                 cell_index, x(p0), y(p0));
                } else if (it->source_category() ==
                                     boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT) {
                    printf("Cell #%ud contains segment end point: (%d, %d).\n",
                                 cell_index, x(p0), y(p0));
                } else {
                    printf("Cell #%ud contains a segment: ((%d, %d), (%d, %d)). \n",
                                 cell_index, x(p0), y(p0), x(p1), y(p1));
                }
            }
            ++cell_index;
        }
    }
    return 0;
}
<commit_msg>assert showing bug in boost library<commit_after>
#include <cstdio>
#include <string.h>
#include <strings.h>
#include <stdio.h> // for file output
#include <fstream>

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>

#include <boost/polygon/voronoi.hpp>

#include "utils/SVG.h"

// Boost.Polygon library voronoi_basic_tutorial.cpp file

//                    Copyright Andrii Sydorchuk 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
//        (See accompanying file LICENSE_1_0.txt or copy at
//                    http://www.boost.org/LICENSE_1_0.txt)

// See http://www.boost.org for updates, documentation, and revision history.

#include <cstdio>
#include <vector>

#include <boost/polygon/voronoi.hpp>
using boost::polygon::voronoi_builder;
using boost::polygon::voronoi_diagram;
using boost::polygon::x;
using boost::polygon::y;
using boost::polygon::low;
using boost::polygon::high;

#include "voronoi_visual_utils.hpp"

#include "utils/IntPoint.h"

#include "utils/Coord_t.h"

using pos_t = double;
using vd_t = voronoi_diagram<pos_t>;

using Point = arachne::Point;
/*
struct Point {
    int a;
    int b;
    Point(int x, int y) : a(x), b(y) {}
};
*/

struct Segment {
    Point p0;
    Point p1;
    Segment(int x1, int y1, int x2, int y2) : p0(x1, y1), p1(x2, y2) {}
};

namespace boost {
namespace polygon {

template <>
struct geometry_concept<Point> {
    typedef point_concept type;
};

template <>
struct point_traits<Point> {
    typedef int coordinate_type;

    static inline coordinate_type get(
            const Point& point, orientation_2d orient) {
        return (orient == HORIZONTAL) ? point.X : point.Y;
    }
};

template <>
struct geometry_concept<Segment> {
    typedef segment_concept type;
};

template <>
struct segment_traits<Segment> {
    typedef int coordinate_type;
    typedef Point point_type;

    static inline point_type get(const Segment& segment, direction_1d dir) {
        return dir.to_int() ? segment.p1 : segment.p0;
    }
};
}    // polygon
}    // boost

// Traversing Voronoi edges using edge iterator.
int iterate_primary_edges1(const voronoi_diagram<pos_t>& vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_edge_iterator it = vd.edges().begin();
             it != vd.edges().end(); ++it) {
        if (it->is_primary())
            ++result;
    }
    return result;
}

// Traversing Voronoi edges using cell iterator.
int iterate_primary_edges2(const voronoi_diagram<pos_t> &vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
             it != vd.cells().end(); ++it) {
        const voronoi_diagram<pos_t>::cell_type& cell = *it;
        const voronoi_diagram<pos_t>::edge_type* edge = cell.incident_edge();
        // This is convenient way to iterate edges around Voronoi cell.
        do {
            if (edge->is_primary())
                ++result;
            edge = edge->next();
        } while (edge != cell.incident_edge());
    }
    return result;
}

// Traversing Voronoi edges using vertex iterator.
// As opposite to the above two functions this one will not iterate through
// edges without finite endpoints and will iterate only once through edges
// with single finite endpoint.
int iterate_primary_edges3(const voronoi_diagram<pos_t> &vd) {
    int result = 0;
    for (voronoi_diagram<pos_t>::const_vertex_iterator it =
             vd.vertices().begin(); it != vd.vertices().end(); ++it) {
        const voronoi_diagram<pos_t>::vertex_type& vertex = *it;
        const voronoi_diagram<pos_t>::edge_type* edge = vertex.incident_edge();
        // This is convenient way to iterate edges around Voronoi vertex.
        do {
            if (edge->is_primary())
                ++result;
            edge = edge->rot_next();
        } while (edge != vertex.incident_edge());
    }
    return result;
}

/*
  point_type retrieve_point(const cell_type& cell) {
    source_index_type index = cell.source_index();
    source_category_type category = cell.source_category();
    if (category == SOURCE_CATEGORY_SINGLE_POINT) {
      return point_data_[index];
    }
    index -= point_data_.size();
    if (category == SOURCE_CATEGORY_SEGMENT_START_POINT) {
      return low(segment_data_[index]);
    } else {
      return high(segment_data_[index]);
    }
  }

  segment_type retrieve_segment(const cell_type& cell) {
    source_index_type index = cell.source_index() - point_data_.size();
    return segment_data_[index];
  }
*/

namespace arachne
{
void try1(voronoi_diagram<pos_t>& vd, std::vector<Point>& points, std::vector<Segment>& segments)
{
    AABB aabb;
    for (const voronoi_diagram<pos_t>::vertex_type& vert : vd.vertices())
    {
        aabb.include(Point(vert.x(), vert.y()));
    }
    for (const Point& p : points)
    {
        aabb.include(p);
    }
    for (const Segment& s : segments)
    {
        aabb.include(s.p0);
        aabb.include(s.p1);
    }

    SVG svg("output/try.svg", aabb);

    for (const Point& p : points)
    {
        svg.writePoint(p);
    }
    for (const Segment& s : segments)
    {
        svg.writeLine(s.p0, s.p1);
        svg.writePoint(s.p0);
        svg.writePoint(s.p1);
    }

    for (const vd_t::edge_type& edge : vd.edges())
    {
        const vd_t::vertex_type* from = edge.vertex0();
        const vd_t::vertex_type* to = edge.vertex1();
        if (from && to)
        {
            if (edge.is_linear())
            {
                svg.writeLine(Point(from->x(), from->y()), Point(to->x(), to->y()), SVG::Color::RED);
            }
            else
            {
                const vd_t::cell_type& left_cell = *edge.cell();
                const vd_t::cell_type& right_cell = *edge.twin()->cell();

                const vd_t::cell_type& segment_cell = (boost::polygon::belongs(left_cell.source_category(), boost::polygon::GEOMETRY_CATEGORY_SEGMENT))? left_cell : right_cell;
                const vd_t::cell_type& point_cell = (boost::polygon::belongs(left_cell.source_category(), boost::polygon::GEOMETRY_CATEGORY_POINT))? left_cell : right_cell;

                Point* point = nullptr;
                Segment& segment = segments[segment_cell.source_index()];

                switch (point_cell.source_category())
                {
                case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
                    point = &points[point_cell.source_index()];
                    break;
                case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
                    point = &segments[point_cell.source_index()].p0;
                    break;
                case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
                    point = &segments[point_cell.source_index()].p1;
                    break;
                default:
                    break;
                }
                if (!point)
                {
                    printf("Cannot make arc!\n");
                    continue;
                }
                Point mid = *point / 2 + (segment.p0 + segment.p1) / 4;
                svg.writeLine(Point(from->x(), from->y()), mid, SVG::Color::BLUE);
                svg.writeLine(mid, Point(to->x(), to->y()), SVG::Color::BLUE);
                //std::vector<Point> discretization;
                //boost::polygon::voronoi_visual_utils<pos_t>::discretize(*point, *segment, 10, &discretization)
            }
        }
    }

    for (const vd_t::vertex_type& vert : vd.vertices())
    {
        svg.writePoint(Point(vert.x(), vert.y()), false, 3, SVG::Color::RED);
    }

    for (const vd_t::cell_type& cell : vd.cells())
    {

    }
}
} // namespace arachne

int main() {
    // Preparing Input Geometries.
    std::vector<Point> points;
    points.push_back(Point(0, 0));
    points.push_back(Point(100, 600));
    std::vector<Segment> segments;
    segments.push_back(Segment(-400, 500, 500, -100));
    segments.push_back(Segment(300, -1100, 1300, -100));

    // Construction of the Voronoi Diagram.
    voronoi_diagram<pos_t> vd;
    construct_voronoi(points.begin(), points.end(),
                                        segments.begin(), segments.end(),
                                        &vd);

    // Traversing Voronoi Graph.
    {
        printf("Traversing Voronoi graph.\n");
        printf("Number of visited primary edges using edge iterator: %d\n",
                iterate_primary_edges1(vd));
        printf("Number of visited primary edges using cell iterator: %d\n",
                iterate_primary_edges2(vd));
        printf("Number of visited primary edges using vertex iterator: %d\n",
                iterate_primary_edges3(vd));
        printf("\n");
    }

    // Using color member of the Voronoi primitives to store the average number
    // of edges around each cell (including secondary edges).
    {
        printf("Number of edges (including secondary) around the Voronoi cells:\n");
        for (voronoi_diagram<pos_t>::const_edge_iterator it = vd.edges().begin();
                 it != vd.edges().end(); ++it) {
            std::size_t cnt = it->cell()->color();
            it->cell()->color(cnt + 1);
        }
        for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
                 it != vd.cells().end(); ++it) {
            printf("%lu ", it->color());
        }
        printf("\n");
        printf("\n");
    }

    // Linking Voronoi cells with input geometries.
    {
        unsigned int cell_index = 0;
        for (voronoi_diagram<pos_t>::const_cell_iterator it = vd.cells().begin();
                 it != vd.cells().end(); ++it) {
            if (it->contains_point()) {
                std::size_t index = it->source_index();
                assert(index < points.size());
                Point p = points[index];
                printf("Cell #%ud contains a point: (%d, %d).\n",
                             cell_index, x(p), y(p));
            } else {
                std::size_t index = it->source_index() - points.size();
                assert(index < segments.size());
                Point p0 = low(segments[index]);
                Point p1 = high(segments[index]);
                if (it->source_category() ==
                        boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) {
                    printf("Cell #%ud contains segment start point: (%d, %d).\n",
                                 cell_index, x(p0), y(p0));
                } else if (it->source_category() ==
                                     boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT) {
                    printf("Cell #%ud contains segment end point: (%d, %d).\n",
                                 cell_index, x(p0), y(p0));
                } else {
                    printf("Cell #%ud contains a segment: ((%d, %d), (%d, %d)). \n",
                                 cell_index, x(p0), y(p0), x(p1), y(p1));
                }
            }
            ++cell_index;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>#ifndef __STAN__COMMON__RECORDER__SUM_VALUES_HPP__
#define __STAN__COMMON__RECORDER__SUM_VALUES_HPP__

#include <vector>
#include <string>

namespace stan {
  namespace common {
    namespace recorder {

      class sum_values {
      public:
        sum_values(const size_t N)
          : N_(N), m_(0), skip_(0), sum_(N_, 0.0) { }

        sum_values(const size_t N, const size_t skip)
          : N_(N), m_(0), skip_(skip), sum_(N_, 0.0) { }

        /**
         * Do nothing with std::string vector
         *
         * @tparam T type of element
         * @param x vector of type T
         */
        void operator()(const std::vector<std::string>& x) {
        }

        /**
         * Add values to cumulative sum
         *
         * @tparam T type of element
         * @param x vector of type T
         */
        template <class T>
        void operator()(const std::vector<T>& x) {
          if (N_ != x.size())
            throw std::length_error("vector provided does not match the parameter length");
          if (m_ >= skip_)
            for (size_t n = 0; n < N_; n++) {
              sum_[n] += x[n];
            }
          m_++;
        }

        /**
         * Do nothing with a string.
         *
         * @param x string to print with prefix in front
         */
        void operator()(const std::string x) { }

        /**
         * Do nothing
         *
         */
        void operator()() { }

        /**
         * Indicator function for whether the instance is recording.
         */
        bool is_recording() const {
          return true;
        }

        const std::vector<double>& sum() const {
          return sum_;
        }

        const size_t called() const {
          return m_;
        }

        const size_t recorded() const {
          if (m_ >= skip_)
            return m_ - skip_;
          else
            return 0;
        }

      private:
        size_t N_;
        size_t m_;
        size_t skip_;
        std::vector<double> sum_;
      };

    }
  }
}

#endif
<commit_msg>Adding include for stdexcept.<commit_after>#ifndef __STAN__COMMON__RECORDER__SUM_VALUES_HPP__
#define __STAN__COMMON__RECORDER__SUM_VALUES_HPP__

#include <vector>
#include <stdexcept>
#include <string>

namespace stan {
  namespace common {
    namespace recorder {

      class sum_values {
      public:
        sum_values(const size_t N)
          : N_(N), m_(0), skip_(0), sum_(N_, 0.0) { }

        sum_values(const size_t N, const size_t skip)
          : N_(N), m_(0), skip_(skip), sum_(N_, 0.0) { }

        /**
         * Do nothing with std::string vector
         *
         * @tparam T type of element
         * @param x vector of type T
         */
        void operator()(const std::vector<std::string>& x) {
        }

        /**
         * Add values to cumulative sum
         *
         * @tparam T type of element
         * @param x vector of type T
         */
        template <class T>
        void operator()(const std::vector<T>& x) {
          if (N_ != x.size())
            throw std::length_error("vector provided does not match the parameter length");
          if (m_ >= skip_)
            for (size_t n = 0; n < N_; n++) {
              sum_[n] += x[n];
            }
          m_++;
        }

        /**
         * Do nothing with a string.
         *
         * @param x string to print with prefix in front
         */
        void operator()(const std::string x) { }

        /**
         * Do nothing
         *
         */
        void operator()() { }

        /**
         * Indicator function for whether the instance is recording.
         */
        bool is_recording() const {
          return true;
        }

        const std::vector<double>& sum() const {
          return sum_;
        }

        const size_t called() const {
          return m_;
        }

        const size_t recorded() const {
          if (m_ >= skip_)
            return m_ - skip_;
          else
            return 0;
        }

      private:
        size_t N_;
        size_t m_;
        size_t skip_;
        std::vector<double> sum_;
      };

    }
  }
}

#endif
<|endoftext|>


<commit_before><commit_msg>Planning: fixed a bug for stop distance.<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/tasks/speed_decider/speed_decider.h"

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "modules/planning/proto/decision.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/util/util.h"
#include "modules/perception/proto/perception_obstacle.pb.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::math::Vec2d;
using apollo::common::Status;
using apollo::perception::PerceptionObstacle;

SpeedDecider::SpeedDecider() : Task("SpeedDecider") {}

bool SpeedDecider::Init(const PlanningConfig& config) {
  dp_st_speed_config_ = config.em_planner_config().dp_st_speed_config();
  st_boundary_config_ = dp_st_speed_config_.st_boundary_config();
  return true;
}

apollo::common::Status SpeedDecider::Execute(
    Frame* frame, ReferenceLineInfo* reference_line_info) {
  Task::Execute(frame, reference_line_info);
  init_point_ = frame_->PlanningStartPoint();
  adc_sl_boundary_ = reference_line_info_->AdcSlBoundary();
  reference_line_ = &reference_line_info_->reference_line();
  if (!MakeObjectDecision(reference_line_info->speed_data(),
                          reference_line_info->path_decision())
           .ok()) {
    const std::string msg = "Get object decision by speed profile failed.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  return Status::OK();
}

SpeedDecider::StPosition SpeedDecider::GetStPosition(
    const SpeedData& speed_profile, const StBoundary& st_boundary) const {
  StPosition st_position = BELOW;
  const double start_t = st_boundary.min_t();
  const double end_t = st_boundary.max_t();
  for (const auto& speed_point : speed_profile.speed_vector()) {
    if (speed_point.t() < start_t) {
      continue;
    }
    if (speed_point.t() > end_t) {
      break;
    }

    STPoint st_point(speed_point.s(), speed_point.t());
    if (st_boundary.IsPointInBoundary(st_point)) {
      const std::string msg =
          "dp_st_graph failed: speed profile cross st_boundaries.";
      AERROR << msg;
      st_position = CROSS;
      return st_position;
    }

    double s_upper = reference_line_info_->reference_line().Length() -
                     reference_line_info_->AdcSlBoundary().end_s();
    double s_lower = 0.0;
    if (st_boundary.GetBoundarySRange(speed_point.t(), &s_upper, &s_lower)) {
      if (s_lower > speed_point.s()) {
        st_position = BELOW;
      } else if (s_upper < speed_point.s()) {
        st_position = ABOVE;
      }
    }
  }
  return st_position;
}

bool SpeedDecider::IsFollowTooClose(const PathObstacle& path_obstacle) const {
  if (!path_obstacle.IsBlockingObstacle()) {
    return false;
  }

  if (path_obstacle.st_boundary().min_t() > 0.0) {
    return false;
  }
  const double obs_speed = path_obstacle.obstacle()->Speed();
  const double ego_speed = init_point_.v();
  if (obs_speed > ego_speed) {
    return false;
  }
  const double distance =
      path_obstacle.st_boundary().min_s() - FLAGS_min_stop_distance_obstacle;
  constexpr double decel = 1.0;
  return distance < std::pow((ego_speed - obs_speed), 2) * 0.5 / decel;
}

Status SpeedDecider::MakeObjectDecision(
    const SpeedData& speed_profile, PathDecision* const path_decision) const {
  if (speed_profile.speed_vector().size() < 2) {
    const std::string msg = "dp_st_graph failed to get speed profile.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  for (const auto* obstacle : path_decision->path_obstacles().Items()) {
    auto* path_obstacle = path_decision->Find(obstacle->Id());
    const auto& boundary = path_obstacle->st_boundary();

    if (boundary.IsEmpty() || boundary.max_s() < 0.0 ||
        boundary.max_t() < 0.0) {
      AppendIgnoreDecision(path_obstacle);
      continue;
    }

    if (path_obstacle->HasLongitudinalDecision()) {
      AppendIgnoreDecision(path_obstacle);
      continue;
    }

    auto position = GetStPosition(speed_profile, boundary);
    switch (position) {
      case BELOW:
        if (boundary.boundary_type() == StBoundary::BoundaryType::KEEP_CLEAR) {
          ObjectDecisionType stop_decision;
          if (CreateStopDecision(*path_obstacle, &stop_decision,
                                 -FLAGS_traffic_light_stop_distance)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/keep_clear",
                                                   stop_decision);
          }
        } else if (CheckIsFollowByT(boundary) &&
                   (boundary.max_t() - boundary.min_t() >
                    FLAGS_follow_min_time_sec)) {
          // stop for low_speed decelerating
          if (IsFollowTooClose(*path_obstacle)) {
            ObjectDecisionType stop_decision;
            if (CreateStopDecision(*path_obstacle, &stop_decision,
                                   -FLAGS_min_stop_distance_obstacle)) {
              path_obstacle->AddLongitudinalDecision("dp_st_graph/too_close",
                                                     stop_decision);
            }
          } else {  // high speed or low speed accelerating
            // FOLLOW decision
            ObjectDecisionType follow_decision;
            if (CreateFollowDecision(*path_obstacle, &follow_decision)) {
              path_obstacle->AddLongitudinalDecision("dp_st_graph",
                                                     follow_decision);
            }
          }
        } else {
          // YIELD decision
          ObjectDecisionType yield_decision;
          if (CreateYieldDecision(*path_obstacle, &yield_decision)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph",
                                                   yield_decision);
          }
        }
        break;
      case ABOVE:
        if (boundary.boundary_type() == StBoundary::BoundaryType::KEEP_CLEAR) {
          ObjectDecisionType ignore;
          ignore.mutable_ignore();
          path_obstacle->AddLongitudinalDecision("dp_st_graph", ignore);
        } else {
          // OVERTAKE decision
          ObjectDecisionType overtake_decision;
          if (CreateOvertakeDecision(*path_obstacle, &overtake_decision)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/overtake",
                                                   overtake_decision);
          }
        }
        break;
      case CROSS:
        if (obstacle->IsBlockingObstacle()) {
          ObjectDecisionType stop_decision;
          if (CreateStopDecision(*path_obstacle, &stop_decision,
                                 -FLAGS_min_stop_distance_obstacle)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/cross",
                                                   stop_decision);
          }
        }
        break;
      default:
        AERROR << "Unknown position:" << position;
    }
    AppendIgnoreDecision(path_obstacle);
  }
  return Status::OK();
}

void SpeedDecider::AppendIgnoreDecision(PathObstacle* path_obstacle) const {
  ObjectDecisionType ignore_decision;
  ignore_decision.mutable_ignore();
  if (!path_obstacle->HasLongitudinalDecision()) {
    path_obstacle->AddLongitudinalDecision("dp_st_graph", ignore_decision);
  }
  if (!path_obstacle->HasLateralDecision()) {
    path_obstacle->AddLateralDecision("dp_st_graph", ignore_decision);
  }
}

bool SpeedDecider::CreateStopDecision(const PathObstacle& path_obstacle,
                                      ObjectDecisionType* const stop_decision,
                                      double stop_distance) const {
  DCHECK_NOTNULL(stop_decision);

  const auto& boundary = path_obstacle.st_boundary();
  const double fence_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + stop_distance;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < fence_s) {
    ADEBUG << "Stop fence is further away, ignore.";
    return false;
  }

  const auto fence_point = reference_line_->GetReferencePoint(fence_s);

  // set STOP decision
  auto* stop = stop_decision->mutable_stop();
  stop->set_distance_s(stop_distance);
  auto* stop_point = stop->mutable_stop_point();
  stop_point->set_x(fence_point.x());
  stop_point->set_y(fence_point.y());
  stop_point->set_z(0.0);
  stop->set_stop_heading(fence_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "STOP: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateFollowDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const follow_decision) const {
  DCHECK_NOTNULL(follow_decision);

  const double follow_speed = init_point_.v();
  const double follow_distance_s = -std::fmax(
      follow_speed * FLAGS_follow_time_buffer, FLAGS_follow_min_distance);

  const auto& boundary = path_obstacle.st_boundary();
  const double reference_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + follow_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_s) {
    ADEBUG << "Follow reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_s);

  // set FOLLOW decision
  auto* follow = follow_decision->mutable_follow();
  follow->set_distance_s(follow_distance_s);
  auto* fence_point = follow->mutable_fence_point();
  fence_point->set_x(ref_point.x());
  fence_point->set_y(ref_point.y());
  fence_point->set_z(0.0);
  follow->set_fence_heading(ref_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "FOLLOW: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateYieldDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const yield_decision) const {
  DCHECK_NOTNULL(yield_decision);

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  double yield_distance = FLAGS_yield_distance;
  switch (obstacle_type) {
    case PerceptionObstacle::PEDESTRIAN:
    case PerceptionObstacle::BICYCLE:
      yield_distance = FLAGS_yield_distance_pedestrian_bycicle;
      break;
    default:
      yield_distance = FLAGS_yield_distance;
      break;
  }

  const auto& obstacle_boundary = path_obstacle.st_boundary();
  const double yield_distance_s =
      std::max(-obstacle_boundary.min_s(), -yield_distance);

  const double reference_line_fence_s =
      adc_sl_boundary_.end_s() + obstacle_boundary.min_s() + yield_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_line_fence_s) {
    ADEBUG << "Yield reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_line_fence_s);

  // set YIELD decision
  auto* yield = yield_decision->mutable_yield();
  yield->set_distance_s(yield_distance_s);
  yield->mutable_fence_point()->set_x(ref_point.x());
  yield->mutable_fence_point()->set_y(ref_point.y());
  yield->mutable_fence_point()->set_z(0.0);
  yield->set_fence_heading(ref_point.heading());

  ADEBUG << "YIELD: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateOvertakeDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const overtake_decision) const {
  DCHECK_NOTNULL(overtake_decision);

  constexpr double kOvertakeTimeBuffer = 3.0;  // in seconds
  constexpr double kMinOvertakeDistance = 10.0;  // in meters

  const auto& velocity = path_obstacle.obstacle()->Perception().velocity();
  const double obstacle_speed =
      common::math::Vec2d::CreateUnitVec2d(init_point_.path_point().theta())
          .InnerProd(Vec2d(velocity.x(), velocity.y()));

  const double overtake_distance_s = std::fmax(
      std::fmax(init_point_.v(), obstacle_speed) * kOvertakeTimeBuffer,
      kMinOvertakeDistance);

  const auto& boundary = path_obstacle.st_boundary();
  const double reference_line_fence_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + overtake_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_line_fence_s) {
    ADEBUG << "Overtake reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_line_fence_s);

  // set OVERTAKE decision
  auto* overtake = overtake_decision->mutable_overtake();
  overtake->set_distance_s(overtake_distance_s);
  overtake->mutable_fence_point()->set_x(ref_point.x());
  overtake->mutable_fence_point()->set_y(ref_point.y());
  overtake->mutable_fence_point()->set_z(0.0);
  overtake->set_fence_heading(ref_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "OVERTAKE: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CheckIsFollowByT(const StBoundary& boundary) const {
  if (boundary.BottomLeftPoint().s() > boundary.BottomRightPoint().s()) {
    return false;
  }
  constexpr double kFollowTimeEpsilon = 1e-3;
  constexpr double kFollowCutOffTime = 0.5;
  if (boundary.min_t() > kFollowCutOffTime ||
      boundary.max_t() < kFollowTimeEpsilon) {
    return false;
  }
  return true;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: ignore out of time range obstacle. (#2855)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/tasks/speed_decider/speed_decider.h"

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "modules/planning/proto/decision.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/util/util.h"
#include "modules/perception/proto/perception_obstacle.pb.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::math::Vec2d;
using apollo::common::Status;
using apollo::perception::PerceptionObstacle;

SpeedDecider::SpeedDecider() : Task("SpeedDecider") {}

bool SpeedDecider::Init(const PlanningConfig& config) {
  dp_st_speed_config_ = config.em_planner_config().dp_st_speed_config();
  st_boundary_config_ = dp_st_speed_config_.st_boundary_config();
  return true;
}

apollo::common::Status SpeedDecider::Execute(
    Frame* frame, ReferenceLineInfo* reference_line_info) {
  Task::Execute(frame, reference_line_info);
  init_point_ = frame_->PlanningStartPoint();
  adc_sl_boundary_ = reference_line_info_->AdcSlBoundary();
  reference_line_ = &reference_line_info_->reference_line();
  if (!MakeObjectDecision(reference_line_info->speed_data(),
                          reference_line_info->path_decision())
           .ok()) {
    const std::string msg = "Get object decision by speed profile failed.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  return Status::OK();
}

SpeedDecider::StPosition SpeedDecider::GetStPosition(
    const SpeedData& speed_profile, const StBoundary& st_boundary) const {
  StPosition st_position = BELOW;
  const double start_t = st_boundary.min_t();
  const double end_t = st_boundary.max_t();
  for (const auto& speed_point : speed_profile.speed_vector()) {
    if (speed_point.t() < start_t) {
      continue;
    }
    if (speed_point.t() > end_t) {
      break;
    }

    STPoint st_point(speed_point.s(), speed_point.t());
    if (st_boundary.IsPointInBoundary(st_point)) {
      const std::string msg =
          "dp_st_graph failed: speed profile cross st_boundaries.";
      AERROR << msg;
      st_position = CROSS;
      return st_position;
    }

    double s_upper = reference_line_info_->reference_line().Length() -
                     reference_line_info_->AdcSlBoundary().end_s();
    double s_lower = 0.0;
    if (st_boundary.GetBoundarySRange(speed_point.t(), &s_upper, &s_lower)) {
      if (s_lower > speed_point.s()) {
        st_position = BELOW;
      } else if (s_upper < speed_point.s()) {
        st_position = ABOVE;
      }
    }
  }
  return st_position;
}

bool SpeedDecider::IsFollowTooClose(const PathObstacle& path_obstacle) const {
  if (!path_obstacle.IsBlockingObstacle()) {
    return false;
  }

  if (path_obstacle.st_boundary().min_t() > 0.0) {
    return false;
  }
  const double obs_speed = path_obstacle.obstacle()->Speed();
  const double ego_speed = init_point_.v();
  if (obs_speed > ego_speed) {
    return false;
  }
  const double distance =
      path_obstacle.st_boundary().min_s() - FLAGS_min_stop_distance_obstacle;
  constexpr double decel = 1.0;
  return distance < std::pow((ego_speed - obs_speed), 2) * 0.5 / decel;
}

Status SpeedDecider::MakeObjectDecision(
    const SpeedData& speed_profile, PathDecision* const path_decision) const {
  if (speed_profile.speed_vector().size() < 2) {
    const std::string msg = "dp_st_graph failed to get speed profile.";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  for (const auto* obstacle : path_decision->path_obstacles().Items()) {
    auto* path_obstacle = path_decision->Find(obstacle->Id());
    const auto& boundary = path_obstacle->st_boundary();

    if (boundary.IsEmpty() || boundary.max_s() < 0.0 ||
        boundary.max_t() < 0.0 ||
        boundary.min_t() > dp_st_speed_config_.total_time()) {
      AppendIgnoreDecision(path_obstacle);
      continue;
    }

    if (path_obstacle->HasLongitudinalDecision()) {
      AppendIgnoreDecision(path_obstacle);
      continue;
    }

    auto position = GetStPosition(speed_profile, boundary);
    switch (position) {
      case BELOW:
        if (boundary.boundary_type() == StBoundary::BoundaryType::KEEP_CLEAR) {
          ObjectDecisionType stop_decision;
          if (CreateStopDecision(*path_obstacle, &stop_decision,
                                 -FLAGS_traffic_light_stop_distance)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/keep_clear",
                                                   stop_decision);
          }
        } else if (CheckIsFollowByT(boundary) &&
                   (boundary.max_t() - boundary.min_t() >
                    FLAGS_follow_min_time_sec)) {
          // stop for low_speed decelerating
          if (IsFollowTooClose(*path_obstacle)) {
            ObjectDecisionType stop_decision;
            if (CreateStopDecision(*path_obstacle, &stop_decision,
                                   -FLAGS_min_stop_distance_obstacle)) {
              path_obstacle->AddLongitudinalDecision("dp_st_graph/too_close",
                                                     stop_decision);
            }
          } else {  // high speed or low speed accelerating
            // FOLLOW decision
            ObjectDecisionType follow_decision;
            if (CreateFollowDecision(*path_obstacle, &follow_decision)) {
              path_obstacle->AddLongitudinalDecision("dp_st_graph",
                                                     follow_decision);
            }
          }
        } else {
          // YIELD decision
          ObjectDecisionType yield_decision;
          if (CreateYieldDecision(*path_obstacle, &yield_decision)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph",
                                                   yield_decision);
          }
        }
        break;
      case ABOVE:
        if (boundary.boundary_type() == StBoundary::BoundaryType::KEEP_CLEAR) {
          ObjectDecisionType ignore;
          ignore.mutable_ignore();
          path_obstacle->AddLongitudinalDecision("dp_st_graph", ignore);
        } else {
          // OVERTAKE decision
          ObjectDecisionType overtake_decision;
          if (CreateOvertakeDecision(*path_obstacle, &overtake_decision)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/overtake",
                                                   overtake_decision);
          }
        }
        break;
      case CROSS:
        if (obstacle->IsBlockingObstacle()) {
          ObjectDecisionType stop_decision;
          if (CreateStopDecision(*path_obstacle, &stop_decision,
                                 -FLAGS_min_stop_distance_obstacle)) {
            path_obstacle->AddLongitudinalDecision("dp_st_graph/cross",
                                                   stop_decision);
          }
        }
        break;
      default:
        AERROR << "Unknown position:" << position;
    }
    AppendIgnoreDecision(path_obstacle);
  }
  return Status::OK();
}

void SpeedDecider::AppendIgnoreDecision(PathObstacle* path_obstacle) const {
  ObjectDecisionType ignore_decision;
  ignore_decision.mutable_ignore();
  if (!path_obstacle->HasLongitudinalDecision()) {
    path_obstacle->AddLongitudinalDecision("dp_st_graph", ignore_decision);
  }
  if (!path_obstacle->HasLateralDecision()) {
    path_obstacle->AddLateralDecision("dp_st_graph", ignore_decision);
  }
}

bool SpeedDecider::CreateStopDecision(const PathObstacle& path_obstacle,
                                      ObjectDecisionType* const stop_decision,
                                      double stop_distance) const {
  DCHECK_NOTNULL(stop_decision);

  const auto& boundary = path_obstacle.st_boundary();
  const double fence_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + stop_distance;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < fence_s) {
    ADEBUG << "Stop fence is further away, ignore.";
    return false;
  }

  const auto fence_point = reference_line_->GetReferencePoint(fence_s);

  // set STOP decision
  auto* stop = stop_decision->mutable_stop();
  stop->set_distance_s(stop_distance);
  auto* stop_point = stop->mutable_stop_point();
  stop_point->set_x(fence_point.x());
  stop_point->set_y(fence_point.y());
  stop_point->set_z(0.0);
  stop->set_stop_heading(fence_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "STOP: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateFollowDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const follow_decision) const {
  DCHECK_NOTNULL(follow_decision);

  const double follow_speed = init_point_.v();
  const double follow_distance_s = -std::fmax(
      follow_speed * FLAGS_follow_time_buffer, FLAGS_follow_min_distance);

  const auto& boundary = path_obstacle.st_boundary();
  const double reference_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + follow_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_s) {
    ADEBUG << "Follow reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_s);

  // set FOLLOW decision
  auto* follow = follow_decision->mutable_follow();
  follow->set_distance_s(follow_distance_s);
  auto* fence_point = follow->mutable_fence_point();
  fence_point->set_x(ref_point.x());
  fence_point->set_y(ref_point.y());
  fence_point->set_z(0.0);
  follow->set_fence_heading(ref_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "FOLLOW: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateYieldDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const yield_decision) const {
  DCHECK_NOTNULL(yield_decision);

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  double yield_distance = FLAGS_yield_distance;
  switch (obstacle_type) {
    case PerceptionObstacle::PEDESTRIAN:
    case PerceptionObstacle::BICYCLE:
      yield_distance = FLAGS_yield_distance_pedestrian_bycicle;
      break;
    default:
      yield_distance = FLAGS_yield_distance;
      break;
  }

  const auto& obstacle_boundary = path_obstacle.st_boundary();
  const double yield_distance_s =
      std::max(-obstacle_boundary.min_s(), -yield_distance);

  const double reference_line_fence_s =
      adc_sl_boundary_.end_s() + obstacle_boundary.min_s() + yield_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_line_fence_s) {
    ADEBUG << "Yield reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_line_fence_s);

  // set YIELD decision
  auto* yield = yield_decision->mutable_yield();
  yield->set_distance_s(yield_distance_s);
  yield->mutable_fence_point()->set_x(ref_point.x());
  yield->mutable_fence_point()->set_y(ref_point.y());
  yield->mutable_fence_point()->set_z(0.0);
  yield->set_fence_heading(ref_point.heading());

  ADEBUG << "YIELD: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CreateOvertakeDecision(
    const PathObstacle& path_obstacle,
    ObjectDecisionType* const overtake_decision) const {
  DCHECK_NOTNULL(overtake_decision);

  constexpr double kOvertakeTimeBuffer = 3.0;  // in seconds
  constexpr double kMinOvertakeDistance = 10.0;  // in meters

  const auto& velocity = path_obstacle.obstacle()->Perception().velocity();
  const double obstacle_speed =
      common::math::Vec2d::CreateUnitVec2d(init_point_.path_point().theta())
          .InnerProd(Vec2d(velocity.x(), velocity.y()));

  const double overtake_distance_s = std::fmax(
      std::fmax(init_point_.v(), obstacle_speed) * kOvertakeTimeBuffer,
      kMinOvertakeDistance);

  const auto& boundary = path_obstacle.st_boundary();
  const double reference_line_fence_s =
      adc_sl_boundary_.end_s() + boundary.min_s() + overtake_distance_s;
  const double main_stop_s =
      reference_line_info_->path_decision()->stop_reference_line_s();
  if (main_stop_s < reference_line_fence_s) {
    ADEBUG << "Overtake reference_s is further away, ignore.";
    return false;
  }

  auto ref_point = reference_line_->GetReferencePoint(reference_line_fence_s);

  // set OVERTAKE decision
  auto* overtake = overtake_decision->mutable_overtake();
  overtake->set_distance_s(overtake_distance_s);
  overtake->mutable_fence_point()->set_x(ref_point.x());
  overtake->mutable_fence_point()->set_y(ref_point.y());
  overtake->mutable_fence_point()->set_z(0.0);
  overtake->set_fence_heading(ref_point.heading());

  PerceptionObstacle::Type obstacle_type =
      path_obstacle.obstacle()->Perception().type();
  ADEBUG << "OVERTAKE: obstacle_id[" << path_obstacle.obstacle()->Id()
      << "] obstacle_type[" << PerceptionObstacle_Type_Name(obstacle_type)
      << "]";

  return true;
}

bool SpeedDecider::CheckIsFollowByT(const StBoundary& boundary) const {
  if (boundary.BottomLeftPoint().s() > boundary.BottomRightPoint().s()) {
    return false;
  }
  constexpr double kFollowTimeEpsilon = 1e-3;
  constexpr double kFollowCutOffTime = 0.5;
  if (boundary.min_t() > kFollowCutOffTime ||
      boundary.max_t() < kFollowTimeEpsilon) {
    return false;
  }
  return true;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <votca/csg/nblistgrid.h>
#include <votca/csg/topology.h>

namespace votca {
namespace csg {

using namespace std;

void NBListGrid::Generate(BeadList &list1, BeadList &list2,
                          bool do_exclusions) {

  _do_exclusions = do_exclusions;
  if (list1.empty()) {
    return;
  }
  if (list2.empty()) {
    return;
  }

  assert(list1.getTopology() == list2.getTopology());
  Topology *top = _top = list1.getTopology();

  InitializeGrid(top->getBox());

  // Add all beads of list1
  for (auto &iter : list1) {
    getCell(iter->getPos())._beads.push_back(iter);
  }

  for (auto &iter : list2) {
    cell_t &cell = getCell(iter->getPos());
    TestBead(cell, iter);
  }
}

void NBListGrid::Generate(BeadList &list, bool do_exclusions) {
  _do_exclusions = do_exclusions;
  if (list.empty()) {
    return;
  }

  Topology *top = _top = list.getTopology();

  InitializeGrid(top->getBox());

  for (auto &iter : list) {
    cell_t &cell = getCell(iter->getPos());
    TestBead(cell, iter);
    getCell(iter->getPos())._beads.push_back(iter);
  }
}
void NBListGrid::InitializeGrid(const Eigen::Matrix3d &box) {
  _box_a = box.col(0);
  _box_b = box.col(1);
  _box_c = box.col(2);

  // create plane normals
  _norm_a = _box_b.cross(_box_c);
  _norm_b = _box_c.cross(_box_a);
  _norm_c = _box_a.cross(_box_b);

  _norm_a.normalize();
  _norm_b.normalize();
  _norm_c.normalize();

  double la = _box_a.dot(_norm_a);
  double lb = _box_b.dot(_norm_b);
  double lc = _box_c.dot(_norm_c);

  // calculate grid size, each grid has to be at least size of cut-off
  _box_Na = Index(std::max(std::abs(la / _cutoff), 1.0));
  _box_Nb = Index(std::max(std::abs(lb / _cutoff), 1.0));
  _box_Nc = Index(std::max(std::abs(lc / _cutoff), 1.0));

  _norm_a = _norm_a / _box_a.dot(_norm_a) * (double)_box_Na;
  _norm_b = _norm_b / _box_b.dot(_norm_b) * (double)_box_Nb;
  _norm_c = _norm_c / _box_c.dot(_norm_c) * (double)_box_Nc;

  _grid.resize(_box_Na * _box_Nb * _box_Nc);

  Index a1, a2, b1, b2, c1, c2;

  a1 = b1 = c1 = -1;
  a2 = b2 = c2 = 1;

  if (_box_Na < 3) {
    a2 = 0;
  }
  if (_box_Nb < 3) {
    b2 = 0;
  }
  if (_box_Nc < 3) {
    c2 = 0;
  }

  if (_box_Na < 2) {
    a1 = 0;
  }
  if (_box_Nb < 2) {
    b1 = 0;
  }
  if (_box_Nc < 2) {
    c1 = 0;
  }

  // wow, setting up the neighbours is an ugly for construct!
  // loop from N..2*N to avoid if and only use %
  for (Index a = _box_Na; a < 2 * _box_Na; ++a) {
    for (Index b = _box_Nb; b < 2 * _box_Nb; ++b) {
      for (Index c = _box_Nc; c < 2 * _box_Nc; ++c) {
        cell_t &cell = getCell(a % _box_Na, b % _box_Nb, c % _box_Nc);
        for (Index aa = a + a1; aa <= a + a2; ++aa) {
          for (Index bb = b + b1; bb <= b + b2; ++bb) {
            for (Index cc = c + c1; cc <= c + c2; ++cc) {
              cell_t *cell2 =
                  &getCell(aa % _box_Na, bb % _box_Nb, cc % _box_Nc);
              if (cell2 == &cell) {
                continue;  // ignore self
              }
              cell._neighbours.push_back(
                  &getCell(aa % _box_Na, bb % _box_Nb, cc % _box_Nc));
            }
          }
        }
      }
    }
  }
}

NBListGrid::cell_t &NBListGrid::getCell(const Eigen::Vector3d &r) {
  Index a = (Index)floor(r.dot(_norm_a));
  Index b = (Index)floor(r.dot(_norm_b));
  Index c = (Index)floor(r.dot(_norm_c));

  if (a < 0) {
    a = _box_Na + a % _box_Na;
  }
  a %= _box_Na;

  if (b < 0) {
    b = _box_Nb + b % _box_Nb;
  }
  b %= _box_Nb;

  if (c < 0) {
    c = _box_Nc + c % _box_Nc;
  }
  c %= _box_Nc;

  return getCell(a, b, c);
}

void NBListGrid::TestBead(NBListGrid::cell_t &cell, Bead *bead) {
  TestCell(cell, bead);
  for (auto &neighbour : cell._neighbours) {
    TestCell(*neighbour, bead);
  }
}

void NBListGrid::TestCell(NBListGrid::cell_t &cell, Bead *bead) {
  Eigen::Vector3d u = bead->getPos();

  for (auto &_bead : cell._beads) {

    Eigen::Vector3d v = _bead->getPos();
    Eigen::Vector3d r = _top->BCShortestConnection(v, u);
    double d = r.norm();
    if (d < _cutoff) {
      if (_do_exclusions) {
        if (_top->getExclusions().IsExcluded(_bead, bead)) {
          continue;
        }
      }
      if ((*_match_function)(_bead, bead, r, d)) {
        if (!FindPair(_bead, bead)) {
          AddPair(_pair_creator(_bead, bead, r));
        }
      }
    }
  }
}

}  // namespace csg
}  // namespace votca
<commit_msg>Made topology in nblistgrid const and reference<commit_after>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <votca/csg/nblistgrid.h>
#include <votca/csg/topology.h>

namespace votca {
namespace csg {

using namespace std;

void NBListGrid::Generate(BeadList &list1, BeadList &list2,
                          bool do_exclusions) {

  _do_exclusions = do_exclusions;
  if (list1.empty()) {
    return;
  }
  if (list2.empty()) {
    return;
  }

  assert(&(list1.getTopology()) == &(list2.getTopology()));
  const Topology & top = _top = list1.getTopology();

  InitializeGrid(top.getBox());

  // Add all beads of list1
  for (auto &iter : list1) {
    getCell(iter->getPos())._beads.push_back(iter);
  }

  for (auto &iter : list2) {
    cell_t &cell = getCell(iter->getPos());
    TestBead(cell, iter);
  }
}

void NBListGrid::Generate(BeadList &list, bool do_exclusions) {
  _do_exclusions = do_exclusions;
  if (list.empty()) {
    return;
  }

  const Topology & top = _top = list.getTopology();

  InitializeGrid(top.getBox());

  for (auto &iter : list) {
    cell_t &cell = getCell(iter->getPos());
    TestBead(cell, iter);
    getCell(iter->getPos())._beads.push_back(iter);
  }
}
void NBListGrid::InitializeGrid(const Eigen::Matrix3d &box) {
  _box_a = box.col(0);
  _box_b = box.col(1);
  _box_c = box.col(2);

  // create plane normals
  _norm_a = _box_b.cross(_box_c);
  _norm_b = _box_c.cross(_box_a);
  _norm_c = _box_a.cross(_box_b);

  _norm_a.normalize();
  _norm_b.normalize();
  _norm_c.normalize();

  double la = _box_a.dot(_norm_a);
  double lb = _box_b.dot(_norm_b);
  double lc = _box_c.dot(_norm_c);

  // calculate grid size, each grid has to be at least size of cut-off
  _box_Na = Index(std::max(std::abs(la / _cutoff), 1.0));
  _box_Nb = Index(std::max(std::abs(lb / _cutoff), 1.0));
  _box_Nc = Index(std::max(std::abs(lc / _cutoff), 1.0));

  _norm_a = _norm_a / _box_a.dot(_norm_a) * (double)_box_Na;
  _norm_b = _norm_b / _box_b.dot(_norm_b) * (double)_box_Nb;
  _norm_c = _norm_c / _box_c.dot(_norm_c) * (double)_box_Nc;

  _grid.resize(_box_Na * _box_Nb * _box_Nc);

  Index a1, a2, b1, b2, c1, c2;

  a1 = b1 = c1 = -1;
  a2 = b2 = c2 = 1;

  if (_box_Na < 3) {
    a2 = 0;
  }
  if (_box_Nb < 3) {
    b2 = 0;
  }
  if (_box_Nc < 3) {
    c2 = 0;
  }

  if (_box_Na < 2) {
    a1 = 0;
  }
  if (_box_Nb < 2) {
    b1 = 0;
  }
  if (_box_Nc < 2) {
    c1 = 0;
  }

  // wow, setting up the neighbours is an ugly for construct!
  // loop from N..2*N to avoid if and only use %
  for (Index a = _box_Na; a < 2 * _box_Na; ++a) {
    for (Index b = _box_Nb; b < 2 * _box_Nb; ++b) {
      for (Index c = _box_Nc; c < 2 * _box_Nc; ++c) {
        cell_t &cell = getCell(a % _box_Na, b % _box_Nb, c % _box_Nc);
        for (Index aa = a + a1; aa <= a + a2; ++aa) {
          for (Index bb = b + b1; bb <= b + b2; ++bb) {
            for (Index cc = c + c1; cc <= c + c2; ++cc) {
              cell_t *cell2 =
                  &getCell(aa % _box_Na, bb % _box_Nb, cc % _box_Nc);
              if (cell2 == &cell) {
                continue;  // ignore self
              }
              cell._neighbours.push_back(
                  &getCell(aa % _box_Na, bb % _box_Nb, cc % _box_Nc));
            }
          }
        }
      }
    }
  }
}

NBListGrid::cell_t &NBListGrid::getCell(const Eigen::Vector3d &r) {
  Index a = (Index)floor(r.dot(_norm_a));
  Index b = (Index)floor(r.dot(_norm_b));
  Index c = (Index)floor(r.dot(_norm_c));

  if (a < 0) {
    a = _box_Na + a % _box_Na;
  }
  a %= _box_Na;

  if (b < 0) {
    b = _box_Nb + b % _box_Nb;
  }
  b %= _box_Nb;

  if (c < 0) {
    c = _box_Nc + c % _box_Nc;
  }
  c %= _box_Nc;

  return getCell(a, b, c);
}

void NBListGrid::TestBead(NBListGrid::cell_t &cell, Bead *bead) {
  TestCell(cell, bead);
  for (auto &neighbour : cell._neighbours) {
    TestCell(*neighbour, bead);
  }
}

void NBListGrid::TestCell(NBListGrid::cell_t &cell, Bead *bead) {
  Eigen::Vector3d u = bead->getPos();

  for (auto &_bead : cell._beads) {

    Eigen::Vector3d v = _bead->getPos();
    Eigen::Vector3d r = _top->BCShortestConnection(v, u);
    double d = r.norm();
    if (d < _cutoff) {
      if (_do_exclusions) {
        if (_top->getExclusions().IsExcluded(_bead, bead)) {
          continue;
        }
      }
      if ((*_match_function)(_bead, bead, r, d)) {
        if (!FindPair(_bead, bead)) {
          AddPair(_pair_creator(_bead, bead, r));
        }
      }
    }
  }
}

}  // namespace csg
}  // namespace votca
<|endoftext|>


<commit_before>/************************************
** No Bullsh*t Command Line Parser **
** nbcl.cpp                        **
** Copyright 2011-2012 OmegaSDG    **
************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

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

#include "nbcl.h"

NBCL::NBCL(int argc, char** argv) :
	argc(argc), argv(argv), strayArgsDesc("")
{
}

NBCL::~NBCL()
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++)
		delete OptList[opt];
}

void NBCL::insert(std::string shortopt, std::string longopt,
	std::string arg, std::string desc)
{
	Option* opt = new Option;
	opt->shortopt = shortopt;
	opt->longopt = longopt;
	opt->arg = arg;
	opt->desc = desc;
	opt->present = false;
	opt->value = "";
	OptList.push_back(opt);
}

void NBCL::setStrayArgsDesc(std::string desc)
{
	strayArgsDesc = desc;
}

bool NBCL::parse()
{
	int argn;
	int opt;

	for (argn = 1; argn < argc; argn++) { /* Read command line. */
		opt = findOpt(argv[argn]);
		if (opt!=-1) { /* This argument is an option switch. */
			if (!OptList[opt]->arg.empty()) { /* It takes an argument. */
				if (argn + 1 < argc) {
					OptList[opt]->value = argv[argn+1]; /* Add next argument as the option value. */
					argn++;
				}
				else
					return false;
			}
			OptList[opt]->present = true; /* Tell the option it exists. */
		}
		else if (argv[argn][0] == '-') /* Nonexistent option. */
			return false;
		else /* This argument is a stray. */
			strayArgsList.push_back(argv[argn]);
	}
	return true;
}

bool NBCL::check(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->present;
	else
		return false;
}

std::string NBCL::get(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->value;
	else
		return "";
}

void NBCL::usage()
{
	int optmax = 0;
	int argmax = 0;

	usageSize(&optmax, &argmax);
	usagePrintShort();
	usagePrintLong(optmax, argmax);
}

std::vector<std::string> NBCL::getStrayArgsList()
{
	return strayArgsList;
}

/* Makes width calculations needed for formatting usage output. */
void NBCL::usageSize(int* optmax, int* argmax)
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++) {
		if (OptList[opt]->shortopt.size() + OptList[opt]->longopt.size() > (unsigned)*optmax)
			*optmax = (int)OptList[opt]->shortopt.size() + (int)OptList[opt]->longopt.size() + 1;

		if ((int)OptList[opt]->arg.size() > *argmax)
			*argmax = (int)OptList[opt]->arg.size();
	}
}

void NBCL::usagePrintShort()
{
	#ifdef _WIN32
		char fname[_MAX_FNAME];
		char ext[_MAX_EXT];
		_splitpath(argv[0], NULL, NULL, fname, ext);
		if (ext[strlen(ext)-1] == ' ') /* Windows thinks I want a space at the end. It's wrong. */
			ext[strlen(ext)-1] = 0;
		fprintf(stderr, "Usage: %s%s [OPTIONS] ", fname, ext);
	#else
		fprintf(stderr, "Usage: %s [OPTIONS] ", argv[0]);
	#endif
	fprintf(stderr, strayArgsDesc.c_str());
}

/* Lots of ugly formatting code. */
void NBCL::usagePrintLong(int optmax, int argmax)
{
	unsigned int opt;

	fprintf(stderr, "\n\nAvailable options:\n");

	for (opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.empty())
			fprintf(stderr, "  %s,", OptList[opt]->shortopt.c_str());
		else
			fprintf(stderr, "     ");

		fprintf(stderr, (std::string("%-")+itostr(optmax+1)+"s").c_str(), OptList[opt]->longopt.c_str());

		if (!OptList[opt]->arg.empty())
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"s").c_str(), OptList[opt]->arg.c_str());
		else
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"c").c_str(), ' ');

		fprintf(stderr, "%s\n", OptList[opt]->desc.c_str());
	}
}

std::string NBCL::itostr(int in)
{
	std::stringstream out;
	out << in;
	return out.str();
}

int NBCL::findOpt(std::string name)
{
	for (unsigned int opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.compare(name) ||
			!OptList[opt]->longopt.compare(name))
				return opt;
	}
	return -1;
}

/* Thanks to:
 * http://stackoverflow.com/questions/1022957
 * http://stackoverflow.com/questions/6812224
*/
/* TODO: Use for breaking lines on small consoles. */
unsigned int NBCL::getConsoleWidth()
{
	#if defined __unix__ || defined __APPLE__
		struct winsize w;
		ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
		return (unsigned int)w.ws_col;
	#elif _WIN32
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		int ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
		if (ret)
			return (unsigned int)csbi.dwSize.X;
		else
			return 0; /* Failure */
	#else
		return 0; /* Failure */
	#endif
}

<commit_msg>Fix potential stack smash.<commit_after>/************************************
** No Bullsh*t Command Line Parser **
** nbcl.cpp                        **
** Copyright 2011-2012 OmegaSDG    **
************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

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

#include "nbcl.h"

NBCL::NBCL(int argc, char** argv) :
	argc(argc), argv(argv), strayArgsDesc("")
{
}

NBCL::~NBCL()
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++)
		delete OptList[opt];
}

void NBCL::insert(std::string shortopt, std::string longopt,
	std::string arg, std::string desc)
{
	Option* opt = new Option;
	opt->shortopt = shortopt;
	opt->longopt = longopt;
	opt->arg = arg;
	opt->desc = desc;
	opt->present = false;
	opt->value = "";
	OptList.push_back(opt);
}

void NBCL::setStrayArgsDesc(std::string desc)
{
	strayArgsDesc = desc;
}

bool NBCL::parse()
{
	int argn;
	int opt;

	for (argn = 1; argn < argc; argn++) { /* Read command line. */
		opt = findOpt(argv[argn]);
		if (opt!=-1) { /* This argument is an option switch. */
			if (!OptList[opt]->arg.empty()) { /* It takes an argument. */
				if (argn + 1 < argc) {
					OptList[opt]->value = argv[argn+1]; /* Add next argument as the option value. */
					argn++;
				}
				else
					return false;
			}
			OptList[opt]->present = true; /* Tell the option it exists. */
		}
		else if (argv[argn][0] == '-') /* Nonexistent option. */
			return false;
		else /* This argument is a stray. */
			strayArgsList.push_back(argv[argn]);
	}
	return true;
}

bool NBCL::check(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->present;
	else
		return false;
}

std::string NBCL::get(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->value;
	else
		return "";
}

void NBCL::usage()
{
	int optmax = 0;
	int argmax = 0;

	usageSize(&optmax, &argmax);
	usagePrintShort();
	usagePrintLong(optmax, argmax);
}

std::vector<std::string> NBCL::getStrayArgsList()
{
	return strayArgsList;
}

/* Makes width calculations needed for formatting usage output. */
void NBCL::usageSize(int* optmax, int* argmax)
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++) {
		if (OptList[opt]->shortopt.size() + OptList[opt]->longopt.size() > (unsigned)*optmax)
			*optmax = (int)OptList[opt]->shortopt.size() + (int)OptList[opt]->longopt.size() + 1;

		if ((int)OptList[opt]->arg.size() > *argmax)
			*argmax = (int)OptList[opt]->arg.size();
	}
}

void NBCL::usagePrintShort()
{
	#ifdef _WIN32
		char fname[_MAX_FNAME];
		char ext[_MAX_EXT];
		_splitpath(argv[0], NULL, NULL, fname, ext);
		if (ext[strlen(ext)-1] == ' ') /* Windows thinks I want a space at the end. It's wrong. */
			ext[strlen(ext)-1] = 0;
		fprintf(stderr, "Usage: %s%s [OPTIONS] ", fname, ext);
	#else
		fprintf(stderr, "Usage: %s [OPTIONS] ", argv[0]);
	#endif
	fprintf(stderr, "%s", strayArgsDesc.c_str());
}

/* Lots of ugly formatting code. */
void NBCL::usagePrintLong(int optmax, int argmax)
{
	unsigned int opt;

	fprintf(stderr, "\n\nAvailable options:\n");

	for (opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.empty())
			fprintf(stderr, "  %s,", OptList[opt]->shortopt.c_str());
		else
			fprintf(stderr, "     ");

		fprintf(stderr, (std::string("%-")+itostr(optmax+1)+"s").c_str(), OptList[opt]->longopt.c_str());

		if (!OptList[opt]->arg.empty())
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"s").c_str(), OptList[opt]->arg.c_str());
		else
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"c").c_str(), ' ');

		fprintf(stderr, "%s\n", OptList[opt]->desc.c_str());
	}
}

std::string NBCL::itostr(int in)
{
	std::stringstream out;
	out << in;
	return out.str();
}

int NBCL::findOpt(std::string name)
{
	for (unsigned int opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.compare(name) ||
			!OptList[opt]->longopt.compare(name))
				return opt;
	}
	return -1;
}

/* Thanks to:
 * http://stackoverflow.com/questions/1022957
 * http://stackoverflow.com/questions/6812224
*/
/* TODO: Use for breaking lines on small consoles. */
unsigned int NBCL::getConsoleWidth()
{
	#if defined __unix__ || defined __APPLE__
		struct winsize w;
		ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
		return (unsigned int)w.ws_col;
	#elif _WIN32
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		int ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
		if (ret)
			return (unsigned int)csbi.dwSize.X;
		else
			return 0; /* Failure */
	#else
		return 0; /* Failure */
	#endif
}

<|endoftext|>


<commit_before>#include "MemoryUtils.h"
#include "Integer64.h"

uint32 MemoryUtils_GetByteProxy(CMIPS* pCtx, uint32 nAddress)
{
	return (uint32)pCtx->m_pMemoryMap->GetByte(nAddress);
}

uint32 MemoryUtils_GetHalfProxy(CMIPS* pCtx, uint32 nAddress)
{
	return (uint32)pCtx->m_pMemoryMap->GetHalf(nAddress);
}

uint32 MemoryUtils_GetWordProxy(CMIPS* pCtx, uint32 nAddress)
{
	return pCtx->m_pMemoryMap->GetWord(nAddress);
}

uint64 MemoryUtils_GetDoubleProxy(CMIPS* context, uint32 address)
{
	assert((address & 0x07) == 0);
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetReadMap(address);
	INTEGER64 result;
#ifdef _DEBUG
	result.q = 0xCCCCCCCCCCCCCCCCull;
#endif
	if(e != NULL)
	{
		switch(e->nType)
		{
		case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
			result.q = *reinterpret_cast<uint64*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart));
			break;
		case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
			for(unsigned int i = 0; i < 2; i++)
			{
				result.d[i] = e->handler(address + (i * 4), 0);
			}
			break;
		default:
			assert(0);
			break;
		}
	}
	return result.q;
}

uint128 MemoryUtils_GetQuadProxy(CMIPS* context, uint32 address)
{
	assert((address & 0x0F) == 0);
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetReadMap(address);
	uint128 result;
#ifdef _DEBUG
	memset(&result, 0xCC, sizeof(result));
#endif
	if(e != NULL)
	{
		switch(e->nType)
		{
		case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
			result = *reinterpret_cast<uint128*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart));
			break;
		case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
			for(unsigned int i = 0; i < 4; i++)
			{
				result.nV[i] = e->handler(address + (i * 4), 0);
			}
			break;
		default:
			assert(0);
			break;
		}
	}
	return result;
}

void MemoryUtils_SetByteProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetByte(nAddress, (uint8)(nValue & 0xFF));
}

void MemoryUtils_SetHalfProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetHalf(nAddress, (uint16)(nValue & 0xFFFF));
}

void MemoryUtils_SetWordProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetWord(nAddress, nValue);
}

void MemoryUtils_SetDoubleProxy(CMIPS* context, uint64 value64, uint32 address)
{
	assert((address & 0x07) == 0);
	INTEGER64 value;
	value.q = value64;
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetWriteMap(address);
	if(e == NULL)
	{
		printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, [0x%0.8X, 0x%0.8X]).\r\n",
			address, value.d0, value.d1);
		return;
	}
	switch(e->nType)
	{
	case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
		*reinterpret_cast<uint64*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart)) = value.q;
		break;
	case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
		for(unsigned int i = 0; i < 2; i++)
		{
			e->handler(address + (i * 4), value.d[i]);
		}
		break;
	default:
		assert(0);
		break;
	}
}

void MemoryUtils_SetQuadProxy(CMIPS* context, const uint128& value, uint32 address)
{
	assert((address & 0x0F) == 0);
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetWriteMap(address);
	if(e == NULL)
	{
		printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, [0x%0.8X, 0x%0.8X, 0x%0.8X, 0x%0.8X]).\r\n",
			address, value.nV0, value.nV1, value.nV2, value.nV3);
		return;
	}
	switch(e->nType)
	{
	case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
		*reinterpret_cast<uint128*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart)) = value;
		break;
	case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
		for(unsigned int i = 0; i < 4; i++)
		{
			e->handler(address + (i * 4), value.nV[i]);
		}
		break;
	default:
		assert(0);
		break;
	}
}
<commit_msg>Read quadwords from unaligned addresses properly.<commit_after>#include "MemoryUtils.h"
#include "Integer64.h"

uint32 MemoryUtils_GetByteProxy(CMIPS* pCtx, uint32 nAddress)
{
	return (uint32)pCtx->m_pMemoryMap->GetByte(nAddress);
}

uint32 MemoryUtils_GetHalfProxy(CMIPS* pCtx, uint32 nAddress)
{
	return (uint32)pCtx->m_pMemoryMap->GetHalf(nAddress);
}

uint32 MemoryUtils_GetWordProxy(CMIPS* pCtx, uint32 nAddress)
{
	return pCtx->m_pMemoryMap->GetWord(nAddress);
}

uint64 MemoryUtils_GetDoubleProxy(CMIPS* context, uint32 address)
{
	assert((address & 0x07) == 0);
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetReadMap(address);
	INTEGER64 result;
#ifdef _DEBUG
	result.q = 0xCCCCCCCCCCCCCCCCull;
#endif
	if(e != NULL)
	{
		switch(e->nType)
		{
		case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
			result.q = *reinterpret_cast<uint64*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart));
			break;
		case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
			for(unsigned int i = 0; i < 2; i++)
			{
				result.d[i] = e->handler(address + (i * 4), 0);
			}
			break;
		default:
			assert(0);
			break;
		}
	}
	return result.q;
}

uint128 MemoryUtils_GetQuadProxy(CMIPS* context, uint32 address)
{
	address &= ~0x0F;
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetReadMap(address);
	uint128 result;
#ifdef _DEBUG
	memset(&result, 0xCC, sizeof(result));
#endif
	if(e != NULL)
	{
		switch(e->nType)
		{
		case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
			result = *reinterpret_cast<uint128*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart));
			break;
		case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
			for(unsigned int i = 0; i < 4; i++)
			{
				result.nV[i] = e->handler(address + (i * 4), 0);
			}
			break;
		default:
			assert(0);
			break;
		}
	}
	return result;
}

void MemoryUtils_SetByteProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetByte(nAddress, (uint8)(nValue & 0xFF));
}

void MemoryUtils_SetHalfProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetHalf(nAddress, (uint16)(nValue & 0xFFFF));
}

void MemoryUtils_SetWordProxy(CMIPS* pCtx, uint32 nValue, uint32 nAddress)
{
	pCtx->m_pMemoryMap->SetWord(nAddress, nValue);
}

void MemoryUtils_SetDoubleProxy(CMIPS* context, uint64 value64, uint32 address)
{
	assert((address & 0x07) == 0);
	INTEGER64 value;
	value.q = value64;
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetWriteMap(address);
	if(e == NULL)
	{
		printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, [0x%0.8X, 0x%0.8X]).\r\n",
			address, value.d0, value.d1);
		return;
	}
	switch(e->nType)
	{
	case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
		*reinterpret_cast<uint64*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart)) = value.q;
		break;
	case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
		for(unsigned int i = 0; i < 2; i++)
		{
			e->handler(address + (i * 4), value.d[i]);
		}
		break;
	default:
		assert(0);
		break;
	}
}

void MemoryUtils_SetQuadProxy(CMIPS* context, const uint128& value, uint32 address)
{
	assert((address & 0x0F) == 0);
	const CMemoryMap::MEMORYMAPELEMENT* e = context->m_pMemoryMap->GetWriteMap(address);
	if(e == NULL)
	{
		printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, [0x%0.8X, 0x%0.8X, 0x%0.8X, 0x%0.8X]).\r\n",
			address, value.nV0, value.nV1, value.nV2, value.nV3);
		return;
	}
	switch(e->nType)
	{
	case CMemoryMap::MEMORYMAP_TYPE_MEMORY:
		*reinterpret_cast<uint128*>(reinterpret_cast<uint8*>(e->pPointer) + (address - e->nStart)) = value;
		break;
	case CMemoryMap::MEMORYMAP_TYPE_FUNCTION:
		for(unsigned int i = 0; i < 4; i++)
		{
			e->handler(address + (i * 4), value.nV[i]);
		}
		break;
	default:
		assert(0);
		break;
	}
}
<|endoftext|>


<commit_before>#pragma once

#include "Defs.hpp"
#include <string>

struct EscapeCodeGenerator {

    using EscapeCode = std::string;

    virtual EscapeCode cursorForward(int) const { return EscapeCode{}; }
    virtual EscapeCode cursorBackward(int) const { return EscapeCode{}; }
    virtual EscapeCode clearTerminalLine() const { return EscapeCode{}; }
    virtual EscapeCode setColor(Color) const { return EscapeCode{}; }

};

struct ANSIEscapeCodeGenerator : public EscapeCodeGenerator {

    EscapeCode cursorForward(int n) const override {
        if (!n) return EscapeCode{};
        EscapeCode a{"\033["};
        a += std::to_string(n);
        a += 'C';
        return a;
    }

    EscapeCode cursorBackward(int n) const override {
        if (!n) return EscapeCode{};
        EscapeCode a{"\033["};
        a += std::to_string(n);
        a += 'D';
        return a;
    }

    EscapeCode clearTerminalLine() const override {
        return EscapeCode{"\033[K"};
    }

    EscapeCode setColor(Color color) const override {
        EscapeCode a{"\033["};
        a += std::to_string(static_cast<int>(color));
        a += 'm';
        return a;
    }

};

<commit_msg>Minor changes<commit_after>#pragma once

#include "Defs.hpp"
#include <string>

struct EscapeCodeGenerator {

    using EscapeCode = std::string;

    virtual EscapeCode cursorForward(int) const { return EscapeCode{}; }
    virtual EscapeCode cursorBackward(int) const { return EscapeCode{}; }
    virtual EscapeCode clearTerminalLine() const { return EscapeCode{}; }
    virtual EscapeCode setColor(Color) const { return EscapeCode{}; }

};

struct ANSIEscapeCodeGenerator final : EscapeCodeGenerator {

    EscapeCode cursorForward(int n) const override {
        if (!n) return EscapeCode{};
        EscapeCode a{"\033["};
        a += std::to_string(n);
        a += 'C';
        return a;
    }

    EscapeCode cursorBackward(int n) const override {
        if (!n) return EscapeCode{};
        EscapeCode a{"\033["};
        a += std::to_string(n);
        a += 'D';
        return a;
    }

    EscapeCode clearTerminalLine() const override {
        return EscapeCode{"\033[K"};
    }

    EscapeCode setColor(Color color) const override {
        EscapeCode a{"\033["};
        a += std::to_string(static_cast<int>(color));
        a += 'm';
        return a;
    }

};

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cloneable.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-07 16:07:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef FORMS_COMPONENT_CLONEABLE_HXX
#include "cloneable.hxx"
#endif

#ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_
#include <com/sun/star/util/XCloneable.hpp>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................

    using namespace ::comphelper;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::util;

    //====================================================================
    //= OCloneableAggregation
    //====================================================================
    //------------------------------------------------------------------
    Reference< XAggregation > OCloneableAggregation::createAggregateClone( const OCloneableAggregation* _pOriginal )
    {
        Reference< XCloneable > xAggregateCloneable;    // will be the aggregate's XCloneable
        Reference< XAggregation > xAggregateClone;      // will be the aggregate's clone

        if ( query_aggregation( _pOriginal->m_xAggregate, xAggregateCloneable ) )
        {
            xAggregateClone = xAggregateClone.query( xAggregateCloneable->createClone() );
            DBG_ASSERT( xAggregateClone.is(), "OCloneableAggregation::createAggregateClone: invalid clone returned by the aggregate!" );
        }
        else
            DBG_ASSERT( !_pOriginal->m_xAggregate.is(), "OCloneableAggregation::createAggregateClone: aggregate is not cloneable!" );

        return xAggregateClone;
    }

//.........................................................................
}   // namespace frm
//.........................................................................

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.146); FILE MERGED 2005/09/05 13:50:27 rt 1.3.146.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cloneable.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:47:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef FORMS_COMPONENT_CLONEABLE_HXX
#include "cloneable.hxx"
#endif

#ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_
#include <com/sun/star/util/XCloneable.hpp>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................

    using namespace ::comphelper;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::util;

    //====================================================================
    //= OCloneableAggregation
    //====================================================================
    //------------------------------------------------------------------
    Reference< XAggregation > OCloneableAggregation::createAggregateClone( const OCloneableAggregation* _pOriginal )
    {
        Reference< XCloneable > xAggregateCloneable;    // will be the aggregate's XCloneable
        Reference< XAggregation > xAggregateClone;      // will be the aggregate's clone

        if ( query_aggregation( _pOriginal->m_xAggregate, xAggregateCloneable ) )
        {
            xAggregateClone = xAggregateClone.query( xAggregateCloneable->createClone() );
            DBG_ASSERT( xAggregateClone.is(), "OCloneableAggregation::createAggregateClone: invalid clone returned by the aggregate!" );
        }
        else
            DBG_ASSERT( !_pOriginal->m_xAggregate.is(), "OCloneableAggregation::createAggregateClone: aggregate is not cloneable!" );

        return xAggregateClone;
    }

//.........................................................................
}   // namespace frm
//.........................................................................

<|endoftext|>


<commit_before>#include "Tab.h"

#include "UIContext.h"

Tab::Tab() {

}

Tab::~Tab() {
    delete _ctxt;
}

DLGPROC Tab::TabProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
    unsigned short nCode, ctrlId;

    switch (message) {
    case WM_INITDIALOG:
        _hWnd = hDlg;
        _ctxt = new UIContext(hDlg);
        LoadSettings();
        return FALSE;

    case WM_COMMAND:
        PropSheet_Changed(GetParent(hDlg), NULL);
        nCode = HIWORD(wParam);
        ctrlId = LOWORD(wParam);
        return Command(nCode, ctrlId);

    case WM_NOTIFY:
        NMHDR *nHdr = (NMHDR *) lParam;
        return Notification(nHdr);
    }

    return FALSE;
}<commit_msg>Call initialize method during WM_INITDIALOG<commit_after>#include "Tab.h"

#include "UIContext.h"

Tab::Tab() {

}

Tab::~Tab() {
    delete _ctxt;
}

DLGPROC Tab::TabProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
    unsigned short nCode, ctrlId;

    switch (message) {
    case WM_INITDIALOG:
        _hWnd = hDlg;
        _ctxt = new UIContext(hDlg);
        Initialize();
        LoadSettings();
        return FALSE;

    case WM_COMMAND:
        PropSheet_Changed(GetParent(hDlg), NULL);
        nCode = HIWORD(wParam);
        ctrlId = LOWORD(wParam);
        return Command(nCode, ctrlId);

    case WM_NOTIFY:
        NMHDR *nHdr = (NMHDR *) lParam;
        return Notification(nHdr);
    }

    return FALSE;
}<|endoftext|>