<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "MooseVariableBase.h"
#include "SubProblem.h"
#include "SystemBase.h"
#include "MooseMesh.h"
#include "MooseApp.h"
#include "InputParameterWarehouse.h"

#include "libmesh/variable.h"
#include "libmesh/dof_map.h"
#include "libmesh/system.h"
#include "libmesh/fe_type.h"
#include "libmesh/string_to_enum.h"

// Users should never actually create this object
registerMooseObject("MooseApp", MooseVariableBase);

defineLegacyParams(MooseVariableBase);

InputParameters
MooseVariableBase::validParams()
{
  InputParameters params = MooseObject::validParams();
  params += BlockRestrictable::validParams();
  params += OutputInterface::validParams();

  MooseEnum order(
      "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH "
      "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH "
      "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH "
      "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH "
      "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST "
      "FORTYSECOND FORTYTHIRD",
      "FIRST",
      true);
  params.addParam<MooseEnum>("order",
                             order,
                             "Order of the FE shape function to use for this variable (additional "
                             "orders not listed here are allowed, depending on the family).");

  MooseEnum family("LAGRANGE MONOMIAL HERMITE SCALAR HIERARCHIC CLOUGH XYZ SZABAB BERNSTEIN "
                   "L2_LAGRANGE L2_HIERARCHIC NEDELEC_ONE LAGRANGE_VEC MONOMIAL_VEC",
                   "LAGRANGE");
  params.addParam<MooseEnum>(
      "family", family, "Specifies the family of FE shape functions to use for this variable.");

  // ArrayVariable capability
  params.addRangeCheckedParam<unsigned int>(
      "components", 1, "components>0", "Number of components for an array variable");

  // Advanced input options
  params.addParam<std::vector<Real>>("scaling",
                                     "Specifies a scaling factor to apply to this variable");
  params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
  params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
  params.addParamNamesToGroup("scaling eigen", "Advanced");

  params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");

  params.registerBase("MooseVariableBase");
  params.addPrivateParam<SystemBase *>("_system_base");
  params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
  params.addPrivateParam<Moose::VarKindType>("_var_kind");
  params.addPrivateParam<unsigned int>("_var_num");
  params.addPrivateParam<THREAD_ID>("tid");

  params.addClassDescription(
      "Base class for Moose variables. This should never be the terminal object type");
  return params;
}

MooseVariableBase::MooseVariableBase(const InputParameters & parameters)
  : MooseObject(parameters),
    BlockRestrictable(this),
    OutputInterface(parameters),
    SetupInterface(this),
    _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
    _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
             Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
    _var_num(getParam<unsigned int>("_var_num")),
    _is_eigen(getParam<bool>("eigen")),
    _var_kind(getParam<Moose::VarKindType>("_var_kind")),
    _subproblem(_sys.subproblem()),
    _variable(_sys.system().variable(_var_num)),
    _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"))),
    _dof_map(_sys.dofMap()),
    _mesh(_subproblem.mesh()),
    _tid(getParam<THREAD_ID>("tid")),
    _count(getParam<unsigned int>("components")),
    _use_dual(getParam<bool>("use_dual"))
{
  scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
                                        : std::vector<Real>(_count, 1.));

  if (getParam<bool>("fv") && getParam<bool>("eigen"))
    paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
  if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
    paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
  if (getParam<bool>("fv") && _fe_type.order != 0)
    paramError("order", "finite volume (fv=true) variables currently support CONST order only");

  if (_count > 1)
  {
    auto name0 = _sys.system().variable(_var_num).name();
    std::size_t found = name0.find_last_of("_");
    if (found == std::string::npos)
      mooseError("Error creating ArrayMooseVariable name with base name ", name0);
    _var_name = name0.substr(0, found);
  }
  else
    _var_name = _sys.system().variable(_var_num).name();
}

const std::vector<dof_id_type> &
MooseVariableBase::allDofIndices() const
{
  const auto it = _sys.subproblem()._var_dof_map.find(name());
  if (it != _sys.subproblem()._var_dof_map.end())
    return it->second;
  else
    mooseError("VariableAllDoFMap not prepared for ",
               name(),
               " . Check nonlocal coupling requirement for the variable.");
}

Order
MooseVariableBase::order() const
{
  return _fe_type.order;
}

std::vector<dof_id_type>
MooseVariableBase::componentDofIndices(const std::vector<dof_id_type> & dof_indices,
                                       unsigned int component) const
{
  std::vector<dof_id_type> new_dof_indices(dof_indices);
  if (component != 0)
  {
    if (isNodal())
      for (auto & id : new_dof_indices)
        id += component;
    else
    {
      unsigned int n = dof_indices.size();
      for (auto & id : new_dof_indices)
        id += component * n;
    }
  }
  return new_dof_indices;
}

void
MooseVariableBase::scalingFactor(Real factor)
{
  _scaling_factor.assign(_count, factor);

#ifdef MOOSE_GLOBAL_AD_INDEXING
  if (!MooseUtils::absoluteFuzzyEqual(factor, 1.) && !_sys.hasVector("scaling_factors"))
    _sys.addScalingVector();
#endif
}

void
MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
{
  _scaling_factor = factor;
}

void
MooseVariableBase::initialSetup()
{
#ifdef MOOSE_GLOBAL_AD_INDEXING
  // Currently the scaling vector is only used through AD residual computing objects
  if (_subproblem.haveADObjects() && !_sys.hasVector("scaling_factors") &&
      std::find_if(_scaling_factor.begin(), _scaling_factor.end(), [](const Real element) {
        return !MooseUtils::absoluteFuzzyEqual(element, 1.);
      }) != _scaling_factor.end())
    _sys.addScalingVector();
#endif
}
<commit_msg>Always addScalingVector from MooseVariableBase::initialSetup<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "MooseVariableBase.h"
#include "SubProblem.h"
#include "SystemBase.h"
#include "MooseMesh.h"
#include "MooseApp.h"
#include "InputParameterWarehouse.h"

#include "libmesh/variable.h"
#include "libmesh/dof_map.h"
#include "libmesh/system.h"
#include "libmesh/fe_type.h"
#include "libmesh/string_to_enum.h"

// Users should never actually create this object
registerMooseObject("MooseApp", MooseVariableBase);

defineLegacyParams(MooseVariableBase);

InputParameters
MooseVariableBase::validParams()
{
  InputParameters params = MooseObject::validParams();
  params += BlockRestrictable::validParams();
  params += OutputInterface::validParams();

  MooseEnum order(
      "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH "
      "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH "
      "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH "
      "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH "
      "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST "
      "FORTYSECOND FORTYTHIRD",
      "FIRST",
      true);
  params.addParam<MooseEnum>("order",
                             order,
                             "Order of the FE shape function to use for this variable (additional "
                             "orders not listed here are allowed, depending on the family).");

  MooseEnum family("LAGRANGE MONOMIAL HERMITE SCALAR HIERARCHIC CLOUGH XYZ SZABAB BERNSTEIN "
                   "L2_LAGRANGE L2_HIERARCHIC NEDELEC_ONE LAGRANGE_VEC MONOMIAL_VEC",
                   "LAGRANGE");
  params.addParam<MooseEnum>(
      "family", family, "Specifies the family of FE shape functions to use for this variable.");

  // ArrayVariable capability
  params.addRangeCheckedParam<unsigned int>(
      "components", 1, "components>0", "Number of components for an array variable");

  // Advanced input options
  params.addParam<std::vector<Real>>("scaling",
                                     "Specifies a scaling factor to apply to this variable");
  params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
  params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
  params.addParamNamesToGroup("scaling eigen", "Advanced");

  params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");

  params.registerBase("MooseVariableBase");
  params.addPrivateParam<SystemBase *>("_system_base");
  params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
  params.addPrivateParam<Moose::VarKindType>("_var_kind");
  params.addPrivateParam<unsigned int>("_var_num");
  params.addPrivateParam<THREAD_ID>("tid");

  params.addClassDescription(
      "Base class for Moose variables. This should never be the terminal object type");
  return params;
}

MooseVariableBase::MooseVariableBase(const InputParameters & parameters)
  : MooseObject(parameters),
    BlockRestrictable(this),
    OutputInterface(parameters),
    SetupInterface(this),
    _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
    _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
             Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
    _var_num(getParam<unsigned int>("_var_num")),
    _is_eigen(getParam<bool>("eigen")),
    _var_kind(getParam<Moose::VarKindType>("_var_kind")),
    _subproblem(_sys.subproblem()),
    _variable(_sys.system().variable(_var_num)),
    _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"))),
    _dof_map(_sys.dofMap()),
    _mesh(_subproblem.mesh()),
    _tid(getParam<THREAD_ID>("tid")),
    _count(getParam<unsigned int>("components")),
    _use_dual(getParam<bool>("use_dual"))
{
  scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
                                        : std::vector<Real>(_count, 1.));

  if (getParam<bool>("fv") && getParam<bool>("eigen"))
    paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
  if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
    paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
  if (getParam<bool>("fv") && _fe_type.order != 0)
    paramError("order", "finite volume (fv=true) variables currently support CONST order only");

  if (_count > 1)
  {
    auto name0 = _sys.system().variable(_var_num).name();
    std::size_t found = name0.find_last_of("_");
    if (found == std::string::npos)
      mooseError("Error creating ArrayMooseVariable name with base name ", name0);
    _var_name = name0.substr(0, found);
  }
  else
    _var_name = _sys.system().variable(_var_num).name();
}

const std::vector<dof_id_type> &
MooseVariableBase::allDofIndices() const
{
  const auto it = _sys.subproblem()._var_dof_map.find(name());
  if (it != _sys.subproblem()._var_dof_map.end())
    return it->second;
  else
    mooseError("VariableAllDoFMap not prepared for ",
               name(),
               " . Check nonlocal coupling requirement for the variable.");
}

Order
MooseVariableBase::order() const
{
  return _fe_type.order;
}

std::vector<dof_id_type>
MooseVariableBase::componentDofIndices(const std::vector<dof_id_type> & dof_indices,
                                       unsigned int component) const
{
  std::vector<dof_id_type> new_dof_indices(dof_indices);
  if (component != 0)
  {
    if (isNodal())
      for (auto & id : new_dof_indices)
        id += component;
    else
    {
      unsigned int n = dof_indices.size();
      for (auto & id : new_dof_indices)
        id += component * n;
    }
  }
  return new_dof_indices;
}

void
MooseVariableBase::scalingFactor(Real factor)
{
  _scaling_factor.assign(_count, factor);

#ifdef MOOSE_GLOBAL_AD_INDEXING
  if (!MooseUtils::absoluteFuzzyEqual(factor, 1.) && !_sys.hasVector("scaling_factors"))
    _sys.addScalingVector();
#endif
}

void
MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
{
  _scaling_factor = factor;
}

void
MooseVariableBase::initialSetup()
{
#ifdef MOOSE_GLOBAL_AD_INDEXING
  // Currently the scaling vector is only used through AD residual computing objects
  if (_subproblem.haveADObjects() &&
      std::find_if(_scaling_factor.begin(), _scaling_factor.end(), [](const Real element) {
        return !MooseUtils::absoluteFuzzyEqual(element, 1.);
      }) != _scaling_factor.end())
    _sys.addScalingVector();
#endif
}
<|endoftext|>


<commit_before>#include "Action.h"

Action::Action(const int _action):
action(_action)
{}

void Action::execute()
{
  //call stored function
}

bool operator==(const Action& target) const
{
  //two actions must be equal if their identifiers are equal
  return action==target.action;
}

bool operator!=(const Action& target) const
{
  return !(*this == target);
}
<commit_msg>Updated constructor definition and operator=<commit_after>#include "Action.h"

Action::Action(const int _action, void (*)() _execute):
action(_action), execute(_execute)
{}

bool operator==(const Action& target) const
{
  //two actions must be equal if their identifiers are equal
  return action==target.action;
}

bool operator!=(const Action& target) const
{
  return !(*this == target);
}

const Action& operator=(const Action& target)
{
  action = target.action;
}
<|endoftext|>


<commit_before><commit_msg>WaE: MSVC2008 C4099 class/struct<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2013-2016 Anton Kozhevnikov, Thomas Schulthess
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
//    following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
//    and the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.

/** \file generate_fv_states.hpp
 *
 *  \brief Contains implementation of sirius::K_point::generate_fv_states method.
 */

inline void K_point::generate_fv_states()
{
    PROFILE("sirius::K_point::generate_fv_states");

    if (!ctx_.full_potential()) {
        return;
    }

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        fv_eigen_vectors_slab().pw_coeffs().allocate_on_device();
        fv_eigen_vectors_slab().pw_coeffs().copy_to_device(0, ctx_.num_fv_states());
    }
    #endif

    /* get thread id */
    #ifdef __GPU
    //int tid = omp_get_thread_num();
    #endif
    mdarray<double_complex, 2> alm(num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size(), memory_t::host_pinned);
    mdarray<double_complex, 2> tmp(unit_cell_.max_mt_aw_basis_size(), ctx_.num_fv_states());

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        alm.allocate(memory_t::device);
        tmp.allocate(memory_t::device);
    }
    #endif

    //#pragma omp for
    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto location = fv_eigen_vectors_slab().spl_num_atoms().location(ia);
        /* number of alm coefficients for atom */
        int mt_aw_size = unit_cell_.atom(ia).mt_aw_basis_size();
        int mt_lo_size = unit_cell_.atom(ia).mt_lo_basis_size();
        /* generate matching coefficients for all G-vectors */
        alm_coeffs_loc_->generate(ia, alm);

        double_complex* tmp_ptr_gpu = (ctx_.processing_unit() == GPU) ? tmp.at<GPU>() : nullptr;
        mdarray<double_complex, 2> tmp1(tmp.at<CPU>(), tmp_ptr_gpu, mt_aw_size, ctx_.num_fv_states());

        /* compute F(lm, i) = A(lm, G)^{T} * evec(G, i) for a single atom */
        if (ctx_.processing_unit() == CPU) {
            linalg<CPU>::gemm(1, 0, mt_aw_size, ctx_.num_fv_states(), num_gkvec_loc(),
                              alm.at<CPU>(), alm.ld(),
                              fv_eigen_vectors_slab().pw_coeffs().prime().at<CPU>(), fv_eigen_vectors_slab().pw_coeffs().prime().ld(),
                              tmp1.at<CPU>(), tmp1.ld());
        }
        #ifdef __GPU
        if (ctx_.processing_unit() == GPU) {
            alm.copy_to_device(mt_aw_size * num_gkvec_loc());
            linalg<GPU>::gemm(1, 0, mt_aw_size, ctx_.num_fv_states(), num_gkvec_loc(),
                              alm.at<GPU>(), alm.ld(),
                              fv_eigen_vectors_slab().pw_coeffs().prime().at<GPU>(), fv_eigen_vectors_slab().pw_coeffs().prime().ld(),
                              tmp1.at<GPU>(), tmp1.ld());
            tmp1.copy_to_host();
        }
        #endif

        comm_.reduce(tmp1.at<CPU>(), static_cast<int>(tmp1.size()), location.rank);

        if (location.rank == comm_.rank()) {
            int offset1 = fv_states().offset_mt_coeffs(location.local_index);
            int offset2 = fv_eigen_vectors_slab().offset_mt_coeffs(location.local_index);
            for (int i = 0; i < ctx_.num_fv_states(); i++) {
                /* aw block */
                std::memcpy(fv_states().mt_coeffs().prime().at<CPU>(offset1, i),
                            tmp1.at<CPU>(0, i),
                            mt_aw_size * sizeof(double_complex));
                /* lo block */
                if (mt_lo_size) {
                    std::memcpy(fv_states().mt_coeffs().prime().at<CPU>(offset1 + mt_aw_size, i),
                                fv_eigen_vectors_slab().mt_coeffs().prime().at<CPU>(offset2, i),
                                mt_lo_size * sizeof(double_complex));
                }
            }
        }
    }

    #pragma omp parallel for
    for (int i = 0; i < ctx_.num_fv_states(); i++) {
        /* G+k block */
        std::memcpy(fv_states().pw_coeffs().prime().at<CPU>(0, i),
                    fv_eigen_vectors_slab().pw_coeffs().prime().at<CPU>(0, i),
                    num_gkvec_loc() * sizeof(double_complex));
    }

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        fv_eigen_vectors_slab().pw_coeffs().deallocate_on_device();
    }
    #endif
}
<commit_msg>print checksums<commit_after>// Copyright (c) 2013-2016 Anton Kozhevnikov, Thomas Schulthess
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
//    following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
//    and the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.

/** \file generate_fv_states.hpp
 *
 *  \brief Contains implementation of sirius::K_point::generate_fv_states method.
 */

inline void K_point::generate_fv_states()
{
    PROFILE("sirius::K_point::generate_fv_states");

    if (!ctx_.full_potential()) {
        return;
    }

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        fv_eigen_vectors_slab().pw_coeffs().allocate_on_device();
        fv_eigen_vectors_slab().pw_coeffs().copy_to_device(0, ctx_.num_fv_states());
    }
    #endif

    mdarray<double_complex, 2> alm(num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size(), memory_t::host_pinned);
    mdarray<double_complex, 2> tmp(unit_cell_.max_mt_aw_basis_size(), ctx_.num_fv_states());

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        alm.allocate(memory_t::device);
        tmp.allocate(memory_t::device);
    }
    #endif

    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto location = fv_eigen_vectors_slab().spl_num_atoms().location(ia);
        /* number of alm coefficients for atom */
        int mt_aw_size = unit_cell_.atom(ia).mt_aw_basis_size();
        int mt_lo_size = unit_cell_.atom(ia).mt_lo_basis_size();
        /* generate matching coefficients for all G-vectors */
        alm_coeffs_loc_->generate(ia, alm);

        double_complex* tmp_ptr_gpu = (ctx_.processing_unit() == GPU) ? tmp.at<GPU>() : nullptr;
        mdarray<double_complex, 2> tmp1(tmp.at<CPU>(), tmp_ptr_gpu, mt_aw_size, ctx_.num_fv_states());

        /* compute F(lm, i) = A(lm, G)^{T} * evec(G, i) for a single atom */
        if (ctx_.processing_unit() == CPU) {
            linalg<CPU>::gemm(1, 0, mt_aw_size, ctx_.num_fv_states(), num_gkvec_loc(),
                              alm.at<CPU>(), alm.ld(),
                              fv_eigen_vectors_slab().pw_coeffs().prime().at<CPU>(), fv_eigen_vectors_slab().pw_coeffs().prime().ld(),
                              tmp1.at<CPU>(), tmp1.ld());
        }
        #ifdef __GPU
        if (ctx_.processing_unit() == GPU) {
            alm.copy_to_device(mt_aw_size * num_gkvec_loc());
            linalg<GPU>::gemm(1, 0, mt_aw_size, ctx_.num_fv_states(), num_gkvec_loc(),
                              alm.at<GPU>(), alm.ld(),
                              fv_eigen_vectors_slab().pw_coeffs().prime().at<GPU>(), fv_eigen_vectors_slab().pw_coeffs().prime().ld(),
                              tmp1.at<GPU>(), tmp1.ld());
            tmp1.copy_to_host();
        }
        #endif

        comm_.reduce(tmp1.at<CPU>(), static_cast<int>(tmp1.size()), location.rank);

        #ifdef __PRINT_OBJECT_CHECKSUM
        auto z1 = tmp1.checksum();
        DUMP("checksum(tmp1): %18.10f %18.10f", std::real(z1), std::imag(z1));
        #endif

        if (location.rank == comm_.rank()) {
            int offset1 = fv_states().offset_mt_coeffs(location.local_index);
            int offset2 = fv_eigen_vectors_slab().offset_mt_coeffs(location.local_index);
            for (int i = 0; i < ctx_.num_fv_states(); i++) {
                /* aw block */
                std::memcpy(fv_states().mt_coeffs().prime().at<CPU>(offset1, i),
                            tmp1.at<CPU>(0, i),
                            mt_aw_size * sizeof(double_complex));
                /* lo block */
                if (mt_lo_size) {
                    std::memcpy(fv_states().mt_coeffs().prime().at<CPU>(offset1 + mt_aw_size, i),
                                fv_eigen_vectors_slab().mt_coeffs().prime().at<CPU>(offset2, i),
                                mt_lo_size * sizeof(double_complex));
                }
            }
        }
    }

    #pragma omp parallel for
    for (int i = 0; i < ctx_.num_fv_states(); i++) {
        /* G+k block */
        std::memcpy(fv_states().pw_coeffs().prime().at<CPU>(0, i),
                    fv_eigen_vectors_slab().pw_coeffs().prime().at<CPU>(0, i),
                    num_gkvec_loc() * sizeof(double_complex));
    }

    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        fv_eigen_vectors_slab().pw_coeffs().deallocate_on_device();
    }
    #endif
}
<|endoftext|>


<commit_before>#include "map/gps_track_container.hpp"

#include "base/logging.hpp"

namespace
{

uint32_t constexpr kDefaultMaxSize = 100000;
hours constexpr kDefaultDuration = hours(24);

uint32_t constexpr kSecondsPerHour = 60 * 60;

} // namespace

GpsTrackContainer::GpsTrackContainer()
    : m_trackDuration(kDefaultDuration)
    , m_maxSize(kDefaultMaxSize)
    , m_counter(0)
{
}

void GpsTrackContainer::SetDuration(hours duration)
{
  lock_guard<mutex> lg(m_guard);

  m_trackDuration = duration;

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback && !removed.empty())
    m_callback(vector<GpsTrackPoint>(), move(removed));
}

void GpsTrackContainer::SetMaxSize(size_t maxSize)
{
  lock_guard<mutex> lg(m_guard);

  m_maxSize = maxSize;

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback && !removed.empty())
    m_callback(vector<GpsTrackPoint>(), move(removed));
}

void GpsTrackContainer::SetCallback(TGpsTrackDiffCallback callback, bool sendAll)
{
  lock_guard<mutex> lg(m_guard);

  m_callback = callback;

  if (!m_callback || !sendAll || m_points.empty())
    return;

  vector<GpsTrackPoint> added;
  CopyPoints(added);

  m_callback(move(added), vector<uint32_t>());
}

uint32_t GpsTrackContainer::AddPoint(m2::PointD const & point, double speedMPS, double timestamp)
{
  lock_guard<mutex> lg(m_guard);

  GpsTrackPoint gtp;
  gtp.m_timestamp = timestamp;
  gtp.m_point = point;
  gtp.m_speedMPS = speedMPS;
  gtp.m_id = ++m_counter;

  // Do not process points which are come with timestamp earlier than timestamp of the last point
  // because it is probably some error in logic or gps error, because valid gps must provide UTC time which is growing.
  if (!m_points.empty() && timestamp < m_points.back().m_timestamp)
  {
    LOG(LINFO, ("Incorrect GPS timestamp sequence"));
    return kInvalidId;
  }

  m_points.push_back(gtp);

  vector<GpsTrackPoint> added;
  added.emplace_back(gtp);

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback)
    m_callback(move(added), move(removed));

  return gtp.m_id;
}

void GpsTrackContainer::GetPoints(vector<GpsTrackPoint> & points) const
{
  lock_guard<mutex> lg(m_guard);

  CopyPoints(points);
}

void GpsTrackContainer::RemoveOldPoints(vector<uint32_t> & removedIds)
{
  // Must be called under m_guard lock

  if (m_points.empty())
    return;

  time_t const lowerBorder = m_points.back().m_timestamp - kSecondsPerHour * m_trackDuration.count();

  if (m_points.front().m_timestamp < lowerBorder)
  {
    GpsTrackPoint pt;
    pt.m_timestamp = lowerBorder;

    auto const itr = lower_bound(m_points.begin(), m_points.end(), pt,
                                 [](GpsTrackPoint const & a, GpsTrackPoint const & b)->bool{ return a.m_timestamp < b.m_timestamp; });

    if (itr != m_points.begin())
    {
      removedIds.reserve(removedIds.size() + distance(m_points.begin(), itr));
      for (auto i = m_points.begin(); i != itr; ++i)
        removedIds.emplace_back(i->m_id);

      m_points.erase(m_points.begin(), itr);
    }
  }

  if (m_points.size() > m_maxSize)
  {
    auto const itr = m_points.begin() + m_points.size() - m_maxSize;

    removedIds.reserve(removedIds.size() + distance(m_points.begin(), itr));
    for (auto i = m_points.begin(); i != itr; ++i)
      removedIds.emplace_back(i->m_id);

    m_points.erase(m_points.begin(), itr);
  }
}

void GpsTrackContainer::CopyPoints(vector<GpsTrackPoint> & points) const
{
  // Must be called under m_guard lock

  vector<GpsTrackPoint> tmp;
  tmp.reserve(m_points.size());
  copy(m_points.begin(), m_points.end(), back_inserter(tmp));
  points.swap(tmp);
}
<commit_msg>Fix identifier order in container. It must be linear<commit_after>#include "map/gps_track_container.hpp"

#include "base/logging.hpp"

namespace
{

uint32_t constexpr kDefaultMaxSize = 100000;
hours constexpr kDefaultDuration = hours(24);

uint32_t constexpr kSecondsPerHour = 60 * 60;

} // namespace

GpsTrackContainer::GpsTrackContainer()
    : m_trackDuration(kDefaultDuration)
    , m_maxSize(kDefaultMaxSize)
    , m_counter(0)
{
}

void GpsTrackContainer::SetDuration(hours duration)
{
  lock_guard<mutex> lg(m_guard);

  m_trackDuration = duration;

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback && !removed.empty())
    m_callback(vector<GpsTrackPoint>(), move(removed));
}

void GpsTrackContainer::SetMaxSize(size_t maxSize)
{
  lock_guard<mutex> lg(m_guard);

  m_maxSize = maxSize;

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback && !removed.empty())
    m_callback(vector<GpsTrackPoint>(), move(removed));
}

void GpsTrackContainer::SetCallback(TGpsTrackDiffCallback callback, bool sendAll)
{
  lock_guard<mutex> lg(m_guard);

  m_callback = callback;

  if (!m_callback || !sendAll || m_points.empty())
    return;

  vector<GpsTrackPoint> added;
  CopyPoints(added);

  m_callback(move(added), vector<uint32_t>());
}

uint32_t GpsTrackContainer::AddPoint(m2::PointD const & point, double speedMPS, double timestamp)
{
  lock_guard<mutex> lg(m_guard);

  // Do not process points which are come with timestamp earlier than timestamp of the last point
  // because it is probably some error in logic or gps error, because valid gps must provide UTC time which is growing.
  if (!m_points.empty() && timestamp < m_points.back().m_timestamp)
  {
    LOG(LINFO, ("Incorrect GPS timestamp sequence"));
    return kInvalidId;
  }

  GpsTrackPoint gtp;
  gtp.m_timestamp = timestamp;
  gtp.m_point = point;
  gtp.m_speedMPS = speedMPS;
  gtp.m_id = ++m_counter;

  m_points.push_back(gtp);

  vector<GpsTrackPoint> added;
  added.emplace_back(gtp);

  vector<uint32_t> removed;
  RemoveOldPoints(removed);

  if (m_callback)
    m_callback(move(added), move(removed));

  return gtp.m_id;
}

void GpsTrackContainer::GetPoints(vector<GpsTrackPoint> & points) const
{
  lock_guard<mutex> lg(m_guard);

  CopyPoints(points);
}

void GpsTrackContainer::RemoveOldPoints(vector<uint32_t> & removedIds)
{
  // Must be called under m_guard lock

  if (m_points.empty())
    return;

  time_t const lowerBorder = m_points.back().m_timestamp - kSecondsPerHour * m_trackDuration.count();

  if (m_points.front().m_timestamp < lowerBorder)
  {
    GpsTrackPoint pt;
    pt.m_timestamp = lowerBorder;

    auto const itr = lower_bound(m_points.begin(), m_points.end(), pt,
                                 [](GpsTrackPoint const & a, GpsTrackPoint const & b)->bool{ return a.m_timestamp < b.m_timestamp; });

    if (itr != m_points.begin())
    {
      removedIds.reserve(removedIds.size() + distance(m_points.begin(), itr));
      for (auto i = m_points.begin(); i != itr; ++i)
        removedIds.emplace_back(i->m_id);

      m_points.erase(m_points.begin(), itr);
    }
  }

  if (m_points.size() > m_maxSize)
  {
    auto const itr = m_points.begin() + m_points.size() - m_maxSize;

    removedIds.reserve(removedIds.size() + distance(m_points.begin(), itr));
    for (auto i = m_points.begin(); i != itr; ++i)
      removedIds.emplace_back(i->m_id);

    m_points.erase(m_points.begin(), itr);
  }
}

void GpsTrackContainer::CopyPoints(vector<GpsTrackPoint> & points) const
{
  // Must be called under m_guard lock

  vector<GpsTrackPoint> tmp;
  tmp.reserve(m_points.size());
  copy(m_points.begin(), m_points.end(), back_inserter(tmp));
  points.swap(tmp);
}
<|endoftext|>


<commit_before>#include <bitcoin/bitcoin.hpp>
using namespace bc;

int main(int argc, char** argv)
{
    if (argc != 2)
    {
        std::cerr << "Usage: sx validaddr ADDRESS" << std::endl;
        return -1;
    }
    payment_address payaddr;
    if (!payaddr.set_encoded(argv[1]))
    {
        std::cout << "Status: invalid" << std::endl;
        return 1;
    }
    std::cout << "Status: OK" << std::endl;
    return 0;
}

<commit_msg>more standard output for validaddr.<commit_after>#include <bitcoin/bitcoin.hpp>
using namespace bc;

int main(int argc, char** argv)
{
    if (argc != 2)
    {
        std::cerr << "Usage: sx validaddr ADDRESS" << std::endl;
        return -1;
    }
    payment_address payaddr;
    if (!payaddr.set_encoded(argv[1]))
    {
        std::cout << "Status: Invalid" << std::endl;
        return 1;
    }
    std::cout << "Status: Success" << std::endl;
    return 0;
}

<|endoftext|>


<commit_before>#include "thunder_system.h"
#include "game/detail/camera_cone.h"
#include "augs/templates/container_templates.h"
#include "augs/graphics/drawers.h"
#include "game/resources/manager.h"
#include "game/systems_temporary/physics_system.h"
#include "game/systems_audiovisual/particles_simulation_system.h"
#include "game/enums/filters.h"
#include "game/transcendental/cosmos.h"
#include "game/detail/particle_types.h"

void thunder_system::thunder::create_root_branch() {
	static thread_local fast_randomization rng;

	thunder::branch b;
	b.lifetime_ms = 0.f;
	b.from = in.first_branch_root.pos;
	b.to = b.from + vec2().set_from_degrees(
		in.first_branch_root.rotation + rng.randval(in.branch_angle_spread)
	) * rng.randval(in.branch_length);
	b.max_lifetime_ms = rng.randval(in.max_branch_lifetime_ms);

	until_next_branching_ms = rng.randval(in.delay_between_branches_ms);
	++num_active_branches;

	branches.push_back(b);
}

void thunder_system::add(const thunder::input in) {
	ensure(in.max_all_spawned_branches > 0);

	thunder new_thunder;
	new_thunder.in = in;
	new_thunder.create_root_branch();

	thunders.push_back(new_thunder);
}

void thunder_system::advance(
	const cosmos& cosmos,
	const augs::delta dt,
	particles_simulation_system& particles_output_for_effects
) {
	static thread_local fast_randomization rng;

	for (thunder& t : thunders) {
		t.until_next_branching_ms -= dt.in_milliseconds();

		const bool should_branch_now = t.until_next_branching_ms <= 0.f;

		if (should_branch_now) {
			t.until_next_branching_ms = rng.randval(t.in.delay_between_branches_ms);

			bool found_suitable_parent = false;

			for (size_t i = 0; i < t.branches.size(); ++i) {
				auto& b = t.branches[i];

				const bool is_leaf = b.children.empty();

				if (is_leaf && b.can_have_children) {
					const auto num_children = std::min(t.in.max_all_spawned_branches, rng.randval(0u, t.in.max_branch_children));

					for (auto i = 0u; i < num_children; ++i) {
						thunder::branch child;
						child.activated = true;
						child.lifetime_ms = 0.f;
						child.from = b.to;
						child.to =
							child.from + vec2().set_from_degrees(rng.randval(t.in.branch_angle_spread) + (b.to - b.from).degrees()) * rng.randval(t.in.branch_length);
						child.max_lifetime_ms = rng.randval(t.in.max_branch_lifetime_ms);

						const auto raycast = cosmos.systems_temporary.get<physics_system>().ray_cast_px(
							cosmos.get_si(),
							child.from,
							child.to,
							filters::bullet()
						);

						if (raycast.hit) {
							child.can_have_children = false;
							child.to = raycast.intersection;
						}

						b.children.push_back(t.branches.size());
						t.branches.push_back(child);
						++t.num_active_branches;
						--t.in.max_all_spawned_branches;
					}

					found_suitable_parent = true;
				}
			}

			if (!found_suitable_parent) {
				t.create_root_branch();
			}
		}

		for (auto& b : t.branches) {
			b.lifetime_ms += dt.in_milliseconds();

			if (b.activated && b.lifetime_ms > b.max_lifetime_ms) {
				const bool is_leaf = b.children.empty();

				if (is_leaf) {
					const auto remnants_emission = get_resource_manager().find(assets::particle_effect_id::THUNDER_REMNANTS)->at(0);

					{
						const auto spawner = [&](auto dummy) {
							auto& new_p = particles_output_for_effects.spawn_particle<decltype(dummy)>(
								rng,
								0.f,
								{ 20.f, 100.f },
								b.to,
								0.f,
								360.f,
								remnants_emission
							);

							new_p.colorize(t.in.color.rgb());

							particles_output_for_effects.add_particle(remnants_emission.particle_render_template.layer, new_p);
						};

						for (size_t i = 0; i < rng.randval(2u, 16u); ++i) {
							spawner(general_particle());
						}
					}
				}

				b.activated = false;
				--t.num_active_branches;
			}
		}
	}

	erase_remove(thunders, [&](const thunder& t) {
		return t.num_active_branches == 0;
	});
}

void thunder_system::draw_thunders(
	augs::vertex_line_buffer& lines,
	const camera_cone camera
) const {
	for (const auto& t : thunders) {
		for (const auto& b : t.branches) {
			if (b.activated) {
				augs::draw_line(lines, camera[b.from], camera[b.to], get_resource_manager().find(assets::game_image_id::BLANK)->texture_maps[texture_map_type::DIFFUSE], t.in.color);
			}
		}
	}
}<commit_msg>Fix crash in thunder system<commit_after>#include "thunder_system.h"
#include "game/detail/camera_cone.h"
#include "augs/templates/container_templates.h"
#include "augs/graphics/drawers.h"
#include "game/resources/manager.h"
#include "game/systems_temporary/physics_system.h"
#include "game/systems_audiovisual/particles_simulation_system.h"
#include "game/enums/filters.h"
#include "game/transcendental/cosmos.h"
#include "game/detail/particle_types.h"

void thunder_system::thunder::create_root_branch() {
	static thread_local fast_randomization rng;

	thunder::branch b;
	b.lifetime_ms = 0.f;
	b.from = in.first_branch_root.pos;
	b.to = b.from + vec2().set_from_degrees(
		in.first_branch_root.rotation + rng.randval(in.branch_angle_spread)
	) * rng.randval(in.branch_length);
	b.max_lifetime_ms = rng.randval(in.max_branch_lifetime_ms);

	until_next_branching_ms = rng.randval(in.delay_between_branches_ms);
	++num_active_branches;

	branches.push_back(b);
}

void thunder_system::add(const thunder::input in) {
	ensure(in.max_all_spawned_branches > 0);

	thunder new_thunder;
	new_thunder.in = in;
	new_thunder.create_root_branch();

	thunders.push_back(new_thunder);
}

void thunder_system::advance(
	const cosmos& cosmos,
	const augs::delta dt,
	particles_simulation_system& particles_output_for_effects
) {
	static thread_local fast_randomization rng;

	for (thunder& t : thunders) {
		t.until_next_branching_ms -= dt.in_milliseconds();

		const bool should_branch_now = t.until_next_branching_ms <= 0.f;

		if (should_branch_now) {
			t.until_next_branching_ms = rng.randval(t.in.delay_between_branches_ms);

			bool found_suitable_parent = false;

			for (size_t i = 0; i < t.branches.size(); ++i) {
				const bool is_leaf = t.branches[i].children.empty();

				if (is_leaf && t.branches[i].can_have_children) {
					const auto num_children = std::min(t.in.max_all_spawned_branches, rng.randval(0u, t.in.max_branch_children));

					for (auto i = 0u; i < num_children; ++i) {
						auto& b = t.branches[i];

						thunder::branch child;
						child.activated = true;
						child.lifetime_ms = 0.f;
						child.from = b.to;
						child.to =
							child.from + vec2().set_from_degrees(rng.randval(t.in.branch_angle_spread) + (b.to - b.from).degrees()) * rng.randval(t.in.branch_length);
						child.max_lifetime_ms = rng.randval(t.in.max_branch_lifetime_ms);

						const auto raycast = cosmos.systems_temporary.get<physics_system>().ray_cast_px(
							cosmos.get_si(),
							child.from,
							child.to,
							filters::bullet()
						);

						if (raycast.hit) {
							child.can_have_children = false;
							child.to = raycast.intersection;
						}

						b.children.push_back(t.branches.size());
						t.branches.push_back(child);
						++t.num_active_branches;
						--t.in.max_all_spawned_branches;
					}

					found_suitable_parent = true;
				}
			}

			if (!found_suitable_parent) {
				t.create_root_branch();
			}
		}

		for (auto& b : t.branches) {
			b.lifetime_ms += dt.in_milliseconds();

			if (b.activated && b.lifetime_ms > b.max_lifetime_ms) {
				const bool is_leaf = b.children.empty();

				if (is_leaf) {
					const auto remnants_emission = get_resource_manager().find(assets::particle_effect_id::THUNDER_REMNANTS)->at(0);

					{
						const auto spawner = [&](auto dummy) {
							auto& new_p = particles_output_for_effects.spawn_particle<decltype(dummy)>(
								rng,
								0.f,
								{ 20.f, 100.f },
								b.to,
								0.f,
								360.f,
								remnants_emission
							);

							new_p.colorize(t.in.color.rgb());

							particles_output_for_effects.add_particle(remnants_emission.particle_render_template.layer, new_p);
						};

						for (size_t i = 0; i < rng.randval(2u, 16u); ++i) {
							spawner(general_particle());
						}
					}
				}

				b.activated = false;
				--t.num_active_branches;
			}
		}
	}

	erase_remove(thunders, [&](const thunder& t) {
		return t.num_active_branches == 0;
	});
}

void thunder_system::draw_thunders(
	augs::vertex_line_buffer& lines,
	const camera_cone camera
) const {
	for (const auto& t : thunders) {
		for (const auto& b : t.branches) {
			if (b.activated) {
				augs::draw_line(lines, camera[b.from], camera[b.to], get_resource_manager().find(assets::game_image_id::BLANK)->texture_maps[texture_map_type::DIFFUSE], t.in.color);
			}
		}
	}
}<|endoftext|>


<commit_before>#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <node_object_wrap.h>
#include <stdlib.h>
#include <strings.h>
#include <wchar.h>
#include <stdio.h>

using namespace v8;
using namespace node;

#define UNI_SUR_HIGH_START   (uint32_t) 0xD800
#define UNI_SUR_LOW_END    (uint32_t) 0xDFFF
#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD
#define UNI_MAX_LEGAL_UTF32  (uint32_t) 0x0010FFFF

static const uint8_t trailingBytesForUTF8[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};

static const uint32_t offsetsFromUTF8[6] = {
  0x00000000, 0x00003080, 0x000E2080,
  0x03C82080, 0xFA082080, 0x82082080
};

static int isLegalUTF8(const uint8_t *source, const int length)
{
  uint8_t a;
  const uint8_t *srcptr = source+length;
  switch (length) {
  default: return 0;
    /* Everything else falls through when "true"... */
/*  case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; RFC3629
makes 5 & 6 bytes UTF-8 illegal
  case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */
  case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 2: if ((a = (*--srcptr)) > 0xBF) return 0;

    switch (*source) {
      /* no fall-through in this inner switch */
      case 0xE0: if (a < 0xA0) return 0; break;
      case 0xED: if (a > 0x9F) return 0; break;
      case 0xF0: if (a < 0x90) return 0; break;
      case 0xF4: if (a > 0x8F) return 0; break;
      default:   if (a < 0x80) return 0;
    }

  case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
  }
  if (*source > 0xF4) return 0;
  return 1;
}

int is_valid_utf8 (size_t len, char *value)
{
  /* is the string valid UTF-8? */
  for (int i = 0; i < len; i++) {
    uint32_t ch = 0;
    uint8_t  extrabytes = trailingBytesForUTF8[(uint8_t) value[i]];

    if (extrabytes + i > len)
      return 0;

    if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0)
      return 0;

    switch (extrabytes) {
      case 5 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 4 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 3 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 2 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 1 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 0 : ch += (uint8_t) value[i];
    }

    ch -= offsetsFromUTF8[extrabytes];

    if (ch <= UNI_MAX_LEGAL_UTF32) {
      if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
        return 0;
    } else {
      return 0;
    }
  }

  return 1;
}

class Validation : public ObjectWrap
{
public:

  static void Initialize(v8::Handle<v8::Object> target)
  {
    HandleScope scope;
    Local<FunctionTemplate> t = FunctionTemplate::New(New);
    t->InstanceTemplate()->SetInternalFieldCount(1);
    NODE_SET_METHOD(t->GetFunction(), "isValidUTF8", Validation::IsValidUTF8);
    target->Set(String::NewSymbol("Validation"), t->GetFunction());
  }

protected:

  static Handle<Value> New(const Arguments& args)
  {
    HandleScope scope;
    Validation* validation = new Validation();
    validation->Wrap(args.This());
    return args.This();
  }

  static Handle<Value> IsValidUTF8(const Arguments& args)
  {
    HandleScope scope;
    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);
    return is_valid_utf8(buffer_length, buffer_data) == 1 ? scope.Close(True()) : scope.Close(False());
   }
};

extern "C" void init (Handle<Object> target)
{
  HandleScope scope;
  Validation::Initialize(target);
}
<commit_msg>fixed bug in utf-8 validator<commit_after>#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <node_object_wrap.h>
#include <stdlib.h>
#include <strings.h>
#include <wchar.h>
#include <stdio.h>

using namespace v8;
using namespace node;

#define UNI_SUR_HIGH_START   (uint32_t) 0xD800
#define UNI_SUR_LOW_END    (uint32_t) 0xDFFF
#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD
#define UNI_MAX_LEGAL_UTF32  (uint32_t) 0x0010FFFF

static const uint8_t trailingBytesForUTF8[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};

static const uint32_t offsetsFromUTF8[6] = {
  0x00000000, 0x00003080, 0x000E2080,
  0x03C82080, 0xFA082080, 0x82082080
};

static int isLegalUTF8(const uint8_t *source, const int length)
{
  uint8_t a;
  const uint8_t *srcptr = source+length;
  switch (length) {
  default: return 0;
  /* Everything else falls through when "true"... */
  /* RFC3629 makes 5 & 6 bytes UTF-8 illegal
  case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */
  case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
  case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
    switch (*source) {
      /* no fall-through in this inner switch */
      case 0xE0: if (a < 0xA0) return 0; break;
      case 0xED: if (a > 0x9F) return 0; break;
      case 0xF0: if (a < 0x90) return 0; break;
      case 0xF4: if (a > 0x8F) return 0; break;
      default:   if (a < 0x80) return 0;
    }

  case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
  }
  if (*source > 0xF4) return 0;
  return 1;
}

int is_valid_utf8 (size_t len, char *value)
{
  /* is the string valid UTF-8? */
  for (int i = 0; i < len; i++) {
    uint32_t ch = 0;
    uint8_t  extrabytes = trailingBytesForUTF8[(uint8_t) value[i]];

    if (extrabytes + i >= len)
      return 0;

    if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0;

    switch (extrabytes) {
      case 5 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 4 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 3 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 2 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 1 : ch += (uint8_t) value[i++]; ch <<= 6;
      case 0 : ch += (uint8_t) value[i];
    }

    ch -= offsetsFromUTF8[extrabytes];

    if (ch <= UNI_MAX_LEGAL_UTF32) {
      if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
        return 0;
    } else {
      return 0;
    }
  }

  return 1;
}

class Validation : public ObjectWrap
{
public:

  static void Initialize(v8::Handle<v8::Object> target)
  {
    HandleScope scope;
    Local<FunctionTemplate> t = FunctionTemplate::New(New);
    t->InstanceTemplate()->SetInternalFieldCount(1);
    NODE_SET_METHOD(t->GetFunction(), "isValidUTF8", Validation::IsValidUTF8);
    target->Set(String::NewSymbol("Validation"), t->GetFunction());
  }

protected:

  static Handle<Value> New(const Arguments& args)
  {
    HandleScope scope;
    Validation* validation = new Validation();
    validation->Wrap(args.This());
    return args.This();
  }

  static Handle<Value> IsValidUTF8(const Arguments& args)
  {
    HandleScope scope;
    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);
    return is_valid_utf8(buffer_length, buffer_data) == 1 ? scope.Close(True()) : scope.Close(False());
   }
};

extern "C" void init (Handle<Object> target)
{
  HandleScope scope;
  Validation::Initialize(target);
}
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <string>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "base/time/default_tick_clock.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/cast_receiver.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/in_process_receiver.h"
#include "media/cast/test/utility/input_builder.h"
#include "media/cast/test/utility/standalone_cast_environment.h"
#include "media/cast/transport/transport/udp_transport.h"
#include "net/base/net_util.h"

#if defined(OS_LINUX)
#include "media/cast/test/linux_output_window.h"
#endif  // OS_LINUX

namespace media {
namespace cast {

// Settings chosen to match default sender settings.
#define DEFAULT_SEND_PORT "0"
#define DEFAULT_RECEIVE_PORT "2344"
#define DEFAULT_SEND_IP "0.0.0.0"
#define DEFAULT_AUDIO_FEEDBACK_SSRC "1"
#define DEFAULT_AUDIO_INCOMING_SSRC "2"
#define DEFAULT_AUDIO_PAYLOAD_TYPE "127"
#define DEFAULT_VIDEO_FEEDBACK_SSRC "12"
#define DEFAULT_VIDEO_INCOMING_SSRC "11"
#define DEFAULT_VIDEO_PAYLOAD_TYPE "96"

#if defined(OS_LINUX)
const int kVideoWindowWidth = 1280;
const int kVideoWindowHeight = 720;
#endif  // OS_LINUX

void GetPorts(int* tx_port, int* rx_port) {
  test::InputBuilder tx_input(
      "Enter send port.", DEFAULT_SEND_PORT, 1, INT_MAX);
  *tx_port = tx_input.GetIntInput();

  test::InputBuilder rx_input(
      "Enter receive port.", DEFAULT_RECEIVE_PORT, 1, INT_MAX);
  *rx_port = rx_input.GetIntInput();
}

std::string GetIpAddress(const std::string display_text) {
  test::InputBuilder input(display_text, DEFAULT_SEND_IP, INT_MIN, INT_MAX);
  std::string ip_address = input.GetStringInput();
  // Ensure IP address is either the default value or in correct form.
  while (ip_address != DEFAULT_SEND_IP &&
         std::count(ip_address.begin(), ip_address.end(), '.') != 3) {
    ip_address = input.GetStringInput();
  }
  return ip_address;
}

void GetSsrcs(AudioReceiverConfig* audio_config) {
  test::InputBuilder input_tx(
      "Choose audio sender SSRC.", DEFAULT_AUDIO_FEEDBACK_SSRC, 1, INT_MAX);
  audio_config->feedback_ssrc = input_tx.GetIntInput();

  test::InputBuilder input_rx(
      "Choose audio receiver SSRC.", DEFAULT_AUDIO_INCOMING_SSRC, 1, INT_MAX);
  audio_config->incoming_ssrc = input_tx.GetIntInput();
}

void GetSsrcs(VideoReceiverConfig* video_config) {
  test::InputBuilder input_tx(
      "Choose video sender SSRC.", DEFAULT_VIDEO_FEEDBACK_SSRC, 1, INT_MAX);
  video_config->feedback_ssrc = input_tx.GetIntInput();

  test::InputBuilder input_rx(
      "Choose video receiver SSRC.", DEFAULT_VIDEO_INCOMING_SSRC, 1, INT_MAX);
  video_config->incoming_ssrc = input_rx.GetIntInput();
}

#if defined(OS_LINUX)
void GetResolution(int* height, int* width) {
  // Resolution values based on sender settings
   test::InputBuilder input_h(
      "Choose video height.", kVideoWindowHeight, 176, 1080);
  *height = input_h.GetIntInput();

  test::InputBuilder input_w(
      "Choose video width.", kVideoWindowHeight, 144, 1920);
  *width = input_w.GetIntInput();
}
#endif  // OS_LINUX

void GetPayloadtype(AudioReceiverConfig* audio_config) {
  test::InputBuilder input("Choose audio receiver payload type.",
                           DEFAULT_AUDIO_PAYLOAD_TYPE,
                           96,
                           127);
  audio_config->rtp_payload_type = input.GetIntInput();
}

AudioReceiverConfig GetAudioReceiverConfig() {
  AudioReceiverConfig audio_config = GetDefaultAudioReceiverConfig();
  GetSsrcs(&audio_config);
  GetPayloadtype(&audio_config);
  return audio_config;
}

void GetPayloadtype(VideoReceiverConfig* video_config) {
  test::InputBuilder input("Choose video receiver payload type.",
                           DEFAULT_VIDEO_PAYLOAD_TYPE,
                           96,
                           127);
  video_config->rtp_payload_type = input.GetIntInput();
}

VideoReceiverConfig GetVideoReceiverConfig() {
  VideoReceiverConfig video_config = GetDefaultVideoReceiverConfig();
  GetSsrcs(&video_config);
  GetPayloadtype(&video_config);
  return video_config;
}

// An InProcessReceiver that renders video frames to a LinuxOutputWindow.  While
// it does receive audio frames, it does not play them.
class ReceiverDisplay : public InProcessReceiver {
 public:
  ReceiverDisplay(const scoped_refptr<CastEnvironment>& cast_environment,
                  const net::IPEndPoint& local_end_point,
                  const net::IPEndPoint& remote_end_point,
                  const AudioReceiverConfig& audio_config,
                  const VideoReceiverConfig& video_config,
                  int width,
                  int height)
      : InProcessReceiver(cast_environment,
                          local_end_point,
                          remote_end_point,
                          audio_config,
                          video_config),
#if defined(OS_LINUX)
        render_(0, 0, width, height, "Cast_receiver"),
#endif  // OS_LINUX
        last_playout_time_(),
        last_render_time_() {
  }

  virtual ~ReceiverDisplay() {}

 protected:
  virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame,
                            const base::TimeTicks& render_time) OVERRIDE {
#ifdef OS_LINUX
    render_.RenderFrame(video_frame);
#endif  // OS_LINUX
    // Print out the delta between frames.
    if (!last_render_time_.is_null()) {
      base::TimeDelta time_diff = render_time - last_render_time_;
      VLOG(2) << "Size = " << video_frame->coded_size().ToString()
              << "; RenderDelay[mS] =  " << time_diff.InMilliseconds();
    }
    last_render_time_ = render_time;
  }

  virtual void OnAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame,
                            const base::TimeTicks& playout_time) OVERRIDE {
    // For audio just print the playout delta between audio frames.
    if (!last_playout_time_.is_null()) {
      base::TimeDelta time_diff = playout_time - last_playout_time_;
      VLOG(2) << "SampleRate = " << audio_frame->frequency
              << "; PlayoutDelay[mS] =  " << time_diff.InMilliseconds();
    }
    last_playout_time_ = playout_time;
  }

#ifdef OS_LINUX
  test::LinuxOutputWindow render_;
#endif  // OS_LINUX
  base::TimeTicks last_playout_time_;
  base::TimeTicks last_render_time_;
};

}  // namespace cast
}  // namespace media

int main(int argc, char** argv) {
  base::AtExitManager at_exit;
  CommandLine::Init(argc, argv);
  InitLogging(logging::LoggingSettings());

  // Enable raw event logging only.
  media::cast::CastLoggingConfig logging_config;
  logging_config.enable_raw_data_collection = true;

  scoped_refptr<media::cast::CastEnvironment> cast_environment(
      new media::cast::StandaloneCastEnvironment(logging_config));

  media::cast::AudioReceiverConfig audio_config =
      media::cast::GetAudioReceiverConfig();
  media::cast::VideoReceiverConfig video_config =
      media::cast::GetVideoReceiverConfig();

  int remote_port, local_port;
  media::cast::GetPorts(&remote_port, &local_port);
  if (!local_port) {
    LOG(ERROR) << "Invalid local port.";
    return 1;
  }

  std::string remote_ip_address = media::cast::GetIpAddress("Enter remote IP.");
  std::string local_ip_address = media::cast::GetIpAddress("Enter local IP.");
  net::IPAddressNumber remote_ip_number;
  net::IPAddressNumber local_ip_number;

  if (!net::ParseIPLiteralToNumber(remote_ip_address, &remote_ip_number)) {
    LOG(ERROR) << "Invalid remote IP address.";
    return 1;
  }

  if (!net::ParseIPLiteralToNumber(local_ip_address, &local_ip_number)) {
    LOG(ERROR) << "Invalid local IP address.";
    return 1;
  }

  net::IPEndPoint remote_end_point(remote_ip_number, remote_port);
  net::IPEndPoint local_end_point(local_ip_number, local_port);

  int width = 0;
  int height = 0;
#if defined(OS_LINUX)
  GetResolution(&height, &width);
#endif  // OS_LINUX
  media::cast::ReceiverDisplay* const receiver_display =
      new media::cast::ReceiverDisplay(cast_environment,
                                       local_end_point,
                                       remote_end_point,
                                       audio_config,
                                       video_config,
                                       width,
                                       height);
  receiver_display->Start();

  base::MessageLoop().Run();  // Run forever (i.e., until SIGTERM).
  NOTREACHED();
  return 0;
}
<commit_msg>Revert of Cast:Add resolution settings to receiver app (https://codereview.chromium.org/203223003/)<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <string>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "base/time/default_tick_clock.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/cast_receiver.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/in_process_receiver.h"
#include "media/cast/test/utility/input_builder.h"
#include "media/cast/test/utility/standalone_cast_environment.h"
#include "media/cast/transport/transport/udp_transport.h"
#include "net/base/net_util.h"

#if defined(OS_LINUX)
#include "media/cast/test/linux_output_window.h"
#endif  // OS_LINUX

namespace media {
namespace cast {

// Settings chosen to match default sender settings.
#define DEFAULT_SEND_PORT "0"
#define DEFAULT_RECEIVE_PORT "2344"
#define DEFAULT_SEND_IP "0.0.0.0"
#define DEFAULT_RESTART "0"
#define DEFAULT_AUDIO_FEEDBACK_SSRC "1"
#define DEFAULT_AUDIO_INCOMING_SSRC "2"
#define DEFAULT_AUDIO_PAYLOAD_TYPE "127"
#define DEFAULT_VIDEO_FEEDBACK_SSRC "12"
#define DEFAULT_VIDEO_INCOMING_SSRC "11"
#define DEFAULT_VIDEO_PAYLOAD_TYPE "96"
#define DEFAULT_VIDEO_CODEC_WIDTH "640"
#define DEFAULT_VIDEO_CODEC_HEIGHT "480"
#define DEFAULT_VIDEO_CODEC_BITRATE "2000"

#if defined(OS_LINUX)
const int kVideoWindowWidth = 1280;
const int kVideoWindowHeight = 720;
#endif  // OS_LINUX

void GetPorts(int* tx_port, int* rx_port) {
  test::InputBuilder tx_input(
      "Enter send port.", DEFAULT_SEND_PORT, 1, INT_MAX);
  *tx_port = tx_input.GetIntInput();

  test::InputBuilder rx_input(
      "Enter receive port.", DEFAULT_RECEIVE_PORT, 1, INT_MAX);
  *rx_port = rx_input.GetIntInput();
}

std::string GetIpAddress(const std::string display_text) {
  test::InputBuilder input(display_text, DEFAULT_SEND_IP, INT_MIN, INT_MAX);
  std::string ip_address = input.GetStringInput();
  // Ensure IP address is either the default value or in correct form.
  while (ip_address != DEFAULT_SEND_IP &&
         std::count(ip_address.begin(), ip_address.end(), '.') != 3) {
    ip_address = input.GetStringInput();
  }
  return ip_address;
}

void GetSsrcs(AudioReceiverConfig* audio_config) {
  test::InputBuilder input_tx(
      "Choose audio sender SSRC.", DEFAULT_AUDIO_FEEDBACK_SSRC, 1, INT_MAX);
  audio_config->feedback_ssrc = input_tx.GetIntInput();

  test::InputBuilder input_rx(
      "Choose audio receiver SSRC.", DEFAULT_AUDIO_INCOMING_SSRC, 1, INT_MAX);
  audio_config->incoming_ssrc = input_tx.GetIntInput();
}

void GetSsrcs(VideoReceiverConfig* video_config) {
  test::InputBuilder input_tx(
      "Choose video sender SSRC.", DEFAULT_VIDEO_FEEDBACK_SSRC, 1, INT_MAX);
  video_config->feedback_ssrc = input_tx.GetIntInput();

  test::InputBuilder input_rx(
      "Choose video receiver SSRC.", DEFAULT_VIDEO_INCOMING_SSRC, 1, INT_MAX);
  video_config->incoming_ssrc = input_rx.GetIntInput();
}

void GetPayloadtype(AudioReceiverConfig* audio_config) {
  test::InputBuilder input("Choose audio receiver payload type.",
                           DEFAULT_AUDIO_PAYLOAD_TYPE,
                           96,
                           127);
  audio_config->rtp_payload_type = input.GetIntInput();
}

AudioReceiverConfig GetAudioReceiverConfig() {
  AudioReceiverConfig audio_config = GetDefaultAudioReceiverConfig();
  GetSsrcs(&audio_config);
  GetPayloadtype(&audio_config);
  return audio_config;
}

void GetPayloadtype(VideoReceiverConfig* video_config) {
  test::InputBuilder input("Choose video receiver payload type.",
                           DEFAULT_VIDEO_PAYLOAD_TYPE,
                           96,
                           127);
  video_config->rtp_payload_type = input.GetIntInput();
}

VideoReceiverConfig GetVideoReceiverConfig() {
  VideoReceiverConfig video_config = GetDefaultVideoReceiverConfig();
  GetSsrcs(&video_config);
  GetPayloadtype(&video_config);
  return video_config;
}

// An InProcessReceiver that renders video frames to a LinuxOutputWindow.  While
// it does receive audio frames, it does not play them.
class ReceiverDisplay : public InProcessReceiver {
 public:
  ReceiverDisplay(const scoped_refptr<CastEnvironment>& cast_environment,
                  const net::IPEndPoint& local_end_point,
                  const net::IPEndPoint& remote_end_point,
                  const AudioReceiverConfig& audio_config,
                  const VideoReceiverConfig& video_config)
      : InProcessReceiver(cast_environment,
                          local_end_point,
                          remote_end_point,
                          audio_config,
                          video_config),
#if defined(OS_LINUX)
        render_(0, 0, kVideoWindowWidth, kVideoWindowHeight, "Cast_receiver"),
#endif  // OS_LINUX
        last_playout_time_(),
        last_render_time_() {
  }

  virtual ~ReceiverDisplay() {}

 protected:
  virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame,
                            const base::TimeTicks& render_time) OVERRIDE {
#ifdef OS_LINUX
    render_.RenderFrame(video_frame);
#endif  // OS_LINUX
    // Print out the delta between frames.
    if (!last_render_time_.is_null()) {
      base::TimeDelta time_diff = render_time - last_render_time_;
      VLOG(2) << "Size = " << video_frame->coded_size().ToString()
              << "; RenderDelay[mS] =  " << time_diff.InMilliseconds();
    }
    last_render_time_ = render_time;
  }

  virtual void OnAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame,
                            const base::TimeTicks& playout_time) OVERRIDE {
    // For audio just print the playout delta between audio frames.
    if (!last_playout_time_.is_null()) {
      base::TimeDelta time_diff = playout_time - last_playout_time_;
      VLOG(2) << "SampleRate = " << audio_frame->frequency
              << "; PlayoutDelay[mS] =  " << time_diff.InMilliseconds();
    }
    last_playout_time_ = playout_time;
  }

#ifdef OS_LINUX
  test::LinuxOutputWindow render_;
#endif  // OS_LINUX
  base::TimeTicks last_playout_time_;
  base::TimeTicks last_render_time_;
};

}  // namespace cast
}  // namespace media

int main(int argc, char** argv) {
  base::AtExitManager at_exit;
  CommandLine::Init(argc, argv);
  InitLogging(logging::LoggingSettings());

  // Enable raw event logging only.
  media::cast::CastLoggingConfig logging_config;
  logging_config.enable_raw_data_collection = true;

  scoped_refptr<media::cast::CastEnvironment> cast_environment(
      new media::cast::StandaloneCastEnvironment(logging_config));

  media::cast::AudioReceiverConfig audio_config =
      media::cast::GetAudioReceiverConfig();
  media::cast::VideoReceiverConfig video_config =
      media::cast::GetVideoReceiverConfig();

  int remote_port, local_port;
  media::cast::GetPorts(&remote_port, &local_port);
  if (!local_port) {
    LOG(ERROR) << "Invalid local port.";
    return 1;
  }

  std::string remote_ip_address = media::cast::GetIpAddress("Enter remote IP.");
  std::string local_ip_address = media::cast::GetIpAddress("Enter local IP.");
  net::IPAddressNumber remote_ip_number;
  net::IPAddressNumber local_ip_number;

  if (!net::ParseIPLiteralToNumber(remote_ip_address, &remote_ip_number)) {
    LOG(ERROR) << "Invalid remote IP address.";
    return 1;
  }

  if (!net::ParseIPLiteralToNumber(local_ip_address, &local_ip_number)) {
    LOG(ERROR) << "Invalid local IP address.";
    return 1;
  }

  net::IPEndPoint remote_end_point(remote_ip_number, remote_port);
  net::IPEndPoint local_end_point(local_ip_number, local_port);

  media::cast::ReceiverDisplay* const receiver_display =
      new media::cast::ReceiverDisplay(cast_environment,
                                       local_end_point,
                                       remote_end_point,
                                       audio_config,
                                       video_config);
  receiver_display->Start();

  base::MessageLoop().Run();  // Run forever (i.e., until SIGTERM).
  NOTREACHED();
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "CaptureViewElement.h"

#include "TimeGraph.h"
#include "Viewport.h"

namespace orbit_gl {

CaptureViewElement::CaptureViewElement(CaptureViewElement* parent, TimeGraph* time_graph,
                                       orbit_gl::Viewport* viewport, TimeGraphLayout* layout)
    : viewport_(viewport), layout_(layout), time_graph_(time_graph), parent_(parent) {
  CHECK(layout != nullptr);
}

void CaptureViewElement::Draw(Batcher& batcher, TextRenderer& text_renderer,
                              const DrawContext& draw_context) {
  DoDraw(batcher, text_renderer, draw_context);

  const DrawContext inner_draw_context = draw_context.IncreasedIndentationLevel();
  for (CaptureViewElement* child : GetChildren()) {
    if (child->ShouldBeRendered()) {
      child->Draw(batcher, text_renderer, inner_draw_context);
    }
  }
}

void CaptureViewElement::UpdatePrimitives(Batcher* batcher, uint64_t min_tick, uint64_t max_tick,
                                          PickingMode picking_mode, float z_offset) {
  DoUpdatePrimitives(batcher, min_tick, max_tick, picking_mode, z_offset);
  for (CaptureViewElement* child : GetChildren()) {
    if (child->ShouldBeRendered()) {
      child->UpdatePrimitives(batcher, min_tick, max_tick, picking_mode, z_offset);
    }
  }
}

void CaptureViewElement::UpdateLayout() {
  for (CaptureViewElement* child : GetChildren()) {
    child->UpdateLayout();
  }
  DoUpdateLayout();
}

void CaptureViewElement::SetWidth(float width) {
  if (width != width_) {
    width_ = width;

    for (auto& child : GetChildren()) {
      child->SetWidth(width);
    }
    RequestUpdate();
  }
}

void CaptureViewElement::SetVisible(bool value) {
  if (visible_ == value) return;

  visible_ = value;
  RequestUpdate();
}

void CaptureViewElement::OnPick(int x, int y) {
  mouse_pos_last_click_ = viewport_->ScreenToWorld(Vec2i(x, y));
  picking_offset_ = mouse_pos_last_click_ - pos_;
  mouse_pos_cur_ = mouse_pos_last_click_;
  picked_ = true;
}

void CaptureViewElement::OnRelease() {
  picked_ = false;
  RequestUpdate();
}

void CaptureViewElement::OnDrag(int x, int y) {
  mouse_pos_cur_ = viewport_->ScreenToWorld(Vec2i(x, y));
  RequestUpdate();
}

void CaptureViewElement::RequestUpdate() {
  if (parent_ != nullptr) {
    parent_->RequestUpdate();
  }
}

}  // namespace orbit_gl<commit_msg>Introduce manual instrumentation scopes to UpdatePrimitives (#2896)<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "CaptureViewElement.h"

#include "TimeGraph.h"
#include "Viewport.h"

namespace orbit_gl {

CaptureViewElement::CaptureViewElement(CaptureViewElement* parent, TimeGraph* time_graph,
                                       orbit_gl::Viewport* viewport, TimeGraphLayout* layout)
    : viewport_(viewport), layout_(layout), time_graph_(time_graph), parent_(parent) {
  CHECK(layout != nullptr);
}

void CaptureViewElement::Draw(Batcher& batcher, TextRenderer& text_renderer,
                              const DrawContext& draw_context) {
  ORBIT_SCOPE_FUNCTION;

  DoDraw(batcher, text_renderer, draw_context);

  const DrawContext inner_draw_context = draw_context.IncreasedIndentationLevel();
  for (CaptureViewElement* child : GetChildren()) {
    if (child->ShouldBeRendered()) {
      child->Draw(batcher, text_renderer, inner_draw_context);
    }
  }
}

void CaptureViewElement::UpdatePrimitives(Batcher* batcher, uint64_t min_tick, uint64_t max_tick,
                                          PickingMode picking_mode, float z_offset) {
  ORBIT_SCOPE_FUNCTION;

  DoUpdatePrimitives(batcher, min_tick, max_tick, picking_mode, z_offset);
  for (CaptureViewElement* child : GetChildren()) {
    if (child->ShouldBeRendered()) {
      child->UpdatePrimitives(batcher, min_tick, max_tick, picking_mode, z_offset);
    }
  }
}

void CaptureViewElement::UpdateLayout() {
  for (CaptureViewElement* child : GetChildren()) {
    child->UpdateLayout();
  }
  DoUpdateLayout();
}

void CaptureViewElement::SetWidth(float width) {
  if (width != width_) {
    width_ = width;

    for (auto& child : GetChildren()) {
      child->SetWidth(width);
    }
    RequestUpdate();
  }
}

void CaptureViewElement::SetVisible(bool value) {
  if (visible_ == value) return;

  visible_ = value;
  RequestUpdate();
}

void CaptureViewElement::OnPick(int x, int y) {
  mouse_pos_last_click_ = viewport_->ScreenToWorld(Vec2i(x, y));
  picking_offset_ = mouse_pos_last_click_ - pos_;
  mouse_pos_cur_ = mouse_pos_last_click_;
  picked_ = true;
}

void CaptureViewElement::OnRelease() {
  picked_ = false;
  RequestUpdate();
}

void CaptureViewElement::OnDrag(int x, int y) {
  mouse_pos_cur_ = viewport_->ScreenToWorld(Vec2i(x, y));
  RequestUpdate();
}

void CaptureViewElement::RequestUpdate() {
  if (parent_ != nullptr) {
    parent_->RequestUpdate();
  }
}

}  // namespace orbit_gl<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2010  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "User.h"
#include <algorithm>

class CPerform : public CModule {
public:
	MODCONSTRUCTOR(CPerform) {}

	virtual ~CPerform() {}

	virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
		GetNV("Perform").Split("\n", m_vPerform, false);

		return true;
	}

	virtual void OnModCommand(const CString& sCommand) {
		CString sCmdName = sCommand.Token(0).AsLower();
		if (sCmdName == "add") {
			CString sPerf = sCommand.Token(1, true);

			if (sPerf.empty()) {
				PutModule("Usage: add <command>");
				return;
			}

			if (sPerf.Left(1) == "/")
				sPerf.LeftChomp();

			if (sPerf.Token(0).Equals("MSG")) {
				sPerf = "PRIVMSG " + sPerf.Token(1, true);
			}

			if ((sPerf.Token(0).Equals("PRIVMSG") ||
				sPerf.Token(0).Equals("NOTICE")) &&
				sPerf.Token(2).Left(1) != ":") {
				sPerf = sPerf.Token(0) + " " + sPerf.Token(1)
					+ " :" + sPerf.Token(2, true);
			}
			m_vPerform.push_back(sPerf);
			PutModule("Added!");
			Save();
		} else if (sCmdName == "del") {
			u_int iNum = sCommand.Token(1, true).ToUInt();
			if (iNum > m_vPerform.size() || iNum <= 0) {
				PutModule("Illegal # Requested");
				return;
			} else {
				m_vPerform.erase(m_vPerform.begin() + iNum - 1);
				PutModule("Command Erased.");
			}
			Save();
		} else if (sCmdName == "list") {
			int i = 1;
			CString sExpanded;
			for (VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); it++, i++) {
				sExpanded = GetUser()->ExpandString(*it);
				if (sExpanded != *it)
					PutModule(CString(i) + ": " + *it + " (" + sExpanded + ")");
				else
					PutModule(CString(i) + ": " + *it);
			}
			PutModule(" -- End of List");
		} else if (sCmdName == "execute") {
			OnIRCConnected();
			PutModule("perform commands sent");
		} else if (sCmdName == "swap") {
			u_int iNumA = sCommand.Token(1).ToUInt();
			u_int iNumB = sCommand.Token(2).ToUInt();

			if (iNumA > m_vPerform.size() || iNumA <= 0 || iNumB > m_vPerform.size() || iNumB <= 0) {
				PutModule("Illegal # Requested");
			} else {
				std::iter_swap(m_vPerform.begin() + (iNumA - 1), m_vPerform.begin() + (iNumB - 1));
				PutModule("Commands Swapped.");
				Save();
			}
		} else {
			PutModule("Commands: add <command>, del <nr>, list, execute, swap <nr> <nr>");
		}
	}

	virtual void OnIRCConnected() {
		for (VCString::iterator it = m_vPerform.begin();
			it != m_vPerform.end();  ++it) {
			PutIRC(GetUser()->ExpandString(*it));
		}
	}

private:
	bool Save() {
		CString sBuffer = "";

		for (VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); ++it) {
			sBuffer += *it + "\n";
		}
		SetNV("Perform", sBuffer);

		return true;
	}

	VCString m_vPerform;
};

MODULEDEFS(CPerform, "Adds perform capabilities")
<commit_msg>Improved perform module description.<commit_after>/*
 * Copyright (C) 2004-2010  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "User.h"
#include <algorithm>

class CPerform : public CModule {
public:
	MODCONSTRUCTOR(CPerform) {}

	virtual ~CPerform() {}

	virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
		GetNV("Perform").Split("\n", m_vPerform, false);

		return true;
	}

	virtual void OnModCommand(const CString& sCommand) {
		CString sCmdName = sCommand.Token(0).AsLower();
		if (sCmdName == "add") {
			CString sPerf = sCommand.Token(1, true);

			if (sPerf.empty()) {
				PutModule("Usage: add <command>");
				return;
			}

			if (sPerf.Left(1) == "/")
				sPerf.LeftChomp();

			if (sPerf.Token(0).Equals("MSG")) {
				sPerf = "PRIVMSG " + sPerf.Token(1, true);
			}

			if ((sPerf.Token(0).Equals("PRIVMSG") ||
				sPerf.Token(0).Equals("NOTICE")) &&
				sPerf.Token(2).Left(1) != ":") {
				sPerf = sPerf.Token(0) + " " + sPerf.Token(1)
					+ " :" + sPerf.Token(2, true);
			}
			m_vPerform.push_back(sPerf);
			PutModule("Added!");
			Save();
		} else if (sCmdName == "del") {
			u_int iNum = sCommand.Token(1, true).ToUInt();
			if (iNum > m_vPerform.size() || iNum <= 0) {
				PutModule("Illegal # Requested");
				return;
			} else {
				m_vPerform.erase(m_vPerform.begin() + iNum - 1);
				PutModule("Command Erased.");
			}
			Save();
		} else if (sCmdName == "list") {
			int i = 1;
			CString sExpanded;
			for (VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); it++, i++) {
				sExpanded = GetUser()->ExpandString(*it);
				if (sExpanded != *it)
					PutModule(CString(i) + ": " + *it + " (" + sExpanded + ")");
				else
					PutModule(CString(i) + ": " + *it);
			}
			PutModule(" -- End of List");
		} else if (sCmdName == "execute") {
			OnIRCConnected();
			PutModule("perform commands sent");
		} else if (sCmdName == "swap") {
			u_int iNumA = sCommand.Token(1).ToUInt();
			u_int iNumB = sCommand.Token(2).ToUInt();

			if (iNumA > m_vPerform.size() || iNumA <= 0 || iNumB > m_vPerform.size() || iNumB <= 0) {
				PutModule("Illegal # Requested");
			} else {
				std::iter_swap(m_vPerform.begin() + (iNumA - 1), m_vPerform.begin() + (iNumB - 1));
				PutModule("Commands Swapped.");
				Save();
			}
		} else {
			PutModule("Commands: add <command>, del <nr>, list, execute, swap <nr> <nr>");
		}
	}

	virtual void OnIRCConnected() {
		for (VCString::iterator it = m_vPerform.begin();
			it != m_vPerform.end();  ++it) {
			PutIRC(GetUser()->ExpandString(*it));
		}
	}

private:
	bool Save() {
		CString sBuffer = "";

		for (VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); ++it) {
			sBuffer += *it + "\n";
		}
		SetNV("Perform", sBuffer);

		return true;
	}

	VCString m_vPerform;
};

MODULEDEFS(CPerform, "Keeps a list of commands to be executed when ZNC connects to IRC.")
<|endoftext|>


<commit_before>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiHugeImage.h"
#include "nuiAttributeAnimation.h"

#define TEXTURE_SIZE 1024

nuiHugeImage::nuiHugeImage(const nglPath& rImagePath)
{
  if (SetObjectClass(_T("nuiHugeImage")))
  {
    InitAttributes();
  }

  mClicked = false;
  mZoom = 1.0f;
  mMinZoom = 0.1f;
  mMaxZoom = 2.0f;
  mX = 0.0f;
  mY = 0.0f;

  mpZoom = new nuiAttributeAnimation();
  mpZoom->SetTargetObject(this);
  mpZoom->SetTargetAttribute(_T("Zoom"));
  mpZoom->SetCaptureStartOnPlay(true);
  mpZoom->SetEndValue(mMaxZoom);
  mpZoom->SetEasing(nuiEasingSinus);
  mpZoom->SetDuration(1.0f);
  AddAnimation(_T("Zoom"), mpZoom);

  mpPanX = new nuiAttributeAnimation();
  mpPanX->SetTargetObject(this);
  mpPanX->SetTargetAttribute(_T("CenterX"));
  mpPanX->SetCaptureStartOnPlay(true);
  mpPanX->SetEndValue(0);
  mpPanX->SetEasing(nuiEasingSinus);
  mpPanX->SetDuration(1.0f);
  AddAnimation(_T("PanX"), mpPanX);

  mpPanY = new nuiAttributeAnimation();
  mpPanY->SetTargetObject(this);
  mpPanY->SetTargetAttribute(_T("CenterY"));
  mpPanY->SetCaptureStartOnPlay(true);
  mpPanY->SetEndValue(0);
  mpPanY->SetEasing(nuiEasingSinus);
  mpPanY->SetDuration(1.0f);
  AddAnimation(_T("PanY"), mpPanY);

  InitImage();
  Load(rImagePath);
  //StartAnimation(_T("Zoom"));
}

nuiHugeImage::~nuiHugeImage()
{

}

void nuiHugeImage::InitAttributes()
{
  AddAttribute(new nuiAttribute<float>(nglString(_T("Zoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("MinZoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetMinZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetMaxZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("MaxZoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetMaxZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetMaxZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("CenterX")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetCenterX),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetCenterX)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("CenterY")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetCenterY),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetCenterY)));
}

bool nuiHugeImage::Load(const nglPath& rImagePath)
{
  ClearImage();

  // Load the big image:
  nglIStream* pStream = rImagePath.OpenRead();
  nglImage* pImage = new nglImage(pStream);
  delete pStream;
  if (!pImage)
    return false;

  int32 w = pImage->GetWidth();
  int32 h = pImage->GetHeight();

  mTextures.resize((w / TEXTURE_SIZE) + 1);

  mImageSize.Set(w, h);

  int32 i = 0;
  for (int32 x = 0; x < w; x += TEXTURE_SIZE, i++)
  {
    int32 j = 0;
    mTextures[i].resize((h / TEXTURE_SIZE) + 1);
    for (int32 y = 0; y < h; y += TEXTURE_SIZE, j++)
    {
      int32 sx = MIN(TEXTURE_SIZE, w - x);
      int32 sy = MIN(TEXTURE_SIZE, h - y);
      nglImage* pCrop = pImage->Crop(x, y, sx, sy);
      //NGL_OUT(_T("Crop[%d][%d] 0x%x\n"), i, j, pCrop);
      mTextures[i][j] = nuiTexture::GetTexture(pCrop, true);
      mTextures[i][j]->EnableAutoMipMap(true);
      mTextures[i][j]->SetMagFilter(GL_LINEAR_MIPMAP_LINEAR);
      mTextures[i][j]->SetMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    }
  }

  delete pImage;

  mZoom = 0.2f;
  mX = w / 2;
  mY = h / 2;

  InvalidateLayout();
  return true;
}

nuiRect nuiHugeImage::CalcIdealSize()
{
  return mImageSize;
}

bool nuiHugeImage::Draw(nuiDrawContext* pContext)
{
  pContext->Translate(mRect.GetWidth()/2, mRect.GetHeight()/2, 0.0f);
  pContext->Scale(mZoom, mZoom, 1.0f);
  pContext->Translate(-mX, -mY, 0.0f);
  pContext->EnableTexturing(true);
  pContext->SetFillColor(nuiColor(255, 255, 255));

  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures[i].size(); j++)
    {
      nuiTexture* pTexture = mTextures[i][j];
      if (pTexture)
      {
        int32 x = i * TEXTURE_SIZE;
        int32 y = j * TEXTURE_SIZE;
        int32 w = pTexture->GetWidth();
        int32 h = pTexture->GetHeight();
        nuiRect src(w, h);
        nuiRect dest(x, y, w, h);
        //NGL_OUT(_T("%d x %d - %ls\n"), i, j, dest.GetValue().GetChars());
        pContext->SetTexture(pTexture);
        pContext->DrawImage(dest, src);
      }
    }
  }

  return true;
}

#define WHEEL_ZOOM 1.07f

bool nuiHugeImage::MouseClicked(const nglMouseInfo& rInfo)
{
  if ((rInfo.Buttons & nglMouseInfo::ButtonLeft)
   && (rInfo.Buttons & nglMouseInfo::ButtonDoubleClick))
  {
    float zoom = 0;
    int32 x = mX;
    int32 y = mY;
    if (mZoom == mMinZoom)
    {
      zoom = mMaxZoom;
    }
    else
    {
      zoom = mMinZoom;
      x += (rInfo.X - (mRect.GetWidth() / 2)) / mZoom;
      y += (rInfo.Y - (mRect.GetHeight() / 2)) / mZoom;
    }

    StopAnimation(_T("Zoom"));
    mpZoom->SetEndValue(zoom);
    StartAnimation(_T("Zoom"));

    if (mX != x)
    {
      StopAnimation(_T("PanX"));
      mpPanX->SetEndValue(x);
      StartAnimation(_T("PanX"));
    }

    if (mY != y)
    {
      StopAnimation(_T("PanY"));
      mpPanY->SetEndValue(y);
      StartAnimation(_T("PanY"));
    }
    Invalidate();
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonLeft)
  {
    mClicked = true;
    mLastX = rInfo.X;
    mLastY = rInfo.Y;
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonWheelUp)
  {
    SetZoom(nuiClamp(mZoom * WHEEL_ZOOM, mMinZoom, mMaxZoom));
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonWheelDown)
  {
    SetZoom(nuiClamp(mZoom / WHEEL_ZOOM, mMinZoom, mMaxZoom));
  }
  return false;
}

bool nuiHugeImage::MouseUnclicked(const nglMouseInfo& rInfo)
{
  if (rInfo.Buttons & nglMouseInfo::ButtonLeft)
  {
    mClicked = false;
  }
  return false;
}

bool nuiHugeImage::MouseMoved(const nglMouseInfo& rInfo)
{
  if (mClicked)
  {
    mX += (mLastX - rInfo.X) / mZoom;
    mY += (mLastY - rInfo.Y) / mZoom;
    mLastX = rInfo.X;
    mLastY = rInfo.Y;
    Invalidate();
  }
  return false;
}

void nuiHugeImage::InitImage()
{
  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures.size(); j++)
    {
      mTextures[i][j] = NULL;
    }
  }
}

void nuiHugeImage::ClearImage()
{
  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures.size(); j++)
    {
      nuiTexture* pTexture = mTextures[i][j];
      if (pTexture);
      {
        pTexture->Release();
        mTextures[i][j] = NULL;
      }
    }
  }
}

void nuiHugeImage::ZoomTo(float zoom)
{
  mpZoom->SetEndValue(zoom);
  StopAnimation(_T("Zoom"));
  StartAnimation(_T("Zoom"));
  Invalidate();
}

void nuiHugeImage::SetZoom(float zoom)
{
  mZoom = zoom;
  Invalidate();
}

float nuiHugeImage::GetZoom() const
{
  return mZoom;
}

void nuiHugeImage::SetCenterX(float set)
{
  mX = set;
  Invalidate();
}

float nuiHugeImage::GetCenterX() const
{
  return mX;
}

void nuiHugeImage::SetCenterY(float set)
{
  mY = set;
  Invalidate();
}

float nuiHugeImage::GetCenterY() const
{
  return mX;
}

float nuiHugeImage::GetMinZoom() const
{
  return mMinZoom;
}

float nuiHugeImage::GetMaxZoom() const
{
  return mMaxZoom;
}

void nuiHugeImage::SetMinZoom(float set)
{
  mMinZoom = set;
  mZoom = nuiClamp(mZoom, mMinZoom, mMaxZoom);
  Invalidate();
}

void nuiHugeImage::SetMaxZoom(float set)
{
  mMaxZoom = set;
  mZoom = nuiClamp(mZoom, mMinZoom, mMaxZoom);
  Invalidate();
}

void nuiHugeImage::Pan(nuiPosition dir)
{
  float displacement = 10;
  switch (dir)
  {
    case nuiTopLeft:
      mX -= displacement;
      mY -= displacement;
      break;
    case nuiTop:
      mY -= displacement;
      break;
    case nuiTopRight:
      mX += displacement;
      mY -= displacement;
      break;
    case nuiRight:
      mX += displacement;
      break;
    case nuiBottomRight:
      mX += displacement;
      mY += displacement;
      break;
    case nuiBottom:
      mY += displacement;
      break;
    case nuiBottomLeft:
      mX -= displacement;
      mY += displacement;
      break;
    case nuiLeft:
      mX -= displacement;
      break;
    default:
      mX = mImageSize.GetWidth() / 2;
      mY = mImageSize.GetHeight() / 2;
      break;
  }

  Invalidate();
}

<commit_msg>more interactive stuff in huge image<commit_after>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiHugeImage.h"
#include "nuiAttributeAnimation.h"

#define TEXTURE_SIZE 1024

nuiHugeImage::nuiHugeImage(const nglPath& rImagePath)
{
  if (SetObjectClass(_T("nuiHugeImage")))
  {
    InitAttributes();
  }

  mClicked = false;
  mZoom = 1.0f;
  mMinZoom = 0.2f;
  mMaxZoom = 1.0f;
  mX = 0.0f;
  mY = 0.0f;

  mpZoom = new nuiAttributeAnimation();
  mpZoom->SetTargetObject(this);
  mpZoom->SetTargetAttribute(_T("Zoom"));
  mpZoom->SetCaptureStartOnPlay(true);
  mpZoom->SetEndValue(mMaxZoom);
  mpZoom->SetEasing(nuiEasingSinus);
  mpZoom->SetDuration(1.0f);
  AddAnimation(_T("Zoom"), mpZoom);

  mpPanX = new nuiAttributeAnimation();
  mpPanX->SetTargetObject(this);
  mpPanX->SetTargetAttribute(_T("CenterX"));
  mpPanX->SetCaptureStartOnPlay(true);
  mpPanX->SetEndValue(0);
  mpPanX->SetEasing(nuiEasingSinus);
  mpPanX->SetDuration(1.0f);
  AddAnimation(_T("PanX"), mpPanX);

  mpPanY = new nuiAttributeAnimation();
  mpPanY->SetTargetObject(this);
  mpPanY->SetTargetAttribute(_T("CenterY"));
  mpPanY->SetCaptureStartOnPlay(true);
  mpPanY->SetEndValue(0);
  mpPanY->SetEasing(nuiEasingSinus);
  mpPanY->SetDuration(1.0f);
  AddAnimation(_T("PanY"), mpPanY);

  InitImage();
  Load(rImagePath);
  //StartAnimation(_T("Zoom"));
}

nuiHugeImage::~nuiHugeImage()
{

}

void nuiHugeImage::InitAttributes()
{
  AddAttribute(new nuiAttribute<float>(nglString(_T("Zoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("MinZoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetMinZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetMaxZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("MaxZoom")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetMaxZoom),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetMaxZoom)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("CenterX")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetCenterX),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetCenterX)));

  AddAttribute(new nuiAttribute<float>(nglString(_T("CenterY")), nuiUnitCustom,
                                       nuiMakeDelegate(this, &nuiHugeImage::GetCenterY),
                                       nuiMakeDelegate(this, &nuiHugeImage::SetCenterY)));
}

bool nuiHugeImage::Load(const nglPath& rImagePath)
{
  ClearImage();

  // Load the big image:
  nglIStream* pStream = rImagePath.OpenRead();
  nglImage* pImage = new nglImage(pStream);
  delete pStream;
  if (!pImage)
    return false;

  int32 w = pImage->GetWidth();
  int32 h = pImage->GetHeight();

  mTextures.resize((w / TEXTURE_SIZE) + 1);

  mImageSize.Set(w, h);

  int32 i = 0;
  for (int32 x = 0; x < w; x += TEXTURE_SIZE, i++)
  {
    int32 j = 0;
    mTextures[i].resize((h / TEXTURE_SIZE) + 1);
    for (int32 y = 0; y < h; y += TEXTURE_SIZE, j++)
    {
      int32 sx = MIN(TEXTURE_SIZE, w - x);
      int32 sy = MIN(TEXTURE_SIZE, h - y);
      nglImage* pCrop = pImage->Crop(x, y, sx, sy);
      //NGL_OUT(_T("Crop[%d][%d] 0x%x\n"), i, j, pCrop);
      mTextures[i][j] = nuiTexture::GetTexture(pCrop, true);
      mTextures[i][j]->EnableAutoMipMap(true);
      mTextures[i][j]->SetMagFilter(GL_LINEAR_MIPMAP_LINEAR);
      mTextures[i][j]->SetMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    }
  }

  delete pImage;

  mZoom = 1.0f;
  mX = w / 2;
  mY = h / 2;

  InvalidateLayout();
  return true;
}

nuiRect nuiHugeImage::CalcIdealSize()
{
  return mImageSize;
}

bool nuiHugeImage::Draw(nuiDrawContext* pContext)
{
  pContext->Translate(mRect.GetWidth()/2, mRect.GetHeight()/2, 0.0f);
  pContext->Scale(mZoom, mZoom, 1.0f);
  pContext->Translate(-mX, -mY, 0.0f);
  pContext->EnableTexturing(true);
  pContext->SetFillColor(nuiColor(255, 255, 255));

  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures[i].size(); j++)
    {
      nuiTexture* pTexture = mTextures[i][j];
      if (pTexture)
      {
        int32 x = i * TEXTURE_SIZE;
        int32 y = j * TEXTURE_SIZE;
        int32 w = pTexture->GetWidth();
        int32 h = pTexture->GetHeight();
        nuiRect src(w, h);
        nuiRect dest(x, y, w, h);
        //NGL_OUT(_T("%d x %d - %ls\n"), i, j, dest.GetValue().GetChars());
        pContext->SetTexture(pTexture);
        pContext->DrawImage(dest, src);
      }
    }
  }

  return true;
}

#define WHEEL_ZOOM 1.07f

bool nuiHugeImage::MouseClicked(const nglMouseInfo& rInfo)
{
  if ((rInfo.Buttons & nglMouseInfo::ButtonLeft)
   && (rInfo.Buttons & nglMouseInfo::ButtonDoubleClick))
  {
    float zoom = 0;
    int32 x = mX;
    int32 y = mY;
    if (mZoom == mMinZoom)
    {
      zoom = mMaxZoom;
    }
    else
    {
      zoom = mMinZoom;
      x += (rInfo.X - (mRect.GetWidth() / 2)) / mZoom;
      y += (rInfo.Y - (mRect.GetHeight() / 2)) / mZoom;
    }

    StopAnimation(_T("Zoom"));
    mpZoom->SetEndValue(zoom);
    StartAnimation(_T("Zoom"));

    if (mX != x)
    {
      StopAnimation(_T("PanX"));
      mpPanX->SetEndValue(x);
      StartAnimation(_T("PanX"));
    }

    if (mY != y)
    {
      StopAnimation(_T("PanY"));
      mpPanY->SetEndValue(y);
      StartAnimation(_T("PanY"));
    }
    Invalidate();
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonLeft)
  {
    mClicked = true;
    mLastX = rInfo.X;
    mLastY = rInfo.Y;
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonWheelUp)
  {
    SetZoom(nuiClamp(mZoom * WHEEL_ZOOM, mMinZoom, mMaxZoom));
  }
  else if (rInfo.Buttons & nglMouseInfo::ButtonWheelDown)
  {
    SetZoom(nuiClamp(mZoom / WHEEL_ZOOM, mMinZoom, mMaxZoom));
  }
  return false;
}

bool nuiHugeImage::MouseUnclicked(const nglMouseInfo& rInfo)
{
  if (rInfo.Buttons & nglMouseInfo::ButtonLeft)
  {
    mClicked = false;
  }
  return false;
}

bool nuiHugeImage::MouseMoved(const nglMouseInfo& rInfo)
{
  if (mClicked)
  {
    mX += (mLastX - rInfo.X) / mZoom;
    mY += (mLastY - rInfo.Y) / mZoom;
    mLastX = rInfo.X;
    mLastY = rInfo.Y;
    Invalidate();
  }
  return false;
}

void nuiHugeImage::InitImage()
{
  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures[i].size(); j++)
    {
      mTextures[i][j] = NULL;
    }
  }
}

void nuiHugeImage::ClearImage()
{
  for (int32 i = 0; i < mTextures.size(); i++)
  {
    for (int32 j = 0; j < mTextures[i].size(); j++)
    {
      nuiTexture* pTexture = mTextures[i][j];
      if (pTexture)
      {
        pTexture->Release();
        mTextures[i][j] = NULL;
      }
    }
  }
}

void nuiHugeImage::ZoomTo(float zoom)
{
  mpZoom->SetEndValue(zoom);
  StopAnimation(_T("Zoom"));
  StartAnimation(_T("Zoom"));
  Invalidate();
}

void nuiHugeImage::SetZoom(float zoom)
{
  mZoom = nuiClamp(zoom, mMinZoom, mMaxZoom);
  Invalidate();
}

float nuiHugeImage::GetZoom() const
{
  return mZoom;
}

void nuiHugeImage::SetCenterX(float set)
{
  mX = set;
  Invalidate();
}

float nuiHugeImage::GetCenterX() const
{
  return mX;
}

void nuiHugeImage::SetCenterY(float set)
{
  mY = set;
  Invalidate();
}

float nuiHugeImage::GetCenterY() const
{
  return mX;
}

float nuiHugeImage::GetMinZoom() const
{
  return mMinZoom;
}

float nuiHugeImage::GetMaxZoom() const
{
  return mMaxZoom;
}

void nuiHugeImage::SetMinZoom(float set)
{
  mMinZoom = set;
  mZoom = nuiClamp(mZoom, mMinZoom, mMaxZoom);
  Invalidate();
}

void nuiHugeImage::SetMaxZoom(float set)
{
  mMaxZoom = set;
  mZoom = nuiClamp(mZoom, mMinZoom, mMaxZoom);
  Invalidate();
}

void nuiHugeImage::Pan(nuiPosition dir)
{
  float displacement = 10;
  switch (dir)
  {
    case nuiTopLeft:
      mX -= displacement;
      mY -= displacement;
      break;
    case nuiTop:
      mY -= displacement;
      break;
    case nuiTopRight:
      mX += displacement;
      mY -= displacement;
      break;
    case nuiRight:
      mX += displacement;
      break;
    case nuiBottomRight:
      mX += displacement;
      mY += displacement;
      break;
    case nuiBottom:
      mY += displacement;
      break;
    case nuiBottomLeft:
      mX -= displacement;
      mY += displacement;
      break;
    case nuiLeft:
      mX -= displacement;
      break;
    default:
      mX = mImageSize.GetWidth() / 2;
      mY = mImageSize.GetHeight() / 2;
      break;
  }

  Invalidate();
}

<|endoftext|>