<commit_before>/* =======================================================================
   Copyright (c) 2012, Institute for Microelectronics,
                       Institute for Analysis and Scientific Computing,
                       TU Wien.
                             -----------------
               ViennaMath - Symbolic and Numerical Math in C++
                             -----------------

   Author:     Karl Rupp                          rupp@iue.tuwien.ac.at

   License:    MIT (X11), see file LICENSE in the ViennaMath base directory
======================================================================= */

// remove assert() statements and the like in order to get reasonable performance
#ifndef NDEBUG
  #define NDEBUG
#endif

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <assert.h>

// ViennaFEM includes:
#include "viennafem/forwards.h"
#include "viennafem/fem.hpp"
#include "viennafem/io/vtk_writer.hpp"

// ViennaGrid includes:
#include "viennagrid/domain.hpp"
#include "viennagrid/config/others.hpp"
#include "viennagrid/io/netgen_reader.hpp"
#include "viennagrid/io/vtk_writer.hpp"

// ViennaData includes:
#include "viennadata/api.hpp"

#include "viennamath/expression.hpp"
#include "viennamath/manipulation/eval.hpp"
#include "viennamath/manipulation/substitute.hpp"
#include "viennamath/manipulation/diff.hpp"

#include "viennamath/runtime/equation.hpp"
#include "viennamath/manipulation/apply_coordinate_system.hpp"

// Boost.uBLAS includes:
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/operation_sparse.hpp>

//ViennaCL includes:
#ifndef VIENNACL_HAVE_UBLAS
 #define VIENNACL_HAVE_UBLAS
#endif

#include "viennacl/linalg/bicgstab.hpp"
#include "viennacl/linalg/norm_2.hpp"
#include "viennacl/linalg/prod.hpp"

using namespace viennamath;

//
// The strain tensor: eps_ij = 0.5 * (du_i/dx_j + du_j/dx_i)
//
template <typename InterfaceType>
std::vector< rt_expr<InterfaceType> > strain_tensor(std::vector< rt_function_symbol<InterfaceType> > const & u)
{
  typedef rt_variable<InterfaceType>     Variable;

  //
  // a 3x3 matrix representing the strain tensor
  //
  std::vector< rt_expr<InterfaceType> > result(9);

  Variable x(0);
  Variable y(1);
  Variable z(2);

  //first row:
  result[0] =        diff(u[0], x);
  result[1] = 0.5 * (diff(u[0], y) + diff(u[1], x));
  result[2] = 0.5 * (diff(u[0], z) + diff(u[2], x));

  //second row:
  result[3] = 0.5 * (diff(u[1], x) + diff(u[0], y));
  result[4] =        diff(u[1], y);
  result[5] = 0.5 * (diff(u[1], z) + diff(u[2], y));

  //third row:
  result[6] = 0.5 * (diff(u[2], x) + diff(u[0], z));
  result[7] = 0.5 * (diff(u[2], y) + diff(u[1], z));
  result[8] =        diff(u[2], z);

  return result;
}

//
// The stress tensor: sigma = 2 \mu eps + \lambda trace(eps) Id  for St. Venent-Kirchhoff material
// can be replaced with other expressions for plasticity and the like
//
template <typename InterfaceType>
std::vector< rt_expr<InterfaceType> > stress_tensor(std::vector< rt_function_symbol<InterfaceType> > const & v)
{
  //
  // a 3x3 matrix representing the stress tensor
  //
  std::vector< rt_expr<InterfaceType> > result(9);
  std::vector< rt_expr<InterfaceType> > strain = strain_tensor(v);

  double mu = 0.5;
  double lambda = 1;

  //The entries are in the following written

  //add 2 \mu eps:
  for (size_t i=0; i<9; ++i)
    result[i] = (2*mu) * strain[i];
    //result[i] = viennamath::constant<>(0);

  //add trace(eps) * Id:
  result[0] = (2*mu) * strain[0] + lambda * (strain[0] + strain[4] + strain[8]);
  result[4] = (2*mu) * strain[4] + lambda * (strain[0] + strain[4] + strain[8]);
  result[8] = (2*mu) * strain[8] + lambda * (strain[0] + strain[4] + strain[8]);

  /*result[0] = lambda * (strain[0] + strain[4] + strain[8]);
  result[4] = lambda * (strain[0] + strain[4] + strain[8]);
  result[8] = lambda * (strain[0] + strain[4] + strain[8]);*/

  return result;
}

//
// Provides the operation a : b, where a and b are tensors
//
template <typename InterfaceType>
rt_expr<InterfaceType> tensor_reduce(std::vector< rt_expr<InterfaceType> > lhs, std::vector< rt_expr<InterfaceType> > rhs)
{
  rt_expr<InterfaceType> ret = lhs[0] * rhs[0];

  for (size_t i=1; i<rhs.size(); ++i)
    ret = ret + lhs[i] * rhs[i];

  return ret;
}

//
// Writes displacements to domain
//
template <typename DomainType, typename VectorType>
void apply_displacements(DomainType & domain, VectorType const & result)
{
  typedef typename DomainType::config_type                                              ConfigType;
  typedef typename viennagrid::result_of::ncell<ConfigType, 0>::type               VertexType;
  typedef typename viennagrid::result_of::ncell_range<DomainType, 0>::type          VertexContainer;
  typedef typename viennagrid::result_of::iterator<VertexContainer>::type               VertexIterator;

  typedef viennafem::mapping_key          MappingKeyType;
  typedef viennafem::boundary_key         BoundaryKeyType;

  MappingKeyType map_key(0);
  BoundaryKeyType bnd_key(0);

  std::cout << "* apply_displacements(): Writing computed displacements onto domain" << std::endl;
  VertexContainer vertices = viennagrid::ncells<0>(domain);
  for (VertexIterator vit = vertices.begin();
      vit != vertices.end();
      ++vit)
  {
    long cur_index = viennadata::access<MappingKeyType, long>(map_key)(*vit);
    if (cur_index > -1)
    {
      vit->point()[0] = vit->point()[0] + result[cur_index+0];
      vit->point()[1] = vit->point()[1] + result[cur_index+1];
      vit->point()[2] = vit->point()[2] + result[cur_index+2];
    }
    else
    {
      if (viennadata::access<BoundaryKeyType, std::vector<double> >(bnd_key)(*vit).size() > 0)
      {
        vit->point()[0] += viennadata::access<BoundaryKeyType, std::vector<double> >(bnd_key)(*vit)[0];
        vit->point()[1] += viennadata::access<BoundaryKeyType, std::vector<double> >(bnd_key)(*vit)[1];
        vit->point()[2] += viennadata::access<BoundaryKeyType, std::vector<double> >(bnd_key)(*vit)[2];
      }
    }
  }
}

int main()
{
  typedef viennagrid::config::hexahedral_3d                             ConfigType;
  typedef viennagrid::result_of::domain<ConfigType>::type         DomainType;

  typedef viennagrid::result_of::ncell_range<DomainType, 0>::type    VertexContainer;
  typedef viennagrid::result_of::iterator<VertexContainer>::type         VertexIterator;
  typedef viennagrid::result_of::ncell<ConfigType, 3>::type              CellType;

  typedef boost::numeric::ublas::compressed_matrix<viennafem::numeric_type>  MatrixType;
  typedef boost::numeric::ublas::vector<viennafem::numeric_type>             VectorType;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;
  typedef viennamath::expr              Expression;

  typedef viennafem::boundary_key      BoundaryKey;

  std::cout << "*********************************************************" << std::endl;
  std::cout << "*****     Demo for LAME equation with ViennaFEM     *****" << std::endl;
  std::cout << "*********************************************************" << std::endl;

  DomainType my_domain;

  try
  {
    viennagrid::io::netgen_reader my_reader;
    my_reader(my_domain, "../examples/data/cube343_hex.mesh");
  }
  catch (...)
  {
    std::cerr << "File-Reader failed. Aborting program..." << std::endl;
    exit(EXIT_FAILURE);
  }

  MatrixType system_matrix;
  VectorType load_vector;

  // the unknown function (vector valued, so one for each of the three components..
  std::vector< FunctionSymbol > u(3);
  u[0] = FunctionSymbol(0, unknown_tag<>());
  u[1] = FunctionSymbol(1, unknown_tag<>());
  u[2] = FunctionSymbol(2, unknown_tag<>());

  std::vector< FunctionSymbol > v(3);
  v[0] = FunctionSymbol(0, test_tag<>());
  v[1] = FunctionSymbol(1, test_tag<>());
  v[2] = FunctionSymbol(2, test_tag<>());

  //
  // Step 1: Define the classical Lame equation
  //             (lambda + mu) div(u) div(v) + mu grad(u):grad(v) = F
  // with force F set to 0.
  //
  // Minimization problem: \int eps : sigma dx = \int F \cdot u dx
  //

  std::vector< Expression > strain = strain_tensor(u);
  std::vector< Expression > stress = stress_tensor(v);

  Equation weak_form_lame = make_equation( integral(symbolic_interval(), tensor_reduce( strain, stress )),
                                           //=
                                           integral(symbolic_interval(), viennamath::rt_constant<double>(1.0) * v[2])
                                         );

  std::cout << "Weak form of Lame equation: " << std::endl;
  std::cout << weak_form_lame << std::endl;

  std::vector<double> bnd_data_right(3);
  bnd_data_right[0] = 0.2; //small displacement into x-direction prescribed

  VertexContainer vertices = viennagrid::ncells<0>(my_domain);
  for (VertexIterator vit = vertices.begin();
      vit != vertices.end();
      ++vit)
  {
    //boundary for first equation: Homogeneous Dirichlet everywhere
    if (vit->point()[0] == 0.0 || vit->point()[0] == 1.0 )
      viennafem::set_dirichlet_boundary(*vit, 0);

    if (vit->point()[0] == 1.0)
    {
      viennafem::set_dirichlet_boundary(*vit, bnd_data_right);
      viennadata::access<BoundaryKey, double>(BoundaryKey(0))(*vit) = bnd_data_right[0]; //this is for the moment used for the VTK writer
    }
  }

  //
  // Create PDE solver functors: (discussion about proper interface required)
  //
  viennafem::pde_assembler fem_assembler;

  //
  // Assemble and solve system and write solution vector to pde_result:
  // (discussion about proper interface required. Introduce a pde_result class?)
  //
  fem_assembler(viennafem::make_linear_pde_system(weak_form_lame,
                                                  u,
                                                  viennafem::make_linear_pde_options(0,
                                                                                viennafem::lagrange_tag<1>(),
                                                                                viennafem::lagrange_tag<1>())
                                                 ),
                my_domain,
                system_matrix,
                load_vector
               );

  VectorType displacements = viennacl::linalg::solve(system_matrix, load_vector, viennacl::linalg::bicgstab_tag());
  std::cout << "* solve(): Residual: " << norm_2(prod(system_matrix, displacements) - load_vector) << std::endl;

  apply_displacements(my_domain, displacements);
  viennafem::io::write_solution_to_VTK_file(displacements, "lame_hex", my_domain, 0);

  std::cout << "*****************************************" << std::endl;
  std::cout << "* Lame solver finished successfully! *" << std::endl;
  std::cout << "*****************************************" << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>reactivated lame_3d_hex example - compiles & executes but doesn't generate results<commit_after>/* =======================================================================
   Copyright (c) 2012, Institute for Microelectronics,
                       Institute for Analysis and Scientific Computing,
                       TU Wien.
                             -----------------
               ViennaMath - Symbolic and Numerical Math in C++
                             -----------------

   Author:     Karl Rupp                          rupp@iue.tuwien.ac.at

   License:    MIT (X11), see file LICENSE in the ViennaMath base directory
======================================================================= */

// remove assert() statements and the like in order to get reasonable performance
#ifndef NDEBUG
  #define NDEBUG
#endif

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <assert.h>

// ViennaFEM includes:
#include "viennafem/forwards.h"
#include "viennafem/fem.hpp"
#include "viennafem/io/vtk_writer.hpp"

// ViennaGrid includes:
#include "viennagrid/forwards.hpp"
#include "viennagrid/config/default_configs.hpp"
#include "viennagrid/io/netgen_reader.hpp"

// ViennaData includes:
#include "viennadata/api.hpp"

#include "viennamath/expression.hpp"
#include "viennamath/manipulation/eval.hpp"
#include "viennamath/manipulation/substitute.hpp"
#include "viennamath/manipulation/diff.hpp"

#include "viennamath/runtime/equation.hpp"
#include "viennamath/manipulation/apply_coordinate_system.hpp"

// Boost.uBLAS includes:
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/operation_sparse.hpp>

//ViennaCL includes:
#ifndef VIENNACL_HAVE_UBLAS
 #define VIENNACL_HAVE_UBLAS
#endif

#include "viennacl/linalg/bicgstab.hpp"
#include "viennacl/linalg/norm_2.hpp"
#include "viennacl/linalg/prod.hpp"

using namespace viennamath;

//
// The strain tensor: eps_ij = 0.5 * (du_i/dx_j + du_j/dx_i)
//
template <typename InterfaceType>
std::vector< rt_expr<InterfaceType> > strain_tensor(std::vector< rt_function_symbol<InterfaceType> > const & u)
{
  typedef rt_variable<InterfaceType>     Variable;

  //
  // a 3x3 matrix representing the strain tensor
  //
  std::vector< rt_expr<InterfaceType> > result(9);

  Variable x(0);
  Variable y(1);
  Variable z(2);

  //first row:
  result[0] =        diff(u[0], x);
  result[1] = 0.5 * (diff(u[0], y) + diff(u[1], x));
  result[2] = 0.5 * (diff(u[0], z) + diff(u[2], x));

  //second row:
  result[3] = 0.5 * (diff(u[1], x) + diff(u[0], y));
  result[4] =        diff(u[1], y);
  result[5] = 0.5 * (diff(u[1], z) + diff(u[2], y));

  //third row:
  result[6] = 0.5 * (diff(u[2], x) + diff(u[0], z));
  result[7] = 0.5 * (diff(u[2], y) + diff(u[1], z));
  result[8] =        diff(u[2], z);

  return result;
}

//
// The stress tensor: sigma = 2 \mu eps + \lambda trace(eps) Id  for St. Venent-Kirchhoff material
// can be replaced with other expressions for plasticity and the like
//
template <typename InterfaceType>
std::vector< rt_expr<InterfaceType> > stress_tensor(std::vector< rt_function_symbol<InterfaceType> > const & v)
{
  //
  // a 3x3 matrix representing the stress tensor
  //
  std::vector< rt_expr<InterfaceType> > result(9);
  std::vector< rt_expr<InterfaceType> > strain = strain_tensor(v);

  double mu = 0.5;
  double lambda = 1;

  //The entries are in the following written

  //add 2 \mu eps:
  for (size_t i=0; i<9; ++i)
    result[i] = (2*mu) * strain[i];
    //result[i] = viennamath::constant<>(0);

  //add trace(eps) * Id:
  result[0] = (2*mu) * strain[0] + lambda * (strain[0] + strain[4] + strain[8]);
  result[4] = (2*mu) * strain[4] + lambda * (strain[0] + strain[4] + strain[8]);
  result[8] = (2*mu) * strain[8] + lambda * (strain[0] + strain[4] + strain[8]);

  /*result[0] = lambda * (strain[0] + strain[4] + strain[8]);
  result[4] = lambda * (strain[0] + strain[4] + strain[8]);
  result[8] = lambda * (strain[0] + strain[4] + strain[8]);*/

  return result;
}

//
// Provides the operation a : b, where a and b are tensors
//
template <typename InterfaceType>
rt_expr<InterfaceType> tensor_reduce(std::vector< rt_expr<InterfaceType> > lhs, std::vector< rt_expr<InterfaceType> > rhs)
{
  rt_expr<InterfaceType> ret = lhs[0] * rhs[0];

  for (size_t i=1; i<rhs.size(); ++i)
    ret = ret + lhs[i] * rhs[i];

  return ret;
}

//
// Writes displacements to domain
//
template <typename DomainT, typename StorageT, typename VectorT>
void apply_displacements(DomainT& domain, StorageT& storage, VectorT const & result)
{
  typedef typename viennagrid::result_of::element<DomainT, viennagrid::vertex_tag>::type           VertexType;
  typedef typename viennagrid::result_of::element_range<DomainT, viennagrid::vertex_tag>::type     VertexContainer;
  typedef typename viennagrid::result_of::iterator<VertexContainer>::type                          VertexIterator;

  typedef viennafem::mapping_key          MappingKeyType;
  typedef viennafem::boundary_key         BoundaryKeyType;

  MappingKeyType map_key(0);
  BoundaryKeyType bnd_key(0);

  std::cout << "* apply_displacements(): Writing computed displacements onto domain" << std::endl;
  VertexContainer vertices = viennagrid::elements<VertexType>(domain);
  for (VertexIterator vit = vertices.begin();
      vit != vertices.end();
      ++vit)
  {
    long cur_index = viennadata::access<MappingKeyType, long>(storage, map_key, *vit);
    if (cur_index > -1)
    {
      viennagrid::point(domain, *vit)[0] += result[cur_index+0];
      viennagrid::point(domain, *vit)[1] += result[cur_index+1];
      viennagrid::point(domain, *vit)[2] += result[cur_index+2];
    }
    else
    {
      if (viennadata::access<BoundaryKeyType, std::vector<double> >(storage, bnd_key, *vit).size() > 0)
      {
        viennagrid::point(domain, *vit)[0] += viennadata::access<BoundaryKeyType, std::vector<double> >(storage, bnd_key, *vit)[0];
        viennagrid::point(domain, *vit)[1] += viennadata::access<BoundaryKeyType, std::vector<double> >(storage, bnd_key, *vit)[1];
        viennagrid::point(domain, *vit)[2] += viennadata::access<BoundaryKeyType, std::vector<double> >(storage, bnd_key, *vit)[2];
      }
    }
  }
}

int main()
{
  typedef viennagrid::domain_t< viennagrid::config::hexahedral_3d >                       DomainType;
  typedef viennagrid::result_of::segmentation<DomainType>::type                           SegmentationType;
  typedef SegmentationType::iterator                                                      SegmentationIterator;
  typedef viennagrid::result_of::element<DomainType, viennagrid::vertex_tag>::type        VertexType;
  typedef viennagrid::result_of::element_range<DomainType, viennagrid::vertex_tag>::type  VertexContainer;
  typedef viennagrid::result_of::iterator<VertexContainer>::type                          VertexIterator;

  typedef boost::numeric::ublas::compressed_matrix<viennafem::numeric_type>  MatrixType;
  typedef boost::numeric::ublas::vector<viennafem::numeric_type>             VectorType;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;
  typedef viennamath::expr              Expression;

  typedef viennafem::boundary_key      BoundaryKey;

  std::cout << "*********************************************************" << std::endl;
  std::cout << "*****     Demo for LAME equation with ViennaFEM     *****" << std::endl;
  std::cout << "*********************************************************" << std::endl;

  //
  // Create a domain from file
  //
  DomainType my_domain;
  SegmentationType segments(my_domain);

  //
  // Create a storage object
  //
  typedef viennadata::storage<> StorageType;
  StorageType   storage;

  try
  {
    viennagrid::io::netgen_reader my_reader;
    my_reader(my_domain, segments, "../examples/data/cube343_hex.mesh");
  }
  catch (...)
  {
    std::cerr << "File-Reader failed. Aborting program..." << std::endl;
    exit(EXIT_FAILURE);
  }

  MatrixType system_matrix;
  VectorType load_vector;

  // the unknown function (vector valued, so one for each of the three components..
  std::vector< FunctionSymbol > u(3);
  u[0] = FunctionSymbol(0, unknown_tag<>());
  u[1] = FunctionSymbol(1, unknown_tag<>());
  u[2] = FunctionSymbol(2, unknown_tag<>());

  std::vector< FunctionSymbol > v(3);
  v[0] = FunctionSymbol(0, test_tag<>());
  v[1] = FunctionSymbol(1, test_tag<>());
  v[2] = FunctionSymbol(2, test_tag<>());

  //
  // Step 1: Define the classical Lame equation
  //             (lambda + mu) div(u) div(v) + mu grad(u):grad(v) = F
  // with force F set to 0.
  //
  // Minimization problem: \int eps : sigma dx = \int F \cdot u dx
  //

  std::vector< Expression > strain = strain_tensor(u);
  std::vector< Expression > stress = stress_tensor(v);

  Equation weak_form_lame = make_equation( integral(symbolic_interval(), tensor_reduce( strain, stress )),
                                           //=
                                           integral(symbolic_interval(), viennamath::rt_constant<double>(1.0) * v[2])
                                         );

  std::cout << "Weak form of Lame equation: " << std::endl;
  std::cout << weak_form_lame << std::endl;

  std::vector<double> bnd_data_right(3);
  bnd_data_right[0] = 0.2; //small displacement into x-direction prescribed

  VertexContainer vertices = viennagrid::elements<VertexType>(my_domain);
  for (VertexIterator vit = vertices.begin();
      vit != vertices.end();
      ++vit)
  {
    //boundary for first equation: Homogeneous Dirichlet everywhere
    if (viennagrid::point(my_domain, *vit)[0] == 0.0 || viennagrid::point(my_domain, *vit)[0] == 1.0 )
      viennafem::set_dirichlet_boundary(storage, *vit, 0);

    if (viennagrid::point(my_domain, *vit)[0] == 1.0)
    {
      viennafem::set_dirichlet_boundary(storage, *vit, bnd_data_right);
      viennadata::access<BoundaryKey, double>(storage, BoundaryKey(0), *vit) = bnd_data_right[0]; //this is for the moment used for the VTK writer
    }
  }

  //
  // Create PDE solver functors: (discussion about proper interface required)
  //
  viennafem::pde_assembler<StorageType> fem_assembler(storage);

  //
  // Assemble and solve system and write solution vector to pde_result:
  // (discussion about proper interface required. Introduce a pde_result class?)
  //
  fem_assembler(viennafem::make_linear_pde_system(weak_form_lame,
                                                  u,
                                                  viennafem::make_linear_pde_options(0,
                                                                                viennafem::lagrange_tag<1>(),
                                                                                viennafem::lagrange_tag<1>())
                                                 ),
                my_domain,
                system_matrix,
                load_vector
               );

  VectorType displacements = viennacl::linalg::solve(system_matrix, load_vector, viennacl::linalg::bicgstab_tag());
  std::cout << "* solve(): Residual: " << norm_2(prod(system_matrix, displacements) - load_vector) << std::endl;

  apply_displacements(my_domain, storage, displacements);
  viennafem::io::write_solution_to_VTK_file(displacements, "lame_hex", my_domain, segments, storage, 0);

  std::cout << "*****************************************" << std::endl;
  std::cout << "* Lame solver finished successfully! *" << std::endl;
  std::cout << "*****************************************" << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;
//_________________________________________________________________________
// This program declares a class for a circle that will have
// member functions that set the center, find the area, find
// the circumference and display these attributes.
// The program as written does not allow the user to input data, but
// rather has the radii and center coordinates of the circles (spheres in the program)
// initialized  at declaration or set by a function.

//class declaration section   (header file)

class Circles
{
public:
   void setCenter(int x, int y);
   double findArea();
   double findCircumference();
   void printCircleStats(); // This outputs the radius and center of the circle.
   Circles (float r);       // Constructor
   Circles();               // Default constructor
private:
   float  radius;
   int    center_x;
   int    center_y;
};

const double PI = 3.14;

//Client section

int main()
{
   Circles sphere(8);
   sphere.setCenter(9,10);
   sphere.printCircleStats();
   char ch;
   cin >> ch;

   return 0;
}

//___________________________________________________________________________
//Implementation section     Member function implementation

Circles::Circles()
{
   radius = 1;
   center_y = 0;
   center_x = 0;
}
// Fill in the code to implement the non-default constructor
Circles::Circles(float r)
{
   radius = r;
   center_y = 0;
   center_x = 0;
}

// Fill in the code to implement the findArea member function
double Circles::findArea(){
	double area=0;
	area = PI*radius*radius;
	return area;
}

// Fill in the code to implement the findCircumference member function
double Circles::findCircumference(){
	double circ=0;
	circ = 2*PI*radius;
	return circ;
}

void Circles::printCircleStats()
// This procedure prints out the radius and center coordinates of the circle
// object that calls it.

{
   cout << "The radius of the circle is " << radius << endl;
   cout << "The center of the circle is (" << center_x
        << "," << center_y << ")" << endl;
   cout << "The area of the circle is " << findArea() << endl;
   cout << "The circumference of the circle is (" << findCircumference() << endl;
}

void Circles::setCenter(int x, int y)
// This procedure will take the coordinates of the center of the circle from
// the user and place them in the appropriate member data.

{
   center_x = x;
   center_y = y;
}
<commit_msg>Update circles.cpp<commit_after>#include <iostream>
using namespace std;
//_________________________________________________________________________
// This program declares a class for a circle that will have
// member functions that set the center, find the area, find
// the circumference and display these attributes.
// The program as written does not allow the user to input data, but
// rather has the radii and center coordinates of the circles (spheres in the program)
// initialized  at declaration or set by a function.

//class declaration section   (header file)

class Circles
{
public:
   //void setCenter(int x, int y);
   double findArea();
   double findCircumference();
   void printCircleStats(); // This outputs the radius and center of the circle.
   Circles (float r);       // Constructor
   Circles (float r, int x, int y);       // Constructor
   Circles();               // Default constructor
private:
   float  radius;
   int    center_x;
   int    center_y;
};

const double PI = 3.14;

//Client section

int main()
{
   Circles sphere1(2);
   Circles sphere2;
   sphere1.printCircleStats();
   sphere2.printCircleStats();
   char ch;
   cin >> ch;

   return 0;
}

//___________________________________________________________________________
//Implementation section     Member function implementation

Circles::Circles()
{
   radius = 1;
   center_y = 0;
   center_x = 0;
}
// Fill in the code to implement the non-default constructor
Circles::Circles(float r)
{
   radius = r;
   center_y = 0;
   center_x = 0;
}

Circles::Circles(float r, int x, int y)
{
   radius = r;
   center_y = y;
   center_x = x;
}

// Fill in the code to implement the findArea member function
double Circles::findArea(){
	double area=0;
	area = PI*radius*radius;
	return area;
}

// Fill in the code to implement the findCircumference member function
double Circles::findCircumference(){
	double circ=0;
	circ = 2*PI*radius;
	return circ;
}

void Circles::printCircleStats()
// This procedure prints out the radius and center coordinates of the circle
// object that calls it.

{
   cout << "The radius of the circle is " << radius << endl;
   cout << "The center of the circle is (" << center_x
        << "," << center_y << ")" << endl;
   cout << "The area of the circle is " << findArea() << endl;
   cout << "The circumference of the circle is " << findCircumference() << endl << endl;
}

/*void Circles::setCenter(int x, int y)
// This procedure will take the coordinates of the center of the circle from
// the user and place them in the appropriate member data.

{
   center_x = x;
   center_y = y;
} */
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexInno.cxx
 ** Lexer for Inno Setup scripts.
 **/
// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
	int state = SCE_INNO_DEFAULT;
	char chPrev;
	char ch = 0;
	char chNext = styler[startPos];
	int lengthDoc = startPos + length;
	char *buffer = new char[length];
	int bufferCount = 0;
	bool isBOL, isEOL, isWS, isBOLWS = 0;
	bool isCode = false;
	bool isCStyleComment = false;

	WordList &sectionKeywords = *keywordLists[0];
	WordList &standardKeywords = *keywordLists[1];
	WordList &parameterKeywords = *keywordLists[2];
	WordList &preprocessorKeywords = *keywordLists[3];
	WordList &pascalKeywords = *keywordLists[4];
	WordList &userKeywords = *keywordLists[5];

	// Go through all provided text segment
	// using the hand-written state machine shown below
	styler.StartAt(startPos);
	styler.StartSegment(startPos);
	for (int i = startPos; i < lengthDoc; i++) {
		chPrev = ch;
		ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			i++;
			continue;
		}

		isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
		isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
		isEOL = (ch == '\n' || ch == '\r');
		isWS = (ch == ' ' || ch == '\t');

		switch(state) {
			case SCE_INNO_DEFAULT:
				if (!isCode && ch == ';' && isBOLWS) {
					// Start of a comment
					state = SCE_INNO_COMMENT;
				} else if (ch == '[' && isBOLWS) {
					// Start of a section name
					bufferCount = 0;
					state = SCE_INNO_SECTION;
				} else if (ch == '#' && isBOLWS) {
					// Start of a preprocessor directive
					state = SCE_INNO_PREPROC;
				} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
					// Start of an inline expansion
					state = SCE_INNO_INLINE_EXPANSION;
				} else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
					// Start of a Pascal comment
					state = SCE_INNO_COMMENT_PASCAL;
					isCStyleComment = false;
				} else if (isCode && ch == '/' && chNext == '/') {
					// Apparently, C-style comments are legal, too
					state = SCE_INNO_COMMENT_PASCAL;
					isCStyleComment = true;
				} else if (ch == '"') {
					// Start of a double-quote string
					state = SCE_INNO_STRING_DOUBLE;
				} else if (ch == '\'') {
					// Start of a single-quote string
					state = SCE_INNO_STRING_SINGLE;
				} else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
					// Start of an identifier
					bufferCount = 0;
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
					state = SCE_INNO_IDENTIFIER;
				} else {
					// Style it the default style
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_COMMENT:
				if (isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_COMMENT);
				}
				break;

			case SCE_INNO_IDENTIFIER:
				if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				} else {
					state = SCE_INNO_DEFAULT;
					buffer[bufferCount] = '\0';

					// Check if the buffer contains a keyword
					if (!isCode && standardKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD);
					} else if (!isCode && parameterKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_PARAMETER);
					} else if (isCode && pascalKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
					} else if (!isCode && userKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
					} else {
						styler.ColourTo(i-1,SCE_INNO_DEFAULT);
					}

					// Push back the faulty character
					chNext = styler[i--];
					ch = chPrev;
				}
				break;

			case SCE_INNO_SECTION:
				if (ch == ']') {
					state = SCE_INNO_DEFAULT;
					buffer[bufferCount] = '\0';

					// Check if the buffer contains a section name
					if (sectionKeywords.InList(buffer)) {
						styler.ColourTo(i,SCE_INNO_SECTION);
						isCode = !CompareCaseInsensitive(buffer, "code");
					} else {
						styler.ColourTo(i,SCE_INNO_DEFAULT);
					}
				} else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				} else {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_PREPROC:
				if (isWS || isEOL) {
					if (isascii(chPrev) && isalpha(chPrev)) {
						state = SCE_INNO_DEFAULT;
						buffer[bufferCount] = '\0';

						// Check if the buffer contains a preprocessor directive
						if (preprocessorKeywords.InList(buffer)) {
							styler.ColourTo(i-1,SCE_INNO_PREPROC);
						} else {
							styler.ColourTo(i-1,SCE_INNO_DEFAULT);
						}

						// Push back the faulty character
						chNext = styler[i--];
						ch = chPrev;
					}
				} else if (isascii(ch) && isalpha(ch)) {
					if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
						bufferCount = 0;
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				}
				break;

			case SCE_INNO_STRING_DOUBLE:
				if (ch == '"' || isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
				}
				break;

			case SCE_INNO_STRING_SINGLE:
				if (ch == '\'' || isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
				}
				break;

			case SCE_INNO_INLINE_EXPANSION:
				if (ch == '}') {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
				} else if (isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_COMMENT_PASCAL:
				if (isCStyleComment) {
					if (isEOL) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
					}
				} else {
					if (ch == '}' || (ch == ')' && chPrev == '*')) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
					} else if (isEOL) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_DEFAULT);
					}
				}
				break;

		}
	}
	delete []buffer;
}

static const char * const innoWordListDesc[] = {
	"Sections",
	"Keywords",
	"Parameters",
	"Preprocessor directives",
	"Pascal keywords",
	"User defined keywords",
	0
};

static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
	unsigned int endPos = startPos + length;
	char chNext = styler[startPos];

	int lineCurrent = styler.GetLine(startPos);

	bool sectionFlag = false;
	int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
	int level;

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler[i+1];
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		int style = styler.StyleAt(i);

		if (style == SCE_INNO_SECTION)
			sectionFlag = true;

		if (atEOL || i == endPos - 1) {
			if (sectionFlag) {
				level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
				if (level == levelPrev)
					styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
			} else {
				level = levelPrev & SC_FOLDLEVELNUMBERMASK;
				if (levelPrev & SC_FOLDLEVELHEADERFLAG)
					level++;
			}

			styler.SetLevel(lineCurrent, level);

			levelPrev = level;
			lineCurrent++;
			sectionFlag = false;
		}
	}
}

LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
<commit_msg>Bug #3283880. Highlight source code inside [CODE] section when lexing starts in the middle. From Marko Njezic.<commit_after>// Scintilla source code edit control
/** @file LexInno.cxx
 ** Lexer for Inno Setup scripts.
 **/
// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
	int state = SCE_INNO_DEFAULT;
	char chPrev;
	char ch = 0;
	char chNext = styler[startPos];
	int lengthDoc = startPos + length;
	char *buffer = new char[length];
	int bufferCount = 0;
	bool isBOL, isEOL, isWS, isBOLWS = 0;
	bool isCStyleComment = false;

	WordList &sectionKeywords = *keywordLists[0];
	WordList &standardKeywords = *keywordLists[1];
	WordList &parameterKeywords = *keywordLists[2];
	WordList &preprocessorKeywords = *keywordLists[3];
	WordList &pascalKeywords = *keywordLists[4];
	WordList &userKeywords = *keywordLists[5];

	int curLine = styler.GetLine(startPos);
	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
	bool isCode = (curLineState == 1);

	// Go through all provided text segment
	// using the hand-written state machine shown below
	styler.StartAt(startPos);
	styler.StartSegment(startPos);
	for (int i = startPos; i < lengthDoc; i++) {
		chPrev = ch;
		ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			i++;
			continue;
		}

		isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
		isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
		isEOL = (ch == '\n' || ch == '\r');
		isWS = (ch == ' ' || ch == '\t');

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			// Remember the line state for future incremental lexing
			curLine = styler.GetLine(i);
			styler.SetLineState(curLine, (isCode ? 1 : 0));
		}

		switch(state) {
			case SCE_INNO_DEFAULT:
				if (!isCode && ch == ';' && isBOLWS) {
					// Start of a comment
					state = SCE_INNO_COMMENT;
				} else if (ch == '[' && isBOLWS) {
					// Start of a section name
					bufferCount = 0;
					state = SCE_INNO_SECTION;
				} else if (ch == '#' && isBOLWS) {
					// Start of a preprocessor directive
					state = SCE_INNO_PREPROC;
				} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
					// Start of an inline expansion
					state = SCE_INNO_INLINE_EXPANSION;
				} else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
					// Start of a Pascal comment
					state = SCE_INNO_COMMENT_PASCAL;
					isCStyleComment = false;
				} else if (isCode && ch == '/' && chNext == '/') {
					// Apparently, C-style comments are legal, too
					state = SCE_INNO_COMMENT_PASCAL;
					isCStyleComment = true;
				} else if (ch == '"') {
					// Start of a double-quote string
					state = SCE_INNO_STRING_DOUBLE;
				} else if (ch == '\'') {
					// Start of a single-quote string
					state = SCE_INNO_STRING_SINGLE;
				} else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
					// Start of an identifier
					bufferCount = 0;
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
					state = SCE_INNO_IDENTIFIER;
				} else {
					// Style it the default style
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_COMMENT:
				if (isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_COMMENT);
				}
				break;

			case SCE_INNO_IDENTIFIER:
				if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				} else {
					state = SCE_INNO_DEFAULT;
					buffer[bufferCount] = '\0';

					// Check if the buffer contains a keyword
					if (!isCode && standardKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD);
					} else if (!isCode && parameterKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_PARAMETER);
					} else if (isCode && pascalKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
					} else if (!isCode && userKeywords.InList(buffer)) {
						styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
					} else {
						styler.ColourTo(i-1,SCE_INNO_DEFAULT);
					}

					// Push back the faulty character
					chNext = styler[i--];
					ch = chPrev;
				}
				break;

			case SCE_INNO_SECTION:
				if (ch == ']') {
					state = SCE_INNO_DEFAULT;
					buffer[bufferCount] = '\0';

					// Check if the buffer contains a section name
					if (sectionKeywords.InList(buffer)) {
						styler.ColourTo(i,SCE_INNO_SECTION);
						isCode = !CompareCaseInsensitive(buffer, "code");
					} else {
						styler.ColourTo(i,SCE_INNO_DEFAULT);
					}
				} else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				} else {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_PREPROC:
				if (isWS || isEOL) {
					if (isascii(chPrev) && isalpha(chPrev)) {
						state = SCE_INNO_DEFAULT;
						buffer[bufferCount] = '\0';

						// Check if the buffer contains a preprocessor directive
						if (preprocessorKeywords.InList(buffer)) {
							styler.ColourTo(i-1,SCE_INNO_PREPROC);
						} else {
							styler.ColourTo(i-1,SCE_INNO_DEFAULT);
						}

						// Push back the faulty character
						chNext = styler[i--];
						ch = chPrev;
					}
				} else if (isascii(ch) && isalpha(ch)) {
					if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
						bufferCount = 0;
					buffer[bufferCount++] = static_cast<char>(tolower(ch));
				}
				break;

			case SCE_INNO_STRING_DOUBLE:
				if (ch == '"' || isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
				}
				break;

			case SCE_INNO_STRING_SINGLE:
				if (ch == '\'' || isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
				}
				break;

			case SCE_INNO_INLINE_EXPANSION:
				if (ch == '}') {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
				} else if (isEOL) {
					state = SCE_INNO_DEFAULT;
					styler.ColourTo(i,SCE_INNO_DEFAULT);
				}
				break;

			case SCE_INNO_COMMENT_PASCAL:
				if (isCStyleComment) {
					if (isEOL) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
					}
				} else {
					if (ch == '}' || (ch == ')' && chPrev == '*')) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
					} else if (isEOL) {
						state = SCE_INNO_DEFAULT;
						styler.ColourTo(i,SCE_INNO_DEFAULT);
					}
				}
				break;

		}
	}
	delete []buffer;
}

static const char * const innoWordListDesc[] = {
	"Sections",
	"Keywords",
	"Parameters",
	"Preprocessor directives",
	"Pascal keywords",
	"User defined keywords",
	0
};

static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
	unsigned int endPos = startPos + length;
	char chNext = styler[startPos];

	int lineCurrent = styler.GetLine(startPos);

	bool sectionFlag = false;
	int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
	int level;

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler[i+1];
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		int style = styler.StyleAt(i);

		if (style == SCE_INNO_SECTION)
			sectionFlag = true;

		if (atEOL || i == endPos - 1) {
			if (sectionFlag) {
				level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
				if (level == levelPrev)
					styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
			} else {
				level = levelPrev & SC_FOLDLEVELNUMBERMASK;
				if (levelPrev & SC_FOLDLEVELHEADERFLAG)
					level++;
			}

			styler.SetLevel(lineCurrent, level);

			levelPrev = level;
			lineCurrent++;
			sectionFlag = false;
		}
	}
}

LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

#include "KmsHttpLoop.h"

#define NAME "httploop"

GST_DEBUG_CATEGORY_STATIC (kms_http_loop_debug_category);
#define GST_CAT_DEFAULT kms_http_loop_debug_category

G_DEFINE_TYPE_WITH_CODE (KmsHttpLoop, kms_http_loop,
                         G_TYPE_OBJECT,
                         GST_DEBUG_CATEGORY_INIT (kms_http_loop_debug_category,
                             NAME, 0, "debug category for kurento loop") )

#define KMS_HTTP_LOOP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KMS_TYPE_HTTP_LOOP, KmsHttpLoopPrivate))

struct _KmsHttpLoopPrivate {
  GThread *thread;
  GRecMutex rmutex;
  GMainLoop *loop;
  GMainContext *context;
  GCond cond;
  GMutex mutex;
  gboolean initialized;
};

#define KMS_HTTP_LOOP_LOCK(elem) \
  (g_rec_mutex_lock (&KMS_HTTP_LOOP ((elem))->priv->rmutex))
#define KMS_HTTP_LOOP_UNLOCK(elem) \
  (g_rec_mutex_unlock (&KMS_HTTP_LOOP ((elem))->priv->rmutex))

/* Object properties */
enum {
  PROP_0,
  PROP_CONTEXT,
  N_PROPERTIES
};

static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

static gboolean
quit_main_loop (KmsHttpLoop *self)
{
  GST_DEBUG ("Exiting main loop");

  g_main_loop_quit (self->priv->loop);
  g_main_context_release (self->priv->context);

  return G_SOURCE_REMOVE;
}

static gpointer
loop_thread_init (gpointer data)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (data);
  GMainLoop *loop;
  GMainContext *context;

  KMS_HTTP_LOOP_LOCK (self);
  self->priv->context = g_main_context_new ();
  context = self->priv->context;
  self->priv->loop = g_main_loop_new (context, FALSE);
  loop = self->priv->loop;
  KMS_HTTP_LOOP_UNLOCK (self);

  /* unlock main process because context is already initialized */
  g_mutex_lock (&self->priv->mutex);
  self->priv->initialized = TRUE;
  g_cond_signal (&self->priv->cond);
  g_mutex_unlock (&self->priv->mutex);

  if (!g_main_context_acquire (context) ) {
    GST_ERROR ("Can not acquire context");
    goto end;
  }

  GST_DEBUG ("Running main loop");
  g_main_loop_run (loop);

end:
  GST_DEBUG ("Thread finished");

  return NULL;
}

static void
kms_http_loop_get_property (GObject *object, guint property_id, GValue *value,
                            GParamSpec *pspec)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (object);

  KMS_HTTP_LOOP_LOCK (self);

  switch (property_id) {
  case PROP_CONTEXT:
    g_value_set_boxed (value, self->priv->context);
    break;

  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    break;
  }

  KMS_HTTP_LOOP_UNLOCK (self);
}

static void
kms_http_loop_dispose (GObject *obj)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (obj);

  GST_DEBUG_OBJECT (obj, "Dispose");

  KMS_HTTP_LOOP_LOCK (self);

  if (self->priv->thread != NULL) {
    if (g_thread_self () != self->priv->thread) {
      GThread *aux = self->priv->thread;

      kms_http_loop_idle_add (self, (GSourceFunc) quit_main_loop,
                              self);
      self->priv->thread = NULL;
      KMS_HTTP_LOOP_UNLOCK (self);
      g_thread_join (aux);
      KMS_HTTP_LOOP_LOCK (self);
    } else {
      /* self thread does not need to wait for itself */
      quit_main_loop (self);
      g_thread_unref (self->priv->thread);
      self->priv->thread = NULL;
    }
  }

  KMS_HTTP_LOOP_UNLOCK (self);

  G_OBJECT_CLASS (kms_http_loop_parent_class)->dispose (obj);
}

static void
kms_http_loop_finalize (GObject *obj)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (obj);

  GST_DEBUG_OBJECT (obj, "Finalize");

  if (self->priv->context != NULL) {
    g_main_context_unref (self->priv->context);
  }

  if (self->priv->loop != NULL) {
    g_main_loop_unref (self->priv->loop);
  }

  g_rec_mutex_clear (&self->priv->rmutex);
  g_mutex_clear (&self->priv->mutex);
  g_cond_clear (&self->priv->cond);

  G_OBJECT_CLASS (kms_http_loop_parent_class)->finalize (obj);
}

static void
kms_http_loop_class_init (KmsHttpLoopClass *klass)
{
  GObjectClass *objclass = G_OBJECT_CLASS (klass);

  objclass->dispose = kms_http_loop_dispose;
  objclass->finalize = kms_http_loop_finalize;
  objclass->get_property = kms_http_loop_get_property;

  /* Install properties */
  obj_properties[PROP_CONTEXT] = g_param_spec_boxed ("context",
                                 "Main loop context",
                                 "Main loop context",
                                 G_TYPE_MAIN_CONTEXT,
                                 (GParamFlags) (G_PARAM_READABLE) );

  g_object_class_install_properties (objclass, N_PROPERTIES, obj_properties);

  /* Registers a private structure for the instantiatable type */
  g_type_class_add_private (klass, sizeof (KmsHttpLoopPrivate) );
}

static void
kms_http_loop_init (KmsHttpLoop *self)
{
  self->priv = KMS_HTTP_LOOP_GET_PRIVATE (self);
  self->priv->context = NULL;
  self->priv->loop = NULL;
  g_rec_mutex_init (&self->priv->rmutex);
  g_cond_init (&self->priv->cond);
  g_mutex_init (&self->priv->mutex);

  self->priv->thread = g_thread_new ("KmsHttpLoop", loop_thread_init, self);

  g_mutex_lock (&self->priv->mutex);

  while (!self->priv->initialized) {
    g_cond_wait (&self->priv->cond, &self->priv->mutex);
  }

  g_mutex_unlock (&self->priv->mutex);
}

KmsHttpLoop *
kms_http_loop_new (void)
{
  return KMS_HTTP_LOOP (g_object_new (KMS_TYPE_HTTP_LOOP, NULL) );
}

static guint
kms_http_loop_attach (KmsHttpLoop *self, GSource *source, gint priority,
                      GSourceFunc function, gpointer data,
                      GDestroyNotify notify)
{
  guint id;

  KMS_HTTP_LOOP_LOCK (self);

  if (self->priv->thread == NULL) {
    KMS_HTTP_LOOP_UNLOCK (self);
    return 0;
  }

  g_source_set_priority (source, priority);
  g_source_set_callback (source, function, data, notify);
  id = g_source_attach (source, self->priv->context);

  KMS_HTTP_LOOP_UNLOCK (self);

  return id;
}

guint
kms_http_loop_idle_add_full (KmsHttpLoop *self, gint priority,
                             GSourceFunc function,
                             gpointer data, GDestroyNotify notify)
{
  GSource *source;
  guint id;

  if (!KMS_IS_HTTP_LOOP (self) ) {
    return 0;
  }

  source = g_idle_source_new ();
  id = kms_http_loop_attach (self, source, priority, function, data, notify);
  g_source_unref (source);

  return id;
}

guint
kms_http_loop_idle_add (KmsHttpLoop *self, GSourceFunc function, gpointer data)
{
  return kms_http_loop_idle_add_full (self, G_PRIORITY_DEFAULT_IDLE, function,
                                      data,
                                      NULL);
}

guint
kms_http_loop_timeout_add_full (KmsHttpLoop *self, gint priority,
                                guint interval,
                                GSourceFunc function, gpointer data,
                                GDestroyNotify notify)
{
  GSource *source;
  guint id;

  if (!KMS_IS_HTTP_LOOP (self) ) {
    return 0;
  }

  source = g_timeout_source_new (interval);
  id = kms_http_loop_attach (self, source, priority, function, data, notify);
  g_source_unref (source);

  return id;
}

guint
kms_http_loop_timeout_add (KmsHttpLoop *self, guint interval,
                           GSourceFunc function,
                           gpointer data)
{
  return kms_http_loop_timeout_add_full (self, G_PRIORITY_DEFAULT, interval,
                                         function, data, NULL);
}

gboolean
kms_http_loop_remove (KmsHttpLoop *self, guint source_id)
{
  GSource *source;

  source = g_main_context_find_source_by_id (self->priv->context, source_id);

  if (source == NULL) {
    return FALSE;
  }

  g_source_destroy (source);
  return TRUE;
}

gboolean
kms_http_loop_is_current_thread (KmsHttpLoop *self)
{
  return (g_thread_self() == self->priv->thread);
}
<commit_msg>KmsHttpLoop: Thread should hold its own reference of context and loop<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

#include "KmsHttpLoop.h"

#define NAME "httploop"

GST_DEBUG_CATEGORY_STATIC (kms_http_loop_debug_category);
#define GST_CAT_DEFAULT kms_http_loop_debug_category

G_DEFINE_TYPE_WITH_CODE (KmsHttpLoop, kms_http_loop,
                         G_TYPE_OBJECT,
                         GST_DEBUG_CATEGORY_INIT (kms_http_loop_debug_category,
                             NAME, 0, "debug category for kurento loop") )

#define KMS_HTTP_LOOP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KMS_TYPE_HTTP_LOOP, KmsHttpLoopPrivate))

struct _KmsHttpLoopPrivate {
  GThread *thread;
  GRecMutex rmutex;
  GMainLoop *loop;
  GMainContext *context;
  GCond cond;
  GMutex mutex;
  gboolean initialized;
};

#define KMS_HTTP_LOOP_LOCK(elem) \
  (g_rec_mutex_lock (&KMS_HTTP_LOOP ((elem))->priv->rmutex))
#define KMS_HTTP_LOOP_UNLOCK(elem) \
  (g_rec_mutex_unlock (&KMS_HTTP_LOOP ((elem))->priv->rmutex))

/* Object properties */
enum {
  PROP_0,
  PROP_CONTEXT,
  N_PROPERTIES
};

static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

static gboolean
quit_main_loop (KmsHttpLoop *self)
{
  GST_DEBUG ("Exiting main loop");

  g_main_loop_quit (self->priv->loop);

  return G_SOURCE_REMOVE;
}

static gpointer
loop_thread_init (gpointer data)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (data);
  GMainLoop *loop;
  GMainContext *context;

  KMS_HTTP_LOOP_LOCK (self);
  self->priv->context = g_main_context_new ();
  context = g_main_context_ref (self->priv->context);
  self->priv->loop = g_main_loop_new (context, FALSE);
  loop = g_main_loop_ref (self->priv->loop);
  KMS_HTTP_LOOP_UNLOCK (self);

  /* unlock main process because context is already initialized */
  g_mutex_lock (&self->priv->mutex);
  self->priv->initialized = TRUE;
  g_cond_signal (&self->priv->cond);
  g_mutex_unlock (&self->priv->mutex);

  if (!g_main_context_acquire (context) ) {
    GST_ERROR ("Can not acquire context");
    goto end;
  }

  GST_DEBUG ("Running main loop");
  g_main_loop_run (loop);
  g_main_context_release (context);

end:
  GST_DEBUG ("Thread finished");
  g_main_loop_unref (loop);
  g_main_context_unref (context);

  return NULL;
}

static void
kms_http_loop_get_property (GObject *object, guint property_id, GValue *value,
                            GParamSpec *pspec)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (object);

  KMS_HTTP_LOOP_LOCK (self);

  switch (property_id) {
  case PROP_CONTEXT:
    g_value_set_boxed (value, self->priv->context);
    break;

  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    break;
  }

  KMS_HTTP_LOOP_UNLOCK (self);
}

static void
kms_http_loop_dispose (GObject *obj)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (obj);

  GST_DEBUG_OBJECT (obj, "Dispose");

  KMS_HTTP_LOOP_LOCK (self);

  if (self->priv->thread != NULL) {
    if (g_thread_self () != self->priv->thread) {
      GThread *aux = self->priv->thread;

      kms_http_loop_idle_add (self, (GSourceFunc) quit_main_loop,
                              self);
      self->priv->thread = NULL;
      KMS_HTTP_LOOP_UNLOCK (self);
      g_thread_join (aux);
      KMS_HTTP_LOOP_LOCK (self);
    } else {
      /* self thread does not need to wait for itself */
      quit_main_loop (self);
      g_thread_unref (self->priv->thread);
      self->priv->thread = NULL;
    }
  }

  KMS_HTTP_LOOP_UNLOCK (self);

  G_OBJECT_CLASS (kms_http_loop_parent_class)->dispose (obj);
}

static void
kms_http_loop_finalize (GObject *obj)
{
  KmsHttpLoop *self = KMS_HTTP_LOOP (obj);

  GST_DEBUG_OBJECT (obj, "Finalize");

  if (self->priv->context != NULL) {
    g_main_context_unref (self->priv->context);
  }

  if (self->priv->loop != NULL) {
    g_main_loop_unref (self->priv->loop);
  }

  g_rec_mutex_clear (&self->priv->rmutex);
  g_mutex_clear (&self->priv->mutex);
  g_cond_clear (&self->priv->cond);

  G_OBJECT_CLASS (kms_http_loop_parent_class)->finalize (obj);
}

static void
kms_http_loop_class_init (KmsHttpLoopClass *klass)
{
  GObjectClass *objclass = G_OBJECT_CLASS (klass);

  objclass->dispose = kms_http_loop_dispose;
  objclass->finalize = kms_http_loop_finalize;
  objclass->get_property = kms_http_loop_get_property;

  /* Install properties */
  obj_properties[PROP_CONTEXT] = g_param_spec_boxed ("context",
                                 "Main loop context",
                                 "Main loop context",
                                 G_TYPE_MAIN_CONTEXT,
                                 (GParamFlags) (G_PARAM_READABLE) );

  g_object_class_install_properties (objclass, N_PROPERTIES, obj_properties);

  /* Registers a private structure for the instantiatable type */
  g_type_class_add_private (klass, sizeof (KmsHttpLoopPrivate) );
}

static void
kms_http_loop_init (KmsHttpLoop *self)
{
  self->priv = KMS_HTTP_LOOP_GET_PRIVATE (self);
  self->priv->context = NULL;
  self->priv->loop = NULL;
  g_rec_mutex_init (&self->priv->rmutex);
  g_cond_init (&self->priv->cond);
  g_mutex_init (&self->priv->mutex);

  self->priv->thread = g_thread_new ("KmsHttpLoop", loop_thread_init, self);

  g_mutex_lock (&self->priv->mutex);

  while (!self->priv->initialized) {
    g_cond_wait (&self->priv->cond, &self->priv->mutex);
  }

  g_mutex_unlock (&self->priv->mutex);
}

KmsHttpLoop *
kms_http_loop_new (void)
{
  return KMS_HTTP_LOOP (g_object_new (KMS_TYPE_HTTP_LOOP, NULL) );
}

static guint
kms_http_loop_attach (KmsHttpLoop *self, GSource *source, gint priority,
                      GSourceFunc function, gpointer data,
                      GDestroyNotify notify)
{
  guint id;

  KMS_HTTP_LOOP_LOCK (self);

  if (self->priv->thread == NULL) {
    KMS_HTTP_LOOP_UNLOCK (self);
    return 0;
  }

  g_source_set_priority (source, priority);
  g_source_set_callback (source, function, data, notify);
  id = g_source_attach (source, self->priv->context);

  KMS_HTTP_LOOP_UNLOCK (self);

  return id;
}

guint
kms_http_loop_idle_add_full (KmsHttpLoop *self, gint priority,
                             GSourceFunc function,
                             gpointer data, GDestroyNotify notify)
{
  GSource *source;
  guint id;

  if (!KMS_IS_HTTP_LOOP (self) ) {
    return 0;
  }

  source = g_idle_source_new ();
  id = kms_http_loop_attach (self, source, priority, function, data, notify);
  g_source_unref (source);

  return id;
}

guint
kms_http_loop_idle_add (KmsHttpLoop *self, GSourceFunc function, gpointer data)
{
  return kms_http_loop_idle_add_full (self, G_PRIORITY_DEFAULT_IDLE, function,
                                      data,
                                      NULL);
}

guint
kms_http_loop_timeout_add_full (KmsHttpLoop *self, gint priority,
                                guint interval,
                                GSourceFunc function, gpointer data,
                                GDestroyNotify notify)
{
  GSource *source;
  guint id;

  if (!KMS_IS_HTTP_LOOP (self) ) {
    return 0;
  }

  source = g_timeout_source_new (interval);
  id = kms_http_loop_attach (self, source, priority, function, data, notify);
  g_source_unref (source);

  return id;
}

guint
kms_http_loop_timeout_add (KmsHttpLoop *self, guint interval,
                           GSourceFunc function,
                           gpointer data)
{
  return kms_http_loop_timeout_add_full (self, G_PRIORITY_DEFAULT, interval,
                                         function, data, NULL);
}

gboolean
kms_http_loop_remove (KmsHttpLoop *self, guint source_id)
{
  GSource *source;

  source = g_main_context_find_source_by_id (self->priv->context, source_id);

  if (source == NULL) {
    return FALSE;
  }

  g_source_destroy (source);
  return TRUE;
}

gboolean
kms_http_loop_is_current_thread (KmsHttpLoop *self)
{
  return (g_thread_self() == self->priv->thread);
}
<|endoftext|>


<commit_before>#include "EsCenterLines.h"

const char *plugin_name{ "EsCenterLines" };
const char *plugin_version{ "1.2" };
const char *plugin_author{ "Oliver Grtzmann" };
const char *plugin_license{ "tbd" };

EsCenterLines::EsCenterLines()
	: EuroScopePlugIn::CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, plugin_name, plugin_version, plugin_author, plugin_license)
{
	ReadRunways();
	EuroScopePlugIn::CPlugIn::RegisterDisplayType("Center Lines", false, true, false, false);
}

EsCenterLines::~EsCenterLines()
{
}

EuroScopePlugIn::CRadarScreen *EsCenterLines::OnRadarScreenCreated(const char *sDisplayName, bool NeedRadarContent, bool GeoReferenced, bool CanBeSaved, bool CanBeCreated)
{
	if (GeoReferenced)
	{
		auto cls = new CenterLinesScreen(lines, ticks, screens);
		screens.push_back(cls);
		return cls;
	}
	return nullptr;
}

void EsCenterLines::OnAirportRunwayActivityChanged()
{
	ReadRunways();
	for (auto x : screens)
		x->RefreshMapContent();

}

void EsCenterLines::CalculateLine(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	double gl, ll, glll, dist;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	for (auto centerlines : rd.runway_settings.lines)
	{
		gl = NauticalMiles(centerlines.length_gap);
		ll = NauticalMiles(centerlines.length_line);
		glll = gl + ll;
		dist = centerlines.starts_with_line ? 0 : gl;
		dist += NauticalMiles(centerlines.distance_thr);
		for (auto i = 0; i < centerlines.repeats; ++i)
		{
			double lat, lon, lat2, lon2;
			gd_line.Position(dist, lat, lon);
			gd_line.Position(dist + ll, lat2, lon2);
			lines.push_back({ { lat, lon }, { lat2, lon2 }, apt_act, rwy_act });
			dist += glll;
		}
	}
}

void EsCenterLines::CalculateSpecial(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	if (!rd.runway_settings.special.length)
		return;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	auto dist_thr = NauticalMiles(rd.runway_settings.special.distance_thr1);
	auto dist_thr2 = NauticalMiles(rd.runway_settings.special.distance_thr2);
	auto dist_thr3 = NauticalMiles(rd.runway_settings.special.distance_thr1 + rd.runway_settings.special.length);
	Coordinate origin, origin2, origin3, end, end2, end3;
	gd_line.Position(dist_thr, origin.latitude, origin.longitude);
	gd_line.Position(dist_thr2, origin2.latitude, origin2.longitude);
	gd_line.Position(dist_thr3, origin3.latitude, origin3.longitude);
	auto line_direction = (rd.runway_settings.special.direction == Direction::left ? rd.runway_heading_calculated - 180 + 90 : rd.runway_heading_calculated - 180 - 90);
	auto f_line = geo.Line(origin.latitude, origin.longitude, line_direction);
	auto f_line2 = geo.Line(origin2.latitude, origin2.longitude, line_direction);
	auto f_line3 = geo.Line(origin3.latitude, origin3.longitude, line_direction);
	f_line.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end.latitude, end.longitude);
	f_line2.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end2.latitude, end2.longitude);
	f_line3.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end3.latitude, end3.longitude);
	lines.push_back({ origin, end, apt_act, rwy_act });
	lines.push_back({ origin2, end2, apt_act, rwy_act });
	lines.push_back({ end, end3, apt_act, rwy_act });
}

void EsCenterLines::CalculateTicks(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	double dist_thr, dist_cl, length;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	for (auto rangeticks : rd.runway_settings.ticks)
	{
		dist_thr = NauticalMiles(rangeticks.distance_thr);
		dist_cl = NauticalMiles(rangeticks.distance_cl);
		length = NauticalMiles(rangeticks.length);
		Coordinate tick_origin;
		gd_line.Position(dist_thr, tick_origin.latitude, tick_origin.longitude);

		if (rangeticks.direction == Direction::left || rangeticks.direction == Direction::both)
		{
			auto tick_line = geo.Line(tick_origin.latitude, tick_origin.longitude, rd.runway_heading_calculated - 180 + rangeticks.angle);
			Coordinate tick_left_start, tick_left_end;
			tick_line.Position(dist_cl, tick_left_start.latitude, tick_left_start.longitude);
			tick_line.Position(dist_cl + length, tick_left_end.latitude, tick_left_end.longitude);
			ticks.push_back({ tick_left_start, tick_left_end, apt_act, rwy_act });
		}

		if (rangeticks.direction == Direction::right || rangeticks.direction == Direction::both)
		{
			auto tick_line = geo.Line(tick_origin.latitude, tick_origin.longitude, rd.runway_heading_calculated - 180 - rangeticks.angle);
			Coordinate tick_right_start, tick_right_end;
			tick_line.Position(dist_cl, tick_right_start.latitude, tick_right_start.longitude);
			tick_line.Position(dist_cl + length, tick_right_end.latitude, tick_right_end.longitude);
			ticks.push_back({ tick_right_start, tick_right_end, apt_act, rwy_act });
		}
	}
}

bool EsCenterLines::GetFixPosition(const std::string &fix, const EuroScopePlugIn::CPosition &threshold, Coordinate &coord)
{
	SelectActiveSectorfile();
	for (auto element = SectorFileElementSelectFirst(EuroScopePlugIn::SECTOR_ELEMENT_FIX); element.IsValid(); element = SectorFileElementSelectNext(element, EuroScopePlugIn::SECTOR_ELEMENT_FIX))
	{
	SectorContainer container(this, EuroScopePlugIn::SECTOR_ELEMENT_FIX);
		if (!strcmp(element.GetName(), fix.c_str()))
		{
			EuroScopePlugIn::CPosition position;
			element.GetPosition(&position, 0);
			if (position.DistanceTo(threshold) > 30)
				continue;
			coord.latitude = position.m_Latitude;
			coord.longitude = position.m_Longitude;
			return true;
		}
	}
	return false;
}

bool EsCenterLines::GetRunwaySettings(const std::string &airport, const std::string &runway, Runway_Settings &rws)
{
	Settings set;
	for (auto apt : set.apts)
	{
		if (airport.starts_with(apt.airport))
		{
			for (auto rwy : apt.runways)
			{
				if (rwy.runway == runway)
				{
					if (rwy.lines.size() == 0)
						rwy.lines = apt.lines;
					if (rwy.ticks.size() == 0)
						rwy.ticks = apt.ticks;
					rws = rwy;
					return true;
				}
			}
		}
	}
	return false;
}

bool EsCenterLines::IsAirportActive(const std::string &airport)
{
	SectorContainer container(this, EuroScopePlugIn::SECTOR_ELEMENT_AIRPORT);
	for (auto apt : container)
	{
		std::string name = apt.GetName();
		if (apt.IsElementActive(false) && airport.starts_with(name))
			return true;
	}
	return false;
}

double EsCenterLines::NauticalMiles(double nm)
{
	return nm * GeographicLib::Constants::nauticalmile();
}

void EsCenterLines::ReadRunways()
{
	lines.clear();
	ticks.clear();
	SectorContainer container(this, EuroScopePlugIn::SECTOR_ELEMENT_RUNWAY);
	for (auto runway : container)
	{
		for (int i = 0; i < 2; ++i)
		{
			Runway_Definition rwy;
			rwy.runway_designator = runway.GetRunwayName(i);
			rwy.airport_name = runway.GetAirportName();
			rwy.active_arrival = runway.IsElementActive(false, i);
			rwy.apt_active_arrival = IsAirportActive(rwy.airport_name);

			if (!GetRunwaySettings(rwy.airport_name, rwy.runway_designator, rwy.runway_settings))
			{
				//get default
				int i = 0;
			}
			Coordinate coord;
			EuroScopePlugIn::CPosition threshold, end;
			runway.GetPosition(&threshold, i);
			runway.GetPosition(&end, i == 1 ? 0 : 1);
			rwy.runway_threshold.latitude = threshold.m_Latitude;
			rwy.runway_threshold.longitude = threshold.m_Longitude;
			rwy.runway_end.latitude = end.m_Latitude;
			rwy.runway_end.longitude = end.m_Longitude;
			if (rwy.runway_settings.fix.size() && GetFixPosition(rwy.runway_settings.fix, threshold, coord))
			{
				double azi1, azi2;
				geo.Inverse(coord.latitude, coord.longitude, rwy.runway_threshold.latitude, rwy.runway_threshold.longitude, azi1, azi2);
				rwy.runway_heading_calculated = azi2;
			}
			else
			{
				double azi1, azi2;
				geo.Inverse(rwy.runway_threshold.latitude, rwy.runway_threshold.longitude, rwy.runway_end.latitude, rwy.runway_end.longitude, azi1, azi2);
				rwy.runway_heading_calculated = azi2;
			}
			CalculateLine(rwy, rwy.apt_active_arrival, rwy.active_arrival);
			CalculateTicks(rwy, rwy.apt_active_arrival, rwy.active_arrival);
			CalculateSpecial(rwy, rwy.apt_active_arrival, rwy.active_arrival);
		}
	}
}
<commit_msg>Removed SectorContainer from GetFixPosition<commit_after>#include "EsCenterLines.h"

const char *plugin_name{ "EsCenterLines" };
const char *plugin_version{ "1.2" };
const char *plugin_author{ "Oliver Grtzmann" };
const char *plugin_license{ "tbd" };

EsCenterLines::EsCenterLines()
	: EuroScopePlugIn::CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, plugin_name, plugin_version, plugin_author, plugin_license)
{
	ReadRunways();
	EuroScopePlugIn::CPlugIn::RegisterDisplayType("Center Lines", false, true, false, false);
}

EsCenterLines::~EsCenterLines()
{
}

EuroScopePlugIn::CRadarScreen *EsCenterLines::OnRadarScreenCreated(const char *sDisplayName, bool NeedRadarContent, bool GeoReferenced, bool CanBeSaved, bool CanBeCreated)
{
	if (GeoReferenced)
	{
		auto cls = new CenterLinesScreen(lines, ticks, screens);
		screens.push_back(cls);
		return cls;
	}
	return nullptr;
}

void EsCenterLines::OnAirportRunwayActivityChanged()
{
	ReadRunways();
	for (auto x : screens)
		x->RefreshMapContent();

}

void EsCenterLines::CalculateLine(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	double gl, ll, glll, dist;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	for (auto centerlines : rd.runway_settings.lines)
	{
		gl = NauticalMiles(centerlines.length_gap);
		ll = NauticalMiles(centerlines.length_line);
		glll = gl + ll;
		dist = centerlines.starts_with_line ? 0 : gl;
		dist += NauticalMiles(centerlines.distance_thr);
		for (auto i = 0; i < centerlines.repeats; ++i)
		{
			double lat, lon, lat2, lon2;
			gd_line.Position(dist, lat, lon);
			gd_line.Position(dist + ll, lat2, lon2);
			lines.push_back({ { lat, lon }, { lat2, lon2 }, apt_act, rwy_act });
			dist += glll;
		}
	}
}

void EsCenterLines::CalculateSpecial(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	if (!rd.runway_settings.special.length)
		return;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	auto dist_thr = NauticalMiles(rd.runway_settings.special.distance_thr1);
	auto dist_thr2 = NauticalMiles(rd.runway_settings.special.distance_thr2);
	auto dist_thr3 = NauticalMiles(rd.runway_settings.special.distance_thr1 + rd.runway_settings.special.length);
	Coordinate origin, origin2, origin3, end, end2, end3;
	gd_line.Position(dist_thr, origin.latitude, origin.longitude);
	gd_line.Position(dist_thr2, origin2.latitude, origin2.longitude);
	gd_line.Position(dist_thr3, origin3.latitude, origin3.longitude);
	auto line_direction = (rd.runway_settings.special.direction == Direction::left ? rd.runway_heading_calculated - 180 + 90 : rd.runway_heading_calculated - 180 - 90);
	auto f_line = geo.Line(origin.latitude, origin.longitude, line_direction);
	auto f_line2 = geo.Line(origin2.latitude, origin2.longitude, line_direction);
	auto f_line3 = geo.Line(origin3.latitude, origin3.longitude, line_direction);
	f_line.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end.latitude, end.longitude);
	f_line2.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end2.latitude, end2.longitude);
	f_line3.Position(NauticalMiles(rd.runway_settings.special.distance_cl), end3.latitude, end3.longitude);
	lines.push_back({ origin, end, apt_act, rwy_act });
	lines.push_back({ origin2, end2, apt_act, rwy_act });
	lines.push_back({ end, end3, apt_act, rwy_act });
}

void EsCenterLines::CalculateTicks(Runway_Definition &rd, bool apt_act, bool rwy_act)
{
	double dist_thr, dist_cl, length;
	auto gd_line = geo.Line(rd.runway_threshold.latitude, rd.runway_threshold.longitude, rd.runway_heading_calculated - 180);
	for (auto rangeticks : rd.runway_settings.ticks)
	{
		dist_thr = NauticalMiles(rangeticks.distance_thr);
		dist_cl = NauticalMiles(rangeticks.distance_cl);
		length = NauticalMiles(rangeticks.length);
		Coordinate tick_origin;
		gd_line.Position(dist_thr, tick_origin.latitude, tick_origin.longitude);

		if (rangeticks.direction == Direction::left || rangeticks.direction == Direction::both)
		{
			auto tick_line = geo.Line(tick_origin.latitude, tick_origin.longitude, rd.runway_heading_calculated - 180 + rangeticks.angle);
			Coordinate tick_left_start, tick_left_end;
			tick_line.Position(dist_cl, tick_left_start.latitude, tick_left_start.longitude);
			tick_line.Position(dist_cl + length, tick_left_end.latitude, tick_left_end.longitude);
			ticks.push_back({ tick_left_start, tick_left_end, apt_act, rwy_act });
		}

		if (rangeticks.direction == Direction::right || rangeticks.direction == Direction::both)
		{
			auto tick_line = geo.Line(tick_origin.latitude, tick_origin.longitude, rd.runway_heading_calculated - 180 - rangeticks.angle);
			Coordinate tick_right_start, tick_right_end;
			tick_line.Position(dist_cl, tick_right_start.latitude, tick_right_start.longitude);
			tick_line.Position(dist_cl + length, tick_right_end.latitude, tick_right_end.longitude);
			ticks.push_back({ tick_right_start, tick_right_end, apt_act, rwy_act });
		}
	}
}

bool EsCenterLines::GetFixPosition(const std::string &fix, const EuroScopePlugIn::CPosition &threshold, Coordinate &coord)
{
	SelectActiveSectorfile();
	for (auto element = SectorFileElementSelectFirst(EuroScopePlugIn::SECTOR_ELEMENT_FIX); element.IsValid(); element = SectorFileElementSelectNext(element, EuroScopePlugIn::SECTOR_ELEMENT_FIX))
	{
		if (!strcmp(element.GetName(), fix.c_str()))
		{
			EuroScopePlugIn::CPosition position;
			element.GetPosition(&position, 0);
			if (position.DistanceTo(threshold) > 30)
				continue;
			coord.latitude = position.m_Latitude;
			coord.longitude = position.m_Longitude;
			return true;
		}
	}
	return false;
}

bool EsCenterLines::GetRunwaySettings(const std::string &airport, const std::string &runway, Runway_Settings &rws)
{
	Settings set;
	for (auto apt : set.apts)
	{
		if (airport.starts_with(apt.airport))
		{
			for (auto rwy : apt.runways)
			{
				if (rwy.runway == runway)
				{
					if (rwy.lines.size() == 0)
						rwy.lines = apt.lines;
					if (rwy.ticks.size() == 0)
						rwy.ticks = apt.ticks;
					rws = rwy;
					return true;
				}
			}
		}
	}
	return false;
}

bool EsCenterLines::IsAirportActive(const std::string &airport)
{
	SectorContainer container(this, EuroScopePlugIn::SECTOR_ELEMENT_AIRPORT);
	for (auto apt : container)
	{
		std::string name = apt.GetName();
		if (apt.IsElementActive(false) && airport.starts_with(name))
			return true;
	}
	return false;
}

double EsCenterLines::NauticalMiles(double nm)
{
	return nm * GeographicLib::Constants::nauticalmile();
}

void EsCenterLines::ReadRunways()
{
	lines.clear();
	ticks.clear();
	SectorContainer container(this, EuroScopePlugIn::SECTOR_ELEMENT_RUNWAY);
	for (auto runway : container)
	{
		for (int i = 0; i < 2; ++i)
		{
			Runway_Definition rwy;
			rwy.runway_designator = runway.GetRunwayName(i);
			rwy.airport_name = runway.GetAirportName();
			rwy.active_arrival = runway.IsElementActive(false, i);
			rwy.apt_active_arrival = IsAirportActive(rwy.airport_name);

			if (!GetRunwaySettings(rwy.airport_name, rwy.runway_designator, rwy.runway_settings))
			{
				//get default
				int i = 0;
			}
			Coordinate coord;
			EuroScopePlugIn::CPosition threshold, end;
			runway.GetPosition(&threshold, i);
			runway.GetPosition(&end, i == 1 ? 0 : 1);
			rwy.runway_threshold.latitude = threshold.m_Latitude;
			rwy.runway_threshold.longitude = threshold.m_Longitude;
			rwy.runway_end.latitude = end.m_Latitude;
			rwy.runway_end.longitude = end.m_Longitude;
			if (rwy.runway_settings.fix.size() && GetFixPosition(rwy.runway_settings.fix, threshold, coord))
			{
				double azi1, azi2;
				geo.Inverse(coord.latitude, coord.longitude, rwy.runway_threshold.latitude, rwy.runway_threshold.longitude, azi1, azi2);
				rwy.runway_heading_calculated = azi2;
			}
			else
			{
				double azi1, azi2;
				geo.Inverse(rwy.runway_threshold.latitude, rwy.runway_threshold.longitude, rwy.runway_end.latitude, rwy.runway_end.longitude, azi1, azi2);
				rwy.runway_heading_calculated = azi2;
			}
			CalculateLine(rwy, rwy.apt_active_arrival, rwy.active_arrival);
			CalculateTicks(rwy, rwy.apt_active_arrival, rwy.active_arrival);
			CalculateSpecial(rwy, rwy.apt_active_arrival, rwy.active_arrival);
		}
	}
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
/// This mini-app demonstrates a breadth-first-search of the built-in
/// graph data structure. This implement's Graph500's BFS benchmark:
/// - Uses the Graph500 Specification Kronecker graph generator with
///   numVertices = 2^scale (--scale specified on command-line)
/// - Uses the builtin hybrid compressed-sparse-row graph format
/// - Computes the 'parent' tree given a root, and does this a number
///   of times (specified by --nbfs).
////////////////////////////////////////////////////////////////////////

#include "common.hpp"

DEFINE_bool( metrics, false, "Dump metrics");

DEFINE_int32(scale, 10, "Log2 number of vertices.");
DEFINE_int32(edgefactor, 16, "Average number of edges per vertex.");
DEFINE_int32(nbfs, 1, "Number of BFS traversals to do.");

GRAPPA_DEFINE_METRIC(SummarizingMetric<double>, bfs_mteps, 0);
GRAPPA_DEFINE_METRIC(SummarizingMetric<double>, bfs_time, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<int64_t>, bfs_nedge, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<double>, graph_create_time, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<double>, verify_time, 0);

int64_t nedge_traversed;

int main(int argc, char* argv[]) {
  init(&argc, &argv);
  run([]{
    int64_t NE = (1L << FLAGS_scale) * FLAGS_edgefactor;
    bool verified = false;
    double t;

    t = walltime();

    // generate "NE" edge tuples, sampling vertices using the
    // Graph500 Kronecker generator to get a power-law graph
    auto tg = TupleGraph::Kronecker(FLAGS_scale, NE, 111, 222);

    // construct the compact graph representation (roughly CSR)
    auto g = Graph<BFSVertex>::create( tg );

    graph_create_time = (walltime()-t);
    LOG(INFO) << graph_create_time;

    auto frontier = GlobalVector<int64_t>::create(g->nv);
    auto next     = GlobalVector<int64_t>::create(g->nv);

    // do BFS from multiple different roots and average their times
    for (int root_idx = 0; root_idx < FLAGS_nbfs; root_idx++) {

      // intialize parent to -1
      forall(g, [](BFSVertex& v){ v->init(); });

      int64_t root = choose_root(g);
      VLOG(1) << "root => " << root;

      // setup 'root' as the parent of itself
      delegate::call(g->vs+root, [=](BFSVertex& v){ v->parent = root; });

      // reset frontier queues
      next->clear();
      frontier->clear();

      // start with root as only thing in frontier
      frontier->push(root);

      t = walltime();

      while (!frontier->empty()) {
        // iterate over vertices in this level of the frontier
        forall(frontier, [g,next](int64_t& i){
          // visit all the adjacencies of the vertex
          // note: this has to be 'async' to prevent deadlock from
          //       running out of available workers
          forall<async>(adj(g,g->vs+i),
            [i,next](int64_t j, GlobalAddress<BFSVertex> vj)
          {
            // at the core where the vertex is...
            bool claimed = delegate::call(vj, [i](BFSVertex& v){
              // note: no synchronization needed because 'call' is
              // guaranteed to be executed atomically because it
              // does no blocking operations
              if (v->parent == -1) {
                // claim parenthood
                v->parent = i;
                return true;
              }
              return false;
            });
            if (claimed) {
              // add this vertex to the frontier for the next level
              // note: we (currently) can't do this 'push' inside the delegate because it may block
              next->push(j);
            }
          });
        });
        // switch to next frontier level
        std::swap(frontier, next);
        next->clear();
      }

      double this_bfs_time = walltime() - t;
      LOG(INFO) << "(root=" << root << ", time=" << this_bfs_time << ")";
      bfs_time += this_bfs_time;

      if (!verified) {
        // only verify the first one to save time
        t = walltime();
        bfs_nedge = verify(tg, g, root);
        verify_time = (walltime()-t);
        LOG(INFO) << verify_time;
        verified = true;
      }

      bfs_mteps += bfs_nedge / this_bfs_time / 1.0e6;
    }

    LOG(INFO) << "\n" << bfs_nedge << "\n" << bfs_time << "\n" << bfs_mteps;

    if (FLAGS_metrics) Metrics::merge_and_print();
    Metrics::merge_and_dump_to_file();

    tg.destroy();
    g->destroy();
    frontier->destroy();
    next->destroy();
  });
  finalize();
}
<commit_msg>modify bfs example to support file input<commit_after>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
/// This mini-app demonstrates a breadth-first-search of the built-in
/// graph data structure. This implement's Graph500's BFS benchmark:
/// - Uses the Graph500 Specification Kronecker graph generator with
///   numVertices = 2^scale (--scale specified on command-line)
/// - Uses the builtin hybrid compressed-sparse-row graph format
/// - Computes the 'parent' tree given a root, and does this a number
///   of times (specified by --nbfs).
////////////////////////////////////////////////////////////////////////

#include "common.hpp"

DEFINE_bool( metrics, false, "Dump metrics");

DEFINE_int32(scale, 10, "Log2 number of vertices.");
DEFINE_int32(edgefactor, 16, "Average number of edges per vertex.");
DEFINE_int32(nbfs, 1, "Number of BFS traversals to do.");

GRAPPA_DEFINE_METRIC(SummarizingMetric<double>, bfs_mteps, 0);
GRAPPA_DEFINE_METRIC(SummarizingMetric<double>, bfs_time, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<int64_t>, bfs_nedge, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<double>, graph_create_time, 0);
GRAPPA_DEFINE_METRIC(SimpleMetric<double>, verify_time, 0);

int64_t nedge_traversed;

int main(int argc, char* argv[]) {
  init(&argc, &argv);
  run([]{
    int64_t NE = (1L << FLAGS_scale) * FLAGS_edgefactor;
    bool verified = false;
    double t;

    t = walltime();

    TupleGraph tg;

    // generate "NE" edge tuples, sampling vertices using the
    // Graph500 Kronecker generator to get a power-law graph
    tg = TupleGraph::Kronecker(FLAGS_scale, NE, 111, 222);

    // construct the compact graph representation (roughly CSR)
    auto g = Graph<BFSVertex>::create( tg );

    graph_create_time = (walltime()-t);
    LOG(INFO) << graph_create_time;

    auto frontier = GlobalVector<int64_t>::create(g->nv);
    auto next     = GlobalVector<int64_t>::create(g->nv);

    // do BFS from multiple different roots and average their times
    for (int root_idx = 0; root_idx < FLAGS_nbfs; root_idx++) {

      // intialize parent to -1
      forall(g, [](BFSVertex& v){ v->init(); });

      int64_t root = choose_root(g);
      VLOG(1) << "root => " << root;

      // setup 'root' as the parent of itself
      delegate::call(g->vs+root, [=](BFSVertex& v){ v->parent = root; });

      // reset frontier queues
      next->clear();
      frontier->clear();

      // start with root as only thing in frontier
      frontier->push(root);

      t = walltime();

      while (!frontier->empty()) {
        // iterate over vertices in this level of the frontier
        forall(frontier, [g,next](int64_t& i){
          // visit all the adjacencies of the vertex
          // note: this has to be 'async' to prevent deadlock from
          //       running out of available workers
          forall<async>(adj(g,g->vs+i),
            [i,next](int64_t j, GlobalAddress<BFSVertex> vj)
          {
            // at the core where the vertex is...
            bool claimed = delegate::call(vj, [i](BFSVertex& v){
              // note: no synchronization needed because 'call' is
              // guaranteed to be executed atomically because it
              // does no blocking operations
              if (v->parent == -1) {
                // claim parenthood
                v->parent = i;
                return true;
              }
              return false;
            });
            if (claimed) {
              // add this vertex to the frontier for the next level
              // note: we (currently) can't do this 'push' inside the delegate because it may block
              next->push(j);
            }
          });
        });
        // switch to next frontier level
        std::swap(frontier, next);
        next->clear();
      }

      double this_bfs_time = walltime() - t;
      LOG(INFO) << "(root=" << root << ", time=" << this_bfs_time << ")";
      bfs_time += this_bfs_time;

      if (!verified) {
        // only verify the first one to save time
        t = walltime();
        bfs_nedge = verify(tg, g, root);
        verify_time = (walltime()-t);
        LOG(INFO) << verify_time;
        verified = true;
      }

      bfs_mteps += bfs_nedge / this_bfs_time / 1.0e6;
    }

    LOG(INFO) << "\n" << bfs_nedge << "\n" << bfs_time << "\n" << bfs_mteps;

    if (FLAGS_metrics) Metrics::merge_and_print();
    Metrics::merge_and_dump_to_file();

    tg.destroy();
    g->destroy();
    frontier->destroy();
    next->destroy();
  });
  finalize();
}
<|endoftext|>