<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };
public:
    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs()); // map projection

            Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
            Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->set_size(m_.width(), m_.height());
                metaItr->second->set_map_srs(proj);
                metaItr->second->start(m_.metawriter_output_properties);
            }

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    apply_to_layer(lyr, p, proj, scale_denom);
                }
            }

            metaItr = m_.begin_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->stop();
            }
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }
private:
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0, double scale_denom)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif
        boost::shared_ptr<datasource> ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            box2d<double> ext = m_.get_buffered_extent();
            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name() << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n";
                std::clog << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            //

            box2d<double> layer_ext = lay.envelope();

            double lx0 = layer_ext.minx();
            double ly0 = layer_ext.miny();
            double lz0 = 0.0;
            double lx1 = layer_ext.maxx();
            double ly1 = layer_ext.maxy();
            double lz1 = 0.0;
            // back project layers extent into main map projection
            prj_trans.backward(lx0,ly0,lz0);
            prj_trans.backward(lx1,ly1,lz1);

            // if no intersection then nothing to do for layer
            if ( lx0 > ext.maxx() || lx1 < ext.minx() || ly0 > ext.maxy() || ly1 < ext.miny() )
            {
                return;
            }

            // clip query bbox
            lx0 = std::max(ext.minx(),lx0);
            ly0 = std::max(ext.miny(),ly0);
            lx1 = std::min(ext.maxx(),lx1);
            ly1 = std::min(ext.maxy(),ly1);

            prj_trans.forward(lx0,ly0,lz0);
            prj_trans.forward(lx1,ly1,lz1);
            box2d<double> bbox(lx0,ly0,lx1,ly1);

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height());
            query q(bbox,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            std::set<std::string> names;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            std::vector<std::string> const& style_names = lay.styles();
            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && style_names.size()>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<commit_msg>if 'maximum-extent' is provided, clip map query extent to it allowing one simple and fast way of controlling out of bounds coordinates when projecting into/from layer projection - see also solution at #549<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };
public:
    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs()); // map projection

            Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
            Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->set_size(m_.width(), m_.height());
                metaItr->second->set_map_srs(proj);
                metaItr->second->start(m_.metawriter_output_properties);
            }

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    apply_to_layer(lyr, p, proj, scale_denom);
                }
            }

            metaItr = m_.begin_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->stop();
            }
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }
private:
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0, double scale_denom)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif
        boost::shared_ptr<datasource> ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            box2d<double> ext = m_.get_buffered_extent();

            // clip buffered extent by maximum extent, if supplied
            boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
            if (maximum_extent) {
                ext.clip(*maximum_extent);
            }

            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name() << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n";
                std::clog << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            //

            box2d<double> layer_ext = lay.envelope();

            double lx0 = layer_ext.minx();
            double ly0 = layer_ext.miny();
            double lz0 = 0.0;
            double lx1 = layer_ext.maxx();
            double ly1 = layer_ext.maxy();
            double lz1 = 0.0;
            // back project layers extent into main map projection
            prj_trans.backward(lx0,ly0,lz0);
            prj_trans.backward(lx1,ly1,lz1);

            // if no intersection then nothing to do for layer
            if ( lx0 > ext.maxx() || lx1 < ext.minx() || ly0 > ext.maxy() || ly1 < ext.miny() )
            {
                return;
            }

            // clip query bbox
            lx0 = std::max(ext.minx(),lx0);
            ly0 = std::max(ext.miny(),ly0);
            lx1 = std::min(ext.maxx(),lx1);
            ly1 = std::min(ext.maxy(),ly1);

            prj_trans.forward(lx0,ly0,lz0);
            prj_trans.forward(lx1,ly1,lz1);
            box2d<double> bbox(lx0,ly0,lx1,ly1);

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height());
            query q(bbox,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            std::set<std::string> names;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            std::vector<std::string> const& style_names = lay.styles();
            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && style_names.size()>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//
//  Base Class
//  Produces the data needed to calculate the quality assurance.
//  All data must be mergeable objects.
//  Y. Schutz CERN July 2007
//

// --- ROOT system ---
#include <TSystem.h>
#include <TFile.h>
#include <TList.h>
#include <TTree.h>
#include <TClonesArray.h>
#include <TParameter.h>
#include <TH1K.h>
#include <TH2C.h>
#include <TH2D.h>
#include <TH2F.h>
#include <TH2I.h>
#include <TH3C.h>
#include <TH3D.h>
#include <TH3F.h>
#include <TH3I.h>
#include <TH3S.h>

// --- Standard library ---

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliQADataMaker.h"
#include "AliQAChecker.h"
#include "AliESDEvent.h"
#include "AliRawReader.h"

ClassImp(AliQADataMaker)

//____________________________________________________________________________
AliQADataMaker::AliQADataMaker(const char * name, const char * title) :
  TNamed(name, title),
  fOutput(0x0),
  fDetectorDir(0x0),
  fDetectorDirName(""),
  fCurrentCycle(0),
  fCycle(9999999),
  fCycleCounter(0),
  fWriteExpert(kFALSE),
  fParameterList(new TList*[AliRecoParam::kNSpecies]),
  fRun(0),
  fEventSpecie(AliRecoParam::kDefault)
{
  // ctor
  fDetectorDirName = GetName() ;
  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    fParameterList[specie] = NULL ;
}

//____________________________________________________________________________
AliQADataMaker::AliQADataMaker(const AliQADataMaker& qadm) :
  TNamed(qadm.GetName(), qadm.GetTitle()),
  fOutput(qadm.fOutput),
  fDetectorDir(qadm.fDetectorDir),
  fDetectorDirName(qadm.fDetectorDirName),
  fCurrentCycle(qadm.fCurrentCycle),
  fCycle(qadm.fCycle),
  fCycleCounter(qadm.fCycleCounter),
  fWriteExpert(qadm.fWriteExpert),
  fParameterList(qadm.fParameterList),
  fRun(qadm.fRun),
  fEventSpecie(qadm.fEventSpecie)
{
  //copy ctor
  fDetectorDirName = GetName() ;
}

//____________________________________________________________________________
Int_t AliQADataMaker::Add2List(TH1 * hist, const Int_t index, TObjArray ** list, const Bool_t expert, const Bool_t saveForCorr)
{
	// Set histograms memory resident and add to the list
	// Maximm allowed is 10000

  Int_t rv = -1 ;
  TClass * classType = hist->Class() ;
  TString className(classType->GetName()) ;
  if( ! className.BeginsWith("T") && ! classType->InheritsFrom("TH1") ) {
    AliError(Form("QA data Object must be a generic ROOT object and derive fom TH1 and not %s", className.Data())) ;
	} else if ( index > 10000 ) {
		AliError("Max number of authorized QA objects is 10000") ;
  } else {
    if (expert)
      hist->SetBit(AliQA::GetExpertBit()) ;
		TH1 * histClone[AliRecoParam::kNSpecies] ;
    for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
      histClone[specie] = CloneMe(hist, specie) ;
      histClone[specie]->SetDirectory(0) ;
      list[specie]->AddAtAndExpand(histClone[specie], index) ;
      if(saveForCorr) {
        char * name = Form("%s_%s", list[AliRecoParam::kDefault]->GetName(), hist->GetName()) ;
        TParameter<double> * p = new TParameter<double>(name, 9999.9999) ;
        if ( fParameterList[specie] == NULL )
          fParameterList[specie] = new TList() ;
        fParameterList[specie]->Add(p) ;
      }
    }
    rv = list[AliRecoParam::kDefault]->GetLast() ;
  }
  delete hist ;
  return rv ;
}

//____________________________________________________________________________
TH1 *  AliQADataMaker::CloneMe(TH1 * hist, Int_t specie) const
{
  // clones a histogram
  char * name = Form("%s_%s", AliRecoParam::GetEventSpecieName(specie), hist->GetName()) ;
  return dynamic_cast<TH1 *>(hist->Clone(name)) ;
}

//____________________________________________________________________________
void AliQADataMaker::DefaultEndOfDetectorCycle(AliQA::TASKINDEX_t task)
{
	// this method must be oveloaded by detectors
	// sets the QA result to Fatal
	AliQA::Instance(AliQA::GetDetIndex(GetName())) ;
	AliQA * qa = AliQA::Instance(task) ;
  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    qa->Set(AliQA::kFATAL, specie) ;
	AliQA::GetQAResultFile()->cd() ;
	qa->Write(AliQA::GetQAName(), kWriteDelete) ;
	AliQA::GetQAResultFile()->Close() ;
}

//____________________________________________________________________________
void AliQADataMaker::Finish() const
{
	// write to the output File
	if (fOutput)
		fOutput->Close() ;
}

//____________________________________________________________________________
TObject * AliQADataMaker::GetData(TObjArray ** list, const Int_t index)
{
	// Returns the QA object at index. Limit is 100.
	if (list[AliRecoParam::AConvert(fEventSpecie)]) {
		if ( index > 10000 ) {
			AliError("Max number of authorized QA objects is 10000") ;
			return NULL ;
		} else {
      Int_t esindex = AliRecoParam::AConvert(fEventSpecie) ;
      return list[esindex]->At(index) ;
		}
  } else {
		AliError("Data list is NULL !!") ;
		return NULL ;
	}
}
<commit_msg>added protection in case the QA object list is not initialized<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//
//  Base Class
//  Produces the data needed to calculate the quality assurance.
//  All data must be mergeable objects.
//  Y. Schutz CERN July 2007
//

// --- ROOT system ---
#include <TSystem.h>
#include <TFile.h>
#include <TList.h>
#include <TTree.h>
#include <TClonesArray.h>
#include <TParameter.h>
#include <TH1K.h>
#include <TH2C.h>
#include <TH2D.h>
#include <TH2F.h>
#include <TH2I.h>
#include <TH3C.h>
#include <TH3D.h>
#include <TH3F.h>
#include <TH3I.h>
#include <TH3S.h>

// --- Standard library ---

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliQADataMaker.h"
#include "AliQAChecker.h"
#include "AliESDEvent.h"
#include "AliRawReader.h"

ClassImp(AliQADataMaker)

//____________________________________________________________________________
AliQADataMaker::AliQADataMaker(const char * name, const char * title) :
  TNamed(name, title),
  fOutput(0x0),
  fDetectorDir(0x0),
  fDetectorDirName(""),
  fCurrentCycle(0),
  fCycle(9999999),
  fCycleCounter(0),
  fWriteExpert(kFALSE),
  fParameterList(new TList*[AliRecoParam::kNSpecies]),
  fRun(0),
  fEventSpecie(AliRecoParam::kDefault)
{
  // ctor
  fDetectorDirName = GetName() ;
  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    fParameterList[specie] = NULL ;
}

//____________________________________________________________________________
AliQADataMaker::AliQADataMaker(const AliQADataMaker& qadm) :
  TNamed(qadm.GetName(), qadm.GetTitle()),
  fOutput(qadm.fOutput),
  fDetectorDir(qadm.fDetectorDir),
  fDetectorDirName(qadm.fDetectorDirName),
  fCurrentCycle(qadm.fCurrentCycle),
  fCycle(qadm.fCycle),
  fCycleCounter(qadm.fCycleCounter),
  fWriteExpert(qadm.fWriteExpert),
  fParameterList(qadm.fParameterList),
  fRun(qadm.fRun),
  fEventSpecie(qadm.fEventSpecie)
{
  //copy ctor
  fDetectorDirName = GetName() ;
}

//____________________________________________________________________________
Int_t AliQADataMaker::Add2List(TH1 * hist, const Int_t index, TObjArray ** list, const Bool_t expert, const Bool_t saveForCorr)
{
	// Set histograms memory resident and add to the list
	// Maximm allowed is 10000

  Int_t rv = -1 ;
  TClass * classType = hist->Class() ;
  TString className(classType->GetName()) ;
  if( ! className.BeginsWith("T") && ! classType->InheritsFrom("TH1") ) {
    AliError(Form("QA data Object must be a generic ROOT object and derive fom TH1 and not %s", className.Data())) ;
	} else if ( index > 10000 ) {
		AliError("Max number of authorized QA objects is 10000") ;
  } else {
    if (expert)
      hist->SetBit(AliQA::GetExpertBit()) ;
		TH1 * histClone[AliRecoParam::kNSpecies] ;
    for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
      histClone[specie] = CloneMe(hist, specie) ;
      histClone[specie]->SetDirectory(0) ;
      list[specie]->AddAtAndExpand(histClone[specie], index) ;
      if(saveForCorr) {
        char * name = Form("%s_%s", list[AliRecoParam::kDefault]->GetName(), hist->GetName()) ;
        TParameter<double> * p = new TParameter<double>(name, 9999.9999) ;
        if ( fParameterList[specie] == NULL )
          fParameterList[specie] = new TList() ;
        fParameterList[specie]->Add(p) ;
      }
    }
    rv = list[AliRecoParam::kDefault]->GetLast() ;
  }
  delete hist ;
  return rv ;
}

//____________________________________________________________________________
TH1 *  AliQADataMaker::CloneMe(TH1 * hist, Int_t specie) const
{
  // clones a histogram
  char * name = Form("%s_%s", AliRecoParam::GetEventSpecieName(specie), hist->GetName()) ;
  return dynamic_cast<TH1 *>(hist->Clone(name)) ;
}

//____________________________________________________________________________
void AliQADataMaker::DefaultEndOfDetectorCycle(AliQA::TASKINDEX_t task)
{
	// this method must be oveloaded by detectors
	// sets the QA result to Fatal
	AliQA::Instance(AliQA::GetDetIndex(GetName())) ;
	AliQA * qa = AliQA::Instance(task) ;
  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    qa->Set(AliQA::kFATAL, specie) ;
	AliQA::GetQAResultFile()->cd() ;
	qa->Write(AliQA::GetQAName(), kWriteDelete) ;
	AliQA::GetQAResultFile()->Close() ;
}

//____________________________________________________________________________
void AliQADataMaker::Finish() const
{
	// write to the output File
	if (fOutput)
		fOutput->Close() ;
}

//____________________________________________________________________________
TObject * AliQADataMaker::GetData(TObjArray ** list, const Int_t index)
{
	// Returns the QA object at index. Limit is 100.
  if ( ! list ) {
		AliError("Data list is NULL !!") ;
		return NULL ;
	}
	if (list[AliRecoParam::AConvert(fEventSpecie)]) {
		if ( index > 10000 ) {
			AliError("Max number of authorized QA objects is 10000") ;
			return NULL ;
		} else {
      Int_t esindex = AliRecoParam::AConvert(fEventSpecie) ;
      return list[esindex]->At(index) ;
		}
  } else {
		AliError("Data list is NULL !!") ;
		return NULL ;
	}
}
<|endoftext|>


<commit_before>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "circles.h"
#include "debug.h"
#include "const.h"
#include <iostream>

using namespace cv;
using namespace std;
//Mat src_gray;

Mat out_src;
namespace bc {
	void find_circles(Mat& src, cv::vector<cv::Vec<float, 3>>& circles){
		Mat input_gray(src.rows, src.cols, CV_8UC3);
		int from_to[] = { 0,0, 1,1, 1,2 };
		mixChannels(&src, 1, &input_gray, 1, from_to, 3); // drop color channels
		cvtColor(input_gray, input_gray, CV_BGR2GRAY);

		/// Apply the Hough Transform to find the circles
		ts("circle");
		HoughCircles(input_gray, circles, CV_HOUGH_GRADIENT, 1, MIN_DIST, UPPER_EDGE, CENTER_THRESH, MIN_RADIUS, MAX_RADIUS);
		te("circle");
		imshow(CAM_WIN, input_gray);
	}
	void draw_circles(Mat& src, vector<Vec3f>& circles){
		out_src = Mat::zeros(OUT_HEIGHT, OUT_WIDTH, CV_8UC3);

		out_src = Scalar(OUT_BG);
		for (size_t i = 0; i < circles.size(); i++)
		{
			Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
			if (center.x < 50 && center.y < 50){
				cout << "Hot corner" << endl;
			}
			int radius = cvRound(circles[i][2]);
			// circle center
			circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
			// circle outline
			circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);

			Point scaled_center = Point((float)center.x, (float)center.y);
			circle(out_src, scaled_center, radius, Scalar(CIRCLE_COLOR), 3, 8, 0);
		}
		frun(text_ovl(src, std::to_string((int)fps_end("loop")) + " fps", Point(0,15), Scalar(255, 0, 100)));
	}
	void draw_blobs(Mat& src){
		Mat canny_output;
		vector<vector<Point>> blobs;
		vector<Vec4i> hierarchy;
		Canny(src, canny_output, BLOB_THRESH, BLOB_THRESH * 2, 3);
		/// Find contours
		findContours(canny_output, blobs, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

		/// Draw contours
		//for (int i = 0; i< blobs.size(); i++)
		//{
			drawContours(out_src, blobs, -1, Scalar(255,255,255), CV_FILLED, 8, hierarchy, 0, Point());
		//}
	}

	void redraw(Mat& src){
		resize(out_src, out_src, Size(OUT_WIDTH, OUT_HEIGHT));
		imshow(MAIN_WIN, src);
		imshow(OUT_WIN, out_src);
	}
}<commit_msg>Fix only one blob being drawn<commit_after>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "circles.h"
#include "debug.h"
#include "const.h"
#include <iostream>

using namespace cv;
using namespace std;
//Mat src_gray;

Mat out_src;
namespace bc {
	void find_circles(Mat& src, cv::vector<cv::Vec<float, 3>>& circles){
		Mat input_gray(src.rows, src.cols, CV_8UC3);
		int from_to[] = { 0,0, 1,1, 1,2 };
		mixChannels(&src, 1, &input_gray, 1, from_to, 3); // drop color channels
		cvtColor(input_gray, input_gray, CV_BGR2GRAY);

		/// Apply the Hough Transform to find the circles
		ts("circle");
		HoughCircles(input_gray, circles, CV_HOUGH_GRADIENT, 1, MIN_DIST, UPPER_EDGE, CENTER_THRESH, MIN_RADIUS, MAX_RADIUS);
		te("circle");
		imshow(CAM_WIN, input_gray);
	}
	void draw_circles(Mat& src, vector<Vec3f>& circles){
		out_src = Mat::zeros(OUT_HEIGHT, OUT_WIDTH, CV_8UC3);

		out_src = Scalar(OUT_BG);
		for (size_t i = 0; i < circles.size(); i++)
		{
			Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
			if (center.x < 50 && center.y < 50){
				cout << "Hot corner" << endl;
			}
			int radius = cvRound(circles[i][2]);
			// circle center
			circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
			// circle outline
			circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);

			Point scaled_center = Point((float)center.x, (float)center.y);
			circle(out_src, scaled_center, radius, Scalar(CIRCLE_COLOR), 3, 8, 0);
		}
		frun(text_ovl(src, std::to_string((int)fps_end("loop")) + " fps", Point(0,15), Scalar(255, 0, 100)));
	}
	void draw_blobs(Mat& src){
		Mat canny_output;
		vector<vector<Point>> blobs;
		vector<Vec4i> hierarchy;
		Canny(src, canny_output, BLOB_THRESH, BLOB_THRESH * 2, 3);
		/// Find contours
		findContours(canny_output, blobs, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

		/// Draw contours
		for (int i = 0; i< blobs.size(); i++)
		{
			drawContours(out_src, blobs, i, Scalar(255,255,255), CV_FILLED, 8, hierarchy, 0, Point());
		}
	}

	void redraw(Mat& src){
		resize(out_src, out_src, Size(OUT_WIDTH, OUT_HEIGHT));
		imshow(MAIN_WIN, src);
		imshow(OUT_WIN, out_src);
	}
}<|endoftext|>


<commit_before>#include "Physics2012Vdb.h"

Physics2012Vdb::Physics2012Vdb() {

}

Physics2012Vdb::~Physics2012Vdb() {

}

void Physics2012Vdb::initHk() {
	memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo(1024 * 1024));
	hkBaseSystem::init(memoryRouter, errorReport);

	// Initialize the monitor stream so that we can send timing information to the Visual Debugger.
	const int monitorSize = 128 * 1024;
	hkMonitorStream& stream = hkMonitorStream::getInstance();
	stream.resize(monitorSize);
	stream.reset();
}

void Physics2012Vdb::run() {
	initPhysics();

	vdb.setVisualDebugger(m_world);

	hkStopwatch stopWatch;
	stopWatch.start();

	hkReal lastTime = stopWatch.getElapsedSeconds();

	const int numStepsPerSecond = 60;
	const hkReal timeStep = 1.0f / hkReal(numStepsPerSecond);

	for (int i = 0; i < numStepsPerSecond * 10; i++) {
		m_world->stepDeltaTime(timeStep);

		vdb.step();

		hkMonitorStream::getInstance().reset();

		//display the position of the rigid body every second
		if (i % 60 == 0) {
			hkVector4 pos = rigidBody->getPosition();
			printf("[%f, %f, %f]\n", pos(0), pos(1), pos(2));
		}

		while (stopWatch.getElapsedSeconds() < lastTime + timeStep);

		lastTime += timeStep;
	}
}

void Physics2012Vdb::quitHk() {
	rigidBody->removeReference();
	m_world->removeReference();

	vdb.quitVdb();

	hkBaseSystem::quit();
	hkMemoryInitUtil::quit();
}

void Physics2012Vdb::initPhysics() {
	m_world = new hkpWorld(hkpWorldCinfo());
	//disable world gravity
	m_world->setGravity(hkVector4::getZero());

	hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

	hkVector4 halfExtents(0.5f, 1.0f, 1.5f);
	hkpBoxShape* boxShape = new hkpBoxShape(halfExtents);

	hkpRigidBodyCinfo bodyCInfo;
	bodyCInfo.m_shape = boxShape;

	const hkReal boxMass = 10.0f;
	hkMassProperties massProperties;
	hkpInertiaTensorComputer::computeShapeVolumeMassProperties(boxShape, boxMass, massProperties);

	bodyCInfo.setMassProperties(massProperties);

	rigidBody = new hkpRigidBody(bodyCInfo);
	boxShape->removeReference();

	m_world->addEntity(rigidBody);
}<commit_msg>Delete Physics2012Vdb.cpp<commit_after><|endoftext|>


<commit_before>/*************************************
** Tsunagari Tile Engine            **
** window.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

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

#include "av/sdl2/window.h"

#include <chrono>
#include <thread>

#include "av/sdl2/error.h"
#include "core/client-conf.h"
#include "core/log.h"
#include "core/measure.h"
#include "core/world.h"

#define CHECK(x)  if (!(x)) { return false; }

static SDL2GameWindow globalWindow;

GameWindow* GameWindow::create() {
    return globalWindow.init() ? &globalWindow
                               : nullptr;
}

GameWindow& GameWindow::instance() {
    return globalWindow;
}

SDL2GameWindow& SDL2GameWindow::instance() {
    return globalWindow;
}

time_t GameWindow::time() {
    std::chrono::time_point<std::chrono::steady_clock> start = globalWindow.start;
    std::chrono::time_point<std::chrono::steady_clock> end = std::chrono::steady_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

SDL_Renderer* SDL2GetRenderer() {
    return globalWindow.renderer;
}

SDL2GameWindow::SDL2GameWindow()
    : renderer(nullptr),
      translation(0.0, 0.0),
      scaling(0.0, 0.0),
      window(nullptr),
      transform(Transform::identity()) {}

bool SDL2GameWindow::init() {
    {
        //TimeMeasure m("Initializing SDL2");
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            sdlDie("SDL2GameWindow", "SDL_Init");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 window");

        int width = conf.windowSize.x;
        int height = conf.windowSize.y;

        Uint32 flags = SDL_WINDOW_HIDDEN;
        if (conf.fullscreen) {
            flags |= SDL_WINDOW_FULLSCREEN;
        }

        window = SDL_CreateWindow("Tsunagari",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  width, height, flags);

        if (window == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateWindow");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 renderer");

        Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;

        renderer = SDL_CreateRenderer(window, -1, flags);

        if (renderer == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateRenderer");
            return false;
        }
    }

    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);

    return true;
}

unsigned SDL2GameWindow::width() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(w);
}

unsigned SDL2GameWindow::height() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(h);
}

void SDL2GameWindow::setCaption(const std::string& caption) {
    SDL_SetWindowTitle(window, caption.c_str());
}

void SDL2GameWindow::mainLoop() {
    SDL_ShowWindow(window);
    while (window != nullptr) {
        handleEvents();
        World::instance().update(time());
        World::instance().draw();
        SDL_RenderPresent(renderer);
    }
}

void SDL2GameWindow::handleEvents() {
    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        handleEvent(event);
    }
}

void SDL2GameWindow::handleEvent(const SDL_Event& event) {
    switch (event.type) {
    case SDL_KEYDOWN: {
        switch (event.key.keysym.sym) {
        case SDLK_ESCAPE:
            //exit(0);
            break;
        }
        break;
    }
    case SDL_QUIT:
        exit(0);
        break;
    }
}

void SDL2GameWindow::drawRect(double x1, double x2, double y1, double y2,
              uint32_t argb) {
    auto a = static_cast<Uint8>((argb >> 24) & 0xFF);
    auto r = static_cast<Uint8>((argb >> 16) & 0xFF);
    auto g = static_cast<Uint8>((argb >>  8) & 0xFF);
    auto b = static_cast<Uint8>((argb >>  0) & 0xFF);

    SDL_Rect rect{static_cast<int>(x1),
                  static_cast<int>(y1),
                  static_cast<int>(x2 - x1),
                  static_cast<int>(y2 - y1)};

    SDL_SetRenderDrawColor(renderer, r, g, b, a);
    SDL_RenderDrawRect(renderer, &rect);
}

void SDL2GameWindow::scale(double x, double y, std::function<void()> op) {
    assert_(x == y);

    Transform prev = transform;

    auto factor = static_cast<float>(x);

    transform = Transform::scale(factor) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::translate(double x, double y, std::function<void()> op) {
    Transform prev = transform;

    transform = Transform::translate(static_cast<float>(x),
                                     static_cast<float>(y)) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::clip(double x, double y, double width, double height,
                          std::function<void()> op) {
    op();
}

void SDL2GameWindow::close() {
    SDL_DestroyWindow(window);
    window = nullptr;
}

void SDL2GameWindow::updateTransform() {
    int w, h;

    SDL_GetWindowSize(window, &w, &h);

    double xScale = transform[0];
    double yScale = transform[5];
    double x = transform[12];
    double y = transform[13];

    translation = {x / xScale, y / yScale};
    scaling = {xScale, yScale};
}
<commit_msg>SDL2Window: Implement keyboard input<commit_after>/*************************************
** Tsunagari Tile Engine            **
** window.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

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

#include "av/sdl2/window.h"

#include <chrono>
#include <thread>

#include "av/sdl2/error.h"
#include "core/client-conf.h"
#include "core/log.h"
#include "core/measure.h"
#include "core/world.h"
#include "util/optional.h"

#define CHECK(x)  if (!(x)) { return false; }

static SDL2GameWindow globalWindow;

GameWindow* GameWindow::create() {
    return globalWindow.init() ? &globalWindow
                               : nullptr;
}

GameWindow& GameWindow::instance() {
    return globalWindow;
}

SDL2GameWindow& SDL2GameWindow::instance() {
    return globalWindow;
}

time_t GameWindow::time() {
    std::chrono::time_point<std::chrono::steady_clock> start = globalWindow.start;
    std::chrono::time_point<std::chrono::steady_clock> end = std::chrono::steady_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

SDL_Renderer* SDL2GetRenderer() {
    return globalWindow.renderer;
}

SDL2GameWindow::SDL2GameWindow()
    : renderer(nullptr),
      translation(0.0, 0.0),
      scaling(0.0, 0.0),
      window(nullptr),
      transform(Transform::identity()) {}

bool SDL2GameWindow::init() {
    {
        //TimeMeasure m("Initializing SDL2");
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            sdlDie("SDL2GameWindow", "SDL_Init");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 window");

        int width = conf.windowSize.x;
        int height = conf.windowSize.y;

        Uint32 flags = SDL_WINDOW_HIDDEN;
        if (conf.fullscreen) {
            flags |= SDL_WINDOW_FULLSCREEN;
        }

        window = SDL_CreateWindow("Tsunagari",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  width, height, flags);

        if (window == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateWindow");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 renderer");

        Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;

        renderer = SDL_CreateRenderer(window, -1, flags);

        if (renderer == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateRenderer");
            return false;
        }
    }

    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);

    return true;
}

unsigned SDL2GameWindow::width() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(w);
}

unsigned SDL2GameWindow::height() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(h);
}

void SDL2GameWindow::setCaption(const std::string& caption) {
    SDL_SetWindowTitle(window, caption.c_str());
}

void SDL2GameWindow::mainLoop() {
    SDL_ShowWindow(window);
    while (window != nullptr) {
        handleEvents();
        World::instance().update(time());
        World::instance().draw();
        SDL_RenderPresent(renderer);
    }
}

void SDL2GameWindow::handleEvents() {
    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        handleEvent(event);
    }
}

void SDL2GameWindow::handleEvent(const SDL_Event& event) {
    KeyboardKey key;

    switch (event.type) {
    case SDL_KEYUP:
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym) {
        case SDLK_ESCAPE: key = KBEscape; break;
        case SDLK_LCTRL: key = KBLeftControl; break;
        case SDLK_RCTRL: key = KBRightControl; break;
        case SDLK_LSHIFT: key = KBLeftShift; break;
        case SDLK_RSHIFT: key = KBRightShift; break;
        case SDLK_SPACE: key = KBSpace; break;
        case SDLK_LEFT: key = KBLeftArrow; break;
        case SDLK_RIGHT: key = KBRightArrow; break;
        case SDLK_UP: key = KBUpArrow; break;
        case SDLK_DOWN: key = KBDownArrow; break;
        default: return;
        }
        if (event.type == SDL_KEYUP) {
            emitKeyUp(key);
        }
        else if (event.type == SDL_KEYDOWN) {
            emitKeyDown(key);
        }
        break;

    case SDL_QUIT:
        exit(0);
        return;

    default:
        return;
    }
}

void SDL2GameWindow::drawRect(double x1, double x2, double y1, double y2,
              uint32_t argb) {
    auto a = static_cast<Uint8>((argb >> 24) & 0xFF);
    auto r = static_cast<Uint8>((argb >> 16) & 0xFF);
    auto g = static_cast<Uint8>((argb >>  8) & 0xFF);
    auto b = static_cast<Uint8>((argb >>  0) & 0xFF);

    SDL_Rect rect{static_cast<int>(x1),
                  static_cast<int>(y1),
                  static_cast<int>(x2 - x1),
                  static_cast<int>(y2 - y1)};

    SDL_SetRenderDrawColor(renderer, r, g, b, a);
    SDL_RenderDrawRect(renderer, &rect);
}

void SDL2GameWindow::scale(double x, double y, std::function<void()> op) {
    assert_(x == y);

    Transform prev = transform;

    auto factor = static_cast<float>(x);

    transform = Transform::scale(factor) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::translate(double x, double y, std::function<void()> op) {
    Transform prev = transform;

    transform = Transform::translate(static_cast<float>(x),
                                     static_cast<float>(y)) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::clip(double x, double y, double width, double height,
                          std::function<void()> op) {
    op();
}

void SDL2GameWindow::close() {
    SDL_DestroyWindow(window);
    window = nullptr;
}

void SDL2GameWindow::updateTransform() {
    int w, h;

    SDL_GetWindowSize(window, &w, &h);

    double xScale = transform[0];
    double yScale = transform[5];
    double x = transform[12];
    double y = transform[13];

    translation = {x / xScale, y / yScale};
    scaling = {xScale, yScale};
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/wallet/mnemonic.hpp>

#include <algorithm>
#include <cstdint>
#include <boost/locale.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/formats/base16.hpp>
#include <bitcoin/bitcoin/math/external/pkcs5_pbkdf2.h>
#include <bitcoin/bitcoin/utility/assert.hpp>
#include <bitcoin/bitcoin/utility/binary.hpp>
#include <bitcoin/bitcoin/utility/general.hpp>
#include <bitcoin/bitcoin/wallet/dictionary.hpp>

namespace libbitcoin {

// Bip-39 constants.
constexpr size_t bip39_check_size = 4;
constexpr size_t min_word_count = 12;
constexpr size_t max_word_count = 128;
constexpr size_t hmac_iterations = 2048;
constexpr size_t dictionary_length = 2048;
// the number of bits consumed for each word index
constexpr size_t bip39_index_bits = 11;

// It would be nice if we could do this statically.
static void validate_dictionary()
{
    BITCOIN_ASSERT_MSG(bip39_dictionary.size() == sizeof(bip39_language),
        "The dictionary does not have the required number of languages.");

#ifndef NDEBUG
    for (const auto& dictionary: bip39_dictionary)
    {
        BITCOIN_ASSERT_MSG(dictionary.second.size() == dictionary_length,
            "A dictionary does not have the required number of elements.");
    }
#endif
}

static const string_list& get_dictionary(bip39_language language)
{
    validate_dictionary();

    const auto it = bip39_dictionary.find(language);

    // We should *always* find the language.
    BITCOIN_ASSERT(it != bip39_dictionary.end());
    return it->second;
}

static bip39_language get_language(const string_list& words)
{
    validate_dictionary();

    if (words.empty())
        return bip39_language::en;

    const auto& first_word = words.front();

    for (const auto& dictionary: bip39_dictionary)
        if (find_position(dictionary.second, first_word) != -1)
            return dictionary.first;

    return bip39_language::en;
}

static std::string normalize_nfkd(const std::string& value)
{
    using namespace boost::locale;
    const generator locale;
    return normalize(value, norm_type::norm_nfkd, locale(""));
}

static uint8_t bip39_shift(size_t bit)
{
    return (1 << (byte_bits - (bit % byte_bits) - 1));
}

// extracts entropy/checksum from the mnemonic and rebuilds the word list
// for comparison; returns true if it's a match (valid), false otherwise
static bool validate_mnemonic(const string_list& words,
    const string_list& dictionary, bip39_language language)
{
    const auto word_count = words.size();
    if ((word_count < min_word_count) || (word_count > max_word_count))
        return false;

    size_t bit = 0;
    data_chunk seed(max_word_count, 0);

    for (const auto& word: words)
    {
        const auto position = find_position(dictionary, word);
        if (position == -1)
            return false;

        for (size_t loop = 0; loop < bip39_index_bits; loop++, bit++)
        {
            if (position & (1 << (bip39_index_bits - loop - 1)))
            {
                const auto byte = bit / byte_bits;
                seed[byte] |= bip39_shift(bit);
            }
        }
    }

    const auto size = bit / byte_bits;
    seed.resize(size);

    const auto mnemonic = encode_mnemonic(seed, language);
    return std::equal(mnemonic.begin(), mnemonic.end(), words.begin());
}

data_chunk decode_mnemonic(const string_list& words,
    const std::string& passphrase)
{
    const auto language = get_language(words);
    const auto& dictionary = get_dictionary(language);

    if (!validate_mnemonic(words, dictionary, language))
        return data_chunk();

    const auto mnemonic = join(words);
    const auto salt = normalize_nfkd("mnemonic" + passphrase);
    const auto salt_chunk = to_data_chunk(salt);

    long_hash hash;
    if (pkcs5_pbkdf2_hmac_sha512(
            mnemonic, salt_chunk, hmac_iterations, hash))
        return data_chunk(hash.begin(), hash.end());

    return data_chunk();
}

string_list encode_mnemonic(data_slice seed, bip39_language language)
{
    if ((seed.size() % bip39_check_size) != 0)
        return string_list();

    const auto& dictionary = get_dictionary(language);
    const auto hash = sha256_hash(seed);
    auto chunk = to_data_chunk(seed);
    extend_data(chunk, hash);

    const size_t seed_bits = (seed.size() * byte_bits);
    const size_t check_bits = (chunk.size() / bip39_check_size);
    const size_t total_bits = (seed_bits + check_bits);
    const size_t word_count = (total_bits / bip39_index_bits);

    BITCOIN_ASSERT((total_bits % bip39_index_bits) == 0);
    BITCOIN_ASSERT((word_count % 3) == 0);

    size_t bit = 0;
    string_list words;

    for (size_t word = 0; word < word_count; word++)
    {
        size_t position = 0;
        for (size_t loop = 0; loop < bip39_index_bits; loop++)
        {
            bit = (word * bip39_index_bits + loop);
            position <<= 1;

            const auto byte = bit / byte_bits;

            if ((chunk[byte] & bip39_shift(bit)) > 0)
                position++;
        }
        BITCOIN_ASSERT(position < dictionary_length);

        words.push_back(dictionary[position]);
    }

    BITCOIN_ASSERT(words.size() == (bit / bip39_index_bits));
    return words;
}

} // namespace libbitcoin

<commit_msg>- Merge branch 'bip-39' of https://github.com/evoskuil/libbitcoin into bip-39<commit_after>/*
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/wallet/mnemonic.hpp>

#include <algorithm>
#include <cstdint>
#include <boost/locale.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/formats/base16.hpp>
#include <bitcoin/bitcoin/math/external/pkcs5_pbkdf2.h>
#include <bitcoin/bitcoin/utility/assert.hpp>
#include <bitcoin/bitcoin/utility/binary.hpp>
#include <bitcoin/bitcoin/utility/general.hpp>
#include <bitcoin/bitcoin/wallet/dictionary.hpp>

namespace libbitcoin {

// Bip-39 constants.
constexpr size_t bip39_check_size = 4;
constexpr size_t min_word_count = 12;
constexpr size_t max_word_count = 128;
constexpr size_t hmac_iterations = 2048;
constexpr size_t dictionary_length = 2048;
// the number of bits consumed for each word index
constexpr size_t bip39_index_bits = 11;

// It would be nice if we could do this statically.
static void validate_dictionary()
{
    BITCOIN_ASSERT_MSG(bip39_dictionary.size() == sizeof(bip39_language),
        "The dictionary does not have the required number of languages.");

#ifndef NDEBUG
    for (const auto& dictionary: bip39_dictionary)
    {
        BITCOIN_ASSERT_MSG(dictionary.second.size() == dictionary_length,
            "A dictionary does not have the required number of elements.");
    }
#endif
}

static const string_list& get_dictionary(bip39_language language)
{
    validate_dictionary();

    const auto it = bip39_dictionary.find(language);

    // We should *always* find the language.
    BITCOIN_ASSERT(it != bip39_dictionary.end());
    return it->second;
}

static bip39_language get_language(const string_list& words)
{
    validate_dictionary();

    if (words.empty())
        return bip39_language::en;

    const auto& first_word = words.front();

    for (const auto& dictionary: bip39_dictionary)
        if (find_position(dictionary.second, first_word) != -1)
            return dictionary.first;

    return bip39_language::en;
}

static std::string normalize_nfkd(const std::string& value)
{
    using namespace boost::locale;
    const generator locale;
    return normalize(value, norm_type::norm_nfkd, locale(""));
}

static uint8_t bip39_shift(size_t bit)
{
    return (1 << (byte_bits - (bit % byte_bits) - 1));
}

// extracts entropy/checksum from the mnemonic and rebuilds the word list
// for comparison; returns true if it's a match (valid), false otherwise
static bool validate_mnemonic(const string_list& words,
    const string_list& dictionary, bip39_language language)
{
    const auto word_count = words.size();
    if ((word_count < min_word_count) || (word_count > max_word_count))
        return false;

    size_t bit = 0;
    data_chunk seed(max_word_count, 0);

    for (const auto& word: words)
    {
        const auto position = find_position(dictionary, word);
        if (position == -1)
            return false;

        for (size_t loop = 0; loop < bip39_index_bits; loop++, bit++)
        {
            if (position & (1 << (bip39_index_bits - loop - 1)))
            {
                const auto byte = bit / byte_bits;
                seed[byte] |= bip39_shift(bit);
            }
        }
    }

    const auto size = bit / byte_bits;
    seed.resize(size);

    const auto mnemonic = encode_mnemonic(seed, language);
    return std::equal(mnemonic.begin(), mnemonic.end(), words.begin());
}

data_chunk decode_mnemonic(const string_list& words,
    const std::string& passphrase)
{
    const auto language = get_language(words);
    const auto& dictionary = get_dictionary(language);

    if (!validate_mnemonic(words, dictionary, language))
        return data_chunk();

    const auto mnemonic = join(words);
    const auto salt = normalize_nfkd("mnemonic" + passphrase);
    const auto salt_chunk = to_data_chunk(salt);

    long_hash hash;
    if (pkcs5_pbkdf2_hmac_sha512(mnemonic, salt_chunk, hmac_iterations, hash))
        return to_data_chunk(hash);

    return data_chunk();
}

string_list encode_mnemonic(data_slice seed, bip39_language language)
{
    if ((seed.size() % bip39_check_size) != 0)
        return string_list();

    const auto& dictionary = get_dictionary(language);
    const auto hash = sha256_hash(seed);
    auto chunk = to_data_chunk(seed);
    extend_data(chunk, hash);

    const size_t seed_bits = (seed.size() * byte_bits);
    const size_t check_bits = (chunk.size() / bip39_check_size);
    const size_t total_bits = (seed_bits + check_bits);
    const size_t word_count = (total_bits / bip39_index_bits);

    BITCOIN_ASSERT((total_bits % bip39_index_bits) == 0);
    BITCOIN_ASSERT((word_count % 3) == 0);

    size_t bit = 0;
    string_list words;

    for (size_t word = 0; word < word_count; word++)
    {
        size_t position = 0;
        for (size_t loop = 0; loop < bip39_index_bits; loop++)
        {
            bit = (word * bip39_index_bits + loop);
            position <<= 1;

            const auto byte = bit / byte_bits;

            if ((chunk[byte] & bip39_shift(bit)) > 0)
                position++;
        }
        BITCOIN_ASSERT(position < dictionary_length);

        words.push_back(dictionary[position]);
    }

    BITCOIN_ASSERT(words.size() == (bit / bip39_index_bits));
    return words;
}

} // namespace libbitcoin

<|endoftext|>


<commit_before>/*
 * DatastoreDelayTestLayer.cpp
 *
 *  Created on: Nov 2, 2011
 *      Author: pschultz
 */

#include "DatastoreDelayTestLayer.hpp"

namespace PV {

DatastoreDelayTestLayer::DatastoreDelayTestLayer(const char* name, HyPerCol * hc) : ANNLayer(name, hc){
   initialize();
}

DatastoreDelayTestLayer::~DatastoreDelayTestLayer() {}

int DatastoreDelayTestLayer::initialize() {
   inited = false; // The first call to updateV sets this to true, so that the class knows whether to initialize or not.
   period = -1; // Can't set period until number of delay levels is determined, but that's determined by the connections,
                // which can't be created until after initialization is finished.  period will be set in the first call to updateV
   return PV_SUCCESS;
}

int DatastoreDelayTestLayer::updateV() {
   const PVLayerLoc * loc = getLayerLoc();
   int nx = loc->nx;
   int ny = loc->ny;
   int nf = loc->nf;
   if( inited ) {
      // Rotate values by one row.
      // This is not MPI-ically correct!
      // Move everything down one row; clobbering row 0 in the process
      for( int y=ny-1; y>0; y-- ) {
         for( int x=0; x<nx; x++ ) {
            for( int f=0; f<nf; f++ ) {
               getV()[kIndex(x,y,f,nx,ny,nf)] = getV()[kIndex(x,y-1,f,nx,ny,nf)];
            }
         }
      }
      // Finally, copy period-th row to zero-th row
      for( int x=0; x<loc->ny; x++ ) {
         for( int f=0; f<loc->nf; f++ ) {
            getV()[kIndex(x,0,f,nx,ny,nf)] = getV()[kIndex(x,period,f,nx,ny,nf)];
         }
      }
   }
   else {
      period = parent->icCommunicator()->publisherStore(clayer->layerId)->numberOfLevels();
      if( nx < period ) {
         if( parent->icCommunicator()->commRank() == 0 ) {
            fflush(stdout);
            fprintf(stderr, "DatastoreDelayTestLayer \"%s\": number of columns (%d) must be >= number of delay levels (%d).  Exiting.\n", name, getLayerLoc()->ny, period);
         }
         exit(EXIT_FAILURE);
      }
      for( int x=0; x<nx; x++ ) {
         for( int f=0; f<nf; f++ ) {
            for( int baserow=0; baserow<period; baserow++ ) {
               pvdata_t r = baserow+1;
               getV()[kIndex(x,baserow,f,nx,ny,nf)] = r;
            }
            for( int row=period; row<ny; row++ ) {
               int baserow=row % period;
               getV()[kIndex(x,row,f,nx,ny,nf)] = getV()[kIndex(x,baserow,f,nx,ny,nf)];
            }
         }
      }
      inited = true;
   }
   return PV_SUCCESS;
}

}  // end of namespace PV block

<commit_msg>Change DatastoreDelayTestLayer::updateV() so that mpi and non-mpi runs have the same values<commit_after>/*
 * DatastoreDelayTestLayer.cpp
 *
 *  Created on: Nov 2, 2011
 *      Author: pschultz
 */

#include "DatastoreDelayTestLayer.hpp"

namespace PV {

DatastoreDelayTestLayer::DatastoreDelayTestLayer(const char* name, HyPerCol * hc) : ANNLayer(name, hc){
   initialize();
}

DatastoreDelayTestLayer::~DatastoreDelayTestLayer() {}

int DatastoreDelayTestLayer::initialize() {
   inited = false; // The first call to updateV sets this to true, so that the class knows whether to initialize or not.
   period = -1; // Can't set period until number of delay levels is determined, but that's determined by the connections,
                // which can't be created until after initialization is finished.  period will be set in the first call to updateV
   return PV_SUCCESS;
}

int DatastoreDelayTestLayer::updateV() {
   const PVLayerLoc * loc = getLayerLoc();
   int nx = loc->nx;
   int ny = loc->ny;
   int nf = loc->nf;
   if( inited ) {
      // Rotate values by one row.
      // This is not MPI-ically correct!
      // Move everything down one row; clobbering row 0 in the process
      for( int y=ny-1; y>0; y-- ) {
         for( int x=0; x<nx; x++ ) {
            for( int f=0; f<nf; f++ ) {
               pvdata_t * V = &getV()[kIndex(x,y,f,nx,ny,nf)];
               (*V)--;
               if( *V == 0 ) *V = period;
            }
         }
      }
      // Finally, copy period-th row to zero-th row
      for( int x=0; x<loc->ny; x++ ) {
         for( int f=0; f<loc->nf; f++ ) {
            getV()[kIndex(x,0,f,nx,ny,nf)] = getV()[kIndex(x,period,f,nx,ny,nf)];
         }
      }
   }
   else {
      period = parent->icCommunicator()->publisherStore(clayer->layerId)->numberOfLevels();
      if( nx < period ) {
         if( parent->icCommunicator()->commRank() == 0 ) {
            fflush(stdout);
            fprintf(stderr, "DatastoreDelayTestLayer \"%s\": number of columns (%d) must be >= number of delay levels (%d).  Exiting.\n", name, getLayerLoc()->ny, period);
         }
         exit(EXIT_FAILURE);
      }
      int base = loc->ky0;
      for( int x=0; x<nx; x++ ) {
         for( int f=0; f<nf; f++ ) {
            for( int row=0; row<ny; row++ ) {
               getV()[kIndex(x,row,f,nx,ny,nf)] = (base+row) % period + 1;
            }
         }
      }
      inited = true;
   }
   return PV_SUCCESS;
}

}  // end of namespace PV block

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 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_BOOST_GEOMETRY_ADAPTERS_HPP
#define MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP

#include <mapnik/config.hpp>

// undef B0 to workaround https://svn.boost.org/trac/boost/ticket/10467
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#undef B0
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
#pragma GCC diagnostic pop
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/geometry/box2d.hpp>

BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<std::int64_t>, std::int64_t, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string)
BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring)
// needed by box2d<T>
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float,  boost::geometry::cs::cartesian, x, y)

namespace mapnik {

template <typename CoordinateType>
struct const_interior_rings
{
    using polygon_type = mapnik::geometry::polygon<CoordinateType> const;
    using const_iterator = typename polygon_type::const_iterator;
    using iterator = const_iterator; // needed by boost::range_iterator
    using value_type = typename polygon_type::value_type;

    const_interior_rings(polygon_type const& poly)
        : poly_(poly) {}

    const_iterator begin() const
    {
        auto itr = poly_.cbegin();
        std::advance(itr, 1);
        return itr;
    }

    const_iterator end() const { return poly_.cend();}

    std::size_t size() const
    {
        return poly_.empty() ? 0 : poly_.size() - 1;
    }

    value_type const& back()  const { return poly_.back(); }
    polygon_type const& poly_;
};

template <typename CoordinateType>
struct interior_rings
{
    using polygon_type = mapnik::geometry::polygon<CoordinateType>;
    using iterator = typename polygon_type::iterator;
    using const_iterator = typename polygon_type::const_iterator;
    using value_type = typename polygon_type::value_type;

    interior_rings(polygon_type & poly)
        : poly_(poly) {}

    iterator begin()
    {
        auto itr = poly_.begin();
        std::advance(itr, 1);
        return itr;
    }

    iterator end() { return poly_.end();}
    const_iterator begin() const
    {
        auto itr = poly_.cbegin();
        std::advance(itr, 1);
        return itr;
    }

    const_iterator end() const { return poly_.cend();}

    void clear()
    {
        poly_.resize(1);
    }

    void resize(std::size_t size)
    {
        poly_.resize(size + 1);
    }

    std::size_t size() const
    {
        return poly_.empty() ? 0 : poly_.size() - 1;
    }

    void push_back(value_type const& val) { poly_.push_back(val); }
    value_type& back() { return poly_.back(); }
    value_type const& back()  const { return poly_.back(); }
    polygon_type & poly_;
};

} // ns mapnik

namespace boost { namespace geometry { namespace traits {

template <typename CoordinateType>
struct tag<mapnik::box2d<CoordinateType> >
{
    using type = box_tag;
};

template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; };
template<> struct point_type<mapnik::box2d<float> > { using type = mapnik::coord2f; };

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, min_corner, 0>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.minx();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_minx(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, min_corner, 1>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.miny();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_miny(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, max_corner, 0>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.maxx();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_maxx(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, max_corner, 1>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.maxy();}
    static inline void set(mapnik::box2d<CoordinateType> &b , ct const& value) { b.set_maxy(value); }
};

template<typename CoordinateType>
struct tag<mapnik::geometry::polygon<CoordinateType> >
{
    using type = polygon_tag;
};

template <typename CoordinateType>
struct point_order<mapnik::geometry::linear_ring<CoordinateType> >
{
    static const order_selector value = counterclockwise;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_point<CoordinateType> >
{
    using type = multi_point_tag;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_line_string<CoordinateType> >
{
    using type = multi_linestring_tag;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_polygon<CoordinateType> >
{
    using type = multi_polygon_tag;
};

// ring
template <typename CoordinateType>
struct ring_const_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::geometry::linear_ring<CoordinateType> const&;
};

template <typename CoordinateType>
struct ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::geometry::linear_ring<CoordinateType>&;
};

// interior
template <typename CoordinateType>
struct interior_const_type<mapnik::geometry::polygon<CoordinateType>>
{
    using type = typename mapnik::const_interior_rings<CoordinateType> const;
};

template <typename CoordinateType>
struct interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::interior_rings<CoordinateType> ;
};

template <typename CoordinateType>
struct exterior_ring<mapnik::geometry::polygon<CoordinateType> >
{
    using ring_const_type   = typename ring_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
    using ring_mutable_type = typename ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;
    static ring_mutable_type get(mapnik::geometry::polygon<CoordinateType> & p)
    {
        if (p.empty()) p.resize(1);
        return p[0];
    }

    static ring_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
    {
        if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!");
        return p[0];
    }
};

template <typename CoordinateType>
struct interior_rings<mapnik::geometry::polygon<CoordinateType> >
{
    using interior_const_type = typename interior_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
    using interior_mutable_type = typename interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;

    static interior_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
    {
        return mapnik::const_interior_rings<CoordinateType>(p);
    }

    static interior_mutable_type get(mapnik::geometry::polygon<CoordinateType>& p)
    {
        return mapnik::interior_rings<CoordinateType>(p);
    }
};

template <typename CoordinateType>
struct resize<mapnik::interior_rings<CoordinateType>>
{
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors, std::size_t new_size)
    {
        interiors.resize(new_size);
    }
};

template <typename CoordinateType>
struct clear<mapnik::interior_rings<CoordinateType>>
{
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors)
    {
        interiors.clear();
    }
};

template <typename CoordinateType>
struct push_back<mapnik::interior_rings<CoordinateType>>
{
    template <typename Ring>
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors, Ring const& ring)
    {
        interiors.push_back(ring);
    }
};

}}}

#endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP
<commit_msg>boost_adapters - apply temp fix via @Algunenano for boost 1.64 (ref #3733)<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 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_BOOST_GEOMETRY_ADAPTERS_HPP
#define MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP

#include <mapnik/config.hpp>

// undef B0 to workaround https://svn.boost.org/trac/boost/ticket/10467
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#undef B0
#if BOOST_VERSION == 106400
#include <boost/qvm/mat_operations.hpp>
#endif
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
#pragma GCC diagnostic pop
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/geometry/box2d.hpp>

BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<std::int64_t>, std::int64_t, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string)
BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring)
// needed by box2d<T>
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float,  boost::geometry::cs::cartesian, x, y)

namespace mapnik {

template <typename CoordinateType>
struct const_interior_rings
{
    using polygon_type = mapnik::geometry::polygon<CoordinateType> const;
    using const_iterator = typename polygon_type::const_iterator;
    using iterator = const_iterator; // needed by boost::range_iterator
    using value_type = typename polygon_type::value_type;

    const_interior_rings(polygon_type const& poly)
        : poly_(poly) {}

    const_iterator begin() const
    {
        auto itr = poly_.cbegin();
        std::advance(itr, 1);
        return itr;
    }

    const_iterator end() const { return poly_.cend();}

    std::size_t size() const
    {
        return poly_.empty() ? 0 : poly_.size() - 1;
    }

    value_type const& back()  const { return poly_.back(); }
    polygon_type const& poly_;
};

template <typename CoordinateType>
struct interior_rings
{
    using polygon_type = mapnik::geometry::polygon<CoordinateType>;
    using iterator = typename polygon_type::iterator;
    using const_iterator = typename polygon_type::const_iterator;
    using value_type = typename polygon_type::value_type;

    interior_rings(polygon_type & poly)
        : poly_(poly) {}

    iterator begin()
    {
        auto itr = poly_.begin();
        std::advance(itr, 1);
        return itr;
    }

    iterator end() { return poly_.end();}
    const_iterator begin() const
    {
        auto itr = poly_.cbegin();
        std::advance(itr, 1);
        return itr;
    }

    const_iterator end() const { return poly_.cend();}

    void clear()
    {
        poly_.resize(1);
    }

    void resize(std::size_t size)
    {
        poly_.resize(size + 1);
    }

    std::size_t size() const
    {
        return poly_.empty() ? 0 : poly_.size() - 1;
    }

    void push_back(value_type const& val) { poly_.push_back(val); }
    value_type& back() { return poly_.back(); }
    value_type const& back()  const { return poly_.back(); }
    polygon_type & poly_;
};

} // ns mapnik

namespace boost { namespace geometry { namespace traits {

template <typename CoordinateType>
struct tag<mapnik::box2d<CoordinateType> >
{
    using type = box_tag;
};

template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; };
template<> struct point_type<mapnik::box2d<float> > { using type = mapnik::coord2f; };

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, min_corner, 0>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.minx();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_minx(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, min_corner, 1>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.miny();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_miny(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, max_corner, 0>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.maxx();}
    static inline void set(mapnik::box2d<CoordinateType> &b, ct const& value) { b.set_maxx(value); }
};

template <typename CoordinateType>
struct indexed_access<mapnik::box2d<CoordinateType>, max_corner, 1>
{
    using ct = CoordinateType;
    static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.maxy();}
    static inline void set(mapnik::box2d<CoordinateType> &b , ct const& value) { b.set_maxy(value); }
};

template<typename CoordinateType>
struct tag<mapnik::geometry::polygon<CoordinateType> >
{
    using type = polygon_tag;
};

template <typename CoordinateType>
struct point_order<mapnik::geometry::linear_ring<CoordinateType> >
{
    static const order_selector value = counterclockwise;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_point<CoordinateType> >
{
    using type = multi_point_tag;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_line_string<CoordinateType> >
{
    using type = multi_linestring_tag;
};

template<typename CoordinateType>
struct tag<mapnik::geometry::multi_polygon<CoordinateType> >
{
    using type = multi_polygon_tag;
};

// ring
template <typename CoordinateType>
struct ring_const_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::geometry::linear_ring<CoordinateType> const&;
};

template <typename CoordinateType>
struct ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::geometry::linear_ring<CoordinateType>&;
};

// interior
template <typename CoordinateType>
struct interior_const_type<mapnik::geometry::polygon<CoordinateType>>
{
    using type = typename mapnik::const_interior_rings<CoordinateType> const;
};

template <typename CoordinateType>
struct interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{
    using type = typename mapnik::interior_rings<CoordinateType> ;
};

template <typename CoordinateType>
struct exterior_ring<mapnik::geometry::polygon<CoordinateType> >
{
    using ring_const_type   = typename ring_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
    using ring_mutable_type = typename ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;
    static ring_mutable_type get(mapnik::geometry::polygon<CoordinateType> & p)
    {
        if (p.empty()) p.resize(1);
        return p[0];
    }

    static ring_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
    {
        if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!");
        return p[0];
    }
};

template <typename CoordinateType>
struct interior_rings<mapnik::geometry::polygon<CoordinateType> >
{
    using interior_const_type = typename interior_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
    using interior_mutable_type = typename interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;

    static interior_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
    {
        return mapnik::const_interior_rings<CoordinateType>(p);
    }

    static interior_mutable_type get(mapnik::geometry::polygon<CoordinateType>& p)
    {
        return mapnik::interior_rings<CoordinateType>(p);
    }
};

template <typename CoordinateType>
struct resize<mapnik::interior_rings<CoordinateType>>
{
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors, std::size_t new_size)
    {
        interiors.resize(new_size);
    }
};

template <typename CoordinateType>
struct clear<mapnik::interior_rings<CoordinateType>>
{
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors)
    {
        interiors.clear();
    }
};

template <typename CoordinateType>
struct push_back<mapnik::interior_rings<CoordinateType>>
{
    template <typename Ring>
    static inline void apply(mapnik::interior_rings<CoordinateType> interiors, Ring const& ring)
    {
        interiors.push_back(ring);
    }
};

}}}

#endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP
<|endoftext|>