<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP

#include <mapnik/renderer_common.hpp>
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/marker_helpers.hpp>

namespace mapnik {

template <typename VD, typename RD, typename RendererType, typename ContextType>
struct render_marker_symbolizer_visitor
{
    using vector_dispatch_type = VD;
    using raster_dispatch_type = RD;
    using buffer_type = typename std::tuple_element<0,ContextType>::type;

    render_marker_symbolizer_visitor(std::string const& filename,
                                     markers_symbolizer const& sym,
                                     mapnik::feature_impl & feature,
                                     proj_transform const& prj_trans,
                                     RendererType & common,
                                     box2d<double> const& clip_box,
                                     ContextType const& renderer_context)
        : filename_(filename),
          sym_(sym),
          feature_(feature),
          prj_trans_(prj_trans),
          common_(common),
          clip_box_(clip_box),
          renderer_context_(renderer_context) {}

    void operator() (marker_null const&) {}

    void operator() (marker_svg const& mark)
    {
        using namespace mapnik::svg;
        bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        // https://github.com/mapnik/mapnik/issues/1316
        bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_);

        agg::trans_affine geom_tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        boost::optional<svg_path_ptr> const& stock_vector_marker = mark.get_data();

        // special case for simple ellipse markers
        // to allow for full control over rx/ry dimensions
        if (filename_ == "shape://ellipse"
           && (has_key(sym_,keys::width) || has_key(sym_,keys::height)))
        {
            svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
            vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
            svg_path_adapter svg_path(stl_storage);
            build_ellipse(sym_, feature_, common_.vars_, *marker_ellipse, svg_path);
            svg_attribute_type attributes;
            bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
            auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
            if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
            vector_dispatch_type rasterizer_dispatch(marker_ellipse,
                                                     svg_path,
                                                     result ? attributes : (*stock_vector_marker)->attributes(),
                                                     image_tr,
                                                     sym_,
                                                     *common_.detector_,
                                                     common_.scale_factor_,
                                                     feature_,
                                                     common_.vars_,
                                                     snap_to_pixels,
                                                     renderer_context_,
                                                     common_.symbol_cache_);

            using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
                                          clip_poly_tag,
                                          transform_tag,
                                          affine_transform_tag,
                                          simplify_tag, smooth_tag,
                                          offset_transform_tag>;
            vertex_converter_type converter(clip_box_,
                                            rasterizer_dispatch,
                                            sym_,
                                            common_.t_,
                                            prj_trans_,
                                            geom_tr,
                                            feature_,
                                            common_.vars_,
                                            common_.scale_factor_);
            if (clip && feature_.paths().size() > 0) // optional clip (default: true)
            {
                geometry_type::types type = feature_.paths()[0].type();
                if (type == geometry_type::types::Polygon)
                    converter.template set<clip_poly_tag>();
                else if (type == geometry_type::types::LineString)
                    converter.template set<clip_line_tag>();
            }
            converter.template set<transform_tag>(); //always transform
            if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
            converter.template set<affine_transform_tag>(); // optional affine transform
            if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
            if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
            apply_markers_multi(feature_, common_.vars_, converter, sym_);
        }
        else
        {
            box2d<double> const& bbox = mark.bounding_box();
            setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature_, common_.vars_, sym_);
            auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
            if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
            vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
            svg_path_adapter svg_path(stl_storage);
            svg_attribute_type attributes;
            bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
            vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
                                                     svg_path,
                                                     result ? attributes : (*stock_vector_marker)->attributes(),
                                                     image_tr,
                                                     sym_,
                                                     *common_.detector_,
                                                     common_.scale_factor_,
                                                     feature_,
                                                     common_.vars_,
                                                     snap_to_pixels,
                                                     renderer_context_,
                                                     common_.symbol_cache_);

            using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
                                          clip_poly_tag,
                                          transform_tag,
                                          affine_transform_tag,
                                          simplify_tag, smooth_tag,
                                          offset_transform_tag>;
            vertex_converter_type converter(clip_box_,
                                            rasterizer_dispatch,
                                            sym_,
                                            common_.t_,
                                            prj_trans_,
                                            geom_tr,
                                            feature_,
                                            common_.vars_,
                                            common_.scale_factor_);
            if (clip && feature_.paths().size() > 0) // optional clip (default: true)
            {
                geometry_type::types type = feature_.paths()[0].type();
                if (type == geometry_type::types::Polygon)
                    converter.template set<clip_poly_tag>();
                else if (type == geometry_type::types::LineString)
                    converter.template set<clip_line_tag>();
            }
            converter.template set<transform_tag>(); //always transform
            if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
            converter.template set<affine_transform_tag>(); // optional affine transform
            if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
            if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
            apply_markers_multi(feature_, common_.vars_, converter, sym_);
        }
    }

    void operator() (marker_rgba8 const& mark)
    {
        using namespace mapnik::svg;
        bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::trans_affine geom_tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
        auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
        box2d<double> const& bbox = mark.bounding_box();
        mapnik::image_rgba8 const& marker = mark.get_data();
        // - clamp sizes to > 4 pixels of interactivity
        coord2d center = bbox.center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine marker_trans = recenter * image_tr;
        raster_dispatch_type rasterizer_dispatch(marker,
                                                 marker_trans,
                                                 sym_,
                                                 *common_.detector_,
                                                 common_.scale_factor_,
                                                 feature_,
                                                 common_.vars_,
                                                 renderer_context_,
                                                 common_.symbol_cache_);

        using vertex_converter_type = vertex_converter<raster_dispatch_type,clip_line_tag,
                                      clip_poly_tag,
                                      transform_tag,
                                      affine_transform_tag,
                                      simplify_tag, smooth_tag,
                                      offset_transform_tag>;
        vertex_converter_type converter(clip_box_,
                                        rasterizer_dispatch,
                                        sym_,
                                        common_.t_,
                                        prj_trans_,
                                        geom_tr,
                                        feature_,
                                        common_.vars_,
                                        common_.scale_factor_);

        if (clip && feature_.paths().size() > 0) // optional clip (default: true)
        {
            geometry_type::types type = feature_.paths()[0].type();
            if (type == geometry_type::types::Polygon)
                converter.template set<clip_poly_tag>();
            else if (type == geometry_type::types::LineString)
                converter.template set<clip_line_tag>();
        }
        converter.template set<transform_tag>(); //always transform
        if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
        converter.template set<affine_transform_tag>(); // optional affine transform
        if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
        if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
        apply_markers_multi(feature_, common_.vars_, converter, sym_);
    }

  private:
    std::string const& filename_;
    markers_symbolizer const& sym_;
    mapnik::feature_impl & feature_;
    proj_transform const& prj_trans_;
    RendererType & common_;
    box2d<double> const& clip_box_;
    ContextType const& renderer_context_;
};

template <typename VD, typename RD, typename RendererType, typename ContextType>
void render_markers_symbolizer(markers_symbolizer const& sym,
                               mapnik::feature_impl & feature,
                               proj_transform const& prj_trans,
                               RendererType & common,
                               box2d<double> const& clip_box,
                               ContextType const& renderer_context)
{
    using namespace mapnik::svg;
    std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
    if (!filename.empty())
    {
        mapnik::marker const& mark = mapnik::marker_cache::instance().find(filename, true);
        render_marker_symbolizer_visitor<VD,RD,RendererType,ContextType> visitor(filename,
                                         sym,
                                         feature,
                                         prj_trans,
                                         common,
                                         clip_box,
                                         renderer_context);
        util::apply_visitor(visitor, mark);
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
<commit_msg>remove trailing whitespace<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP

#include <mapnik/renderer_common.hpp>
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/marker_helpers.hpp>

namespace mapnik {

template <typename VD, typename RD, typename RendererType, typename ContextType>
struct render_marker_symbolizer_visitor
{
    using vector_dispatch_type = VD;
    using raster_dispatch_type = RD;
    using buffer_type = typename std::tuple_element<0,ContextType>::type;

    render_marker_symbolizer_visitor(std::string const& filename,
                                     markers_symbolizer const& sym,
                                     mapnik::feature_impl & feature,
                                     proj_transform const& prj_trans,
                                     RendererType & common,
                                     box2d<double> const& clip_box,
                                     ContextType const& renderer_context)
        : filename_(filename),
          sym_(sym),
          feature_(feature),
          prj_trans_(prj_trans),
          common_(common),
          clip_box_(clip_box),
          renderer_context_(renderer_context) {}

    void operator() (marker_null const&) {}

    void operator() (marker_svg const& mark)
    {
        using namespace mapnik::svg;
        bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        // https://github.com/mapnik/mapnik/issues/1316
        bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_);

        agg::trans_affine geom_tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        boost::optional<svg_path_ptr> const& stock_vector_marker = mark.get_data();

        // special case for simple ellipse markers
        // to allow for full control over rx/ry dimensions
        if (filename_ == "shape://ellipse"
           && (has_key(sym_,keys::width) || has_key(sym_,keys::height)))
        {
            svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
            vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
            svg_path_adapter svg_path(stl_storage);
            build_ellipse(sym_, feature_, common_.vars_, *marker_ellipse, svg_path);
            svg_attribute_type attributes;
            bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
            auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
            if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
            vector_dispatch_type rasterizer_dispatch(marker_ellipse,
                                                     svg_path,
                                                     result ? attributes : (*stock_vector_marker)->attributes(),
                                                     image_tr,
                                                     sym_,
                                                     *common_.detector_,
                                                     common_.scale_factor_,
                                                     feature_,
                                                     common_.vars_,
                                                     snap_to_pixels,
                                                     renderer_context_,
                                                     common_.symbol_cache_);

            using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
                                          clip_poly_tag,
                                          transform_tag,
                                          affine_transform_tag,
                                          simplify_tag, smooth_tag,
                                          offset_transform_tag>;
            vertex_converter_type converter(clip_box_,
                                            rasterizer_dispatch,
                                            sym_,
                                            common_.t_,
                                            prj_trans_,
                                            geom_tr,
                                            feature_,
                                            common_.vars_,
                                            common_.scale_factor_);
            if (clip && feature_.paths().size() > 0) // optional clip (default: true)
            {
                geometry_type::types type = feature_.paths()[0].type();
                if (type == geometry_type::types::Polygon)
                    converter.template set<clip_poly_tag>();
                else if (type == geometry_type::types::LineString)
                    converter.template set<clip_line_tag>();
            }
            converter.template set<transform_tag>(); //always transform
            if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
            converter.template set<affine_transform_tag>(); // optional affine transform
            if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
            if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
            apply_markers_multi(feature_, common_.vars_, converter, sym_);
        }
        else
        {
            box2d<double> const& bbox = mark.bounding_box();
            setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature_, common_.vars_, sym_);
            auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
            if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
            vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
            svg_path_adapter svg_path(stl_storage);
            svg_attribute_type attributes;
            bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
            vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
                                                     svg_path,
                                                     result ? attributes : (*stock_vector_marker)->attributes(),
                                                     image_tr,
                                                     sym_,
                                                     *common_.detector_,
                                                     common_.scale_factor_,
                                                     feature_,
                                                     common_.vars_,
                                                     snap_to_pixels,
                                                     renderer_context_,
                                                     common_.symbol_cache_);

            using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
                                          clip_poly_tag,
                                          transform_tag,
                                          affine_transform_tag,
                                          simplify_tag, smooth_tag,
                                          offset_transform_tag>;
            vertex_converter_type converter(clip_box_,
                                            rasterizer_dispatch,
                                            sym_,
                                            common_.t_,
                                            prj_trans_,
                                            geom_tr,
                                            feature_,
                                            common_.vars_,
                                            common_.scale_factor_);
            if (clip && feature_.paths().size() > 0) // optional clip (default: true)
            {
                geometry_type::types type = feature_.paths()[0].type();
                if (type == geometry_type::types::Polygon)
                    converter.template set<clip_poly_tag>();
                else if (type == geometry_type::types::LineString)
                    converter.template set<clip_line_tag>();
            }
            converter.template set<transform_tag>(); //always transform
            if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
            converter.template set<affine_transform_tag>(); // optional affine transform
            if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
            if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
            apply_markers_multi(feature_, common_.vars_, converter, sym_);
        }
    }

    void operator() (marker_rgba8 const& mark)
    {
        using namespace mapnik::svg;
        bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::trans_affine geom_tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
        auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
        box2d<double> const& bbox = mark.bounding_box();
        mapnik::image_rgba8 const& marker = mark.get_data();
        // - clamp sizes to > 4 pixels of interactivity
        coord2d center = bbox.center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine marker_trans = recenter * image_tr;
        raster_dispatch_type rasterizer_dispatch(marker,
                                                 marker_trans,
                                                 sym_,
                                                 *common_.detector_,
                                                 common_.scale_factor_,
                                                 feature_,
                                                 common_.vars_,
                                                 renderer_context_,
                                                 common_.symbol_cache_);

        using vertex_converter_type = vertex_converter<raster_dispatch_type,clip_line_tag,
                                      clip_poly_tag,
                                      transform_tag,
                                      affine_transform_tag,
                                      simplify_tag, smooth_tag,
                                      offset_transform_tag>;
        vertex_converter_type converter(clip_box_,
                                        rasterizer_dispatch,
                                        sym_,
                                        common_.t_,
                                        prj_trans_,
                                        geom_tr,
                                        feature_,
                                        common_.vars_,
                                        common_.scale_factor_);

        if (clip && feature_.paths().size() > 0) // optional clip (default: true)
        {
            geometry_type::types type = feature_.paths()[0].type();
            if (type == geometry_type::types::Polygon)
                converter.template set<clip_poly_tag>();
            else if (type == geometry_type::types::LineString)
                converter.template set<clip_line_tag>();
        }
        converter.template set<transform_tag>(); //always transform
        if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
        converter.template set<affine_transform_tag>(); // optional affine transform
        if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
        if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
        apply_markers_multi(feature_, common_.vars_, converter, sym_);
    }

  private:
    std::string const& filename_;
    markers_symbolizer const& sym_;
    mapnik::feature_impl & feature_;
    proj_transform const& prj_trans_;
    RendererType & common_;
    box2d<double> const& clip_box_;
    ContextType const& renderer_context_;
};

template <typename VD, typename RD, typename RendererType, typename ContextType>
void render_markers_symbolizer(markers_symbolizer const& sym,
                               mapnik::feature_impl & feature,
                               proj_transform const& prj_trans,
                               RendererType & common,
                               box2d<double> const& clip_box,
                               ContextType const& renderer_context)
{
    using namespace mapnik::svg;
    std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
    if (!filename.empty())
    {
        mapnik::marker const& mark = mapnik::marker_cache::instance().find(filename, true);
        render_marker_symbolizer_visitor<VD,RD,RendererType,ContextType> visitor(filename,
                                         sym,
                                         feature,
                                         prj_trans,
                                         common,
                                         clip_box,
                                         renderer_context);
        util::apply_visitor(visitor, mark);
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
<|endoftext|>


<commit_before>// ------------------------------------------------------------------------
// audioio-sine.cpp: Sine wave generator
//
// Adaptation to Ecasound:
//
// Copyright (C) 2007,2008 Kai Vehmanen (adaptation to Ecasound)
//
// Sources for sine generation (cmt-src-1.15/src/sine.cpp):
//
// Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
// 2000-2002 Richard W.E. Furse. The author may be contacted at
// richard@muse.demon.co.uk.
//
// Attributes:
//     eca-style-version: 3 (see Ecasound Programmer's Guide)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <algorithm>
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>

#include <math.h> /* C++'s standard <cmath> does not define M_PI */

#include <kvu_message_item.h>
#include <kvu_numtostr.h>
#include <kvu_dbc.h>

#include "eca-object-factory.h"
#include "samplebuffer.h"
#include "audioio-tone.h"

#include "eca-error.h"
#include "eca-logger.h"

/**
 * FIXME notes  (last update 2008-03-06)
 *
 *  - define the syntax: is this 'tone', 'sinetone',
 *    'tone=sine', ..., or?
 *  - add support for multichannel testing (different
 *    frequnecies for different channels?)
 */

using std::cout;
using std::endl;
using std::atof;
using std::string;

/* Sine table size is given by (1 << SINE_TABLE_BITS). */
#define SINE_TABLE_BITS 14
#define SINE_TABLE_SHIFT (8 * sizeof(unsigned long) - SINE_TABLE_BITS)

SAMPLE_SPECS::sample_t *g_pfSineTable = NULL;
SAMPLE_SPECS::sample_t g_fPhaseStepBase = 0;

static void initialise_sine_wavetable(void)
{
  if (g_pfSineTable == NULL) {
    unsigned long lTableSize = (1 << SINE_TABLE_BITS);
    double dShift = (double(M_PI) * 2) / lTableSize;
    g_pfSineTable = new SAMPLE_SPECS::sample_t[lTableSize];
    if (g_pfSineTable != NULL)
      for (unsigned long lIndex = 0; lIndex < lTableSize; lIndex++)
	g_pfSineTable[lIndex] = SAMPLE_SPECS::sample_t(sin(dShift * lIndex));
  }
  if (g_fPhaseStepBase == 0) {
    g_fPhaseStepBase = (SAMPLE_SPECS::sample_t)pow(2, sizeof(unsigned long) * 8);
  }
}

AUDIO_IO_TONE::AUDIO_IO_TONE (const std::string& name)
  :  m_lPhaseStep(0),
     m_fCachedFrequency(0),
     m_fLimitFrequency(0),
     m_fPhaseStepScalar(0)
{
  set_label(name);
  initialise_sine_wavetable();
}

AUDIO_IO_TONE::~AUDIO_IO_TONE(void)
{
}

AUDIO_IO_TONE* AUDIO_IO_TONE::clone(void) const
{
  AUDIO_IO_TONE* target = new AUDIO_IO_TONE();

  for(int n = 0; n < number_of_params(); n++) {
    target->set_parameter(n + 1, get_parameter(n + 1));
  }

  target->set_position_in_samples(position_in_samples());
  if (ECA_AUDIO_POSITION::length_set())
    target->ECA_AUDIO_POSITION::set_length_in_samples(ECA_AUDIO_POSITION::length_in_samples());

  target->buffersize_rep = buffersize_rep;
  target->finished_rep = finished_rep;
  target->m_lPhase = m_lPhase;
  target->m_lPhaseStep = m_lPhaseStep;
  DBC_CHECK(target->m_fCachedFrequency == m_fCachedFrequency);
  target->m_fLimitFrequency = m_fLimitFrequency;
  target->m_fPhaseStepScalar = m_fPhaseStepScalar;

  return target;
}

void AUDIO_IO_TONE::open(void) throw(AUDIO_IO::SETUP_ERROR &)
{
  DBC_CHECK(samples_per_second() != 0);

  if (io_mode() != AUDIO_IO::io_read)
    throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIO_IO_TONE: Writing to tone generator not allowed!"));

  finished_rep = false;
  m_fLimitFrequency
    = SAMPLE_SPECS::sample_t(samples_per_second() * 0.5);
  m_fPhaseStepScalar
    = SAMPLE_SPECS::sample_t(g_fPhaseStepBase / samples_per_second());

  /* recalculate m_fLimitFrequency and mfPhaseStepScalar */
  if (m_fCachedFrequency)
    setPhaseStepFromFrequency(m_fCachedFrequency, true);

  AUDIO_IO::open();
}

void AUDIO_IO_TONE::close(void)
{
  AUDIO_IO::close();
}

bool AUDIO_IO_TONE::finite_length_stream(void) const
{
  return ECA_AUDIO_POSITION::length_set();
}

void AUDIO_IO_TONE::read_buffer(SAMPLE_BUFFER* sbuf)
{
  /* write to sbuf->buffer[ch], similarly as the LADSPA
   * chainops */

  /* FIXME: actually, we should reset the channel count
   *        every time -> we output an 'sbuf' with fixed
   *        number of channels */
  sbuf->number_of_channels(channels());

  /* set the length according to our buffersize */
  if (ECA_AUDIO_POSITION::length_set() &&
      (position_in_samples() + buffersize())
      >= ECA_AUDIO_POSITION::length_in_samples()) {
    /* over requested duration, adjust buffersize */
    sbuf->length_in_samples(ECA_AUDIO_POSITION::length_in_samples()
			    - position_in_samples());
    finished_rep = true;
  }
  else
    sbuf->length_in_samples(buffersize());

  i.init(sbuf);
  i.begin();

#if 0
  ECA_LOG_MSG(ECA_LOGGER::system_objects,
	      "In tone read_buffer().");
#endif

  while(!i.end()) {
    for(int n = 0; n < channels(); n++) {
      if (i.end())
	break;

      *(i.current(n))
	= g_pfSineTable[m_lPhase >> SINE_TABLE_SHIFT];

    }

    m_lPhase += m_lPhaseStep;

    i.next();
  }

  change_position_in_samples(sbuf->length_in_samples());
}

void AUDIO_IO_TONE::write_buffer(SAMPLE_BUFFER* sbuf)
{
  /* NOP */
  DBC_CHECK(false);
}

void AUDIO_IO_TONE::seek_position(void)
{
  /* note: phase must be correct after arbitrary seeks */
  m_lPhase = m_lPhaseStep * position_in_samples();

  if (ECA_AUDIO_POSITION::length_set() == true &&
      position_in_samples() <
      ECA_AUDIO_POSITION::length_in_samples())
    finished_rep = false;
}

void AUDIO_IO_TONE::setPhaseStepFromFrequency(const SAMPLE_SPECS::sample_t fFrequency, bool force)
{
  if (fFrequency != m_fCachedFrequency || force == true) {
    if (fFrequency >= 0 && fFrequency < m_fLimitFrequency)
      m_lPhaseStep = (unsigned long)(m_fPhaseStepScalar * fFrequency);
    else
      m_lPhaseStep = 0;
    m_fCachedFrequency = fFrequency;
  }
}

void AUDIO_IO_TONE::set_parameter(int param,
				  string value)
{
  ECA_LOG_MSG(ECA_LOGGER::user_objects,
	      AUDIO_IO::parameter_set_to_string(param, value));

  switch (param)
    {
    case 1:
      {
	AUDIO_IO::set_parameter (param, value);
	break;
      }
    case 2:
      {
	/* type; only "sine" supported */
	break;
      }
    case 3:
      {
	setPhaseStepFromFrequency (atof(value.c_str()), false);
	break;
      }
    case 4:
      {
	double duration = atof(value.c_str());
	if (duration > 0.0f)
	  ECA_AUDIO_POSITION::set_length_in_seconds(duration);
	break;
      }
    }
}

string AUDIO_IO_TONE::get_parameter(int param) const
{
  switch (param)
    {
    case 1: return AUDIO_IO::get_parameter(param);
    case 2: return "sine";
    case 3: return kvu_numtostr(m_fCachedFrequency);
    case 4:
      {
	if (ECA_AUDIO_POSITION::length_set() == true)
	  return kvu_numtostr(ECA_AUDIO_POSITION::length_in_seconds_exact());
	else
	  return kvu_numtostr(-1.0f);
      }
    default: break;
    }

  return std::string();
}
<commit_msg>Clean up comments and debugging code.<commit_after>// ------------------------------------------------------------------------
// audioio-tone.cpp: Tone generator
//
// Adaptation to Ecasound:
// Copyright (C) 2007,2008 Kai Vehmanen (adaptation to Ecasound)
//
// Sources for sine generation (cmt-src-1.15/src/sine.cpp):
//
// Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
// 2000-2002 Richard W.E. Furse. The author may be contacted at
// richard@muse.demon.co.uk.
//
// Attributes:
//     eca-style-version: 3 (see Ecasound Programmer's Guide)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <algorithm>
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>

#include <math.h> /* C++'s standard <cmath> does not define M_PI */

#include <kvu_message_item.h>
#include <kvu_numtostr.h>
#include <kvu_dbc.h>

#include "eca-object-factory.h"
#include "samplebuffer.h"
#include "audioio-tone.h"

#include "eca-error.h"
#include "eca-logger.h"

/**
 * FIXME notes  (last update 2008-03-06)
 *
 *  - define the syntax: is this 'tone', 'sinetone',
 *    'tone=sine', ..., or?
 *  - add support for multichannel testing (different
 *    frequnecies for different channels?)
 */

using std::cout;
using std::endl;
using std::atof;
using std::string;

/* Sine table size is given by (1 << SINE_TABLE_BITS). */
#define SINE_TABLE_BITS 14
#define SINE_TABLE_SHIFT (8 * sizeof(unsigned long) - SINE_TABLE_BITS)

SAMPLE_SPECS::sample_t *g_pfSineTable = NULL;
SAMPLE_SPECS::sample_t g_fPhaseStepBase = 0;

static void initialise_sine_wavetable(void)
{
  if (g_pfSineTable == NULL) {
    unsigned long lTableSize = (1 << SINE_TABLE_BITS);
    double dShift = (double(M_PI) * 2) / lTableSize;
    g_pfSineTable = new SAMPLE_SPECS::sample_t[lTableSize];
    if (g_pfSineTable != NULL)
      for (unsigned long lIndex = 0; lIndex < lTableSize; lIndex++)
	g_pfSineTable[lIndex] = SAMPLE_SPECS::sample_t(sin(dShift * lIndex));
  }
  if (g_fPhaseStepBase == 0) {
    g_fPhaseStepBase = (SAMPLE_SPECS::sample_t)pow(2, sizeof(unsigned long) * 8);
  }
}

AUDIO_IO_TONE::AUDIO_IO_TONE (const std::string& name)
  :  m_lPhaseStep(0),
     m_fCachedFrequency(0),
     m_fLimitFrequency(0),
     m_fPhaseStepScalar(0)
{
  set_label(name);
  initialise_sine_wavetable();
}

AUDIO_IO_TONE::~AUDIO_IO_TONE(void)
{
}

AUDIO_IO_TONE* AUDIO_IO_TONE::clone(void) const
{
  AUDIO_IO_TONE* target = new AUDIO_IO_TONE();

  for(int n = 0; n < number_of_params(); n++) {
    target->set_parameter(n + 1, get_parameter(n + 1));
  }

  target->set_position_in_samples(position_in_samples());
  if (ECA_AUDIO_POSITION::length_set())
    target->ECA_AUDIO_POSITION::set_length_in_samples(ECA_AUDIO_POSITION::length_in_samples());

  target->buffersize_rep = buffersize_rep;
  target->finished_rep = finished_rep;
  target->m_lPhase = m_lPhase;
  target->m_lPhaseStep = m_lPhaseStep;
  DBC_CHECK(target->m_fCachedFrequency == m_fCachedFrequency);
  target->m_fLimitFrequency = m_fLimitFrequency;
  target->m_fPhaseStepScalar = m_fPhaseStepScalar;

  return target;
}

void AUDIO_IO_TONE::open(void) throw(AUDIO_IO::SETUP_ERROR &)
{
  DBC_CHECK(samples_per_second() != 0);

  if (io_mode() != AUDIO_IO::io_read)
    throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIO_IO_TONE: Writing to tone generator not allowed!"));

  finished_rep = false;
  m_fLimitFrequency
    = SAMPLE_SPECS::sample_t(samples_per_second() * 0.5);
  m_fPhaseStepScalar
    = SAMPLE_SPECS::sample_t(g_fPhaseStepBase / samples_per_second());

  /* recalculate m_fLimitFrequency and mfPhaseStepScalar */
  if (m_fCachedFrequency)
    setPhaseStepFromFrequency(m_fCachedFrequency, true);

  AUDIO_IO::open();
}

void AUDIO_IO_TONE::close(void)
{
  AUDIO_IO::close();
}

bool AUDIO_IO_TONE::finite_length_stream(void) const
{
  return ECA_AUDIO_POSITION::length_set();
}

void AUDIO_IO_TONE::read_buffer(SAMPLE_BUFFER* sbuf)
{
  /* write to sbuf->buffer[ch], similarly as the LADSPA
   * chainops */

  sbuf->number_of_channels(channels());

  /* set the length according to our buffersize */
  if (ECA_AUDIO_POSITION::length_set() &&
      (position_in_samples() + buffersize())
      >= ECA_AUDIO_POSITION::length_in_samples()) {
    /* over requested duration, adjust buffersize */
    sbuf->length_in_samples(ECA_AUDIO_POSITION::length_in_samples()
			    - position_in_samples());
    finished_rep = true;
  }
  else
    sbuf->length_in_samples(buffersize());

  i.init(sbuf);
  i.begin();

  while(!i.end()) {
    for(int n = 0; n < channels(); n++) {
      if (i.end())
	break;

      *(i.current(n))
	= g_pfSineTable[m_lPhase >> SINE_TABLE_SHIFT];

    }

    m_lPhase += m_lPhaseStep;

    i.next();
  }

  change_position_in_samples(sbuf->length_in_samples());
}

void AUDIO_IO_TONE::write_buffer(SAMPLE_BUFFER* sbuf)
{
  /* NOP */
  DBC_CHECK(false);
}

void AUDIO_IO_TONE::seek_position(void)
{
  /* note: phase must be correct after arbitrary seeks */
  m_lPhase = m_lPhaseStep * position_in_samples();

  if (ECA_AUDIO_POSITION::length_set() == true &&
      position_in_samples() <
      ECA_AUDIO_POSITION::length_in_samples())
    finished_rep = false;
}

void AUDIO_IO_TONE::setPhaseStepFromFrequency(const SAMPLE_SPECS::sample_t fFrequency, bool force)
{
  if (fFrequency != m_fCachedFrequency || force == true) {
    if (fFrequency >= 0 && fFrequency < m_fLimitFrequency)
      m_lPhaseStep = (unsigned long)(m_fPhaseStepScalar * fFrequency);
    else
      m_lPhaseStep = 0;
    m_fCachedFrequency = fFrequency;
  }
}

void AUDIO_IO_TONE::set_parameter(int param,
				  string value)
{
  ECA_LOG_MSG(ECA_LOGGER::user_objects,
	      AUDIO_IO::parameter_set_to_string(param, value));

  switch (param)
    {
    case 1:
      {
	AUDIO_IO::set_parameter (param, value);
	break;
      }
    case 2:
      {
	/* type; only "sine" supported */
	break;
      }
    case 3:
      {
	setPhaseStepFromFrequency (atof(value.c_str()), false);
	break;
      }
    case 4:
      {
	double duration = atof(value.c_str());
	if (duration > 0.0f)
	  ECA_AUDIO_POSITION::set_length_in_seconds(duration);
	break;
      }
    }
}

string AUDIO_IO_TONE::get_parameter(int param) const
{
  switch (param)
    {
    case 1: return AUDIO_IO::get_parameter(param);
    case 2: return "sine";
    case 3: return kvu_numtostr(m_fCachedFrequency);
    case 4:
      {
	if (ECA_AUDIO_POSITION::length_set() == true)
	  return kvu_numtostr(ECA_AUDIO_POSITION::length_in_seconds_exact());
	else
	  return kvu_numtostr(-1.0f);
      }
    default: break;
    }

  return std::string();
}
<|endoftext|>


<commit_before>#include "Transform.h"
#include <assert.h>

using namespace Core;
using namespace Math;

const Matrix & Transform::ComputeLocalMatrix()
{
	_localMat._11 = _scale.x * _right.x;
	_localMat._12 = _scale.y * _up.x;
	_localMat._13 = _scale.z * _forward.x;
	_localMat._14 = 0.0f;

	_localMat._21 = _scale.x * _right.y;
	_localMat._22 = _scale.y * _up.y;
	_localMat._23 = _scale.z * _forward.y;
	_localMat._24 = 0.0f;

	_localMat._31 = _scale.x * _right.z;
	_localMat._32 = _scale.y * _up.z;
	_localMat._33 = _scale.z * _forward.z;
	_localMat._34 = 0.0f;

	_localMat._41 = _position.x;
	_localMat._42 = _position.y;
	_localMat._43 = _position.z;
	_localMat._44 = 1.0f;

	return _localMat;
}

void Transform::UpdatePosition(const Vector3& pos)
{
	_position = pos;
	SetDirty();
}

void Transform::UpdateScale(const Vector3& scale)
{
	_scale = scale;
	SetDirty();
}

void Transform::UpdateRight(const Vector3& r)
{
	LookAtDir(Vector3::Cross(_up, r));
}

void Transform::UpdateUp(const Vector3& u)
{
	LookAtDir(Vector3::Cross(u, _right));
}

void Transform::UpdateForward(const Vector3& f)
{
	LookAtDir(f);
}

void Transform::UpdateEulerAngle(const Vector3 & e)
{
	_eulerAngle = e;
	_quaternion = Quaternion::FromEuler(-e);

	_right		= _quaternion.GetRight();
	_up			= _quaternion.GetUp();
	_forward	= _quaternion.GetForward();

	SetDirty();
}

void Transform::UpdateQuaternion(const Quaternion & q)
{
	_quaternion = q;

	Matrix rotationMatrix = Matrix::RotateUsingQuaternion(_quaternion);
	_eulerAngle = Vector3::FromRotationMatrix(rotationMatrix);

	_right		= _quaternion.GetRight();
	_up			= _quaternion.GetUp();
	_forward	= _quaternion.GetForward();

	SetDirty();
}

void Transform::LookAtPos(const Vector3 & targetPos, const Vector3* upVec)
{
	Vector3 position	= GetPosition();
	Vector3 forward		= (targetPos - position).Normalized();

	LookAtDir(forward, upVec);
}

void Transform::LookAtDir(const Vector3 & targetDir, const Vector3* upVec)
{
	Matrix rotMat = Matrix::LookAtDir(targetDir, upVec);

	_eulerAngle = Vector3::FromRotationMatrix(rotMat);
	_quaternion = Quaternion::FromRotationMatrix(rotMat);

	SetDirty();
}

void Transform::AddChild(Transform& child)
{
	child._parentId = _parentId;

	assert(HasChild(child.GetObjectId()) == false);
	_childIds.push_back(child.GetObjectId());
}

const Vector3 Transform::GetWorldPosition() const
{
	return Vector3(_worldMat._41, _worldMat._42, _worldMat._43);
}

const Vector3 Transform::GetWorldScale() const
{
	return Vector3(	Vector3(_worldMat._11, _worldMat._12, _worldMat._13).Length(),
					Vector3(_worldMat._21, _worldMat._22, _worldMat._23).Length(),
					Vector3(_worldMat._31, _worldMat._32, _worldMat._33).Length() );
}

const Vector3 Transform::GetWorldRight(const Vector3& scale) const
{
	return Vector3(	_worldMat._11 / scale.x,
					_worldMat._21 / scale.y,
					_worldMat._31 / scale.z	).Normalized();
}

const Vector3 Transform::GetWorldUp(const Vector3& scale) const
{
	return Vector3(	_worldMat._12 / scale.x,
					_worldMat._22 / scale.y,
					_worldMat._32 / scale.z	).Normalized();
}

const Vector3 Transform::GetWorldForward(const Vector3& scale)	const
{
	return Vector3(	_worldMat._13 / scale.x,
					_worldMat._23 / scale.y,
					_worldMat._33 / scale.z	).Normalized();
}

const Vector3 Transform::FetchWorldEulerAngle() const
{
	Vector3 scale = GetWorldScale();
	Matrix rotMat = Matrix::MakeRotationMatrix(GetWorldRight(scale), GetWorldUp(scale), GetWorldForward(scale));

	return Vector3::FromRotationMatrix(rotMat);
}

const Quaternion Transform::FetchWorldQuaternion() const
{
	Vector3 scale = GetWorldScale();
	Matrix rotMat = Matrix::MakeRotationMatrix(GetWorldRight(scale), GetWorldUp(scale), GetWorldForward(scale));

	return Quaternion::FromRotationMatrix(rotMat);
}

bool Transform::HasChild(ObjectId id) const
{
	for (const auto childId : _childIds)
	{
		if(childId.Literal() == id.Literal())
			return true;
	}

	return false;
}

void Transform::DeleteChild(ObjectId id)
{
	uint pos = 0;
	for (pos; pos < _childIds.size() && _childIds[pos] != id; ++pos);

	assert(pos == _childIds.size());
	_childIds.erase(_childIds.begin() + pos);
}

void Transform::UpdateDirty(TransformPool& pool)
{
	for (uint id = _objectId.Literal(); id != ObjectId::Undefined(); id = _parentId.Literal())
		pool.Find(id)->_dirty |= _dirty;
}

void Transform::_ComputeWorldMatrix(TransformPool& pool)
{
	for (auto childId : _childIds)
	{
		auto child = pool.Find(childId.Literal());
		assert(child);

		child->_worldMat = child->ComputeLocalMatrix() * _worldMat;
		child->_ComputeWorldMatrix(pool);
	}
}

void Transform::ComputeWorldMatrix(TransformPool& pool)
{
	// this func must be run in root
	assert(_parentId.Literal() == ObjectId::Undefined());

	if(_dirty == false)	return;
	_worldMat = ComputeLocalMatrix();

	_ComputeWorldMatrix(pool);
}
<commit_msg>Update Transform.cpp<commit_after>#include "Transform.h"
#include <assert.h>

using namespace Core;
using namespace Math;

const Matrix & Transform::ComputeLocalMatrix()
{
	_localMat._11 = _scale.x * _right.x;
	_localMat._12 = _scale.y * _up.x;
	_localMat._13 = _scale.z * _forward.x;
	_localMat._14 = 0.0f;

	_localMat._21 = _scale.x * _right.y;
	_localMat._22 = _scale.y * _up.y;
	_localMat._23 = _scale.z * _forward.y;
	_localMat._24 = 0.0f;

	_localMat._31 = _scale.x * _right.z;
	_localMat._32 = _scale.y * _up.z;
	_localMat._33 = _scale.z * _forward.z;
	_localMat._34 = 0.0f;

	_localMat._41 = _position.x;
	_localMat._42 = _position.y;
	_localMat._43 = _position.z;
	_localMat._44 = 1.0f;

	return _localMat;
}

void Transform::UpdatePosition(const Vector3& pos)
{
	_position = pos;
	SetDirty();
}

void Transform::UpdateScale(const Vector3& scale)
{
	_scale = scale;
	SetDirty();
}

void Transform::UpdateRight(const Vector3& r)
{
	LookAtDir(Vector3::Cross(_up, r));
}

void Transform::UpdateUp(const Vector3& u)
{
	LookAtDir(Vector3::Cross(u, _right));
}

void Transform::UpdateForward(const Vector3& f)
{
	LookAtDir(f);
}

void Transform::UpdateEulerAngle(const Vector3 & e)
{
	_eulerAngle = e;
	_quaternion = Quaternion::FromEuler(-e);

	_right		= _quaternion.GetRight();
	_up			= _quaternion.GetUp();
	_forward	= _quaternion.GetForward();

	SetDirty();
}

void Transform::UpdateQuaternion(const Quaternion & q)
{
	_quaternion = q;

	Matrix rotationMatrix = Matrix::RotateUsingQuaternion(_quaternion);
	_eulerAngle = Vector3::FromRotationMatrix(rotationMatrix);

	_right		= _quaternion.GetRight();
	_up			= _quaternion.GetUp();
	_forward	= _quaternion.GetForward();

	SetDirty();
}

void Transform::LookAtPos(const Vector3 & targetPos, const Vector3* upVec)
{
	Vector3 position	= GetPosition();
	Vector3 forward		= (targetPos - position).Normalized();

	LookAtDir(forward, upVec);
}

void Transform::LookAtDir(const Vector3 & targetDir, const Vector3* upVec)
{
	Matrix rotMat = Matrix::LookAtDir(targetDir, upVec);

	_eulerAngle = Vector3::FromRotationMatrix(rotMat);
	_quaternion = Quaternion::FromRotationMatrix(rotMat);

	SetDirty();
}

void Transform::AddChild(Transform& child)
{
	child._parentId = _parentId;

	assert(HasChild(child.GetObjectId()) == false);
	_childIds.push_back(child.GetObjectId());
}

const Vector3 Transform::GetWorldPosition() const
{
	return Vector3(_worldMat._41, _worldMat._42, _worldMat._43);
}

const Vector3 Transform::GetWorldScale() const
{
	return Vector3(	Vector3(_worldMat._11, _worldMat._12, _worldMat._13).Length(),
					Vector3(_worldMat._21, _worldMat._22, _worldMat._23).Length(),
					Vector3(_worldMat._31, _worldMat._32, _worldMat._33).Length() );
}

const Vector3 Transform::GetWorldRight(const Vector3& scale) const
{
	return Vector3(	_worldMat._11 / scale.x,
					_worldMat._21 / scale.y,
					_worldMat._31 / scale.z	).Normalized();
}

const Vector3 Transform::GetWorldUp(const Vector3& scale) const
{
	return Vector3(	_worldMat._12 / scale.x,
					_worldMat._22 / scale.y,
					_worldMat._32 / scale.z	).Normalized();
}

const Vector3 Transform::GetWorldForward(const Vector3& scale)	const
{
	return Vector3(	_worldMat._13 / scale.x,
					_worldMat._23 / scale.y,
					_worldMat._33 / scale.z	).Normalized();
}

const Vector3 Transform::FetchWorldEulerAngle() const
{
	Vector3 scale = GetWorldScale();
	Matrix rotMat = Matrix::MakeRotationMatrix(GetWorldRight(scale), GetWorldUp(scale), GetWorldForward(scale));

	return Vector3::FromRotationMatrix(rotMat);
}

const Quaternion Transform::FetchWorldQuaternion() const
{
	Vector3 scale = GetWorldScale();
	Matrix rotMat = Matrix::MakeRotationMatrix(GetWorldRight(scale), GetWorldUp(scale), GetWorldForward(scale));

	return Quaternion::FromRotationMatrix(rotMat);
}

bool Transform::HasChild(ObjectId id) const
{
	for (const auto childId : _childIds)
	{
		if(childId.Literal() == id.Literal())
			return true;
	}

	return false;
}

void Transform::DeleteChild(ObjectId id)
{
	uint pos = 0;
	for (pos; pos < _childIds.size() && _childIds[pos] != id; ++pos);

	assert(pos == _childIds.size());
	_childIds.erase(_childIds.begin() + pos);
}

void Transform::UpdateDirty(TransformPool& pool)
{
	for (uint id = _objectId.Literal(); id != ObjectId::Undefined(); id = _parentId.Literal())
		pool.Find(id)->_dirty |= _dirty;
}

void Transform::_ComputeWorldMatrix(TransformPool& pool)
{
	for (auto childId : _childIds)
	{
		auto child = pool.Find(childId.Literal());
		assert(child);
				// parent   <-   child
		child->_worldMat = _worldMat * child->ComputeLocalMatrix();
		child->_ComputeWorldMatrix(pool);
	}
}

void Transform::ComputeWorldMatrix(TransformPool& pool)
{
	// this func must be run in root
	assert(_parentId.Literal() == ObjectId::Undefined());

	if(_dirty == false)	return;
	_worldMat = ComputeLocalMatrix();

	_ComputeWorldMatrix(pool);
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2013, Patrick P. Putnam (putnampp@gmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of the FreeBSD Project.
 ******************************************************************************/

#include "../clothoobjects/common_types.h"
#include "LifeExpectancyModel.h"
#include "../ClothoModelCoordinator.h"
#include "SimulationManager.h"

#include <iostream>

#include "../clothoobjects/events/DeathEvent.h"
#include "gsl/gsl_randist.h"

#include <time.h>

#include "IntVTime.h"

using std::cout;
using std::endl;

const string DISTRIBUTION_K = "distribution";
const string MEAN_K = "mean";
const string STDEV_K = "stdev";

DEFINE_REGISTERED_CLOTHO_MODEL( LifeExpectancyModel )

template <>
ClothoModel * ClothoModelCreator< LifeExpectancyModel >::createModel() {
    shared_ptr< LifeExpectancyModel> pm( new LifeExpectancyModel() );
    shared_ptr<ClothoModelCoordinator> coord = ClothoModelCoordinator::getInstance();

    coord->addEventHandler( evt_BirthEvent.getDataType(), pm );

    return &*pm;
}

template<>
ClothoModel * ClothoModelCreator< LifeExpectancyModel >::createModelFrom( const YAML::Node & n ) {
    shared_ptr< LifeExpectancyModel > pm( new LifeExpectancyModel() );
    pm->configure( n );
    shared_ptr<ClothoModelCoordinator> coord = ClothoModelCoordinator::getInstance();

    coord->addEventHandler( evt_BirthEvent.getDataType(), pm );

    return &*pm;
}

LifeExpectancyModel::LifeExpectancyModel() : m_rng( gsl_rng_alloc( gsl_rng_taus ) ) {
    long seed = time(NULL);
    gsl_rng_set( m_rng, seed );
}

LifeExpectancyModel::~LifeExpectancyModel() {}

void LifeExpectancyModel::configure( const YAML::Node & n ) {
    if( n[ MALE_K ] ) {
        YAML::Node tmp = n[MALE_K];
        if( tmp[ MEAN_K ] ) {
            m_male_mean = tmp[MEAN_K].as< double >();
        }
        if( tmp[ STDEV_K ] ) {
            m_male_sigma = tmp[STDEV_K].as< double >();
        }
    }

    if( n[ FEMALE_K ] ) {
        YAML::Node tmp = n[FEMALE_K];
        if( tmp[ MEAN_K ] ) {
            m_female_mean = tmp[MEAN_K].as< double >();
        }
        if( tmp[ STDEV_K ] ) {
            m_female_sigma = tmp[STDEV_K].as< double >();
        }
    }
}

void LifeExpectancyModel::handle( const Event * evt ) {
    const string name = evt->getDataType();

    if( name == evt_BirthEvent.getDataType() ) {
        const BirthEvent * bEvt = dynamic_cast< const BirthEvent * >( evt );
        handle( bEvt );
    }
}

void LifeExpectancyModel::handle( const BirthEvent * evt ) {
    if(! evt ) return;

    double expected_age = 0.0;

    switch( evt->getSex() ) {
    case FEMALE:
        expected_age = gsl_ran_gaussian( m_rng, m_female_sigma );
        expected_age += m_female_mean;
        break;
    case MALE:
        expected_age = gsl_ran_gaussian( m_rng, m_male_sigma );
        expected_age += m_male_mean;
        break;
    default:
        expected_age = gsl_ran_gaussian( m_rng, m_unk_sigma );
        expected_age += m_unk_mean;
        break;
    };

    IntVTime tDeath = dynamic_cast< const IntVTime & >( evt->getBirthTime() ) + (int)expected_age;
    Event * dEvent = new DeathEvent( evt->getBirthTime(), tDeath, evt->getSender(), evt->getSender(), evt->getEventId().getEventNum() );

    ClothoModelCoordinator::getInstance()->routeEvent( dEvent );
}

void LifeExpectancyModel::dump( ostream & out ) {

}

<commit_msg>Use new copy constructor for DeathEvent<commit_after>/*******************************************************************************
 * Copyright (c) 2013, Patrick P. Putnam (putnampp@gmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of the FreeBSD Project.
 ******************************************************************************/

#include "../clothoobjects/common_types.h"
#include "LifeExpectancyModel.h"
#include "../ClothoModelCoordinator.h"
#include "SimulationManager.h"

#include <iostream>

#include "../clothoobjects/events/DeathEvent.h"
#include "gsl/gsl_randist.h"

#include <time.h>

#include "IntVTime.h"

using std::cout;
using std::endl;

const string DISTRIBUTION_K = "distribution";
const string MEAN_K = "mean";
const string STDEV_K = "stdev";

DEFINE_REGISTERED_CLOTHO_MODEL( LifeExpectancyModel )

template <>
ClothoModel * ClothoModelCreator< LifeExpectancyModel >::createModel() {
    shared_ptr< LifeExpectancyModel> pm( new LifeExpectancyModel() );
    shared_ptr<ClothoModelCoordinator> coord = ClothoModelCoordinator::getInstance();

    coord->addEventHandler( evt_BirthEvent.getDataType(), pm );

    return &*pm;
}

template<>
ClothoModel * ClothoModelCreator< LifeExpectancyModel >::createModelFrom( const YAML::Node & n ) {
    shared_ptr< LifeExpectancyModel > pm( new LifeExpectancyModel() );
    pm->configure( n );
    shared_ptr<ClothoModelCoordinator> coord = ClothoModelCoordinator::getInstance();

    coord->addEventHandler( evt_BirthEvent.getDataType(), pm );

    return &*pm;
}

LifeExpectancyModel::LifeExpectancyModel() : m_rng( gsl_rng_alloc( gsl_rng_taus ) ) {
    long seed = time(NULL);
    gsl_rng_set( m_rng, seed );
}

LifeExpectancyModel::~LifeExpectancyModel() {}

void LifeExpectancyModel::configure( const YAML::Node & n ) {
    if( n[ MALE_K ] ) {
        YAML::Node tmp = n[MALE_K];
        if( tmp[ MEAN_K ] ) {
            m_male_mean = tmp[MEAN_K].as< double >();
        }
        if( tmp[ STDEV_K ] ) {
            m_male_sigma = tmp[STDEV_K].as< double >();
        }
    }

    if( n[ FEMALE_K ] ) {
        YAML::Node tmp = n[FEMALE_K];
        if( tmp[ MEAN_K ] ) {
            m_female_mean = tmp[MEAN_K].as< double >();
        }
        if( tmp[ STDEV_K ] ) {
            m_female_sigma = tmp[STDEV_K].as< double >();
        }
    }
}

void LifeExpectancyModel::handle( const Event * evt ) {
    const string name = evt->getDataType();

    if( name == evt_BirthEvent.getDataType() ) {
        const BirthEvent * bEvt = dynamic_cast< const BirthEvent * >( evt );
        handle( bEvt );
    }
}

void LifeExpectancyModel::handle( const BirthEvent * evt ) {
    if(! evt ) return;

    double expected_age = 0.0;

    switch( evt->getSex() ) {
    case FEMALE:
        expected_age = gsl_ran_gaussian( m_rng, m_female_sigma );
        expected_age += m_female_mean;
        break;
    case MALE:
        expected_age = gsl_ran_gaussian( m_rng, m_male_sigma );
        expected_age += m_male_mean;
        break;
    default:
        expected_age = gsl_ran_gaussian( m_rng, m_unk_sigma );
        expected_age += m_unk_mean;
        break;
    };

    IntVTime tDeath = dynamic_cast< const IntVTime & >( evt->getBirthTime() ) + (int)expected_age;
    Event * dEvent = new DeathEvent( evt->getBirthTime(), tDeath, evt->getSender(), evt->getSender(), evt->getEventId() );

    ClothoModelCoordinator::getInstance()->routeEvent( dEvent );
}

void LifeExpectancyModel::dump( ostream & out ) {

}

<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP__
#define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP__

#include <stan/prob/traits.hpp>
#include <stan/math/matrix_error_handling.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/prob/constants.hpp>

namespace stan {

  namespace prob {

    // Categorical(n|theta)  [0 < n <= N;   0 <= theta[n] <= 1;  SUM theta = 1]
    template <bool propto,
              typename T_prob,
              class Policy>
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                    const Policy&) {
      static const char* function = "stan::prob::categorical_log(%1%)";

      using stan::math::check_bounded;
      using stan::math::check_simplex;
      using boost::math::tools::promote_args;

      typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type lb = 1;

      typename promote_args<T_prob>::type lp(0.0);
      if (!check_bounded(function, n, lb, theta.size(),
                         "Number of categories",
                         &lp, Policy()))
        return lp;
      if (!check_simplex(function, theta,
                         "Probabilities parameter",
                         &lp, Policy()))
        return lp;

      if (include_summand<propto,T_prob>::value)
        return log(theta(n-1));
      return 0.0;
    }

    template <bool propto,
              typename T_prob>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
      return categorical_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_prob,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                    const Policy&) {
      return categorical_log<false>(n,theta,Policy());
    }

    template <typename T_prob>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
      return categorical_log<false>(n,theta,stan::math::default_policy());
    }

  }
}
#endif
<commit_msg>moved error checking to doubles for simplex in categorical, still not maximally efficient because of alloc of new vector<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP__
#define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP__

#include <stan/prob/traits.hpp>
#include <stan/math/matrix_error_handling.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/prob/constants.hpp>

namespace stan {

  namespace prob {

    // Categorical(n|theta)  [0 < n <= N;   0 <= theta[n] <= 1;  SUM theta = 1]
    template <bool propto,
              typename T_prob,
              class Policy>
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(int n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                    const Policy&) {
      static const char* function = "stan::prob::categorical_log(%1%)";

      using stan::math::check_bounded;
      using stan::math::check_simplex;
      using boost::math::tools::promote_args;
      using stan::math::value_of;

      typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type lb = 1;

      double lp = 0.0;
      if (!check_bounded(function, n, lb, theta.size(),
                         "Number of categories",
                         &lp, Policy()))
        return lp;

      if (!stan::is_constant_struct<T_prob>::value) {
        Eigen::Matrix<double,Eigen::Dynamic,1> theta_dbl(theta.size());
        for (int i = 0; i < theta_dbl.size(); ++i)
          theta_dbl(i) = value_of(theta(i));
        if (!check_simplex(function, theta,
                           "Probabilities parameter",
                           &lp, Policy()))
          return lp;
      } else {
        if (!check_simplex(function, theta,
                           "Probabilities parameter",
                           &lp, Policy()))
          return lp;
      }

      if (include_summand<propto,T_prob>::value)
        return log(theta(n-1));
      return 0.0;
    }

    template <bool propto,
              typename T_prob>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
      return categorical_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_prob,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                    const Policy&) {
      return categorical_log<false>(n,theta,Policy());
    }

    template <typename T_prob>
    inline
    typename boost::math::tools::promote_args<T_prob>::type
    categorical_log(const typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type n,
                    const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
      return categorical_log<false>(n,theta,stan::math::default_policy());
    }

  }
}
#endif
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginLatex
//
//  Although specific vector data import approaches, as the one
//  presented later in \ref{sec:ReadDXF}, can be useful, it is even more
//  interesting to have available approaches which are independent of
//  the input format. Unfortunately, many vector data formats do not
//  share the models for the data they represent. However, in some
//  cases, when simple data is stored, it can be decomposed in simple
//  objects as for instance polylines, polygons and points. This is
//  the case for the Shapefile and the KML (Keyhole Markup Language),
//  for instance.
//
//  Even though specific reader/writer for Shapefile and the Google KML
//  are available in OTB, we designed a generic approach for the IO of
//  this kind of data.
//
//  In \ref{sec:VectorDataProjection}, you will find more information on
//  how projection work for the vector data and how you can export
//  the results obtained with OTB to the real world.
//
//  This example illustrates the use of OTB's vector data IO
//  framework.
//
//  We will start by including the header files for the classes
//  describing the vector data and the corresponding reader and writer.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataFileWriter.h"
// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
//
//  We will also need to include the header files for the classes
//  which model the individual objects that we get from the vector
//  data structure.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkPreOrderTreeIterator.h"
#include "otbObjectList.h"
#include "otbPolygon.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[])
{

  if( argc != 3 )
  {
    std::cerr << "Usage: " << argv[0] ;
    std::cerr << "inputFile outputFile" << std::endl;
    return EXIT_FAILURE;
  }

  typedef unsigned short int PixelType;

//  Software Guide : BeginLatex
  //
//  We define the types for the vector data structure and the
//  corresponding file reader.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::VectorData<PixelType,2>           VectorDataType;

  typedef otb::VectorDataFileReader<VectorDataType>
      VectorDataFileReaderType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We can now instantiate the reader and read the data.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
  reader->SetFileName(argv[1]);
  reader->Update();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  The vector data obtained from the reader wil provide a tree of
//  nodes containing the actual objects of the scene. This tree will
//  be accessed using an \doxygen{itk}{PreOrderTreeIterator}.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  typedef VectorDataType::DataTreeType      DataTreeType;
  typedef itk::PreOrderTreeIterator<DataTreeType>    TreeIteratorType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  In this example we will only read polygon objects from the input
//  file before writing them to the output file. We define the type
//  for the polygon object as well as an iterator to the vertices. The
//  polygons obtained will be stored in an \doxygen{otb}{ObjectList}.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  typedef otb::Polygon<double> PolygonType;
  typedef PolygonType::VertexListConstIteratorType PolygonIteratorType;
  typedef otb::ObjectList<PolygonType> PolygonListType;

  typedef PolygonListType::Iterator PolygonListIteratorType;

  PolygonListType::Pointer polygonList = PolygonListType::New();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We get the data tree and instantiate an iterator to walk through it.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  TreeIteratorType it(reader->GetOutput()->GetDataTree());

  it.GoToBegin();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We check that the current object is a polygon using the
//  \code{IsPolygonFeature()} method and get its exterior ring in
//  order to sore it into the list.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  while(!it.IsAtEnd())
  {
    if(it.Get()->IsPolygonFeature())
    {
      polygonList->PushBack(it.Get()->GetPolygonExteriorRing());
    }
    ++it;
  }

// Software Guide : EndCodeSnippet

  polygonList->PushBack(PolygonType::New());

//  Software Guide : BeginLatex
  //
//  Before writing the polygons to the output file, we have to build
//  the vector data structure. This structure will be build up of
//  nodes. We define the types needed for that.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  VectorDataType::Pointer outVectorData = VectorDataType::New();

  typedef VectorDataType::DataNodeType               DataNodeType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We fill the data structure with the nodes. The root node is a
//  document which is composed of folders. A list of polygons can be
//  seen as a multi polygon object.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    DataNodeType::Pointer document = DataNodeType::New();
    document->SetNodeType(otb::DOCUMENT);
    document->SetNodeId("polygon");
    DataNodeType::Pointer folder = DataNodeType::New();
    folder->SetNodeType(otb::FOLDER);
    DataNodeType::Pointer multiPolygon = DataNodeType::New();
    multiPolygon->SetNodeType(otb::FEATURE_MULTIPOLYGON);

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  We assign these objects to the data tree stored by the vector data object.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    DataTreeType::Pointer tree = outVectorData->GetDataTree();
    DataNodeType::Pointer root = tree->GetRoot()->Get();

    tree->Add(document,root);
    tree->Add(folder,document);
    tree->Add(multiPolygon,folder);

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  We can now iterate through the polygon list and fill the vector
//  data structure.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    for(PolygonListType::Iterator it = polygonList->Begin();
        it != polygonList->End(); ++it)
    {
      DataNodeType::Pointer newPolygon = DataNodeType::New();
      newPolygon->SetPolygonExteriorRing(it.Get());
      tree->Add(newPolygon,multiPolygon);
    }

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  An finally we write the vector data to a file using a generic
//  \doxygen{otb}{VectorDataFileWriter}.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    typedef otb::VectorDataFileWriter<VectorDataType> WriterType;

    WriterType::Pointer writer = WriterType::New();
    writer->SetInput(outVectorData);
    writer->SetFileName(argv[2]);
    writer->Update();

// Software Guide : EndCodeSnippet

    return EXIT_SUCCESS;
}
<commit_msg>DOC: Some corrections to VectorDataIOExample<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginLatex
//
//  Although specific vector data IO approaches, as the one
//  presented in section \ref{sec:ReadDXF}, can be useful, it is even more
//  interesting to have available approaches which are independent of
//  the input format. Unfortunately, many vector data formats do not
//  share the models for the data they represent. However, in some
//  cases, when simple data is stored, it can be decomposed in simple
//  objects as for instance polylines, polygons and points. This is
//  the case for the Shapefile and the KML (Keyhole Markup Language),
//  for instance.
//
//  Even though specific reader/writer for Shapefile and the Google KML
//  are available in OTB, we designed a generic approach for the IO of
//  this kind of data.
//
//  In section \ref{sec:VectorDataProjection}, you will find more information on
//  how projections work for the vector data and how you can export
//  the results obtained with OTB to the real world.
//
//  This example illustrates the use of OTB's vector data IO
//  framework.
//
//  We will start by including the header files for the classes
//  describing the vector data and the corresponding reader and writer.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataFileWriter.h"
// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
//
//  We will also need to include the header files for the classes
//  which model the individual objects that we get from the vector
//  data structure.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkPreOrderTreeIterator.h"
#include "otbObjectList.h"
#include "otbPolygon.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[])
{

  if( argc != 3 )
  {
    std::cerr << "Usage: " << argv[0] ;
    std::cerr << "inputFile outputFile" << std::endl;
    return EXIT_FAILURE;
  }

  typedef unsigned short int PixelType;

//  Software Guide : BeginLatex
  //
//  We define the types for the vector data structure and the
//  corresponding file reader.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::VectorData<PixelType,2>           VectorDataType;

  typedef otb::VectorDataFileReader<VectorDataType>
      VectorDataFileReaderType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We can now instantiate the reader and read the data.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
  reader->SetFileName(argv[1]);
  reader->Update();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  The vector data obtained from the reader will provide a tree of
//  nodes containing the actual objects of the scene. This tree will
//  be accessed using an \doxygen{itk}{PreOrderTreeIterator}.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  typedef VectorDataType::DataTreeType      DataTreeType;
  typedef itk::PreOrderTreeIterator<DataTreeType>    TreeIteratorType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  In this example we will only read polygon objects from the input
//  file before writing them to the output file. We define the type
//  for the polygon object as well as an iterator to the vertices. The
//  polygons obtained will be stored in an \doxygen{otb}{ObjectList}.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  typedef otb::Polygon<double> PolygonType;
  typedef PolygonType::VertexListConstIteratorType PolygonIteratorType;
  typedef otb::ObjectList<PolygonType> PolygonListType;

  typedef PolygonListType::Iterator PolygonListIteratorType;

  PolygonListType::Pointer polygonList = PolygonListType::New();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We get the data tree and instantiate an iterator to walk through it.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  TreeIteratorType it(reader->GetOutput()->GetDataTree());

  it.GoToBegin();

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We check that the current object is a polygon using the
//  \code{IsPolygonFeature()} method and get its exterior ring in
//  order to store it into the list.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  while(!it.IsAtEnd())
  {
    if(it.Get()->IsPolygonFeature())
    {
      polygonList->PushBack(it.Get()->GetPolygonExteriorRing());
    }
    ++it;
  }

// Software Guide : EndCodeSnippet

  polygonList->PushBack(PolygonType::New());

//  Software Guide : BeginLatex
  //
//  Before writing the polygons to the output file, we have to build
//  the vector data structure. This structure will be built up of
//  nodes. We define the types needed for that.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

  VectorDataType::Pointer outVectorData = VectorDataType::New();

  typedef VectorDataType::DataNodeType               DataNodeType;

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
  //
//  We fill the data structure with the nodes. The root node is a
//  document which is composed of folders. A list of polygons can be
//  seen as a multi polygon object.
  //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    DataNodeType::Pointer document = DataNodeType::New();
    document->SetNodeType(otb::DOCUMENT);
    document->SetNodeId("polygon");
    DataNodeType::Pointer folder = DataNodeType::New();
    folder->SetNodeType(otb::FOLDER);
    DataNodeType::Pointer multiPolygon = DataNodeType::New();
    multiPolygon->SetNodeType(otb::FEATURE_MULTIPOLYGON);

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  We assign these objects to the data tree stored by the vector data object.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    DataTreeType::Pointer tree = outVectorData->GetDataTree();
    DataNodeType::Pointer root = tree->GetRoot()->Get();

    tree->Add(document,root);
    tree->Add(folder,document);
    tree->Add(multiPolygon,folder);

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  We can now iterate through the polygon list and fill the vector
//  data structure.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    for(PolygonListType::Iterator it = polygonList->Begin();
        it != polygonList->End(); ++it)
    {
      DataNodeType::Pointer newPolygon = DataNodeType::New();
      newPolygon->SetPolygonExteriorRing(it.Get());
      tree->Add(newPolygon,multiPolygon);
    }

// Software Guide : EndCodeSnippet
//  Software Guide : BeginLatex
    //
//  And finally we write the vector data to a file using a generic
//  \doxygen{otb}{VectorDataFileWriter}.
    //
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

    typedef otb::VectorDataFileWriter<VectorDataType> WriterType;

    WriterType::Pointer writer = WriterType::New();
    writer->SetInput(outVectorData);
    writer->SetFileName(argv[2]);
    writer->Update();

// Software Guide : EndCodeSnippet

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>FIX balls missing their correct entityIDs<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/platform_thread.h"
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "chrome_mini_installer.h"

namespace {
class MiniInstallTest : public testing::Test {
   protected:
    void CleanTheSystem() {
      ChromeMiniInstaller userinstall(mini_installer_constants::kUserInstall);
      userinstall.UnInstall();
      if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
        ChromeMiniInstaller systeminstall(
                            mini_installer_constants::kSystemInstall);
        systeminstall.UnInstall();
      }
    }
    virtual void SetUp() {
      CleanTheSystem();
    }

    virtual void TearDown() {
      PlatformThread::Sleep(2000);
      CleanTheSystem();
    }
  };
};

TEST_F(MiniInstallTest, FullInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallFullInstaller();
}

// Will enable this test after bug#9593 gets fixed.
TEST_F(MiniInstallTest, DISABLED_DifferentialInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallDifferentialInstaller();
}

TEST_F(MiniInstallTest, DISABLED_StandaloneInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallStandaloneIntaller();
}

TEST_F(MiniInstallTest, MiniInstallerOverChromeMetaInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.OverInstall();
}

TEST_F(MiniInstallTest, MiniInstallerSystemInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kSystemInstall);
    installer.Install();
  }
}

TEST_F(MiniInstallTest, MiniInstallerUserInstallTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.Install();
}

TEST(InstallUtilTests, MiniInstallTestValidWindowsVersion) {
  // We run the tests on all supported OSes.
  // Make sure the code agrees.
  EXPECT_TRUE(InstallUtil::IsOSSupported());
}
<commit_msg>comment test again as the fix didnt work.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/platform_thread.h"
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "chrome_mini_installer.h"

namespace {
class MiniInstallTest : public testing::Test {
   protected:
    void CleanTheSystem() {
      ChromeMiniInstaller userinstall(mini_installer_constants::kUserInstall);
      userinstall.UnInstall();
      if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
        ChromeMiniInstaller systeminstall(
                            mini_installer_constants::kSystemInstall);
        systeminstall.UnInstall();
      }
    }
    virtual void SetUp() {
      CleanTheSystem();
    }

    virtual void TearDown() {
      PlatformThread::Sleep(2000);
      CleanTheSystem();
    }
  };
};

TEST_F(MiniInstallTest, FullInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallFullInstaller();
}

// Will enable this test after bug#9593 gets fixed.
TEST_F(MiniInstallTest, DISABLED_DifferentialInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallDifferentialInstaller();
}

TEST_F(MiniInstallTest, DISABLED_StandaloneInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallStandaloneIntaller();
}

TEST_F(MiniInstallTest, MiniInstallerOverChromeMetaInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.OverInstall();
}

TEST_F(MiniInstallTest, DISABLED_MiniInstallerSystemInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kSystemInstall);
    installer.Install();
  }
}

TEST_F(MiniInstallTest, DISABLED_MiniInstallerUserInstallTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.Install();
}

TEST(InstallUtilTests, MiniInstallTestValidWindowsVersion) {
  // We run the tests on all supported OSes.
  // Make sure the code agrees.
  EXPECT_TRUE(InstallUtil::IsOSSupported());
}
<|endoftext|>


<commit_before>#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <stm32f3xx_hal_conf.h>

#include <xXx/components/wireless/nrf24l01p/nrf24l01p_esb.hpp>
#include <xXx/templates/queue.hpp>
#include <xXx/utils/logging.hpp>

#include "gpio.hpp"
#include "led.hpp"
#include "spi.hpp"

const uint32_t baseAddress_0 = 0xE7E7E7E7;
const uint32_t baseAddress_1 = 0xC2C2C2C2;
const uint8_t addressPrefix  = 0xE7;

union Counter_t {
    uint8_t m8[4];
    uint32_t m32;
};

Counter_t counter = {.m32 = 0};

extern SPI_HandleTypeDef hspi2;

Gpio port1_CE(PORT1_CE_GPIO_Port, PORT1_CE_Pin);
Gpio port1_CS(PORT1_CS_GPIO_Port, PORT1_CS_Pin);
Gpio port1_INT(PORT1_INT_GPIO_Port, PORT1_INT_Pin);

Gpio port2_CE(PORT2_CE_GPIO_Port, PORT2_CE_Pin);
Gpio port2_CS(PORT2_CS_GPIO_Port, PORT2_CS_Pin);
Gpio port2_INT(PORT2_INT_GPIO_Port, PORT2_INT_Pin);

Spi port1_SPI(hspi2, port1_CS);
Spi port2_SPI(hspi2, port2_CS);

Gpio button(BUTTON_GPIO_Port, BUTTON_Pin);

nRF24L01P_ESB transmitter(port1_SPI, port1_CE, port1_INT);
nRF24L01P_ESB receiver(port2_SPI, port2_CE, port2_INT);

Led led[] = {Led(LD3), Led(LD5), Led(LD7), Led(LD9), Led(LD10), Led(LD8), Led(LD6), Led(LD4)};

static void txCallback(int8_t numRetries, void* user) {
    counter.m32++;

    if (numRetries > 0) {
        LOG("numRetries: %d", numRetries);
    }
};

static void rxCallback(uint8_t bytes[], size_t numBytes, void* user) {
    BUFFER("bytes:", bytes, numBytes);
};

static void buttonCallback(void* user){
    //    button.disableInterrupt();
    //    transmitter.queueTransmission(counter.m8, sizeof(counter), txCallback, NULL);
    //    led[1].toggle();
    //    transmitter.notifyFromISR();
};

extern "C" void initializeApplication() {
    button.enableInterrupt(buttonCallback, NULL);

    transmitter.create(256, Task_Priority_MID);
    receiver.create(256, Task_Priority_HIGH);
}

extern "C" void applicationTaskFunction(void const* argument) {
    vTaskDelay(1000);

    transmitter.setTxBaseAddress(baseAddress_0);
    transmitter.setTxAddressPrefix(addressPrefix);

    transmitter.setDataRate(DataRate_2MBPS);
    transmitter.setCrcConfig(CrcConfig_2Bytes);
    transmitter.setChannel(2);
    transmitter.setOutputPower(OutputPower_m18dBm);
    transmitter.setRetryCount(0xF);
    transmitter.setRetryDelay(0xF);

    receiver.setRxBaseAddress_0(baseAddress_0);
    receiver.setRxAddressPrefix(0, addressPrefix);

    receiver.setDataRate(DataRate_2MBPS);
    receiver.setCrcConfig(CrcConfig_2Bytes);
    receiver.setChannel(2);
    receiver.setOutputPower(OutputPower_m18dBm);
    receiver.setRetryCount(0xF);
    receiver.setRetryDelay(0xF);

    receiver.startListening(0, rxCallback, NULL);

    transmitter.switchOperatingMode(OperatingMode_Tx);
    receiver.switchOperatingMode(OperatingMode_Rx);

    for (;;) {
        led[0].set();
        transmitter.queueTransmission(counter.m8, sizeof(counter), txCallback, NULL);
        transmitter.notify();
        led[0].clear();

        vTaskDelay(250);
    }
}
<commit_msg>Bugfix<commit_after>#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <stm32f3xx_hal_conf.h>

#include <xXx/components/wireless/nrf24l01p/nrf24l01p_esb.hpp>
#include <xXx/templates/queue.hpp>
#include <xXx/utils/logging.hpp>

#include "gpio.hpp"
#include "led.hpp"
#include "spi.hpp"

const uint32_t baseAddress   = 0xE7E7E7E7;
const uint32_t baseAddress_1 = 0xC2C2C2C2;
const uint8_t addressPrefix  = 0xE7;

union Counter_t {
    uint8_t m8[4];
    uint32_t m32;
};

Counter_t counter = {.m32 = 0};

extern SPI_HandleTypeDef hspi2;

Gpio port1_CE(PORT1_CE_GPIO_Port, PORT1_CE_Pin);
Gpio port1_CS(PORT1_CS_GPIO_Port, PORT1_CS_Pin);
Gpio port1_INT(PORT1_INT_GPIO_Port, PORT1_INT_Pin);

Gpio port2_CE(PORT2_CE_GPIO_Port, PORT2_CE_Pin);
Gpio port2_CS(PORT2_CS_GPIO_Port, PORT2_CS_Pin);
Gpio port2_INT(PORT2_INT_GPIO_Port, PORT2_INT_Pin);

Spi port1_SPI(hspi2, port1_CS);
Spi port2_SPI(hspi2, port2_CS);

Gpio button(BUTTON_GPIO_Port, BUTTON_Pin);

nRF24L01P_ESB transmitter(port1_SPI, port1_CE, port1_INT);
nRF24L01P_ESB receiver(port2_SPI, port2_CE, port2_INT);

Led led[] = {Led(LD3), Led(LD5), Led(LD7), Led(LD9), Led(LD10), Led(LD8), Led(LD6), Led(LD4)};

static void txCallback(int8_t numRetries, void* user) {
    counter.m32++;

    if (numRetries > 0) {
        LOG("numRetries: %d", numRetries);
    }
};

static void rxCallback(uint8_t bytes[], size_t numBytes, void* user) {
    BUFFER("bytes:", bytes, numBytes);
};

static void buttonCallback(void* user){
    //    button.disableInterrupt();
    //    transmitter.queueTransmission(counter.m8, sizeof(counter), txCallback, NULL);
    //    led[1].toggle();
    //    transmitter.notifyFromISR();
};

extern "C" void initializeApplication() {
    button.enableInterrupt(buttonCallback, NULL);

    transmitter.create(256, Task_Priority_MID);
    receiver.create(256, Task_Priority_HIGH);
}

extern "C" void applicationTaskFunction(void const* argument) {
    vTaskDelay(1000);

    transmitter.setTxBaseAddress(baseAddress);
    transmitter.setTxAddressPrefix(addressPrefix);
    transmitter.setDataRate(DataRate_2MBPS);
    transmitter.setCrcConfig(CrcConfig_2Bytes);
    transmitter.setChannel(2);
    transmitter.setOutputPower(OutputPower_m18dBm);
    transmitter.setRetryCount(0xF);
    transmitter.setRetryDelay(0xF);

    receiver.setRxBaseAddress_0(baseAddress);
    receiver.setRxAddressPrefix(0, addressPrefix);
    receiver.setDataRate(DataRate_2MBPS);
    receiver.setCrcConfig(CrcConfig_2Bytes);
    receiver.setChannel(2);
    receiver.setOutputPower(OutputPower_m18dBm);

    receiver.startListening(0, rxCallback, NULL);

    transmitter.switchOperatingMode(OperatingMode_Tx);
    receiver.switchOperatingMode(OperatingMode_Rx);

    for (;;) {
        led[0].set();
        transmitter.queueTransmission(counter.m8, sizeof(counter), txCallback, NULL);
        transmitter.notify();
        led[0].clear();

        vTaskDelay(250);
    }
}
<|endoftext|>