<commit_before>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

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

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

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

 //
Miscellaneous Example 6 - Meshing with LibMesh's TetGen and Triangle Interfaces

 //
 // LibMesh provides interfaces to both Triangle and TetGen for generating
 // Delaunay triangulations and tetrahedralizations in two and three dimensions
 // (respectively).

// Local header files
#include "libmesh/elem.h"
#include "libmesh/face_tri3.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_tetgen_interface.h"
#include "libmesh/mesh_triangle_holes.h"
#include "libmesh/mesh_triangle_interface.h"
#include "libmesh/node.h"
#include "libmesh/serial_mesh.h"

// Bring in everything from the libMesh namespace
using namespace libMesh;

// Major functions called by main
void triangulate_domain(const Parallel::Communicator& comm);
void tetrahedralize_domain(const Parallel::Communicator& comm);

// Helper routine for tetrahedralize_domain().  Adds the points and elements
// of a convex hull generated by TetGen to the input mesh
void add_cube_convex_hull_to_mesh(MeshBase& mesh, Point lower_limit, Point upper_limit);

// Begin the main program.
int main (int argc, char** argv)
{
  // Initialize libMesh and any dependent libaries, like in example 2.
  LibMeshInit init (argc, argv);

  libmesh_example_assert(2 <= LIBMESH_DIM, "2D support");

  std::cout << "Triangulating an L-shaped domain with holes" << std::endl;

  // 1.) 2D triangulation of L-shaped domain with three holes of different shape
  triangulate_domain(init.comm);

  libmesh_example_assert(3 <= LIBMESH_DIM, "3D support");

  std::cout << "Tetrahedralizing a prismatic domain with a hole" << std::endl;

  // 2.) 3D tetrahedralization of rectangular domain with hole.
  tetrahedralize_domain(init.comm);

  return 0;
}

void triangulate_domain(const Parallel::Communicator& comm)
{
#ifdef LIBMESH_HAVE_TRIANGLE
  // Use typedefs for slightly less typing.
  typedef TriangleInterface::Hole Hole;
  typedef TriangleInterface::PolygonHole PolygonHole;
  typedef TriangleInterface::ArbitraryHole ArbitraryHole;

  // Libmesh mesh that will eventually be created.
  Mesh mesh(2, comm);

  // The points which make up the L-shape:
  mesh.add_point(Point( 0. ,  0.));
  mesh.add_point(Point( 0. , -1.));
  mesh.add_point(Point(-1. , -1.));
  mesh.add_point(Point(-1. ,  1.));
  mesh.add_point(Point( 1. ,  1.));
  mesh.add_point(Point( 1. ,  0.));

  // Declare the TriangleInterface object.  This is where
  // we can set parameters of the triangulation and where the
  // actual triangulate function lives.
  TriangleInterface t(mesh);

  // Customize the variables for the triangulation
  t.desired_area()       = .01;

  // A Planar Straight Line Graph (PSLG) is essentially a list
  // of segments which have to exist in the final triangulation.
  // For an L-shaped domain, Triangle will compute the convex
  // hull of boundary points if we do not specify the PSLG.
  // The PSLG algorithm is also required for triangulating domains
  // containing holes
  t.triangulation_type() = TriangleInterface::PSLG;

  // Turn on/off Laplacian mesh smoothing after generation.
  // By default this is on.
  t.smooth_after_generating() = true;

  // Define holes...

  // hole_1 is a circle (discretized by 50 points)
  PolygonHole hole_1(Point(-0.5,  0.5), // center
		     0.25,              // radius
		     50);               // n. points

  // hole_2 is itself a triangle
  PolygonHole hole_2(Point(0.5, 0.5),   // center
		     0.1,               // radius
		     3);                // n. points

  // hole_3 is an ellipse of 100 points which we define here
  Point ellipse_center(-0.5,  -0.5);
  const unsigned int n_ellipse_points=100;
  std::vector<Point> ellipse_points(n_ellipse_points);
  const Real
    dtheta = 2*libMesh::pi / static_cast<Real>(n_ellipse_points),
    a = .1,
    b = .2;

  for (unsigned int i=0; i<n_ellipse_points; ++i)
    ellipse_points[i]= Point(ellipse_center(0)+a*cos(i*dtheta),
			     ellipse_center(1)+b*sin(i*dtheta));

  ArbitraryHole hole_3(ellipse_center, ellipse_points);

  // Create the vector of Hole*'s ...
  std::vector<Hole*> holes;
  holes.push_back(&hole_1);
  holes.push_back(&hole_2);
  holes.push_back(&hole_3);

  // ... and attach it to the triangulator object
  t.attach_hole_list(&holes);

  // Triangulate!
  t.triangulate();

  // Write the result to file
  mesh.write("delaunay_l_shaped_hole.e");

#endif // LIBMESH_HAVE_TRIANGLE
}

void tetrahedralize_domain(const Parallel::Communicator& comm)
{
#ifdef LIBMESH_HAVE_TETGEN
  // The algorithm is broken up into several steps:
  // 1.) A convex hull is constructed for a rectangular hole.
  // 2.) A convex hull is constructed for the domain exterior.
  // 3.) Neighbor information is updated so TetGen knows there is a convex hull
  // 4.) A vector of hole points is created.
  // 5.) The domain is tetrahedralized, the mesh is written out, etc.

  // The mesh we will eventually generate
  SerialMesh mesh(3,comm);

  // Lower and Upper bounding box limits for a rectangular hole within the unit cube.
  Point hole_lower_limit(0.2, 0.2, 0.4);
  Point hole_upper_limit(0.8, 0.8, 0.6);

  // 1.) Construct a convex hull for the hole
  add_cube_convex_hull_to_mesh(mesh, hole_lower_limit, hole_upper_limit);

  // 2.) Generate elements comprising the outer boundary of the domain.
  add_cube_convex_hull_to_mesh(mesh, Point(0.,0.,0.), Point(1., 1., 1.));

  // 3.) Update neighbor information so that TetGen can verify there is a convex hull.
  mesh.find_neighbors();

  // 4.) Set up vector of hole points
  std::vector<Point> hole(1);
  hole[0] = Point( 0.5*(hole_lower_limit + hole_upper_limit) );

  // 5.) Set parameters and tetrahedralize the domain

  // 0 means "use TetGen default value"
  Real quality_constraint = 2.0;

  // The volume constraint determines the max-allowed tetrahedral
  // volume in the Mesh.  TetGen will split cells which are larger than
  // this size
  Real volume_constraint = 0.001;

  // Construct the Delaunay tetrahedralization
  TetGenMeshInterface t(mesh);
  t.triangulate_conformingDelaunayMesh_carvehole(hole,
						 quality_constraint,
						 volume_constraint);

  // Find neighbors, etc in preparation for writing out the Mesh
  mesh.prepare_for_use();

  // Finally, write out the result
  mesh.write("hole_3D.e");
#endif // LIBMESH_HAVE_TETGEN
}

void add_cube_convex_hull_to_mesh(MeshBase& mesh, Point lower_limit, Point upper_limit)
{
#ifdef LIBMESH_HAVE_TETGEN
  SerialMesh cube_mesh(3);

  unsigned n_elem = 1;

  MeshTools::Generation::build_cube(cube_mesh,
				    n_elem,n_elem,n_elem, // n. elements in each direction
				    lower_limit(0), upper_limit(0),
				    lower_limit(1), upper_limit(1),
				    lower_limit(2), upper_limit(2),
				    HEX8);

  // The pointset_convexhull() algorithm will ignore the Hex8s
  // in the Mesh, and just construct the triangulation
  // of the convex hull.
  TetGenMeshInterface t(cube_mesh);
  t.pointset_convexhull();

  // Now add all nodes from the boundary of the cube_mesh to the input mesh.

  // Map from "node id in cube_mesh" -> "node id in mesh".  Initially inserted
  // with a dummy value, later to be assigned a value by the input mesh.
  std::map<unsigned,unsigned> node_id_map;
  typedef std::map<unsigned,unsigned>::iterator iterator;

  {
    MeshBase::element_iterator it = cube_mesh.elements_begin();
    const MeshBase::element_iterator end = cube_mesh.elements_end();
    for ( ; it != end; ++it)
      {
	Elem* elem = *it;

	for (unsigned s=0; s<elem->n_sides(); ++s)
	  if (elem->neighbor(s) == NULL)
	    {
	      // Add the node IDs of this side to the set
	      AutoPtr<Elem> side = elem->side(s);

	      for (unsigned n=0; n<side->n_nodes(); ++n)
		node_id_map.insert( std::make_pair(side->node(n), /*dummy_value=*/0) );
	    }
      }
  }

  // For each node in the map, insert it into the input mesh and keep
  // track of the ID assigned.
  for (iterator it=node_id_map.begin(); it != node_id_map.end(); ++it)
    {
      // Id of the node in the cube mesh
      unsigned id = (*it).first;

      // Pointer to node in the cube mesh
      Node* old_node = cube_mesh.node_ptr(id);

      // Add geometric point to input mesh
      Node* new_node = mesh.add_point ( *old_node );

      // Track ID value of new_node in map
      (*it).second = new_node->id();
    }

  // With the points added and the map data structure in place, we are
  // ready to add each TRI3 element of the cube_mesh to the input Mesh
  // with proper node assignments
  {
    MeshBase::element_iterator       el     = cube_mesh.elements_begin();
    const MeshBase::element_iterator end_el = cube_mesh.elements_end();

    for (; el != end_el; ++el)
      {
	Elem* old_elem = *el;

	if (old_elem->type() == TRI3)
	  {
	    Elem* new_elem = mesh.add_elem(new Tri3);

	    // Assign nodes in new elements.  Since this is an example,
	    // we'll do it in several steps.
	    for (unsigned i=0; i<old_elem->n_nodes(); ++i)
	      {
		// Locate old node ID in the map
		iterator it = node_id_map.find(old_elem->node(i));

		// Check for not found
		if (it == node_id_map.end())
		  {
		    libMesh::err << "Node id " << old_elem->node(i) << " not found in map!" << std::endl;
		    libmesh_error();
		  }

		// Mapping to node ID in input mesh
		unsigned new_node_id = (*it).second;

		// Node pointer assigned from input mesh
		new_elem->set_node(i) = mesh.node_ptr(new_node_id);
	      }
	  }
      }
  }
#endif // LIBMESH_HAVE_TETGEN
}
<commit_msg>Add communicator for miscellaneous_ex6 SerialMesh<commit_after>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

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

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

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

 //
Miscellaneous Example 6 - Meshing with LibMesh's TetGen and Triangle Interfaces

 //
 // LibMesh provides interfaces to both Triangle and TetGen for generating
 // Delaunay triangulations and tetrahedralizations in two and three dimensions
 // (respectively).

// Local header files
#include "libmesh/elem.h"
#include "libmesh/face_tri3.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_tetgen_interface.h"
#include "libmesh/mesh_triangle_holes.h"
#include "libmesh/mesh_triangle_interface.h"
#include "libmesh/node.h"
#include "libmesh/serial_mesh.h"

// Bring in everything from the libMesh namespace
using namespace libMesh;

// Major functions called by main
void triangulate_domain(const Parallel::Communicator& comm);
void tetrahedralize_domain(const Parallel::Communicator& comm);

// Helper routine for tetrahedralize_domain().  Adds the points and elements
// of a convex hull generated by TetGen to the input mesh
void add_cube_convex_hull_to_mesh(MeshBase& mesh, Point lower_limit, Point upper_limit);

// Begin the main program.
int main (int argc, char** argv)
{
  // Initialize libMesh and any dependent libaries, like in example 2.
  LibMeshInit init (argc, argv);

  libmesh_example_assert(2 <= LIBMESH_DIM, "2D support");

  std::cout << "Triangulating an L-shaped domain with holes" << std::endl;

  // 1.) 2D triangulation of L-shaped domain with three holes of different shape
  triangulate_domain(init.comm);

  libmesh_example_assert(3 <= LIBMESH_DIM, "3D support");

  std::cout << "Tetrahedralizing a prismatic domain with a hole" << std::endl;

  // 2.) 3D tetrahedralization of rectangular domain with hole.
  tetrahedralize_domain(init.comm);

  return 0;
}

void triangulate_domain(const Parallel::Communicator& comm)
{
#ifdef LIBMESH_HAVE_TRIANGLE
  // Use typedefs for slightly less typing.
  typedef TriangleInterface::Hole Hole;
  typedef TriangleInterface::PolygonHole PolygonHole;
  typedef TriangleInterface::ArbitraryHole ArbitraryHole;

  // Libmesh mesh that will eventually be created.
  Mesh mesh(2, comm);

  // The points which make up the L-shape:
  mesh.add_point(Point( 0. ,  0.));
  mesh.add_point(Point( 0. , -1.));
  mesh.add_point(Point(-1. , -1.));
  mesh.add_point(Point(-1. ,  1.));
  mesh.add_point(Point( 1. ,  1.));
  mesh.add_point(Point( 1. ,  0.));

  // Declare the TriangleInterface object.  This is where
  // we can set parameters of the triangulation and where the
  // actual triangulate function lives.
  TriangleInterface t(mesh);

  // Customize the variables for the triangulation
  t.desired_area()       = .01;

  // A Planar Straight Line Graph (PSLG) is essentially a list
  // of segments which have to exist in the final triangulation.
  // For an L-shaped domain, Triangle will compute the convex
  // hull of boundary points if we do not specify the PSLG.
  // The PSLG algorithm is also required for triangulating domains
  // containing holes
  t.triangulation_type() = TriangleInterface::PSLG;

  // Turn on/off Laplacian mesh smoothing after generation.
  // By default this is on.
  t.smooth_after_generating() = true;

  // Define holes...

  // hole_1 is a circle (discretized by 50 points)
  PolygonHole hole_1(Point(-0.5,  0.5), // center
		     0.25,              // radius
		     50);               // n. points

  // hole_2 is itself a triangle
  PolygonHole hole_2(Point(0.5, 0.5),   // center
		     0.1,               // radius
		     3);                // n. points

  // hole_3 is an ellipse of 100 points which we define here
  Point ellipse_center(-0.5,  -0.5);
  const unsigned int n_ellipse_points=100;
  std::vector<Point> ellipse_points(n_ellipse_points);
  const Real
    dtheta = 2*libMesh::pi / static_cast<Real>(n_ellipse_points),
    a = .1,
    b = .2;

  for (unsigned int i=0; i<n_ellipse_points; ++i)
    ellipse_points[i]= Point(ellipse_center(0)+a*cos(i*dtheta),
			     ellipse_center(1)+b*sin(i*dtheta));

  ArbitraryHole hole_3(ellipse_center, ellipse_points);

  // Create the vector of Hole*'s ...
  std::vector<Hole*> holes;
  holes.push_back(&hole_1);
  holes.push_back(&hole_2);
  holes.push_back(&hole_3);

  // ... and attach it to the triangulator object
  t.attach_hole_list(&holes);

  // Triangulate!
  t.triangulate();

  // Write the result to file
  mesh.write("delaunay_l_shaped_hole.e");

#endif // LIBMESH_HAVE_TRIANGLE
}

void tetrahedralize_domain(const Parallel::Communicator& comm)
{
#ifdef LIBMESH_HAVE_TETGEN
  // The algorithm is broken up into several steps:
  // 1.) A convex hull is constructed for a rectangular hole.
  // 2.) A convex hull is constructed for the domain exterior.
  // 3.) Neighbor information is updated so TetGen knows there is a convex hull
  // 4.) A vector of hole points is created.
  // 5.) The domain is tetrahedralized, the mesh is written out, etc.

  // The mesh we will eventually generate
  SerialMesh mesh(3,comm);

  // Lower and Upper bounding box limits for a rectangular hole within the unit cube.
  Point hole_lower_limit(0.2, 0.2, 0.4);
  Point hole_upper_limit(0.8, 0.8, 0.6);

  // 1.) Construct a convex hull for the hole
  add_cube_convex_hull_to_mesh(mesh, hole_lower_limit, hole_upper_limit);

  // 2.) Generate elements comprising the outer boundary of the domain.
  add_cube_convex_hull_to_mesh(mesh, Point(0.,0.,0.), Point(1., 1., 1.));

  // 3.) Update neighbor information so that TetGen can verify there is a convex hull.
  mesh.find_neighbors();

  // 4.) Set up vector of hole points
  std::vector<Point> hole(1);
  hole[0] = Point( 0.5*(hole_lower_limit + hole_upper_limit) );

  // 5.) Set parameters and tetrahedralize the domain

  // 0 means "use TetGen default value"
  Real quality_constraint = 2.0;

  // The volume constraint determines the max-allowed tetrahedral
  // volume in the Mesh.  TetGen will split cells which are larger than
  // this size
  Real volume_constraint = 0.001;

  // Construct the Delaunay tetrahedralization
  TetGenMeshInterface t(mesh);
  t.triangulate_conformingDelaunayMesh_carvehole(hole,
						 quality_constraint,
						 volume_constraint);

  // Find neighbors, etc in preparation for writing out the Mesh
  mesh.prepare_for_use();

  // Finally, write out the result
  mesh.write("hole_3D.e");
#endif // LIBMESH_HAVE_TETGEN
}

void add_cube_convex_hull_to_mesh(MeshBase& mesh, Point lower_limit, Point upper_limit)
{
#ifdef LIBMESH_HAVE_TETGEN
  SerialMesh cube_mesh(3,mesh.communicator());

  unsigned n_elem = 1;

  MeshTools::Generation::build_cube(cube_mesh,
				    n_elem,n_elem,n_elem, // n. elements in each direction
				    lower_limit(0), upper_limit(0),
				    lower_limit(1), upper_limit(1),
				    lower_limit(2), upper_limit(2),
				    HEX8);

  // The pointset_convexhull() algorithm will ignore the Hex8s
  // in the Mesh, and just construct the triangulation
  // of the convex hull.
  TetGenMeshInterface t(cube_mesh);
  t.pointset_convexhull();

  // Now add all nodes from the boundary of the cube_mesh to the input mesh.

  // Map from "node id in cube_mesh" -> "node id in mesh".  Initially inserted
  // with a dummy value, later to be assigned a value by the input mesh.
  std::map<unsigned,unsigned> node_id_map;
  typedef std::map<unsigned,unsigned>::iterator iterator;

  {
    MeshBase::element_iterator it = cube_mesh.elements_begin();
    const MeshBase::element_iterator end = cube_mesh.elements_end();
    for ( ; it != end; ++it)
      {
	Elem* elem = *it;

	for (unsigned s=0; s<elem->n_sides(); ++s)
	  if (elem->neighbor(s) == NULL)
	    {
	      // Add the node IDs of this side to the set
	      AutoPtr<Elem> side = elem->side(s);

	      for (unsigned n=0; n<side->n_nodes(); ++n)
		node_id_map.insert( std::make_pair(side->node(n), /*dummy_value=*/0) );
	    }
      }
  }

  // For each node in the map, insert it into the input mesh and keep
  // track of the ID assigned.
  for (iterator it=node_id_map.begin(); it != node_id_map.end(); ++it)
    {
      // Id of the node in the cube mesh
      unsigned id = (*it).first;

      // Pointer to node in the cube mesh
      Node* old_node = cube_mesh.node_ptr(id);

      // Add geometric point to input mesh
      Node* new_node = mesh.add_point ( *old_node );

      // Track ID value of new_node in map
      (*it).second = new_node->id();
    }

  // With the points added and the map data structure in place, we are
  // ready to add each TRI3 element of the cube_mesh to the input Mesh
  // with proper node assignments
  {
    MeshBase::element_iterator       el     = cube_mesh.elements_begin();
    const MeshBase::element_iterator end_el = cube_mesh.elements_end();

    for (; el != end_el; ++el)
      {
	Elem* old_elem = *el;

	if (old_elem->type() == TRI3)
	  {
	    Elem* new_elem = mesh.add_elem(new Tri3);

	    // Assign nodes in new elements.  Since this is an example,
	    // we'll do it in several steps.
	    for (unsigned i=0; i<old_elem->n_nodes(); ++i)
	      {
		// Locate old node ID in the map
		iterator it = node_id_map.find(old_elem->node(i));

		// Check for not found
		if (it == node_id_map.end())
		  {
		    libMesh::err << "Node id " << old_elem->node(i) << " not found in map!" << std::endl;
		    libmesh_error();
		  }

		// Mapping to node ID in input mesh
		unsigned new_node_id = (*it).second;

		// Node pointer assigned from input mesh
		new_elem->set_node(i) = mesh.node_ptr(new_node_id);
	      }
	  }
      }
  }
#endif // LIBMESH_HAVE_TETGEN
}
<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <sys/ioctl.h>
#include <unistd.h>

typedef ssize_t (*ReadSignature)(int, void*, size_t);

// TODO: per-process memory?
static char __line[1024];
static int __line_index = 0;

#define cursor_forward(x) printf("\033[%dC", (x))
#define cursor_backward(x) printf("\033[%dD", (x))

int open_history_file(FILE **f) {
    char history[512], *home_dir = getenv("HOME");

    strcpy(history, home_dir);
    strcat(history, "/.bash_history");

    if ((*f = fopen(history, "r")) == NULL) {
        printf("No such file %s\n", history);
        return -1;
    }

    return 0;
}

void complete_from_history(char *pattern, char *result) {

    char *buffer = 0;
    size_t len = 0;

    FILE *f = 0;

    open_history_file(&f);

    while (getline(&buffer, &len, f) != -1) {
        *strchr(buffer, '\n') = 0;
        if (!strncmp(buffer, pattern, strlen(pattern))) {
            strcpy(result, buffer + strlen(pattern));
            break;
        }
    }

    fclose(f);

}

void interactive_completion(unsigned char c) {

    char buffer[2048];
    struct winsize w;

    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // TODO:

    switch (c) {
        case 0xd: // newline
            __line_index = 0;
            memset(__line, 0, 1024);
            memset(buffer, 0, 2048);
            break;

        case 0x7f: // backspace
            if (__line_index > 0)
                __line[--__line_index] = 0;
            break;

        default:
            __line[__line_index++] = c;
            __line[__line_index] = 0;
            complete_from_history(__line, buffer);
            if (strlen(buffer) > strlen(__line)) {
                cursor_forward(1);
                printf("\e[1;30m%s\e[0m", buffer);
                cursor_backward((int)strlen(buffer) + 1);
                fflush(stdout);
            }
            break;
   }

}

ssize_t read(int fd, void *buf, size_t count) {
    static ReadSignature real_read = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));
    ssize_t ret = real_read(fd, buf, count);

    if (0 == fd) {
        interactive_completion(*(unsigned char *)buf);
    }

    return ret;
}

<commit_msg>added a little bit of STL<commit_after>#include <dlfcn.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <sys/ioctl.h>
#include <unistd.h>
#include <array>

typedef ssize_t (*ReadSignature)(int, void*, size_t);

// TODO: per-process memory?
using LineBuffer = std::array<char, 1024>;
static LineBuffer line_buffer;
static auto line_buffer_pos = line_buffer.begin();

#define cursor_forward(x) printf("\033[%dC", (x))
#define cursor_backward(x) printf("\033[%dD", (x))

int open_history_file(FILE **f) {
    char history[512], *home_dir = getenv("HOME");

    strcpy(history, home_dir);
    strcat(history, "/.bash_history");

    if ((*f = fopen(history, "r")) == NULL) {
        printf("No such file %s\n", history);
        return -1;
    }

    return 0;
}

void complete_from_history(char *pattern, char *result) {

    char *buffer = 0;
    size_t len = 0;

    FILE *f = 0;

    open_history_file(&f);

    while (getline(&buffer, &len, f) != -1) {
        *strchr(buffer, '\n') = 0;
        if (!strncmp(buffer, pattern, strlen(pattern))) {
            strcpy(result, buffer + strlen(pattern));
            break;
        }
    }

    fclose(f);

}

void interactive_completion(unsigned char c) {

    char buffer[2048];
    struct winsize w;

    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // TODO:

    switch (c) {
        case 0xd: // newline
            line_buffer_pos = line_buffer.begin();
            std::fill(std::begin(line_buffer), std::end(line_buffer), 0);
            memset(buffer, 0, 2048);
            break;

        case 0x7f: // backspace
            if (line_buffer_pos != line_buffer.begin()) {
                *(--line_buffer_pos) = 0;
            }
            break;

        default:
            *(++line_buffer_pos) = c;
            *(line_buffer_pos) = 0;
            complete_from_history(line_buffer.data(), buffer);
            if (strlen(buffer) > strlen(line_buffer.data())) {
                cursor_forward(1);
                printf("\e[1;30m%s\e[0m", buffer);
                cursor_backward((int)strlen(buffer) + 1);
                fflush(stdout);
            }
            break;
   }

}

ssize_t read(int fd, void *buf, size_t count) {
    static ReadSignature real_read = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));
    ssize_t ret = real_read(fd, buf, count);

    if (0 == fd) {
        interactive_completion(*(unsigned char *)buf);
    }

    return ret;
}

<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

typedef ssize_t (*ReadSignature)(int, void*, size_t);

thread_local ReadSignature realRead = NULL;

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::vector<std::string> history;

static void readHistory() {

    if (history.size()) return;

    std::string historyFileName(getenv("HOME"));
    historyFileName += "/.bash_history";

    std::ifstream historyFile(historyFileName);
    std::string line;

    while (std::getline(historyFile, line))
        history.push_back(line);

}

static void newlineHandler() {

}

static void backspaceHandler() {

    if (lineBufferPos != lineBuffer.begin()) {
        *(--lineBufferPos) = 0;
    }

}

 std::string findCompletion(const std::string &pattern) {

    for (auto it = history.end() - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0)
            return *it;
    }

    return pattern;

}

void regularCharHandler(char c) {

    *lineBufferPos = c;
    lineBufferPos++;

    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(pattern);

    cursor_forward(1);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());
    cursor_backward(completion.length() - pattern.length() + 1);
    fflush(stdout);

}

static void yebash(unsigned char c) {

    // TODO: uncomment later
    //if (!getenv("YEBASH")) {
    //    return;
    //}

    readHistory();

    switch (c) {

        case 0x0d: // newline
            newlineHandler();
            break;

        case 0x7f: // backspace
            backspaceHandler();
            break;

        default: // regular char
            regularCharHandler(c);
            break;

    }
}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0)
        yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;

}

<commit_msg>Add newline handling<commit_after>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

typedef ssize_t (*ReadSignature)(int, void*, size_t);

thread_local ReadSignature realRead = NULL;

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::vector<std::string> history;

static void readHistory() {

    if (history.size()) return;

    std::string historyFileName(getenv("HOME"));
    historyFileName += "/.bash_history";

    std::ifstream historyFile(historyFileName);
    std::string line;

    while (std::getline(historyFile, line))
        history.push_back(line);

}

static void newlineHandler() {

    lineBuffer.fill(0);
    lineBufferPos = lineBuffer.begin();

}

static void backspaceHandler() {

    if (lineBufferPos != lineBuffer.begin()) {
        *(--lineBufferPos) = 0;
    }

}

 std::string findCompletion(const std::string &pattern) {

    for (auto it = history.end() - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0)
            return *it;
    }

    return pattern;

}

void regularCharHandler(char c) {

    *lineBufferPos = c;
    lineBufferPos++;

    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(pattern);

    cursor_forward(1);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());
    cursor_backward(completion.length() - pattern.length() + 1);
    fflush(stdout);

}

static void yebash(unsigned char c) {

    // TODO: uncomment later
    //if (!getenv("YEBASH")) {
    //    return;
    //}

    readHistory();

    switch (c) {

        case 0x09: // tab
            // TODO: seeking through history
            break;

        case 0x0d: // newline
            newlineHandler();
            break;

        case 0x17: // ctrl+w
            newlineHandler(); // TODO: this has to clear lineBuffer
            break;

        case 0x7f: // backspace
            backspaceHandler();
            break;

        default: // regular char
            regularCharHandler(c);
            break;

    }
}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0)
        yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;

}

<|endoftext|>


<commit_before>#include "../include/TamuraDistance.h"

using namespace cv;
using namespace std;

double TamuraDistance::calc(const ImageData &dat1, const ImageData &dat2) {

    double F_crs1 = calc_granularity(dat1.rgb_img);
    double F_crs2 = calc_granularity(dat2.rgb_img);
    cout << "F_crs: " << Vec2d(F_crs1, F_crs2) << endl;

    // TODO normalisierung
    // TODO vermeide mehrfachberechnung fr 1
    // TODO performance?
    return fabs(F_crs1 - F_crs2);
}

string TamuraDistance::get_class_name() {
	return "Tamura-Granularity-Distance";
}

double TamuraDistance::calc_granularity(Mat bgr_img){
    //vector<Mat> A_k_list;
	//vector<Mat> E_k_list;

	Mat gray_img;
	cvtColor(bgr_img, gray_img, CV_BGR2GRAY);

	Mat S_best_k(bgr_img.size(), CV_32S);
	Mat S_best_maxval(bgr_img.size(), CV_64F, Scalar(0));

	for (int k = kmin; k <= kmax; k++) {
        cout << "k " << k << endl;
		Mat A_k(bgr_img.size(), CV_64F);
		int k_pow = pow(2, k - 1);
		for (int x = 0; x < bgr_img.rows; x++) {
			for (int y = 0; y < bgr_img.cols; y++) {

				double sum = 0;
				for (int i = x - k_pow; i < x + k_pow; i++) {
					for (int j = y - k_pow; j < y + k_pow; j++) {
						// Out of range pixels are obtained by mirroring at the edge	alt: BORDER_WRAP
						sum += gray_img.at<uchar>(borderInterpolate(i, gray_img.rows, BORDER_REFLECT_101), borderInterpolate(j, gray_img.cols, BORDER_REFLECT_101));

					}
				}
				A_k.at<double>(x, y) = sum / pow(2, 2 * k);

			}
		}
		//A_k_list.push_back(A_k);

		Mat E_k_h(bgr_img.size(), CV_64F), E_k_v(bgr_img.size(), CV_64F);
		for (int x = 0; x < bgr_img.rows; x++) {
			for (int y = 0; y < bgr_img.cols; y++) {

				E_k_h.at<double>(x, y) = fabs(A_k.at<double>(borderInterpolate(x + k_pow, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y, A_k.cols, BORDER_REFLECT_101)) - A_k.at<double>(borderInterpolate(x - k_pow, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y, A_k.cols, BORDER_REFLECT_101)));
				E_k_v.at<double>(x, y) = fabs(A_k.at<double>(borderInterpolate(x, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y + k_pow, A_k.cols, BORDER_REFLECT_101)) - A_k.at<double>(borderInterpolate(x, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y - k_pow, A_k.cols, BORDER_REFLECT_101)));

				double maxval = max(E_k_h.at<double>(x, y), E_k_v.at<double>(x, y));
				if (maxval > S_best_maxval.at<double>(x, y)) {
					S_best_maxval.at<double>(x, y) = maxval;
					S_best_k.at<int>(x, y) = pow(2, k);
				}
			}
		}
		//E_k_list.push_back(E_k_h);
		//E_k_list.push_back(E_k_v);
	}

	//Mat F_crs;
	//normalize(S_best_k, F_crs, )

	/*
	//Mat res;
	//boxFilter(A_k_list[3], res, -1, Size(8, 8));
	//cout << (res == A_k_list[3]) << endl;

	Mat dst;
	normalize(A_k_list.at(3), dst, 0, 1, cv::NORM_MINMAX);
	imshow("test", dst);
	waitKey(0);

	//imshow("abc", A_k_list.front());
	//waitKey(0);
	return 8;
	//*/

	//cout << "S_best_k" << S_best_k << endl;
    //double F_crs = cv::sum(S_best_k)[0] / S_best_k.total();
    return mean(S_best_k)[0];

}
<commit_msg>replaced cumulating by boxcar filter<commit_after>#include "../include/TamuraDistance.h"

using namespace cv;
using namespace std;

double TamuraDistance::calc(const ImageData &dat1, const ImageData &dat2) {

    double F_crs1 = calc_granularity(dat1.rgb_img);
    double F_crs2 = calc_granularity(dat2.rgb_img);
    cout << "F_crs: " << Vec2d(F_crs1, F_crs2) << endl;

    // TODO normalisierung
    // TODO vermeide mehrfachberechnung fr 1
    // TODO performance?
    return fabs(F_crs1 - F_crs2);
}

string TamuraDistance::get_class_name() {
	return "Tamura-Granularity-Distance";
}

double TamuraDistance::calc_granularity(Mat bgr_img){
    //vector<Mat> A_k_list;
	//vector<Mat> E_k_list;

	Mat gray_img;
	cvtColor(bgr_img, gray_img, CV_BGR2GRAY);

	Mat S_best_k(bgr_img.size(), CV_32S);
	Mat S_best_maxval(bgr_img.size(), CV_64F, Scalar(0));

	for (int k = kmin; k <= kmax; k++) {
        cout << "k " << k << endl;
		Mat A_k(bgr_img.size(), CV_64F);
		int k_pow = pow(2, k - 1);
		/*
		for (int x = 0; x < bgr_img.rows; x++) {
			for (int y = 0; y < bgr_img.cols; y++) {

				double sum = 0;
				for (int i = x - k_pow; i < x + k_pow; i++) {
					for (int j = y - k_pow; j < y + k_pow; j++) {
						// Out of range pixels are obtained by mirroring at the edge	alt: BORDER_WRAP
						sum += gray_img.at<uchar>(borderInterpolate(i, gray_img.rows, BORDER_REFLECT_101), borderInterpolate(j, gray_img.cols, BORDER_REFLECT_101));

					}
				}
				A_k.at<double>(x, y) = sum / pow(2, 2 * k);

			}
		}
		*/

        boxFilter(gray_img, A_k, CV_64F, Size(2*k_pow,2*k_pow), Point(-1,-1), true, BORDER_REFLECT_101);
        //A_k /= pow(2, 2 * k);
		//A_k_list.push_back(A_k);

		Mat E_k_h(bgr_img.size(), CV_64F), E_k_v(bgr_img.size(), CV_64F);
		for (int x = 0; x < bgr_img.rows; x++) {
			for (int y = 0; y < bgr_img.cols; y++) {

				E_k_h.at<double>(x, y) = fabs(A_k.at<double>(borderInterpolate(x + k_pow, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y, A_k.cols, BORDER_REFLECT_101)) - A_k.at<double>(borderInterpolate(x - k_pow, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y, A_k.cols, BORDER_REFLECT_101)));
				E_k_v.at<double>(x, y) = fabs(A_k.at<double>(borderInterpolate(x, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y + k_pow, A_k.cols, BORDER_REFLECT_101)) - A_k.at<double>(borderInterpolate(x, A_k.rows, BORDER_REFLECT_101), borderInterpolate(y - k_pow, A_k.cols, BORDER_REFLECT_101)));

				double maxval = max(E_k_h.at<double>(x, y), E_k_v.at<double>(x, y));
				if (maxval > S_best_maxval.at<double>(x, y)) {
					S_best_maxval.at<double>(x, y) = maxval;
					S_best_k.at<int>(x, y) = pow(2, k);
				}
			}
		}
		//E_k_list.push_back(E_k_h);
		//E_k_list.push_back(E_k_v);
	}

	//Mat F_crs;
	//normalize(S_best_k, F_crs, )

	/*
	//Mat res;
	//boxFilter(A_k_list[3], res, -1, Size(8, 8));
	//cout << (res == A_k_list[3]) << endl;

	Mat dst;
	normalize(A_k_list.at(3), dst, 0, 1, cv::NORM_MINMAX);
	imshow("test", dst);
	waitKey(0);

	//imshow("abc", A_k_list.front());
	//waitKey(0);
	return 8;
	//*/

	//cout << "S_best_k" << S_best_k << endl;
    //double F_crs = cv::sum(S_best_k)[0] / S_best_k.total();
    return mean(S_best_k)[0];

}
<|endoftext|>


<commit_before>#include "rapid_pbd/step_executor.h"

#include <sstream>

#include "boost/shared_ptr.hpp"
#include "moveit_msgs/MoveGroupAction.h"
#include "rapid_pbd_msgs/Action.h"
#include "rapid_pbd_msgs/Step.h"
#include "ros/ros.h"
#include "tf/transform_listener.h"

#include "rapid_pbd/action_executor.h"
#include "rapid_pbd/errors.h"
#include "rapid_pbd/motion_planning.h"
#include "rapid_pbd/visualizer.h"
#include "rapid_pbd/world.h"

using boost::shared_ptr;
using rapid_pbd_msgs::Action;
using rapid_pbd_msgs::Step;

namespace rapid {
namespace pbd {
StepExecutor::StepExecutor(const rapid_pbd_msgs::Step& step,
                           ActionClients* action_clients,
                           const RobotConfig& robot_config, World* world,
                           const RuntimeVisualizer& runtime_viz,
                           const tf::TransformListener& tf_listener,
                           const ros::Publisher& planning_scene_pub)
    : step_(step),
      action_clients_(action_clients),
      robot_config_(robot_config),
      world_(world),
      runtime_viz_(runtime_viz),
      motion_planning_(robot_config, world, tf_listener, planning_scene_pub),
      executors_() {}

bool StepExecutor::IsValid(const rapid_pbd_msgs::Step& step) {
  for (size_t i = 0; i < step.actions.size(); ++i) {
    const Action& action = step.actions[i];
    if (!ActionExecutor::IsValid(action)) {
      ROS_ERROR("Action type %s invalid in action %ld", action.type.c_str(), i);
      return false;
    }
  }
  return true;
}

void StepExecutor::Init() {
  for (size_t i = 0; i < step_.actions.size(); ++i) {
    Action action = step_.actions[i];
    shared_ptr<ActionExecutor> ae(
        new ActionExecutor(action, action_clients_, &motion_planning_, world_,
                           robot_config_, runtime_viz_));
    executors_.push_back(ae);
  }
}

std::string StepExecutor::Start() {
  motion_planning_.ClearGoals();
  std::string error("");
  for (size_t i = 0; i < step_.actions.size(); ++i) {
    error = executors_[i]->Start();
    if (error != "") {
      return error;
    }
  }
  if (motion_planning_.num_goals() > 0) {
    moveit_msgs::MoveGroupGoal goal;
    motion_planning_.BuildGoal(&goal);
    action_clients_->moveit_client.sendGoal(goal);
  }
  return "";
}

bool StepExecutor::IsDone(std::string* error) const {
  for (size_t i = 0; i < executors_.size(); ++i) {
    const shared_ptr<ActionExecutor>& executor = executors_[i];
    if (!executor->IsDone(error)) {
      return false;
    }
    if (*error != "") {
      return true;
    }
  }
  if (motion_planning_.num_goals() > 0) {
    if (!action_clients_->moveit_client.getState().isDone()) {
      return false;
    }
    moveit_msgs::MoveGroupResultConstPtr result =
        action_clients_->moveit_client.getResult();
    if (!result) {
      *error = "MoveIt returned null result.";
    }
    if (result->error_code.val != moveit_msgs::MoveItErrorCodes::SUCCESS) {
      std::stringstream ss;
      ss << errors::kUnreachablePose
         << " MoveIt error code: " << ErrorCodeToString(result->error_code);
      *error = ss.str();
    }

    // Insert a delay at the end to avoid "start state out of bounds" errors for
    // subsequent motion plans.
    ros::Duration(1).sleep();
  }
  return true;
}

void StepExecutor::Cancel() {
  for (size_t i = 0; i < executors_.size(); ++i) {
    const shared_ptr<ActionExecutor>& executor = executors_[i];
    executor->Cancel();
  }
  if (motion_planning_.num_goals() > 0) {
    action_clients_->moveit_client.cancelAllGoals();
    motion_planning_.ClearGoals();
  }

  executors_.clear();
}

}  // namespace pbd
}  // namespace rapid
<commit_msg>Shorten delay.<commit_after>#include "rapid_pbd/step_executor.h"

#include <sstream>

#include "boost/shared_ptr.hpp"
#include "moveit_msgs/MoveGroupAction.h"
#include "rapid_pbd_msgs/Action.h"
#include "rapid_pbd_msgs/Step.h"
#include "ros/ros.h"
#include "tf/transform_listener.h"

#include "rapid_pbd/action_executor.h"
#include "rapid_pbd/errors.h"
#include "rapid_pbd/motion_planning.h"
#include "rapid_pbd/visualizer.h"
#include "rapid_pbd/world.h"

using boost::shared_ptr;
using rapid_pbd_msgs::Action;
using rapid_pbd_msgs::Step;

namespace rapid {
namespace pbd {
StepExecutor::StepExecutor(const rapid_pbd_msgs::Step& step,
                           ActionClients* action_clients,
                           const RobotConfig& robot_config, World* world,
                           const RuntimeVisualizer& runtime_viz,
                           const tf::TransformListener& tf_listener,
                           const ros::Publisher& planning_scene_pub)
    : step_(step),
      action_clients_(action_clients),
      robot_config_(robot_config),
      world_(world),
      runtime_viz_(runtime_viz),
      motion_planning_(robot_config, world, tf_listener, planning_scene_pub),
      executors_() {}

bool StepExecutor::IsValid(const rapid_pbd_msgs::Step& step) {
  for (size_t i = 0; i < step.actions.size(); ++i) {
    const Action& action = step.actions[i];
    if (!ActionExecutor::IsValid(action)) {
      ROS_ERROR("Action type %s invalid in action %ld", action.type.c_str(), i);
      return false;
    }
  }
  return true;
}

void StepExecutor::Init() {
  for (size_t i = 0; i < step_.actions.size(); ++i) {
    Action action = step_.actions[i];
    shared_ptr<ActionExecutor> ae(
        new ActionExecutor(action, action_clients_, &motion_planning_, world_,
                           robot_config_, runtime_viz_));
    executors_.push_back(ae);
  }
}

std::string StepExecutor::Start() {
  motion_planning_.ClearGoals();
  std::string error("");
  for (size_t i = 0; i < step_.actions.size(); ++i) {
    error = executors_[i]->Start();
    if (error != "") {
      return error;
    }
  }
  if (motion_planning_.num_goals() > 0) {
    moveit_msgs::MoveGroupGoal goal;
    motion_planning_.BuildGoal(&goal);
    action_clients_->moveit_client.sendGoal(goal);
  }
  return "";
}

bool StepExecutor::IsDone(std::string* error) const {
  for (size_t i = 0; i < executors_.size(); ++i) {
    const shared_ptr<ActionExecutor>& executor = executors_[i];
    if (!executor->IsDone(error)) {
      return false;
    }
    if (*error != "") {
      return true;
    }
  }
  if (motion_planning_.num_goals() > 0) {
    if (!action_clients_->moveit_client.getState().isDone()) {
      return false;
    }
    moveit_msgs::MoveGroupResultConstPtr result =
        action_clients_->moveit_client.getResult();
    if (!result) {
      *error = "MoveIt returned null result.";
    }
    if (result->error_code.val != moveit_msgs::MoveItErrorCodes::SUCCESS) {
      std::stringstream ss;
      ss << errors::kUnreachablePose
         << " MoveIt error code: " << ErrorCodeToString(result->error_code);
      *error = ss.str();
    }

    // Insert a delay at the end to avoid "start state out of bounds" errors for
    // subsequent motion plans.
    ros::Duration(0.1).sleep();
  }
  return true;
}

void StepExecutor::Cancel() {
  for (size_t i = 0; i < executors_.size(); ++i) {
    const shared_ptr<ActionExecutor>& executor = executors_[i];
    executor->Cancel();
  }
  if (motion_planning_.num_goals() > 0) {
    action_clients_->moveit_client.cancelAllGoals();
    motion_planning_.ClearGoals();
  }

  executors_.clear();
}

}  // namespace pbd
}  // namespace rapid
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <seastar/core/seastar.hh>
#include <seastar/core/print.hh>

#include "reader_concurrency_semaphore.hh"
#include "utils/exceptions.hh"

reader_permit::resource_units::resource_units(reader_concurrency_semaphore& semaphore, reader_resources res) noexcept
        : _semaphore(&semaphore), _resources(res) {
}

reader_permit::resource_units::resource_units(resource_units&& o) noexcept
    : _semaphore(o._semaphore)
    , _resources(std::exchange(o._resources, {})) {
}

reader_permit::resource_units::~resource_units() {
    reset();
}

reader_permit::resource_units& reader_permit::resource_units::operator=(resource_units&& o) noexcept {
    if (&o == this) {
        return *this;
    }
    reset();
    _semaphore = o._semaphore;
    _resources = std::exchange(o._resources, {});
    return *this;
}

void reader_permit::resource_units::add(resource_units&& o) {
    assert(_semaphore == o._semaphore);
    _resources += std::exchange(o._resources, {});
}

void reader_permit::resource_units::reset(reader_resources res) {
    _semaphore->consume(res);
    if (_resources) {
        _semaphore->signal(_resources);
    }
    _resources = res;
}

reader_permit::reader_permit(reader_concurrency_semaphore& semaphore)
    : _semaphore(&semaphore) {
}

future<reader_permit::resource_units> reader_permit::wait_admission(size_t memory, db::timeout_clock::time_point timeout) {
    return _semaphore->do_wait_admission(memory, timeout);
}

reader_permit::resource_units reader_permit::consume_memory(size_t memory) {
    return consume_resources(reader_resources{0, ssize_t(memory)});
}

reader_permit::resource_units reader_permit::consume_resources(reader_resources res) {
    _semaphore->consume(res);
    return resource_units(*_semaphore, res);
}

void reader_concurrency_semaphore::signal(const resources& r) noexcept {
    _resources += r;
    while (!_wait_list.empty() && has_available_units(_wait_list.front().res)) {
        auto& x = _wait_list.front();
        _resources -= x.res;
        try {
            x.pr.set_value(reader_permit::resource_units(*this, x.res));
        } catch (...) {
            x.pr.set_exception(std::current_exception());
        }
        _wait_list.pop_front();
    }
}

reader_concurrency_semaphore::~reader_concurrency_semaphore() {
    broken(std::make_exception_ptr(broken_semaphore{}));
}

reader_concurrency_semaphore::inactive_read_handle reader_concurrency_semaphore::register_inactive_read(std::unique_ptr<inactive_read> ir) {
    // Implies _inactive_reads.empty(), we don't queue new readers before
    // evicting all inactive reads.
    if (_wait_list.empty()) {
        const auto [it, _] = _inactive_reads.emplace(_next_id++, std::move(ir));
        (void)_;
        ++_inactive_read_stats.population;
        return inactive_read_handle(*this, it->first);
    }

    // The evicted reader will release its permit, hopefully allowing us to
    // admit some readers from the _wait_list.
    ir->evict();
    ++_inactive_read_stats.permit_based_evictions;
    return inactive_read_handle();
}

std::unique_ptr<reader_concurrency_semaphore::inactive_read> reader_concurrency_semaphore::unregister_inactive_read(inactive_read_handle irh) {
    if (irh && irh._sem != this) {
        throw std::runtime_error(fmt::format(
                    "reader_concurrency_semaphore::unregister_inactive_read(): "
                    "attempted to unregister an inactive read with a handle belonging to another semaphore: "
                    "this is {} (0x{:x}) but the handle belongs to {} (0x{:x})",
                    name(),
                    reinterpret_cast<uintptr_t>(this),
                    irh._sem->name(),
                    reinterpret_cast<uintptr_t>(irh._sem)));
    }

    if (auto it = _inactive_reads.find(irh._id); it != _inactive_reads.end()) {
        auto ir = std::move(it->second);
        _inactive_reads.erase(it);
        --_inactive_read_stats.population;
        return ir;
    }
    return {};
}

bool reader_concurrency_semaphore::try_evict_one_inactive_read() {
    if (_inactive_reads.empty()) {
        return false;
    }
    auto it = _inactive_reads.begin();
    it->second->evict();
    _inactive_reads.erase(it);

    ++_inactive_read_stats.permit_based_evictions;
    --_inactive_read_stats.population;

    return true;
}

future<reader_permit::resource_units> reader_concurrency_semaphore::do_wait_admission(size_t memory, db::timeout_clock::time_point timeout) {
    if (_wait_list.size() >= _max_queue_length) {
        if (_prethrow_action) {
            _prethrow_action();
        }
        return make_exception_future<reader_permit::resource_units>(
                std::make_exception_ptr(std::runtime_error(
                        format("{}: restricted mutation reader queue overload", _name))));
    }
    auto r = resources(1, static_cast<ssize_t>(memory));
    auto it = _inactive_reads.begin();
    while (!may_proceed(r) && it != _inactive_reads.end()) {
        auto ir = std::move(it->second);
        it = _inactive_reads.erase(it);
        ir->evict();

        ++_inactive_read_stats.permit_based_evictions;
        --_inactive_read_stats.population;
    }
    if (may_proceed(r)) {
        _resources -= r;
        return make_ready_future<reader_permit::resource_units>(reader_permit::resource_units(*this, r));
    }
    promise<reader_permit::resource_units> pr;
    auto fut = pr.get_future();
    _wait_list.push_back(entry(std::move(pr), r), timeout);
    return fut;
}

reader_permit reader_concurrency_semaphore::make_permit() {
    return reader_permit(*this);
}

void reader_concurrency_semaphore::broken(std::exception_ptr ex) {
    while (!_wait_list.empty()) {
        _wait_list.front().pr.set_exception(std::make_exception_ptr(broken_semaphore{}));
        _wait_list.pop_front();
    }
}

// A file that tracks the memory usage of buffers resulting from read
// operations.
class tracking_file_impl : public file_impl {
    file _tracked_file;
    reader_permit _permit;

public:
    tracking_file_impl(file file, reader_permit permit)
        : _tracked_file(std::move(file))
        , _permit(std::move(permit)) {
        _memory_dma_alignment = _tracked_file.memory_dma_alignment();
        _disk_read_dma_alignment = _tracked_file.disk_read_dma_alignment();
        _disk_write_dma_alignment = _tracked_file.disk_write_dma_alignment();
    }

    tracking_file_impl(const tracking_file_impl&) = delete;
    tracking_file_impl& operator=(const tracking_file_impl&) = delete;
    tracking_file_impl(tracking_file_impl&&) = default;
    tracking_file_impl& operator=(tracking_file_impl&&) = default;

    virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->write_dma(pos, buffer, len, pc);
    }

    virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->write_dma(pos, std::move(iov), pc);
    }

    virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->read_dma(pos, buffer, len, pc);
    }

    virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->read_dma(pos, iov, pc);
    }

    virtual future<> flush(void) override {
        return get_file_impl(_tracked_file)->flush();
    }

    virtual future<struct stat> stat(void) override {
        return get_file_impl(_tracked_file)->stat();
    }

    virtual future<> truncate(uint64_t length) override {
        return get_file_impl(_tracked_file)->truncate(length);
    }

    virtual future<> discard(uint64_t offset, uint64_t length) override {
        return get_file_impl(_tracked_file)->discard(offset, length);
    }

    virtual future<> allocate(uint64_t position, uint64_t length) override {
        return get_file_impl(_tracked_file)->allocate(position, length);
    }

    virtual future<uint64_t> size(void) override {
        return get_file_impl(_tracked_file)->size();
    }

    virtual future<> close() override {
        return get_file_impl(_tracked_file)->close();
    }

    virtual std::unique_ptr<file_handle_impl> dup() override {
        return get_file_impl(_tracked_file)->dup();
    }

    virtual subscription<directory_entry> list_directory(std::function<future<> (directory_entry de)> next) override {
        return get_file_impl(_tracked_file)->list_directory(std::move(next));
    }

    virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->dma_read_bulk(offset, range_size, pc).then([this, units = _permit.consume_memory(range_size)] (temporary_buffer<uint8_t> buf) {
            return make_ready_future<temporary_buffer<uint8_t>>(make_tracked_temporary_buffer(std::move(buf), _permit));
        });
    }
};

file make_tracked_file(file f, reader_permit p) {
    return file(make_shared<tracking_file_impl>(f, std::move(p)));
}
<commit_msg>reader_permit: reader_resources: make true RAII class<commit_after>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <seastar/core/seastar.hh>
#include <seastar/core/print.hh>

#include "reader_concurrency_semaphore.hh"
#include "utils/exceptions.hh"

reader_permit::resource_units::resource_units(reader_concurrency_semaphore& semaphore, reader_resources res) noexcept
        : _semaphore(&semaphore), _resources(res) {
    _semaphore->consume(res);
}

reader_permit::resource_units::resource_units(resource_units&& o) noexcept
    : _semaphore(o._semaphore)
    , _resources(std::exchange(o._resources, {})) {
}

reader_permit::resource_units::~resource_units() {
    reset();
}

reader_permit::resource_units& reader_permit::resource_units::operator=(resource_units&& o) noexcept {
    if (&o == this) {
        return *this;
    }
    reset();
    _semaphore = o._semaphore;
    _resources = std::exchange(o._resources, {});
    return *this;
}

void reader_permit::resource_units::add(resource_units&& o) {
    assert(_semaphore == o._semaphore);
    _resources += std::exchange(o._resources, {});
}

void reader_permit::resource_units::reset(reader_resources res) {
    _semaphore->consume(res);
    if (_resources) {
        _semaphore->signal(_resources);
    }
    _resources = res;
}

reader_permit::reader_permit(reader_concurrency_semaphore& semaphore)
    : _semaphore(&semaphore) {
}

future<reader_permit::resource_units> reader_permit::wait_admission(size_t memory, db::timeout_clock::time_point timeout) {
    return _semaphore->do_wait_admission(memory, timeout);
}

reader_permit::resource_units reader_permit::consume_memory(size_t memory) {
    return consume_resources(reader_resources{0, ssize_t(memory)});
}

reader_permit::resource_units reader_permit::consume_resources(reader_resources res) {
    return resource_units(*_semaphore, res);
}

void reader_concurrency_semaphore::signal(const resources& r) noexcept {
    _resources += r;
    while (!_wait_list.empty() && has_available_units(_wait_list.front().res)) {
        auto& x = _wait_list.front();
        try {
            x.pr.set_value(reader_permit::resource_units(*this, x.res));
        } catch (...) {
            x.pr.set_exception(std::current_exception());
        }
        _wait_list.pop_front();
    }
}

reader_concurrency_semaphore::~reader_concurrency_semaphore() {
    broken(std::make_exception_ptr(broken_semaphore{}));
}

reader_concurrency_semaphore::inactive_read_handle reader_concurrency_semaphore::register_inactive_read(std::unique_ptr<inactive_read> ir) {
    // Implies _inactive_reads.empty(), we don't queue new readers before
    // evicting all inactive reads.
    if (_wait_list.empty()) {
        const auto [it, _] = _inactive_reads.emplace(_next_id++, std::move(ir));
        (void)_;
        ++_inactive_read_stats.population;
        return inactive_read_handle(*this, it->first);
    }

    // The evicted reader will release its permit, hopefully allowing us to
    // admit some readers from the _wait_list.
    ir->evict();
    ++_inactive_read_stats.permit_based_evictions;
    return inactive_read_handle();
}

std::unique_ptr<reader_concurrency_semaphore::inactive_read> reader_concurrency_semaphore::unregister_inactive_read(inactive_read_handle irh) {
    if (irh && irh._sem != this) {
        throw std::runtime_error(fmt::format(
                    "reader_concurrency_semaphore::unregister_inactive_read(): "
                    "attempted to unregister an inactive read with a handle belonging to another semaphore: "
                    "this is {} (0x{:x}) but the handle belongs to {} (0x{:x})",
                    name(),
                    reinterpret_cast<uintptr_t>(this),
                    irh._sem->name(),
                    reinterpret_cast<uintptr_t>(irh._sem)));
    }

    if (auto it = _inactive_reads.find(irh._id); it != _inactive_reads.end()) {
        auto ir = std::move(it->second);
        _inactive_reads.erase(it);
        --_inactive_read_stats.population;
        return ir;
    }
    return {};
}

bool reader_concurrency_semaphore::try_evict_one_inactive_read() {
    if (_inactive_reads.empty()) {
        return false;
    }
    auto it = _inactive_reads.begin();
    it->second->evict();
    _inactive_reads.erase(it);

    ++_inactive_read_stats.permit_based_evictions;
    --_inactive_read_stats.population;

    return true;
}

future<reader_permit::resource_units> reader_concurrency_semaphore::do_wait_admission(size_t memory, db::timeout_clock::time_point timeout) {
    if (_wait_list.size() >= _max_queue_length) {
        if (_prethrow_action) {
            _prethrow_action();
        }
        return make_exception_future<reader_permit::resource_units>(
                std::make_exception_ptr(std::runtime_error(
                        format("{}: restricted mutation reader queue overload", _name))));
    }
    auto r = resources(1, static_cast<ssize_t>(memory));
    auto it = _inactive_reads.begin();
    while (!may_proceed(r) && it != _inactive_reads.end()) {
        auto ir = std::move(it->second);
        it = _inactive_reads.erase(it);
        ir->evict();

        ++_inactive_read_stats.permit_based_evictions;
        --_inactive_read_stats.population;
    }
    if (may_proceed(r)) {
        return make_ready_future<reader_permit::resource_units>(reader_permit::resource_units(*this, r));
    }
    promise<reader_permit::resource_units> pr;
    auto fut = pr.get_future();
    _wait_list.push_back(entry(std::move(pr), r), timeout);
    return fut;
}

reader_permit reader_concurrency_semaphore::make_permit() {
    return reader_permit(*this);
}

void reader_concurrency_semaphore::broken(std::exception_ptr ex) {
    while (!_wait_list.empty()) {
        _wait_list.front().pr.set_exception(std::make_exception_ptr(broken_semaphore{}));
        _wait_list.pop_front();
    }
}

// A file that tracks the memory usage of buffers resulting from read
// operations.
class tracking_file_impl : public file_impl {
    file _tracked_file;
    reader_permit _permit;

public:
    tracking_file_impl(file file, reader_permit permit)
        : _tracked_file(std::move(file))
        , _permit(std::move(permit)) {
        _memory_dma_alignment = _tracked_file.memory_dma_alignment();
        _disk_read_dma_alignment = _tracked_file.disk_read_dma_alignment();
        _disk_write_dma_alignment = _tracked_file.disk_write_dma_alignment();
    }

    tracking_file_impl(const tracking_file_impl&) = delete;
    tracking_file_impl& operator=(const tracking_file_impl&) = delete;
    tracking_file_impl(tracking_file_impl&&) = default;
    tracking_file_impl& operator=(tracking_file_impl&&) = default;

    virtual future<size_t> write_dma(uint64_t pos, const void* buffer, size_t len, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->write_dma(pos, buffer, len, pc);
    }

    virtual future<size_t> write_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->write_dma(pos, std::move(iov), pc);
    }

    virtual future<size_t> read_dma(uint64_t pos, void* buffer, size_t len, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->read_dma(pos, buffer, len, pc);
    }

    virtual future<size_t> read_dma(uint64_t pos, std::vector<iovec> iov, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->read_dma(pos, iov, pc);
    }

    virtual future<> flush(void) override {
        return get_file_impl(_tracked_file)->flush();
    }

    virtual future<struct stat> stat(void) override {
        return get_file_impl(_tracked_file)->stat();
    }

    virtual future<> truncate(uint64_t length) override {
        return get_file_impl(_tracked_file)->truncate(length);
    }

    virtual future<> discard(uint64_t offset, uint64_t length) override {
        return get_file_impl(_tracked_file)->discard(offset, length);
    }

    virtual future<> allocate(uint64_t position, uint64_t length) override {
        return get_file_impl(_tracked_file)->allocate(position, length);
    }

    virtual future<uint64_t> size(void) override {
        return get_file_impl(_tracked_file)->size();
    }

    virtual future<> close() override {
        return get_file_impl(_tracked_file)->close();
    }

    virtual std::unique_ptr<file_handle_impl> dup() override {
        return get_file_impl(_tracked_file)->dup();
    }

    virtual subscription<directory_entry> list_directory(std::function<future<> (directory_entry de)> next) override {
        return get_file_impl(_tracked_file)->list_directory(std::move(next));
    }

    virtual future<temporary_buffer<uint8_t>> dma_read_bulk(uint64_t offset, size_t range_size, const io_priority_class& pc) override {
        return get_file_impl(_tracked_file)->dma_read_bulk(offset, range_size, pc).then([this, units = _permit.consume_memory(range_size)] (temporary_buffer<uint8_t> buf) {
            return make_ready_future<temporary_buffer<uint8_t>>(make_tracked_temporary_buffer(std::move(buf), _permit));
        });
    }
};

file make_tracked_file(file f, reader_permit p) {
    return file(make_shared<tracking_file_impl>(f, std::move(p)));
}
<|endoftext|>


<commit_before>/*
 * TextFileParser.cpp
 *
 *  Created on: 24.01.2015
 *      Author: sartz
 */

#include "TextFileParser.hpp"
#include <fstream>
#include <sstream>
#include <iostream>
#include "CoinItem.hpp"
#include "TimeItem.hpp"
#include "TriggerItem.hpp"
#include "KeyItem.hpp"
#include "ItemFactory.hpp"
#include "globals.hpp"
#include "TextureManager.hpp"
#include "Tile.hpp"

TextFileParser::TextFileParser() {
	// TODO Auto-generated constructor stub

}

TextFileParser::~TextFileParser() {
	// TODO Auto-generated destructor stub
}

void TextFileParser::loadTextFile(Scene &scene, std::string fileName)
{
	std::ifstream infile(fileName);
//	infile.open(fileName.c_str());
	std::string line;

//	sf::Texture *itemsTexture;
//	itemsTexture->loadFromFile(std::string(PATH) + "img/items.png");
	sf::Sprite *itemSprite = new sf::Sprite();
	itemSprite->setTexture(textureManager.itemsTexture);
	ItemFactory tmpFactory = ItemFactory();

	while (std::getline(infile, line))
	{
		std::istringstream iss(line);
		std::string first;
		iss >> first;

		if (first == "Start")
		{
			int x,y;
			iss >> x;
			iss >> y;
			scene.startPos.x = x*Tile::pixelSizeX*Scene::tileScaleFactor;
			scene.startPos.y = y*Tile::pixelSizeY*Scene::tileScaleFactor;
		}

		if (first == "Portal")
		{
			int x,y;
			iss >> x;
			iss >> y;
			scene.portalPos.x = x*Tile::pixelSizeX*Scene::tileScaleFactor;
			scene.portalPos.y = y*Tile::pixelSizeY*Scene::tileScaleFactor;
			Item *tmpItem = tmpFactory.getItem("PortalItem");
			tmpItem->setPosition(x, y);
			scene.items.push_back(*tmpItem);
		}

		if (first == "Item")
		{
			std::string second;
			iss >> second;
			int x,y;
			iss >> x;
			iss >> y;

			Item *tmpItem = tmpFactory.getItem(second);
			tmpItem->setPosition(x*Tile::pixelSizeX*Scene::tileScaleFactor, y*Tile::pixelSizeY*Scene::tileScaleFactor);
			scene.items.push_back(*tmpItem);
		}

		if (first == "TriggerItem")
		{
			int x1, x2, y1, y2;
			iss >> x1;
			iss >> y1;
			iss >> x2;
			iss >> y2;

			TriggerItem *tmpItem = (TriggerItem*) tmpFactory.getItem("TriggerItem");
			tmpItem->setSwitchPos(x1*Tile::pixelSizeX*Scene::tileScaleFactor, y1*Tile::pixelSizeY*Scene::tileScaleFactor, x2*Tile::pixelSizeX*Scene::tileScaleFactor, y2*Tile::pixelSizeY*Scene::tileScaleFactor);
			scene.items.push_back(*tmpItem);
		}

	}
}
<commit_msg>Fix des letzten fehlerhaften Commits (durch Mergen)<commit_after>/*
 * TextFileParser.cpp
 *
 *  Created on: 24.01.2015
 *      Author: sartz
 */

#include "TextFileParser.hpp"
#include <fstream>
#include <sstream>
#include <iostream>
#include "CoinItem.hpp"
#include "TimeItem.hpp"
#include "TriggerItem.hpp"
#include "KeyItem.hpp"
#include "ItemFactory.hpp"
#include "globals.hpp"
#include "TextureManager.hpp"
#include "Tile.hpp"

TextFileParser::TextFileParser() {
	// TODO Auto-generated constructor stub

}

TextFileParser::~TextFileParser() {
	// TODO Auto-generated destructor stub
}

void TextFileParser::loadTextFile(Scene &scene, std::string fileName)
{
	std::ifstream infile(fileName);
//	infile.open(fileName.c_str());
	std::string line;

//	sf::Texture *itemsTexture;
//	itemsTexture->loadFromFile(std::string(PATH) + "img/items.png");
	sf::Sprite *itemSprite = new sf::Sprite();
	itemSprite->setTexture(textureManager.itemsTexture);
	ItemFactory tmpFactory = ItemFactory();

	while (std::getline(infile, line))
	{
		std::istringstream iss(line);
		std::string first;
		iss >> first;

		if (first == "Start")
		{
			int x,y;
			iss >> x;
			iss >> y;
			scene.startPos.x = x*Tile::pixelSizeX*Scene::tileScaleFactor;
			scene.startPos.y = y*Tile::pixelSizeY*Scene::tileScaleFactor;
		}

		if (first == "Portal")
		{
			int x,y;
			iss >> x;
			iss >> y;
			scene.portalPos.x = x*Tile::pixelSizeX*Scene::tileScaleFactor;
			scene.portalPos.y = y*Tile::pixelSizeY*Scene::tileScaleFactor;
			Item *tmpItem = tmpFactory.getItem("PortalItem");
			tmpItem->setPosition(x, y);
			scene.items.push_back(tmpItem);
		}

		if (first == "Item")
		{
			std::string second;
			iss >> second;
			int x,y;
			iss >> x;
			iss >> y;

			Item *tmpItem = tmpFactory.getItem(second);
			tmpItem->setPosition(x*Tile::pixelSizeX*Scene::tileScaleFactor, y*Tile::pixelSizeY*Scene::tileScaleFactor);
			scene.items.push_back(tmpItem);
		}

		if (first == "TriggerItem")
		{
			int x1, x2, y1, y2;
			iss >> x1;
			iss >> y1;
			iss >> x2;
			iss >> y2;

			TriggerItem *tmpItem = (TriggerItem*) tmpFactory.getItem("TriggerItem");
			tmpItem->setSwitchPos(x1*Tile::pixelSizeX*Scene::tileScaleFactor, y1*Tile::pixelSizeY*Scene::tileScaleFactor, x2*Tile::pixelSizeX*Scene::tileScaleFactor, y2*Tile::pixelSizeY*Scene::tileScaleFactor);
			scene.items.push_back(tmpItem);
		}

	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2000-2008, François Revol, <revol@free.fr>. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "ThemeAddonItem.h"
#include "ThemeInterfaceView.h"
#include "ThemeManager.h"
#include "UITheme.h"
#include <BeBuild.h>
#ifdef B_ZETA_VERSION
#include <locale/Locale.h>
#else
#define _T(v) v
#define B_LANGUAGE_CHANGED '_BLC'
#define B_PREF_APP_SET_DEFAULTS 'zPAD'
#define B_PREF_APP_REVERT 'zPAR'
#define B_PREF_APP_ADDON_REF 'zPAA'
#endif
#include <Button.h>
#include <CheckBox.h>
#include <Font.h>
#include <Roster.h>
#include <View.h>
#include <stdio.h>

#define CTRL_OFF_X 40
#define CTRL_OFF_Y 25
#define CTRL_SPACING 10

#define HAVE_PREF_BTN

ThemeAddonItem::ThemeAddonItem(BRect bounds, ThemeInterfaceView *iview, int32 id)
	: ViewItem(bounds, "addonitem", B_FOLLOW_NONE, B_WILL_DRAW)
{
	ThemeManager *tman;
	fId = id;
	fIView = iview;
	tman = iview->GetThemeManager();
	fAddonName = tman->AddonName(id);
	BString tip(tman->AddonDescription(id));
#ifdef B_BEOS_VERSION_DANO
	SetToolTipText(tip.String());
	SetViewUIColor(B_UI_PANEL_BACKGROUND_COLOR);
	SetLowUIColor(B_UI_PANEL_BACKGROUND_COLOR);
	SetHighUIColor(B_UI_PANEL_TEXT_COLOR);
#else
	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	SetHighColor(ui_color(B_PANEL_TEXT_COLOR));
#endif
	BMessage *apply = new BMessage(CB_APPLY);
	apply->AddInt32("addon", id);
	BMessage *save = new BMessage(CB_SAVE);
	save->AddInt32("addon", id);
	BMessage *prefs = new BMessage(BTN_PREFS);
	prefs->AddInt32("addon", id);
	fApplyBox = new BCheckBox(BRect(CTRL_OFF_X, CTRL_OFF_Y, CTRL_OFF_X+50, CTRL_OFF_Y+30), "apply", _T("Apply"), apply);
	fApplyBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_SET_ALL)?B_CONTROL_ON:B_CONTROL_OFF);
	fSaveBox = new BCheckBox(BRect(CTRL_OFF_X+50+CTRL_SPACING, CTRL_OFF_Y, CTRL_OFF_X+100+CTRL_SPACING, CTRL_OFF_Y+30), "save", _T("Save"), save);
	fSaveBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_RETRIEVE)?B_CONTROL_ON:B_CONTROL_OFF);
#ifdef B_BEOS_VERSION_DANO
	fApplyBox->SetToolTipText(_T("Use this information from themes"));
	fSaveBox->SetToolTipText(_T("Save this information to themes"));
#endif
#ifdef HAVE_PREF_BTN
	fPrefsBtn = new BButton(BRect(CTRL_OFF_X+100+CTRL_SPACING*2, CTRL_OFF_Y, CTRL_OFF_X+150+CTRL_SPACING*2, CTRL_OFF_Y+30), "prefs", _T("Preferences"), prefs);
#ifdef B_BEOS_VERSION_DANO
	fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic."));
#endif
#endif
	BFont fnt;
	GetFont(&fnt);
	fnt.SetSize(fnt.Size()+1);
	fnt.SetFace(B_ITALIC_FACE);
	SetFont(&fnt);
}

ThemeAddonItem::~ThemeAddonItem()
{
	delete fApplyBox;
	delete fSaveBox;
#ifdef HAVE_PREF_BTN
	delete fPrefsBtn;
#endif
}

void
ThemeAddonItem::DrawItem(BView *ownerview, BRect frame, bool complete)
{
	ViewItem::DrawItem(ownerview, frame, complete);
}

void
ThemeAddonItem::AttachedToWindow()
{
	AddChild(fApplyBox);
	fApplyBox->SetTarget(fIView);
	AddChild(fSaveBox);
	fSaveBox->SetTarget(fIView);
#ifdef HAVE_PREF_BTN
	AddChild(fPrefsBtn);
	fPrefsBtn->SetTarget(fIView);
#endif
	RelayoutButtons();
}

void
ThemeAddonItem::MessageReceived(BMessage *message)
{
	switch (message->what) {
	case B_LANGUAGE_CHANGED:
		break;
	}
	BView::MessageReceived(message);
}

void
ThemeAddonItem::Draw(BRect)
{
	DrawString(fAddonName.String(), BPoint(10, 15/*Bounds().Height()/2*/));
}

void
ThemeAddonItem::RelocalizeStrings()
{
	fApplyBox->SetLabel(_T("Apply"));
	fSaveBox->SetLabel(_T("Save"));
#ifdef B_BEOS_VERSION_DANO
	fApplyBox->SetToolTipText(_T("Use this information from themes"));
	fSaveBox->SetToolTipText(_T("Save this information to themes"));
#endif
#ifdef HAVE_PREF_BTN
	fPrefsBtn->SetLabel(_T("Preferences"));
#ifdef B_BEOS_VERSION_DANO
	fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic."));
#endif
#endif
	RelayoutButtons();
}

void
ThemeAddonItem::RelayoutButtons()
{
	fApplyBox->ResizeToPreferred();
	fSaveBox->MoveTo(fApplyBox->Frame().right+CTRL_SPACING, fApplyBox->Frame().top);
	fSaveBox->ResizeToPreferred();
#ifdef HAVE_PREF_BTN
	fPrefsBtn->MoveTo(fSaveBox->Frame().right+CTRL_SPACING, fSaveBox->Frame().top);
	fPrefsBtn->ResizeToPreferred();
#endif
}

int32
ThemeAddonItem::AddonId()
{
	return fId;
}

<commit_msg>Add tooltips on Haiku<commit_after>/*
 * Copyright 2000-2008, François Revol, <revol@free.fr>. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "ThemeAddonItem.h"
#include "ThemeInterfaceView.h"
#include "ThemeManager.h"
#include "UITheme.h"
#include <BeBuild.h>
#ifdef B_ZETA_VERSION
#include <locale/Locale.h>
#else
#define _T(v) v
#define B_LANGUAGE_CHANGED '_BLC'
#define B_PREF_APP_SET_DEFAULTS 'zPAD'
#define B_PREF_APP_REVERT 'zPAR'
#define B_PREF_APP_ADDON_REF 'zPAA'
#endif
#include <Button.h>
#include <CheckBox.h>
#include <Font.h>
#include <Roster.h>
#include <View.h>
#include <stdio.h>

#define CTRL_OFF_X 40
#define CTRL_OFF_Y 25
#define CTRL_SPACING 10

#define HAVE_PREF_BTN

ThemeAddonItem::ThemeAddonItem(BRect bounds, ThemeInterfaceView *iview, int32 id)
	: ViewItem(bounds, "addonitem", B_FOLLOW_NONE, B_WILL_DRAW)
{
	ThemeManager *tman;
	fId = id;
	fIView = iview;
	tman = iview->GetThemeManager();
	fAddonName = tman->AddonName(id);
	BString tip(tman->AddonDescription(id));
#ifdef B_BEOS_VERSION_DANO
	SetToolTipText(tip.String());
	SetViewUIColor(B_UI_PANEL_BACKGROUND_COLOR);
	SetLowUIColor(B_UI_PANEL_BACKGROUND_COLOR);
	SetHighUIColor(B_UI_PANEL_TEXT_COLOR);
#else
#ifdef __HAIKU__
	SetToolTip(tip.String());
#endif
	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	SetHighColor(ui_color(B_PANEL_TEXT_COLOR));
#endif
	BMessage *apply = new BMessage(CB_APPLY);
	apply->AddInt32("addon", id);
	BMessage *save = new BMessage(CB_SAVE);
	save->AddInt32("addon", id);
	BMessage *prefs = new BMessage(BTN_PREFS);
	prefs->AddInt32("addon", id);
	fApplyBox = new BCheckBox(BRect(CTRL_OFF_X, CTRL_OFF_Y, CTRL_OFF_X+50, CTRL_OFF_Y+30), "apply", _T("Apply"), apply);
	fApplyBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_SET_ALL)?B_CONTROL_ON:B_CONTROL_OFF);
	fSaveBox = new BCheckBox(BRect(CTRL_OFF_X+50+CTRL_SPACING, CTRL_OFF_Y, CTRL_OFF_X+100+CTRL_SPACING, CTRL_OFF_Y+30), "save", _T("Save"), save);
	fSaveBox->SetValue((tman->AddonFlags(id) & Z_THEME_ADDON_DO_RETRIEVE)?B_CONTROL_ON:B_CONTROL_OFF);
#ifdef B_BEOS_VERSION_DANO
	fApplyBox->SetToolTipText(_T("Use this information from themes"));
	fSaveBox->SetToolTipText(_T("Save this information to themes"));
#endif
#ifdef __HAIKU__
	fApplyBox->SetToolTip(_T("Use this information from themes"));
	fSaveBox->SetToolTip(_T("Save this information to themes"));
#endif
#ifdef HAVE_PREF_BTN
	fPrefsBtn = new BButton(BRect(CTRL_OFF_X+100+CTRL_SPACING*2, CTRL_OFF_Y, CTRL_OFF_X+150+CTRL_SPACING*2, CTRL_OFF_Y+30), "prefs", _T("Preferences"), prefs);
#ifdef B_BEOS_VERSION_DANO
	fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic."));
#endif
#ifdef __HAIKU__
	fPrefsBtn->SetToolTip(_T("Run the preferences panel for this topic."));
#endif
#endif
	BFont fnt;
	GetFont(&fnt);
	fnt.SetSize(fnt.Size()+1);
	fnt.SetFace(B_ITALIC_FACE);
	SetFont(&fnt);
}

ThemeAddonItem::~ThemeAddonItem()
{
	delete fApplyBox;
	delete fSaveBox;
#ifdef HAVE_PREF_BTN
	delete fPrefsBtn;
#endif
}

void
ThemeAddonItem::DrawItem(BView *ownerview, BRect frame, bool complete)
{
	ViewItem::DrawItem(ownerview, frame, complete);
}

void
ThemeAddonItem::AttachedToWindow()
{
	AddChild(fApplyBox);
	fApplyBox->SetTarget(fIView);
	AddChild(fSaveBox);
	fSaveBox->SetTarget(fIView);
#ifdef HAVE_PREF_BTN
	AddChild(fPrefsBtn);
	fPrefsBtn->SetTarget(fIView);
#endif
	RelayoutButtons();
}

void
ThemeAddonItem::MessageReceived(BMessage *message)
{
	switch (message->what) {
	case B_LANGUAGE_CHANGED:
		break;
	}
	BView::MessageReceived(message);
}

void
ThemeAddonItem::Draw(BRect)
{
	DrawString(fAddonName.String(), BPoint(10, 15/*Bounds().Height()/2*/));
}

void
ThemeAddonItem::RelocalizeStrings()
{
	fApplyBox->SetLabel(_T("Apply"));
	fSaveBox->SetLabel(_T("Save"));
#ifdef B_BEOS_VERSION_DANO
	fApplyBox->SetToolTipText(_T("Use this information from themes"));
	fSaveBox->SetToolTipText(_T("Save this information to themes"));
#endif
#ifdef __HAIKU__
	fApplyBox->SetToolTip(_T("Use this information from themes"));
	fSaveBox->SetToolTip(_T("Save this information to themes"));
#endif
#ifdef HAVE_PREF_BTN
	fPrefsBtn->SetLabel(_T("Preferences"));
#ifdef B_BEOS_VERSION_DANO
	fPrefsBtn->SetToolTipText(_T("Run the preferences panel for this topic."));
#endif
#ifdef __HAIKU__
	fPrefsBtn->SetToolTip(_T("Run the preferences panel for this topic."));
#endif
#endif
	RelayoutButtons();
}

void
ThemeAddonItem::RelayoutButtons()
{
	fApplyBox->ResizeToPreferred();
	fSaveBox->MoveTo(fApplyBox->Frame().right+CTRL_SPACING, fApplyBox->Frame().top);
	fSaveBox->ResizeToPreferred();
#ifdef HAVE_PREF_BTN
	fPrefsBtn->MoveTo(fSaveBox->Frame().right+CTRL_SPACING, fSaveBox->Frame().top);
	fPrefsBtn->ResizeToPreferred();
#endif
}

int32
ThemeAddonItem::AddonId()
{
	return fId;
}

<|endoftext|>


<commit_before>#include "ToolBase.h"
#include "TSVFileStream.h"
#include "Helper.h"
#include "BasicStatistics.h"
#include <QFileInfo>
#include <QBitArray>

class ConcreteTool
		: public ToolBase
{
	Q_OBJECT

public:
	ConcreteTool(int& argc, char *argv[])
		: ToolBase(argc, argv)
	{
		ops << ">" << ">=" << "=" << "<=" << "<" << "is" << "contains";
	}

	virtual void setup()
	{
		setDescription("Filters the rows of a TSV file according to the value of a specific column.");
		addString("filter", "Filter string with column name, operation and value,e.g. 'depth > 17'.\nValid operations are '" + ops.join("','") + "'.", false);
		//optional
		addInfile("in", "Input TSV file. If unset, reads from STDIN.", true);
		addOutfile("out", "Output TSV file. If unset, writes to STDOUT.", true);
		addFlag("numeric", "If set, column name is interpreted as a 1-based column number.");
		addFlag("v", "Invert filter.");
	}

	virtual void main()
	{
		//init
		QString in = getInfile("in");
		QString out = getOutfile("out");
		if(in!="" && in==out)
		{
			THROW(ArgumentException, "Input and output files must be different when streaming!");
		}
		TSVFileStream instream(in);
		QSharedPointer<QFile> outstream = Helper::openFileForWriting(out, true);
		bool v = getFlag("v");

		//split filter
		QString filter = getString("filter");
		QStringList parts = filter.split(" ");
		if (parts.count()<3)
		{
			THROW(CommandLineParsingException, "Could not split filter '" + filter + "' in three or more parts (by space)!");
		}
		//re-join string values with spaces
		while(parts.count()>3)
		{
			int count = parts.count();
			parts[count-2] += " " +parts[count-1];
			parts.removeLast();
		}

		//check column
		QVector<int> cols = instream.checkColumns(parts[0].toLatin1().split(','), getFlag("numeric"));
		if (cols.count()!=1)
		{
			THROW(CommandLineParsingException, "Could not determine column name/index '" + parts[0] + "'!");
		}
		int col = cols[0];

		//check operation
		QByteArray op = parts[1].toLatin1();
		int op_index = ops.indexOf(op);
		if(op_index==-1)
		{
			THROW(CommandLineParsingException, "Invalid operation '" + op + "'!");
		}

		//check value
		QByteArray value = parts[2].toLatin1();
		double value_num = 0;
		if (op_index<5)
		{
			if(!BasicStatistics::isValidFloat(value))
			{
				THROW(CommandLineParsingException, "Non-numeric filter value '" + value + "' for numeric filter operation '" + op + " given!");
			}
			value_num = value.toDouble();
		}

		//write comments
		foreach (QByteArray comment, instream.comments())
		{
			outstream->write(comment);
			outstream->write("\n");
		}

		//write header
		const int col_count = instream.header().count();
		outstream->write("#");
		for(int i=0; i<col_count; ++i)
		{
			outstream->write(instream.header()[i]);
			outstream->write(i==col_count-1 ? "\n" : "\t");
		}

		qDebug() << parts[0] << " " << op << " " << parts[2];

		//write content
		while(!instream.atEnd())
		{
			QList<QByteArray> parts = instream.readLine();
			if (parts.count()==0) continue;

			QByteArray value2 = parts[col];
			double value2_num = 0;
			if (op_index<5)
			{
				bool ok = true;
				value2_num = value2.toDouble(&ok);
				if (!ok)
				{
					THROW(CommandLineParsingException, "Non-numeric value '" + value2 + "' for numeric filter operation '" + op + " in line " + QString::number(instream.lineIndex()+1) + "!");
				}
			}

			bool pass_filter = true;
			switch(op_index)
			{
				case 0: //">"
					pass_filter = value2_num>value_num;
					break;
				case 1: //">="
					pass_filter = value2_num>=value_num;
					break;
				case 2: //"="
					pass_filter = value2_num==value_num;
					break;
				case 3: //"<="
					pass_filter = value2_num<=value_num;
					break;
				case 4: //"<"
					pass_filter = value2_num<value_num;
					break;
				case 5: //"is"
					pass_filter = value2 == value;
					break;
				case 6: //"contains"
					pass_filter = value2.contains(value);
					break;
				default:
					THROW(ProgrammingException, "Invalid filter operation index " + QString::number(op_index) + "!");
			};

			if ((!v && !pass_filter) ||  (v && pass_filter))
			{
				continue;
			}

			for(int i=0; i<col_count; ++i)
			{
				outstream->write(parts[i]);
				outstream->write(i==col_count-1 ? "\n" : "\t");
			}
		}
    }

	//valid operations list
	QStringList ops;
};

#include "main.moc"

int main(int argc, char *argv[])
{
	ConcreteTool tool(argc, argv);
	return tool.execute();
}

<commit_msg>src/TsvFilter/main.cpp: removed Debug output<commit_after>#include "ToolBase.h"
#include "TSVFileStream.h"
#include "Helper.h"
#include "BasicStatistics.h"
#include <QFileInfo>
#include <QBitArray>

class ConcreteTool
		: public ToolBase
{
	Q_OBJECT

public:
	ConcreteTool(int& argc, char *argv[])
		: ToolBase(argc, argv)
	{
		ops << ">" << ">=" << "=" << "<=" << "<" << "is" << "contains";
	}

	virtual void setup()
	{
		setDescription("Filters the rows of a TSV file according to the value of a specific column.");
		addString("filter", "Filter string with column name, operation and value,e.g. 'depth > 17'.\nValid operations are '" + ops.join("','") + "'.", false);
		//optional
		addInfile("in", "Input TSV file. If unset, reads from STDIN.", true);
		addOutfile("out", "Output TSV file. If unset, writes to STDOUT.", true);
		addFlag("numeric", "If set, column name is interpreted as a 1-based column number.");
		addFlag("v", "Invert filter.");
	}

	virtual void main()
	{
		//init
		QString in = getInfile("in");
		QString out = getOutfile("out");
		if(in!="" && in==out)
		{
			THROW(ArgumentException, "Input and output files must be different when streaming!");
		}
		TSVFileStream instream(in);
		QSharedPointer<QFile> outstream = Helper::openFileForWriting(out, true);
		bool v = getFlag("v");

		//split filter
		QString filter = getString("filter");
		QStringList parts = filter.split(" ");
		if (parts.count()<3)
		{
			THROW(CommandLineParsingException, "Could not split filter '" + filter + "' in three or more parts (by space)!");
		}
		//re-join string values with spaces
		while(parts.count()>3)
		{
			int count = parts.count();
			parts[count-2] += " " +parts[count-1];
			parts.removeLast();
		}

		//check column
		QVector<int> cols = instream.checkColumns(parts[0].toLatin1().split(','), getFlag("numeric"));
		if (cols.count()!=1)
		{
			THROW(CommandLineParsingException, "Could not determine column name/index '" + parts[0] + "'!");
		}
		int col = cols[0];

		//check operation
		QByteArray op = parts[1].toLatin1();
		int op_index = ops.indexOf(op);
		if(op_index==-1)
		{
			THROW(CommandLineParsingException, "Invalid operation '" + op + "'!");
		}

		//check value
		QByteArray value = parts[2].toLatin1();
		double value_num = 0;
		if (op_index<5)
		{
			if(!BasicStatistics::isValidFloat(value))
			{
				THROW(CommandLineParsingException, "Non-numeric filter value '" + value + "' for numeric filter operation '" + op + " given!");
			}
			value_num = value.toDouble();
		}

		//write comments
		foreach (QByteArray comment, instream.comments())
		{
			outstream->write(comment);
			outstream->write("\n");
		}

		//write header
		const int col_count = instream.header().count();
		outstream->write("#");
		for(int i=0; i<col_count; ++i)
		{
			outstream->write(instream.header()[i]);
			outstream->write(i==col_count-1 ? "\n" : "\t");
		}

		//write content
		while(!instream.atEnd())
		{
			QList<QByteArray> parts = instream.readLine();
			if (parts.count()==0) continue;

			QByteArray value2 = parts[col];
			double value2_num = 0;
			if (op_index<5)
			{
				bool ok = true;
				value2_num = value2.toDouble(&ok);
				if (!ok)
				{
					THROW(CommandLineParsingException, "Non-numeric value '" + value2 + "' for numeric filter operation '" + op + " in line " + QString::number(instream.lineIndex()+1) + "!");
				}
			}

			bool pass_filter = true;
			switch(op_index)
			{
				case 0: //">"
					pass_filter = value2_num>value_num;
					break;
				case 1: //">="
					pass_filter = value2_num>=value_num;
					break;
				case 2: //"="
					pass_filter = value2_num==value_num;
					break;
				case 3: //"<="
					pass_filter = value2_num<=value_num;
					break;
				case 4: //"<"
					pass_filter = value2_num<value_num;
					break;
				case 5: //"is"
					pass_filter = value2 == value;
					break;
				case 6: //"contains"
					pass_filter = value2.contains(value);
					break;
				default:
					THROW(ProgrammingException, "Invalid filter operation index " + QString::number(op_index) + "!");
			};

			if ((!v && !pass_filter) ||  (v && pass_filter))
			{
				continue;
			}

			for(int i=0; i<col_count; ++i)
			{
				outstream->write(parts[i]);
				outstream->write(i==col_count-1 ? "\n" : "\t");
			}
		}
    }

	//valid operations list
	QStringList ops;
};

#include "main.moc"

int main(int argc, char *argv[])
{
	ConcreteTool tool(argc, argv);
	return tool.execute();
}

<|endoftext|>