<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_MESH_OPERATORS
#define MFEM_MESH_OPERATORS

#include "../config/config.hpp"
#include "../general/array.hpp"
#include "mesh.hpp"
#include "../fem/estimators.hpp"

#include <limits>

namespace mfem
{

/** @brief The MeshOperator class serves as base for mesh manipulation classes.

    The purpose of the class is to provide a common abstraction for various
    AMR mesh control schemes. The typical use in an AMR loop is illustrated
    in examples 6/6p and 15/15p.

    A more general loop that also supports sequences of mesh operators with
    multiple updates looks like this:
    \code
       for (...)
       {
          // computations on the current mesh ...
          while (mesh_operator->Apply(mesh))
          {
             // update FiniteElementSpaces and interpolate GridFunctions ...
             if (mesh_operator->Continue()) { break; }
          }
          if (mesh_operator->Stop()) { break; }
       }
    \endcode
 */
class MeshOperator
{
private:
   int mod;

protected:
   friend class MeshOperatorSequence;

   /** @brief Implementation of the mesh operation. Invoked by the Apply()
              public method.
       @return Combination of ActionInfo constants. */
   virtual int ApplyImpl(Mesh &mesh) = 0;

   /// Constructor to be used by derived classes.
   MeshOperator() : mod(NONE) { }

public:
   /** @brief Action and information constants and masks.

       Combinations of constants are returned by the Apply() virtual method and
       can be accessed directly with GetActionInfo() or indirectly with methods
       like Stop(), Continue(), etc. The information bits (MASK_INFO) can be set
       only when the update bit is set (see MASK_UPDATE). */
   enum Action
   {
      NONE        = 0, /**< continue with computations without updating spaces
                            or grid-functions, i.e. the mesh was not modified */
      CONTINUE    = 1, /**< update spaces and grid-functions and continue
                            computations with the new mesh */
      STOP        = 2, ///< a stopping criterion was satisfied
      REPEAT      = 3, /**< update spaces and grid-functions and call the
                            operator Apply() method again */
      MASK_UPDATE = 1, ///< bit mask for the "update" bit
      MASK_ACTION = 3  ///< bit mask for all "action" bits
   };

   enum Info
   {
      REFINED     = 4*1, ///< the mesh was refined
      DEREFINED   = 4*2, ///< the mesh was de-refined
      REBALANCED  = 4*3, ///< the mesh was rebalanced
      MASK_INFO   = ~3   ///< bit mask for all "info" bits
   };

   /** @brief Perform the mesh operation.
       @return true if FiniteElementSpaces and GridFunctions need to be updated.
   */
   bool Apply(Mesh &mesh) { return ((mod = ApplyImpl(mesh)) & MASK_UPDATE); }

   /** @brief Check if STOP action is requested, e.g. stopping criterion is
       satisfied. */
   bool Stop() const { return ((mod & MASK_ACTION) == STOP); }
   /** @brief Check if REPEAT action is requested, i.e. FiniteElementSpaces and
       GridFunctions need to be updated, and Apply() must be called again. */
   bool Repeat() const { return ((mod & MASK_ACTION) == REPEAT); }
   /** @brief Check if CONTINUE action is requested, i.e. FiniteElementSpaces
       and GridFunctions need to be updated and computations should continue. */
   bool Continue() const { return ((mod & MASK_ACTION) == CONTINUE); }

   /// Check if the mesh was refined.
   bool Refined() const { return ((mod & MASK_INFO) == REFINED); }
   /// Check if the mesh was de-refined.
   bool Derefined() const { return ((mod & MASK_INFO) == DEREFINED); }
   /// Check if the mesh was rebalanced.
   bool Rebalanced() const { return ((mod & MASK_INFO) == REBALANCED); }

   /** @brief Get the full ActionInfo value generated by the last call to
       Apply(). */
   int GetActionInfo() const { return mod; }

   /// Reset the MeshOperator.
   virtual void Reset() = 0;

   /// The destructor is virtual.
   virtual ~MeshOperator() { }
};

/** Composition of MeshOperators into a sequence. Use the Append() method to
    create the sequence. */
class MeshOperatorSequence : public MeshOperator
{
protected:
   int step;
   Array<MeshOperator*> sequence; ///< MeshOperators sequence, owned by us.

   /// Do not allow copy construction, due to assumed ownership.
   MeshOperatorSequence(const MeshOperatorSequence &) { }

   /** @brief Apply the MeshOperatorSequence.
       @return ActionInfo value corresponding to the last applied operator from
       the sequence. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Constructor. Use the Append() method to create the sequence.
   MeshOperatorSequence() : step(-1) { }

   /// Delete all operators from the sequence.
   virtual ~MeshOperatorSequence();

   /** @brief Add an operator to the end of the sequence.
       The MeshOperatorSequence assumes ownership of the operator. */
   void Append(MeshOperator *mc) { sequence.Append(mc); }

   /// Access the underlying sequence.
   Array<MeshOperator*> &GetSequence() { return sequence; }

   /// Reset all MeshOperators in the sequence.
   virtual void Reset();
};

/** @brief Mesh refinement operator using an error threshold.

    This class uses the given ErrorEstimator to estimate local element errors
    and then marks for refinement all elements i such that loc_err_i > threshold.
    The threshold is computed as
    \code
       threshold = max(total_err * total_fraction * pow(num_elements,-1.0/p),
                       local_err_goal);
    \endcode
    where p (=total_norm_p), total_fraction, and local_err_goal are settable
    parameters, total_err = (sum_i local_err_i^p)^{1/p}, when p < inf,
    or total_err = max_i local_err_i, when p = inf.
*/
class ThresholdRefiner : public MeshOperator
{
protected:
   ErrorEstimator &estimator;
   AnisotropicErrorEstimator *aniso_estimator;

   double total_norm_p;
   double total_err_goal;
   double total_fraction;
   double local_err_goal;
   long   max_elements;

   double threshold;
   long num_marked_elements;

   Array<Refinement> marked_elements;
   long current_sequence;

   int non_conforming;
   int nc_limit;

   double GetNorm(const Vector &local_err, Mesh &mesh) const;

   /** @brief Apply the operator to the mesh.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Construct a ThresholdRefiner using the given ErrorEstimator.
   ThresholdRefiner(ErrorEstimator &est);

   // default destructor (virtual)

   /** @brief Set the exponent, p, of the discrete p-norm used to compute the
       total error from the local element errors. */
   void SetTotalErrorNormP(double norm_p = infinity())
   { total_norm_p = norm_p; }

   /** @brief Set the total error stopping criterion: stop when
       total_err <= total_err_goal. The default value is zero. */
   void SetTotalErrorGoal(double err_goal) { total_err_goal = err_goal; }

   /** @brief Set the total fraction used in the computation of the threshold.
       The default value is 1/2.
       @note If fraction == 0, total_err is essentially ignored in the threshold
       computation, i.e. threshold = local error goal. */
   void SetTotalErrorFraction(double fraction) { total_fraction = fraction; }

   /** @brief Set the local stopping criterion: stop when
       local_err_i <= local_err_goal. The default value is zero.
       @note If local_err_goal == 0, it is essentially ignored in the threshold
       computation. */
   void SetLocalErrorGoal(double err_goal) { local_err_goal = err_goal; }

   /** @brief Set the maximum number of elements stopping criterion: stop when
       the input mesh has num_elements >= max_elem. The default value is
       LONG_MAX. */
   void SetMaxElements(long max_elem) { max_elements = max_elem; }

   /// Use nonconforming refinement, if possible (triangles, quads, hexes).
   void PreferNonconformingRefinement() { non_conforming = 1; }

   /** @brief Use conforming refinement, if possible (triangles, tetrahedra)
       -- this is the default. */
   void PreferConformingRefinement() { non_conforming = -1; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). */
   void SetNCLimit(int nc_limit)
   {
      MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
      this->nc_limit = nc_limit;
   }

   /// Get the number of marked elements in the last Apply() call.
   long GetNumMarkedElements() const { return num_marked_elements; }

   /// Get the threshold used in the last Apply() call.
   double GetThreshold() const { return threshold; }

   /// Reset the associated estimator.
   virtual void Reset();
};

// TODO: BulkRefiner to refine a portion of the global error

/** @brief De-refinement operator using an error threshold.

    This de-refinement operator marks elements in the hierarchy whose children
    are leaves and their combined error is below a given threshold. The
    errors of the children are combined by one of the following operations:
    - op = 0: minimum of the errors
    - op = 1: sum of the errors (default)
    - op = 2: maximum of the errors. */
class ThresholdDerefiner : public MeshOperator
{
protected:
   ErrorEstimator &estimator;

   double threshold;
   int nc_limit, op;

   /** @brief Apply the operator to the mesh.
       @return DEREFINED + CONTINUE if some elements were de-refined; NONE
       otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Construct a ThresholdDerefiner using the given ErrorEstimator.
   ThresholdDerefiner(ErrorEstimator &est)
      : estimator(est)
   {
      threshold = 0.0;
      nc_limit = 0;
      op = 1;
   }

   // default destructor (virtual)

   /// Set the de-refinement threshold. The default value is zero.
   void SetThreshold(double thresh) { threshold = thresh; }

   void SetOp(int op) { this->op = op; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). */
   void SetNCLimit(int nc_limit)
   {
      MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
      this->nc_limit = nc_limit;
   }

   /// Reset the associated estimator.
   virtual void Reset() { estimator.Reset(); }
};

/** @brief Refinement operator to control data oscillation.

    This class computes osc_K(f) := || h ⋅ (I - Π) f ||_K  at each element K.
    Here, Π is the L2-projection and ||⋅||_K is the L2-norm, restricted to the
    element K. All elements satisfying the inequality
    \code
       osc_K(f) > threshold ⋅ ||f|| / sqrt(n_el),
    \endcode
    are refined. Here, threshold is a postive parameter, ||⋅|| is the L2-norm
    over the entire domain Ω, and n_el is the number of elements in the mesh.

    Note that if osc(f) = threshold ⋅ ||f|| / sqrt(n_el) for each K, then
    \code
       osc(f) = sqrt( sum_K osc_K^2(f)) = threshold ⋅ ||f||.
    \endcode
    This is the reason for the 1/sqrt(n_el) factor. */
class CoefficientRefiner : public MeshOperator
{
protected:
   int nc_limit = 1;
   int nonconforming = -1;
   int order;
   long max_elements = std::numeric_limits<long>::max();
   double threshold = 1.0e-2;
   double global_osc = 0.0;
   Array<int> mesh_refinements;
   Vector element_oscs;
   Coefficient *coeff = NULL;
   GridFunction *gf;
   const IntegrationRule *ir_default[Geometry::NumGeom];
   const IntegrationRule **irs = NULL;

   /** @brief Apply the operator to the mesh once.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Constructor
   CoefficientRefiner(int order_) : order(order_) { }

   /** @brief Apply the operator to the mesh max_it times or until tolerance
    *  achieved.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int PreprocessMesh(Mesh &mesh, int max_it);

   int PreprocessMesh(Mesh &mesh)
   {
      int max_it = 10;
      return PreprocessMesh(mesh, max_it);
   }

   /// Set the refinement threshold. The default value is 1.0e-2.
   void SetThreshold(double threshold_) { threshold = threshold_; }

   /** @brief Set the maximum number of elements stopping criterion: stop when
       the input mesh has num_elements >= max_elem. The default value is
       LONG_MAX. */
   void SetMaxElements(long max_elements_) { max_elements = max_elements_; }

   /// Set the function f
   void SetCoefficient(Coefficient &coeff_)
   {
      element_oscs.Destroy();
      global_osc = 0.0;
      coeff = &coeff_;
   }

   /// Reset the oscillation order
   void SetOrder(double order_) { order = order_; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). The default value is 1, which helps ensure appropriate
       refinements in pathological situations where the default quadrature
       order is too low.  */
   void SetNCLimit(int nc_limit_)
   {
      MFEM_ASSERT(nc_limit_ >= 0, "Invalid NC limit");
      nc_limit = nc_limit_;
   }

   // Set a custom integration rule
   void SetIntRule(const IntegrationRule *irs_[]) { irs = irs_; }

   // Return the value of the global relative data oscillation
   double GetOsc() { return global_osc; }

   // Return the local relative data oscillation errors
   Vector GetLocalOscs()
   {
      MFEM_ASSERT(element_oscs.Size() > 0,
                  "Local oscillations have not been computed yet")
      return element_oscs;
   }

   /// Reset
   virtual void Reset();
};

/** @brief ParMesh rebalancing operator.

    If the mesh is a parallel mesh, perform rebalancing; otherwise, do nothing.
*/
class Rebalancer : public MeshOperator
{
protected:
   /** @brief Rebalance a parallel mesh (only non-conforming parallel meshes are
       supported).
       @return CONTINUE + REBALANCE on success, NONE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Empty.
   virtual void Reset() { }
};

} // namespace mfem

#endif // MFEM_MESH_OPERATORS
<commit_msg>make GetOsc at const member function<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_MESH_OPERATORS
#define MFEM_MESH_OPERATORS

#include "../config/config.hpp"
#include "../general/array.hpp"
#include "mesh.hpp"
#include "../fem/estimators.hpp"

#include <limits>

namespace mfem
{

/** @brief The MeshOperator class serves as base for mesh manipulation classes.

    The purpose of the class is to provide a common abstraction for various
    AMR mesh control schemes. The typical use in an AMR loop is illustrated
    in examples 6/6p and 15/15p.

    A more general loop that also supports sequences of mesh operators with
    multiple updates looks like this:
    \code
       for (...)
       {
          // computations on the current mesh ...
          while (mesh_operator->Apply(mesh))
          {
             // update FiniteElementSpaces and interpolate GridFunctions ...
             if (mesh_operator->Continue()) { break; }
          }
          if (mesh_operator->Stop()) { break; }
       }
    \endcode
 */
class MeshOperator
{
private:
   int mod;

protected:
   friend class MeshOperatorSequence;

   /** @brief Implementation of the mesh operation. Invoked by the Apply()
              public method.
       @return Combination of ActionInfo constants. */
   virtual int ApplyImpl(Mesh &mesh) = 0;

   /// Constructor to be used by derived classes.
   MeshOperator() : mod(NONE) { }

public:
   /** @brief Action and information constants and masks.

       Combinations of constants are returned by the Apply() virtual method and
       can be accessed directly with GetActionInfo() or indirectly with methods
       like Stop(), Continue(), etc. The information bits (MASK_INFO) can be set
       only when the update bit is set (see MASK_UPDATE). */
   enum Action
   {
      NONE        = 0, /**< continue with computations without updating spaces
                            or grid-functions, i.e. the mesh was not modified */
      CONTINUE    = 1, /**< update spaces and grid-functions and continue
                            computations with the new mesh */
      STOP        = 2, ///< a stopping criterion was satisfied
      REPEAT      = 3, /**< update spaces and grid-functions and call the
                            operator Apply() method again */
      MASK_UPDATE = 1, ///< bit mask for the "update" bit
      MASK_ACTION = 3  ///< bit mask for all "action" bits
   };

   enum Info
   {
      REFINED     = 4*1, ///< the mesh was refined
      DEREFINED   = 4*2, ///< the mesh was de-refined
      REBALANCED  = 4*3, ///< the mesh was rebalanced
      MASK_INFO   = ~3   ///< bit mask for all "info" bits
   };

   /** @brief Perform the mesh operation.
       @return true if FiniteElementSpaces and GridFunctions need to be updated.
   */
   bool Apply(Mesh &mesh) { return ((mod = ApplyImpl(mesh)) & MASK_UPDATE); }

   /** @brief Check if STOP action is requested, e.g. stopping criterion is
       satisfied. */
   bool Stop() const { return ((mod & MASK_ACTION) == STOP); }
   /** @brief Check if REPEAT action is requested, i.e. FiniteElementSpaces and
       GridFunctions need to be updated, and Apply() must be called again. */
   bool Repeat() const { return ((mod & MASK_ACTION) == REPEAT); }
   /** @brief Check if CONTINUE action is requested, i.e. FiniteElementSpaces
       and GridFunctions need to be updated and computations should continue. */
   bool Continue() const { return ((mod & MASK_ACTION) == CONTINUE); }

   /// Check if the mesh was refined.
   bool Refined() const { return ((mod & MASK_INFO) == REFINED); }
   /// Check if the mesh was de-refined.
   bool Derefined() const { return ((mod & MASK_INFO) == DEREFINED); }
   /// Check if the mesh was rebalanced.
   bool Rebalanced() const { return ((mod & MASK_INFO) == REBALANCED); }

   /** @brief Get the full ActionInfo value generated by the last call to
       Apply(). */
   int GetActionInfo() const { return mod; }

   /// Reset the MeshOperator.
   virtual void Reset() = 0;

   /// The destructor is virtual.
   virtual ~MeshOperator() { }
};

/** Composition of MeshOperators into a sequence. Use the Append() method to
    create the sequence. */
class MeshOperatorSequence : public MeshOperator
{
protected:
   int step;
   Array<MeshOperator*> sequence; ///< MeshOperators sequence, owned by us.

   /// Do not allow copy construction, due to assumed ownership.
   MeshOperatorSequence(const MeshOperatorSequence &) { }

   /** @brief Apply the MeshOperatorSequence.
       @return ActionInfo value corresponding to the last applied operator from
       the sequence. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Constructor. Use the Append() method to create the sequence.
   MeshOperatorSequence() : step(-1) { }

   /// Delete all operators from the sequence.
   virtual ~MeshOperatorSequence();

   /** @brief Add an operator to the end of the sequence.
       The MeshOperatorSequence assumes ownership of the operator. */
   void Append(MeshOperator *mc) { sequence.Append(mc); }

   /// Access the underlying sequence.
   Array<MeshOperator*> &GetSequence() { return sequence; }

   /// Reset all MeshOperators in the sequence.
   virtual void Reset();
};

/** @brief Mesh refinement operator using an error threshold.

    This class uses the given ErrorEstimator to estimate local element errors
    and then marks for refinement all elements i such that loc_err_i > threshold.
    The threshold is computed as
    \code
       threshold = max(total_err * total_fraction * pow(num_elements,-1.0/p),
                       local_err_goal);
    \endcode
    where p (=total_norm_p), total_fraction, and local_err_goal are settable
    parameters, total_err = (sum_i local_err_i^p)^{1/p}, when p < inf,
    or total_err = max_i local_err_i, when p = inf.
*/
class ThresholdRefiner : public MeshOperator
{
protected:
   ErrorEstimator &estimator;
   AnisotropicErrorEstimator *aniso_estimator;

   double total_norm_p;
   double total_err_goal;
   double total_fraction;
   double local_err_goal;
   long   max_elements;

   double threshold;
   long num_marked_elements;

   Array<Refinement> marked_elements;
   long current_sequence;

   int non_conforming;
   int nc_limit;

   double GetNorm(const Vector &local_err, Mesh &mesh) const;

   /** @brief Apply the operator to the mesh.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Construct a ThresholdRefiner using the given ErrorEstimator.
   ThresholdRefiner(ErrorEstimator &est);

   // default destructor (virtual)

   /** @brief Set the exponent, p, of the discrete p-norm used to compute the
       total error from the local element errors. */
   void SetTotalErrorNormP(double norm_p = infinity())
   { total_norm_p = norm_p; }

   /** @brief Set the total error stopping criterion: stop when
       total_err <= total_err_goal. The default value is zero. */
   void SetTotalErrorGoal(double err_goal) { total_err_goal = err_goal; }

   /** @brief Set the total fraction used in the computation of the threshold.
       The default value is 1/2.
       @note If fraction == 0, total_err is essentially ignored in the threshold
       computation, i.e. threshold = local error goal. */
   void SetTotalErrorFraction(double fraction) { total_fraction = fraction; }

   /** @brief Set the local stopping criterion: stop when
       local_err_i <= local_err_goal. The default value is zero.
       @note If local_err_goal == 0, it is essentially ignored in the threshold
       computation. */
   void SetLocalErrorGoal(double err_goal) { local_err_goal = err_goal; }

   /** @brief Set the maximum number of elements stopping criterion: stop when
       the input mesh has num_elements >= max_elem. The default value is
       LONG_MAX. */
   void SetMaxElements(long max_elem) { max_elements = max_elem; }

   /// Use nonconforming refinement, if possible (triangles, quads, hexes).
   void PreferNonconformingRefinement() { non_conforming = 1; }

   /** @brief Use conforming refinement, if possible (triangles, tetrahedra)
       -- this is the default. */
   void PreferConformingRefinement() { non_conforming = -1; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). */
   void SetNCLimit(int nc_limit)
   {
      MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
      this->nc_limit = nc_limit;
   }

   /// Get the number of marked elements in the last Apply() call.
   long GetNumMarkedElements() const { return num_marked_elements; }

   /// Get the threshold used in the last Apply() call.
   double GetThreshold() const { return threshold; }

   /// Reset the associated estimator.
   virtual void Reset();
};

// TODO: BulkRefiner to refine a portion of the global error

/** @brief De-refinement operator using an error threshold.

    This de-refinement operator marks elements in the hierarchy whose children
    are leaves and their combined error is below a given threshold. The
    errors of the children are combined by one of the following operations:
    - op = 0: minimum of the errors
    - op = 1: sum of the errors (default)
    - op = 2: maximum of the errors. */
class ThresholdDerefiner : public MeshOperator
{
protected:
   ErrorEstimator &estimator;

   double threshold;
   int nc_limit, op;

   /** @brief Apply the operator to the mesh.
       @return DEREFINED + CONTINUE if some elements were de-refined; NONE
       otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Construct a ThresholdDerefiner using the given ErrorEstimator.
   ThresholdDerefiner(ErrorEstimator &est)
      : estimator(est)
   {
      threshold = 0.0;
      nc_limit = 0;
      op = 1;
   }

   // default destructor (virtual)

   /// Set the de-refinement threshold. The default value is zero.
   void SetThreshold(double thresh) { threshold = thresh; }

   void SetOp(int op) { this->op = op; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). */
   void SetNCLimit(int nc_limit)
   {
      MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
      this->nc_limit = nc_limit;
   }

   /// Reset the associated estimator.
   virtual void Reset() { estimator.Reset(); }
};

/** @brief Refinement operator to control data oscillation.

    This class computes osc_K(f) := || h ⋅ (I - Π) f ||_K  at each element K.
    Here, Π is the L2-projection and ||⋅||_K is the L2-norm, restricted to the
    element K. All elements satisfying the inequality
    \code
       osc_K(f) > threshold ⋅ ||f|| / sqrt(n_el),
    \endcode
    are refined. Here, threshold is a postive parameter, ||⋅|| is the L2-norm
    over the entire domain Ω, and n_el is the number of elements in the mesh.

    Note that if osc(f) = threshold ⋅ ||f|| / sqrt(n_el) for each K, then
    \code
       osc(f) = sqrt( sum_K osc_K^2(f)) = threshold ⋅ ||f||.
    \endcode
    This is the reason for the 1/sqrt(n_el) factor. */
class CoefficientRefiner : public MeshOperator
{
protected:
   int nc_limit = 1;
   int nonconforming = -1;
   int order;
   long max_elements = std::numeric_limits<long>::max();
   double threshold = 1.0e-2;
   double global_osc = 0.0;
   Array<int> mesh_refinements;
   Vector element_oscs;
   Coefficient *coeff = NULL;
   GridFunction *gf;
   const IntegrationRule *ir_default[Geometry::NumGeom];
   const IntegrationRule **irs = NULL;

   /** @brief Apply the operator to the mesh once.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Constructor
   CoefficientRefiner(int order_) : order(order_) { }

   /** @brief Apply the operator to the mesh max_it times or until tolerance
    *  achieved.
       @return STOP if a stopping criterion is satisfied or no elements were
       marked for refinement; REFINED + CONTINUE otherwise. */
   virtual int PreprocessMesh(Mesh &mesh, int max_it);

   int PreprocessMesh(Mesh &mesh)
   {
      int max_it = 10;
      return PreprocessMesh(mesh, max_it);
   }

   /// Set the refinement threshold. The default value is 1.0e-2.
   void SetThreshold(double threshold_) { threshold = threshold_; }

   /** @brief Set the maximum number of elements stopping criterion: stop when
       the input mesh has num_elements >= max_elem. The default value is
       LONG_MAX. */
   void SetMaxElements(long max_elements_) { max_elements = max_elements_; }

   /// Set the function f
   void SetCoefficient(Coefficient &coeff_)
   {
      element_oscs.Destroy();
      global_osc = 0.0;
      coeff = &coeff_;
   }

   /// Reset the oscillation order
   void SetOrder(double order_) { order = order_; }

   /** @brief Set the maximum ratio of refinement levels of adjacent elements
       (0 = unlimited). The default value is 1, which helps ensure appropriate
       refinements in pathological situations where the default quadrature
       order is too low.  */
   void SetNCLimit(int nc_limit_)
   {
      MFEM_ASSERT(nc_limit_ >= 0, "Invalid NC limit");
      nc_limit = nc_limit_;
   }

   // Set a custom integration rule
   void SetIntRule(const IntegrationRule *irs_[]) { irs = irs_; }

   // Return the value of the global relative data oscillation
   const double GetOsc() { return global_osc; }

   // Return the local relative data oscillation errors
   Vector GetLocalOscs()
   {
      MFEM_ASSERT(element_oscs.Size() > 0,
                  "Local oscillations have not been computed yet")
      return element_oscs;
   }

   /// Reset
   virtual void Reset();
};

/** @brief ParMesh rebalancing operator.

    If the mesh is a parallel mesh, perform rebalancing; otherwise, do nothing.
*/
class Rebalancer : public MeshOperator
{
protected:
   /** @brief Rebalance a parallel mesh (only non-conforming parallel meshes are
       supported).
       @return CONTINUE + REBALANCE on success, NONE otherwise. */
   virtual int ApplyImpl(Mesh &mesh);

public:
   /// Empty.
   virtual void Reset() { }
};

} // namespace mfem

#endif // MFEM_MESH_OPERATORS
<|endoftext|>


<commit_before>inline mdarray<double, 1>
Band::get_h_diag(K_point* kp__,
                 double v0__,
                 double theta0__) const
{
    // TODO: code is replicated in o_diag
    splindex<block> spl_num_atoms(unit_cell_.num_atoms(), kp__->comm().size(), kp__->comm().rank());
    int nlo{0};
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        nlo += unit_cell_.atom(ia).mt_lo_basis_size();
    }

    mdarray<double, 1> h_diag(kp__->num_gkvec_loc() + nlo);
    for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
        int ig = kp__->gkvec().gvec_offset(kp__->comm().rank()) + igloc;

        double ekin = 0.5 * (kp__->gkvec().gkvec_cart(ig) * kp__->gkvec().gkvec_cart(ig));
        h_diag[igloc] = v0__ + ekin * theta0__;
    }

    matrix<double_complex> alm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());
    matrix<double_complex> halm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());

    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto& atom = unit_cell_.atom(ia);
        int nmt = atom.mt_aw_basis_size();

        kp__->alm_coeffs_loc().generate(ia, alm);
        apply_hmt_to_apw<spin_block_t::nm>(atom, kp__->num_gkvec_loc(), alm, halm);

        for (int xi = 0; xi < nmt; xi++) {
            for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
                h_diag[igloc] += std::real(std::conj(alm(igloc, xi)) * halm(igloc, xi));
            }
        }
    }

    nlo = 0;
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        auto& atom = unit_cell_.atom(ia);
        auto& type = atom.type();
        for (int ilo = 0; ilo < type.mt_lo_basis_size(); ilo++) {
            int xi_lo = type.mt_aw_basis_size() + ilo;
            /* local orbital indices */
            int lm_lo    = type.indexb(xi_lo).lm;
            int idxrf_lo = type.indexb(xi_lo).idxrf;

            h_diag[kp__->num_gkvec_loc() + nlo] = atom.radial_integrals_sum_L3<spin_block_t::nm>(idxrf_lo, idxrf_lo, gaunt_coefs_->gaunt_vector(lm_lo, lm_lo)).real();
            nlo++;
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        h_diag.allocate(memory_t::device);
        h_diag.copy_to_device();
    }
    #endif
    return std::move(h_diag);
}

inline mdarray<double, 1>
Band::get_o_diag(K_point* kp__,
                 double theta0__) const
{
    splindex<block> spl_num_atoms(unit_cell_.num_atoms(), kp__->comm().size(), kp__->comm().rank());
    int nlo{0};
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        nlo += unit_cell_.atom(ia).mt_lo_basis_size();
    }

    mdarray<double, 1> o_diag(kp__->num_gkvec_loc() + nlo);
    for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
        o_diag[igloc] = theta0__;
    }
    for (size_t i = kp__->num_gkvec_loc(); i < o_diag.size(); i++) {
        o_diag[i] = 1;
    }

    matrix<double_complex> alm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());

    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto& atom = unit_cell_.atom(ia);
        int nmt = atom.mt_aw_basis_size();

        kp__->alm_coeffs_loc().generate(ia, alm);

        for (int xi = 0; xi < nmt; xi++) {
            for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
                o_diag[igloc] += std::real(std::conj(alm(igloc, xi)) * alm(igloc, xi));
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        o_diag.allocate(memory_t::device);
        o_diag.copy_to_device();
    }
    #endif
    return std::move(o_diag);
}

template <typename T>
inline mdarray<double, 1>
Band::get_h_diag(K_point* kp__,
                 int ispn__,
                 double v0__,
                 D_operator<T>& d_op__) const
{
    PROFILE("sirius::Band::get_h_diag");

    mdarray<double, 1> h_diag(kp__->num_gkvec_loc());

    /* local H contribution */
    for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
        int ig = kp__->igk_loc(ig_loc);
        auto vgk = kp__->gkvec().gkvec_cart(ig);
        h_diag[ig_loc] = 0.5 * (vgk * vgk) + v0__;
    }

    /* non-local H contribution */
    auto& beta_gk_t = kp__->beta_projectors().beta_gk_t();
    matrix<double_complex> beta_gk_tmp(unit_cell_.max_mt_basis_size(), kp__->num_gkvec_loc());

    for (int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
        auto& atom_type = unit_cell_.atom_type(iat);
        int nbf = atom_type.mt_basis_size();
        matrix<double_complex> d_sum(nbf, nbf);
        d_sum.zero();

        for (int i = 0; i < atom_type.num_atoms(); i++) {
            int ia = atom_type.atom_id(i);

            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    d_sum(xi1, xi2) += d_op__(xi1, xi2, ispn__, ia);
                }
            }
        }

        int offs = unit_cell_.atom_type(iat).offset_lo();
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi = 0; xi < nbf; xi++) {
                beta_gk_tmp(xi, ig_loc) = beta_gk_t(ig_loc, offs + xi);
            }
        }

        #pragma omp parallel for schedule(static)
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    /* compute <G+k|beta_xi1> D_{xi1, xi2} <beta_xi2|G+k> contribution from all atoms */
                    auto z = beta_gk_tmp(xi1, ig_loc) * d_sum(xi1, xi2) * std::conj(beta_gk_tmp(xi2, ig_loc));
                    h_diag[ig_loc] += z.real();
                }
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        h_diag.allocate(memory_t::device);
        h_diag.copy_to_device();
    }
    #endif
    return std::move(h_diag);
}

template <typename T>
inline mdarray<double, 1>
Band::get_o_diag(K_point* kp__,
                 Q_operator<T>& q_op__) const
{
    PROFILE("sirius::Band::get_o_diag");

    mdarray<double, 1> o_diag(kp__->num_gkvec_loc());
    for (int ig = 0; ig < kp__->num_gkvec_loc(); ig++) {
        o_diag[ig] = 1;
    }

    /* non-local O contribution */
    auto& beta_gk_t = kp__->beta_projectors().beta_gk_t();
    matrix<double_complex> beta_gk_tmp(unit_cell_.max_mt_basis_size(), kp__->num_gkvec_loc());

    for (int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
        auto& atom_type = unit_cell_.atom_type(iat);
        if (!atom_type.pp_desc().augment) {
            continue;
        }

        int nbf = atom_type.mt_basis_size();

        matrix<double_complex> q_sum(nbf, nbf);
        q_sum.zero();

        for (int i = 0; i < atom_type.num_atoms(); i++) {
            int ia = atom_type.atom_id(i);

            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    q_sum(xi1, xi2) += q_op__(xi1, xi2, ia);
                }
            }
        }

        int offs = unit_cell_.atom_type(iat).offset_lo();
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi = 0; xi < nbf; xi++) {
                beta_gk_tmp(xi, ig_loc) = beta_gk_t(ig_loc, offs + xi);
            }
        }

        #pragma omp parallel for
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    /* compute <G+k|beta_xi1> Q_{xi1, xi2} <beta_xi2|G+k> contribution from all atoms */
                    auto z = beta_gk_tmp(xi1, ig_loc) * q_sum(xi1, xi2) * std::conj(beta_gk_tmp(xi2, ig_loc));
                    o_diag[ig_loc] += z.real();
                }
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        o_diag.allocate(memory_t::device);
        o_diag.copy_to_device();
    }
    #endif
    return std::move(o_diag);
}
<commit_msg>adopt to new beta class<commit_after>inline mdarray<double, 1>
Band::get_h_diag(K_point* kp__,
                 double v0__,
                 double theta0__) const
{
    // TODO: code is replicated in o_diag
    splindex<block> spl_num_atoms(unit_cell_.num_atoms(), kp__->comm().size(), kp__->comm().rank());
    int nlo{0};
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        nlo += unit_cell_.atom(ia).mt_lo_basis_size();
    }

    mdarray<double, 1> h_diag(kp__->num_gkvec_loc() + nlo);
    for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
        int ig = kp__->gkvec().gvec_offset(kp__->comm().rank()) + igloc;

        double ekin = 0.5 * (kp__->gkvec().gkvec_cart(ig) * kp__->gkvec().gkvec_cart(ig));
        h_diag[igloc] = v0__ + ekin * theta0__;
    }

    matrix<double_complex> alm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());
    matrix<double_complex> halm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());

    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto& atom = unit_cell_.atom(ia);
        int nmt = atom.mt_aw_basis_size();

        kp__->alm_coeffs_loc().generate(ia, alm);
        apply_hmt_to_apw<spin_block_t::nm>(atom, kp__->num_gkvec_loc(), alm, halm);

        for (int xi = 0; xi < nmt; xi++) {
            for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
                h_diag[igloc] += std::real(std::conj(alm(igloc, xi)) * halm(igloc, xi));
            }
        }
    }

    nlo = 0;
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        auto& atom = unit_cell_.atom(ia);
        auto& type = atom.type();
        for (int ilo = 0; ilo < type.mt_lo_basis_size(); ilo++) {
            int xi_lo = type.mt_aw_basis_size() + ilo;
            /* local orbital indices */
            int lm_lo    = type.indexb(xi_lo).lm;
            int idxrf_lo = type.indexb(xi_lo).idxrf;

            h_diag[kp__->num_gkvec_loc() + nlo] = atom.radial_integrals_sum_L3<spin_block_t::nm>(idxrf_lo, idxrf_lo, gaunt_coefs_->gaunt_vector(lm_lo, lm_lo)).real();
            nlo++;
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        h_diag.allocate(memory_t::device);
        h_diag.copy_to_device();
    }
    #endif
    return std::move(h_diag);
}

inline mdarray<double, 1>
Band::get_o_diag(K_point* kp__,
                 double theta0__) const
{
    splindex<block> spl_num_atoms(unit_cell_.num_atoms(), kp__->comm().size(), kp__->comm().rank());
    int nlo{0};
    for (int ialoc = 0; ialoc < spl_num_atoms.local_size(); ialoc++) {
        int ia = spl_num_atoms[ialoc];
        nlo += unit_cell_.atom(ia).mt_lo_basis_size();
    }

    mdarray<double, 1> o_diag(kp__->num_gkvec_loc() + nlo);
    for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
        o_diag[igloc] = theta0__;
    }
    for (size_t i = kp__->num_gkvec_loc(); i < o_diag.size(); i++) {
        o_diag[i] = 1;
    }

    matrix<double_complex> alm(kp__->num_gkvec_loc(), unit_cell_.max_mt_aw_basis_size());

    for (int ia = 0; ia < unit_cell_.num_atoms(); ia++) {
        auto& atom = unit_cell_.atom(ia);
        int nmt = atom.mt_aw_basis_size();

        kp__->alm_coeffs_loc().generate(ia, alm);

        for (int xi = 0; xi < nmt; xi++) {
            for (int igloc = 0; igloc < kp__->num_gkvec_loc(); igloc++) {
                o_diag[igloc] += std::real(std::conj(alm(igloc, xi)) * alm(igloc, xi));
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        o_diag.allocate(memory_t::device);
        o_diag.copy_to_device();
    }
    #endif
    return std::move(o_diag);
}

template <typename T>
inline mdarray<double, 1>
Band::get_h_diag(K_point* kp__,
                 int ispn__,
                 double v0__,
                 D_operator<T>& d_op__) const
{
    PROFILE("sirius::Band::get_h_diag");

    mdarray<double, 1> h_diag(kp__->num_gkvec_loc());

    /* local H contribution */
    for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
        int ig = kp__->igk_loc(ig_loc);
        auto vgk = kp__->gkvec().gkvec_cart(ig);
        h_diag[ig_loc] = 0.5 * (vgk * vgk) + v0__;
    }

    /* non-local H contribution */
    auto& beta_gk_t = kp__->beta_projectors().pw_coeffs_t(0);
    matrix<double_complex> beta_gk_tmp(unit_cell_.max_mt_basis_size(), kp__->num_gkvec_loc());

    for (int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
        auto& atom_type = unit_cell_.atom_type(iat);
        int nbf = atom_type.mt_basis_size();
        matrix<double_complex> d_sum(nbf, nbf);
        d_sum.zero();

        for (int i = 0; i < atom_type.num_atoms(); i++) {
            int ia = atom_type.atom_id(i);

            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    d_sum(xi1, xi2) += d_op__(xi1, xi2, ispn__, ia);
                }
            }
        }

        int offs = unit_cell_.atom_type(iat).offset_lo();
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi = 0; xi < nbf; xi++) {
                beta_gk_tmp(xi, ig_loc) = beta_gk_t(ig_loc, offs + xi);
            }
        }

        #pragma omp parallel for schedule(static)
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    /* compute <G+k|beta_xi1> D_{xi1, xi2} <beta_xi2|G+k> contribution from all atoms */
                    auto z = beta_gk_tmp(xi1, ig_loc) * d_sum(xi1, xi2) * std::conj(beta_gk_tmp(xi2, ig_loc));
                    h_diag[ig_loc] += z.real();
                }
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        h_diag.allocate(memory_t::device);
        h_diag.copy_to_device();
    }
    #endif
    return std::move(h_diag);
}

template <typename T>
inline mdarray<double, 1>
Band::get_o_diag(K_point* kp__,
                 Q_operator<T>& q_op__) const
{
    PROFILE("sirius::Band::get_o_diag");

    mdarray<double, 1> o_diag(kp__->num_gkvec_loc());
    for (int ig = 0; ig < kp__->num_gkvec_loc(); ig++) {
        o_diag[ig] = 1;
    }

    /* non-local O contribution */
    auto& beta_gk_t = kp__->beta_projectors().pw_coeffs_t(0);
    matrix<double_complex> beta_gk_tmp(unit_cell_.max_mt_basis_size(), kp__->num_gkvec_loc());

    for (int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
        auto& atom_type = unit_cell_.atom_type(iat);
        if (!atom_type.pp_desc().augment) {
            continue;
        }

        int nbf = atom_type.mt_basis_size();

        matrix<double_complex> q_sum(nbf, nbf);
        q_sum.zero();

        for (int i = 0; i < atom_type.num_atoms(); i++) {
            int ia = atom_type.atom_id(i);

            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    q_sum(xi1, xi2) += q_op__(xi1, xi2, ia);
                }
            }
        }

        int offs = unit_cell_.atom_type(iat).offset_lo();
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi = 0; xi < nbf; xi++) {
                beta_gk_tmp(xi, ig_loc) = beta_gk_t(ig_loc, offs + xi);
            }
        }

        #pragma omp parallel for
        for (int ig_loc = 0; ig_loc < kp__->num_gkvec_loc(); ig_loc++) {
            for (int xi2 = 0; xi2 < nbf; xi2++) {
                for (int xi1 = 0; xi1 < nbf; xi1++) {
                    /* compute <G+k|beta_xi1> Q_{xi1, xi2} <beta_xi2|G+k> contribution from all atoms */
                    auto z = beta_gk_tmp(xi1, ig_loc) * q_sum(xi1, xi2) * std::conj(beta_gk_tmp(xi2, ig_loc));
                    o_diag[ig_loc] += z.real();
                }
            }
        }
    }
    #ifdef __GPU
    if (ctx_.processing_unit() == GPU) {
        o_diag.allocate(memory_t::device);
        o_diag.copy_to_device();
    }
    #endif
    return std::move(o_diag);
}
<|endoftext|>


<commit_before>#include "player.h"

Pacman::Pacman()
{
	MobileObject::MobileObject();
	x = 0;
	y = 0;
	boundX = 0;
	boundY = 0;
	velocity = 1;

	image = NULL;
};

void Pacman::Init(float x, float y, int boundX,  int boundY, int velocity, float lives, ALLEGRO_BITMAP *image)
{
	MobileObject::Init(x, y, boundX, boundY, image);

	Pacman::velocity = velocity;
	Pacman::lives = lives;

	maxFrame = 6;
	curFrame = 0;
	frameCount = 0;								//depends on sprite NEED TO BE FILLED WITH CORRECT VALUES
	frameDelay = 3;
	frameWidth = 32;
	frameHeight = 32;
	animationColumns = 6;

	Pacman::image = image;
}

void Pacman::Movement(bool *keys)
{
	if(keys[UP]) MobileObject::MoveUp();
	else if(keys[DOWN]) MobileObject::MoveDown();
	else if(keys[LEFT]) MobileObject::MoveLeft();
	else if(keys[RIGHT]) MobileObject::MoveRight();
}

void Pacman::Destroy()
{
	MobileObject::Destroy();

}
void Pacman::Update(bool *keys)
{
	Pacman::Movement(keys);

	if(++frameCount >= frameDelay)
	{
		curFrame ++;
		if(curFrame >= maxFrame)
			curFrame = 0;
		else if(curFrame <= 0)
			curFrame = maxFrame;

		frameCount = 0;
	}
	if(Pacman::x < 0)
		Pacman::x = WIDTH - 1;
	else if(Pacman::x > WIDTH)
		Pacman::x = 1;

}
void Pacman::Render()
{

	MobileObject::Render();

	int fx = (curFrame % animationColumns) * frameWidth;
	int fy = (curFrame / animationColumns) * frameHeight;

	al_draw_bitmap_region(image, fx, fy, frameWidth, frameHeight, x - frameWidth / 2, y - frameHeight / 2, 0);
}

void Pacman::Collided(int ObjectID)
{

}<commit_msg>Changed the drawing function for Pacman<commit_after>#include "player.h"

Pacman::Pacman()
{
	MobileObject::MobileObject();
	x = 0;
	y = 0;
	boundX = 0;
	boundY = 0;
	velocity = 1;

	image = NULL;
};

void Pacman::Init(float x, float y, int boundX,  int boundY, int velocity, float lives, ALLEGRO_BITMAP *image)
{
	MobileObject::Init(x, y, boundX, boundY, image);

	Pacman::velocity = velocity;
	Pacman::lives = lives;

	maxFrame = 6;
	curFrame = 0;
	frameCount = 0;								//depends on sprite NEED TO BE FILLED WITH CORRECT VALUES
	frameDelay = 3;
	frameWidth = 32;
	frameHeight = 32;
	animationColumns = 6;

	Pacman::image = image;
}

void Pacman::Movement(bool *keys)
{
	if(keys[UP]) MobileObject::MoveUp();
	else if(keys[DOWN]) MobileObject::MoveDown();
	else if(keys[LEFT]) MobileObject::MoveLeft();
	else if(keys[RIGHT]) MobileObject::MoveRight();
}

void Pacman::Destroy()
{
	MobileObject::Destroy();

}
void Pacman::Update(bool *keys)
{
	Pacman::Movement(keys);

	if(++frameCount >= frameDelay)
	{
		curFrame ++;
		if(curFrame >= maxFrame)
			curFrame = 0;
		else if(curFrame <= 0)
			curFrame = maxFrame;

		frameCount = 0;
	}
	if(Pacman::x < 0)
		Pacman::x = WIDTH - 1;
	else if(Pacman::x > WIDTH)
		Pacman::x = 1;

}
void Pacman::Render()
{

	MobileObject::Render();

	int fx = (curFrame % animationColumns) * frameWidth;
	int fy = (curFrame / animationColumns) * frameHeight;

	al_draw_tinted_scaled_rotated_bitmap_region(image, fx, fy, frameWidth, frameHeight,
		al_map_rgba_f(1, 1, 1, 1.0), frameWidth / 2, frameHeight / 2, x - frameWidth / 2,
		y - frameHeight / 2, 1, 1, 0, 0); //TBI: rotating pacman depending on what dir is he moving to
										  // can be done by changing the penultimate argument to smth like
										  // ALLEGRO_PI / 2, u can try it out yourself

	//al_draw_bitmap_region(image, fx, fy, frameWidth, frameHeight, x - frameWidth / 2, y - frameHeight / 2, 0);
}

void Pacman::Collided(int ObjectID)
{

}<|endoftext|>


<commit_before>#include "pch.h"
#include "axl_mt_TlsMgr.h"

namespace axl {
namespace mt {

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

bool CTlsMgr::m_IsDead = false;

CTlsMgr::CTlsMgr ()
{
	m_TlsIdx = TlsAlloc ();
	m_SlotCount = 0;
}

CTlsMgr::~CTlsMgr ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
	{
		AXL_MEM_DELETE (pPage);
		SetCurrentThreadPage (NULL);
	}

	TlsFree (m_TlsIdx);
	s_IsDead = true;
}

void
NTAPI
CTlsMgr::TlsCallback (
	HANDLE hModule,
	dword_t Reason,
	void* pReserved
	)
{
	if (Reason != DLL_THREAD_DETACH || m_IsDead)
		return;

	CTlsMgr* pThis = GetTlsMgr ();

	TPage* pPage = pThis->FindCurrentThreadPage ();
	if (!pPage)
		return;

	AXL_MEM_DELETE (pPage);

	TlsSetValue (pThis->m_TlsIdx, NULL);
}

#elif (_AXL_ENV == AXL_ENV_POSIX)

CTlsMgr::CTlsMgr ()
{
	pthread_key_create (&m_TlsKey, TlsDestructor);
	m_SlotCount = 0;
}

CTlsMgr::~CTlsMgr ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
	{
		AXL_MEM_DELETE (pPage);
		SetCurrentThreadPage (NULL);
	}

	pthread_key_delete (m_TlsKey);
}

#endif

CTlsValue
CTlsMgr::GetSlotValue (size_t Slot)
{
	TPage* pPage = FindCurrentThreadPage ();
	if (!pPage)
		return ref::EPtr_Null;

	size_t Count = pPage->m_Array.GetCount ();
	if (Slot >= Count)
		return ref::EPtr_Null;

	rtl::CBoxListEntryT <CTlsValue>* pEntry = pPage->m_Array [Slot];
	if (!pEntry)
		return ref::EPtr_Null;

	return pEntry->m_Value;
}

CTlsValue
CTlsMgr::SetSlotValue (
	size_t Slot,
	const CTlsValue& Value
	)
{
	TPage* pPage = GetCurrentThreadPage ();

	size_t Count = pPage->m_Array.GetCount ();
	if (Slot >= Count)
	{
		if (!Value)
			return CTlsValue ();

		pPage->m_Array.SetCount (Slot + 1);
	}

	rtl::CBoxListEntryT <CTlsValue>* pEntry = pPage->m_Array [Slot];

	CTlsValue OldValue;

	if (pEntry)
	{
		OldValue = pEntry->m_Value;

		if (Value)
		{
			pEntry->m_Value = Value;
		}
		else
		{
			pPage->m_ValueList.Remove (pEntry);
			pPage->m_Array [Slot] = NULL;
		}
	}
	else if (Value)
	{
		pEntry = pPage->m_ValueList.InsertTail (Value).GetEntry ();
		pPage->m_Array [Slot] = pEntry;
	}

	return OldValue;
}

CTlsMgr::TPage*
CTlsMgr::GetCurrentThreadPage ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
		return pPage;

	pPage = AXL_MEM_NEW (TPage);
	SetCurrentThreadPage (pPage);
	return pPage;
}

//.............................................................................

} // namespace mt
} // namespace axl

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

#pragma section (AXL_MT_TLS_CALLBACK_SECTION, long, read)

extern "C"
__declspec(allocate (AXL_MT_TLS_CALLBACK_SECTION))
PIMAGE_TLS_CALLBACK g_axl_mt_pfTlsCallback = axl::mt::CTlsMgr::TlsCallback;

#ifdef _WIN64
#	pragma comment (linker, "/INCLUDE:_tls_used")
#	pragma comment (linker, "/INCLUDE:g_axl_mt_pfTlsCallback")
#else
#	pragma comment (linker, "/INCLUDE:__tls_used")
#	pragma comment (linker, "/INCLUDE:_g_axl_mt_pfTlsCallback")
#endif

#endif

//.............................................................................

<commit_msg>[axl.mt] typo in tls-mgr<commit_after>#include "pch.h"
#include "axl_mt_TlsMgr.h"

namespace axl {
namespace mt {

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

bool CTlsMgr::m_IsDead = false;

CTlsMgr::CTlsMgr ()
{
	m_TlsIdx = TlsAlloc ();
	m_SlotCount = 0;
}

CTlsMgr::~CTlsMgr ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
	{
		AXL_MEM_DELETE (pPage);
		SetCurrentThreadPage (NULL);
	}

	TlsFree (m_TlsIdx);
	m_IsDead = true;
}

void
NTAPI
CTlsMgr::TlsCallback (
	HANDLE hModule,
	dword_t Reason,
	void* pReserved
	)
{
	if (Reason != DLL_THREAD_DETACH || m_IsDead)
		return;

	CTlsMgr* pThis = GetTlsMgr ();

	TPage* pPage = pThis->FindCurrentThreadPage ();
	if (!pPage)
		return;

	AXL_MEM_DELETE (pPage);

	TlsSetValue (pThis->m_TlsIdx, NULL);
}

#elif (_AXL_ENV == AXL_ENV_POSIX)

CTlsMgr::CTlsMgr ()
{
	pthread_key_create (&m_TlsKey, TlsDestructor);
	m_SlotCount = 0;
}

CTlsMgr::~CTlsMgr ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
	{
		AXL_MEM_DELETE (pPage);
		SetCurrentThreadPage (NULL);
	}

	pthread_key_delete (m_TlsKey);
}

#endif

CTlsValue
CTlsMgr::GetSlotValue (size_t Slot)
{
	TPage* pPage = FindCurrentThreadPage ();
	if (!pPage)
		return ref::EPtr_Null;

	size_t Count = pPage->m_Array.GetCount ();
	if (Slot >= Count)
		return ref::EPtr_Null;

	rtl::CBoxListEntryT <CTlsValue>* pEntry = pPage->m_Array [Slot];
	if (!pEntry)
		return ref::EPtr_Null;

	return pEntry->m_Value;
}

CTlsValue
CTlsMgr::SetSlotValue (
	size_t Slot,
	const CTlsValue& Value
	)
{
	TPage* pPage = GetCurrentThreadPage ();

	size_t Count = pPage->m_Array.GetCount ();
	if (Slot >= Count)
	{
		if (!Value)
			return CTlsValue ();

		pPage->m_Array.SetCount (Slot + 1);
	}

	rtl::CBoxListEntryT <CTlsValue>* pEntry = pPage->m_Array [Slot];

	CTlsValue OldValue;

	if (pEntry)
	{
		OldValue = pEntry->m_Value;

		if (Value)
		{
			pEntry->m_Value = Value;
		}
		else
		{
			pPage->m_ValueList.Remove (pEntry);
			pPage->m_Array [Slot] = NULL;
		}
	}
	else if (Value)
	{
		pEntry = pPage->m_ValueList.InsertTail (Value).GetEntry ();
		pPage->m_Array [Slot] = pEntry;
	}

	return OldValue;
}

CTlsMgr::TPage*
CTlsMgr::GetCurrentThreadPage ()
{
	TPage* pPage = FindCurrentThreadPage ();
	if (pPage)
		return pPage;

	pPage = AXL_MEM_NEW (TPage);
	SetCurrentThreadPage (pPage);
	return pPage;
}

//.............................................................................

} // namespace mt
} // namespace axl

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

#pragma section (AXL_MT_TLS_CALLBACK_SECTION, long, read)

extern "C"
__declspec(allocate (AXL_MT_TLS_CALLBACK_SECTION))
PIMAGE_TLS_CALLBACK g_axl_mt_pfTlsCallback = axl::mt::CTlsMgr::TlsCallback;

#ifdef _WIN64
#	pragma comment (linker, "/INCLUDE:_tls_used")
#	pragma comment (linker, "/INCLUDE:g_axl_mt_pfTlsCallback")
#else
#	pragma comment (linker, "/INCLUDE:__tls_used")
#	pragma comment (linker, "/INCLUDE:_g_axl_mt_pfTlsCallback")
#endif

#endif

//.............................................................................

<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <vector>

namespace gtl {
#define SQR(x) pow((double)x, 2.0)

#if defined(min) || defined(max)
#error Error: min or max are defined as preprocessor macros, probably in <windows.h>.  Define NOMINMAX macro before including any system headers!
#if !defined(NOMINMAX)
#define NOMINMAX
#endif
#endif

// useful constants
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif

#define EPS std::numeric_limits<Type>::epsilon()

    //! Convert a_value from degrees to radians.
    template <typename Type>
    Type DegToRad(Type a)
    {
        return (Type)(a * 0.01745329251994);
    }

    //!  Convert a_value from radians to degrees.
    template <typename Type>
    Type RadToDeg(Type a)
    {
        return (Type)(a * 57.2957795130823);
    }

    template <typename Type>
    inline const Type& min3(const Type& a, const Type& b, const Type& c)
    {
        return std::min(std::min(a, b), c);
    }

    template <typename Type>
    inline const Type& max3(const Type& a, const Type& b, const Type& c)
    {
        return std::max(std::max(a, b), c);
    }

    template <typename Type>
    inline void clamp(const Type& min, Type& value, const Type& max)
    {
        value = (value < min) ? min : (value > max) ? max : value;
    }

    template <typename Type>
    inline Type rand(const Type min, const Type max)
    {
        return (std::rand() / (Type)RAND_MAX) * (max - min) + min;
    }

    template <typename Type>
    inline Type sign(Type a)
    {
        return (a >= (Type)0.0) ? (Type)1.0 : (Type)-1.0;
    }

    template <typename Type>
    inline bool equals(const Type& a, const Type& b, Type eps = std::numeric_limits<Type>::epsilon())
    {
        return (std::abs(a - b) < eps);
    }

    inline bool isPowerOfTwo(int value)
    {
        return (value & (value - 1)) == 0;
    }

    inline int nearestPowerOfTwo(int value)
    {
        int vlog = (int)(log((float)value) * 1.4427f);

        return (int)pow(2.f, (float)vlog);
    }

} // namespace gtl
<commit_msg>Use constepr for clamp<commit_after>#pragma once

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <vector>

namespace gtl {
#define SQR(x) pow((double)x, 2.0)

#if defined(min) || defined(max)
#error Error: min or max are defined as preprocessor macros, probably in <windows.h>.  Define NOMINMAX macro before including any system headers!
#if !defined(NOMINMAX)
#define NOMINMAX
#endif
#endif

// useful constants
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif

#define EPS std::numeric_limits<Type>::epsilon()

    //! Convert a_value from degrees to radians.
    template <typename Type>
    Type DegToRad(Type a)
    {
        return (Type)(a * 0.01745329251994);
    }

    //!  Convert a_value from radians to degrees.
    template <typename Type>
    Type RadToDeg(Type a)
    {
        return (Type)(a * 57.2957795130823);
    }

    template <typename Type>
    inline const Type& min3(const Type& a, const Type& b, const Type& c)
    {
        return std::min(std::min(a, b), c);
    }

    template <typename Type>
    inline const Type& max3(const Type& a, const Type& b, const Type& c)
    {
        return std::max(std::max(a, b), c);
    }

    template <typename Type>
    constexpr Type clamp(const Type& value, const Type& min, const Type& max)
    {
        return (value < min) ? min : (value > max) ? max : value;
    }

    template <typename Type>
    inline Type rand(const Type min, const Type max)
    {
        return (std::rand() / (Type)RAND_MAX) * (max - min) + min;
    }

    template <typename Type>
    inline Type sign(Type a)
    {
        return (a >= (Type)0.0) ? (Type)1.0 : (Type)-1.0;
    }

    template <typename Type>
    inline bool equals(const Type& a, const Type& b, Type eps = std::numeric_limits<Type>::epsilon())
    {
        return (std::abs(a - b) < eps);
    }

    inline bool isPowerOfTwo(int value)
    {
        return (value & (value - 1)) == 0;
    }

    inline int nearestPowerOfTwo(int value)
    {
        int vlog = (int)(log((float)value) * 1.4427f);

        return (int)pow(2.f, (float)vlog);
    }

} // namespace gtl
<|endoftext|>


<commit_before>#include "Sound.h"
#include <alure/alure.h>
#include <map>
#include "ResourceManager.h"
#include <assert.h>
#include "Engine/Logging.h"

namespace Sound
{

const int CHUNK_LENGTH = 16386;

typedef std::map<std::string, ALuint> BufferMap;
BufferMap sounds;

int soundSourceCount;
ALuint* soundSources;
ALuint musicSource;
ALuint musicBufs[2];
alureStream* currentMusicStream = NULL;
std::string currentMusicName = "";
int soundSourceIndex = 0;

void DieUnpleasantly()
{
	StopMusic();
	alureShutdownDevice();
}

ALubyte* GetSoundData(const std::string& path, size_t& length)
{
	SDL_RWops* rwops = ResourceManager::OpenFile(path + ".aiff");
	if (!rwops)
		rwops = ResourceManager::OpenFile(path + ".ogg");
	if (!rwops)
	{
		length = 0;
		return NULL;
	}
	return (ALubyte*)ResourceManager::ReadFull(&length, rwops, 1);
}

static ALuint GetSound(const std::string& name)
{
	BufferMap::iterator iter = sounds.find(name);
	if (iter != sounds.end())
		return iter->second;
	size_t length;
	ALubyte* data = GetSoundData("Sounds/" + name, length);
	ALuint buf = alureCreateBufferFromMemory(data, length);
	free(data);
	sounds.insert(std::make_pair(name, buf));
	return buf;
}

void Init(int frequency, int resolution, int sources)
{
	(void)resolution;
	--sources; // one spare source for music
	ALCint attribs[] = {
		ALC_FREQUENCY, frequency,
		ALC_MONO_SOURCES, sources,
		ALC_STEREO_SOURCES, 1,
		0
	};
	alureInitDevice(NULL, attribs);
	soundSources = new ALuint[sources];
	alGenSources(sources, soundSources);
	alGenSources(1, &musicSource);
	//alGenBuffers(2, musicBufs);
	soundSourceCount = sources;
	atexit(DieUnpleasantly);
}

static ALuint GetFreeSource()
{
	int idx = soundSourceIndex++;
	soundSourceIndex = soundSourceIndex % soundSourceCount;
	return soundSources[idx];
}

void Preload(const std::string& name)
{
	GetSound(name);
}

void PlaySound(const std::string& name, float gain)
{
	ALuint buf    = GetSound(name);
	ALuint source = GetFreeSource();
	alSourcei(source, AL_BUFFER, buf);
	alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
	alSourcef(source, AL_GAIN, gain);
	alSourcePlay(source);
}

void PlaySoundPositional(const std::string& name, vec2 pos, float gain)
{
	ALfloat fpos[] = {pos.X(), pos.Y(), 0.0f};
	ALuint buf    = GetSound(name);
	ALuint source = GetFreeSource();
	alSourcei(source, AL_BUFFER, buf);
	alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
	alSourcefv(source, AL_POSITION, fpos);
	alSourcef(source, AL_GAIN, gain);
	alSourcePlay(source);
}

static ALfloat forientation[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};

void SetListener(vec2 pos, vec2 vel)
{
	ALfloat fpos[] = {pos.X(), pos.Y(), 0.0f};
	ALfloat fvel[] = {vel.X(), vel.Y(), 0.0f};
	alListenerfv(AL_POSITION, fpos);
	alListenerfv(AL_VELOCITY, fvel);
	if (vel.ModulusSquared() > 0.2f)
	{
		forientation[0] = fvel[0];
		forientation[1] = fvel[1];
	}
	alListenerfv(AL_ORIENTATION, forientation);
}

static void MusicEndCallback(void* ud, ALuint source)
{
	alureDestroyStream(currentMusicStream, 2, musicBufs);
	currentMusicStream = NULL;
	currentMusicName = "";
	free(ud);
}

void PlayMusic(const std::string& name)
{
	if (currentMusicStream)
		alureStopSource(musicSource, AL_TRUE);
	size_t length;
	ALubyte* data = GetSoundData("Music/" + name, length);
	currentMusicName = name;
	currentMusicStream = alureCreateStreamFromStaticMemory(data, length, CHUNK_LENGTH, 2, musicBufs);
	alurePlaySourceStream(musicSource, currentMusicStream, 2, 1, MusicEndCallback, data);
	LOG("Sound", LOG_MESSAGE, "Music: %s", name.c_str());
	if (!data)
		LOG("Sound", LOG_WARNING, "failed to find music");
}

void StopMusic()
{
	if (!currentMusicStream)
		return;
	alureStopSource(musicSource, AL_TRUE);
}

std::string MusicName()
{
	return "";
}

float MusicVolume()
{
	return 1.0f;
}

void SetMusicVolume(float mvol)
{
}

float SoundVolume()
{
	return 1.0f;
}

void SetSoundVolume(float mvol)
{
}

}
<commit_msg>Made OpenAL sound backend respect music volume.<commit_after>#include "Sound.h"
#include <alure/alure.h>
#include <map>
#include "ResourceManager.h"
#include <assert.h>
#include "Engine/Logging.h"

namespace Sound
{

const int CHUNK_LENGTH = 16386;

typedef std::map<std::string, ALuint> BufferMap;
BufferMap sounds;

int soundSourceCount;
ALuint* soundSources;
ALuint musicSource;
ALuint musicBufs[2];
alureStream* currentMusicStream = NULL;
std::string currentMusicName = "";
int soundSourceIndex = 0;

void DieUnpleasantly()
{
	StopMusic();
	alureShutdownDevice();
}

ALubyte* GetSoundData(const std::string& path, size_t& length)
{
	SDL_RWops* rwops = ResourceManager::OpenFile(path + ".aiff");
	if (!rwops)
		rwops = ResourceManager::OpenFile(path + ".ogg");
	if (!rwops)
	{
		length = 0;
		return NULL;
	}
	return (ALubyte*)ResourceManager::ReadFull(&length, rwops, 1);
}

static ALuint GetSound(const std::string& name)
{
	BufferMap::iterator iter = sounds.find(name);
	if (iter != sounds.end())
		return iter->second;
	size_t length;
	ALubyte* data = GetSoundData("Sounds/" + name, length);
	ALuint buf = alureCreateBufferFromMemory(data, length);
	free(data);
	sounds.insert(std::make_pair(name, buf));
	return buf;
}

void Init(int frequency, int resolution, int sources)
{
	(void)resolution;
	--sources; // one spare source for music
	ALCint attribs[] = {
		ALC_FREQUENCY, frequency,
		ALC_MONO_SOURCES, sources,
		ALC_STEREO_SOURCES, 1,
		0
	};
	alureInitDevice(NULL, attribs);
	soundSources = new ALuint[sources];
	alGenSources(sources, soundSources);
	alGenSources(1, &musicSource);
	//alGenBuffers(2, musicBufs);
	soundSourceCount = sources;
	atexit(DieUnpleasantly);
}

static ALuint GetFreeSource()
{
	int idx = soundSourceIndex++;
	soundSourceIndex = soundSourceIndex % soundSourceCount;
	return soundSources[idx];
}

void Preload(const std::string& name)
{
	GetSound(name);
}

void PlaySound(const std::string& name, float gain)
{
	ALuint buf    = GetSound(name);
	ALuint source = GetFreeSource();
	alSourcei(source, AL_BUFFER, buf);
	alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
	alSourcef(source, AL_GAIN, gain);
	alSourcePlay(source);
}

void PlaySoundPositional(const std::string& name, vec2 pos, float gain)
{
	ALfloat fpos[] = {pos.X(), pos.Y(), 0.0f};
	ALuint buf    = GetSound(name);
	ALuint source = GetFreeSource();
	alSourcei(source, AL_BUFFER, buf);
	alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
	alSourcefv(source, AL_POSITION, fpos);
	alSourcef(source, AL_GAIN, gain);
	alSourcePlay(source);
}

static ALfloat forientation[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};

void SetListener(vec2 pos, vec2 vel)
{
	ALfloat fpos[] = {pos.X(), pos.Y(), 0.0f};
	ALfloat fvel[] = {vel.X(), vel.Y(), 0.0f};
	alListenerfv(AL_POSITION, fpos);
	alListenerfv(AL_VELOCITY, fvel);
	if (vel.ModulusSquared() > 0.2f)
	{
		forientation[0] = fvel[0];
		forientation[1] = fvel[1];
	}
	alListenerfv(AL_ORIENTATION, forientation);
}

static void MusicEndCallback(void* ud, ALuint source)
{
	alureDestroyStream(currentMusicStream, 2, musicBufs);
	currentMusicStream = NULL;
	currentMusicName = "";
	free(ud);
}

void PlayMusic(const std::string& name)
{
	if (currentMusicStream)
		alureStopSource(musicSource, AL_TRUE);
	size_t length;
	ALubyte* data = GetSoundData("Music/" + name, length);
	currentMusicName = name;
	currentMusicStream = alureCreateStreamFromStaticMemory(data, length, CHUNK_LENGTH, 2, musicBufs);
	alurePlaySourceStream(musicSource, currentMusicStream, 2, 1, MusicEndCallback, data);
	LOG("Sound", LOG_MESSAGE, "Music: %s", name.c_str());
	if (!data)
		LOG("Sound", LOG_WARNING, "failed to find music");
}

void StopMusic()
{
	if (!currentMusicStream)
		return;
	alureStopSource(musicSource, AL_TRUE);
}

std::string MusicName()
{
	return "";
}

float MusicVolume()
{
	ALfloat rv;
	alGetSourcefv(musicSource, AL_GAIN, &rv);
	return rv;
}

void SetMusicVolume(float mvol)
{
	alSourcef(musicSource, AL_GAIN, mvol);
}

float SoundVolume()
{
	return 1.0f;
}

void SetSoundVolume(float mvol)
{
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2021 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <functional>
#include <string>
#ifdef _WIN32
  #include <windows.h>
#else
  #include <stdio.h>
#endif
#include <subhook.h>
#include "amxpathfinder.h"
#include "crashdetect.h"
#include "fileutils.h"
#include "logprintf.h"
#include "natives.h"
#include "options.h"
#include "os.h"
#include "plugincommon.h"
#include "pluginversion.h"
#include "stringutils.h"

namespace {

std::vector<std::function<void()>> unload_callbacks;

subhook::Hook exec_hook;
subhook::Hook open_file_hook;
std::string last_opened_amx_file_name;

#ifdef _WIN32
  HANDLE WINAPI CreateFileAHook(
    LPCSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile)
  {
    subhook::ScopedHookRemove _(&open_file_hook);
    const char *ext = fileutils::GetFileExtensionPtr(lpFileName);
    if (ext != nullptr && stringutils::CompareIgnoreCase(ext, "amx") == 0) {
      last_opened_amx_file_name = lpFileName;
    }
    return CreateFileA(
      lpFileName,
      dwDesiredAccess,
      dwShareMode,
      lpSecurityAttributes,
      dwCreationDisposition,
      dwFlagsAndAttributes,
      hTemplateFile);
  }
#else
  FILE *FopenHook(const char *filename, const char *mode) {
    subhook::ScopedHookRemove _(&open_file_hook);
    const char *ext = fileutils::GetFileExtensionPtr(filename);
    if (ext != nullptr && stringutils::CompareIgnoreCase(ext, "amx") == 0) {
      last_opened_amx_file_name = filename;
    }
    return fopen(filename, mode);
  }
#endif

int AMXAPI OnDebugHook(AMX *amx) {
  return CrashDetect::GetHandler(amx)->OnDebugHook();
}

int AMXAPI OnCallback(AMX *amx, cell index, cell *result, cell *params) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnCallback(index, result, params);
}

int AMXAPI OnExec(AMX *amx, cell *retval, int index) {
  if (amx->flags & AMX_FLAG_BROWSE) {
    return amx_Exec(amx, retval, index);
  }
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  if (handler == nullptr) {
    return amx_Exec(amx, retval, index);
  }
  return handler->OnExec(retval, index);
}

int AMXAPI OnExecError(AMX *amx, cell index, cell *retval, int error) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnExecError(index, retval, error);
}

int AMXAPI OnLongCallRequest(AMX *amx, int option, int value) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnLongCallRequest(option, value);
}

} // anonymous namespace

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
  return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
  void **exports = reinterpret_cast<void**>(ppData[PLUGIN_DATA_AMX_EXPORTS]);
  ::logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];

  void *amx_Exec_ptr = exports[PLUGIN_AMX_EXPORT_Exec];
  void *amx_Exec_sub = subhook::ReadHookDst(amx_Exec_ptr);

  if (amx_Exec_sub == nullptr) {
    exec_hook.Install(amx_Exec_ptr, (void*)OnExec);
    unload_callbacks.push_back([]() {
      exec_hook.Remove();
    });
  } else {
    std::string module =
      fileutils::GetFileName(os::GetModuleName(amx_Exec_sub));
    if (!module.empty()) {
      logprintf("  CrashDetect must be loaded before '%s'", module.c_str());
    }
    return false;
  }

  #if _WIN32
    open_file_hook.Install((void*)CreateFileA, (void*)CreateFileAHook);
  #else
    open_file_hook.Install((void*)fopen, (void*)FopenHook);
  #endif
  unload_callbacks.push_back([]() {
    open_file_hook.Remove();
  });

  AMXPathFinder::shared().AddSearchPath("gamemodes");
  AMXPathFinder::shared().AddSearchPath("filterscripts");

  const char *amx_path_var = getenv("AMX_PATH");
  if (amx_path_var != nullptr) {
    stringutils::SplitString(
      amx_path_var,
      fileutils::kNativePathListSepChar,
      std::bind1st(std::mem_fun(&AMXPathFinder::AddSearchPath),
                   &AMXPathFinder::shared()));
  }

  os::SetCrashHandler(CrashDetect::OnCrash);
  os::SetInterruptHandler(CrashDetect::OnInterrupt);
  CrashDetect::PluginLoad();

  logprintf("  CrashDetect plugin " PLUGIN_VERSION_STRING);
  return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
  CrashDetect::PluginUnload();

  for (auto &callback : unload_callbacks) {
    callback();
  }
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
  if (!last_opened_amx_file_name.empty()) {
    AMXPathFinder::shared().AddKnownFile(amx, last_opened_amx_file_name);
  }

  CrashDetect *handler = CrashDetect::CreateHandler(amx);
  handler->Load();

  amx_SetDebugHook(amx, OnDebugHook);
  amx_SetCallback(amx, OnCallback);

  static AMX_EXT_HOOKS ext_hooks = {
    OnExecError,
    OnLongCallRequest
  };
  amx_SetExtHooks(amx, &ext_hooks);

  RegisterNatives(amx);
  return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) {
  CrashDetect::GetHandler(amx)->Unload();
  CrashDetect::DestroyHandler(amx);
  return AMX_ERR_NONE;
}
<commit_msg>Initialise `address_naught`.<commit_after>// Copyright (c) 2011-2021 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <functional>
#include <string>
#ifdef _WIN32
  #include <windows.h>
#else
  #include <stdio.h>
#endif
#include <subhook.h>
#include "amxpathfinder.h"
#include "crashdetect.h"
#include "fileutils.h"
#include "logprintf.h"
#include "natives.h"
#include "options.h"
#include "os.h"
#include "plugincommon.h"
#include "pluginversion.h"
#include "stringutils.h"

namespace {

std::vector<std::function<void()>> unload_callbacks;

subhook::Hook exec_hook;
subhook::Hook open_file_hook;
std::string last_opened_amx_file_name;

#ifdef _WIN32
  HANDLE WINAPI CreateFileAHook(
    LPCSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile)
  {
    subhook::ScopedHookRemove _(&open_file_hook);
    const char *ext = fileutils::GetFileExtensionPtr(lpFileName);
    if (ext != nullptr && stringutils::CompareIgnoreCase(ext, "amx") == 0) {
      last_opened_amx_file_name = lpFileName;
    }
    return CreateFileA(
      lpFileName,
      dwDesiredAccess,
      dwShareMode,
      lpSecurityAttributes,
      dwCreationDisposition,
      dwFlagsAndAttributes,
      hTemplateFile);
  }
#else
  FILE *FopenHook(const char *filename, const char *mode) {
    subhook::ScopedHookRemove _(&open_file_hook);
    const char *ext = fileutils::GetFileExtensionPtr(filename);
    if (ext != nullptr && stringutils::CompareIgnoreCase(ext, "amx") == 0) {
      last_opened_amx_file_name = filename;
    }
    return fopen(filename, mode);
  }
#endif

int AMXAPI OnDebugHook(AMX *amx) {
  return CrashDetect::GetHandler(amx)->OnDebugHook();
}

int AMXAPI OnCallback(AMX *amx, cell index, cell *result, cell *params) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnCallback(index, result, params);
}

int AMXAPI OnExec(AMX *amx, cell *retval, int index) {
  if (amx->flags & AMX_FLAG_BROWSE) {
    return amx_Exec(amx, retval, index);
  }
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  if (handler == nullptr) {
    return amx_Exec(amx, retval, index);
  }
  return handler->OnExec(retval, index);
}

int AMXAPI OnExecError(AMX *amx, cell index, cell *retval, int error) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnExecError(index, retval, error);
}

int AMXAPI OnLongCallRequest(AMX *amx, int option, int value) {
  CrashDetect *handler = CrashDetect::GetHandler(amx);
  return handler->OnLongCallRequest(option, value);
}

} // anonymous namespace

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
  return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
  void **exports = reinterpret_cast<void**>(ppData[PLUGIN_DATA_AMX_EXPORTS]);
  ::logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];

  void *amx_Exec_ptr = exports[PLUGIN_AMX_EXPORT_Exec];
  void *amx_Exec_sub = subhook::ReadHookDst(amx_Exec_ptr);

  if (amx_Exec_sub == nullptr) {
    exec_hook.Install(amx_Exec_ptr, (void*)OnExec);
    unload_callbacks.push_back([]() {
      exec_hook.Remove();
    });
  } else {
    std::string module =
      fileutils::GetFileName(os::GetModuleName(amx_Exec_sub));
    if (!module.empty()) {
      logprintf("  CrashDetect must be loaded before '%s'", module.c_str());
    }
    return false;
  }

  #if _WIN32
    open_file_hook.Install((void*)CreateFileA, (void*)CreateFileAHook);
  #else
    open_file_hook.Install((void*)fopen, (void*)FopenHook);
  #endif
  unload_callbacks.push_back([]() {
    open_file_hook.Remove();
  });

  AMXPathFinder::shared().AddSearchPath("gamemodes");
  AMXPathFinder::shared().AddSearchPath("filterscripts");

  const char *amx_path_var = getenv("AMX_PATH");
  if (amx_path_var != nullptr) {
    stringutils::SplitString(
      amx_path_var,
      fileutils::kNativePathListSepChar,
      std::bind1st(std::mem_fun(&AMXPathFinder::AddSearchPath),
                   &AMXPathFinder::shared()));
  }

  os::SetCrashHandler(CrashDetect::OnCrash);
  os::SetInterruptHandler(CrashDetect::OnInterrupt);
  CrashDetect::PluginLoad();

  logprintf("  CrashDetect plugin " PLUGIN_VERSION_STRING);
  return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
  CrashDetect::PluginUnload();

  for (auto &callback : unload_callbacks) {
    callback();
  }
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
  if (!last_opened_amx_file_name.empty()) {
    AMXPathFinder::shared().AddKnownFile(amx, last_opened_amx_file_name);
  }

  CrashDetect *handler = CrashDetect::CreateHandler(amx);
  handler->Load();

  amx_SetDebugHook(amx, OnDebugHook);
  amx_SetCallback(amx, OnCallback);

  static AMX_EXT_HOOKS ext_hooks = {
    OnExecError,
    OnLongCallRequest,
    0
  };
  amx_SetExtHooks(amx, &ext_hooks);

  RegisterNatives(amx);
  return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) {
  CrashDetect::GetHandler(amx)->Unload();
  CrashDetect::DestroyHandler(amx);
  return AMX_ERR_NONE;
}
<|endoftext|>


<commit_before>//
// Created by clonker on 07.03.16.
//

#include <readdy/model/Kernel.h>
#include <readdy/plugin/KernelProvider.h>
#include <boost/algorithm/string/predicate.hpp>
#include "gtest/gtest.h"

namespace plug = readdy::plugin;

namespace {
    TEST(Kernel, LoadingNonexistingPlugin) {
        plug::KernelProvider::getInstance().add("foo", [] {return new readdy::model::Kernel("foo");});
        try {
            plug::KernelProvider::getInstance().create("foo2");
            FAIL() << "Expected NoSuchPluginException!";
        } catch (plug::NoSuchPluginException const &ex) {
            SUCCEED() << "NoSuchPluginException caught.";
        } catch (...) {
            FAIL() << "Expected NoSuchPluginException!";
        }
    }

    TEST(Kernel, LoadingExistingPlugin) {
        plug::KernelProvider::getInstance().add("bar", [] {return new readdy::model::Kernel("bar");});
        auto kk_ptr = plug::KernelProvider::getInstance().create("bar");
        EXPECT_STREQ("bar", kk_ptr.get()->getName().c_str());
    }

    TEST(KernelProvider, SanityCheckDefaultDirectory) {
        std::string defaultDirectory = plug::KernelProvider::getInstance().getDefaultKernelDirectory();
        BOOST_LOG_TRIVIAL(debug) << "default directory is " << defaultDirectory;
        SUCCEED();
    }

    TEST(KernelProvider, TestLoadPluginsFromDirectory) {
        // if we're in conda
        const char *env = std::getenv("CONDA_ENV_PATH");
        std::string pluginDir = "lib/readdy_plugins";
        if (env) {
            auto _env = std::string(env);
            if (!boost::algorithm::ends_with(env, "/")) {
                _env = _env.append("/");
            }
            pluginDir = _env.append(pluginDir);
        }
        plug::KernelProvider::getInstance().loadKernelsFromDirectory(pluginDir);
        BOOST_LOG_TRIVIAL(debug) << "current path: " << boost::filesystem::current_path().string();
    }

    TEST(KernelProvider, TestFoo) {
        auto k = plug::KernelProvider::getInstance().create("SingleCPU");
        auto name = k.get()->getName();
        BOOST_LOG_TRIVIAL(debug) << "foo name: " << name;
    }

    TEST(KernelProvider, TestTestProgram) {
        auto single_cpu_kernel = plug::KernelProvider::getInstance().create("SingleCPU");
        auto test_program = single_cpu_kernel.get()->createProgram("TestProgram");
        test_program.get()->execute();
    }
}
<commit_msg>[tests] fix loading plugins from directory test<commit_after>//
// Created by clonker on 07.03.16.
//

#include <readdy/model/Kernel.h>
#include <readdy/plugin/KernelProvider.h>
#include <boost/algorithm/string/predicate.hpp>
#include "gtest/gtest.h"

namespace plug = readdy::plugin;

namespace {
    TEST(Kernel, LoadingNonexistingPlugin) {
        plug::KernelProvider::getInstance().add("foo", [] {return new readdy::model::Kernel("foo");});
        try {
            plug::KernelProvider::getInstance().create("foo2");
            FAIL() << "Expected NoSuchPluginException!";
        } catch (plug::NoSuchPluginException const &ex) {
            SUCCEED() << "NoSuchPluginException caught.";
        } catch (...) {
            FAIL() << "Expected NoSuchPluginException!";
        }
    }

    TEST(Kernel, LoadingExistingPlugin) {
        plug::KernelProvider::getInstance().add("bar", [] {return new readdy::model::Kernel("bar");});
        auto kk_ptr = plug::KernelProvider::getInstance().create("bar");
        EXPECT_STREQ("bar", kk_ptr.get()->getName().c_str());
    }

    TEST(KernelProvider, SanityCheckDefaultDirectory) {
        std::string defaultDirectory = plug::KernelProvider::getInstance().getDefaultKernelDirectory();
        BOOST_LOG_TRIVIAL(debug) << "default directory is " << defaultDirectory;
        SUCCEED();
    }

    TEST(KernelProvider, TestLoadPluginsFromDirectory) {
        // if we're in conda
        const char *env = std::getenv("CONDA_ENV_PATH");
        if(!env) {
            env = std::getenv("PREFIX");
        }
        std::string pluginDir = "lib/readdy_plugins";
        if (env) {
            auto _env = std::string(env);
            if (!boost::algorithm::ends_with(env, "/")) {
                _env = _env.append("/");
            }
            pluginDir = _env.append(pluginDir);
        }
        plug::KernelProvider::getInstance().loadKernelsFromDirectory(pluginDir);
        BOOST_LOG_TRIVIAL(debug) << "current path: " << boost::filesystem::current_path().string();
    }

    TEST(KernelProvider, TestFoo) {
        auto k = plug::KernelProvider::getInstance().create("SingleCPU");
        auto name = k.get()->getName();
        BOOST_LOG_TRIVIAL(debug) << "foo name: " << name;
    }

    TEST(KernelProvider, TestTestProgram) {
        auto single_cpu_kernel = plug::KernelProvider::getInstance().create("SingleCPU");
        auto test_program = single_cpu_kernel.get()->createProgram("TestProgram");
        test_program.get()->execute();
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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 "XalanSpaceNodeTester.hpp"

#include "xalanc/PlatformSupport/DOMStringHelper.hpp"
#include "xalanc/PlatformSupport/XalanMessageLoader.hpp"

#include "Constants.hpp"
#include "StylesheetConstructionContext.hpp"

XALAN_CPP_NAMESPACE_BEGIN

XalanSpaceNodeTester::XalanSpaceNodeTester() :
    NodeTester(),
    m_matchScore(XPath::eMatchScoreNone),
	m_type(ePreserve)
{
}

XalanSpaceNodeTester::XalanSpaceNodeTester(const XalanSpaceNodeTester&	theSource) :
    NodeTester(theSource),
    m_matchScore(theSource.m_matchScore),
	m_type(theSource.m_type)
{
}

XalanSpaceNodeTester::XalanSpaceNodeTester(
			eType							theType,
            StylesheetConstructionContext&  theConstructionContext,
            const XalanDOMString&           theNameTest,
            const PrefixResolver&           thePrefixResolver,
            const LocatorType*              theLocator) :
    NodeTester(
		theConstructionContext,
		theNameTest,
		thePrefixResolver,
		theLocator,
		&m_matchScore),
    m_matchScore(),
	m_type(theType)
{
    assert(m_matchScore != XPath::eMatchScoreNone);
}

XalanSpaceNodeTester::~XalanSpaceNodeTester()
{
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Use initialize() function instead of constructor.<commit_after>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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 "XalanSpaceNodeTester.hpp"

#include "xalanc/PlatformSupport/DOMStringHelper.hpp"
#include "xalanc/PlatformSupport/XalanMessageLoader.hpp"

#include "Constants.hpp"
#include "StylesheetConstructionContext.hpp"

XALAN_CPP_NAMESPACE_BEGIN

XalanSpaceNodeTester::XalanSpaceNodeTester() :
    NodeTester(),
    m_matchScore(XPath::eMatchScoreNone),
	m_type(ePreserve)
{
}

XalanSpaceNodeTester::XalanSpaceNodeTester(const XalanSpaceNodeTester&	theSource) :
    NodeTester(theSource),
    m_matchScore(theSource.m_matchScore),
	m_type(theSource.m_type)
{
}

XalanSpaceNodeTester::XalanSpaceNodeTester(
			eType							theType,
            StylesheetConstructionContext&  theConstructionContext,
            const XalanDOMString&           theNameTest,
            const PrefixResolver&           thePrefixResolver,
            const LocatorType*              theLocator) :
    NodeTester(),
    m_matchScore(),
	m_type(theType)
{
	m_matchScore = initialize(
		theConstructionContext,
		theNameTest,
		thePrefixResolver,
		theLocator);

    assert(m_matchScore != XPath::eMatchScoreNone);
}

XalanSpaceNodeTester::~XalanSpaceNodeTester()
{
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <QApplication>
#include <QCommandLineParser>

#include <KAboutData>
#include <KLocalizedString>

#include "mainwindow.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    KAboutData aboutData(QStringLiteral("heaptrack_gui"), i18n("Heaptrack GUI"), QStringLiteral("0.1"),
                         i18n("A visualizer for heaptrack data files."), KAboutLicense::LGPL,
                         i18n("Copyright 2015, Milian Wolff <mail@milianw.de>"), QString(), QStringLiteral("mail@milianw.de"));

    aboutData.addAuthor(i18n("Milian Wolff"), i18n("Original author, maintainer"),
                        QStringLiteral("mail@milianw.de"), QStringLiteral("http://milianw.de"));

    aboutData.setOrganizationDomain("kde.org");
    KAboutData::setApplicationData(aboutData);

    app.setApplicationName(aboutData.componentName());
    app.setApplicationDisplayName(aboutData.displayName());
    app.setOrganizationDomain(aboutData.organizationDomain());
    app.setWindowIcon(QIcon::fromTheme(QStringLiteral("office-chart-area")));
    app.setApplicationVersion(aboutData.version());

    QCommandLineParser parser;
    KAboutData::setApplicationData(aboutData);
    parser.addVersionOption();
    parser.addHelpOption();
    aboutData.setupCommandLine(&parser);

    parser.addPositionalArgument(QStringLiteral("files"), i18n( "Files to load" ), i18n("[FILE...]"));

    parser.process(app);
    aboutData.processCommandLine(&parser);

    foreach (const QString &file, parser.positionalArguments()) {
        MainWindow* window = new MainWindow;
        window->loadFile(file);
        window->show();
    }

    if (parser.positionalArguments().isEmpty()) {
        MainWindow* window = new MainWindow;
        window->show();
    }

    return app.exec();
}<commit_msg>Set application domain for translations<commit_after>/*
 * Copyright 2015 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <QApplication>
#include <QCommandLineParser>

#include <KAboutData>
#include <KLocalizedString>

#include "mainwindow.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    KLocalizedString::setApplicationDomain("heaptrack");

    KAboutData aboutData(QStringLiteral("heaptrack_gui"), i18n("Heaptrack GUI"), QStringLiteral("0.1"),
                         i18n("A visualizer for heaptrack data files."), KAboutLicense::LGPL,
                         i18n("Copyright 2015, Milian Wolff <mail@milianw.de>"), QString(), QStringLiteral("mail@milianw.de"));

    aboutData.addAuthor(i18n("Milian Wolff"), i18n("Original author, maintainer"),
                        QStringLiteral("mail@milianw.de"), QStringLiteral("http://milianw.de"));

    aboutData.setOrganizationDomain("kde.org");
    KAboutData::setApplicationData(aboutData);

    app.setApplicationName(aboutData.componentName());
    app.setApplicationDisplayName(aboutData.displayName());
    app.setOrganizationDomain(aboutData.organizationDomain());
    app.setWindowIcon(QIcon::fromTheme(QStringLiteral("office-chart-area")));
    app.setApplicationVersion(aboutData.version());

    QCommandLineParser parser;
    KAboutData::setApplicationData(aboutData);
    parser.addVersionOption();
    parser.addHelpOption();
    aboutData.setupCommandLine(&parser);

    parser.addPositionalArgument(QStringLiteral("files"), i18n( "Files to load" ), i18n("[FILE...]"));

    parser.process(app);
    aboutData.processCommandLine(&parser);

    foreach (const QString &file, parser.positionalArguments()) {
        MainWindow* window = new MainWindow;
        window->loadFile(file);
        window->show();
    }

    if (parser.positionalArguments().isEmpty()) {
        MainWindow* window = new MainWindow;
        window->show();
    }

    return app.exec();
}<|endoftext|>