<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATOR_PRODUCTS_HH
#define DUNE_GDT_OPERATOR_PRODUCTS_HH

#include <type_traits>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/functions/constant.hh>

#include "../localoperator/codim0.hh"
#include "../localfunctional/codim0.hh"
#include "../localevaluation/product.hh"
#include "../localevaluation/elliptic.hh"

namespace Dune {
namespace GDT {
namespace ProductOperator {

template< class GridPartType >
class L2
{
public:
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;

  L2(const GridPartType& grid_part)
    : grid_part_(grid_part)
  {}

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  void apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& /*range*/,
              const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& /*source*/) const
  {
    static_assert((Dune::AlwaysFalse< RR >::value), "Not implemented for this combination!");
  }

  template< class RangeFieldType, int dimRangeRows, int dimRangeCols >
  RangeFieldType apply2(const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          range,
                        const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          source) const
  {
    typedef Stuff::LocalizableFunctionInterface
        < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >
      RangeType;
    // some preparations
    const LocalFunctional::Codim0Integral< LocalEvaluation::Product< RangeType > > local_functional(range);
    RangeFieldType ret = 0;
    DynamicVector< RangeFieldType > local_functional_result(1, 0);
    std::vector< DynamicVector< RangeFieldType > > tmp_vectors(local_functional.numTmpObjectsRequired(),
                                                               DynamicVector< RangeFieldType >(1, 0));

    // walk the grid
    const auto entity_it_end = grid_part_.template end< 0 >();
    for (auto entity_it = grid_part_.template begin< 0 >(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get the local function
      const auto source_local_function = source.local_function(entity);
      // apply local functional
      local_functional.apply(*source_local_function, local_functional_result, tmp_vectors);
      assert(local_functional_result.size() == 1);
      ret += local_functional_result[0];
    } // walk the grid
    return ret;
  } // ... apply2(...)

private:
  const GridPartType& grid_part_;
}; // class L2

template< class GridPartType >
class H1
{
public:
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;

  H1(const GridPartType& grid_part)
    : grid_part_(grid_part)
  {}

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  void apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& /*range*/,
              const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& /*source*/) const
  {
    static_assert((Dune::AlwaysFalse< RR >::value), "Not implemented for this combination!");
  }

  template< class RangeFieldType, int dimRangeRows, int dimRangeCols >
  RangeFieldType apply2(const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          range,
                        const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          source) const
  {
    // some preparations
    typedef Stuff::Function::Constant< EntityType, DomainFieldType, dimDomain, RangeFieldType, 1 > ConstantFunctionType;
    const ConstantFunctionType one(1);
    const LocalOperator::Codim0Integral< LocalEvaluation::Elliptic< ConstantFunctionType > > local_operator(one);
    RangeFieldType ret = 0;
    DynamicMatrix< RangeFieldType > local_operator_result(1, 1, 0);
    std::vector< DynamicMatrix< RangeFieldType > > tmp_matrices(local_operator.numTmpObjectsRequired(),
                                                                DynamicMatrix< RangeFieldType >(1, 1, 0));

    // walk the grid
    const auto entity_it_end = grid_part_.template end< 0 >();
    for (auto entity_it = grid_part_.template begin< 0 >(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get the local functions
      const auto source_local_function = source.local_function(entity);
      const auto range_local_function = range.local_function(entity);
      // apply local operator
      local_operator.apply(*source_local_function, *range_local_function, local_operator_result, tmp_matrices);
      assert(local_operator_result.rows() == 1);
      assert(local_operator_result.cols() == 1);
      ret += local_operator_result[0][0];
    } // walk the grid
    return ret;
  } // ... apply2(...)

private:
  const GridPartType& grid_part_;
}; // class H1

} // namespace ProductOperator
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATOR_PRODUCTS_HH
<commit_msg>[operator.products] renamed H1 -> H1Semi<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATOR_PRODUCTS_HH
#define DUNE_GDT_OPERATOR_PRODUCTS_HH

#include <type_traits>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/functions/constant.hh>

#include "../localoperator/codim0.hh"
#include "../localfunctional/codim0.hh"
#include "../localevaluation/product.hh"
#include "../localevaluation/elliptic.hh"

namespace Dune {
namespace GDT {
namespace ProductOperator {

template< class GridPartType >
class L2
{
public:
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;

  L2(const GridPartType& grid_part)
    : grid_part_(grid_part)
  {}

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  void apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& /*range*/,
              const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& /*source*/) const
  {
    static_assert((Dune::AlwaysFalse< RR >::value), "Not implemented for this combination!");
  }

  template< class RangeFieldType, int dimRangeRows, int dimRangeCols >
  RangeFieldType apply2(const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          range,
                        const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          source) const
  {
    typedef Stuff::LocalizableFunctionInterface
        < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >
      RangeType;
    // some preparations
    const LocalFunctional::Codim0Integral< LocalEvaluation::Product< RangeType > > local_functional(range);
    RangeFieldType ret = 0;
    DynamicVector< RangeFieldType > local_functional_result(1, 0);
    std::vector< DynamicVector< RangeFieldType > > tmp_vectors(local_functional.numTmpObjectsRequired(),
                                                               DynamicVector< RangeFieldType >(1, 0));

    // walk the grid
    const auto entity_it_end = grid_part_.template end< 0 >();
    for (auto entity_it = grid_part_.template begin< 0 >(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get the local function
      const auto source_local_function = source.local_function(entity);
      // apply local functional
      local_functional.apply(*source_local_function, local_functional_result, tmp_vectors);
      assert(local_functional_result.size() == 1);
      ret += local_functional_result[0];
    } // walk the grid
    return ret;
  } // ... apply2(...)

private:
  const GridPartType& grid_part_;
}; // class L2

template< class GridPartType >
class H1Semi
{
public:
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;

  H1Semi(const GridPartType& grid_part)
    : grid_part_(grid_part)
  {}

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  void apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& /*range*/,
              const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& /*source*/) const
  {
    static_assert((Dune::AlwaysFalse< RR >::value), "Not implemented for this combination!");
  }

  template< class RangeFieldType, int dimRangeRows, int dimRangeCols >
  RangeFieldType apply2(const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          range,
                        const Stuff::LocalizableFunctionInterface
                            < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRangeRows, dimRangeCols >&
                          source) const
  {
    // some preparations
    typedef Stuff::Function::Constant< EntityType, DomainFieldType, dimDomain, RangeFieldType, 1 > ConstantFunctionType;
    const ConstantFunctionType one(1);
    const LocalOperator::Codim0Integral< LocalEvaluation::Elliptic< ConstantFunctionType > > local_operator(one);
    RangeFieldType ret = 0;
    DynamicMatrix< RangeFieldType > local_operator_result(1, 1, 0);
    std::vector< DynamicMatrix< RangeFieldType > > tmp_matrices(local_operator.numTmpObjectsRequired(),
                                                                DynamicMatrix< RangeFieldType >(1, 1, 0));

    // walk the grid
    const auto entity_it_end = grid_part_.template end< 0 >();
    for (auto entity_it = grid_part_.template begin< 0 >(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get the local functions
      const auto source_local_function = source.local_function(entity);
      const auto range_local_function = range.local_function(entity);
      // apply local operator
      local_operator.apply(*source_local_function, *range_local_function, local_operator_result, tmp_matrices);
      assert(local_operator_result.rows() == 1);
      assert(local_operator_result.cols() == 1);
      ret += local_operator_result[0][0];
    } // walk the grid
    return ret;
  } // ... apply2(...)

private:
  const GridPartType& grid_part_;
}; // class H1Semi

} // namespace ProductOperator
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATOR_PRODUCTS_HH
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_FUNCTIONS_SPE10_HH
#define DUNE_STUFF_FUNCTIONS_SPE10_HH

#include <iostream>
#include <memory>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configtree.hh>
#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/string.hh>

#include "checkerboard.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

// default, to allow for specialization
template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Spe10Model1
{
public:
  Spe10Model1() = delete;
}; // class FunctionSpe10Model1

/**
 *  \note For dimRange 1 we only read the Kx values from the file.
 */
template< class EntityImp, class DomainFieldImp, class RangeFieldImp >
class Spe10Model1< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 >
  : public Checkerboard< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 >
{
  typedef Checkerboard< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 > BaseType;
  typedef Spe10Model1< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 > ThisType;
public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const int                            dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType   RangeFieldType;
  static const int                            dimRange = BaseType::dimRange;
  typedef typename BaseType::RangeType        RangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".spe10.model1";
  }

private:
  static const size_t numXelements;
  static const size_t numYelements;
  static const size_t numZelements;
  static const RangeFieldType minValue;
  static const RangeFieldType maxValue;

  static std::vector< RangeType > read_values_from_file(const std::string& filename,
                                                        const RangeFieldType& min,
                                                        const RangeFieldType& max)

  {
    if (!(max > min))
      DUNE_THROW_COLORFULLY(Dune::RangeError,
                            "max (is " << max << ") has to be larger than min (is " << min << ")!");
    const RangeFieldType scale = (max - min) / (maxValue - minValue);
    const RangeType shift = min - scale*minValue;
    // read all the data from the file
    std::ifstream datafile(filename);
    if (datafile.is_open()) {
      static const size_t entriesPerDim = numXelements*numYelements*numZelements;
      // create storage (there should be exactly 6000 values in the file, but we onyl read the first 2000)
      std::vector< RangeType > data(entriesPerDim, RangeFieldType(0));
      double tmp = 0;
      size_t counter = 0;
      while (datafile >> tmp && counter < entriesPerDim) {
        data[counter] = (tmp * scale) + shift;
        ++counter;
      }
      datafile.close();
      if (counter != entriesPerDim)
        DUNE_THROW_COLORFULLY(Dune::IOError,
                              "wrong number of entries in '" << filename << "' (are " << counter << ", should be "
                              << entriesPerDim << ")!");
      return data;
    } else
      DUNE_THROW_COLORFULLY(Dune::IOError, "could not open '" << filename << "'!");
  } // Spe10Model1()

public:
  Spe10Model1(const std::string& filename,
              std::vector< DomainFieldType >&& lowerLeft,
              std::vector< DomainFieldType >&& upperRight,
              const RangeFieldType min = minValue,
              const RangeFieldType max = maxValue,
              const std::string nm = static_id())
    : BaseType(std::move(lowerLeft),
               std::move(upperRight),
               {numXelements, numZelements},
               read_values_from_file(filename, min, max), nm)
  {}

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["filename"] = "perm_case1.dat";
    config["lower_left"] = "[0.0; 0.0]";
    config["upper_right"] = "[762.0; 15.24]";
    config["min_value"] = "0.001";
    config["max_value"] = "998.915";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    // extract needed data
    const auto filename = cfg.get< std::string >("filename");
    auto lower_left = cfg.get< std::vector< DomainFieldType > >("lower_left", dimDomain);
    auto upper_right = cfg.get< std::vector< DomainFieldType > >("upper_right", dimDomain);
    const auto min_val = cfg.get< RangeFieldType >("min_value", minValue);
    const auto max_val = cfg.get< RangeFieldType >("max_value", maxValue);
    const auto nm = cfg.get< std::string >("name", static_id());
    // create and return, leave the checks to the constructor
    return Common::make_unique< ThisType >(filename, std::move(lower_left), std::move(upper_right), min_val, max_val, nm);
  } // ... create(...)
}; // class Spe10Model1< ..., 2, ..., 1, 1 >

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numXelements = 100;

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numYelements = 1;

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numZelements = 20;

template< class E, class D, class R >
const typename Spe10Model1< E, D, 2, R, 1, 1 >::RangeFieldType Spe10Model1< E, D, 2, R, 1, 1 >::minValue = 0.001;

template< class E, class D, class R >
const typename Spe10Model1< E, D, 2, R, 1, 1 >::RangeFieldType Spe10Model1< E, D, 2, R, 1, 1 >::maxValue = 998.915;

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Spe10Model1< etype, dftype, ddim, rftype, rdim, rcdim >;

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2, 1, 1)

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2, 1, 1)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2, 1, 1)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES
# endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTIONS_SPE10_HH
<commit_msg>[functions.spe10] use new vector notation and new get method<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_FUNCTIONS_SPE10_HH
#define DUNE_STUFF_FUNCTIONS_SPE10_HH

#include <iostream>
#include <memory>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configtree.hh>
#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/string.hh>

#include "checkerboard.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

// default, to allow for specialization
template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Spe10Model1
{
public:
  Spe10Model1() = delete;
}; // class FunctionSpe10Model1

/**
 *  \note For dimRange 1 we only read the Kx values from the file.
 */
template< class EntityImp, class DomainFieldImp, class RangeFieldImp >
class Spe10Model1< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 >
  : public Checkerboard< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 >
{
  typedef Checkerboard< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 > BaseType;
  typedef Spe10Model1< EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1 > ThisType;
public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const int                            dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType   RangeFieldType;
  static const int                            dimRange = BaseType::dimRange;
  typedef typename BaseType::RangeType        RangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".spe10.model1";
  }

private:
  static const size_t numXelements;
  static const size_t numYelements;
  static const size_t numZelements;
  static const RangeFieldType minValue;
  static const RangeFieldType maxValue;

  static std::vector< RangeType > read_values_from_file(const std::string& filename,
                                                        const RangeFieldType& min,
                                                        const RangeFieldType& max)

  {
    if (!(max > min))
      DUNE_THROW_COLORFULLY(Dune::RangeError,
                            "max (is " << max << ") has to be larger than min (is " << min << ")!");
    const RangeFieldType scale = (max - min) / (maxValue - minValue);
    const RangeType shift = min - scale*minValue;
    // read all the data from the file
    std::ifstream datafile(filename);
    if (datafile.is_open()) {
      static const size_t entriesPerDim = numXelements*numYelements*numZelements;
      // create storage (there should be exactly 6000 values in the file, but we onyl read the first 2000)
      std::vector< RangeType > data(entriesPerDim, RangeFieldType(0));
      double tmp = 0;
      size_t counter = 0;
      while (datafile >> tmp && counter < entriesPerDim) {
        data[counter] = (tmp * scale) + shift;
        ++counter;
      }
      datafile.close();
      if (counter != entriesPerDim)
        DUNE_THROW_COLORFULLY(Dune::IOError,
                              "wrong number of entries in '" << filename << "' (are " << counter << ", should be "
                              << entriesPerDim << ")!");
      return data;
    } else
      DUNE_THROW_COLORFULLY(Dune::IOError, "could not open '" << filename << "'!");
  } // Spe10Model1()

public:
  Spe10Model1(const std::string& filename,
              std::vector< DomainFieldType >&& lowerLeft,
              std::vector< DomainFieldType >&& upperRight,
              const RangeFieldType min = minValue,
              const RangeFieldType max = maxValue,
              const std::string nm = static_id())
    : BaseType(std::move(lowerLeft),
               std::move(upperRight),
               {numXelements, numZelements},
               read_values_from_file(filename, min, max), nm)
  {}

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["filename"] = "perm_case1.dat";
    config["lower_left"] = "[0.0 0.0]";
    config["upper_right"] = "[762.0 15.24]";
    config["min_value"] = "0.001";
    config["max_value"] = "998.915";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::ConfigTree default_cfg = default_config();
    // create
    return Common::make_unique< ThisType >(
          cfg.get("filename",     default_cfg.get< std::string >("filename")),
          cfg.get("lower_left",   default_cfg.get< std::vector< DomainFieldType > >("lower_left"), dimDomain),
          cfg.get("upper_right",  default_cfg.get< std::vector< DomainFieldType > >("upper_right"), dimDomain),
          cfg.get("min_val",      minValue),
          cfg.get("max_val",      maxValue),
          cfg.get("name",         default_cfg.get< std::string >("name")));
  } // ... create(...)
}; // class Spe10Model1< ..., 2, ..., 1, 1 >

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numXelements = 100;

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numYelements = 1;

template< class E, class D, class R >
const size_t Spe10Model1< E, D, 2, R, 1, 1 >::numZelements = 20;

template< class E, class D, class R >
const typename Spe10Model1< E, D, 2, R, 1, 1 >::RangeFieldType Spe10Model1< E, D, 2, R, 1, 1 >::minValue = 0.001;

template< class E, class D, class R >
const typename Spe10Model1< E, D, 2, R, 1, 1 >::RangeFieldType Spe10Model1< E, D, 2, R, 1, 1 >::maxValue = 998.915;

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Spe10Model1< etype, dftype, ddim, rftype, rdim, rcdim >;

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2, 1, 1)

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2, 1, 1)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2, 1, 1)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_SPE10_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_SPE10_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_SPE10_LIST_DOMAINFIELDTYPES
# endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTIONS_SPE10_HH
<|endoftext|>


<commit_before>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * + Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * + Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This file is a derivative work of Philippe Decaudin's AntTweakBar
 * library, version 1.16, which is distributed under the following terms:
 *
 * Copyright (C) 2005-2013 Philippe Decaudin
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 * not claim that you wrote the original software. If you use this
 * software in a product, an acknowledgment in the product documentation
 * would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 * not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 */

#include <AntTweakBar.h>

#include "SDLtoATB.hh"

// TwEventSDL returns zero if msg has not been handled,
// and a non-zero value if it has been handled by the AntTweakBar library.
int TW_CALL myTwEventSDL20(const SDL_Event &event)
{
  int handled = 0;
  //static int s_KeyMod = 0;

  switch (event.type) {

#if 0
  case SDL_TEXTINPUT:
    if (event.text.text[0] != 0 && event.text.text[1] == 0) {
      if (s_KeyMod & TW_KMOD_CTRL && event.text.text[0] < 32)
        handled = TwKeyPressed(event.text.text[0] + 'a' - 1, s_KeyMod);
      else {
        if (s_KeyMod & KMOD_RALT)
          s_KeyMod &= ~KMOD_CTRL;
        handled = TwKeyPressed(event.text.text[0], s_KeyMod);
      }
    }
    s_KeyMod = 0;
    break;

  case SDL_KEYDOWN:
    if (event.key.keysym.sym & SDLK_SCANCODE_MASK) {
      int key = 0;
      switch (event.key.keysym.sym) {
      case SDLK_UP:
        key = TW_KEY_UP;
        break;
      case SDLK_DOWN:
        key = TW_KEY_DOWN;
        break;
      case SDLK_RIGHT:
        key = TW_KEY_RIGHT;
        break;
      case SDLK_LEFT:
        key = TW_KEY_LEFT;
        break;
      case SDLK_INSERT:
        key = TW_KEY_INSERT;
        break;
      case SDLK_HOME:
        key = TW_KEY_HOME;
        break;
      case SDLK_END:
        key = TW_KEY_END;
        break;
      case SDLK_PAGEUP:
        key = TW_KEY_PAGE_UP;
        break;
      case SDLK_PAGEDOWN:
        key = TW_KEY_PAGE_DOWN;
        break;
      default:
        if (event.key.keysym.sym >= SDLK_F1 &&
            event.key.keysym.sym <= SDLK_F12)
          key = event.key.keysym.sym + TW_KEY_F1 - SDLK_F1;
      }
      if (key != 0)
        handled = TwKeyPressed(key, event.key.keysym.mod);
    }
    else if (event.key.keysym.mod & TW_KMOD_ALT)
      handled = TwKeyPressed(event.key.keysym.sym & 0xFF,
                             event.key.keysym.mod);
    else
      s_KeyMod = event.key.keysym.mod;
    break;

  case SDL_KEYUP:
    s_KeyMod = 0;
    break;
#endif

  case SDL_MOUSEMOTION:
    handled = TwMouseMotion(event.motion.x, event.motion.y);
    break;

  case SDL_MOUSEWHEEL:
    handled = TwMouseWheel(event.wheel.y);
    break;

  case SDL_MOUSEBUTTONUP:
  case SDL_MOUSEBUTTONDOWN:
    TwMouseAction action;
    if (event.button.state == SDL_PRESSED)
      action = TW_MOUSE_PRESSED;
    else if (event.button.state == SDL_RELEASED)
      action = TW_MOUSE_RELEASED;
    else
      break;

    TwMouseButtonID button;
    if (event.button.button == SDL_BUTTON_LMASK)
      button = TW_MOUSE_LEFT;
    else if (event.button.button == SDL_BUTTON_MMASK)
      button = TW_MOUSE_MIDDLE;
    else if (event.button.button == SDL_BUTTON_RMASK)
      button = TW_MOUSE_RIGHT;
    else
      break;

    handled = TwMouseButton(action, button);

    break;

  case SDL_WINDOWEVENT:
    if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
      // tell the new size to TweakBar
      TwWindowSize(event.window.data1, event.window.data2);
      // do not set 'handled', SDL_VIDEORESIZE may be also processed by
      // the calling application
    }
    break;
  }

  return handled;
}
<commit_msg>Handle ATB mouse wheel events correctly<commit_after>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * + Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * + Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This file is a derivative work of Philippe Decaudin's AntTweakBar
 * library, version 1.16, which is distributed under the following terms:
 *
 * Copyright (C) 2005-2013 Philippe Decaudin
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 * not claim that you wrote the original software. If you use this
 * software in a product, an acknowledgment in the product documentation
 * would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 * not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 */

#include <AntTweakBar.h>

#include "SDLtoATB.hh"

// TwEventSDL returns zero if msg has not been handled,
// and a non-zero value if it has been handled by the AntTweakBar library.
int TW_CALL myTwEventSDL20(const SDL_Event &event)
{
  int handled = 0;
  //static int s_KeyMod = 0;

  switch (event.type) {

#if 0
  case SDL_TEXTINPUT:
    if (event.text.text[0] != 0 && event.text.text[1] == 0) {
      if (s_KeyMod & TW_KMOD_CTRL && event.text.text[0] < 32)
        handled = TwKeyPressed(event.text.text[0] + 'a' - 1, s_KeyMod);
      else {
        if (s_KeyMod & KMOD_RALT)
          s_KeyMod &= ~KMOD_CTRL;
        handled = TwKeyPressed(event.text.text[0], s_KeyMod);
      }
    }
    s_KeyMod = 0;
    break;

  case SDL_KEYDOWN:
    if (event.key.keysym.sym & SDLK_SCANCODE_MASK) {
      int key = 0;
      switch (event.key.keysym.sym) {
      case SDLK_UP:
        key = TW_KEY_UP;
        break;
      case SDLK_DOWN:
        key = TW_KEY_DOWN;
        break;
      case SDLK_RIGHT:
        key = TW_KEY_RIGHT;
        break;
      case SDLK_LEFT:
        key = TW_KEY_LEFT;
        break;
      case SDLK_INSERT:
        key = TW_KEY_INSERT;
        break;
      case SDLK_HOME:
        key = TW_KEY_HOME;
        break;
      case SDLK_END:
        key = TW_KEY_END;
        break;
      case SDLK_PAGEUP:
        key = TW_KEY_PAGE_UP;
        break;
      case SDLK_PAGEDOWN:
        key = TW_KEY_PAGE_DOWN;
        break;
      default:
        if (event.key.keysym.sym >= SDLK_F1 &&
            event.key.keysym.sym <= SDLK_F12)
          key = event.key.keysym.sym + TW_KEY_F1 - SDLK_F1;
      }
      if (key != 0)
        handled = TwKeyPressed(key, event.key.keysym.mod);
    }
    else if (event.key.keysym.mod & TW_KMOD_ALT)
      handled = TwKeyPressed(event.key.keysym.sym & 0xFF,
                             event.key.keysym.mod);
    else
      s_KeyMod = event.key.keysym.mod;
    break;

  case SDL_KEYUP:
    s_KeyMod = 0;
    break;
#endif

  case SDL_MOUSEMOTION:
    handled = TwMouseMotion(event.motion.x, event.motion.y);
    break;

  case SDL_MOUSEWHEEL:
    {
      static int s_WheelPos = 0;
      s_WheelPos += event.wheel.y;
      handled = TwMouseWheel(s_WheelPos);
    }
    break;

  case SDL_MOUSEBUTTONUP:
  case SDL_MOUSEBUTTONDOWN:
    TwMouseAction action;
    if (event.button.state == SDL_PRESSED)
      action = TW_MOUSE_PRESSED;
    else if (event.button.state == SDL_RELEASED)
      action = TW_MOUSE_RELEASED;
    else
      break;

    TwMouseButtonID button;
    if (event.button.button == SDL_BUTTON_LMASK)
      button = TW_MOUSE_LEFT;
    else if (event.button.button == SDL_BUTTON_MMASK)
      button = TW_MOUSE_MIDDLE;
    else if (event.button.button == SDL_BUTTON_RMASK)
      button = TW_MOUSE_RIGHT;
    else
      break;

    handled = TwMouseButton(action, button);

    break;

  case SDL_WINDOWEVENT:
    if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
      // tell the new size to TweakBar
      TwWindowSize(event.window.data1, event.window.data2);
      // do not set 'handled', SDL_VIDEORESIZE may be also processed by
      // the calling application
    }
    break;
  }

  return handled;
}
<|endoftext|>


<commit_before>// Time:  O(logn)
// Space: O(1)

// Iterative solution.
class Solution {
public:
    double myPow(double x, int n) {
        double result = 1;
        long long abs_n = abs(static_cast<long long>(n));
        while (abs_n > 0) {
            if (abs_n & 1) {
                result *= x;
            }
            abs_n >>= 1;
            x *= x;
        }
        return n < 0 ? 1 / result : result;
    }
};

// Time:  O(logn)
// Space: O(logn)
// Recursive solution.
class Solution2 {
public:
    double myPow(double x, int n) {
        if (n < 0 && n != -n) {
            return 1.0 / myPow(x, -n);
        }
        if (n == 0) {
            return 1;
        }
        double v = myPow(x, n / 2);
        if (n % 2 == 0) {
            return v * v;
        } else {
            return v * v * x;
        }
    }
};
<commit_msg>Update powx-n.cpp<commit_after>// Time:  O(logn) = O(1)
// Space: O(1)

// Iterative solution.
class Solution {
public:
    double myPow(double x, int n) {
        double result = 1;
        long long abs_n = abs(static_cast<long long>(n));
        while (abs_n > 0) {
            if (abs_n & 1) {
                result *= x;
            }
            abs_n >>= 1;
            x *= x;
        }
        return n < 0 ? 1 / result : result;
    }
};

// Time:  O(logn) = O(1)
// Space: O(logn) = O(1)
// Recursive solution.
class Solution2 {
public:
    double myPow(double x, int n) {
        if (n < 0 && n != -n) {
            return 1.0 / myPow(x, -n);
        }
        if (n == 0) {
            return 1;
        }
        double v = myPow(x, n / 2);
        if (n % 2 == 0) {
            return v * v;
        } else {
            return v * v * x;
        }
    }
};
<|endoftext|>


<commit_before>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include "config.h"

#include "tdebug.h"
#include "tstring.h"
#include "tdebuglistener.h"

#include <bitset>
#include <cstdio>
#include <cstdarg>

using namespace TagLib;

namespace
{
  String format(const char *fmt, ...)
  {
    va_list args;
    va_start(args, fmt);

    char buf[256];

#if defined(HAVE_SNPRINTF)

    vsnprintf(buf, sizeof(buf), fmt, args);

#elif defined(HAVE_SPRINTF_S)

    vsprintf_s(buf, fmt, args);

#else

    // Be careful. May cause a buffer overflow.
    vsprintf(buf, fmt, args);

#endif

    va_end(args);

    return String(buf);
  }
}

namespace TagLib
{
  // The instance is defined in tdebuglistener.cpp.
  extern DebugListener *debugListener;

  void debug(const String &s)
  {
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)

    debugListener->printMessage("TagLib: " + s + "\n");

#endif
  }

  void debugData(const ByteVector &v)
  {
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)

    for(size_t i = 0; i < v.size(); ++i)
    {
      String msg
        = format("*** [%d] - char '%c' - int %d, 0x%02x, 0b", i, v[i], v[i], v[i]);

      std::bitset<8> b(v[i]);
      for(int j = 7; j >= 0; --j)
        msg += format("%d", (b.test(j) ? 1 : 0));

      msg += "\n";

      debugListener->printMessage(msg);
    }

#endif
  }
}
<commit_msg>Making use of std::bitset::to_string()<commit_after>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include "config.h"

#include "tdebug.h"
#include "tstring.h"
#include "tdebuglistener.h"

#include <bitset>
#include <cstdio>
#include <cstdarg>

using namespace TagLib;

namespace
{
  String format(const char *fmt, ...)
  {
    va_list args;
    va_start(args, fmt);

    char buf[256];

#if defined(HAVE_SNPRINTF)

    vsnprintf(buf, sizeof(buf), fmt, args);

#elif defined(HAVE_SPRINTF_S)

    vsprintf_s(buf, fmt, args);

#else

    // Be careful. May cause a buffer overflow.
    vsprintf(buf, fmt, args);

#endif

    va_end(args);

    return String(buf);
  }
}

namespace TagLib
{
  // The instance is defined in tdebuglistener.cpp.
  extern DebugListener *debugListener;

  void debug(const String &s)
  {
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)

    debugListener->printMessage("TagLib: " + s + "\n");

#endif
  }

  void debugData(const ByteVector &v)
  {
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)

    for(size_t i = 0; i < v.size(); ++i)
    {
      std::string bits = std::bitset<8>(v[i]).to_string();
      String msg = format("*** [%d] - char '%c' - int %d, 0x%02x, 0b%s\n",
        i, v[i], v[i], v[i], bits.c_str());

      debugListener->printMessage(msg);
    }

#endif
  }
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "editor/config_loader.hpp"
#include "editor/editor_config.hpp"

#include "base/stl_helpers.hpp"

using namespace editor;

UNIT_TEST(EditorConfig_TypeDescription)
{
  using EType = feature::Metadata::EType;
  using Fields = editor::TypeAggregatedDescription::FeatureFields;

  Fields const poi = {
    feature::Metadata::FMD_OPEN_HOURS,
    feature::Metadata::FMD_PHONE_NUMBER,
    feature::Metadata::FMD_WEBSITE,
    feature::Metadata::FMD_EMAIL,
    feature::Metadata::FMD_LEVEL
  };

  pugi::xml_document doc;
  ConfigLoader::LoadFromLocal(doc);

  EditorConfig config;
  config.SetConfig(doc);

  {
    editor::TypeAggregatedDescription desc;
    TEST(!config.GetTypeDescription({"death-star"}, desc), ());
  }
  {
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-hunting_stand"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(!desc.IsAddressEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), Fields{EType::FMD_HEIGHT}, ());
  }
  {
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"shop-toys"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(desc.IsAddressEditable(), ());
    auto fields = poi;
    fields.push_back(EType::FMD_INTERNET);
    base::SortUnique(fields);
    TEST_EQUAL(desc.GetEditableFields(), fields, ());
  }
  {
    // Select amenity-bank because it goes first in config.
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-bar", "amenity-bank"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(desc.IsAddressEditable(), ());
    auto fields = poi;
    fields.push_back(EType::FMD_OPERATOR);
    base::SortUnique(fields);
    TEST_EQUAL(desc.GetEditableFields(), fields, ());
  }
  {
    // Testing type inheritance
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-place_of_worship-christian"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), poi, ());
  }
  {
    // Testing long type inheritance on a fake object
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"tourism-artwork-impresionism-monet"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), Fields{}, ());
  }
  // TODO(mgsergio): Test case with priority="high" when there is one on editor.config.
}

UNIT_TEST(EditorConfig_GetTypesThatCanBeAdded)
{
  pugi::xml_document doc;
  ConfigLoader::LoadFromLocal(doc);

  EditorConfig config;
  config.SetConfig(doc);

  auto const types = config.GetTypesThatCanBeAdded();
  TEST(find(begin(types), end(types), "amenity-cafe") != end(types), ());
  TEST(find(begin(types), end(types), "natural-peak") == end(types), ());
  // Marked as "editable=no".
  TEST(find(begin(types), end(types), "aeroway-airport") == end(types), ());
}
<commit_msg>[editor][test] Fix test.<commit_after>#include "testing/testing.hpp"

#include "editor/config_loader.hpp"
#include "editor/editor_config.hpp"

#include "base/stl_helpers.hpp"

using namespace editor;

UNIT_TEST(EditorConfig_TypeDescription)
{
  using EType = feature::Metadata::EType;
  using Fields = editor::TypeAggregatedDescription::FeatureFields;

  Fields const poi = {
    feature::Metadata::FMD_OPEN_HOURS,
    feature::Metadata::FMD_PHONE_NUMBER,
    feature::Metadata::FMD_WEBSITE,
    feature::Metadata::FMD_EMAIL,
    feature::Metadata::FMD_LEVEL
  };

  pugi::xml_document doc;
  ConfigLoader::LoadFromLocal(doc);

  EditorConfig config;
  config.SetConfig(doc);

  {
    editor::TypeAggregatedDescription desc;
    TEST(!config.GetTypeDescription({"death-star"}, desc), ());
  }
  {
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-hunting_stand"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(!desc.IsAddressEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), Fields{EType::FMD_HEIGHT}, ());
  }
  {
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"shop-toys"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(desc.IsAddressEditable(), ());
    auto fields = poi;
    fields.push_back(EType::FMD_INTERNET);
    base::SortUnique(fields);
    TEST_EQUAL(desc.GetEditableFields(), fields, ());
  }
  {
    // Select amenity-bank because it goes first in config.
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-bar", "amenity-bank"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST(desc.IsAddressEditable(), ());
    auto fields = poi;
    base::SortUnique(fields);
    TEST_EQUAL(desc.GetEditableFields(), fields, ());
  }
  {
    // Testing type inheritance
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"amenity-place_of_worship-christian"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), poi, ());
  }
  {
    // Testing long type inheritance on a fake object
    editor::TypeAggregatedDescription desc;
    TEST(config.GetTypeDescription({"tourism-artwork-impresionism-monet"}, desc), ());
    TEST(desc.IsNameEditable(), ());
    TEST_EQUAL(desc.GetEditableFields(), Fields{}, ());
  }
  // TODO(mgsergio): Test case with priority="high" when there is one on editor.config.
}

UNIT_TEST(EditorConfig_GetTypesThatCanBeAdded)
{
  pugi::xml_document doc;
  ConfigLoader::LoadFromLocal(doc);

  EditorConfig config;
  config.SetConfig(doc);

  auto const types = config.GetTypesThatCanBeAdded();
  TEST(find(begin(types), end(types), "amenity-cafe") != end(types), ());
  TEST(find(begin(types), end(types), "natural-peak") == end(types), ());
  // Marked as "editable=no".
  TEST(find(begin(types), end(types), "aeroway-airport") == end(types), ());
}
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/exception.hpp"
#include "guichan/focushandler.hpp"
#include "guichan/gui.hpp"
#include "guichan/key.hpp"
#include "config.hpp"

extern "C"
{
  char* gcnGuichanVersion()
  {
    return PACKAGE_VERSION;
  }
}

namespace gcn
{

  Gui::Gui()
  {
    mTop = NULL;
    mInput = NULL;
    mGraphics = NULL;
    mFocusHandler = new FocusHandler();
    mTopHasMouse = false;
		mTabbing = true;
  } // end Gui

  Gui::~Gui()
  {
		if (Widget::widgetExists(mTop))
		{
			setTop(NULL);
		}

    delete mFocusHandler;

  } // end ~Gui

  void Gui::setTop(Widget* top)
  {
    if (mTop)
    {
      mTop->_setFocusHandler(NULL);
    }
    if (top)
    {
      top->_setFocusHandler(mFocusHandler);
    }

    mTop = top;

  } // end setTop

  Widget* Gui::getTop() const
  {
    return mTop;

  } // end getTop

  void Gui::setGraphics(Graphics* graphics)
  {
    mGraphics = graphics;

  } // end setGraphics

  Graphics* Gui::getGraphics() const
  {
    return mGraphics;

  } // end getGraphics

  void Gui::setInput(Input* input)
  {
    mInput = input;

  } // end setInput

  Input* Gui::getInput() const
  {
    return mInput;

  } // end getInput

  void Gui::logic()
  {
    if (!mTop)
    {
      throw GCN_EXCEPTION("Gui::logic. No top widget set");
    }

    if(mInput)
    {
			mInput->_pollInput();

			while (!mInput->isMouseQueueEmpty())
			{
				MouseInput mi = mInput->dequeueMouseInput();

				// Send mouse input to every widget that has the mouse.
				if (mi.x > 0 && mi.y > 0
						&& mTop->getDimension().isPointInRect(mi.x, mi.y))
				{
					if (!mTop->hasMouse())
					{
						mTop->_mouseInMessage();
					}

					MouseInput mio = mi;
					mio.x -= mTop->getX();
					mio.y -= mTop->getY();
					mTop->_mouseInputMessage(mio);
				}
				else if (mTop->hasMouse())
				{
					mTop->_mouseOutMessage();
				}

				Widget* f = mFocusHandler->getFocused();
				Widget* d = mFocusHandler->getDragged();

				// If the focused widget doesn't have the mouse,
				// send the mouse input to the focused widget.
				if (f != NULL && !f->hasMouse())
				{
					int xOffset, yOffset;
					f->getAbsolutePosition(xOffset, yOffset);

					MouseInput mio = mi;
					mio.x -= xOffset;
					mio.y -= yOffset;

					f->_mouseInputMessage(mio);
				}

				// If the dragged widget is different from the focused
				// widget, send the mouse input to the dragged widget.
				if (d != NULL && d != f && !d->hasMouse())
				{
					int xOffset, yOffset;
					d->getAbsolutePosition(xOffset, yOffset);

					MouseInput mio = mi;
					mio.x -= xOffset;
					mio.y -= yOffset;

					d->_mouseInputMessage(mio);
				}

				mFocusHandler->applyChanges();

			} // end while

      while (!mInput->isKeyQueueEmpty())
      {
        KeyInput ki = mInput->dequeueKeyInput();

				if (mTabbing
						&& ki.getKey().getValue() == Key::TAB
						&& ki.getType() == KeyInput::PRESS)
				{
					if (ki.getKey().isShiftPressed())
					{
						mFocusHandler->tabPrevious();
					}
					else
					{
						mFocusHandler->tabNext();
					}
				}
				else
				{
					// Send key inputs to the focused widgets
					if (mFocusHandler->getFocused())
					{
						if (mFocusHandler->getFocused()->isFocusable())
						{
							mFocusHandler->getFocused()->_keyInputMessage(ki);
						}
						else
						{
							mFocusHandler->focusNone();
						}
					}
				}

				mFocusHandler->applyChanges();

      } // end while

    } // end if

    mTop->logic();

	} // end logic

  void Gui::draw()
  {
    if (!mTop)
    {
      throw GCN_EXCEPTION("Gui::draw. No top widget set");
    }
    if (!mGraphics)
    {
      throw GCN_EXCEPTION("Gui::draw. No graphics set");
    }

    mGraphics->_beginDraw();

		// If top has a border,
		// draw it before drawing top
		if (mTop->getBorderSize() > 0)
		{
			Rectangle rec = mTop->getDimension();
			rec.x -= mTop->getBorderSize();
			rec.y -= mTop->getBorderSize();
			rec.width += 2 * mTop->getBorderSize();
			rec.height += 2 * mTop->getBorderSize();
			mGraphics->pushClipArea(rec);
			mTop->drawBorder(mGraphics);
			mGraphics->popClipArea();
		}

		mGraphics->pushClipArea(mTop->getDimension());
    mTop->draw(mGraphics);
    mGraphics->popClipArea();

		mGraphics->_endDraw();

  } // end draw

	void Gui::focusNone()
	{
		mFocusHandler->focusNone();
	}

	void Gui::setTabbingEnabled(bool tabbing)
	{
		mTabbing = tabbing;
	}

	bool Gui::isTabbingEnabled()
	{
		return mTabbing;
	}

} // end gcn
<commit_msg>Moved gcnGuichanVersion to guichan.cpp.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/exception.hpp"
#include "guichan/focushandler.hpp"
#include "guichan/gui.hpp"
#include "guichan/key.hpp"

namespace gcn
{

  Gui::Gui()
  {
    mTop = NULL;
    mInput = NULL;
    mGraphics = NULL;
    mFocusHandler = new FocusHandler();
    mTopHasMouse = false;
		mTabbing = true;
  } // end Gui

  Gui::~Gui()
  {
		if (Widget::widgetExists(mTop))
		{
			setTop(NULL);
		}

    delete mFocusHandler;

  } // end ~Gui

  void Gui::setTop(Widget* top)
  {
    if (mTop)
    {
      mTop->_setFocusHandler(NULL);
    }
    if (top)
    {
      top->_setFocusHandler(mFocusHandler);
    }

    mTop = top;

  } // end setTop

  Widget* Gui::getTop() const
  {
    return mTop;

  } // end getTop

  void Gui::setGraphics(Graphics* graphics)
  {
    mGraphics = graphics;

  } // end setGraphics

  Graphics* Gui::getGraphics() const
  {
    return mGraphics;

  } // end getGraphics

  void Gui::setInput(Input* input)
  {
    mInput = input;

  } // end setInput

  Input* Gui::getInput() const
  {
    return mInput;

  } // end getInput

  void Gui::logic()
  {
    if (!mTop)
    {
      throw GCN_EXCEPTION("Gui::logic. No top widget set");
    }

    if(mInput)
    {
			mInput->_pollInput();

			while (!mInput->isMouseQueueEmpty())
			{
				MouseInput mi = mInput->dequeueMouseInput();

				// Send mouse input to every widget that has the mouse.
				if (mi.x > 0 && mi.y > 0
						&& mTop->getDimension().isPointInRect(mi.x, mi.y))
				{
					if (!mTop->hasMouse())
					{
						mTop->_mouseInMessage();
					}

					MouseInput mio = mi;
					mio.x -= mTop->getX();
					mio.y -= mTop->getY();
					mTop->_mouseInputMessage(mio);
				}
				else if (mTop->hasMouse())
				{
					mTop->_mouseOutMessage();
				}

				Widget* f = mFocusHandler->getFocused();
				Widget* d = mFocusHandler->getDragged();

				// If the focused widget doesn't have the mouse,
				// send the mouse input to the focused widget.
				if (f != NULL && !f->hasMouse())
				{
					int xOffset, yOffset;
					f->getAbsolutePosition(xOffset, yOffset);

					MouseInput mio = mi;
					mio.x -= xOffset;
					mio.y -= yOffset;

					f->_mouseInputMessage(mio);
				}

				// If the dragged widget is different from the focused
				// widget, send the mouse input to the dragged widget.
				if (d != NULL && d != f && !d->hasMouse())
				{
					int xOffset, yOffset;
					d->getAbsolutePosition(xOffset, yOffset);

					MouseInput mio = mi;
					mio.x -= xOffset;
					mio.y -= yOffset;

					d->_mouseInputMessage(mio);
				}

				mFocusHandler->applyChanges();

			} // end while

      while (!mInput->isKeyQueueEmpty())
      {
        KeyInput ki = mInput->dequeueKeyInput();

				if (mTabbing
						&& ki.getKey().getValue() == Key::TAB
						&& ki.getType() == KeyInput::PRESS)
				{
					if (ki.getKey().isShiftPressed())
					{
						mFocusHandler->tabPrevious();
					}
					else
					{
						mFocusHandler->tabNext();
					}
				}
				else
				{
					// Send key inputs to the focused widgets
					if (mFocusHandler->getFocused())
					{
						if (mFocusHandler->getFocused()->isFocusable())
						{
							mFocusHandler->getFocused()->_keyInputMessage(ki);
						}
						else
						{
							mFocusHandler->focusNone();
						}
					}
				}

				mFocusHandler->applyChanges();

      } // end while

    } // end if

    mTop->logic();

	} // end logic

  void Gui::draw()
  {
    if (!mTop)
    {
      throw GCN_EXCEPTION("Gui::draw. No top widget set");
    }
    if (!mGraphics)
    {
      throw GCN_EXCEPTION("Gui::draw. No graphics set");
    }

    mGraphics->_beginDraw();

		// If top has a border,
		// draw it before drawing top
		if (mTop->getBorderSize() > 0)
		{
			Rectangle rec = mTop->getDimension();
			rec.x -= mTop->getBorderSize();
			rec.y -= mTop->getBorderSize();
			rec.width += 2 * mTop->getBorderSize();
			rec.height += 2 * mTop->getBorderSize();
			mGraphics->pushClipArea(rec);
			mTop->drawBorder(mGraphics);
			mGraphics->popClipArea();
		}

		mGraphics->pushClipArea(mTop->getDimension());
    mTop->draw(mGraphics);
    mGraphics->popClipArea();

		mGraphics->_endDraw();

  } // end draw

	void Gui::focusNone()
	{
		mFocusHandler->focusNone();
	}

	void Gui::setTabbingEnabled(bool tabbing)
	{
		mTabbing = tabbing;
	}

	bool Gui::isTabbingEnabled()
	{
		return mTabbing;
	}

} // end gcn
<|endoftext|>


<commit_before>#include "Intake.h"
#include "Commands/IntakeBall.h"
#include "Commands/PushBall.h"
#include <math.h>

/**
 * Subsystems namespace with implementation
 * of Intake class.
 */
namespace subsystems
{

using IntakeBall = commands::IntakeBall;
using PushBall = commands::PushBall;

// Constructor:
Intake::Intake() : Subsystem("Intake")
{
	roller_ = new CANTalon(1);
	detector_ = new DigitalInput(2);
	// Default values:
	intake_speed_ = 1.0;
	push_speed_ = -1.0;
	state_ = State_t::OFF;
	mode_ = Mode_t::VELOCITY;
	max_velocity_ = 30;
	allowed_error_ = 0.1;
}

// Destructor:
Intake::~Intake()
{
	delete roller_;
	delete detector_;
}

// Main functions:
void Intake::Initialize()
{
	roller_->SetFeedbackDevice(CANTalon::QuadEncoder);
	roller_->ConfigEncoderCodesPerRev(1024);
	roller_->SetSensorDirection(false);
	roller_->SelectProfileSlot(0);
	roller_->SetVoltageRampRate(0.0);
	roller_->SetCloseLoopRampRate(0.0);

	// Configure max and min voltage outputs
	roller_->ConfigNominalOutputVoltage(0.0, 0.0);
	roller_->ConfigPeakOutputVoltage(12.0, -12.0);
}

bool Intake::CheckSwitch() const
{
	return (detector_->Get());
}

void Intake::TakeBall(bool check)
{
	if (CheckSwitch() && check)
		Stop();
	else
		SetSpeed(intake_speed_);
}

void Intake::OutakeBall()
{
	SetSpeed(push_speed_);
}

void Intake::SetSpeed(double speed)
{
	if (mode_ == Mode_t::VELOCITY)
	{
		roller_->Set(max_velocity_ * speed);
	}
	else if (mode_ == Mode_t::VBUS)
	{
		roller_->Set(speed);
	}
}

double Intake::GetSpeed() const
{
	return roller_->Get();
}

void Intake::Stop()
{
	SetSpeed(0.0);
}

void Intake::SetIntakeSpeed(double intake_speed)
{
	intake_speed_ = intake_speed;
}

void Intake::SetPushSpeed(double push_speed)
{
	push_speed_ = push_speed;
}

double Intake::GetIntakeSpeed() const
{
	return intake_speed_;
}

double Intake::GetPushSpeed() const
{
	return push_speed_;
}

// Error functions:
double Intake::GetErr() const
{
	return roller_->GetSetpoint() - roller_->Get();
}

void Intake::SetAllowedError(double err)
{
	allowed_error_ = err;
}

double Intake::GetAllowedError() const
{
	return allowed_error_;
}

bool Intake::IsAllowable() const
{
	return (fabs(GetErr()) > fabs(allowed_error_));
}

double Intake::GetMaxVelocity() const
{
	return max_velocity_;
}

void Intake::SetMaxVelocity(double max_velocity)
{
	max_velocity_ = max_velocity;
}

// State functions:
void Intake::SetState(State_t state)
{
	state_ = state;
}

Intake::State_t Intake::GetState() const
{
	return state_;
}

// Mode functions:
void Intake::SetMode(Mode_t mode)
{
	mode_ = mode;
}

Intake::Mode_t Intake::GetMode() const
{
	return mode_;
}

// Command functions:
IntakeBall* Intake::MakeIntakeBall()
{
	return new IntakeBall(this);
}

PushBall* Intake::MakePushBall()
{
	return new PushBall(this);
}

} // end namespace subsystems
<commit_msg>Inconsequential format updates<commit_after>#include "Intake.h"
#include "Commands/IntakeBall.h"
#include "Commands/PushBall.h"
#include <math.h>

/**
 * Subsystems namespace with implementation
 * of Intake class.
 */
namespace subsystems
{

using IntakeBall = commands::IntakeBall;
using PushBall = commands::PushBall;

// Constructor:
Intake::Intake() : Subsystem("Intake")
{
	roller_ = new CANTalon(1);
	detector_ = new DigitalInput(2);

	// Default values:
	intake_speed_ = 1.0;
	push_speed_ = -1.0;

	state_ = State_t::OFF;
	mode_ = Mode_t::VELOCITY;

	max_velocity_ = 30;
	allowed_error_ = 0.1;
}

// Destructor:
Intake::~Intake()
{
	delete roller_;
	delete detector_;
}

// Main functions:
void Intake::Initialize()
{
	roller_->SetFeedbackDevice(CANTalon::QuadEncoder);
	roller_->ConfigEncoderCodesPerRev(1024);
	roller_->SetSensorDirection(false);
	roller_->SelectProfileSlot(0);
	roller_->SetVoltageRampRate(0.0);
	roller_->SetCloseLoopRampRate(0.0);

	// Configure max and min voltage outputs
	roller_->ConfigNominalOutputVoltage(0.0, 0.0);
	roller_->ConfigPeakOutputVoltage(12.0, -12.0);
}

bool Intake::CheckSwitch() const
{
	return (detector_->Get());
}

void Intake::TakeBall(bool check)
{
	if (CheckSwitch() && check)
		Stop();
	else
		SetSpeed(intake_speed_);
}

void Intake::OutakeBall()
{
	SetSpeed(push_speed_);
}

void Intake::SetSpeed(double speed)
{
	if (mode_ == Mode_t::VELOCITY)
	{
		roller_->Set(max_velocity_ * speed);
	}
	else if (mode_ == Mode_t::VBUS)
	{
		roller_->Set(speed);
	}
}

double Intake::GetSpeed() const
{
	return roller_->Get();
}

void Intake::Stop()
{
	SetSpeed(0.0);
}

void Intake::SetIntakeSpeed(double intake_speed)
{
	intake_speed_ = intake_speed;
}

void Intake::SetPushSpeed(double push_speed)
{
	push_speed_ = push_speed;
}

double Intake::GetIntakeSpeed() const
{
	return intake_speed_;
}

double Intake::GetPushSpeed() const
{
	return push_speed_;
}

double Intake::GetMaxVelocity() const
{
	return max_velocity_;
}

void Intake::SetMaxVelocity(double max_velocity)
{
	max_velocity_ = max_velocity;
}

// Error functions:
double Intake::GetErr() const
{
	return roller_->GetSetpoint() - roller_->Get();
}

void Intake::SetAllowedError(double err)
{
	allowed_error_ = err;
}

double Intake::GetAllowedError() const
{
	return allowed_error_;
}

bool Intake::IsAllowable() const
{
	return (fabs(GetErr()) > fabs(allowed_error_));
}

// State functions:
void Intake::SetState(State_t state)
{
	state_ = state;
}

Intake::State_t Intake::GetState() const
{
	return state_;
}

// Control mode functions:
void Intake::SetMode(Mode_t mode)
{
	if (mode_ != mode)
	{
		mode_ = mode;
		if (mode_ == Mode_t::VELOCITY)
			roller_->SetControlMode(CANTalon::ControlMode::kSpeed);
		else if (mode_ == Mode_t::VBUS)
			roller_->SetControlMode(CANTalon::ControlMode::kPercentVbus);
	}
}

Intake::Mode_t Intake::GetMode() const
{
	return mode_;
}

// Command functions:
IntakeBall* Intake::MakeIntakeBall()
{
	return new IntakeBall(this);
}

PushBall* Intake::MakePushBall()
{
	return new PushBall(this);
}

} // end namespace subsystems
<|endoftext|>


<commit_before>/*
  Q Light Controller
  qlcfixturemode.cpp

  Copyright (C) Heikki Junnila

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <iostream>
#include <QString>
#include <QDebug>
#include <QVector>
#include <QtXml>

#include "qlcfixturemode.h"
#include "qlcfixturehead.h"
#include "qlcfixturedef.h"
#include "qlcchannel.h"
#include "qlcphysical.h"

QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef)
    : m_fixtureDef(fixtureDef)
{
    Q_ASSERT(fixtureDef != NULL);
}

QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef, const QLCFixtureMode* mode)
    : m_fixtureDef(fixtureDef)
{
    Q_ASSERT(fixtureDef != NULL);
    Q_ASSERT(mode != NULL);

    if (mode != NULL)
        *this = *mode;
}

QLCFixtureMode::~QLCFixtureMode()
{
}

QLCFixtureMode& QLCFixtureMode::operator=(const QLCFixtureMode& mode)
{
    if (this != &mode)
    {
        m_name = mode.m_name;
        m_physical = mode.m_physical;
        m_heads = mode.m_heads;

        /* Clear the existing list of channels */
        m_channels.clear();

        Q_ASSERT(m_fixtureDef != NULL);

        quint32 i = 0;
        QVectorIterator <QLCChannel*> it(mode.m_channels);
        while (it.hasNext() == true)
        {
            /* Since m_fixtureDef might not be the same as
               mode.m_fixtureDef, we need to search for a
               channel with the same name from m_fixtureDef and
               not from mode.m_fixtureDef. If the channel in the
               other mode is deleted, the one in this copied mode
               will be invalid and we end up in a crash. */
            QLCChannel* ch = it.next();
            QLCChannel* actual = m_fixtureDef->channel(ch->name());
            if (actual != NULL)
                insertChannel(actual, i++);
            else
                qWarning() << Q_FUNC_INFO << "Unable to find channel"
                           << ch->name() << "for mode"
                           << m_name << "from its fixture definition";
        }
    }

    return *this;
}

/****************************************************************************
 * Name
 ****************************************************************************/

void QLCFixtureMode::setName(const QString &name)
{
    m_name = name;
}

QString QLCFixtureMode::name() const
{
    return m_name;
}

/*****************************************************************************
 * Fixture definition
 *****************************************************************************/

QLCFixtureDef* QLCFixtureMode::fixtureDef() const
{
    return m_fixtureDef;
}

/****************************************************************************
 * Channels
 ****************************************************************************/

bool QLCFixtureMode::insertChannel(QLCChannel* channel, quint32 index)
{
    if (channel == NULL)
    {
        qWarning() << Q_FUNC_INFO << "Will not add a NULL channel to mode"
                   << m_name;
        return false;
    }

    Q_ASSERT(m_fixtureDef != NULL);

    if (m_fixtureDef->channels().contains(channel) == true)
    {
        if (m_channels.contains(channel) == false)
        {
            if (index >= quint32(m_channels.size()))
                m_channels.append(channel);
            else
                m_channels.insert(index, channel);
            return true;
        }
        else
        {
            qWarning() << Q_FUNC_INFO << "Channel" << channel->name()
                       << "is already a member of mode" << m_name;
            return false;
        }
    }
    else
    {
        qWarning() << Q_FUNC_INFO << "Will not add channel" << channel->name()
                   << "to mode" << m_name
                   << "because the channel does not belong to mode's"
                   << "parent fixture definition.";
        return false;
    }
}

bool QLCFixtureMode::removeChannel(const QLCChannel* channel)
{
    QMutableVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        if (it.next() == channel)
        {
            /* Don't delete the channel since QLCFixtureModes
               don't own them. QLCFixtureDefs do. */
            it.remove();
            return true;
        }
    }

    return false;
}

void QLCFixtureMode::removeAllChannels()
{
    m_channels.clear();
}

QLCChannel* QLCFixtureMode::channel(const QString& name) const
{
    QVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        QLCChannel* ch = it.next();
        Q_ASSERT(ch != NULL);
        if (ch->name() == name)
            return ch;
    }

    return NULL;
}

QLCChannel* QLCFixtureMode::channel(quint32 ch) const
{
    if (ch >= quint32(m_channels.size()))
        return NULL;
    else
        return m_channels.at(ch);
}

QVector <QLCChannel*> QLCFixtureMode::channels() const
{
    return m_channels;
}

quint32 QLCFixtureMode::channelNumber(QLCChannel* channel) const
{
    if (channel == NULL)
        return QLCChannel::invalid();

    for (int i = 0; i < m_channels.size(); i++)
    {
        if (m_channels.at(i) == channel)
            return i;
    }

    return QLCChannel::invalid();
}

/*****************************************************************************
 * Heads
 *****************************************************************************/

void QLCFixtureMode::insertHead(int index, const QLCFixtureHead& head)
{
    if (index < 0 || index >= m_heads.size())
        m_heads.append(head);
    else
        m_heads.insert(index, head);
}

void QLCFixtureMode::removeHead(int index)
{
    if (index >= 0 && index < m_heads.size())
        m_heads.remove(index);
}

void QLCFixtureMode::replaceHead(int index, const QLCFixtureHead& head)
{
    if (index >= 0 && index < m_heads.size())
        m_heads[index] = head;
}

QVector <QLCFixtureHead> const& QLCFixtureMode::heads() const
{
    return m_heads;
}

int QLCFixtureMode::headForChannel(quint32 chnum) const
{
    for (int i = 0; i < m_heads.size(); i++)
    {
        if (m_heads[i].channels().contains(chnum) == true)
            return i;
    }

    return -1;
}

void QLCFixtureMode::cacheHeads()
{
    for (int i = 0; i < m_heads.size(); i++)
    {
        QLCFixtureHead& head(m_heads[i]);
        head.cacheChannels(this);
    }
}

/****************************************************************************
 * Physical
 ****************************************************************************/

void QLCFixtureMode::setPhysical(const QLCPhysical& physical)
{
    m_physical = physical;
}

QLCPhysical QLCFixtureMode::physical() const
{
    return m_physical;
}

/****************************************************************************
 * Load & Save
 ****************************************************************************/

bool QLCFixtureMode::loadXML(const QDomElement& root)
{
    if (root.tagName() != KXMLQLCFixtureMode)
    {
        qWarning() << Q_FUNC_INFO << "Mode tag not found";
        return false;
    }

    /* Mode name */
    QString str = root.attribute(KXMLQLCFixtureModeName);
    if (str.isEmpty() == true)
    {
        qWarning() << Q_FUNC_INFO << "Mode has no name";
        return false;
    }
    else
    {
        setName(str);
    }

    /* Subtags */
    QDomNode node = root.firstChild();
    while (node.isNull() == false)
    {
        QDomElement tag = node.toElement();
        if (tag.tagName() == KXMLQLCFixtureModeChannel)
        {
            /* Channel */
            Q_ASSERT(m_fixtureDef != NULL);
            str = tag.attribute(KXMLQLCFixtureModeChannelNumber);
            insertChannel(m_fixtureDef->channel(tag.text()),
                          str.toInt());
        }
        else if (tag.tagName() == KXMLQLCFixtureHead)
        {
            /* Head */
            QLCFixtureHead head;
            if (head.loadXML(tag) == true)
                insertHead(-1, head);
        }
        else if (tag.tagName() == KXMLQLCPhysical)
        {
            /* Physical */
            QLCPhysical physical;
            physical.loadXML(tag);
            setPhysical(physical);
        }
        else
        {
            qWarning() << Q_FUNC_INFO << "Unknown Fixture Mode tag:" << tag.tagName();
        }

        node = node.nextSibling();
    }

    // Cache all head channels
    cacheHeads();

    return true;
}

bool QLCFixtureMode::saveXML(QDomDocument* doc, QDomElement* root)
{
    QDomElement tag;
    QDomElement chtag;
    QDomText text;
    QString str;
    int i = 0;

    Q_ASSERT(doc != NULL);
    Q_ASSERT(root != NULL);

    /* Mode entry */
    tag = doc->createElement(KXMLQLCFixtureMode);
    tag.setAttribute(KXMLQLCFixtureModeName, m_name);
    root->appendChild(tag);

    m_physical.saveXML(doc, &tag);

    /* Channels */
    QVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        chtag = doc->createElement(KXMLQLCFixtureModeChannel);
        tag.appendChild(chtag);

        str.setNum(i++);
        chtag.setAttribute(KXMLQLCFixtureModeChannelNumber, str);

        text = doc->createTextNode(it.next()->name());
        chtag.appendChild(text);
    }

    /* Heads */
    QVectorIterator <QLCFixtureHead> hit(m_heads);
    while (hit.hasNext() == true)
        hit.next().saveXML(doc, &tag);

    return true;
}
<commit_msg>qlcfixturemode::channel: less code, same effect<commit_after>/*
  Q Light Controller
  qlcfixturemode.cpp

  Copyright (C) Heikki Junnila

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <iostream>
#include <QString>
#include <QDebug>
#include <QVector>
#include <QtXml>

#include "qlcfixturemode.h"
#include "qlcfixturehead.h"
#include "qlcfixturedef.h"
#include "qlcchannel.h"
#include "qlcphysical.h"

QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef)
    : m_fixtureDef(fixtureDef)
{
    Q_ASSERT(fixtureDef != NULL);
}

QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef, const QLCFixtureMode* mode)
    : m_fixtureDef(fixtureDef)
{
    Q_ASSERT(fixtureDef != NULL);
    Q_ASSERT(mode != NULL);

    if (mode != NULL)
        *this = *mode;
}

QLCFixtureMode::~QLCFixtureMode()
{
}

QLCFixtureMode& QLCFixtureMode::operator=(const QLCFixtureMode& mode)
{
    if (this != &mode)
    {
        m_name = mode.m_name;
        m_physical = mode.m_physical;
        m_heads = mode.m_heads;

        /* Clear the existing list of channels */
        m_channels.clear();

        Q_ASSERT(m_fixtureDef != NULL);

        quint32 i = 0;
        QVectorIterator <QLCChannel*> it(mode.m_channels);
        while (it.hasNext() == true)
        {
            /* Since m_fixtureDef might not be the same as
               mode.m_fixtureDef, we need to search for a
               channel with the same name from m_fixtureDef and
               not from mode.m_fixtureDef. If the channel in the
               other mode is deleted, the one in this copied mode
               will be invalid and we end up in a crash. */
            QLCChannel* ch = it.next();
            QLCChannel* actual = m_fixtureDef->channel(ch->name());
            if (actual != NULL)
                insertChannel(actual, i++);
            else
                qWarning() << Q_FUNC_INFO << "Unable to find channel"
                           << ch->name() << "for mode"
                           << m_name << "from its fixture definition";
        }
    }

    return *this;
}

/****************************************************************************
 * Name
 ****************************************************************************/

void QLCFixtureMode::setName(const QString &name)
{
    m_name = name;
}

QString QLCFixtureMode::name() const
{
    return m_name;
}

/*****************************************************************************
 * Fixture definition
 *****************************************************************************/

QLCFixtureDef* QLCFixtureMode::fixtureDef() const
{
    return m_fixtureDef;
}

/****************************************************************************
 * Channels
 ****************************************************************************/

bool QLCFixtureMode::insertChannel(QLCChannel* channel, quint32 index)
{
    if (channel == NULL)
    {
        qWarning() << Q_FUNC_INFO << "Will not add a NULL channel to mode"
                   << m_name;
        return false;
    }

    Q_ASSERT(m_fixtureDef != NULL);

    if (m_fixtureDef->channels().contains(channel) == true)
    {
        if (m_channels.contains(channel) == false)
        {
            if (index >= quint32(m_channels.size()))
                m_channels.append(channel);
            else
                m_channels.insert(index, channel);
            return true;
        }
        else
        {
            qWarning() << Q_FUNC_INFO << "Channel" << channel->name()
                       << "is already a member of mode" << m_name;
            return false;
        }
    }
    else
    {
        qWarning() << Q_FUNC_INFO << "Will not add channel" << channel->name()
                   << "to mode" << m_name
                   << "because the channel does not belong to mode's"
                   << "parent fixture definition.";
        return false;
    }
}

bool QLCFixtureMode::removeChannel(const QLCChannel* channel)
{
    QMutableVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        if (it.next() == channel)
        {
            /* Don't delete the channel since QLCFixtureModes
               don't own them. QLCFixtureDefs do. */
            it.remove();
            return true;
        }
    }

    return false;
}

void QLCFixtureMode::removeAllChannels()
{
    m_channels.clear();
}

QLCChannel* QLCFixtureMode::channel(const QString& name) const
{
    QVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        QLCChannel* ch = it.next();
        Q_ASSERT(ch != NULL);
        if (ch->name() == name)
            return ch;
    }

    return NULL;
}

QLCChannel* QLCFixtureMode::channel(quint32 ch) const
{
    return m_channels.value(ch, NULL);
}

QVector <QLCChannel*> QLCFixtureMode::channels() const
{
    return m_channels;
}

quint32 QLCFixtureMode::channelNumber(QLCChannel* channel) const
{
    if (channel == NULL)
        return QLCChannel::invalid();

    for (int i = 0; i < m_channels.size(); i++)
    {
        if (m_channels.at(i) == channel)
            return i;
    }

    return QLCChannel::invalid();
}

/*****************************************************************************
 * Heads
 *****************************************************************************/

void QLCFixtureMode::insertHead(int index, const QLCFixtureHead& head)
{
    if (index < 0 || index >= m_heads.size())
        m_heads.append(head);
    else
        m_heads.insert(index, head);
}

void QLCFixtureMode::removeHead(int index)
{
    if (index >= 0 && index < m_heads.size())
        m_heads.remove(index);
}

void QLCFixtureMode::replaceHead(int index, const QLCFixtureHead& head)
{
    if (index >= 0 && index < m_heads.size())
        m_heads[index] = head;
}

QVector <QLCFixtureHead> const& QLCFixtureMode::heads() const
{
    return m_heads;
}

int QLCFixtureMode::headForChannel(quint32 chnum) const
{
    for (int i = 0; i < m_heads.size(); i++)
    {
        if (m_heads[i].channels().contains(chnum) == true)
            return i;
    }

    return -1;
}

void QLCFixtureMode::cacheHeads()
{
    for (int i = 0; i < m_heads.size(); i++)
    {
        QLCFixtureHead& head(m_heads[i]);
        head.cacheChannels(this);
    }
}

/****************************************************************************
 * Physical
 ****************************************************************************/

void QLCFixtureMode::setPhysical(const QLCPhysical& physical)
{
    m_physical = physical;
}

QLCPhysical QLCFixtureMode::physical() const
{
    return m_physical;
}

/****************************************************************************
 * Load & Save
 ****************************************************************************/

bool QLCFixtureMode::loadXML(const QDomElement& root)
{
    if (root.tagName() != KXMLQLCFixtureMode)
    {
        qWarning() << Q_FUNC_INFO << "Mode tag not found";
        return false;
    }

    /* Mode name */
    QString str = root.attribute(KXMLQLCFixtureModeName);
    if (str.isEmpty() == true)
    {
        qWarning() << Q_FUNC_INFO << "Mode has no name";
        return false;
    }
    else
    {
        setName(str);
    }

    /* Subtags */
    QDomNode node = root.firstChild();
    while (node.isNull() == false)
    {
        QDomElement tag = node.toElement();
        if (tag.tagName() == KXMLQLCFixtureModeChannel)
        {
            /* Channel */
            Q_ASSERT(m_fixtureDef != NULL);
            str = tag.attribute(KXMLQLCFixtureModeChannelNumber);
            insertChannel(m_fixtureDef->channel(tag.text()),
                          str.toInt());
        }
        else if (tag.tagName() == KXMLQLCFixtureHead)
        {
            /* Head */
            QLCFixtureHead head;
            if (head.loadXML(tag) == true)
                insertHead(-1, head);
        }
        else if (tag.tagName() == KXMLQLCPhysical)
        {
            /* Physical */
            QLCPhysical physical;
            physical.loadXML(tag);
            setPhysical(physical);
        }
        else
        {
            qWarning() << Q_FUNC_INFO << "Unknown Fixture Mode tag:" << tag.tagName();
        }

        node = node.nextSibling();
    }

    // Cache all head channels
    cacheHeads();

    return true;
}

bool QLCFixtureMode::saveXML(QDomDocument* doc, QDomElement* root)
{
    QDomElement tag;
    QDomElement chtag;
    QDomText text;
    QString str;
    int i = 0;

    Q_ASSERT(doc != NULL);
    Q_ASSERT(root != NULL);

    /* Mode entry */
    tag = doc->createElement(KXMLQLCFixtureMode);
    tag.setAttribute(KXMLQLCFixtureModeName, m_name);
    root->appendChild(tag);

    m_physical.saveXML(doc, &tag);

    /* Channels */
    QVectorIterator <QLCChannel*> it(m_channels);
    while (it.hasNext() == true)
    {
        chtag = doc->createElement(KXMLQLCFixtureModeChannel);
        tag.appendChild(chtag);

        str.setNum(i++);
        chtag.setAttribute(KXMLQLCFixtureModeChannelNumber, str);

        text = doc->createTextNode(it.next()->name());
        chtag.appendChild(text);
    }

    /* Heads */
    QVectorIterator <QLCFixtureHead> hit(m_heads);
    while (hit.hasNext() == true)
        hit.next().saveXML(doc, &tag);

    return true;
}
<|endoftext|>