<commit_before>#pragma once

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/not_null.hpp"
#include "geometry/rotation.hpp"
#include "geometry/orthogonal_map.hpp"
#include "ksp_plugin/frames.hpp"
#include "ksp_plugin/part.hpp"
#include "ksp_plugin/vessel.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "serialization/ksp_plugin.pb.h"

namespace principia {

using base::not_null;
using geometry::OrthogonalMap;
using physics::DegreesOfFreedom;
using physics::RelativeDegreesOfFreedom;

namespace ksp_plugin {

class PhysicsBubble {
 public:
  using BarycentricToWorldSun = geometry::OrthogonalMap<Barycentric, WorldSun>;

  PhysicsBubble();
  ~PhysicsBubble() = default;

  // Creates |next_| if it is null.  Adds the |vessel| to |next_->vessels| with
  // a list of pointers to the Parts in |parts|.  Merges |parts| into
  // |next_->parts|.  The |vessel| must not already be in |next_->vessels|.
  // |parts| must not contain a |PartId| already in |next_->parts|.
  void AddVesselToNext(not_null<Vessel*> const vessel,
                       std::vector<IdAndOwnedPart> parts);

  // If |next_| is not null, computes the world centre of mass, trajectory
  // (including intrinsic acceleration) of |*next_|. Moves |next_| into
  // |current_|.  The trajectory of the centre of mass is reset to a single
  // point at |current_time| if the composition of the bubble changes.
  // TODO(phl): Document the parameters!
  void Prepare(BarycentricToWorldSun const& barycentric_to_world_sun,
               Instant const& current_time,
               Instant const& next_time);

  // Computes and returns |current_->displacement_correction|.  This is the
  // |World| shift to be applied to the bubble in order for it to be in the
  // correct position.
  Displacement<World> DisplacementCorrection(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      Celestial const& reference_celestial,
      Position<World> const& reference_celestial_world_position) const;

  // Computes and returns |current_->velocity_correction|.  This is the |World|
  // shift to be applied to the physics bubble in order for it to have the
  // correct velocity.
  Velocity<World> VelocityCorrection(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      Celestial const& reference_celestial) const;

  // Returns |current_ == nullptr|.
  bool empty() const;

  // Returns 0 if |empty()|, 1 otherwise.
  std::size_t size() const;

  // Returns |current_->vessels.size()|, or 0 if |empty()|.
  std::size_t number_of_vessels() const;

  // Returns true if, and only if, |vessel| is in |current_->vessels|.
  // |current_| may be null, in that case, returns false.
  bool contains(not_null<Vessel*> const vessel) const;

  // Selectors for the data in |current_|.
  std::vector<not_null<Vessel*>> vessels() const;
  RelativeDegreesOfFreedom<Barycentric> const& from_centre_of_mass(
      not_null<Vessel const*> const vessel) const;
  Trajectory<Barycentric> const& centre_of_mass_trajectory() const;
  not_null<Trajectory<Barycentric>*> mutable_centre_of_mass_trajectory() const;

  void WriteToMessage(
      std::function<std::string(not_null<Vessel const*>)> const guid,
      not_null<serialization::PhysicsBubble*> const message) const;
  static std::unique_ptr<PhysicsBubble> ReadFromMessage(
      std::function<not_null<Vessel*>(std::string)> const vessel,
      serialization::PhysicsBubble const& message);

 private:
  using PartCorrespondence = std::pair<not_null<Part<World>*>,
                                       not_null<Part<World>*>>;

  struct PreliminaryState {
    PreliminaryState();
    std::map<not_null<Vessel*> const,
             std::vector<not_null<Part<World>*> const>> vessels;
    PartIdToOwnedPart parts;
  };

  struct FullState : public PreliminaryState {
    explicit FullState(
        PreliminaryState&& preliminary_state);  // NOLINT(build/c++11)

    // TODO(egg): these fields should be |std::optional| when that becomes a
    // thing.
    std::unique_ptr<DegreesOfFreedom<World>> centre_of_mass;
    std::unique_ptr<Trajectory<Barycentric>> centre_of_mass_trajectory;
    std::unique_ptr<std::map<not_null<Vessel const*> const,
                             RelativeDegreesOfFreedom<Barycentric>>>
        from_centre_of_mass;
    std::unique_ptr<Displacement<World>> displacement_correction;
    std::unique_ptr<Velocity<World>> velocity_correction;
  };

  // Computes the world degrees of freedom of the centre of mass of
  // |next| using the contents of |next->parts|.
  void ComputeNextCentreOfMassWorldDegreesOfFreedom(
      not_null<FullState*> const next);

  // Computes |next->displacements_from_centre_of_mass| and
  // |next->velocities_from_centre_of_mass|.
  void ComputeNextVesselOffsets(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      not_null<FullState*> const next);

  // Creates |next->centre_of_mass_trajectory| and appends to it the barycentre
  // of the degrees of freedom of the vessels in |next->vessels|.  There is no
  // intrinsic acceleration.
  void RestartNext(Instant const& current_time,
                   not_null<FullState*> const next);

  // Returns the parts common to |current_| and |next|.  The returned vector
  // contains pair of pointers to parts (current_part, next_part) for all parts
  // common to the two bubbles
  std::vector<PhysicsBubble::PartCorrespondence> ComputeCommonParts(
      FullState const& next);

  // Returns the intrinsic acceleration measured on the parts that are common to
  // the current and next bubbles.
  Vector<Acceleration, World> IntrinsicAcceleration(
      Instant const& current_time,
      Instant const& next_time,
      std::vector<PartCorrespondence>const& common_parts);

  // Given the vector of common parts, constructs
  // |next->centre_of_mass_trajectory| and appends degrees of freedom at
  // |current_time| that conserve the degrees of freedom of the centre of mass
  // of the parts in |common_parts|.
  void Shift(BarycentricToWorldSun const& barycentric_to_world_sun,
             Instant const& current_time,
             std::vector<PartCorrespondence> const& common_parts,
             not_null<FullState*> const next);

  std::unique_ptr<FullState> current_;
  // The following member is only accessed by |AddVesselToNext| and at the
  // beginning of |Prepare|.
  std::unique_ptr<PreliminaryState> next_;

  MasslessBody const body_;
};

}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>Aphlabetize.<commit_after>#pragma once

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/not_null.hpp"
#include "geometry/orthogonal_map.hpp"
#include "geometry/rotation.hpp"
#include "ksp_plugin/frames.hpp"
#include "ksp_plugin/part.hpp"
#include "ksp_plugin/vessel.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "serialization/ksp_plugin.pb.h"

namespace principia {

using base::not_null;
using geometry::OrthogonalMap;
using physics::DegreesOfFreedom;
using physics::RelativeDegreesOfFreedom;

namespace ksp_plugin {

class PhysicsBubble {
 public:
  using BarycentricToWorldSun = geometry::OrthogonalMap<Barycentric, WorldSun>;

  PhysicsBubble();
  ~PhysicsBubble() = default;

  // Creates |next_| if it is null.  Adds the |vessel| to |next_->vessels| with
  // a list of pointers to the Parts in |parts|.  Merges |parts| into
  // |next_->parts|.  The |vessel| must not already be in |next_->vessels|.
  // |parts| must not contain a |PartId| already in |next_->parts|.
  void AddVesselToNext(not_null<Vessel*> const vessel,
                       std::vector<IdAndOwnedPart> parts);

  // If |next_| is not null, computes the world centre of mass, trajectory
  // (including intrinsic acceleration) of |*next_|. Moves |next_| into
  // |current_|.  The trajectory of the centre of mass is reset to a single
  // point at |current_time| if the composition of the bubble changes.
  // TODO(phl): Document the parameters!
  void Prepare(BarycentricToWorldSun const& barycentric_to_world_sun,
               Instant const& current_time,
               Instant const& next_time);

  // Computes and returns |current_->displacement_correction|.  This is the
  // |World| shift to be applied to the bubble in order for it to be in the
  // correct position.
  Displacement<World> DisplacementCorrection(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      Celestial const& reference_celestial,
      Position<World> const& reference_celestial_world_position) const;

  // Computes and returns |current_->velocity_correction|.  This is the |World|
  // shift to be applied to the physics bubble in order for it to have the
  // correct velocity.
  Velocity<World> VelocityCorrection(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      Celestial const& reference_celestial) const;

  // Returns |current_ == nullptr|.
  bool empty() const;

  // Returns 0 if |empty()|, 1 otherwise.
  std::size_t size() const;

  // Returns |current_->vessels.size()|, or 0 if |empty()|.
  std::size_t number_of_vessels() const;

  // Returns true if, and only if, |vessel| is in |current_->vessels|.
  // |current_| may be null, in that case, returns false.
  bool contains(not_null<Vessel*> const vessel) const;

  // Selectors for the data in |current_|.
  std::vector<not_null<Vessel*>> vessels() const;
  RelativeDegreesOfFreedom<Barycentric> const& from_centre_of_mass(
      not_null<Vessel const*> const vessel) const;
  Trajectory<Barycentric> const& centre_of_mass_trajectory() const;
  not_null<Trajectory<Barycentric>*> mutable_centre_of_mass_trajectory() const;

  void WriteToMessage(
      std::function<std::string(not_null<Vessel const*>)> const guid,
      not_null<serialization::PhysicsBubble*> const message) const;
  static std::unique_ptr<PhysicsBubble> ReadFromMessage(
      std::function<not_null<Vessel*>(std::string)> const vessel,
      serialization::PhysicsBubble const& message);

 private:
  using PartCorrespondence = std::pair<not_null<Part<World>*>,
                                       not_null<Part<World>*>>;

  struct PreliminaryState {
    PreliminaryState();
    std::map<not_null<Vessel*> const,
             std::vector<not_null<Part<World>*> const>> vessels;
    PartIdToOwnedPart parts;
  };

  struct FullState : public PreliminaryState {
    explicit FullState(
        PreliminaryState&& preliminary_state);  // NOLINT(build/c++11)

    // TODO(egg): these fields should be |std::optional| when that becomes a
    // thing.
    std::unique_ptr<DegreesOfFreedom<World>> centre_of_mass;
    std::unique_ptr<Trajectory<Barycentric>> centre_of_mass_trajectory;
    std::unique_ptr<std::map<not_null<Vessel const*> const,
                             RelativeDegreesOfFreedom<Barycentric>>>
        from_centre_of_mass;
    std::unique_ptr<Displacement<World>> displacement_correction;
    std::unique_ptr<Velocity<World>> velocity_correction;
  };

  // Computes the world degrees of freedom of the centre of mass of
  // |next| using the contents of |next->parts|.
  void ComputeNextCentreOfMassWorldDegreesOfFreedom(
      not_null<FullState*> const next);

  // Computes |next->displacements_from_centre_of_mass| and
  // |next->velocities_from_centre_of_mass|.
  void ComputeNextVesselOffsets(
      BarycentricToWorldSun const& barycentric_to_world_sun,
      not_null<FullState*> const next);

  // Creates |next->centre_of_mass_trajectory| and appends to it the barycentre
  // of the degrees of freedom of the vessels in |next->vessels|.  There is no
  // intrinsic acceleration.
  void RestartNext(Instant const& current_time,
                   not_null<FullState*> const next);

  // Returns the parts common to |current_| and |next|.  The returned vector
  // contains pair of pointers to parts (current_part, next_part) for all parts
  // common to the two bubbles
  std::vector<PhysicsBubble::PartCorrespondence> ComputeCommonParts(
      FullState const& next);

  // Returns the intrinsic acceleration measured on the parts that are common to
  // the current and next bubbles.
  Vector<Acceleration, World> IntrinsicAcceleration(
      Instant const& current_time,
      Instant const& next_time,
      std::vector<PartCorrespondence>const& common_parts);

  // Given the vector of common parts, constructs
  // |next->centre_of_mass_trajectory| and appends degrees of freedom at
  // |current_time| that conserve the degrees of freedom of the centre of mass
  // of the parts in |common_parts|.
  void Shift(BarycentricToWorldSun const& barycentric_to_world_sun,
             Instant const& current_time,
             std::vector<PartCorrespondence> const& common_parts,
             not_null<FullState*> const next);

  std::unique_ptr<FullState> current_;
  // The following member is only accessed by |AddVesselToNext| and at the
  // beginning of |Prepare|.
  std::unique_ptr<PreliminaryState> next_;

  MasslessBody const body_;
};

}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>#include "GolfBall.hpp"
#include "../Resources.hpp"
#include "Default3D.vert.hpp"
#include "Default3D.geom.hpp"
#include "Default3D.frag.hpp"
#include "glm/gtc/constants.hpp"
#include "../Util/Log.hpp"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>

GolfBall::GolfBall(BallType ballType, TerrainObject* terrain) : ModelObject(modelGeometry = Resources().CreateOBJModel("Resources/Models/GolfBall/GolfBall.obj"),
                                                                            "Resources/Models/GolfBall/Diffuse.png",
                                                                            "Resources/Models/GolfBall/Normal.png",
                                                                            "Resources/Models/GolfBall/Specular.png") {
    active = false;

    restitution = ballType == TWOPIECE ? 0.78f : 0.68f;
    this->terrain = terrain;
    groundLevel = this->terrain->Position().y;
    origin = glm::vec3(1.f, 0.f, 1.f);

    /// @todo Mass based on explosive material.
    mass = 0.0459f;
    this->ballType = ballType;

    sphere.position = Position();
    SetRadius(0.0214f);
}

GolfBall::~GolfBall() {
    Resources().FreeOBJModel(modelGeometry);
}

void GolfBall::Reset(){
    active = false;
    velocity = glm::vec3(0.f, 0.f, 0.f);
    angularVelocity = glm::vec3(0.f, 0.f, 0.f);
    SetPosition(origin);
    sphere.position = Position();
    orientation = glm::quat();
}

void GolfBall::Update(double time, const glm::vec3& wind, std::vector<PlayerObject>& players) {
	if (active) {
		Move(static_cast<float>(time)* velocity);
		sphere.position = Position();

		if (glm::length(angularVelocity) > 0.0001f) {
			glm::quat deltaQuat = glm::angleAxis(static_cast<float>(time)* glm::length(angularVelocity), glm::normalize(angularVelocity));
			orientation = deltaQuat * orientation;
		}

		glm::vec3 dragForce, magnusForce = glm::vec3(0.f, 0.f, 0.f);

		// Check for collision
		groundLevel = terrain->GetY(Position().x, Position().z);
		if (glm::length(velocity) > 0.0001f && (sphere.position.y - sphere.radius) < groundLevel){
			float vCritical = 0.3f;
			float e = 0.35f;
			float muSliding = 0.51f;
			float muRolling = 0.096f;
			SetPosition(Position().x, groundLevel + sphere.radius, Position().z);
			sphere.position = Position();
			//glm::vec3 eRoh = glm::normalize(glm::vec3(0.f, 1.f, 0.f));
			glm::vec3 eRoh = terrain->GetNormal(Position().x, Position().z);
			glm::vec3 tangentialVelocity = velocity - glm::dot(velocity, eRoh) * eRoh;
			glm::vec3 eFriction = glm::vec3(0.f, 0.f, 0.f);
			if (glm::length(glm::cross(eRoh, angularVelocity) + tangentialVelocity) > 0.0001f){
				eFriction = glm::normalize(sphere.radius * glm::cross(eRoh, angularVelocity) + tangentialVelocity);
			}
			float vRoh = glm::dot(velocity, eRoh);
			float deltaU = -(e + 1.f) * vRoh;
			glm::vec3 angularDirection = glm::cross(eRoh, glm::normalize(tangentialVelocity));
			float w = glm::dot(angularVelocity, angularDirection);

			if (fabs(vRoh) < vCritical && glm::length(tangentialVelocity) > 0.0001f) {
				if (w * sphere.radius + 0.0001f < glm::length(tangentialVelocity)) {
					// Sliding.
					velocity = tangentialVelocity - static_cast<float>(time)* (eFriction * muSliding * 9.82f*eRoh.y);
					angularVelocity += (5.f / 2.f) * (muSliding * 9.82f / sphere.radius * static_cast<float>(time)) * angularDirection;
				} else {
					// Rolling.
					velocity = tangentialVelocity - static_cast<float>(time)* (glm::normalize(tangentialVelocity) * muRolling * 9.82f*eRoh.y);
					float tangentialVelocityAfter = glm::length(velocity - glm::dot(velocity, eRoh) * eRoh);
					angularVelocity = (glm::length(tangentialVelocityAfter) / sphere.radius) * angularDirection;
					// Stopped.
					if (glm::length(velocity) < 0.005f) {
						velocity = glm::vec3(0.f, 0.f, 0.f);
						angularVelocity = glm::vec3(0.f, 0.f, 0.f);
					}
				}
			} else {
				float deltaTime = pow(mass * mass / (fabs(vRoh) * sphere.radius), 0.2f) * 0.00251744f;
				float velocityRoh = glm::dot(velocity, eRoh);
				float velocityNormal = glm::dot(velocity, eFriction);
				float uRoh = -e*velocityRoh;
				float deltauRoh = uRoh - (velocityRoh);
				float deltaUn = muSliding*deltauRoh;
				float rollUn = (5.f / 7.f)*velocityNormal;
				float slideUn = velocityNormal - deltaUn;

				if (velocityNormal > rollUn){
					velocity = uRoh*eRoh + rollUn*eFriction;
					angularVelocity += muRolling * (deltaU + 9.82f*eRoh.y * deltaTime) / sphere.radius * glm::cross(eRoh, eFriction);
				} else {
					velocity = uRoh*eRoh + slideUn*eFriction;
					angularVelocity += muSliding * (deltaU + 9.82f *eRoh.y* deltaTime) / sphere.radius * glm::cross(eRoh, eFriction);
				}
			}
		} else {
			// Calculate magnus force.
			float v = glm::length(velocity);
			float u = glm::length(velocity - wind);
			float w = glm::length(angularVelocity);
			glm::vec3 eU = (velocity - wind) / u;
			magnusForce = glm::vec3(0.f, 0.f, 0.f);
			if (u > 0.f && v > 0.f && w > 0.f) {
				float Cm = (sqrt(1.f + 0.31f * (w / v)) - 1.f) / 20.f;
				float Fm = 0.5f * Cm * 1.23f * area * u * u;
				magnusForce = Fm * glm::cross(eU, glm::normalize(angularVelocity));
			}

			// Calculate drag force.
			float cD;
			if (ballType == TWOPIECE)
				cD = v < 65.f ? -0.0051f * v + 0.53f : 0.21f;
			else
				cD = v < 60.f ? -0.0084f * v + 0.73f : 0.22f;
			dragForce = glm::vec3(0.f, 0.f, 0.f);
			if (u > 0.f)
				dragForce = -0.5f * 1.23f * area * cD * u * u * eU;
		}
		// Calculate gravitational force.
		glm::vec3 gravitationForce = glm::vec3(0.f, mass * -9.82f, 0.f);
		// Get acceleration from total force.
		glm::vec3 acceleration = (dragForce + magnusForce + gravitationForce) / mass;
		velocity += acceleration * static_cast<float>(time);

	}
}

void GolfBall::Render(Camera* camera, const glm::vec2& screenSize, const glm::vec4& clippingPlane) const{
    ModelObject::Render(camera, screenSize, clippingPlane);
}

void GolfBall::Explode(std::vector<PlayerObject>& players, int playerIndex){
    //@TODO: Set mass equivalent depending on material used.
    float equivalenceFactor = 1.0f;
    float massEquivalent = mass*equivalenceFactor;
    for (auto &player : players){
        glm::vec3 distanceV = (Position() - player.Position());
        float distance = glm::length(distanceV);
        //pow(meq, 1.f/3.f) => cube root of meq
        float z = distance / (pow(massEquivalent, 1.f / 3.f));
        float alpha = 1 + pow((z / 4.5f), 2.f);
        float beta = 1 + pow((z / 0.048f), 2.f);
        float gamma = 1 + pow((z / 1.35f), 2.f);
        float delta = 1 + pow((z / 0.32f), 2.f);
        float Pf = 8.08f*pow(10.f, 7.f)*alpha;
        Pf = Pf / sqrt(beta*gamma*delta);
        player.TakeDamage(Pf);
    }
    origin = players[playerIndex].Position();
    Reset();
}

void GolfBall::Strike(ClubType club, const glm::vec3& clubVelocity) {
    active = true;

    // Club velocity in strike plane.
    float v = glm::length(clubVelocity);
    if (v > 0.f)
    {
        float sinLoft = sin(club.loft);
        float cosLoft = cos(club.loft);

        // Ball velocity.
        float massCoefficient = club.mass / (club.mass + mass);
        float Up = (1.f + restitution) * massCoefficient * v * cosLoft;
        float Un = (2.f / 7.f) * massCoefficient * v * sinLoft;

        // Go back from strike plane to 3D.
        glm::vec3 forward = clubVelocity / v;
        glm::vec3 up = glm::cross(forward, glm::cross(glm::vec3(0.f, 1.f, 0.f), forward));
        glm::vec3 ep = glm::normalize(cosLoft * forward + sinLoft * up);
        glm::vec3 en = glm::normalize(sinLoft * forward - cosLoft * up);

        // Total velocity.
        velocity = Up * ep + Un * en;
        angularVelocity = -Un / sphere.radius * glm::cross(ep, en);
    } else {
        velocity = glm::vec3(0.f, 0.f, 0.f);
        angularVelocity = glm::vec3(0.f, 0.f, 0.f);
    }
}

void GolfBall::SetRadius(float radius) {
    sphere.radius = radius;
    SetScale(glm::vec3(radius, radius, radius));
    area = glm::pi<float>() * radius * radius;
}

glm::mat4 GolfBall::Orientation() const {
    return glm::toMat4(orientation);
}
<commit_msg>Changed minimum velocity to stop the ball.<commit_after>#include "GolfBall.hpp"
#include "../Resources.hpp"
#include "Default3D.vert.hpp"
#include "Default3D.geom.hpp"
#include "Default3D.frag.hpp"
#include "glm/gtc/constants.hpp"
#include "../Util/Log.hpp"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>

GolfBall::GolfBall(BallType ballType, TerrainObject* terrain) : ModelObject(modelGeometry = Resources().CreateOBJModel("Resources/Models/GolfBall/GolfBall.obj"),
                                                                            "Resources/Models/GolfBall/Diffuse.png",
                                                                            "Resources/Models/GolfBall/Normal.png",
                                                                            "Resources/Models/GolfBall/Specular.png") {
    active = false;

    restitution = ballType == TWOPIECE ? 0.78f : 0.68f;
    this->terrain = terrain;
    groundLevel = this->terrain->Position().y;
    origin = glm::vec3(1.f, 0.f, 1.f);

    /// @todo Mass based on explosive material.
    mass = 0.0459f;
    this->ballType = ballType;

    sphere.position = Position();
    SetRadius(0.0214f);
}

GolfBall::~GolfBall() {
    Resources().FreeOBJModel(modelGeometry);
}

void GolfBall::Reset(){
    active = false;
    velocity = glm::vec3(0.f, 0.f, 0.f);
    angularVelocity = glm::vec3(0.f, 0.f, 0.f);
    SetPosition(origin);
    sphere.position = Position();
    orientation = glm::quat();
}

void GolfBall::Update(double time, const glm::vec3& wind, std::vector<PlayerObject>& players) {
	if (active) {
		Move(static_cast<float>(time)* velocity);
		sphere.position = Position();

		if (glm::length(angularVelocity) > 0.0001f) {
			glm::quat deltaQuat = glm::angleAxis(static_cast<float>(time)* glm::length(angularVelocity), glm::normalize(angularVelocity));
			orientation = deltaQuat * orientation;
		}

		glm::vec3 dragForce, magnusForce = glm::vec3(0.f, 0.f, 0.f);

		// Check for collision
		groundLevel = terrain->GetY(Position().x, Position().z);
		if (glm::length(velocity) > 0.0001f && (sphere.position.y - sphere.radius) < groundLevel){
			float vCritical = 0.3f;
			float e = 0.35f;
			float muSliding = 0.51f;
			float muRolling = 0.096f;
			SetPosition(Position().x, groundLevel + sphere.radius, Position().z);
			sphere.position = Position();
			//glm::vec3 eRoh = glm::normalize(glm::vec3(0.f, 1.f, 0.f));
			glm::vec3 eRoh = terrain->GetNormal(Position().x, Position().z);
			glm::vec3 tangentialVelocity = velocity - glm::dot(velocity, eRoh) * eRoh;
			glm::vec3 eFriction = glm::vec3(0.f, 0.f, 0.f);
			if (glm::length(glm::cross(eRoh, angularVelocity) + tangentialVelocity) > 0.0001f){
				eFriction = glm::normalize(sphere.radius * glm::cross(eRoh, angularVelocity) + tangentialVelocity);
			}
			float vRoh = glm::dot(velocity, eRoh);
			float deltaU = -(e + 1.f) * vRoh;
			glm::vec3 angularDirection = glm::cross(eRoh, glm::normalize(tangentialVelocity));
			float w = glm::dot(angularVelocity, angularDirection);

			if (fabs(vRoh) < vCritical && glm::length(tangentialVelocity) > 0.0001f) {
				if (w * sphere.radius + 0.0001f < glm::length(tangentialVelocity)) {
					// Sliding.
					velocity = tangentialVelocity - static_cast<float>(time)* (eFriction * muSliding * 9.82f*eRoh.y);
					angularVelocity += (5.f / 2.f) * (muSliding * 9.82f / sphere.radius * static_cast<float>(time)) * angularDirection;
				} else {
					// Rolling.
					velocity = tangentialVelocity - static_cast<float>(time)* (glm::normalize(tangentialVelocity) * muRolling * 9.82f*eRoh.y);
					float tangentialVelocityAfter = glm::length(velocity - glm::dot(velocity, eRoh) * eRoh);
					angularVelocity = (glm::length(tangentialVelocityAfter) / sphere.radius) * angularDirection;
					// Stopped.
					if (glm::length(velocity) < 0.2f) {
						velocity = glm::vec3(0.f, 0.f, 0.f);
						angularVelocity = glm::vec3(0.f, 0.f, 0.f);
					}
				}
			} else {
				float deltaTime = pow(mass * mass / (fabs(vRoh) * sphere.radius), 0.2f) * 0.00251744f;
				float velocityRoh = glm::dot(velocity, eRoh);
				float velocityNormal = glm::dot(velocity, eFriction);
				float uRoh = -e*velocityRoh;
				float deltauRoh = uRoh - (velocityRoh);
				float deltaUn = muSliding*deltauRoh;
				float rollUn = (5.f / 7.f)*velocityNormal;
				float slideUn = velocityNormal - deltaUn;

				if (velocityNormal > rollUn){
					velocity = uRoh*eRoh + rollUn*eFriction;
					angularVelocity += muRolling * (deltaU + 9.82f*eRoh.y * deltaTime) / sphere.radius * glm::cross(eRoh, eFriction);
				} else {
					velocity = uRoh*eRoh + slideUn*eFriction;
					angularVelocity += muSliding * (deltaU + 9.82f *eRoh.y* deltaTime) / sphere.radius * glm::cross(eRoh, eFriction);
				}
			}
		} else {
			// Calculate magnus force.
			float v = glm::length(velocity);
			float u = glm::length(velocity - wind);
			float w = glm::length(angularVelocity);
			glm::vec3 eU = (velocity - wind) / u;
			magnusForce = glm::vec3(0.f, 0.f, 0.f);
			if (u > 0.f && v > 0.f && w > 0.f) {
				float Cm = (sqrt(1.f + 0.31f * (w / v)) - 1.f) / 20.f;
				float Fm = 0.5f * Cm * 1.23f * area * u * u;
				magnusForce = Fm * glm::cross(eU, glm::normalize(angularVelocity));
			}

			// Calculate drag force.
			float cD;
			if (ballType == TWOPIECE)
				cD = v < 65.f ? -0.0051f * v + 0.53f : 0.21f;
			else
				cD = v < 60.f ? -0.0084f * v + 0.73f : 0.22f;
			dragForce = glm::vec3(0.f, 0.f, 0.f);
			if (u > 0.f)
				dragForce = -0.5f * 1.23f * area * cD * u * u * eU;
		}
		// Calculate gravitational force.
		glm::vec3 gravitationForce = glm::vec3(0.f, mass * -9.82f, 0.f);
		// Get acceleration from total force.
		glm::vec3 acceleration = (dragForce + magnusForce + gravitationForce) / mass;
		velocity += acceleration * static_cast<float>(time);

	}
}

void GolfBall::Render(Camera* camera, const glm::vec2& screenSize, const glm::vec4& clippingPlane) const{
    ModelObject::Render(camera, screenSize, clippingPlane);
}

void GolfBall::Explode(std::vector<PlayerObject>& players, int playerIndex){
    //@TODO: Set mass equivalent depending on material used.
    float equivalenceFactor = 1.0f;
    float massEquivalent = mass*equivalenceFactor;
    for (auto &player : players){
        glm::vec3 distanceV = (Position() - player.Position());
        float distance = glm::length(distanceV);
        //pow(meq, 1.f/3.f) => cube root of meq
        float z = distance / (pow(massEquivalent, 1.f / 3.f));
        float alpha = 1 + pow((z / 4.5f), 2.f);
        float beta = 1 + pow((z / 0.048f), 2.f);
        float gamma = 1 + pow((z / 1.35f), 2.f);
        float delta = 1 + pow((z / 0.32f), 2.f);
        float Pf = 8.08f*pow(10.f, 7.f)*alpha;
        Pf = Pf / sqrt(beta*gamma*delta);
        player.TakeDamage(Pf);
    }
    origin = players[playerIndex].Position();
    Reset();
}

void GolfBall::Strike(ClubType club, const glm::vec3& clubVelocity) {
    active = true;

    // Club velocity in strike plane.
    float v = glm::length(clubVelocity);
    if (v > 0.f)
    {
        float sinLoft = sin(club.loft);
        float cosLoft = cos(club.loft);

        // Ball velocity.
        float massCoefficient = club.mass / (club.mass + mass);
        float Up = (1.f + restitution) * massCoefficient * v * cosLoft;
        float Un = (2.f / 7.f) * massCoefficient * v * sinLoft;

        // Go back from strike plane to 3D.
        glm::vec3 forward = clubVelocity / v;
        glm::vec3 up = glm::cross(forward, glm::cross(glm::vec3(0.f, 1.f, 0.f), forward));
        glm::vec3 ep = glm::normalize(cosLoft * forward + sinLoft * up);
        glm::vec3 en = glm::normalize(sinLoft * forward - cosLoft * up);

        // Total velocity.
        velocity = Up * ep + Un * en;
        angularVelocity = -Un / sphere.radius * glm::cross(ep, en);
    } else {
        velocity = glm::vec3(0.f, 0.f, 0.f);
        angularVelocity = glm::vec3(0.f, 0.f, 0.f);
    }
}

void GolfBall::SetRadius(float radius) {
    sphere.radius = radius;
    SetScale(glm::vec3(radius, radius, radius));
    area = glm::pi<float>() * radius * radius;
}

glm::mat4 GolfBall::Orientation() const {
    return glm::toMat4(orientation);
}
<|endoftext|>


<commit_before>/*

  Copyright (C) 2003-2008  Grame
  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
  research@grame.fr

  This file is provided as an example of the MusicXML Library use.
*/

#ifdef WIN32
# pragma warning (disable : 4786)
#endif

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

#include "libmusicxml.h"

using namespace std;
using namespace MusicXML2;

//_______________________________________________________________________________
int main(int argc, char *argv[])
{
  cout << "libmusicxml version " << musicxmllibVersionStr() << endl;
  cout << "libmusicxml to guido converter version " << musicxml2guidoVersionStr() << endl;
  cout << "libmusicxml to lilypond converter version " << musicxml2lilypondVersionStr() << endl;
  return 0;
}
<commit_msg>output change<commit_after>/*

  Copyright (C) 2003-2008  Grame
  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
  research@grame.fr

  This file is provided as an example of the MusicXML Library use.
*/

#ifdef WIN32
# pragma warning (disable : 4786)
#endif

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

#include "libmusicxml.h"

using namespace std;
using namespace MusicXML2;

//_______________________________________________________________________________
int main(int argc, char *argv[])
{
  cout << "libmusicxml version " << musicxmllibVersionStr() << endl;
  cout << "musicxml to guido converter version " << musicxml2guidoVersionStr() << endl;
  cout << "musicxml to lilypond converter version " << musicxml2lilypondVersionStr() << endl;
  return 0;
}
<|endoftext|>


<commit_before>/*
 * sig_demo.C
 *   Ignore ^C, catch and respond to ^| and USR1 signal.
 *
 * Bryan Clair, 2002
 */

#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

//
// handle_signal
//   Called asynchronously when signals are received.
//   It's not generally safe to use cout in a signal handler.
//
//   int the_sig is the type of signal received.
//
void handle_signal(int the_sig)
{
  switch(the_sig) {
  case SIGQUIT:
    cout << "Caught SIGQUIT.\n";
    break;
  case SIGUSR1:
    cout << "Caught SIGUSR1.\n";
    break;
  }
}

main()
{
  int i;

  // set ^C to be ignored
  signal(SIGINT,SIG_IGN);

  // set handler to catch ^| and USR1 signal
  signal(SIGQUIT,handle_signal);
  signal(SIGUSR1,handle_signal);

  // count for a while
  for (i=0; ;i++) {
    cout << i << endl;
    sleep(1);
  }
}
<commit_msg>check return value from sleep.<commit_after>/*
 * sig_demo.C
 *   Ignore ^C, catch and respond to ^| and USR1 signal.
 *
 * Bryan Clair, 2002-2015
 */

#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

//
// handle_signal
//   Called asynchronously when signals are received.
//   It's not generally safe to use cout in a signal handler.
//
//   int the_sig is the type of signal received.
//
void handle_signal(int the_sig)
{
  switch(the_sig) {
  case SIGQUIT:
    cout << "Caught SIGQUIT.\n";
    break;
  case SIGUSR1:
    cout << "Caught SIGUSR1.\n";
    break;
  }
}

main()
{
  // set ^C to be ignored
  signal(SIGINT,SIG_IGN);

  // set handler to catch ^| and USR1 signal
  signal(SIGQUIT,handle_signal);
  signal(SIGUSR1,handle_signal);

  // count for a while
  int i, timeleft;
  for (i=0; ;i++) {
    cout << i << endl;
    timeleft = sleep(1);
    if (timeleft != 0)
      cout << "woke with " << timeleft << " second left" << endl;
  }
}
<|endoftext|>


<commit_before>#include <iostream>

class Fracao {
  private:
    int num;
    int den;

  public:
    void imprimir( void ) {
        std::cout << getNum() << "/" << getDen() << '\n';
    }

    void setNum( const int num ) {
        this->num = num;
    }

    void setDen( const int den ) {
        if( den != 0 ) {
            this->den = den;
        } else {
            std::cout << "Erro denominador" << '\n';
            this->den = 0;
        }
    }

    int getNum( void ) const {
        return num;
    }

    int getDen( void ) const {
        return den;
    }

    Fracao( const int num, const int den ) {
        setNum( num );
        setDen( den );

        imprimir();
    }

    ~Fracao( void ) {
        std::cout << "Destrutor: ";
        imprimir();
        std::cout << '\n';
    }
};

Fracao operator*( const Fracao &a, const Fracao &b ) {
    Fracao resultado( a.getNum() * b.getNum(), a.getDen() * b.getDen() );

    return resultado;
}

int main( void ) {
    Fracao a( 1, 2 );
    Fracao b( 2, 4 );

    a.imprimir();
    b.imprimir();

    Fracao resultado = a * b;

    resultado.imprimir();

    return 0;
}
<commit_msg>Correção da multiplicação<commit_after>#include <iostream>

class Fracao {
  private:
    int num;
    int den;

  public:
    void imprimir( void ) const {
        std::cout << getNum() << "/" << getDen() << '\n';
    }

    void setNum( const int num ) {
        this->num = num;
    }

    void setDen( const int den ) {
        if( den != 0 ) {
            this->den = den;
        } else {
            std::cout << "Erro denominador" << '\n';
            this->den = 0;
        }
    }

    int getNum( void ) const {
        return num;
    }

    int getDen( void ) const {
        return den;
    }

    Fracao( const int num, const int den ) {
        setNum( num );
        setDen( den );

        imprimir();
    }

    ~Fracao( void ) {
        std::cout << "Destrutor: ";
        imprimir();
        std::cout << '\n';
    }

    Fracao operator*( const Fracao &b ) const {
        Fracao resultado( this->getNum() * b.getNum(), this->getDen() * b.getDen() );

        return resultado;
    }
};

int main( void ) {
    Fracao a( 1, 2 );
    Fracao b( 2, 4 );

    a.imprimir();
    b.imprimir();

    Fracao resultado = a * b;

    resultado.imprimir();

    return 0;
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
/// \file   es/storage.hpp
/// \brief  The entity/component data store
//
// Copyright 2013, nocte@hippie.nu            Released under the MIT License.
//---------------------------------------------------------------------------
#pragma once

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
#include <unordered_map>

#include "component.hpp"
#include "entity.hpp"
#include "traits.hpp"

namespace es {

/** A storage ties entities and components together.
 * Storage associates two other bits of data with every entity:
 * - A 64-bit mask that keeps track of which components are defined
 * - A vector of bytes, holding the actual data
 *
 * The vector of bytes tries to pack the component data as tightly as
 * possible.  It is really fast for plain old datatypes, but it also
 * handles nontrivial types safely.  It packs a virtual table and a
 * pointer to some heap space in the vector, and calls the constructor
 * and destructor as needed.
 */
class storage
{
    // It is assumed the first few components will be accessed the
    // most often.  We keep a cache of the first 12.
    static constexpr uint32_t cache_size = 12;
    static constexpr uint32_t cache_mask = (1 << cache_size) - 1;

    /** This data gets associated with every entity. */
    struct elem
    {
        /** Bitmask to keep track of which components are held in \a data. */
        std::bitset<64>     components;
        /** Component data for this entity. */
        std::vector<char>   data;
    };

    typedef component::placeholder placeholder;

    /** Data types that do not have a flat memory layout are kept in the
     ** elem::data buffer in a placeholder object. */
    template <typename t>
    class holder : public placeholder
    {
    public:
        holder () { }
        holder (t init) : held_(std::move(init)) { }

        const t& held() const { return held_; }
        t&       held()       { return held_; }

        placeholder* clone() const { return new holder<t>(held_); }

    private:
        t held_;
    };

    typedef std::unordered_map<uint32_t, elem> stor_impl;

public:
    typedef uint8_t     component_id;

    typedef stor_impl::iterator         iterator;
    typedef stor_impl::const_iterator   const_iterator;

public:
    /** Variable references are used by systems to access an entity's data.
     *  It keeps track of the elem::data buffer and the offset inside that
     *  buffer. */
    template <typename type>
    class var_ref
    {
        friend class storage;

        type& get()
        {
            if (is_flat<type>::value)
                return *reinterpret_cast<type*>(&*e_.data.begin() + offset_);

            auto ptr (reinterpret_cast<holder<type>*>(&*e_.data.begin() + offset_));
            return ptr->held();
        }

    public:
        operator const type& () const
        {
            if (is_flat<type>::value)
                return *reinterpret_cast<const type*>(&*e_.data.begin() + offset_);

            auto ptr (reinterpret_cast<const holder<type>*>(&*e_.data.begin() + offset_));
            return ptr->held();
        }

        var_ref& operator= (type assign)
        {
            if (is_flat<type>::value)
            {
                new (&*e_.data.begin() + offset_) type(std::move(assign));
            }
            else
            {
                auto ptr (reinterpret_cast<holder<type>*>(&*e_.data.begin() + offset_));
                new (ptr) holder<type>(std::move(assign));
            }
            return *this;
        }

        template <typename s>
        var_ref& operator+= (s val)
            { get() += val; return *this; }

        template <typename s>
        var_ref& operator-= (s val)
            { get() -= val; return *this; }

        template <typename s>
        var_ref& operator*= (s val)
            { get() *= val; return *this; }

        template <typename s>
        var_ref& operator/= (s val)
            { get() /= val; return *this; }

    protected:
        var_ref (size_t offset, elem& e)
            : offset_(offset), e_(e)
            { }

    private:
        size_t offset_;
        elem&  e_;
    };

public:
    storage()
        : next_id_(0)
        {
            component_offsets_.push_back(0);
        }

    template <typename type>
    component_id register_component (std::string name)
        {
            size_t size;

            if (is_flat<type>::value)
            {
                size = sizeof(type);
                components_.emplace_back(name, size, nullptr);
            }
            else
            {
                flat_mask_.set(components_.size());
                size = sizeof(holder<type>);
                components_.emplace_back(name, size,
                                         std::unique_ptr<placeholder>(new holder<type>()));
            }

            if (components_.size() < cache_size)
            {
                size_t i (component_offsets_.size());
                component_offsets_.resize(i * 2);
                for (size_t j (i); j != i * 2; ++j)
                    component_offsets_[j] = component_offsets_[j-i] + size;
            }

            return components_.size() - 1;
        }

    component_id find_component (const std::string& name) const
        {
            auto found (std::find(components_.begin(), components_.end(), name));
            if (found == components_.end())
                throw std::logic_error("component does not exist");

            return std::distance(components_.begin(), found);
        }

    const component& operator[] (component_id id) const
        { return components_[id]; }

    const std::vector<component>& components() const
        { return components_; }

public:
    entity new_entity()
        {
            entities_[next_id_++];
            return next_id_ - 1;
        }

    /** Create a whole bunch of empty entities in one go.
     * @param count     The number of entities to create
     * @return The range of entities created */
    std::pair<entity, entity> new_entities (size_t count)
        {
            auto range_begin (next_id_);
            for (; count > 0; --count)
                entities_[next_id_++];

            return std::make_pair(range_begin, next_id_);
        }

    entity clone_entity (iterator f)
        {
            elem& e (f->second);
            entities_[next_id_++] = e;

            // Quick check if we need to make deep copies
            if ((e.components & flat_mask_).any())
            {
                size_t off (0);
                for (int c_id (0); c_id < 64 && off < e.data.size(); ++c_id)
                {
                    if (e.components[c_id])
                    {
                        if (!components_[c_id].is_flat())
                        {
                            auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                            ptr = ptr->clone();
                        }
                        off += components_[c_id].size();
                    }
                }
            }
            return next_id_ - 1;
        }

    iterator find (entity en)
        {
            auto found (entities_.find(en.id()));
            if (found == entities_.end())
                throw std::logic_error("unknown entity");

            return found;
        }

    const_iterator find (entity en) const
        {
            auto found (entities_.find(en.id()));
            if (found == entities_.end())
                throw std::logic_error("unknown entity");

            return found;
        }

    void delete_entity (entity en)
        { delete_entity(find(en)); }

    void delete_entity (iterator f)
        {
            elem& e (f->second);

            // Quick check if we'll have to call any destructors.
            if ((e.components & flat_mask_).any())
            {
                size_t off (0);
                for (int search (0); search < 64 && off < e.data.size(); ++search)
                {
                    if (e.components[search])
                    {
                        if (!components_[search].is_flat())
                        {
                            auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                            ptr->~placeholder();
                        }
                        off += components_[search].size();
                    }
                }
            }

            entities_.erase(f);
        }

    void remove_component_from_entity (iterator en, component_id c)
        {
            auto& e (en->second);
            if (!e.components[c])
                return;

            size_t off (offset(e, c));
            auto& comp_info (components_[c]);
            if (!comp_info.is_flat())
            {
                auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                ptr->~placeholder();
            }
            auto o (e.data.begin() + off);
            e.data.erase(o, o + comp_info.size());
            e.components.reset(c);
        }

    /** Call a function for every entity that has a given component.
     *  The callee can then query and change the value of the component through
     *  a var_ref object, or remove the entity.
     * @param c     The component to look for.
     * @param func  The function to call.  This function will be passed an
     *              iterator to the current entity, and a var_ref corresponding
     *              to the component value in this entity. */
    template <typename t>
    void for_each (component_id c, std::function<void(iterator, var_ref<t>)> func)
        {
            std::bitset<64> mask;
            mask.set(c);
            for (auto i (entities_.begin()); i != entities_.end(); )
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                    func(i, var_ref<t>(offset(e, c), e));

                i = next;
            }
        }

    template <typename t1, typename t2>
    void for_each (component_id c1, component_id c2,
                   std::function<void(iterator, var_ref<t1>, var_ref<t2>)> func)
        {
            std::bitset<64> mask;
            mask.set(c1);
            mask.set(c2);
            for (auto i (entities_.begin()); i != entities_.end(); ++i)
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                {
                    func(i, var_ref<t1>(offset(e, c1), e),
                            var_ref<t2>(offset(e, c2), e));
                }
                i = next;
            }
        }

    template <typename t1, typename t2, typename t3>
    void for_each (component_id c1, component_id c2, component_id c3,
                   std::function<void(iterator, var_ref<t1>, var_ref<t2>, var_ref<t3>)> func)
        {
            std::bitset<64> mask;
            mask.set(c1);
            mask.set(c2);
            mask.set(c3);
            for (auto i (entities_.begin()); i != entities_.end(); ++i)
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                {
                    func(i, var_ref<t1>(offset(e, c1), e),
                            var_ref<t2>(offset(e, c2), e),
                            var_ref<t3>(offset(e, c3), e));
                }
                i = next;
            }
        }

    bool exists (entity en) const
        { return entities_.count(en.id()); }

    template <typename type>
    void set (entity en, component_id c_id, type val)
        { return set<type>(find(en), c_id, std::move(val)); }

    template <typename type>
    void set (iterator en, component_id c_id, type val)
        {
            const component& c (components_[c_id]);
            elem&  e   (en->second);
            size_t off (offset(e, c_id));

            if (!e.components[c_id])
            {
                if (e.data.size() < off)
                    e.data.resize(off + c.size());
                else
                    e.data.insert(e.data.begin() + off, c.size(), 0);

                e.components.set(c_id);
            }

            if (is_flat<type>::value)
            {
                assert(e.data.size() >= off + sizeof(type));
                new (&*e.data.begin() + off) type(std::move(val));
            }
            else
            {
                assert(e.data.size() >= off + sizeof(holder<type>));
                auto ptr (reinterpret_cast<holder<type>*>(&*e.data.begin() + off));
                new (ptr) holder<type>(std::move(val));
            }
        }

    template <typename type>
    const type& get (entity en, component_id c_id) const
        { return get<type>(find(en), c_id); }

    template <typename type>
    const type& get (const_iterator en, component_id c_id) const
        {
            auto& e (en->second);
            if (!e.components[c_id])
                throw std::logic_error("entity does not have component");

            return get<type>(e, c_id);
        }

private:
    template <typename type>
    const type& get (const elem& e, component_id c_id) const
        {
            size_t off (offset(e, c_id));
            if (is_flat<type>::value)
                return *reinterpret_cast<const type*>(&*e.data.begin() + off);

            auto ptr (reinterpret_cast<const holder<type>*>(&*e.data.begin() + off));

            return ptr->held();
        }

    size_t offset (const elem& e, component_id c) const
        {
            assert(c < components_.size());
            assert((c & cache_mask) < component_offsets_.size());
            size_t result (component_offsets_[c & cache_mask]);

            for (component_id search (cache_size); search < c; ++search)
            {
                if (e.components[search])
                    result += components_[search].size();
            }
            return result;
        }

private:
    /** Keeps track of entity IDs to give out. */
    uint32_t                            next_id_;
    /** The list of registered components. */
    std::vector<component>              components_;
    /** Mapping entity IDs to their data. */
    std::unordered_map<uint32_t, elem>  entities_;
    /** A lookup table for the data offsets of components.
     *  The index is the bitmask as used in elem::components. */
    std::vector<size_t>                 component_offsets_;
    /** A bitmask to quickly determine whether a certain combination of
     ** components has a flat memory layout or not. */
    std::bitset<64>                     flat_mask_;
};

} // namespace es
<commit_msg>Bugfix in for_each<commit_after>//---------------------------------------------------------------------------
/// \file   es/storage.hpp
/// \brief  The entity/component data store
//
// Copyright 2013, nocte@hippie.nu            Released under the MIT License.
//---------------------------------------------------------------------------
#pragma once

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
#include <unordered_map>

#include "component.hpp"
#include "entity.hpp"
#include "traits.hpp"

namespace es {

/** A storage ties entities and components together.
 * Storage associates two other bits of data with every entity:
 * - A 64-bit mask that keeps track of which components are defined
 * - A vector of bytes, holding the actual data
 *
 * The vector of bytes tries to pack the component data as tightly as
 * possible.  It is really fast for plain old datatypes, but it also
 * handles nontrivial types safely.  It packs a virtual table and a
 * pointer to some heap space in the vector, and calls the constructor
 * and destructor as needed.
 */
class storage
{
    // It is assumed the first few components will be accessed the
    // most often.  We keep a cache of the first 12.
    static constexpr uint32_t cache_size = 12;
    static constexpr uint32_t cache_mask = (1 << cache_size) - 1;

    /** This data gets associated with every entity. */
    struct elem
    {
        /** Bitmask to keep track of which components are held in \a data. */
        std::bitset<64>     components;
        /** Component data for this entity. */
        std::vector<char>   data;
    };

    typedef component::placeholder placeholder;

    /** Data types that do not have a flat memory layout are kept in the
     ** elem::data buffer in a placeholder object. */
    template <typename t>
    class holder : public placeholder
    {
    public:
        holder () { }
        holder (t init) : held_(std::move(init)) { }

        const t& held() const { return held_; }
        t&       held()       { return held_; }

        placeholder* clone() const { return new holder<t>(held_); }

    private:
        t held_;
    };

    typedef std::unordered_map<uint32_t, elem> stor_impl;

public:
    typedef uint8_t     component_id;

    typedef stor_impl::iterator         iterator;
    typedef stor_impl::const_iterator   const_iterator;

public:
    /** Variable references are used by systems to access an entity's data.
     *  It keeps track of the elem::data buffer and the offset inside that
     *  buffer. */
    template <typename type>
    class var_ref
    {
        friend class storage;

        type& get()
        {
            if (is_flat<type>::value)
                return *reinterpret_cast<type*>(&*e_.data.begin() + offset_);

            auto ptr (reinterpret_cast<holder<type>*>(&*e_.data.begin() + offset_));
            return ptr->held();
        }

    public:
        operator const type& () const
        {
            if (is_flat<type>::value)
                return *reinterpret_cast<const type*>(&*e_.data.begin() + offset_);

            auto ptr (reinterpret_cast<const holder<type>*>(&*e_.data.begin() + offset_));
            return ptr->held();
        }

        var_ref& operator= (type assign)
        {
            if (is_flat<type>::value)
            {
                new (&*e_.data.begin() + offset_) type(std::move(assign));
            }
            else
            {
                auto ptr (reinterpret_cast<holder<type>*>(&*e_.data.begin() + offset_));
                new (ptr) holder<type>(std::move(assign));
            }
            return *this;
        }

        template <typename s>
        var_ref& operator+= (s val)
            { get() += val; return *this; }

        template <typename s>
        var_ref& operator-= (s val)
            { get() -= val; return *this; }

        template <typename s>
        var_ref& operator*= (s val)
            { get() *= val; return *this; }

        template <typename s>
        var_ref& operator/= (s val)
            { get() /= val; return *this; }

    protected:
        var_ref (size_t offset, elem& e)
            : offset_(offset), e_(e)
            { }

    private:
        size_t offset_;
        elem&  e_;
    };

public:
    storage()
        : next_id_(0)
        {
            component_offsets_.push_back(0);
        }

    template <typename type>
    component_id register_component (std::string name)
        {
            size_t size;

            if (is_flat<type>::value)
            {
                size = sizeof(type);
                components_.emplace_back(name, size, nullptr);
            }
            else
            {
                flat_mask_.set(components_.size());
                size = sizeof(holder<type>);
                components_.emplace_back(name, size,
                                         std::unique_ptr<placeholder>(new holder<type>()));
            }

            if (components_.size() < cache_size)
            {
                size_t i (component_offsets_.size());
                component_offsets_.resize(i * 2);
                for (size_t j (i); j != i * 2; ++j)
                    component_offsets_[j] = component_offsets_[j-i] + size;
            }

            return components_.size() - 1;
        }

    component_id find_component (const std::string& name) const
        {
            auto found (std::find(components_.begin(), components_.end(), name));
            if (found == components_.end())
                throw std::logic_error("component does not exist");

            return std::distance(components_.begin(), found);
        }

    const component& operator[] (component_id id) const
        { return components_[id]; }

    const std::vector<component>& components() const
        { return components_; }

public:
    entity new_entity()
        {
            entities_[next_id_++];
            return next_id_ - 1;
        }

    /** Create a whole bunch of empty entities in one go.
     * @param count     The number of entities to create
     * @return The range of entities created */
    std::pair<entity, entity> new_entities (size_t count)
        {
            auto range_begin (next_id_);
            for (; count > 0; --count)
                entities_[next_id_++];

            return std::make_pair(range_begin, next_id_);
        }

    entity clone_entity (iterator f)
        {
            elem& e (f->second);
            entities_[next_id_++] = e;

            // Quick check if we need to make deep copies
            if ((e.components & flat_mask_).any())
            {
                size_t off (0);
                for (int c_id (0); c_id < 64 && off < e.data.size(); ++c_id)
                {
                    if (e.components[c_id])
                    {
                        if (!components_[c_id].is_flat())
                        {
                            auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                            ptr = ptr->clone();
                        }
                        off += components_[c_id].size();
                    }
                }
            }
            return next_id_ - 1;
        }

    iterator find (entity en)
        {
            auto found (entities_.find(en.id()));
            if (found == entities_.end())
                throw std::logic_error("unknown entity");

            return found;
        }

    const_iterator find (entity en) const
        {
            auto found (entities_.find(en.id()));
            if (found == entities_.end())
                throw std::logic_error("unknown entity");

            return found;
        }

    void delete_entity (entity en)
        { delete_entity(find(en)); }

    void delete_entity (iterator f)
        {
            elem& e (f->second);

            // Quick check if we'll have to call any destructors.
            if ((e.components & flat_mask_).any())
            {
                size_t off (0);
                for (int search (0); search < 64 && off < e.data.size(); ++search)
                {
                    if (e.components[search])
                    {
                        if (!components_[search].is_flat())
                        {
                            auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                            ptr->~placeholder();
                        }
                        off += components_[search].size();
                    }
                }
            }

            entities_.erase(f);
        }

    void remove_component_from_entity (iterator en, component_id c)
        {
            auto& e (en->second);
            if (!e.components[c])
                return;

            size_t off (offset(e, c));
            auto& comp_info (components_[c]);
            if (!comp_info.is_flat())
            {
                auto ptr (reinterpret_cast<placeholder*>(&*e.data.begin() + off));
                ptr->~placeholder();
            }
            auto o (e.data.begin() + off);
            e.data.erase(o, o + comp_info.size());
            e.components.reset(c);
        }

    /** Call a function for every entity that has a given component.
     *  The callee can then query and change the value of the component through
     *  a var_ref object, or remove the entity.
     * @param c     The component to look for.
     * @param func  The function to call.  This function will be passed an
     *              iterator to the current entity, and a var_ref corresponding
     *              to the component value in this entity. */
    template <typename t>
    void for_each (component_id c, std::function<void(iterator, var_ref<t>)> func)
        {
            std::bitset<64> mask;
            mask.set(c);
            for (auto i (entities_.begin()); i != entities_.end(); )
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                    func(i, var_ref<t>(offset(e, c), e));

                i = next;
            }
        }

    template <typename t1, typename t2>
    void for_each (component_id c1, component_id c2,
                   std::function<void(iterator, var_ref<t1>, var_ref<t2>)> func)
        {
            std::bitset<64> mask;
            mask.set(c1);
            mask.set(c2);
            for (auto i (entities_.begin()); i != entities_.end(); )
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                {
                    func(i, var_ref<t1>(offset(e, c1), e),
                            var_ref<t2>(offset(e, c2), e));
                }
                i = next;
            }
        }

    template <typename t1, typename t2, typename t3>
    void for_each (component_id c1, component_id c2, component_id c3,
                   std::function<void(iterator, var_ref<t1>, var_ref<t2>, var_ref<t3>)> func)
        {
            std::bitset<64> mask;
            mask.set(c1);
            mask.set(c2);
            mask.set(c3);
            for (auto i (entities_.begin()); i != entities_.end(); )
            {
                auto next (std::next(i));
                elem& e (i->second);
                if ((e.components & mask) == mask)
                {
                    func(i, var_ref<t1>(offset(e, c1), e),
                            var_ref<t2>(offset(e, c2), e),
                            var_ref<t3>(offset(e, c3), e));
                }
                i = next;
            }
        }

    bool exists (entity en) const
        { return entities_.count(en.id()); }

    template <typename type>
    void set (entity en, component_id c_id, type val)
        { return set<type>(find(en), c_id, std::move(val)); }

    template <typename type>
    void set (iterator en, component_id c_id, type val)
        {
            const component& c (components_[c_id]);
            elem&  e   (en->second);
            size_t off (offset(e, c_id));

            if (!e.components[c_id])
            {
                if (e.data.size() < off)
                    e.data.resize(off + c.size());
                else
                    e.data.insert(e.data.begin() + off, c.size(), 0);

                e.components.set(c_id);
            }

            if (is_flat<type>::value)
            {
                assert(e.data.size() >= off + sizeof(type));
                new (&*e.data.begin() + off) type(std::move(val));
            }
            else
            {
                assert(e.data.size() >= off + sizeof(holder<type>));
                auto ptr (reinterpret_cast<holder<type>*>(&*e.data.begin() + off));
                new (ptr) holder<type>(std::move(val));
            }
        }

    template <typename type>
    const type& get (entity en, component_id c_id) const
        { return get<type>(find(en), c_id); }

    template <typename type>
    const type& get (const_iterator en, component_id c_id) const
        {
            auto& e (en->second);
            if (!e.components[c_id])
                throw std::logic_error("entity does not have component");

            return get<type>(e, c_id);
        }

private:
    template <typename type>
    const type& get (const elem& e, component_id c_id) const
        {
            size_t off (offset(e, c_id));
            if (is_flat<type>::value)
                return *reinterpret_cast<const type*>(&*e.data.begin() + off);

            auto ptr (reinterpret_cast<const holder<type>*>(&*e.data.begin() + off));

            return ptr->held();
        }

    size_t offset (const elem& e, component_id c) const
        {
            assert(c < components_.size());
            assert((c & cache_mask) < component_offsets_.size());
            size_t result (component_offsets_[c & cache_mask]);

            for (component_id search (cache_size); search < c; ++search)
            {
                if (e.components[search])
                    result += components_[search].size();
            }
            return result;
        }

private:
    /** Keeps track of entity IDs to give out. */
    uint32_t                            next_id_;
    /** The list of registered components. */
    std::vector<component>              components_;
    /** Mapping entity IDs to their data. */
    std::unordered_map<uint32_t, elem>  entities_;
    /** A lookup table for the data offsets of components.
     *  The index is the bitmask as used in elem::components. */
    std::vector<size_t>                 component_offsets_;
    /** A bitmask to quickly determine whether a certain combination of
     ** components has a flat memory layout or not. */
    std::bitset<64>                     flat_mask_;
};

} // namespace es
<|endoftext|>


<commit_before>#include "errors.h"
#include <sstream>
#include <string.h>

using namespace es3;

extern ES3LIB_PUBLIC const die_t es3::die=die_t();
extern ES3LIB_PUBLIC const libc_die_t es3::libc_die=libc_die_t();
extern ES3LIB_PUBLIC const result_code_t es3::sok=result_code_t();

es3_exception::es3_exception(const result_code_t &code) : code_(code)
{
	std::stringstream s;
	s<<("Error code: ")<<code.code()<<", description: "<<code.desc();
	what_=s.str();
}

int es3::operator | (const int res, const libc_die_t &)
{
	if (res>=0)
		return res;
	char buf[1024]={0};

	strerror_r(errno, buf, 1023);
	err(errFatal) << "Got error: " << buf;
	//Unreachable
}
<commit_msg>Backtrace hack<commit_after>#include "errors.h"
#include <sstream>
#include <string.h>

using namespace es3;

extern ES3LIB_PUBLIC const die_t es3::die=die_t();
extern ES3LIB_PUBLIC const libc_die_t es3::libc_die=libc_die_t();
extern ES3LIB_PUBLIC const result_code_t es3::sok=result_code_t();

es3_exception::es3_exception(const result_code_t &code) : code_(code)
{
	std::stringstream s;
	backtrace_it();
	s<<("Error code: ")<<code.code()<<", description: "<<code.desc();
	what_=s.str();
}

int es3::operator | (const int res, const libc_die_t &)
{
	if (res>=0)
		return res;
	char buf[1024]={0};

	strerror_r(errno, buf, 1023);
	err(errFatal) << "Got error: " << buf;
	//Unreachable
}
<|endoftext|>


<commit_before>#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/allocator.hpp>
#include <agency/detail/index_cast.hpp>
#include <agency/detail/shape_cast.hpp>
#include <thrust/detail/swap.h>

namespace agency
{
namespace cuda
{
namespace detail
{

template<class T, class Shape = size_t, class Index = Shape>
class array
{
  public:
    using value_type = T;

    using pointer = value_type*;

    using const_pointer = const value_type*;

    using shape_type = Shape;

    using index_type = Index;

    __host__ __device__
    array() : shape_{}, data_(nullptr) {}

    __host__ __device__
    array(const shape_type& shape)
      : shape_(shape)
    {
      allocator<value_type> alloc;
      data_ = alloc.allocate(size());
    }

    __host__ __device__
    array(const array& other)
      : array(other.shape())
    {
      auto iter = other.begin();
      auto result = begin();

      for(; iter != other.end(); ++iter, ++result)
      {
        *result = *iter;
      }
    }

    __host__ __device__
    array(array&& other)
      : shape_{}, data_{}
    {
      thrust::swap(shape_, other.shape_);
      thrust::swap(data_,  other.data_);
    }

    __host__ __device__
    ~array()
    {
      allocator<value_type> alloc;
      alloc.deallocate(data_, size());
    }

    __host__ __device__
    value_type& operator[](index_type idx)
    {
      std::size_t idx_1d = agency::detail::index_cast<std::size_t>(idx, shape(), size());

      return data_[idx_1d];
    }

    __host__ __device__
    shape_type shape() const
    {
      return shape_;
    }

    __host__ __device__
    std::size_t size() const
    {
      return agency::detail::shape_cast<std::size_t>(shape_);
    }

    __host__ __device__
    pointer data()
    {
      return data_;
    }

    __host__ __device__
    const_pointer data() const
    {
      return data_;
    }

    __host__ __device__
    pointer begin()
    {
      return data();
    }

    __host__ __device__
    pointer end()
    {
      return begin() + size();
    }

    __host__ __device__
    const_pointer begin() const
    {
      return data();
    }

    __host__ __device__
    const_pointer end() const
    {
      return begin() + size();
    }

    __agency_hd_warning_disable__
    template<class Range>
    __host__ __device__
    bool operator==(const Range& rhs) const
    {
      auto i = begin();
      auto j = rhs.begin();

      for(; i != end(); ++i, ++j)
      {
        if(*i != *j)
        {
          return false;
        }
      }

      return true;
    }

  private:
    shape_type shape_;

    pointer data_;
};

} // end detail
} // end cuda
} // end agency

<commit_msg>Give cuda::detail::array a fill constructor<commit_after>#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/allocator.hpp>
#include <agency/detail/index_cast.hpp>
#include <agency/detail/shape_cast.hpp>
#include <thrust/detail/swap.h>

namespace agency
{
namespace cuda
{
namespace detail
{

template<class T, class Shape = size_t, class Index = Shape>
class array
{
  public:
    using value_type = T;

    using pointer = value_type*;

    using const_pointer = const value_type*;

    using shape_type = Shape;

    using index_type = Index;

    __host__ __device__
    array() : shape_{}, data_(nullptr) {}

    __host__ __device__
    array(const shape_type& shape)
      : shape_(shape)
    {
      allocator<value_type> alloc;
      data_ = alloc.allocate(size());
    }

    __host__ __device__
    array(const shape_type& shape, const T& val)
      : array(shape)
    {
      for(auto& x : *this)
      {
        x = val;
      }
    }

    __host__ __device__
    array(const array& other)
      : array(other.shape())
    {
      auto iter = other.begin();
      auto result = begin();

      for(; iter != other.end(); ++iter, ++result)
      {
        *result = *iter;
      }
    }

    __host__ __device__
    array(array&& other)
      : shape_{}, data_{}
    {
      thrust::swap(shape_, other.shape_);
      thrust::swap(data_,  other.data_);
    }

    __host__ __device__
    ~array()
    {
      allocator<value_type> alloc;
      alloc.deallocate(data_, size());
    }

    __host__ __device__
    value_type& operator[](index_type idx)
    {
      std::size_t idx_1d = agency::detail::index_cast<std::size_t>(idx, shape(), size());

      return data_[idx_1d];
    }

    __host__ __device__
    shape_type shape() const
    {
      return shape_;
    }

    __host__ __device__
    std::size_t size() const
    {
      return agency::detail::shape_cast<std::size_t>(shape_);
    }

    __host__ __device__
    pointer data()
    {
      return data_;
    }

    __host__ __device__
    const_pointer data() const
    {
      return data_;
    }

    __host__ __device__
    pointer begin()
    {
      return data();
    }

    __host__ __device__
    pointer end()
    {
      return begin() + size();
    }

    __host__ __device__
    const_pointer begin() const
    {
      return data();
    }

    __host__ __device__
    const_pointer end() const
    {
      return begin() + size();
    }

    __agency_hd_warning_disable__
    template<class Range>
    __host__ __device__
    bool operator==(const Range& rhs) const
    {
      auto i = begin();
      auto j = rhs.begin();

      for(; i != end(); ++i, ++j)
      {
        if(*i != *j)
        {
          return false;
        }
      }

      return true;
    }

  private:
    shape_type shape_;

    pointer data_;
};

} // end detail
} // end cuda
} // end agency

<|endoftext|>


<commit_before>// Copyright 2017 Netherlands Institute for Radio Astronomy (ASTRON)
// Copyright 2017 Netherlands eScience Center
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

struct Options {
  // Debug mode
  bool debug;
  // Print messages to standard output
  bool print;
  // Use subband dedispersion
  bool subbandDedispersion;
  // Compact the triggered events in time and DM dimensions
  bool compactResults;
  // Threshold for triggering
  float threshold;
};

struct DeviceOptions {
  // OpenCL platform ID
  unsigned int platformID;
  // OpenCL device ID
  unsigned int deviceID;
  // OpenCL device name
  std::string deviceName;
  // Padding of OpenCL devices
  AstroData::paddingConf padding;
};

struct DataOptions {
  // Use LOFAR file as input
  bool dataLOFAR;
  // Use SIGPROC file as input
  bool dataSIGPROC;
  // Use PSRDADA buffer as input
  bool dataPSRDADA;
  // Limit the number of batches processed from a LOFAR file
  bool limit;
  // Size (in bytes) of the SIGPROC file header
  unsigned int headerSizeSIGPROC;
  // Name of the input file
  std::string dataFile;
  // Name of the LOFAR header file
  std::string headerFile;
  // Basename for the output files
  std::string outputFile;
  // Name of the file containing the zapped channels
  std::string channelsFile;
  // Name of the file containing the integration steps
  std::string integrationFile;
#ifdef HAVE_PSRDADA
  // PSRDADA buffer key
  key_t dadaKey;
#endif // HAVE_PSRDADA
};

struct GeneratorOptions {
  // Use random numbers in generated data
  bool random;
  // Width of random generated pulse
  unsigned int width;
  // DM of random generated pulse
  float DM;
};

struct HostMemory {
  // Input data
  std::vector<std::vector<std::vector<inputDataType> *> *> input;
  // Zapped channels
  std::vector<unsigned int> zappedChannels;
  // Integration steps
  std::set<unsigned int> integrationSteps;
  // Map to create synthesized beams
  std::vector<unsigned int> beamMapping;
  // Dispersed data
  std::vector<inputDataType> dispersedData;
  // Subbanded data
  std::vector<outputDataType> subbandedData;
  // Dedispersed data
  std::vector<outputDataType> dedispersedData;
  // Integrated data
  std::vector<outputDataType> integratedData;
  // SNR data
  std::vector<float> snrData;
  // Index of the sample with highest SNR value
  std::vector<unsigned int> snrSamples;
  // Shifts single step dedispersion
  std::vector<float> * shiftsSingleStep;
  // Shifts step one subbanding dedispersion
  std::vector<float> * shiftsStepOne;
  // Shifts step two subbanding dedispersion
  std::vector<float> * shiftsStepTwo;
#ifdef HAVE_PSRDADA
  // PSRDADA ring buffer
  dada_hdu_t * ringBuffer;
  // Input data
  std::vector<std::vector<inputDataType> *> inputDADA;
#endif // HAVE_PSRDADA
};

struct DeviceMemory {
  // Shifts single step dedispersion
  cl::Buffer shiftsSingleStep;
  // Shifts step one subbanding dedispersion
  cl::Buffer shiftsStepOne;
  // Shifts step two subbanding dedispersion
  cl::Buffer shiftsStepTwo;
  // Zapped channels
  cl::Buffer zappedChannels;
  // Map to create synthesized beams
  cl::Buffer beamMapping;
  // Dispersed dada
  cl::Buffer dispersedData;
  // Subbanded data
  cl::Buffer subbandedData;
  // Dedispersed data
  cl::Buffer dedispersedData;
  // Integrated data
  cl::Buffer integratedData;
  // SNR data
  cl::Buffer snrData;
  // Index of the sample with highest SNR value
  cl::Buffer snrSamples;
};

struct KernelConfigurations {
  // Configuration of single step dedispersion kernel
  Dedispersion::tunedDedispersionConf dedispersionSingleStepParameters;
  // Configuration of subband dedispersion kernel, step one
  Dedispersion::tunedDedispersionConf dedispersionStepOneParameters;
  // Configuration of subband dedispersion kernel, step two
  Dedispersion::tunedDedispersionConf dedispersionStepTwoParameters;
  // Configuration of integration kernel
  Integration::tunedIntegrationConf integrationParameters;
  // Configuration of SNR kernel
  SNR::tunedSNRConf snrParameters;
};

struct Kernels {
  // Single step dedispersion kernel
  cl::Kernel * dedispersionSingleStep;
  // Step one subbanding dedispersion kernel
  cl::Kernel * dedispersionStepOne;
  // Step two subbanding dedispersion kernel
  cl::Kernel * dedispersionStepTwo;
  // Integration kernels, one for each integration step
  std::vector<cl::Kernel *> integration;
  // SNR kernels, one for the original data and one for each integration step
  std::vector<cl::Kernel *> snr;
};

struct KernelRunTimeConfigurations {
  // Global NDrange for single step dedispersion
  cl::NDRange dedispersionSingleStepGlobal;
  // Local NDRange for single step dedispersion
  cl::NDRange dedispersionSingleStepLocal;
  // Global NDRange for subbanding dedispersion step one
  cl::NDRange dedispersionStepOneGlobal;
  // Local NDRange for subbanding dedispersion step one
  cl::NDRange dedispersionStepOneLocal;
  // Global NDRange for subbanding dedispersion step two
  cl::NDRange dedispersionStepTwoGlobal;
  // Local NDRange for subbanding dedispersion step two
  cl::NDRange dedispersionStepTwoLocal;
  // Global NDRange for integration
  std::vector<cl::NDRange> integrationGlobal;
  // Local NDRange for integration
  std::vector<cl::NDRange> integrationLocal;
  // Global NDRange for SNR
  std::vector<cl::NDRange> snrGlobal;
  // Local NDRange for SNR
  std::vector<cl::NDRange> snrLocal;
};

struct Timers {
  isa::utils::Timer inputLoad;
  isa::utils::Timer search;
  isa::utils::Timer inputHandling;
  isa::utils::Timer inputCopy;
  isa::utils::Timer dedispersionSingleStep;
  isa::utils::Timer dedispersionStepOne;
  isa::utils::Timer dedispersionStepTwo;
  isa::utils::Timer integration;
  isa::utils::Timer snr;
  isa::utils::Timer outputCopy;
  isa::utils::Timer trigger;
};

struct TriggeredEvent {
  unsigned int beam = 0;
  unsigned int sample = 0;
  unsigned int integration = 0;
  float DM = 0.0f;
  float SNR = 0.0f;
};

struct CompactedEvent : TriggeredEvent {
  unsigned int compactedIntegration = 1;
  unsigned int compactedDMs = 1;
};
using TriggeredEvents = std::vector<std::map<unsigned int, std::vector<TriggeredEvent>>>;
using CompactedEvents = std::vector<std::vector<CompactedEvent>>;

struct OpenCLRunTime {
  cl::Context * clContext;
  std::vector<cl::Platform> * clPlatforms;
  std::vector<cl::Device> * clDevices;
  std::vector<std::vector<cl::CommandQueue>> * clQueues;
};

<commit_msg>Changing the names.<commit_after>// Copyright 2017 Netherlands Institute for Radio Astronomy (ASTRON)
// Copyright 2017 Netherlands eScience Center
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

struct Options {
  // Debug mode
  bool debug;
  // Print messages to standard output
  bool print;
  // Use subband dedispersion
  bool subbandDedispersion;
  // Compact the triggered events in time and DM dimensions
  bool compactResults;
  // Threshold for triggering
  float threshold;
};

struct DeviceOptions {
  // OpenCL platform ID
  unsigned int platformID;
  // OpenCL device ID
  unsigned int deviceID;
  // OpenCL device name
  std::string deviceName;
  // Padding of OpenCL devices
  AstroData::paddingConf padding;
};

struct DataOptions {
  // Use LOFAR file as input
  bool dataLOFAR;
  // Use SIGPROC file as input
  bool dataSIGPROC;
  // Use PSRDADA buffer as input
  bool dataPSRDADA;
  // Limit the number of batches processed from a LOFAR file
  bool limit;
  // Size (in bytes) of the SIGPROC file header
  unsigned int headerSizeSIGPROC;
  // Name of the input file
  std::string dataFile;
  // Name of the LOFAR header file
  std::string headerFile;
  // Basename for the output files
  std::string outputFile;
  // Name of the file containing the zapped channels
  std::string channelsFile;
  // Name of the file containing the integration steps
  std::string integrationFile;
#ifdef HAVE_PSRDADA
  // PSRDADA buffer key
  key_t dadaKey;
#endif // HAVE_PSRDADA
};

struct GeneratorOptions {
  // Use random numbers in generated data
  bool random;
  // Width of random generated pulse
  unsigned int width;
  // DM of random generated pulse
  float DM;
};

struct HostMemory {
  // Input data
  std::vector<std::vector<std::vector<inputDataType> *> *> input;
  // Zapped channels
  std::vector<unsigned int> zappedChannels;
  // Integration steps
  std::set<unsigned int> integrationSteps;
  // Map to create synthesized beams
  std::vector<unsigned int> beamMapping;
  // Dispersed data
  std::vector<inputDataType> dispersedData;
  // Subbanded data
  std::vector<outputDataType> subbandedData;
  // Dedispersed data
  std::vector<outputDataType> dedispersedData;
  // Integrated data
  std::vector<outputDataType> integratedData;
  // SNR data
  std::vector<float> snrData;
  // Index of the sample with highest SNR value
  std::vector<unsigned int> snrSamples;
  // Shifts single step dedispersion
  std::vector<float> * shiftsSingleStep;
  // Shifts step one subbanding dedispersion
  std::vector<float> * shiftsStepOne;
  // Shifts step two subbanding dedispersion
  std::vector<float> * shiftsStepTwo;
#ifdef HAVE_PSRDADA
  // PSRDADA ring buffer
  dada_hdu_t * ringBuffer;
  // Input data
  std::vector<std::vector<inputDataType> *> inputDADA;
#endif // HAVE_PSRDADA
};

struct DeviceMemory {
  // Shifts single step dedispersion
  cl::Buffer shiftsSingleStep;
  // Shifts step one subbanding dedispersion
  cl::Buffer shiftsStepOne;
  // Shifts step two subbanding dedispersion
  cl::Buffer shiftsStepTwo;
  // Zapped channels
  cl::Buffer zappedChannels;
  // Map to create synthesized beams
  cl::Buffer beamMapping;
  // Dispersed dada
  cl::Buffer dispersedData;
  // Subbanded data
  cl::Buffer subbandedData;
  // Dedispersed data
  cl::Buffer dedispersedData;
  // Integrated data
  cl::Buffer integratedData;
  // SNR data
  cl::Buffer snrData;
  // Index of the sample with highest SNR value
  cl::Buffer snrSamples;
};

struct KernelConfigurations {
  // Configuration of single step dedispersion kernel
  Dedispersion::tunedDedispersionConf dedispersionSingleStepParameters;
  // Configuration of subband dedispersion kernel, step one
  Dedispersion::tunedDedispersionConf dedispersionStepOneParameters;
  // Configuration of subband dedispersion kernel, step two
  Dedispersion::tunedDedispersionConf dedispersionStepTwoParameters;
  // Configuration of integration kernel
  Integration::tunedIntegrationConf integrationParameters;
  // Configuration of SNR kernel
  SNR::tunedSNRConf snrParameters;
};

struct Kernels {
  // Single step dedispersion kernel
  cl::Kernel * dedispersionSingleStep;
  // Step one subbanding dedispersion kernel
  cl::Kernel * dedispersionStepOne;
  // Step two subbanding dedispersion kernel
  cl::Kernel * dedispersionStepTwo;
  // Integration kernels, one for each integration step
  std::vector<cl::Kernel *> integration;
  // SNR kernels, one for the original data and one for each integration step
  std::vector<cl::Kernel *> snr;
};

struct KernelRunTimeConfigurations {
  // Global NDrange for single step dedispersion
  cl::NDRange dedispersionSingleStepGlobal;
  // Local NDRange for single step dedispersion
  cl::NDRange dedispersionSingleStepLocal;
  // Global NDRange for subbanding dedispersion step one
  cl::NDRange dedispersionStepOneGlobal;
  // Local NDRange for subbanding dedispersion step one
  cl::NDRange dedispersionStepOneLocal;
  // Global NDRange for subbanding dedispersion step two
  cl::NDRange dedispersionStepTwoGlobal;
  // Local NDRange for subbanding dedispersion step two
  cl::NDRange dedispersionStepTwoLocal;
  // Global NDRange for integration
  std::vector<cl::NDRange> integrationGlobal;
  // Local NDRange for integration
  std::vector<cl::NDRange> integrationLocal;
  // Global NDRange for SNR
  std::vector<cl::NDRange> snrGlobal;
  // Local NDRange for SNR
  std::vector<cl::NDRange> snrLocal;
};

struct Timers {
  isa::utils::Timer inputLoad;
  isa::utils::Timer search;
  isa::utils::Timer inputHandling;
  isa::utils::Timer inputCopy;
  isa::utils::Timer dedispersionSingleStep;
  isa::utils::Timer dedispersionStepOne;
  isa::utils::Timer dedispersionStepTwo;
  isa::utils::Timer integration;
  isa::utils::Timer snr;
  isa::utils::Timer outputCopy;
  isa::utils::Timer trigger;
};

struct TriggeredEvent {
  unsigned int beam = 0;
  unsigned int sample = 0;
  unsigned int integration = 0;
  float DM = 0.0f;
  float SNR = 0.0f;
};

struct CompactedEvent : TriggeredEvent {
  unsigned int compactedIntegration = 1;
  unsigned int compactedDMs = 1;
};
using TriggeredEvents = std::vector<std::map<unsigned int, std::vector<TriggeredEvent>>>;
using CompactedEvents = std::vector<std::vector<CompactedEvent>>;

struct OpenCLRunTime {
  cl::Context * context;
  std::vector<cl::Platform> * platforms;
  std::vector<cl::Device> * devices;
  std::vector<std::vector<cl::CommandQueue>> * queues;
};

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef VARIABLES_H
#define VARIABLES_H

#include <string>
#include <map>

#include "Types.hpp"

#include "ByteCodeFileWriter.hpp"

namespace eddic {

class Variable {
    private:
        std::string m_name;
        Type m_type;
        int m_index;
    public:
        Variable(const std::string& name, Type type, int index) : m_name(name), m_type(type), m_index(index) {}
        std::string name() {
            return m_name;
        }
        int index() {
            return m_index;
        }
        Type type() {
            return m_type;
        }
};

class Variables {
    private:
        std::map<std::string, Variable*> variables;
        unsigned int currentVariable;
    public:
        Variables() {
            currentVariable = 0;
        };
        ~Variables();
        bool exists(const std::string& variable) const;
        unsigned int index(const std::string& variable) const;
        Variable* create(const std::string& variable, Type type);
        Variable* find(const std::string& variable);
        void write(ByteCodeFileWriter& writer);
};

} //end of eddic

#endif
<commit_msg>Enforce constness of Variable members and functions<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef VARIABLES_H
#define VARIABLES_H

#include <string>
#include <map>

#include "Types.hpp"

#include "ByteCodeFileWriter.hpp"

namespace eddic {

class Variable {
    private:
        const std::string m_name;
        const Type m_type;
        const int m_index;
    public:
        Variable(const std::string& name, Type type, int index) : m_name(name), m_type(type), m_index(index) {}
        std::string name() const  {
            return m_name;
        }
        int index() const {
            return m_index;
        }
        Type type() const {
            return m_type;
        }
};

class Variables {
    private:
        std::map<std::string, Variable*> variables;
        unsigned int currentVariable;
    public:
        Variables() {
            currentVariable = 0;
        };
        ~Variables();
        bool exists(const std::string& variable) const;
        unsigned int index(const std::string& variable) const;
        Variable* create(const std::string& variable, Type type);
        Variable* find(const std::string& variable);
        void write(ByteCodeFileWriter& writer);
};

} //end of eddic

#endif
<|endoftext|>