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

#ifndef DUNE_GDT_SPACES_CG_PDELAB_HH
#define DUNE_GDT_SPACES_CG_PDELAB_HH

#include <memory>

#include <dune/common/fvector.hh>
#include <dune/common/deprecated.hh>

#include <dune/geometry/genericgeometry/topologytypes.hh>

#if HAVE_DUNE_ISTL
# include <dune/istl/paamg/pinfo.hh>
# include <dune/stuff/la/solver/istl_amg.hh>
#endif

#if HAVE_DUNE_PDELAB
# include <dune/pdelab/finiteelementmap/pkfem.hh>
# include <dune/pdelab/finiteelementmap/qkfem.hh>
# include <dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
# include <dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh>
# include <dune/pdelab/constraints/conforming.hh>
#endif // HAVE_DUNE_PDELAB

#include <dune/stuff/common/type_utils.hh>

#include <dune/gdt/spaces/parallel.hh>

#include "../../mapper/pdelab.hh"
#include "../../basefunctionset/pdelab.hh"

#include "interface.hh"

namespace Dune {

namespace GDT {
namespace Spaces {
namespace CG {

#if HAVE_DUNE_PDELAB

// forward, to be used in the traits and to allow for specialization
template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBased
{
  static_assert(Dune::AlwaysFalse< GridViewImp >::value, "Untested for this combination of dimensions!");
};

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBasedTraits
{
public:
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols > derived_type;
  typedef GridViewImp                   GridViewType;
  static const int                      polOrder = polynomialOrder;
  static_assert(polOrder >= 1, "Wrong polOrder given!");
private:
  typedef typename GridViewType::ctype  DomainFieldType;
  static const size_t                   dimDomain = GridViewType::dimension;
public:
  typedef RangeFieldImp                 RangeFieldType;
private:
  template< class G, bool single_geom, bool is_simplex, bool is_cube >
  struct FeMap
  {
    static_assert(Dune::AlwaysFalse< G >::value,
                  "This space is only implemented for either fully simplicial or fully cubic grids!");
  };
  template< class G >
  struct FeMap< G, true, true, false >
  {
    typedef PDELab::PkLocalFiniteElementMap < GridViewType, DomainFieldType, RangeFieldType, polOrder> Type;
  };
  template< class G >
  struct FeMap< G, true, false, true >
  {
    typedef PDELab::QkLocalFiniteElementMap < GridViewType, DomainFieldType, RangeFieldType, polOrder> Type;
  };
  typedef typename GridViewType::Grid GridType;
  static const bool single_geom_ = Dune::Capabilities::hasSingleGeometryType< GridType >::v;
  static const bool simplicial_ = (Dune::Capabilities::hasSingleGeometryType< GridType >::topologyId
                                   == GenericGeometry::SimplexTopology< dimDomain >::type::id);
  static const bool cubic_ = (Dune::Capabilities::hasSingleGeometryType< GridType >::topologyId
                              == GenericGeometry::CubeTopology< dimDomain >::type::id);
  typedef typename FeMap< GridType, single_geom_, simplicial_, cubic_ >::Type FEMapType;
public:
  template< class G, size_t dimRange >
  struct BackendMapper
  {
    typedef PDELab::VectorGridFunctionSpace< GridViewType, FEMapType, dimRange, PDELab::ISTLVectorBackend<>,
                                             PDELab::ISTLVectorBackend<>, PDELab::OverlappingConformingDirichletConstraints > Type;
    typedef Mapper::ContinuousPowerPdelabWrapper< Type > MapType;
  };
  template< class G >
  struct BackendMapper< G, 1 >
  {
    typedef PDELab::GridFunctionSpace< GridViewType, FEMapType, PDELab::OverlappingConformingDirichletConstraints > Type;
    typedef Mapper::ContinuousPdelabWrapper< Type > MapType;
  };
  typedef typename BackendMapper< GridType, rangeDim >::Type BackendType;
  typedef typename BackendMapper< GridType, rangeDim >::MapType MapperType;
  typedef typename GridViewType::template Codim< 0 >::Entity EntityType;
 /* template< class G, size_t dimRange >
  struct BasefunctionSet
  {
    typedef BaseFunctionSet::PdelabWrapper< PDELab::GridFunctionSpace< GridViewType, FEMapType, PDELab::OverlappingConformingDirichletConstraints >,
                                            EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange, rangeDimCols > Type;
  };
  template< class G >
  struct BasefunctionSet< G, 1 >
  {
    typedef BaseFunctionSet::PdelabWrapper< BackendType, EntityType, DomainFieldType, dimDomain, RangeFieldType, 1, rangeDimCols > Type;
  };
  typedef typename BasefunctionSet< GridType, rangeDim >::Type BaseFunctionSetType;*/
  typedef BaseFunctionSet::PdelabWrapper< BackendType, EntityType, DomainFieldType, dimDomain, RangeFieldType, rangeDim, rangeDimCols > BaseFunctionSetType;
  static const Stuff::Grid::ChoosePartView part_view_type = Stuff::Grid::ChoosePartView::view;
  static const bool needs_grid_view = true;

  typedef typename CommunicationChooser<GridViewType>::Type CommunicatorType;
private:
  friend class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols >;
}; // class PdelabBasedTraits

template< class GridViewImp, int polynomialOrder, class RangeFieldImp >
class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >
  : public Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                                GridViewImp::dimension, 1, 1 >
{
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                               GridViewImp::dimension, 1, 1 >                    BaseType;
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >       ThisType;
public:
  typedef PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 > Traits;

  static const int    polOrder = Traits::polOrder;
  static const size_t dimDomain = BaseType::dimDomain;
  static const size_t dimRange = BaseType::dimRange;
  static const size_t dimRangeCols = BaseType::dimRangeCols;

  typedef typename Traits::GridViewType         GridViewType;
  typedef typename Traits::RangeFieldType       RangeFieldType;
  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;

  typedef typename GridViewType::ctype              DomainFieldType;
  typedef FieldVector< DomainFieldType, dimDomain > DomainType;
  typedef CommunicationChooser< GridViewType >      CommunicationChooserType;
  typedef typename CommunicationChooserType::Type   CommunicatorType;

private:
  typedef typename Traits::FEMapType FEMapType;

public:
  typedef typename BaseType::IntersectionType  IntersectionType;
  typedef typename BaseType::EntityType        EntityType;
  typedef typename BaseType::PatternType       PatternType;
  typedef typename BaseType::BoundaryInfoType  BoundaryInfoType;

  explicit PdelabBased(GridViewType gV)
    : gridView_(gV)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {}

  /**
   * \brief Copy ctor.
   * \note  Manually implemented bc of the std::mutex + communicator_ unique_ptr
   */
  PdelabBased(const ThisType& other)
    : gridView_(other.gridView_)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {
    // make sure our new communicator is prepared if other's was
    if (other.communicator_prepared_)
      const auto& DUNE_UNUSED(comm) = this->communicator();
  }

  /**
   * \brief Move ctor.
   * \note  Manually implemented bc of the std::mutex.
   */
  PdelabBased(ThisType&& source)
    : gridView_(source.gridView_)
    , fe_map_(source.fe_map_)
    , backend_(source.backend_)
    , mapper_(source.mapper_)
    , communicator_(std::move(source.communicator_))
    , communicator_prepared_(source.communicator_prepared_)
  {}

  ThisType& operator=(const ThisType& other) = delete;

  ThisType& operator=(ThisType&& source) = delete;

  const GridViewType& grid_view() const
  {
    return gridView_;
  }

  const BackendType& backend() const
  {
    return backend_;
  }

  const MapperType& mapper() const
  {
    return mapper_;
  }

  std::vector< DomainType > lagrange_points(const EntityType& entity) const
  {
    return BaseType::lagrange_points_order_1(entity);
  }

  std::set< size_t > local_dirichlet_DoFs(const EntityType& entity,
                                          const BoundaryInfoType& boundaryInfo) const
  {
    return BaseType::local_dirichlet_DoFs_order_1(entity, boundaryInfo);
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    return BaseFunctionSetType(backend_, entity);
  }

  CommunicatorType& communicator() const
  {
    std::lock_guard< std::mutex > DUNE_UNUSED(gg)(communicator_mutex_);
    if (!communicator_prepared_)
      communicator_prepared_ = CommunicationChooserType::prepare(*this, *communicator_);
    return *communicator_;
  } // ... communicator(...)

private:
  GridViewType gridView_;
  const FEMapType fe_map_;
  const BackendType backend_;
  const MapperType mapper_;
  mutable std::unique_ptr<CommunicatorType> communicator_;
  mutable bool communicator_prepared_;
  mutable std::mutex communicator_mutex_;
}; // class PdelabBased< ..., 1 >

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim >
class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >
  : public Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >,
                                GridViewImp::dimension, rangeDim, 1 >
{
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >,
                               GridViewImp::dimension, rangeDim, 1 >              BaseType;
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                               GridViewImp::dimension, 1, 1 >                     ScalarBaseType;
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 > ThisType;
public:
  typedef PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 > Traits;

  static const int    polOrder = Traits::polOrder;
  static const size_t dimDomain = BaseType::dimDomain;
  static const size_t dimRange = BaseType::dimRange;
  static const size_t dimRangeCols = BaseType::dimRangeCols;

  typedef typename Traits::GridViewType         GridViewType;
  typedef typename Traits::RangeFieldType       RangeFieldType;
  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;

  typedef typename GridViewType::ctype              DomainFieldType;
  typedef FieldVector< DomainFieldType, dimDomain > DomainType;
  typedef CommunicationChooser< GridViewType >      CommunicationChooserType;
  typedef typename CommunicationChooserType::Type   CommunicatorType;

private:
  typedef typename Traits::FEMapType FEMapType;

public:
  typedef typename BaseType::IntersectionType  IntersectionType;
  typedef typename BaseType::EntityType        EntityType;
  typedef typename BaseType::PatternType       PatternType;
  typedef typename BaseType::BoundaryInfoType  BoundaryInfoType;

  explicit PdelabBased(GridViewType gV)
    : gridView_(gV)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {}

  /**
   * \brief Copy ctor.
   * \note  Manually implemented bc of the std::mutex + communicator_ unique_ptr
   */
  PdelabBased(const ThisType& other)
    : gridView_(other.gridView_)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {
    // make sure our new communicator is prepared if other's was
    if (other.communicator_prepared_)
      const auto& DUNE_UNUSED(comm) = this->communicator();
  }

  /**
   * \brief Move ctor.
   * \note  Manually implemented bc of the std::mutex.
   */
  PdelabBased(ThisType&& source)
    : gridView_(source.gridView_)
    , fe_map_(source.fe_map_)
    , backend_(source.backend_)
    , mapper_(source.mapper_)
    , communicator_(std::move(source.communicator_))
    , communicator_prepared_(source.communicator_prepared_)
  {}

  ThisType& operator=(const ThisType& other) = delete;

  ThisType& operator=(ThisType&& source) = delete;

  const GridViewType& grid_view() const
  {
    return gridView_;
  }

  const BackendType& backend() const
  {
    return backend_;
  }

  const MapperType& mapper() const
  {
    return mapper_;
  }

  std::vector< DomainType > lagrange_points(const EntityType& entity) const
  {
    return ScalarBaseType::lagrange_points_order_1(entity);  //should do the right thing
  }

  std::set< size_t > local_dirichlet_DoFs(const EntityType& entity,
                                          const BoundaryInfoType& boundaryInfo) const
  {
    return BaseType::local_dirichlet_DoFs_order_1(entity, boundaryInfo);  //throws a Dune_Not_Implemented atm
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    return BaseFunctionSetType(backend_, entity);
  }

  CommunicatorType& communicator() const
  {
    std::lock_guard< std::mutex > DUNE_UNUSED(gg)(communicator_mutex_);
    if (!communicator_prepared_)
      communicator_prepared_ = CommunicationChooserType::prepare(*this, *communicator_);
    return *communicator_;
  } // ... communicator(...)

private:
  GridViewType gridView_;
  const FEMapType fe_map_;
  const BackendType backend_;
  const MapperType mapper_;
  mutable std::unique_ptr<CommunicatorType> communicator_;
  mutable bool communicator_prepared_;
  mutable std::mutex communicator_mutex_;
}; // class PdelabBased< ..., dimRange, 1 >

#else // HAVE_DUNE_PDELAB

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBased
{
  static_assert(Dune::AlwaysFalse< GridViewImp >::value, "You are missing dune-pdelab!");
};

#endif // HAVE_DUNE_PDELAB

} // namespace CG
} // namespace Spaces
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_CG_PDELAB_HH
<commit_msg>[spaces/cg/pdelab] clean up and whitespaces<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACES_CG_PDELAB_HH
#define DUNE_GDT_SPACES_CG_PDELAB_HH

#include <memory>

#include <dune/common/fvector.hh>
#include <dune/common/deprecated.hh>

#include <dune/geometry/genericgeometry/topologytypes.hh>

#if HAVE_DUNE_ISTL
# include <dune/istl/paamg/pinfo.hh>
# include <dune/stuff/la/solver/istl_amg.hh>
#endif

#if HAVE_DUNE_PDELAB
# include <dune/pdelab/finiteelementmap/pkfem.hh>
# include <dune/pdelab/finiteelementmap/qkfem.hh>
# include <dune/pdelab/gridfunctionspace/gridfunctionspace.hh>
# include <dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh>
# include <dune/pdelab/constraints/conforming.hh>
#endif // HAVE_DUNE_PDELAB

#include <dune/stuff/common/type_utils.hh>

#include <dune/gdt/spaces/parallel.hh>

#include "../../mapper/pdelab.hh"
#include "../../basefunctionset/pdelab.hh"

#include "interface.hh"

namespace Dune {

namespace GDT {
namespace Spaces {
namespace CG {

#if HAVE_DUNE_PDELAB

// forward, to be used in the traits and to allow for specialization
template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBased
{
  static_assert(Dune::AlwaysFalse< GridViewImp >::value, "Untested for this combination of dimensions!");
};

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBasedTraits
{
public:
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols > derived_type;
  typedef GridViewImp                   GridViewType;
  static const int                      polOrder = polynomialOrder;
  static_assert(polOrder >= 1, "Wrong polOrder given!");
private:
  typedef typename GridViewType::ctype  DomainFieldType;
  static const size_t                   dimDomain = GridViewType::dimension;
public:
  typedef RangeFieldImp                 RangeFieldType;
private:
  template< class G, bool single_geom, bool is_simplex, bool is_cube >
  struct FeMap
  {
    static_assert(Dune::AlwaysFalse< G >::value,
                  "This space is only implemented for either fully simplicial or fully cubic grids!");
  };
  template< class G >
  struct FeMap< G, true, true, false >
  {
    typedef PDELab::PkLocalFiniteElementMap < GridViewType, DomainFieldType, RangeFieldType, polOrder> Type;
  };
  template< class G >
  struct FeMap< G, true, false, true >
  {
    typedef PDELab::QkLocalFiniteElementMap < GridViewType, DomainFieldType, RangeFieldType, polOrder> Type;
  };
  typedef typename GridViewType::Grid GridType;
  static const bool single_geom_ = Dune::Capabilities::hasSingleGeometryType< GridType >::v;
  static const bool simplicial_ = (Dune::Capabilities::hasSingleGeometryType< GridType >::topologyId
                                   == GenericGeometry::SimplexTopology< dimDomain >::type::id);
  static const bool cubic_ = (Dune::Capabilities::hasSingleGeometryType< GridType >::topologyId
                              == GenericGeometry::CubeTopology< dimDomain >::type::id);
  typedef typename FeMap< GridType, single_geom_, simplicial_, cubic_ >::Type FEMapType;
public:
  template< class G, size_t dimRange >
  struct BackendMapper
  {
    typedef PDELab::VectorGridFunctionSpace< GridViewType, FEMapType, dimRange, PDELab::ISTLVectorBackend<>,
                                             PDELab::ISTLVectorBackend<>, PDELab::OverlappingConformingDirichletConstraints > Type;
    typedef Mapper::ContinuousPowerPdelabWrapper< Type > MapType;
  };
  template< class G >
  struct BackendMapper< G, 1 >
  {
    typedef PDELab::GridFunctionSpace< GridViewType, FEMapType, PDELab::OverlappingConformingDirichletConstraints > Type;
    typedef Mapper::ContinuousPdelabWrapper< Type > MapType;
  };
  typedef typename BackendMapper< GridType, rangeDim >::Type    BackendType;
  typedef typename BackendMapper< GridType, rangeDim >::MapType MapperType;
  typedef typename GridViewType::template Codim< 0 >::Entity    EntityType;
  typedef BaseFunctionSet::PdelabWrapper< BackendType, EntityType, DomainFieldType, dimDomain, RangeFieldType, rangeDim, rangeDimCols > BaseFunctionSetType;
  static const Stuff::Grid::ChoosePartView part_view_type = Stuff::Grid::ChoosePartView::view;
  static const bool needs_grid_view = true;

  typedef typename CommunicationChooser<GridViewType>::Type CommunicatorType;
private:
  friend class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols >;
}; // class PdelabBasedTraits

template< class GridViewImp, int polynomialOrder, class RangeFieldImp >
class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >
  : public Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                                GridViewImp::dimension, 1, 1 >
{
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                               GridViewImp::dimension, 1, 1 >                    BaseType;
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >       ThisType;
public:
  typedef PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 > Traits;

  static const int    polOrder = Traits::polOrder;
  static const size_t dimDomain = BaseType::dimDomain;
  static const size_t dimRange = BaseType::dimRange;
  static const size_t dimRangeCols = BaseType::dimRangeCols;

  typedef typename Traits::GridViewType         GridViewType;
  typedef typename Traits::RangeFieldType       RangeFieldType;
  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;

  typedef typename GridViewType::ctype              DomainFieldType;
  typedef FieldVector< DomainFieldType, dimDomain > DomainType;
  typedef CommunicationChooser< GridViewType >      CommunicationChooserType;
  typedef typename CommunicationChooserType::Type   CommunicatorType;

private:
  typedef typename Traits::FEMapType FEMapType;

public:
  typedef typename BaseType::IntersectionType  IntersectionType;
  typedef typename BaseType::EntityType        EntityType;
  typedef typename BaseType::PatternType       PatternType;
  typedef typename BaseType::BoundaryInfoType  BoundaryInfoType;

  explicit PdelabBased(GridViewType gV)
    : gridView_(gV)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {}

  /**
   * \brief Copy ctor.
   * \note  Manually implemented bc of the std::mutex + communicator_ unique_ptr
   */
  PdelabBased(const ThisType& other)
    : gridView_(other.gridView_)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {
    // make sure our new communicator is prepared if other's was
    if (other.communicator_prepared_)
      const auto& DUNE_UNUSED(comm) = this->communicator();
  }

  /**
   * \brief Move ctor.
   * \note  Manually implemented bc of the std::mutex.
   */
  PdelabBased(ThisType&& source)
    : gridView_(source.gridView_)
    , fe_map_(source.fe_map_)
    , backend_(source.backend_)
    , mapper_(source.mapper_)
    , communicator_(std::move(source.communicator_))
    , communicator_prepared_(source.communicator_prepared_)
  {}

  ThisType& operator=(const ThisType& other) = delete;

  ThisType& operator=(ThisType&& source) = delete;

  const GridViewType& grid_view() const
  {
    return gridView_;
  }

  const BackendType& backend() const
  {
    return backend_;
  }

  const MapperType& mapper() const
  {
    return mapper_;
  }

  std::vector< DomainType > lagrange_points(const EntityType& entity) const
  {
    return BaseType::lagrange_points_order_1(entity);
  }

  std::set< size_t > local_dirichlet_DoFs(const EntityType& entity,
                                          const BoundaryInfoType& boundaryInfo) const
  {
    return BaseType::local_dirichlet_DoFs_order_1(entity, boundaryInfo);
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    return BaseFunctionSetType(backend_, entity);
  }

  CommunicatorType& communicator() const
  {
    std::lock_guard< std::mutex > DUNE_UNUSED(gg)(communicator_mutex_);
    if (!communicator_prepared_)
      communicator_prepared_ = CommunicationChooserType::prepare(*this, *communicator_);
    return *communicator_;
  } // ... communicator(...)

private:
  GridViewType gridView_;
  const FEMapType fe_map_;
  const BackendType backend_;
  const MapperType mapper_;
  mutable std::unique_ptr<CommunicatorType> communicator_;
  mutable bool communicator_prepared_;
  mutable std::mutex communicator_mutex_;
}; // class PdelabBased< ..., 1 >

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim >
class PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >
  : public Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >,
                                GridViewImp::dimension, rangeDim, 1 >
{
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 >,
                               GridViewImp::dimension, rangeDim, 1 >              BaseType;
  typedef Spaces::CGInterface< PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, 1, 1 >,
                               GridViewImp::dimension, 1, 1 >                     ScalarBaseType;
  typedef PdelabBased< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 > ThisType;
public:
  typedef PdelabBasedTraits< GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1 > Traits;

  static const int    polOrder = Traits::polOrder;
  static const size_t dimDomain = BaseType::dimDomain;
  static const size_t dimRange = BaseType::dimRange;
  static const size_t dimRangeCols = BaseType::dimRangeCols;

  typedef typename Traits::GridViewType         GridViewType;
  typedef typename Traits::RangeFieldType       RangeFieldType;
  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;

  typedef typename GridViewType::ctype              DomainFieldType;
  typedef FieldVector< DomainFieldType, dimDomain > DomainType;
  typedef CommunicationChooser< GridViewType >      CommunicationChooserType;
  typedef typename CommunicationChooserType::Type   CommunicatorType;

private:
  typedef typename Traits::FEMapType FEMapType;

public:
  typedef typename BaseType::IntersectionType  IntersectionType;
  typedef typename BaseType::EntityType        EntityType;
  typedef typename BaseType::PatternType       PatternType;
  typedef typename BaseType::BoundaryInfoType  BoundaryInfoType;

  explicit PdelabBased(GridViewType gV)
    : gridView_(gV)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {}

  /**
   * \brief Copy ctor.
   * \note  Manually implemented bc of the std::mutex + communicator_ unique_ptr
   */
  PdelabBased(const ThisType& other)
    : gridView_(other.gridView_)
    , fe_map_(gridView_)
    , backend_(gridView_, fe_map_)
    , mapper_(backend_)
    , communicator_(CommunicationChooser< GridViewImp >::create(gridView_))
    , communicator_prepared_(false)
  {
    // make sure our new communicator is prepared if other's was
    if (other.communicator_prepared_)
      const auto& DUNE_UNUSED(comm) = this->communicator();
  }

  /**
   * \brief Move ctor.
   * \note  Manually implemented bc of the std::mutex.
   */
  PdelabBased(ThisType&& source)
    : gridView_(source.gridView_)
    , fe_map_(source.fe_map_)
    , backend_(source.backend_)
    , mapper_(source.mapper_)
    , communicator_(std::move(source.communicator_))
    , communicator_prepared_(source.communicator_prepared_)
  {}

  ThisType& operator=(const ThisType& other) = delete;

  ThisType& operator=(ThisType&& source) = delete;

  const GridViewType& grid_view() const
  {
    return gridView_;
  }

  const BackendType& backend() const
  {
    return backend_;
  }

  const MapperType& mapper() const
  {
    return mapper_;
  }

  std::vector< DomainType > lagrange_points(const EntityType& entity) const
  {
    return ScalarBaseType::lagrange_points_order_1(entity);  //should do the right thing
  }

  std::set< size_t > local_dirichlet_DoFs(const EntityType& entity,
                                          const BoundaryInfoType& boundaryInfo) const
  {
    return BaseType::local_dirichlet_DoFs_order_1(entity, boundaryInfo);  //throws a Dune_Not_Implemented atm
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    return BaseFunctionSetType(backend_, entity);
  }

  CommunicatorType& communicator() const
  {
    std::lock_guard< std::mutex > DUNE_UNUSED(gg)(communicator_mutex_);
    if (!communicator_prepared_)
      communicator_prepared_ = CommunicationChooserType::prepare(*this, *communicator_);
    return *communicator_;
  } // ... communicator(...)

private:
  GridViewType gridView_;
  const FEMapType fe_map_;
  const BackendType backend_;
  const MapperType mapper_;
  mutable std::unique_ptr<CommunicatorType> communicator_;
  mutable bool communicator_prepared_;
  mutable std::mutex communicator_mutex_;
}; // class PdelabBased< ..., dimRange, 1 >

#else // HAVE_DUNE_PDELAB

template< class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class PdelabBased
{
  static_assert(Dune::AlwaysFalse< GridViewImp >::value, "You are missing dune-pdelab!");
};

#endif // HAVE_DUNE_PDELAB

} // namespace CG
} // namespace Spaces
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_CG_PDELAB_HH
<|endoftext|>


<commit_before>/** @file mixed_logit.test.cc
 *
 *  A "stress" test driver for mixed logit.
 *
 *  @author Dongryeol Lee (dongryel@cc.gatech.edu)
 */

// for BOOST testing
#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>
#include <time.h>
#include "mlpack/mixed_logit_dcm/mixed_logit_dcm_dev.h"

namespace mlpack {
namespace mixed_logit_dcm {

int num_attributes_;
int num_people_;
std::vector<int> num_discrete_choices_;

class TestMixedLogitDCM {

  private:

    template<typename TableType>
    void GenerateRandomDataset_(
      TableType *random_attribute_dataset,
      TableType *random_discrete_choice_set_info_dataset) {

      // Find the total number of discrete choices.
      int total_num_attributes =
        std::accumulate(
          num_discrete_choices.begin(), num_discrete_choices.end(), 0);

      random_attribute_dataset->Init(
        mlpack::mixed_logit_dcm::num_attributes_, total_num_attributes);

      for(int j = 0; j < total_num_attributes; j++) {
        core::table::DensePoint point;
        random_attribute_dataset->get(j, &point);
        for(int i = 0; i < mlpack::mixed_logit_dcm::num_attributes_; i++) {
          point[i] = core::math::Random(0.1, 1.0);
        }
      }

      random_discrete_choice_set_info_dataset->Init(
        2, mlpack::mixed_logit_dcm::num_people_);
      for(int j = 0; j < mlpack::mixed_logit_dcm::num_people_; j++) {
        core::table::DensePoint point;
        random_discrete_choice_set_info_dataset->get(j, &point);
        point[0] = core::math::RandInt(
                     mlpack::mixed_logit_dcm::num_discrete_choices_[j]);
        point[1] = mlpack::mixed_logit_dcm::num_discrete_choices_[j];
      }
    }

  public:

    int StressTestMain() {
      for(int i = 0; i < 20; i++) {
        for(int k = 0; k < 2; k++) {

          // Randomly choose the number of attributes and the number
          // of people and the number of discrete choices per each
          // person.
          mlpack::mixed_logit_dcm::num_attributes_ = core::math::RandInt(5, 20);
          mlpack::mixed_logit_dcm::num_people_ = core::math::RandInt(50, 101);
          mlpack::mixed_logit_dcm::num_discrete_choices_.resize(
            mlpack::mixed_logit_dcm::num_people_);

          switch(k) {
            case 0:

              // Test the constant distribution.
              StressTest();
              break;
            case 1:

              // Test the Gaussian distribution.
              StressTest();
              break;
          }
        }
      }
      return 0;
    }

    int StressTest() {

      typedef core::table::Table <
      core::tree::GenMetricTree <
      core::tree::AbstractStatistic > > TableType;

      // The list of arguments.
      std::vector< std::string > args;

      // Push in the reference dataset name.
      std::string attributes_in("random_attributes.csv");
      args.push_back(std::string("--attributes_in=") + attributes_in);

      // Push in the discrete choice set info name.
      std::string discrete_choice_set_info_in(
        "random_discrete_choice_set_info.csv");
      args.push_back(
        std::string("--discrete_choice_set_info_in=") +
        discrete_choice_set_info_in);

      // Print out the header of the trial.
      std::cout << "\n==================\n";
      std::cout << "Test trial begin\n";
      std::cout << "Number of attributes: " <<
                mlpack::mixed_logit_dcm::num_attributes_ << "\n";
      std::cout << "Number of people: " <<
                mlpack::mixed_logit_dcm::num_people_ << "\n";

      // Generate the random dataset and save it.
      TableType random_attribute_table;
      TableType random_discrete_choice_set_info_table;
      GenerateRandomDataset_(
        &random_attribute_table, &random_discrete_choice_set_info_table);
      random_attribute_table.Save(attributes_in);
      random_discrete_choice_set_info_table.Save(discrete_choice_set_info_in);

      return 0;
    };
};
}
}

BOOST_AUTO_TEST_SUITE(TestSuiteKde)
BOOST_AUTO_TEST_CASE(TestCaseKde) {

  // Call the tests.
  mlpack::kde::TestKde kde_test;
  kde_test.StressTestMain();

  std::cout << "All tests passed!\n";
}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Test compiles, now have to run it.<commit_after>/** @file mixed_logit.test.cc
 *
 *  A "stress" test driver for mixed logit.
 *
 *  @author Dongryeol Lee (dongryel@cc.gatech.edu)
 */

// for BOOST testing
#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>
#include <numeric>
#include <time.h>
#include "core/table/table.h"
#include "core/tree/gen_metric_tree.h"
#include "mlpack/mixed_logit_dcm/mixed_logit_dcm_dev.h"

namespace mlpack {
namespace mixed_logit_dcm {

int num_attributes_;
int num_people_;
std::vector<int> num_discrete_choices_;

class TestMixedLogitDCM {

  private:

    template<typename TableType>
    void GenerateRandomDataset_(
      TableType *random_attribute_dataset,
      TableType *random_discrete_choice_set_info_dataset) {

      // Find the total number of discrete choices.
      int total_num_attributes =
        std::accumulate(
          mlpack::mixed_logit_dcm::num_discrete_choices_.begin(),
          mlpack::mixed_logit_dcm::num_discrete_choices_.end(), 0);

      random_attribute_dataset->Init(
        mlpack::mixed_logit_dcm::num_attributes_, total_num_attributes);

      for(int j = 0; j < total_num_attributes; j++) {
        core::table::DensePoint point;
        random_attribute_dataset->get(j, &point);
        for(int i = 0; i < mlpack::mixed_logit_dcm::num_attributes_; i++) {
          point[i] = core::math::Random(0.1, 1.0);
        }
      }

      random_discrete_choice_set_info_dataset->Init(
        2, mlpack::mixed_logit_dcm::num_people_);
      for(int j = 0; j < mlpack::mixed_logit_dcm::num_people_; j++) {
        core::table::DensePoint point;
        random_discrete_choice_set_info_dataset->get(j, &point);
        point[0] = core::math::RandInt(
                     mlpack::mixed_logit_dcm::num_discrete_choices_[j]);
        point[1] = mlpack::mixed_logit_dcm::num_discrete_choices_[j];
      }
    }

  public:

    int StressTestMain() {
      for(int i = 0; i < 20; i++) {
        for(int k = 0; k < 2; k++) {

          // Randomly choose the number of attributes and the number
          // of people and the number of discrete choices per each
          // person.
          mlpack::mixed_logit_dcm::num_attributes_ = core::math::RandInt(5, 20);
          mlpack::mixed_logit_dcm::num_people_ = core::math::RandInt(50, 101);
          mlpack::mixed_logit_dcm::num_discrete_choices_.resize(
            mlpack::mixed_logit_dcm::num_people_);

          switch(k) {
            case 0:

              // Test the constant distribution.
              StressTest();
              break;
            case 1:

              // Test the Gaussian distribution.
              StressTest();
              break;
          }
        }
      }
      return 0;
    }

    int StressTest() {

      typedef core::table::Table <
      core::tree::GenMetricTree <
      core::tree::AbstractStatistic > > TableType;

      // The list of arguments.
      std::vector< std::string > args;

      // Push in the reference dataset name.
      std::string attributes_in("random_attributes.csv");
      args.push_back(std::string("--attributes_in=") + attributes_in);

      // Push in the discrete choice set info name.
      std::string discrete_choice_set_info_in(
        "random_discrete_choice_set_info.csv");
      args.push_back(
        std::string("--discrete_choice_set_info_in=") +
        discrete_choice_set_info_in);

      // Print out the header of the trial.
      std::cout << "\n==================\n";
      std::cout << "Test trial begin\n";
      std::cout << "Number of attributes: " <<
                mlpack::mixed_logit_dcm::num_attributes_ << "\n";
      std::cout << "Number of people: " <<
                mlpack::mixed_logit_dcm::num_people_ << "\n";

      // Generate the random dataset and save it.
      TableType random_attribute_table;
      TableType random_discrete_choice_set_info_table;
      GenerateRandomDataset_(
        &random_attribute_table, &random_discrete_choice_set_info_table);
      random_attribute_table.Save(attributes_in);
      random_discrete_choice_set_info_table.Save(discrete_choice_set_info_in);

      return 0;
    };
};
}
}

BOOST_AUTO_TEST_SUITE(TestSuiteMixedLogitDCM)
BOOST_AUTO_TEST_CASE(TestCaseMixedLogitDCM) {

  // Call the tests.
  mlpack::mixed_logit_dcm::TestMixedLogitDCM dcm_test;
  dcm_test.StressTestMain();

  std::cout << "All tests passed!\n";
}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "utility.h"

#include <ee/EE_DTex.h>
#include <ee/EE_GTxt.h>
#include <gum/ShaderLab.h>
#include <gum/RenderContext.h>

#include <shaderlab/ShaderMgr.h>
#include <shaderlab/Shape2Shader.h>
#include <shaderlab/Shape3Shader.h>
#include <shaderlab/Sprite2Shader.h>
#include <shaderlab/Sprite3Shader.h>
#include <shaderlab/BlendShader.h>
#include <shaderlab/FilterShader.h>
#include <shaderlab/MaskShader.h>
#include <shaderlab/Model3Shader.h>

#include <gl/glew.h>
#include <glfw.h>

namespace edb
{

int init_gl()
{
	glfwInit();
	if(!glfwOpenWindow(100, 100, 8, 8, 8, 8, 24, 8, GLFW_WINDOW))
	{
		glfwTerminate();
		return -2;
	}

//	gum::ShaderLab::Instance()->Init();
	{
		sl::ShaderMgr* mgr = sl::ShaderMgr::Instance();
		ur::RenderContext* rc = gum::RenderContext::Instance()->GetImpl();
		mgr->SetContext(rc);

		mgr->CreateShader(sl::SHAPE2, new sl::Shape2Shader(rc));
		mgr->CreateShader(sl::SHAPE3, new sl::Shape3Shader(rc));
		mgr->CreateShader(sl::SPRITE2, new sl::Sprite2Shader(rc));
		mgr->CreateShader(sl::SPRITE3, new sl::Sprite3Shader(rc));
		mgr->CreateShader(sl::BLEND, new sl::BlendShader(rc));
		mgr->CreateShader(sl::FILTER, new sl::FilterShader(rc));
		mgr->CreateShader(sl::MASK, new sl::MaskShader(rc));
		mgr->CreateShader(sl::MODEL3, new sl::Model3Shader(rc));
	}

	ee::DTex::Init();
	ee::GTxt::Init();

// 	sl::SubjectMVP2::Instance()->NotifyModelview(0, 0, 1, 1);
// 	sl::SubjectMVP2::Instance()->NotifyProjection(100, 100);

	return 0;
}

}<commit_msg>[CHANGED] update glfw2 to glfw3<commit_after>#include "utility.h"

#include <ee/EE_DTex.h>
#include <ee/EE_GTxt.h>
#include <gum/ShaderLab.h>
#include <gum/RenderContext.h>

#include <shaderlab/ShaderMgr.h>
#include <shaderlab/Shape2Shader.h>
#include <shaderlab/Shape3Shader.h>
#include <shaderlab/Sprite2Shader.h>
#include <shaderlab/Sprite3Shader.h>
#include <shaderlab/BlendShader.h>
#include <shaderlab/FilterShader.h>
#include <shaderlab/MaskShader.h>
#include <shaderlab/Model3Shader.h>

#include <gl/glew.h>
#include <glfw3.h>

#include <iostream>

namespace edb
{

static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}

static int prepare_gl_context()
{
	glfwSetErrorCallback(error_callback);
	if (!glfwInit()) {
		exit(EXIT_FAILURE);
	}

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(100, 100, "easydb", nullptr, nullptr);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	//// Initialize GLEW to setup the OpenGL Function pointers
	//if (glewInit() != GLEW_OK) {
	//	return -1;
	//}
}

int init_gl()
{
	int ret = prepare_gl_context();
	if (ret < 0) {
		return ret;
	}

//	gum::ShaderLab::Instance()->Init();
	{
		sl::ShaderMgr* mgr = sl::ShaderMgr::Instance();
		ur::RenderContext* rc = gum::RenderContext::Instance()->GetImpl();
		mgr->SetContext(rc);

		mgr->CreateShader(sl::SHAPE2, new sl::Shape2Shader(rc));
		mgr->CreateShader(sl::SHAPE3, new sl::Shape3Shader(rc));
		mgr->CreateShader(sl::SPRITE2, new sl::Sprite2Shader(rc));
		mgr->CreateShader(sl::SPRITE3, new sl::Sprite3Shader(rc));
		mgr->CreateShader(sl::BLEND, new sl::BlendShader(rc));
		mgr->CreateShader(sl::FILTER, new sl::FilterShader(rc));
		mgr->CreateShader(sl::MASK, new sl::MaskShader(rc));
		mgr->CreateShader(sl::MODEL3, new sl::Model3Shader(rc));
	}

	ee::DTex::Init();
	ee::GTxt::Init();

// 	sl::SubjectMVP2::Instance()->NotifyModelview(0, 0, 1, 1);
// 	sl::SubjectMVP2::Instance()->NotifyProjection(100, 100);

	return 0;
}

}<|endoftext|>


<commit_before>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Quaternion.h"
#include "Vector3.h"
#include "LuaStack.h"
#include "LuaEnvironment.h"

namespace crown
{

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion(lua_State* L)
{
	LuaStack stack(L);

	Vector3& v = stack.get_vector3(1);
	float w = stack.get_float(2);

	stack.push_quaternion(Quaternion(v, w));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_negate(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	q.negate();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_load_identity(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	q.load_identity();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_length(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_float(q.length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_conjugate(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_quaternion(q.get_conjugate());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_inverse(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_quaternion(q.get_inverse());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_cross(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q1 = stack.get_quaternion(1);
	Quaternion& q2 = stack.get_quaternion(2);

	stack.push_quaternion(q1 * q2);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_multiply(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);
	float k = stack.get_float(2);

	stack.push_quaternion(q * k);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_power(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);
	float k = stack.get_float(2);

	stack.push_quaternion(q.power(k));

	return 1;
}

//-----------------------------------------------------------------------------
void load_quaternion(LuaEnvironment& env)
{
	env.load_module_function("Quaternion", "new",			quaternion);
	env.load_module_function("Quaternion", "negate",		quaternion_negate);
	env.load_module_function("Quaternion", "load_identity",	quaternion_load_identity);
	env.load_module_function("Quaternion", "length",		quaternion_length);
	env.load_module_function("Quaternion", "conjugate",		quaternion_conjugate);
	env.load_module_function("Quaternion", "inverse",		quaternion_inverse);
	env.load_module_function("Quaternion", "cross",			quaternion_cross);
	env.load_module_function("Quaternion", "mul",			quaternion_multiply);
	env.load_module_function("Quaternion", "pow",			quaternion_power);
}

} //namespace crown<commit_msg>Rename mul to multiply according to code guidelines<commit_after>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Quaternion.h"
#include "Vector3.h"
#include "LuaStack.h"
#include "LuaEnvironment.h"

namespace crown
{

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion(lua_State* L)
{
	LuaStack stack(L);

	Vector3& v = stack.get_vector3(1);
	float w = stack.get_float(2);

	stack.push_quaternion(Quaternion(v, w));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_negate(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	q.negate();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_load_identity(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	q.load_identity();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_length(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_float(q.length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_conjugate(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_quaternion(q.get_conjugate());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_inverse(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);

	stack.push_quaternion(q.get_inverse());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_cross(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q1 = stack.get_quaternion(1);
	Quaternion& q2 = stack.get_quaternion(2);

	stack.push_quaternion(q1 * q2);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_multiply(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);
	float k = stack.get_float(2);

	stack.push_quaternion(q * k);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int quaternion_power(lua_State* L)
{
	LuaStack stack(L);

	Quaternion& q = stack.get_quaternion(1);
	float k = stack.get_float(2);

	stack.push_quaternion(q.power(k));

	return 1;
}

//-----------------------------------------------------------------------------
void load_quaternion(LuaEnvironment& env)
{
	env.load_module_function("Quaternion", "new",			quaternion);
	env.load_module_function("Quaternion", "negate",		quaternion_negate);
	env.load_module_function("Quaternion", "load_identity",	quaternion_load_identity);
	env.load_module_function("Quaternion", "length",		quaternion_length);
	env.load_module_function("Quaternion", "conjugate",		quaternion_conjugate);
	env.load_module_function("Quaternion", "inverse",		quaternion_inverse);
	env.load_module_function("Quaternion", "cross",			quaternion_cross);
	env.load_module_function("Quaternion", "multiply",		quaternion_multiply);
	env.load_module_function("Quaternion", "pow",			quaternion_power);
}

} //namespace crown<|endoftext|>


<commit_before>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include "diff_solver.h"
#include "diff_system.h"
#include "dof_map.h"
#include "numeric_vector.h"
#include "parameter_vector.h"
#include "qoi_set.h"
#include "sensitivity_data.h"
#include "time_solver.h"

DifferentiableSystem::DifferentiableSystem
                      (EquationSystems& es,
                       const std::string& name,
                       const unsigned int number) :
  Parent      (es, name, number),
  compute_internal_sides(false),
  postprocess_sides(false),
  time_solver (NULL),
  time(0.),
  deltat(1.),
  print_solution_norms(false),
  print_solutions(false),
  print_residual_norms(false),
  print_residuals(false),
  print_jacobian_norms(false),
  print_jacobians(false),
  print_element_jacobians(false),
  use_fixed_solution(false)
{
}

DifferentiableSystem::~DifferentiableSystem ()
{
  this->clear();
}

void DifferentiableSystem::clear ()
{
  _time_evolving.resize(0);

  use_fixed_solution = false;
}

void DifferentiableSystem::reinit ()
{
  Parent::reinit();

  time_solver->reinit();
}

void DifferentiableSystem::init_data ()
{
  // give us flags for every variable that might be time evolving
  _time_evolving.resize(this->n_vars(), false);

  // Do any initialization our solvers need
  libmesh_assert (time_solver.get() != NULL);
  time_solver->init();

  // Next initialize ImplicitSystem data
  Parent::init_data();
}

AutoPtr<DiffContext> DifferentiableSystem::build_context ()
{
  return AutoPtr<DiffContext>(new DiffContext(*this));
}

void DifferentiableSystem::assemble ()
{
  this->assembly(true, true);
}

void DifferentiableSystem::solve ()
{
  time_solver->solve();
}

LinearSolver<Number>* DifferentiableSystem::get_linear_solver() const
{
  return this->time_solver->linear_solver().get();
}

std::pair<unsigned int, Real> DifferentiableSystem::get_linear_solve_parameters() const
{
  return std::make_pair(this->time_solver->diff_solver()->max_linear_iterations,
                        this->time_solver->diff_solver()->relative_residual_tolerance);
}

void DifferentiableSystem::release_linear_solver(LinearSolver<Number>*) const
{
}
<commit_msg>Avoid uninitialized variable - this shouldn't have led to any bugs, though.<commit_after>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include "diff_solver.h"
#include "diff_system.h"
#include "dof_map.h"
#include "numeric_vector.h"
#include "parameter_vector.h"
#include "qoi_set.h"
#include "sensitivity_data.h"
#include "time_solver.h"

DifferentiableSystem::DifferentiableSystem
                      (EquationSystems& es,
                       const std::string& name,
                       const unsigned int number) :
  Parent      (es, name, number),
  compute_internal_sides(false),
  postprocess_sides(false),
  assemble_qoi_sides(false),
  time_solver (NULL),
  time(0.),
  deltat(1.),
  print_solution_norms(false),
  print_solutions(false),
  print_residual_norms(false),
  print_residuals(false),
  print_jacobian_norms(false),
  print_jacobians(false),
  print_element_jacobians(false),
  use_fixed_solution(false)
{
}

DifferentiableSystem::~DifferentiableSystem ()
{
  this->clear();
}

void DifferentiableSystem::clear ()
{
  _time_evolving.resize(0);

  use_fixed_solution = false;
}

void DifferentiableSystem::reinit ()
{
  Parent::reinit();

  time_solver->reinit();
}

void DifferentiableSystem::init_data ()
{
  // give us flags for every variable that might be time evolving
  _time_evolving.resize(this->n_vars(), false);

  // Do any initialization our solvers need
  libmesh_assert (time_solver.get() != NULL);
  time_solver->init();

  // Next initialize ImplicitSystem data
  Parent::init_data();
}

AutoPtr<DiffContext> DifferentiableSystem::build_context ()
{
  return AutoPtr<DiffContext>(new DiffContext(*this));
}

void DifferentiableSystem::assemble ()
{
  this->assembly(true, true);
}

void DifferentiableSystem::solve ()
{
  time_solver->solve();
}

LinearSolver<Number>* DifferentiableSystem::get_linear_solver() const
{
  return this->time_solver->linear_solver().get();
}

std::pair<unsigned int, Real> DifferentiableSystem::get_linear_solve_parameters() const
{
  return std::make_pair(this->time_solver->diff_solver()->max_linear_iterations,
                        this->time_solver->diff_solver()->relative_residual_tolerance);
}

void DifferentiableSystem::release_linear_solver(LinearSolver<Number>*) const
{
}
<|endoftext|>


<commit_before>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2020 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

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

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

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

#include "NFSceneProcessModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFMessageDefine/NFMsgDefine.h"

bool NFSceneProcessModule::Init()
{
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneModule = pPluginManager->FindModule<NFISceneModule>();
	m_pCellModule = pPluginManager->FindModule<NFICellModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();

    return true;
}

bool NFSceneProcessModule::Shut()
{
    return true;
}

bool NFSceneProcessModule::Execute()
{
    return true;
}

bool NFSceneProcessModule::AfterInit()
{
    m_pKernelModule->AddClassCallBack(NFrame::Player::ThisName(), this, &NFSceneProcessModule::OnObjectClassEvent);

	m_pSceneModule->AddEnterSceneConditionCallBack(this, &NFSceneProcessModule::EnterSceneConditionEvent);

	m_pSceneModule->AddBeforeEnterSceneGroupCallBack(this, &NFSceneProcessModule::BeforeEnterSceneGroupEvent);
	m_pSceneModule->AddAfterEnterSceneGroupCallBack(this, &NFSceneProcessModule::AfterEnterSceneGroupEvent);
	m_pSceneModule->AddBeforeLeaveSceneGroupCallBack(this, &NFSceneProcessModule::BeforeLeaveSceneGroupEvent);
	m_pSceneModule->AddAfterLeaveSceneGroupCallBack(this, &NFSceneProcessModule::AfterLeaveSceneGroupEvent);
    //////////////////////////////////////////////////////////////////////////

    return true;
}

bool NFSceneProcessModule::ReadyExecute()
{
	NF_SHARE_PTR<NFIClass> xLogicClass = m_pClassModule->GetElement(NFrame::Scene::ThisName());
	if (xLogicClass)
	{
		const std::vector<std::string>& strIdList = xLogicClass->GetIDList();
		for (int i = 0; i < strIdList.size(); ++i)
		{
			const std::string& strId = strIdList[i];

			//load first
			LoadSceneResource(strId);
			//create second
			CreateSceneBaseGroup(strId);
		}
	}

	return true;
}

bool NFSceneProcessModule::RequestEnterScene(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFVector3& pos, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		int nNewGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
		if (nNewGroupID > 0)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, nNewGroupID, nType, pos, argList);
		}
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
		const int nMaxGroup = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroup());
		const int nMaxPlayer = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroupPlayers());
		for (int i = 1; i <= nMaxGroup; ++i)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, 1, nType, pos, argList);
		}

		return false;
	}
	else
	{
		if (nGroupID > 0)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, nGroupID, nType, pos, argList);
		}
		else
		{
			int nNewGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
			if (nNewGroupID > 0)
			{
				return m_pSceneModule->RequestEnterScene(self, nSceneID, nNewGroupID, nType, pos, argList);
			}
		}
	}

	return false;
}

int NFSceneProcessModule::BeforeLeaveSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	//change AI onwer

	return 0;
}

int NFSceneProcessModule::AfterLeaveSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{

	}
	else if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

		return 0;
	}
	else
	{
		NFDataList varObjectList;
		if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
		{
			m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

			m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
		}
	}

	return 0;
}

int NFSceneProcessModule::OnObjectClassEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFDataList& var)
{
    if (strClassName == NFrame::Player::ThisName())
    {
        if (CLASS_OBJECT_EVENT::COE_DESTROY == eClassEvent)
        {
			int nSceneID = m_pKernelModule->GetPropertyInt32(self, NFrame::Player::SceneID());
			int nGroupID = m_pKernelModule->GetPropertyInt32(self, NFrame::Player::GroupID());
			NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());

            if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
            {
                m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

                m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
            }
			else if (eSceneType == NFMsg::ESceneType::MULTI_CLONE_SCENE)
			{
				NFDataList varObjectList;
				if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
				{
					m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

					m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
				}
			}
        }
    }

    return 0;
}

int NFSceneProcessModule::EnterSceneConditionEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	return 0;
}

int NFSceneProcessModule::BeforeEnterSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	//you can use object pool to enhance performance
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID, NFDataList::Empty());
	}
	else if (eSceneType  == NFMsg::ESceneType::MULTI_CLONE_SCENE)
	{
		NFDataList varObjectList;
		if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
		{
			m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID, NFDataList::Empty());
		}
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
	}

	return 0;
}

int NFSceneProcessModule::AfterEnterSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
	}
	else if (eSceneType == NFMsg::ESceneType::MULTI_CLONE_SCENE)
	{
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{

	}

	return 1;
}

bool NFSceneProcessModule::LoadSceneResource(const std::string& strSceneIDName)
{
    const std::string& strSceneFilePath = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::FilePath());

    rapidxml::file<> xFileSource(strSceneFilePath.c_str());
    rapidxml::xml_document<>  xFileDoc;
    xFileDoc.parse<0>(xFileSource.data());

	int nSceneID = lexical_cast<int>(strSceneIDName);

    rapidxml::xml_node<>* pSeedFileRoot = xFileDoc.first_node();
    for (rapidxml::xml_node<>* pSeedFileNode = pSeedFileRoot->first_node(); pSeedFileNode; pSeedFileNode = pSeedFileNode->next_sibling())
    {
        std::string strSeedID = pSeedFileNode->first_attribute(NFrame::IObject::ID().c_str())->value();
		std::string strConfigID = pSeedFileNode->first_attribute(NFrame::IObject::ConfigID().c_str())->value();
        float fSeedX = lexical_cast<float>(pSeedFileNode->first_attribute("X")->value());
        float fSeedY = lexical_cast<float>(pSeedFileNode->first_attribute("Y")->value());
        float fSeedZ = lexical_cast<float>(pSeedFileNode->first_attribute("Z")->value());
		int nWeight = lexical_cast<int>(pSeedFileNode->first_attribute("Weight")->value());
		m_pSceneModule->AddSeedData(nSceneID, strSeedID, strConfigID, NFVector3(fSeedX, fSeedY, fSeedZ), nWeight);

	}

	const std::string& strRelivePosition = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::RelivePos());
	NFDataList xRelivePositionList;
	xRelivePositionList.Split(strRelivePosition, ";");
	for (int i = 0; i < xRelivePositionList.GetCount(); ++i)
	{
		const std::string& strPos = xRelivePositionList.String(i);
		if (!strPos.empty())
		{
			NFDataList xPosition;
			xPosition.Split(strPos, ",");
			if (xPosition.GetCount() == 3)
			{
				float fPosX = lexical_cast<float>(xPosition.String(0));
				float fPosY = lexical_cast<float>(xPosition.String(1));
				float fPosZ = lexical_cast<float>(xPosition.String(2));
				m_pSceneModule->AddRelivePosition(nSceneID, i, NFVector3(fPosX, fPosY, fPosZ));
			}
		}
	}
	/*
	const std::string& strTagPosition = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::TagPos());
	NFDataList xTagPositionList;
	xTagPositionList.Split(strTagPosition, ";");
	for (int i = 0; i < xTagPositionList.GetCount(); ++i)
	{
		const std::string& strPos = xTagPositionList.String(i);
		if (!strPos.empty())
		{
			NFDataList xPosition;
			xPosition.Split(strPos, ",");
			if (xPosition.GetCount() == 3)
			{
				float fPosX = lexical_cast<float>(xPosition.String(0));
				float fPosY = lexical_cast<float>(xPosition.String(1));
				float fPosZ = lexical_cast<float>(xPosition.String(2));
				m_pSceneModule->AddTagPosition(nSceneID, i, NFVector3(fPosX, fPosY, fPosZ));
			}
		}
	}

	*/

    return true;
}

bool NFSceneProcessModule::CreateSceneBaseGroup(const std::string & strSceneIDName)
{
	const int nSceneID = lexical_cast<int>(strSceneIDName);
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	const int nMaxGroup = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroup());
	if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
		//line 10
		for (int i = 0; i < 1; ++i)
		{
			int nGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
			if (nGroupID > 0)
			{
				m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID);
			}
			else
			{
				m_pLogModule->LogError("CreateSceneBaseGroup error " + strSceneIDName);
			}
		}

		return true;
	}
	return false;
}
<commit_msg>fix bug<commit_after>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2020 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

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

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

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

#include "NFSceneProcessModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFMessageDefine/NFMsgDefine.h"

bool NFSceneProcessModule::Init()
{
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneModule = pPluginManager->FindModule<NFISceneModule>();
	m_pCellModule = pPluginManager->FindModule<NFICellModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();

    return true;
}

bool NFSceneProcessModule::Shut()
{
    return true;
}

bool NFSceneProcessModule::Execute()
{
    return true;
}

bool NFSceneProcessModule::AfterInit()
{
    m_pKernelModule->AddClassCallBack(NFrame::Player::ThisName(), this, &NFSceneProcessModule::OnObjectClassEvent);

	m_pSceneModule->AddEnterSceneConditionCallBack(this, &NFSceneProcessModule::EnterSceneConditionEvent);

	m_pSceneModule->AddBeforeEnterSceneGroupCallBack(this, &NFSceneProcessModule::BeforeEnterSceneGroupEvent);
	m_pSceneModule->AddAfterEnterSceneGroupCallBack(this, &NFSceneProcessModule::AfterEnterSceneGroupEvent);
	m_pSceneModule->AddBeforeLeaveSceneGroupCallBack(this, &NFSceneProcessModule::BeforeLeaveSceneGroupEvent);
	m_pSceneModule->AddAfterLeaveSceneGroupCallBack(this, &NFSceneProcessModule::AfterLeaveSceneGroupEvent);
    //////////////////////////////////////////////////////////////////////////

    return true;
}

bool NFSceneProcessModule::ReadyExecute()
{
	NF_SHARE_PTR<NFIClass> xLogicClass = m_pClassModule->GetElement(NFrame::Scene::ThisName());
	if (xLogicClass)
	{
		const std::vector<std::string>& strIdList = xLogicClass->GetIDList();
		for (int i = 0; i < strIdList.size(); ++i)
		{
			const std::string& strId = strIdList[i];

			//load first
			LoadSceneResource(strId);
			//create second
			CreateSceneBaseGroup(strId);
		}
	}

	return true;
}

bool NFSceneProcessModule::RequestEnterScene(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFVector3& pos, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		int nNewGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
		if (nNewGroupID > 0)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, nNewGroupID, nType, pos, argList);
		}
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
		const int nMaxGroup = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroup());
		const int nMaxPlayer = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroupPlayers());
		for (int i = 1; i <= nMaxGroup; ++i)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, 1, nType, pos, argList);
		}

		return false;
	}
	else
	{
		if (nGroupID > 0)
		{
			return m_pSceneModule->RequestEnterScene(self, nSceneID, nGroupID, nType, pos, argList);
		}
		else
		{
			int nNewGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
			if (nNewGroupID > 0)
			{
				return m_pSceneModule->RequestEnterScene(self, nSceneID, nNewGroupID, nType, pos, argList);
			}
		}
	}

	return false;
}

int NFSceneProcessModule::BeforeLeaveSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	//change AI onwer

	return 0;
}

int NFSceneProcessModule::AfterLeaveSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{

	}
	else if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

		return 0;
	}
	else
	{
		NFDataList varObjectList;
		if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
		{
			m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

			m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
		}
	}

	return 0;
}

int NFSceneProcessModule::OnObjectClassEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFDataList& var)
{
    if (strClassName == NFrame::Player::ThisName())
    {
        if (CLASS_OBJECT_EVENT::COE_DESTROY == eClassEvent)
        {
			int nSceneID = m_pKernelModule->GetPropertyInt32(self, NFrame::Player::SceneID());
			int nGroupID = m_pKernelModule->GetPropertyInt32(self, NFrame::Player::GroupID());
			NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());

            if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
            {
                m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

                m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
            }
			else if (eSceneType == NFMsg::ESceneType::MULTI_CLONE_SCENE)
			{
				NFDataList varObjectList;
				if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
				{
					m_pKernelModule->ReleaseGroupScene(nSceneID, nGroupID);

					m_pLogModule->LogInfo(self, "DestroyCloneSceneGroup " + std::to_string(nGroupID), __FUNCTION__ , __LINE__);
				}
			}
        }
    }

    return 0;
}

int NFSceneProcessModule::EnterSceneConditionEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	return 0;
}

int NFSceneProcessModule::BeforeEnterSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	//you can use object pool to enhance performance
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
		m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID, NFDataList::Empty());
	}
	else if (eSceneType == NFMsg::ESceneType::MULTI_CLONE_SCENE
		|| eSceneType == NFMsg::ESceneType::PVP_MODE_SCENE
	   	|| eSceneType == NFMsg::ESceneType::MVM_MODE_SCENE
	   	|| eSceneType == NFMsg::ESceneType::SURVIVAL_MODE_SCENE)
	{
		NFDataList varObjectList;
		if (m_pKernelModule->GetGroupObjectList(nSceneID, nGroupID, varObjectList, true) && varObjectList.GetCount() <= 0)
		{
			m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID, NFDataList::Empty());
		}
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
	}

	return 0;
}

int NFSceneProcessModule::AfterEnterSceneGroupEvent(const NFGUID & self, const int nSceneID, const int nGroupID, const int nType, const NFDataList & argList)
{
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	if (eSceneType == NFMsg::ESceneType::SINGLE_CLONE_SCENE)
	{
	}
	else if (eSceneType == NFMsg::ESceneType::MULTI_CLONE_SCENE)
	{
	}
	else if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{

	}

	return 1;
}

bool NFSceneProcessModule::LoadSceneResource(const std::string& strSceneIDName)
{
    const std::string& strSceneFilePath = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::FilePath());

    rapidxml::file<> xFileSource(strSceneFilePath.c_str());
    rapidxml::xml_document<>  xFileDoc;
    xFileDoc.parse<0>(xFileSource.data());

	int nSceneID = lexical_cast<int>(strSceneIDName);

    rapidxml::xml_node<>* pSeedFileRoot = xFileDoc.first_node();
    for (rapidxml::xml_node<>* pSeedFileNode = pSeedFileRoot->first_node(); pSeedFileNode; pSeedFileNode = pSeedFileNode->next_sibling())
    {
        std::string strSeedID = pSeedFileNode->first_attribute(NFrame::IObject::ID().c_str())->value();
		std::string strConfigID = pSeedFileNode->first_attribute(NFrame::IObject::ConfigID().c_str())->value();
        float fSeedX = lexical_cast<float>(pSeedFileNode->first_attribute("X")->value());
        float fSeedY = lexical_cast<float>(pSeedFileNode->first_attribute("Y")->value());
        float fSeedZ = lexical_cast<float>(pSeedFileNode->first_attribute("Z")->value());
		int nWeight = lexical_cast<int>(pSeedFileNode->first_attribute("Weight")->value());
		m_pSceneModule->AddSeedData(nSceneID, strSeedID, strConfigID, NFVector3(fSeedX, fSeedY, fSeedZ), nWeight);

	}

	const std::string& strRelivePosition = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::RelivePos());
	NFDataList xRelivePositionList;
	xRelivePositionList.Split(strRelivePosition, ";");
	for (int i = 0; i < xRelivePositionList.GetCount(); ++i)
	{
		const std::string& strPos = xRelivePositionList.String(i);
		if (!strPos.empty())
		{
			NFDataList xPosition;
			xPosition.Split(strPos, ",");
			if (xPosition.GetCount() == 3)
			{
				float fPosX = lexical_cast<float>(xPosition.String(0));
				float fPosY = lexical_cast<float>(xPosition.String(1));
				float fPosZ = lexical_cast<float>(xPosition.String(2));
				m_pSceneModule->AddRelivePosition(nSceneID, i, NFVector3(fPosX, fPosY, fPosZ));
			}
		}
	}
	/*
	const std::string& strTagPosition = m_pElementModule->GetPropertyString(strSceneIDName, NFrame::Scene::TagPos());
	NFDataList xTagPositionList;
	xTagPositionList.Split(strTagPosition, ";");
	for (int i = 0; i < xTagPositionList.GetCount(); ++i)
	{
		const std::string& strPos = xTagPositionList.String(i);
		if (!strPos.empty())
		{
			NFDataList xPosition;
			xPosition.Split(strPos, ",");
			if (xPosition.GetCount() == 3)
			{
				float fPosX = lexical_cast<float>(xPosition.String(0));
				float fPosY = lexical_cast<float>(xPosition.String(1));
				float fPosZ = lexical_cast<float>(xPosition.String(2));
				m_pSceneModule->AddTagPosition(nSceneID, i, NFVector3(fPosX, fPosY, fPosZ));
			}
		}
	}

	*/

    return true;
}

bool NFSceneProcessModule::CreateSceneBaseGroup(const std::string & strSceneIDName)
{
	const int nSceneID = lexical_cast<int>(strSceneIDName);
	NFMsg::ESceneType eSceneType = (NFMsg::ESceneType)m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::Type());
	const int nMaxGroup = m_pElementModule->GetPropertyInt32(std::to_string(nSceneID), NFrame::Scene::MaxGroup());
	if (eSceneType == NFMsg::ESceneType::NORMAL_SCENE)
	{
		//line 10
		for (int i = 0; i < 1; ++i)
		{
			int nGroupID = m_pKernelModule->RequestGroupScene(nSceneID);
			if (nGroupID > 0)
			{
				m_pSceneModule->CreateSceneNPC(nSceneID, nGroupID);
			}
			else
			{
				m_pLogModule->LogError("CreateSceneBaseGroup error " + strSceneIDName);
			}
		}

		return true;
	}
	return false;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "../include/Database.hpp"
#include <boost/filesystem.hpp>
#include <iostream>

boost::filesystem::path tempfile() {
	return boost::filesystem::temp_directory_path() /= boost::filesystem::unique_path();
}

TEST(DatabaseTest, dbCreationCustom) {
	boost::filesystem::path dbPath(tempfile());
	Database db(dbPath.c_str());

	ASSERT_TRUE(boost::filesystem::exists(dbPath));
}

TEST(DatabaseTest, writeRecords) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("bar");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;

	db.add(dbd1);
	db.add(dbd2);

	db.shutdown();

	ASSERT_EQ(2, db.getRecordsWritten());
}

TEST(DatabaseTest, writeRecordsWithInvalid) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("bar");
	Database::db_data dbd3("notValid");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;
	dbd3.status = Database::INVALID;

	db.add(dbd1);
	db.add(dbd2);
	db.add(dbd3);

	db.shutdown();

	ASSERT_EQ(3, db.getRecordsWritten());
}

TEST(DatabaseTest, writeDuplicateRecords) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("foo");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;

	db.add(dbd1);
	db.add(dbd2);

	db.shutdown();

	ASSERT_EQ(1, db.getRecordsWritten());
}

TEST(DatabaseTest, entryExistsNonExistant) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");

	ASSERT_FALSE(db.entryExists(dbd1));
}

TEST(DatabaseTest, entryExists) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	dbd1.status = Database::OK;
	db.add(dbd1);
	db.flush();
	ASSERT_TRUE(db.entryExists(dbd1));
	db.shutdown();
}

TEST(DatabaseTest, getSHAvalid) {
	Database db(tempfile().c_str());

	Database::db_data data;

	data.filePath = fs::path("foobar");
	data.sha256 = "ABCD";
	data.pHash = 1;
	data.status = Database::OK;

	db.add(data);
	db.flush();

	std::string shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_EQ("ABCD", shaHash);
	db.shutdown();
}

TEST(DatabaseTest, getSHANotExisting) {
	Database db(tempfile().c_str());

	std::string shaHash = db.getSHA(fs::path("unknown"));

	ASSERT_TRUE(shaHash.empty());
	db.shutdown();
}

TEST(DatabaseTest, updateSHA) {
	Database db(tempfile().c_str());

	Database::db_data data;

	data.filePath = fs::path("foobar");
	data.sha256 = "";
	data.pHash = 1;
	data.status = Database::OK;

	db.add(data);
	db.flush();

	std::string shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_TRUE(shaHash.empty());

	db.updateSHA256("foobar", "foo");

	shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_EQ("foo", shaHash);
}

TEST(DatabaseTest, getDefaultUserSchemaVersion) {
	Database db(tempfile().c_str());

	int version = db.getUserSchemaVersion();

	ASSERT_EQ(Database::getCurrentSchemaVersion(),version);
}

TEST(DatabaseTest, setUserSchemaVersion) {
	Database db(tempfile().c_str());

	int version = db.getUserSchemaVersion();

	// guard
	ASSERT_EQ(Database::getCurrentSchemaVersion(), version);

	db.setUserSchemaVersion(42);
	version = db.getUserSchemaVersion();

	ASSERT_EQ(42, version);
}

TEST(DatabaseTest, dbNewerThanCurrent) {
	const char* dbPath = tempfile().c_str();
	Database db(dbPath);
	db.exec("PRAGMA locking_mode = NORMAL;");

	db.setUserSchemaVersion(42);
	int version = db.getUserSchemaVersion();

	ASSERT_EQ(42, version);

	db.shutdown();
	ASSERT_THROW(Database db2(dbPath), std::runtime_error);
}

<commit_msg>Added test fixture class for database tests<commit_after>#include <gtest/gtest.h>
#include "../include/Database.hpp"
#include <boost/filesystem.hpp>
#include <iostream>

class DatabaseTest : public :: testing::Test {
protected:

	const Database db;
	boost::filesystem::path dbPath;

	boost::filesystem::path tempfile() {
		return boost::filesystem::temp_directory_path() /= boost::filesystem::unique_path();
	}

	DatabaseTest() {
		dbPath(tempfile());
		db = new Database(dbPath);
	}
};

TEST(DatabaseTest, dbCreationCustom) {
	boost::filesystem::path dbPath(tempfile());
	Database db(dbPath.c_str());

	ASSERT_TRUE(boost::filesystem::exists(dbPath));
}

TEST(DatabaseTest, writeRecords) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("bar");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;

	db.add(dbd1);
	db.add(dbd2);

	db.shutdown();

	ASSERT_EQ(2, db.getRecordsWritten());
}

TEST(DatabaseTest, writeRecordsWithInvalid) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("bar");
	Database::db_data dbd3("notValid");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;
	dbd3.status = Database::INVALID;

	db.add(dbd1);
	db.add(dbd2);
	db.add(dbd3);

	db.shutdown();

	ASSERT_EQ(3, db.getRecordsWritten());
}

TEST(DatabaseTest, writeDuplicateRecords) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	Database::db_data dbd2("foo");

	dbd1.status = Database::OK;
	dbd2.status = Database::OK;

	db.add(dbd1);
	db.add(dbd2);

	db.shutdown();

	ASSERT_EQ(1, db.getRecordsWritten());
}

TEST(DatabaseTest, entryExistsNonExistant) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");

	ASSERT_FALSE(db.entryExists(dbd1));
}

TEST(DatabaseTest, entryExists) {
	boost::filesystem::path dbPath(tempfile());

	Database db(dbPath.c_str());

	Database::db_data dbd1("foo");
	dbd1.status = Database::OK;
	db.add(dbd1);
	db.flush();
	ASSERT_TRUE(db.entryExists(dbd1));
	db.shutdown();
}

TEST(DatabaseTest, getSHAvalid) {
	Database db(tempfile().c_str());

	Database::db_data data;

	data.filePath = fs::path("foobar");
	data.sha256 = "ABCD";
	data.pHash = 1;
	data.status = Database::OK;

	db.add(data);
	db.flush();

	std::string shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_EQ("ABCD", shaHash);
	db.shutdown();
}

TEST(DatabaseTest, getSHANotExisting) {
	Database db(tempfile().c_str());

	std::string shaHash = db.getSHA(fs::path("unknown"));

	ASSERT_TRUE(shaHash.empty());
	db.shutdown();
}

TEST(DatabaseTest, updateSHA) {
	Database db(tempfile().c_str());

	Database::db_data data;

	data.filePath = fs::path("foobar");
	data.sha256 = "";
	data.pHash = 1;
	data.status = Database::OK;

	db.add(data);
	db.flush();

	std::string shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_TRUE(shaHash.empty());

	db.updateSHA256("foobar", "foo");

	shaHash = db.getSHA(fs::path("foobar"));

	ASSERT_EQ("foo", shaHash);
}

TEST(DatabaseTest, getDefaultUserSchemaVersion) {
	Database db(tempfile().c_str());

	int version = db.getUserSchemaVersion();

	ASSERT_EQ(Database::getCurrentSchemaVersion(),version);
}

TEST(DatabaseTest, setUserSchemaVersion) {
	Database db(tempfile().c_str());

	int version = db.getUserSchemaVersion();

	// guard
	ASSERT_EQ(Database::getCurrentSchemaVersion(), version);

	db.setUserSchemaVersion(42);
	version = db.getUserSchemaVersion();

	ASSERT_EQ(42, version);
}

TEST(DatabaseTest, dbNewerThanCurrent) {
	const char* dbPath = tempfile().c_str();
	Database db(dbPath);
	db.exec("PRAGMA locking_mode = NORMAL;");

	db.setUserSchemaVersion(42);
	int version = db.getUserSchemaVersion();

	ASSERT_EQ(42, version);

	db.shutdown();
	ASSERT_THROW(Database db2(dbPath), std::runtime_error);
}

<|endoftext|>