<commit_before>/*!
 * # Expected behaviour:
 * Same as the box_vee3d demo.
 *
 * It seems to behave as expected if the excentricity is not too big (tested with 10 and 100).
 *
 * # Symptoms:
 * Some object just fall through the ground, missing any collison. Then, after a while they seem
 * to notice that they are deep into the plane, and "jump" due to penetration resolution.
 * Thus, some collision are missed.
 * Identically, some boxes just dont collide to each other some times.
 *
 * # Cause:
 * Not sure, but this seems to be an accuracy limitation of the contact manifold generators
 * (OneShotContactManifoldGenerator and IncrementalContactManifoldGenerator). The repetitive
 * transformations of the saved contact might invalidate them.
 *
 * However, this might be a real bug for some other non-accuracy-related reasons. For example, when
 * a box is deep on the plane without contact why does the one-shot contact manifold generator
 * fails? Something wrong with the perturbation?
 *
 * This might be (but it is very unlikely) a problem with the DBVT that might become invalid.
 * Though this seems very unlikely as the AABBs seem to be fine and the plane has an infinite aabb
 * anyway. Thurthermore, the ray-cast (which uses the dbvt…) works fine, even for "jumpy" objects.
 *
 *
 * # Solution:
 *
 *
 * # Limitations of the solution:
 *
 */

extern crate nalgebra as na;
extern crate ncollide;
extern crate nphysics3d;
extern crate nphysics_testbed3d;

use na::{Isometry3, Point3, Vector3};
use ncollide::shape::{ConvexHull, Cuboid, Plane, ShapeHandle};
use ncollide::procedural;
use nphysics3d::world::World;
use nphysics3d::object::{BodyHandle, Material};
use nphysics3d::volumetric::Volumetric;
use nphysics_testbed3d::Testbed;

const COLLIDER_MARGIN: f32 = 0.01;

fn main() {
    /*
     * World
     */
    let mut world = World::new();
    world.set_gravity(Vector3::new(0.0, -9.81, 0.0));

    /*
     * Ground
     */
    let ground_size = 50.0;
    let ground_shape =
        ShapeHandle::new(Cuboid::new(Vector3::repeat(ground_size - COLLIDER_MARGIN)));
    let ground_pos = Isometry3::new(Vector3::y() * -ground_size, na::zero());

    world.add_collider(
        COLLIDER_MARGIN,
        ground_shape,
        BodyHandle::ground(),
        ground_pos,
        Material::default(),
    );

    /*
     * Create the convex geometries.
     */
    let num = 8;
    let shift = 2.0;
    let excentricity = 5000.0f32;
    let centerx = shift * (num as f32) / 2.0;
    let centery = shift / 2.0;
    let centerz = shift * (num as f32) / 2.0;

    let mut cuboid_mesh = procedural::cuboid(&Vector3::new(2.0 - 0.08, 2.0 - 0.08, 2.0 - 0.08));

    for c in cuboid_mesh.coords.iter_mut() {
        *c = *c + Vector3::new(excentricity, excentricity, excentricity);
    }

    let indices: Vec<usize> = cuboid_mesh.flat_indices()
        .into_iter()
        .map(|i| i as usize)
        .collect();
    let vertices = cuboid_mesh.coords;

    for v in &vertices {
        println!("Vertex: {}", *v)
    }

    for i in indices.chunks(3) {
        println!("Index: {}, {}, {}", i[0], i[1], i[2])
    }
    println!("Original indices: {:?}", cuboid_mesh.indices);

    let geom = ShapeHandle::new(ConvexHull::try_new(vertices, &indices).unwrap());
    let inertia = geom.inertia(1.0);
    let center_of_mass = geom.center_of_mass();

    for i in 0usize..num {
        for j in 0usize..num {
            for k in 0usize..num {
                let x = i as f32 * shift - centerx - excentricity;
                let y = j as f32 * shift + centery - excentricity;
                let z = k as f32 * shift - centerz - excentricity;

                /*
                 * Create the rigid body.
                 */
                let pos = Isometry3::new(Vector3::new(x, y, z), na::zero());
                let handle = world.add_rigid_body(pos, inertia, center_of_mass);

                /*
                 * Create the collider.
                 */
                world.add_collider(
                    COLLIDER_MARGIN,
                    geom.clone(),
                    handle,
                    Isometry3::identity(),
                    Material::default(),
                );
            }
        }
    }

    /*
     * Set up the testbed.
     */
    let mut testbed = Testbed::new(world);

    testbed.look_at(Point3::new(-30.0, 30.0, -30.0), Point3::new(0.0, 0.0, 0.0));
    testbed.run();
}
<commit_msg>Update infos about the bug involving non-centered convex solids.<commit_after>/*!
 * # Expected behaviour:
 * Same as the box_vee3d demo.
 *
 * It seems to behave as expected if the excentricity is not too big (tested with 10 and 100).
 *
 * # Symptoms:
 * Some objets jitter when they touch the ground.
 *
 * # Cause:
 * Not sure, but this seems to be an accuracy limitation of the contact manifold generators.
 *
 * This might be (but it is very unlikely) a problem with the DBVT that might become invalid.
 * Though this seems very unlikely as the AABBs seem to be fine and the plane has an infinite aabb
 * anyway. Thurthermore, the ray-cast (which uses the dbvt…) works fine, even for "jumpy" objects.
 *
 *
 * # Solution:
 *
 */

extern crate nalgebra as na;
extern crate ncollide;
extern crate nphysics3d;
extern crate nphysics_testbed3d;

use na::{Isometry3, Point3, Vector3};
use ncollide::shape::{ConvexHull, Cuboid, Plane, ShapeHandle};
use ncollide::procedural;
use nphysics3d::world::World;
use nphysics3d::object::{BodyHandle, Material};
use nphysics3d::volumetric::Volumetric;
use nphysics_testbed3d::Testbed;

const COLLIDER_MARGIN: f32 = 0.01;

fn main() {
    /*
     * World
     */
    let mut world = World::new();
    world.set_gravity(Vector3::new(0.0, -9.81, 0.0));

    /*
     * Ground
     */
    let ground_size = 50.0;
    let ground_shape =
        ShapeHandle::new(Cuboid::new(Vector3::repeat(ground_size - COLLIDER_MARGIN)));
    let ground_pos = Isometry3::new(Vector3::y() * -ground_size, na::zero());

    world.add_collider(
        COLLIDER_MARGIN,
        ground_shape,
        BodyHandle::ground(),
        ground_pos,
        Material::default(),
    );

    /*
     * Create the convex geometries.
     */
    let num = 8;
    let rad = 0.1;
    let shift = rad * 2.0;
    let excentricity = 1000.0f32;
    let centerx = shift * (num as f32) / 2.0;
    let centery = shift / 2.0;
    let centerz = shift * (num as f32) / 2.0;

    let mut cuboid_mesh = procedural::cuboid(&Vector3::repeat(2.0 * (rad - COLLIDER_MARGIN)));

    for c in cuboid_mesh.coords.iter_mut() {
        *c = *c + Vector3::new(excentricity, excentricity, excentricity);
    }

    let indices: Vec<usize> = cuboid_mesh.flat_indices()
        .into_iter()
        .map(|i| i as usize)
        .collect();
    let vertices = cuboid_mesh.coords;

    let geom = ShapeHandle::new(ConvexHull::try_new(vertices, &indices).unwrap());
    let inertia = geom.inertia(1.0);
    let center_of_mass = geom.center_of_mass();

    for i in 0usize..num {
        for j in 0usize..num {
            for k in 0usize..num {
                let x = i as f32 * shift - centerx - excentricity;
                let y = j as f32 * shift + centery - excentricity;
                let z = k as f32 * shift - centerz - excentricity;

                /*
                 * Create the rigid body.
                 */
                let pos = Isometry3::new(Vector3::new(x, y, z), na::zero());
                let handle = world.add_rigid_body(pos, inertia, center_of_mass);

                /*
                 * Create the collider.
                 */
                world.add_collider(
                    COLLIDER_MARGIN,
                    geom.clone(),
                    handle,
                    Isometry3::identity(),
                    Material::default(),
                );
            }
        }
    }

    /*
     * Set up the testbed.
     */
    let mut testbed = Testbed::new(world);

    testbed.look_at(Point3::new(-10.0, 10.0, -10.0), Point3::new(0.0, 0.0, 0.0));
    testbed.run();
}
<|endoftext|>


<commit_before>use std::process::{Child, Command};

pub struct Runner {
    process: Option<Child>,
    restart: bool,
    cls: bool,
}

impl Runner {
    pub fn new(restart: bool, clear: bool) -> Runner {
        Runner {
            process: None,
            restart: restart,
            cls: clear
        }
    }

    #[cfg(target_family = "windows")]
    fn clear(&self) {
        let _ = Command::new("cls").status();
    }

    #[cfg(target_family = "unix")]
    fn clear(&self) {
        let _ = Command::new("clear").status();
    }

    #[cfg(target_family = "windows")]
    fn kill(&self) {
        if let Some(ref child) = self.process {
            debug!("Killing child process (pid: {})", child.id());

            let _ = child.kill();
        }
    }

    #[cfg(target_family = "unix")]
    fn kill(&self) {
        use libc;

        extern {
            fn killpg(pgrp: libc::pid_t, sig: libc::c_int) -> libc::c_int;
        }

        if let Some(ref child) = self.process {
            debug!("Killing child process (pid: {})", child.id());

            unsafe {
                killpg(child.id() as i32, libc::SIGTERM);
            }
        }
    }

    #[cfg(target_family = "windows")]
    fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> {
        let mut command = Command::new("cmd.exe");
        command.arg("/C").arg(cmd);

        if !updated_paths.is_empty() {
            command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
        }

        debug!("Executing: {}", cmd);

        command.spawn().ok()
    }

    #[cfg(target_family = "unix")]
    fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> {
        use libc;
        use std::os::unix::process::CommandExt;

        let mut command = Command::new("sh");
        command.arg("-c").arg(cmd);

        if !updated_paths.is_empty() {
            command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
        }

        debug!("Executing: {}", cmd);

        command
            .before_exec(|| unsafe { libc::setpgid(0, 0); Ok(()) })
            .spawn()
            .ok()
    }

    pub fn run_command(&mut self, cmd: &str, updated_paths: Vec<&str>) {
        if self.restart {
            self.kill();
        }

        self.wait();

        if self.cls {
            self.clear();
        }

        self.process = self.invoke(cmd, updated_paths);
    }

    #[cfg(target_family = "windows")]
    fn wait(&self) {
        if let Some(ref child) = self.process {
            debug!("Waiting for child process (pid: {})", child.id());
            let _ = child.wait();
        }
    }

    #[cfg(target_family = "unix")]
    fn wait(&self) {
        use nix::sys::wait::{waitpid};

        if let Some(ref child) = self.process {
            debug!("Waiting for child process (pid: {})", child.id());

            let pid = child.id() as i32;
            let _ = waitpid(-pid, None);
        }
    }
}

impl Drop for Runner {
    fn drop(&mut self) {
        self.kill();
        self.wait();
    }
}
<commit_msg>Fix Windows bugs relating to mutability<commit_after>use std::process::{Child, Command};

pub struct Runner {
    process: Option<Child>,
    restart: bool,
    cls: bool,
}

impl Runner {
    pub fn new(restart: bool, clear: bool) -> Runner {
        Runner {
            process: None,
            restart: restart,
            cls: clear
        }
    }

    #[cfg(target_family = "windows")]
    fn clear(&self) {
        let _ = Command::new("cls").status();
    }

    #[cfg(target_family = "unix")]
    fn clear(&self) {
        let _ = Command::new("clear").status();
    }

    #[cfg(target_family = "windows")]
    fn kill(&mut self) {
        if let Some(ref mut child) = self.process {
            debug!("Killing child process (pid: {})", child.id());

            let _ = child.kill();
        }
    }

    #[cfg(target_family = "unix")]
    fn kill(&mut self) {
        use libc;

        extern {
            fn killpg(pgrp: libc::pid_t, sig: libc::c_int) -> libc::c_int;
        }

        if let Some(ref mut child) = self.process {
            debug!("Killing child process (pid: {})", child.id());

            unsafe {
                killpg(child.id() as i32, libc::SIGTERM);
            }
        }
    }

    #[cfg(target_family = "windows")]
    fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> {
        let mut command = Command::new("cmd.exe");
        command.arg("/C").arg(cmd);

        if !updated_paths.is_empty() {
            command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
        }

        debug!("Executing: {}", cmd);

        command.spawn().ok()
    }

    #[cfg(target_family = "unix")]
    fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> {
        use libc;
        use std::os::unix::process::CommandExt;

        let mut command = Command::new("sh");
        command.arg("-c").arg(cmd);

        if !updated_paths.is_empty() {
            command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
        }

        debug!("Executing: {}", cmd);

        command
            .before_exec(|| unsafe { libc::setpgid(0, 0); Ok(()) })
            .spawn()
            .ok()
    }

    pub fn run_command(&mut self, cmd: &str, updated_paths: Vec<&str>) {
        if self.restart {
            self.kill();
        }

        self.wait();

        if self.cls {
            self.clear();
        }

        self.process = self.invoke(cmd, updated_paths);
    }

    #[cfg(target_family = "windows")]
    fn wait(&mut self) {
        if let Some(ref mut child) = self.process {
            debug!("Waiting for child process (pid: {})", child.id());
            let _ = child.wait();
        }
    }

    #[cfg(target_family = "unix")]
    fn wait(&mut self) {
        use nix::sys::wait::{waitpid};

        if let Some(ref mut child) = self.process {
            debug!("Waiting for child process (pid: {})", child.id());

            let pid = child.id() as i32;
            let _ = waitpid(-pid, None);
        }
    }
}

impl Drop for Runner {
    fn drop(&mut self) {
        self.kill();
        self.wait();
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;

#[derive(Clone)]
pub struct Socket {
    addr: String,
}

impl Socket {
    pub fn new(addr: String) -> Self
    {
        Socket {
            addr,
        }
    }

    pub fn send<D>(&self, command: D) -> Option<String>
        where D: ::std::fmt::Display
    {
        let mut stream = match ::std::net::TcpStream::connect(self.addr.clone()) {
            Ok(stream) => stream,
            Err(_) => panic!("Unable to connect"),
        };

        info!("> {}", command);

        let message = format!("{}\r\n", command);
        stream.write(message.as_bytes())
            .unwrap();

        if message.contains("?") {
            Some(self.receive(stream))
        }
        else {
            None
        }
    }

    fn receive(&self, stream: ::std::net::TcpStream) -> String {
        let mut message = String::new();
        let mut reader = ::std::io::BufReader::new(stream);

        reader.read_line(&mut message)
            .unwrap();

        let message = message.trim_right_matches("\r\n");

        debug!("< {}", message);

        message.into()
    }
}
<commit_msg>Fixes deprecated trim_right_matches<commit_after>use std::io::prelude::*;

#[derive(Clone)]
pub struct Socket {
    addr: String,
}

impl Socket {
    pub fn new(addr: String) -> Self
    {
        Socket {
            addr,
        }
    }

    pub fn send<D>(&self, command: D) -> Option<String>
        where D: ::std::fmt::Display
    {
        let mut stream = match ::std::net::TcpStream::connect(self.addr.clone()) {
            Ok(stream) => stream,
            Err(_) => panic!("Unable to connect"),
        };

        info!("> {}", command);

        let message = format!("{}\r\n", command);
        stream.write(message.as_bytes())
            .unwrap();

        if message.contains("?") {
            Some(self.receive(stream))
        }
        else {
            None
        }
    }

    fn receive(&self, stream: ::std::net::TcpStream) -> String {
        let mut message = String::new();
        let mut reader = ::std::io::BufReader::new(stream);

        reader.read_line(&mut message)
            .unwrap();

        let message = message.trim_end_matches("\r\n");

        debug!("< {}", message);

        message.into()
    }
}
<|endoftext|>


<commit_before>use nalgebra::{UnitQuaternion, Vector2, Vector3, Vector4};
use serde::Deserialize;
use serde_json::from_reader;
use std::f32::consts;
use std::fs::File;
use std::ops::{Add, Div, Mul, Sub};
use std::path::Path;

use resource::{Cache, Load, LoadError};

/// Time used as sampling type in splines.
pub type Time = f32;

/// A spline control point.
///
/// This type associates a value at a given type. It also contains an interpolation object used to
/// determine how to interpolate values on the segment defined by this key and the next one.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
pub struct Key<T> {
  /// Time at which the `Key` should be reached.
  pub t: Time,
  /// Actual value.
  pub value: T,
  /// Interpolation mode.
  pub interpolation: Interpolation
}

impl<T> Key<T> {
  pub fn new(t: Time, value: T, interpolation: Interpolation) -> Self {
    Key {
      t: t,
      value: value,
      interpolation: interpolation
    }
  }
}

/// Interpolation mode.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Interpolation {
  /// Hold a `Key` until the time passes the normalized step threshold, in which case the next
  /// key is used.
  ///
  /// *Note: if you set the threshold to `0.5`, the first key will be used until the time is half
  /// between the two keys; the second key will be in used afterwards. If you set it to `1.0`, the
  /// first key will be kept until the next key.*
  #[serde(rename = "step")]
  Step(f32),
  /// Linear interpolation between a key and the next one.
  #[serde(rename = "linear")]
  Linear,
  /// Cosine interpolation between a key and the next one.
  #[serde(rename = "cosine")]
  Cosine,
  /// Catmull-Rom interpolation.
  #[serde(rename = "catmull_rom")]
  CatmullRom
}

/// Spline curve used to provide interpolation between control points (keys).
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Spline<T> {
  keys: Vec<Key<T>>,
}

impl<T> Spline<T> {
  pub fn new(mut cps: Vec<Key<T>>) -> Self {
    cps.sort_by(|k0, k1| k0.t.partial_cmp(&k1.t).unwrap());

    Spline {
      keys: cps
    }
  }
}

impl<'a, T> Load<'a> for Spline<T> where T: Deserialize {
  type Args = ();

  fn load<P>(path: P, _: &mut Cache<'a>, _: Self::Args) -> Result<Self, LoadError> where P: AsRef<Path> {
    let path = path.as_ref();

    let file = File::open(path).map_err(|e| LoadError::FileNotFound(path.to_path_buf(), format!("{:?}", e)))?;
    let keys = from_reader(file).map_err(|e| LoadError::ParseFailed(format!("{:?}", e)))?;

    Ok(Spline::new(keys))
  }
}

pub struct SplineIterator<'a, T> where T: 'a {
  anim_param: &'a Spline<T>,
  i: usize
}

impl<'a, T> Iterator for SplineIterator<'a, T> {
  type Item = &'a Key<T>;

  fn next(&mut self) -> Option<Self::Item> {
    let r = self.anim_param.keys.get(self.i);

    if let Some(_) = r {
      self.i += 1;
    }

    r
  }
}

impl<'a, T> IntoIterator for &'a Spline<T> {
  type Item = &'a Key<T>;
  type IntoIter = SplineIterator<'a, T>;

  fn into_iter(self) -> Self::IntoIter {
    SplineIterator {
      anim_param: self,
      i: 0
    }
  }
}

/// Implement this trait if your type is a key you want to sample with.
pub trait Interpolate: Copy {
  /// Linear interpolation.
  fn lerp(a: Self, b: Self, t: Time) -> Self;
  /// Cubic hermite interpolation.
  fn cubic_hermite(_: (Self, Time), a: (Self, Time), b: (Self, Time), _: (Self, Time), t: Time) -> Self {
    Self::lerp(a.0, b.0, t)
  }
}

impl Interpolate for f32 {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector2<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector3<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector4<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for UnitQuaternion<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    a * UnitQuaternion::new(&(UnitQuaternion::new(&a.quaternion().conjugate()) * b).quaternion().powf(t))
  }
}

// Default implementation of Interpolate::lerp.
fn lerp<T>(a: T, b: T, t: Time) -> T where T: Add<Output = T> + Mul<Time, Output = T> {
  a * (1. - t) + b * t
}

// Default implementation of Interpolate::cubic_hermit.

fn cubic_hermite<T>(x: (T, Time), a: (T, Time), b: (T, Time), y: (T, Time), t: Time) -> T
    where T: Copy + Add<Output = T> + Sub<Output = T> + Mul<Time, Output = T> + Div<Time, Output = T> {
  // time stuff
  let t2 = t * t;
  let t3 = t2 * t;
  let two_t3 = 2. * t3;
  let three_t2 = 3. * t2;

  // tangents
  let m0 = (b.0 - x.0) / (b.1 - x.1);
	let m1 = (y.0 - a.0) / (y.1 - a.1);

  a.0 * (two_t3 - three_t2 + 1.) + m0 * (t3 - 2. * t2 + t) + b.0 * (-two_t3 + three_t2) + m1 * (t3 - t2)
}

/// Samplers can sample `Spline` by providing a `Time`. They should be mutable so that they can
/// maintain an internal state for optimization purposes.
#[derive(Copy, Clone, Default)]
pub struct Sampler {
  /// Playback cursor – gives the lower control point index of the current portion of the curve
  /// we’re sampling at.
  cursor: usize
}

impl Sampler {
  pub fn new() -> Self {
    Sampler {
      cursor: 0
    }
  }

  /// Sample a spline. If `random_sampling` is set, random sampling is generally faster than
  /// continuous sampling. Though, if you use continuous sampling, set `random_sampling` to `false`
	/// for max speed performance.
  pub fn sample<T>(&mut self, t: Time, param: &Spline<T>, random_sampling: bool) -> Option<T>
      where T: Interpolate {
    let i = if random_sampling {
      binary_search_lower_cp(&param.keys, t)
    } else {
      let i = around_search_lower_cp(&param.keys, self.cursor, t);

      // if we’ve found the index, replace the cursor to speed up next searches
      if let Some(cursor) = i {
        self.cursor = cursor;
      }

      i
    };

    let i = match i {
      Some(i) => i,
      None => return None
    };

    let cp0 = &param.keys[i];

    match cp0.interpolation {
      Interpolation::Step(threshold) => {
        let cp1 = &param.keys[i+1];
        Some(if t < threshold { cp0.value } else { cp1.value })
      },
      Interpolation::Linear => {
        let cp1 = &param.keys[i+1];
        let nt = normalize_time(t, cp0, cp1);

        Some(Interpolate::lerp(cp0.value, cp1.value, nt))
      },
      Interpolation::Cosine => {
        let cp1 = &param.keys[i+1];
        let nt = normalize_time(t, cp0, cp1);
        let cos_nt = (1. - f32::cos(nt * consts::PI)) * 0.5;

        Some(Interpolate::lerp(cp0.value, cp1.value, cos_nt))
      },
      Interpolation::CatmullRom => {
        // We need at least four points for Catmull Rom; ensure we have them, otherwise, return
        // None.
        if i == 0 || i >= param.keys.len() - 2 {
          None
        } else {
          let cp1 = &param.keys[i+1];
          let cpm0 = &param.keys[i-1];
          let cpm1 = &param.keys[i+2];
          let nt = normalize_time(t, cp0, cp1);

          Some(Interpolate::cubic_hermite((cpm0.value, cpm0.t), (cp0.value, cp0.t), (cp1.value, cp1.t), (cpm1.value, cpm1.t), nt))
        }
      }
    }
  }
}

// Normalize a time ([0;1]) given two control points.
fn normalize_time<T>(t: Time, cp: &Key<T>, cp1: &Key<T>) -> Time {
  (t - cp.t) / (cp1.t - cp.t)
}

// Find the lower control point corresponding to a given time. Random version.
fn binary_search_lower_cp<T>(cps: &[Key<T>], t: Time) -> Option<usize> {
  let len = cps.len() as i32;
  if len < 2 {
    return None;
  }

  let mut down = 0;
  let mut up = len - 1;

  while down <= up {
    let m = (up + down) / 2;
    if m < 0 || m >= len - 1 {
      return None;
    }

    let cp0 = &cps[m as usize];

    if cp0.t > t {
      up = m-1;
    } else {
      let cp1 = &cps[(m+1) as usize];

      if t >= cp1.t {
        down = m+1;
      } else {
        return Some(m as usize)
      }
    }
  }

  None
}

// Find the lower control point corresponding to a given time. Continuous version. `i` is the last
// known found index.
fn around_search_lower_cp<T>(cps: &[Key<T>], mut i: usize, t: Time) -> Option<usize> {
  let len = cps.len();

  if len < 2 {
    return None;
  }

  loop {
    let cp = &cps[i];
    let cp1 = &cps[i+1];

    if t >= cp1.t {
      if i >= len - 2 {
        return None;
      }

      i += 1;
    } else if t < cp.t {
      if i == 0 {
        return None;
      }

      i -= 1;
    } else {
      break; // found
    }
  }

  Some(i)
}
<commit_msg>Added info! for spline loading.<commit_after>use nalgebra::{UnitQuaternion, Vector2, Vector3, Vector4};
use serde::Deserialize;
use serde_json::from_reader;
use std::f32::consts;
use std::fs::File;
use std::ops::{Add, Div, Mul, Sub};
use std::path::Path;

use resource::{Cache, Load, LoadError};

/// Time used as sampling type in splines.
pub type Time = f32;

/// A spline control point.
///
/// This type associates a value at a given type. It also contains an interpolation object used to
/// determine how to interpolate values on the segment defined by this key and the next one.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
pub struct Key<T> {
  /// Time at which the `Key` should be reached.
  pub t: Time,
  /// Actual value.
  pub value: T,
  /// Interpolation mode.
  pub interpolation: Interpolation
}

impl<T> Key<T> {
  pub fn new(t: Time, value: T, interpolation: Interpolation) -> Self {
    Key {
      t: t,
      value: value,
      interpolation: interpolation
    }
  }
}

/// Interpolation mode.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Interpolation {
  /// Hold a `Key` until the time passes the normalized step threshold, in which case the next
  /// key is used.
  ///
  /// *Note: if you set the threshold to `0.5`, the first key will be used until the time is half
  /// between the two keys; the second key will be in used afterwards. If you set it to `1.0`, the
  /// first key will be kept until the next key.*
  #[serde(rename = "step")]
  Step(f32),
  /// Linear interpolation between a key and the next one.
  #[serde(rename = "linear")]
  Linear,
  /// Cosine interpolation between a key and the next one.
  #[serde(rename = "cosine")]
  Cosine,
  /// Catmull-Rom interpolation.
  #[serde(rename = "catmull_rom")]
  CatmullRom
}

/// Spline curve used to provide interpolation between control points (keys).
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Spline<T> {
  keys: Vec<Key<T>>,
}

impl<T> Spline<T> {
  pub fn new(mut cps: Vec<Key<T>>) -> Self {
    cps.sort_by(|k0, k1| k0.t.partial_cmp(&k1.t).unwrap());

    Spline {
      keys: cps
    }
  }
}

impl<'a, T> Load<'a> for Spline<T> where T: Deserialize {
  type Args = ();

  fn load<P>(path: P, _: &mut Cache<'a>, _: Self::Args) -> Result<Self, LoadError> where P: AsRef<Path> {
    let path = path.as_ref();

    info!("loading spline: {:?}", path);

    let file = File::open(path).map_err(|e| LoadError::FileNotFound(path.to_path_buf(), format!("{:?}", e)))?;
    let keys = from_reader(file).map_err(|e| LoadError::ParseFailed(format!("{:?}", e)))?;

    Ok(Spline::new(keys))
  }
}

pub struct SplineIterator<'a, T> where T: 'a {
  anim_param: &'a Spline<T>,
  i: usize
}

impl<'a, T> Iterator for SplineIterator<'a, T> {
  type Item = &'a Key<T>;

  fn next(&mut self) -> Option<Self::Item> {
    let r = self.anim_param.keys.get(self.i);

    if let Some(_) = r {
      self.i += 1;
    }

    r
  }
}

impl<'a, T> IntoIterator for &'a Spline<T> {
  type Item = &'a Key<T>;
  type IntoIter = SplineIterator<'a, T>;

  fn into_iter(self) -> Self::IntoIter {
    SplineIterator {
      anim_param: self,
      i: 0
    }
  }
}

/// Implement this trait if your type is a key you want to sample with.
pub trait Interpolate: Copy {
  /// Linear interpolation.
  fn lerp(a: Self, b: Self, t: Time) -> Self;
  /// Cubic hermite interpolation.
  fn cubic_hermite(_: (Self, Time), a: (Self, Time), b: (Self, Time), _: (Self, Time), t: Time) -> Self {
    Self::lerp(a.0, b.0, t)
  }
}

impl Interpolate for f32 {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector2<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector3<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for Vector4<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    lerp(a, b, t)
  }

  fn cubic_hermite(x: (Self, Time), a: (Self, Time), b: (Self, Time), y: (Self, Time), t: Time) -> Self {
    cubic_hermite(x, a, b, y, t)
  }
}

impl Interpolate for UnitQuaternion<f32> {
  fn lerp(a: Self, b: Self, t: Time) -> Self {
    a * UnitQuaternion::new(&(UnitQuaternion::new(&a.quaternion().conjugate()) * b).quaternion().powf(t))
  }
}

// Default implementation of Interpolate::lerp.
fn lerp<T>(a: T, b: T, t: Time) -> T where T: Add<Output = T> + Mul<Time, Output = T> {
  a * (1. - t) + b * t
}

// Default implementation of Interpolate::cubic_hermit.

fn cubic_hermite<T>(x: (T, Time), a: (T, Time), b: (T, Time), y: (T, Time), t: Time) -> T
    where T: Copy + Add<Output = T> + Sub<Output = T> + Mul<Time, Output = T> + Div<Time, Output = T> {
  // time stuff
  let t2 = t * t;
  let t3 = t2 * t;
  let two_t3 = 2. * t3;
  let three_t2 = 3. * t2;

  // tangents
  let m0 = (b.0 - x.0) / (b.1 - x.1);
	let m1 = (y.0 - a.0) / (y.1 - a.1);

  a.0 * (two_t3 - three_t2 + 1.) + m0 * (t3 - 2. * t2 + t) + b.0 * (-two_t3 + three_t2) + m1 * (t3 - t2)
}

/// Samplers can sample `Spline` by providing a `Time`. They should be mutable so that they can
/// maintain an internal state for optimization purposes.
#[derive(Copy, Clone, Default)]
pub struct Sampler {
  /// Playback cursor – gives the lower control point index of the current portion of the curve
  /// we’re sampling at.
  cursor: usize
}

impl Sampler {
  pub fn new() -> Self {
    Sampler {
      cursor: 0
    }
  }

  /// Sample a spline. If `random_sampling` is set, random sampling is generally faster than
  /// continuous sampling. Though, if you use continuous sampling, set `random_sampling` to `false`
	/// for max speed performance.
  pub fn sample<T>(&mut self, t: Time, param: &Spline<T>, random_sampling: bool) -> Option<T>
      where T: Interpolate {
    let i = if random_sampling {
      binary_search_lower_cp(&param.keys, t)
    } else {
      let i = around_search_lower_cp(&param.keys, self.cursor, t);

      // if we’ve found the index, replace the cursor to speed up next searches
      if let Some(cursor) = i {
        self.cursor = cursor;
      }

      i
    };

    let i = match i {
      Some(i) => i,
      None => return None
    };

    let cp0 = &param.keys[i];

    match cp0.interpolation {
      Interpolation::Step(threshold) => {
        let cp1 = &param.keys[i+1];
        Some(if t < threshold { cp0.value } else { cp1.value })
      },
      Interpolation::Linear => {
        let cp1 = &param.keys[i+1];
        let nt = normalize_time(t, cp0, cp1);

        Some(Interpolate::lerp(cp0.value, cp1.value, nt))
      },
      Interpolation::Cosine => {
        let cp1 = &param.keys[i+1];
        let nt = normalize_time(t, cp0, cp1);
        let cos_nt = (1. - f32::cos(nt * consts::PI)) * 0.5;

        Some(Interpolate::lerp(cp0.value, cp1.value, cos_nt))
      },
      Interpolation::CatmullRom => {
        // We need at least four points for Catmull Rom; ensure we have them, otherwise, return
        // None.
        if i == 0 || i >= param.keys.len() - 2 {
          None
        } else {
          let cp1 = &param.keys[i+1];
          let cpm0 = &param.keys[i-1];
          let cpm1 = &param.keys[i+2];
          let nt = normalize_time(t, cp0, cp1);

          Some(Interpolate::cubic_hermite((cpm0.value, cpm0.t), (cp0.value, cp0.t), (cp1.value, cp1.t), (cpm1.value, cpm1.t), nt))
        }
      }
    }
  }
}

// Normalize a time ([0;1]) given two control points.
fn normalize_time<T>(t: Time, cp: &Key<T>, cp1: &Key<T>) -> Time {
  (t - cp.t) / (cp1.t - cp.t)
}

// Find the lower control point corresponding to a given time. Random version.
fn binary_search_lower_cp<T>(cps: &[Key<T>], t: Time) -> Option<usize> {
  let len = cps.len() as i32;
  if len < 2 {
    return None;
  }

  let mut down = 0;
  let mut up = len - 1;

  while down <= up {
    let m = (up + down) / 2;
    if m < 0 || m >= len - 1 {
      return None;
    }

    let cp0 = &cps[m as usize];

    if cp0.t > t {
      up = m-1;
    } else {
      let cp1 = &cps[(m+1) as usize];

      if t >= cp1.t {
        down = m+1;
      } else {
        return Some(m as usize)
      }
    }
  }

  None
}

// Find the lower control point corresponding to a given time. Continuous version. `i` is the last
// known found index.
fn around_search_lower_cp<T>(cps: &[Key<T>], mut i: usize, t: Time) -> Option<usize> {
  let len = cps.len();

  if len < 2 {
    return None;
  }

  loop {
    let cp = &cps[i];
    let cp1 = &cps[i+1];

    if t >= cp1.t {
      if i >= len - 2 {
        return None;
      }

      i += 1;
    } else if t < cp.t {
      if i == 0 {
        return None;
      }

      i -= 1;
    } else {
      break; // found
    }
  }

  Some(i)
}
<|endoftext|>


<commit_before>use std::io;
use std::io::ErrorKind::WouldBlock;
use std::net::SocketAddr;

use mio::tcp::TcpStream;
#[cfg(feature="ssl")]
use openssl::ssl::SslStream;
#[cfg(feature="ssl")]
use openssl::ssl::error::Error as SslError;
use bytes::{Buf, BufMut};

use result::{Result, Error, Kind};

fn map_non_block<T>(res: io::Result<T>) -> io::Result<Option<T>> {
    match res {
        Ok(value) => Ok(Some(value)),
        Err(err) => {
            if let WouldBlock = err.kind() {
                Ok(None)
            } else {
                Err(err)
            }
        }
    }
}

pub trait TryReadBuf: io::Read {
    fn try_read_buf<B: BufMut>(&mut self, buf: &mut B) -> io::Result<Option<usize>>
        where Self : Sized
    {
        // Reads the length of the slice supplied by buf.mut_bytes into the buffer
        // This is not guaranteed to consume an entire datagram or segment.
        // If your protocol is msg based (instead of continuous stream) you should
        // ensure that your buffer is large enough to hold an entire segment (1532 bytes if not jumbo
        // frames)
        let res = map_non_block(self.read(unsafe { buf.bytes_mut() }));

        if let Ok(Some(cnt)) = res {
            unsafe { buf.advance_mut(cnt); }
        }

        res
    }
}

pub trait TryWriteBuf: io::Write {
    fn try_write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<Option<usize>>
        where Self : Sized
    {
        let res = map_non_block(self.write(buf.bytes()));

        if let Ok(Some(cnt)) = res {
            buf.advance(cnt);
        }

        res
    }
}

impl<T: io::Read> TryReadBuf for T {}
impl<T: io::Write> TryWriteBuf for T {}

use self::Stream::*;
pub enum Stream {
    Tcp(TcpStream),
    #[cfg(feature="ssl")]
    Tls {
        sock: SslStream<TcpStream>,
        negotiating: bool,
    }
}

impl Stream {

    pub fn tcp(stream: TcpStream) -> Stream {
        Tcp(stream)
    }

    #[cfg(feature="ssl")]
    pub fn tls(stream: SslStream<TcpStream>) -> Stream {
        Tls { sock: stream, negotiating: false }
    }

    #[cfg(feature="ssl")]
    pub fn is_tls(&self) -> bool {
        match *self {
            Tcp(_) => false,
            Tls {..} => true,
        }
    }

    pub fn evented(&self) -> &TcpStream {
        match *self {
            Tcp(ref sock) => sock,
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref(),
        }
    }

    pub fn is_negotiating(&self) -> bool {
        match *self {
            Tcp(_) => false,
            #[cfg(feature="ssl")]
            Tls { sock: _, ref negotiating } => *negotiating,
        }

    }

    pub fn clear_negotiating(&mut self) -> Result<()> {
        match *self {
            Tcp(_) => Err(Error::new(Kind::Internal, "Attempted to clear negotiating flag on non ssl connection.")),
            #[cfg(feature="ssl")]
            Tls { sock: _, ref mut negotiating } => Ok(*negotiating = false),
        }
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match *self {
            Tcp(ref sock) => sock.peer_addr(),
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref().peer_addr(),
        }
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        match *self {
            Tcp(ref sock) => sock.local_addr(),
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref().local_addr(),
        }
    }
}

impl io::Read for Stream {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Tcp(ref mut sock) => sock.read(buf),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, ref mut negotiating } => {
                match sock.ssl_read(buf) {
                    Ok(cnt) => Ok(cnt),
                    Err(SslError::WantWrite(_)) => {
                        *negotiating = true;
                        Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants writing"))
                    },
                    Err(SslError::WantRead(_)) => Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants reading")),
                    Err(err) =>
                        Err(io::Error::new(io::ErrorKind::Other, err)),
                }
            }
        }
    }
}

impl io::Write for Stream {

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            Tcp(ref mut sock) => sock.write(buf),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, ref mut negotiating } => {

                *negotiating = false;

                match sock.ssl_write(buf) {
                    Ok(cnt) => Ok(cnt),
                    Err(SslError::WantRead(_)) => {
                        *negotiating = true;
                        Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants reading"))
                    },
                    Err(SslError::WantWrite(_)) => Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants writing")),
                    Err(err) =>
                        Err(io::Error::new(io::ErrorKind::Other, err)),
                }
            }
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            Tcp(ref mut sock) => sock.flush(),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, negotiating: _ } => sock.flush(),
        }
    }
}
<commit_msg>refactor(stream): Change TryReadBuf to take Vec directly instead of BufMut<commit_after>use std::io;
use std::io::ErrorKind::WouldBlock;
use std::net::SocketAddr;

use mio::tcp::TcpStream;
#[cfg(feature="ssl")]
use openssl::ssl::SslStream;
#[cfg(feature="ssl")]
use openssl::ssl::error::Error as SslError;
use bytes::Buf;

use result::{Result, Error, Kind};

fn map_non_block<T>(res: io::Result<T>) -> io::Result<Option<T>> {
    match res {
        Ok(value) => Ok(Some(value)),
        Err(err) => {
            if let WouldBlock = err.kind() {
                Ok(None)
            } else {
                Err(err)
            }
        }
    }
}

pub trait TryReadBuf: io::Read {
    fn try_read_buf(&mut self, buf: &mut Vec<u8>) -> io::Result<Option<usize>>
        where Self : Sized
    {
        // Reads the length of the slice supplied by buf into the buffer
        // This is not guaranteed to consume an entire datagram or segment.
        // If your protocol is msg based (instead of continuous stream) you should
        // ensure that your buffer is large enough to hold an entire segment (1532 bytes if not jumbo
        // frames)
        map_non_block(self.read_to_end(buf))
    }
}

pub trait TryWriteBuf: io::Write {
    fn try_write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<Option<usize>>
        where Self : Sized
    {
        let res = map_non_block(self.write(buf.bytes()));

        if let Ok(Some(cnt)) = res {
            buf.advance(cnt);
        }

        res
    }
}

impl<T: io::Read> TryReadBuf for T {}
impl<T: io::Write> TryWriteBuf for T {}

use self::Stream::*;
pub enum Stream {
    Tcp(TcpStream),
    #[cfg(feature="ssl")]
    Tls {
        sock: SslStream<TcpStream>,
        negotiating: bool,
    }
}

impl Stream {

    pub fn tcp(stream: TcpStream) -> Stream {
        Tcp(stream)
    }

    #[cfg(feature="ssl")]
    pub fn tls(stream: SslStream<TcpStream>) -> Stream {
        Tls { sock: stream, negotiating: false }
    }

    #[cfg(feature="ssl")]
    pub fn is_tls(&self) -> bool {
        match *self {
            Tcp(_) => false,
            Tls {..} => true,
        }
    }

    pub fn evented(&self) -> &TcpStream {
        match *self {
            Tcp(ref sock) => sock,
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref(),
        }
    }

    pub fn is_negotiating(&self) -> bool {
        match *self {
            Tcp(_) => false,
            #[cfg(feature="ssl")]
            Tls { sock: _, ref negotiating } => *negotiating,
        }

    }

    pub fn clear_negotiating(&mut self) -> Result<()> {
        match *self {
            Tcp(_) => Err(Error::new(Kind::Internal, "Attempted to clear negotiating flag on non ssl connection.")),
            #[cfg(feature="ssl")]
            Tls { sock: _, ref mut negotiating } => Ok(*negotiating = false),
        }
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match *self {
            Tcp(ref sock) => sock.peer_addr(),
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref().peer_addr(),
        }
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        match *self {
            Tcp(ref sock) => sock.local_addr(),
            #[cfg(feature="ssl")]
            Tls { ref sock, ..} => sock.get_ref().local_addr(),
        }
    }
}

impl io::Read for Stream {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Tcp(ref mut sock) => sock.read(buf),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, ref mut negotiating } => {
                match sock.ssl_read(buf) {
                    Ok(cnt) => Ok(cnt),
                    Err(SslError::WantWrite(_)) => {
                        *negotiating = true;
                        Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants writing"))
                    },
                    Err(SslError::WantRead(_)) => Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants reading")),
                    Err(err) =>
                        Err(io::Error::new(io::ErrorKind::Other, err)),
                }
            }
        }
    }
}

impl io::Write for Stream {

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            Tcp(ref mut sock) => sock.write(buf),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, ref mut negotiating } => {

                *negotiating = false;

                match sock.ssl_write(buf) {
                    Ok(cnt) => Ok(cnt),
                    Err(SslError::WantRead(_)) => {
                        *negotiating = true;
                        Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants reading"))
                    },
                    Err(SslError::WantWrite(_)) => Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL wants writing")),
                    Err(err) =>
                        Err(io::Error::new(io::ErrorKind::Other, err)),
                }
            }
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            Tcp(ref mut sock) => sock.flush(),
            #[cfg(feature="ssl")]
            Tls { ref mut sock, negotiating: _ } => sock.flush(),
        }
    }
}
<|endoftext|>


<commit_before>//! Describes the sea current

/// The current selected arrow.
#[deriving(Copy)]
pub struct SelectedArrow(pub Option<uint>);

#[deriving(Copy)]
pub struct Arrow {
    pub pos: [f64, ..2],
    pub dir: [f64, ..2],
}

impl Arrow {
    pub fn line(&self, speedup: f64) -> [f64, ..4] {
        [
            self.pos[0],
            self.pos[1],
            self.pos[0] + self.dir[0] * speedup,
            self.pos[1] + self.dir[1] * speedup
        ]
    }
}

pub struct MovingArrow {
    pub arrow: Arrow,
    pub start_pos: [f64, ..2],
    pub time: f64,
}

pub struct Stream {
    /// Arrows that describe the stream current
    pub arrows: Vec<Arrow>,
    /// A rectangle used to pick random coordinates
    pub rect: [f64, ..4],
    /// A range to pick random sea current strength
    pub strength: [f64, ..2],
    /// The phase of the arrow the moment they were added.
    pub arrow_phases: Vec<f64>,
}

impl Stream {
    pub fn add_arrow(&mut self, arrow: Arrow, phase: f64) {
        self.arrows.push(arrow);
        self.arrow_phases.push(phase);
    }

    /// Computes stream at position using weighted average
    pub fn at(&self, pos: [f64, ..2]) -> [f64, ..2] {
        use piston::vecmath::vec2_add as add;
        use piston::vecmath::vec2_sub as sub;
        use piston::vecmath::vec2_len as len;
        use piston::vecmath::vec2_scale as scale;
        use std::num::FloatMath;

        if self.arrows.len() == 0 { return [0.0, ..2]; }

        let mut sum = [0.0, ..2];
        let mut sum_w = 0.0;
        for (i, arrow) in self.arrows.iter().enumerate() {
            let l = len(sub(arrow.pos, pos)).max(0.01);
            let w = 1.0 / (l * l);
            let phase_w = self.arrow_phases[i].cos();
            sum = add(sum, scale(arrow.dir, w * phase_w));
            sum_w += w;
        }

        scale(sum, 1.0 / sum_w)
    }

    pub fn nm(&self, sample_size: f64) -> [u32, ..2] {
        let [_, _, w, h] = self.rect;
        [(w / sample_size) as u32, (h / sample_size) as u32]
    }
}

pub fn add_arrow(pos: [f64, ..2]) {
    use current_stream;
    use current_selected_arrow;
    use std::rand::random;
    use piston::vecmath::consts::Radians;

    let stream = unsafe { &mut *current_stream() };
    let selected_arrow = unsafe { &mut *current_selected_arrow() };

    stream.add_arrow(
        Arrow {
            pos: pos,
            dir: [0.0, ..2],
        },
        random::<f64>() * Radians::_360()
    );

    let id = stream.arrows.len() - 1;
    *selected_arrow = SelectedArrow(Some(id));
}

pub fn edit_selected_arrow(pos: [f64, ..2]) {
    use current_stream;
    use current_selected_arrow;
    use piston::vecmath::vec2_sub as sub;
    use piston::vecmath::vec2_scale as scale;
    use settings::stream::SPEEDUP;

    let stream = unsafe { &mut *current_stream() };
    let &SelectedArrow(selected_arrow) = unsafe { &mut *current_selected_arrow() };
    let id = match selected_arrow {
        None => { return; }
        Some(x) => x
    };
    stream.arrows[id].dir = scale(sub(pos, stream.arrows[id].pos), 1.0 / SPEEDUP);
}

pub fn deselect_arrow() {
    use current_selected_arrow;

    *unsafe { current_selected_arrow() } = SelectedArrow(None);
}

pub fn refresh_moving_arrows() {
    use current_stream;
    use current_moving_arrows;
    use settings::stream::SAMPLE_SIZE;

    let stream = unsafe { &mut *current_stream() };
    let moving_arrows = unsafe { &mut *current_moving_arrows() };

    moving_arrows.clear();
    let [x, y, _, _] = stream.rect;
    let [n, m] = stream.nm(SAMPLE_SIZE);
    for i in range(0, n) {
        for j in range(0, m) {
            let sx = i as f64 * SAMPLE_SIZE + x;
            let sy = j as f64 * SAMPLE_SIZE + y;
            moving_arrows.push(MovingArrow {
                arrow: Arrow {
                    pos: [sx, sy],
                    dir: stream.at([sx, sy]),
                },
                start_pos: [sx, sy],
                time: 0.0,
            });
        }
    }
}

pub fn update_stream(dt: f64) {
    use current_stream;
    use settings::stream::PHASE_VEL;
    use piston::vecmath::consts::Radians;

    let shift = dt * PHASE_VEL * Radians::_360();
    let stream = unsafe { &mut *current_stream() };
    for arrow_phase in stream.arrow_phases.iter_mut() {
        *arrow_phase += shift;
    }
}

pub fn update_moving_arrows(dt: f64) {
    use current_stream;
    use current_moving_arrows;
    use piston::vecmath::vec2_add as add;
    use piston::vecmath::vec2_scale as scale;
    use piston::vecmath::vec2_len as len;
    use settings::stream::{ MOVING_ARROW_TIME_SPAN, SPEEDUP };

    let stream = unsafe { &mut *current_stream() };
    let moving_arrows = unsafe { &mut *current_moving_arrows() };
    for moving_arrow in moving_arrows.iter_mut() {
        let arrow = moving_arrow.arrow;
        let diff = scale(arrow.dir, dt * SPEEDUP);
        moving_arrow.arrow.pos = add(arrow.pos, diff);
        moving_arrow.arrow.dir = stream.at(moving_arrow.arrow.pos);
        moving_arrow.time += len(diff);
        if moving_arrow.time > MOVING_ARROW_TIME_SPAN {
            // Reset back to beginning.
            let start_pos = moving_arrow.start_pos;
            let dir = stream.at(start_pos);
            *moving_arrow = MovingArrow {
                arrow: Arrow {
                    pos: start_pos,
                    dir: dir,
                },
                start_pos: start_pos,
                time: 0.0,
            };
        }
    }
}

<commit_msg>Refactored<commit_after>//! Describes the sea current

/// The current selected arrow.
#[deriving(Copy)]
pub struct SelectedArrow(pub Option<uint>);

#[deriving(Copy)]
pub struct Arrow {
    pub pos: [f64, ..2],
    pub dir: [f64, ..2],
}

impl Arrow {
    pub fn line(&self, speedup: f64) -> [f64, ..4] {
        [
            self.pos[0],
            self.pos[1],
            self.pos[0] + self.dir[0] * speedup,
            self.pos[1] + self.dir[1] * speedup
        ]
    }
}

pub struct MovingArrow {
    pub arrow: Arrow,
    pub start_pos: [f64, ..2],
    pub time: f64,
}

pub struct Stream {
    /// Arrows that describe the stream current
    pub arrows: Vec<Arrow>,
    /// A rectangle used to pick random coordinates
    pub rect: [f64, ..4],
    /// A range to pick random sea current strength
    pub strength: [f64, ..2],
    /// The phase of the arrow the moment they were added.
    pub arrow_phases: Vec<f64>,
}

impl Stream {
    pub fn add_arrow(&mut self, arrow: Arrow, phase: f64) {
        self.arrows.push(arrow);
        self.arrow_phases.push(phase);
    }

    /// Computes stream at position using weighted average
    pub fn at(&self, pos: [f64, ..2]) -> [f64, ..2] {
        use piston::vecmath::vec2_add as add;
        use piston::vecmath::vec2_sub as sub;
        use piston::vecmath::vec2_len as len;
        use piston::vecmath::vec2_scale as scale;
        use std::num::FloatMath;

        if self.arrows.len() == 0 { return [0.0, ..2]; }

        let mut sum = [0.0, ..2];
        let mut sum_w = 0.0;
        for (i, arrow) in self.arrows.iter().enumerate() {
            let l = len(sub(arrow.pos, pos)).max(0.01);
            let w = 1.0 / (l * l);
            let phase_w = self.arrow_phases[i].cos();
            sum = add(sum, scale(arrow.dir, w * phase_w));
            sum_w += w;
        }

        scale(sum, 1.0 / sum_w)
    }

    pub fn nm(&self, sample_size: f64) -> [u32, ..2] {
        let [_, _, w, h] = self.rect;
        [(w / sample_size) as u32, (h / sample_size) as u32]
    }

    pub fn update(&mut self, dt: f64) {
        use settings::stream::PHASE_VEL;
        use piston::vecmath::consts::Radians;

        let shift = dt * PHASE_VEL * Radians::_360();
        for arrow_phase in self.arrow_phases.iter_mut() {
            *arrow_phase += shift;
        }
    }

}

pub fn add_arrow(pos: [f64, ..2]) {
    use current_stream;
    use current_selected_arrow;
    use std::rand::random;
    use piston::vecmath::consts::Radians;

    let stream = unsafe { &mut *current_stream() };
    let selected_arrow = unsafe { &mut *current_selected_arrow() };

    stream.add_arrow(
        Arrow {
            pos: pos,
            dir: [0.0, ..2],
        },
        random::<f64>() * Radians::_360()
    );

    let id = stream.arrows.len() - 1;
    *selected_arrow = SelectedArrow(Some(id));
}

pub fn edit_selected_arrow(pos: [f64, ..2]) {
    use current_stream;
    use current_selected_arrow;
    use piston::vecmath::vec2_sub as sub;
    use piston::vecmath::vec2_scale as scale;
    use settings::stream::SPEEDUP;

    let stream = unsafe { &mut *current_stream() };
    let &SelectedArrow(selected_arrow) = unsafe { &mut *current_selected_arrow() };
    let id = match selected_arrow {
        None => { return; }
        Some(x) => x
    };
    stream.arrows[id].dir = scale(sub(pos, stream.arrows[id].pos), 1.0 / SPEEDUP);
}

pub fn deselect_arrow() {
    use current_selected_arrow;

    *unsafe { current_selected_arrow() } = SelectedArrow(None);
}

pub fn refresh_moving_arrows() {
    use current_stream;
    use current_moving_arrows;
    use settings::stream::SAMPLE_SIZE;

    let stream = unsafe { &mut *current_stream() };
    let moving_arrows = unsafe { &mut *current_moving_arrows() };

    moving_arrows.clear();
    let [x, y, _, _] = stream.rect;
    let [n, m] = stream.nm(SAMPLE_SIZE);
    for i in range(0, n) {
        for j in range(0, m) {
            let sx = i as f64 * SAMPLE_SIZE + x;
            let sy = j as f64 * SAMPLE_SIZE + y;
            moving_arrows.push(MovingArrow {
                arrow: Arrow {
                    pos: [sx, sy],
                    dir: stream.at([sx, sy]),
                },
                start_pos: [sx, sy],
                time: 0.0,
            });
        }
    }
}

pub fn update_stream(dt: f64) {
    use current_stream;

    unsafe { current_stream() }.update(dt);
}

pub fn update_moving_arrows(dt: f64) {
    use current_stream;
    use current_moving_arrows;
    use piston::vecmath::vec2_add as add;
    use piston::vecmath::vec2_scale as scale;
    use piston::vecmath::vec2_len as len;
    use settings::stream::{ MOVING_ARROW_TIME_SPAN, SPEEDUP };

    let stream = unsafe { &mut *current_stream() };
    let moving_arrows = unsafe { &mut *current_moving_arrows() };
    for moving_arrow in moving_arrows.iter_mut() {
        let arrow = moving_arrow.arrow;
        let diff = scale(arrow.dir, dt * SPEEDUP);
        moving_arrow.arrow.pos = add(arrow.pos, diff);
        moving_arrow.arrow.dir = stream.at(moving_arrow.arrow.pos);
        moving_arrow.time += len(diff);
        if moving_arrow.time > MOVING_ARROW_TIME_SPAN {
            // Reset back to beginning.
            let start_pos = moving_arrow.start_pos;
            let dir = stream.at(start_pos);
            *moving_arrow = MovingArrow {
                arrow: Arrow {
                    pos: start_pos,
                    dir: dir,
                },
                start_pos: start_pos,
                time: 0.0,
            };
        }
    }
}

<|endoftext|>


<commit_before>// Options
// Space before /
// Quote style
// Ordering of attributes

#[cfg(test)]
mod test {
    use std::io::{IoResult,MemWriter};

    use super::super::{Document,Element};
    use super::super::{ElementElementChild,TextElementChild,CommentElementChild,PIElementChild};

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    enum Content {
        WElement(Element),
        WElementEnd(String),
    }

    fn format_element<W : Writer>(element: Element, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
        try!(write!(writer, "<{}", element.name()));

        for attr in element.attributes().iter() {
            try!(write!(writer, " {}='{}'", attr.name(), attr.value()));
        }

        let mut children = element.children();
        if children.is_empty() {
            writer.write_str("/>")
        } else {
            try!(writer.write_str(">"));

            todo.push(WElementEnd(element.name()));
            children.reverse();
            let x = children.move_iter().map(|c| match c {
                ElementElementChild(element) => WElement(element),
                TextElementChild(_) => fail!("text?"),
                CommentElementChild(_) => fail!("comment?"),
                PIElementChild(_) => fail!("PI?"),
            }).collect();
            todo.push_all_move(x);

            Ok(())
        }
    }

    fn format_document<W : Writer>(doc: &Document, writer: &mut W) -> IoResult<()> {
        let mut todo = Vec::new();

        try!(writer.write_str("<?xml version='1.0'?>"));
        let e = doc.root().children()[0].element().expect("not an element?");

        todo.push(WElement(e));

        while ! todo.is_empty() {
            match todo.pop().unwrap() {
                WElement(e) => try!(format_element(e, &mut todo, writer)),
                WElementEnd(name) => try!(write!(writer, "</{}>", name)),
            }
        }

        Ok(())
    }

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn top_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }

    #[test]
    fn element_with_attributes() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        e.set_attribute("a".to_string(), "b".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
    }

    #[test]
    fn nested_element() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let world = d.new_element("world".to_string());
        hello.append_child(world);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><world/></hello>");
    }
}
<commit_msg>Write text nodes<commit_after>// Options
// Space before /
// Quote style
// Ordering of attributes

#[cfg(test)]
mod test {
    use std::io::{IoResult,MemWriter};

    use super::super::{Document,Element,Text};
    use super::super::{ElementElementChild,TextElementChild,CommentElementChild,PIElementChild};

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    enum Content {
        WElement(Element),
        WElementEnd(String),
        WText(Text),
    }

    fn format_element<W : Writer>(element: Element, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
        try!(write!(writer, "<{}", element.name()));

        for attr in element.attributes().iter() {
            try!(write!(writer, " {}='{}'", attr.name(), attr.value()));
        }

        let mut children = element.children();
        if children.is_empty() {
            writer.write_str("/>")
        } else {
            try!(writer.write_str(">"));

            todo.push(WElementEnd(element.name()));
            children.reverse();
            let x = children.move_iter().map(|c| match c {
                ElementElementChild(element) => WElement(element),
                TextElementChild(t) => WText(t),
                CommentElementChild(_) => fail!("comment?"),
                PIElementChild(_) => fail!("PI?"),
            }).collect();
            todo.push_all_move(x);

            Ok(())
        }
    }

    fn format_document<W : Writer>(doc: &Document, writer: &mut W) -> IoResult<()> {
        let mut todo = Vec::new();

        try!(writer.write_str("<?xml version='1.0'?>"));
        let e = doc.root().children()[0].element().expect("not an element?");

        todo.push(WElement(e));

        while ! todo.is_empty() {
            match todo.pop().unwrap() {
                WElement(e) => try!(format_element(e, &mut todo, writer)),
                WElementEnd(name) => try!(write!(writer, "</{}>", name)),
                WText(t) => try!(writer.write_str(t.text().as_slice())),
            }
        }

        Ok(())
    }

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn top_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }

    #[test]
    fn element_with_attributes() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        e.set_attribute("a".to_string(), "b".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
    }

    #[test]
    fn nested_element() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let world = d.new_element("world".to_string());
        hello.append_child(world);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><world/></hello>");
    }

    #[test]
    fn nested_text() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let text = d.new_text("A fine day to you!".to_string());
        hello.append_child(text);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello>A fine day to you!</hello>");
    }
}
<|endoftext|>


<commit_before>use std;
use std::panic;
use std::cell::Cell;
use std::marker::PhantomData;

pub struct Scope<'s> {
    active_holes: Cell<usize>,
    marker: PhantomData<Cell<&'s mut ()>>
}

impl<'s> Scope<'s> {

    pub fn take_and_recover<'c, 'm: 's, T: 'm, F: FnOnce() -> T>(&'c self, mut_ref: &'m mut T, recovery: F) -> (T, Hole<'c, 'm, T, F>) {
        use std::ptr;

        let t: T;
        let hole: Hole<'c, 'm, T, F>;
        let num_of_holes = self.active_holes.get();
        if num_of_holes == std::usize::MAX {
            panic!("Too many holes!");
        }
        self.active_holes.set(num_of_holes + 1);
        unsafe {
            t = ptr::read(mut_ref);
            hole = Hole {
                active_holes: &self.active_holes,
                hole: mut_ref,
                recovery: Some(recovery)
            };
        };
        (t, hole)
    }

    pub fn take<'c, 'm: 's, T: 'm>(&'c self, mut_ref: &'m mut T) -> (T, Hole<'c, 'm, T, fn() -> T>) {
        fn panic<T>() -> T {
            panic!("Failed to recover a Hole!")
        }
        self.take_and_recover(mut_ref, panic)
    }
}

pub fn scope<'s, F, R>(f: F) -> R
    where F: FnOnce(&Scope<'s>) -> R {
    let this = Scope { active_holes: Cell::new(0), marker: PhantomData };
    let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
        f(&this)
    }));
    if this.active_holes.get() != 0 {
        std::process::abort();
    }
    match result {
        Ok(r) => r,
        Err(p) => panic::resume_unwind(p),
    }

}

#[must_use]
pub struct Hole<'c, 'm, T: 'm, F: FnOnce() -> T> {
    active_holes: &'c Cell<usize>,
    hole: &'m mut T,
    recovery: Option<F>,
}

impl<'c, 'm, T: 'm, F: FnOnce() -> T> Hole<'c, 'm, T, F> {
    pub fn fill(mut self, t: T) {
        use std::ptr;
        use std::mem;

        unsafe {
            ptr::write(self.hole, t);
        }
        let num_holes = self.active_holes.get();
        self.active_holes.set(num_holes - 1);
        mem::forget(self);
    }
}

impl<'c, 'm, T: 'm, F: FnOnce() -> T> Drop for Hole<'c, 'm, T, F> {
    fn drop(&mut self) {
        use std::ptr;
        use std::mem;

        let result = panic::catch_unwind(panic::AssertUnwindSafe(||{
            (self.recovery.take().expect("No recovery function in Hole!"))()
        }));
        match result {
            Ok(t) => {
                unsafe {
                    ptr::write(self.hole, t);
                }
                let num_holes = self.active_holes.get();
                self.active_holes.set(num_holes - 1);
            },
            Err(p) => panic::resume_unwind(p)
        }
    }
}

#[test]
fn scope_based_take() {
    #[derive(Debug)]
    struct Foo;

    #[derive(Debug)]
    struct Bar {
        a: Foo,
        b: Foo
    }
    let mut bar = Bar { a: Foo, b: Foo };
    scope(|scope| {
        let (a, a_hole) = scope.take(&mut bar.a);
        let (b, b_hole) = scope.take(&mut bar.b);
        // Imagine consuming a and b
        a_hole.fill(Foo);
        b_hole.fill(Foo);
    });
    println!("{:?}", &bar);
}<commit_msg>* Remove useless panic catching from `Hole` destructor. Panics in recovery function will cause unfilled Hole to be noted.<commit_after>use std;
use std::panic;
use std::cell::Cell;
use std::marker::PhantomData;

pub struct Scope<'s> {
    active_holes: Cell<usize>,
    marker: PhantomData<Cell<&'s mut ()>>
}

impl<'s> Scope<'s> {

    pub fn take_and_recover<'c, 'm: 's, T: 'm, F: FnOnce() -> T>(&'c self, mut_ref: &'m mut T, recovery: F) -> (T, Hole<'c, 'm, T, F>) {
        use std::ptr;

        let t: T;
        let hole: Hole<'c, 'm, T, F>;
        let num_of_holes = self.active_holes.get();
        if num_of_holes == std::usize::MAX {
            panic!("Too many holes!");
        }
        self.active_holes.set(num_of_holes + 1);
        unsafe {
            t = ptr::read(mut_ref);
            hole = Hole {
                active_holes: &self.active_holes,
                hole: mut_ref,
                recovery: Some(recovery)
            };
        };
        (t, hole)
    }

    pub fn take<'c, 'm: 's, T: 'm>(&'c self, mut_ref: &'m mut T) -> (T, Hole<'c, 'm, T, fn() -> T>) {
        fn panic<T>() -> T {
            panic!("Failed to recover a Hole!")
        }
        self.take_and_recover(mut_ref, panic)
    }
}

pub fn scope<'s, F, R>(f: F) -> R
    where F: FnOnce(&Scope<'s>) -> R {
    let this = Scope { active_holes: Cell::new(0), marker: PhantomData };
    let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
        f(&this)
    }));
    if this.active_holes.get() != 0 {
        std::process::abort();
    }
    match result {
        Ok(r) => r,
        Err(p) => panic::resume_unwind(p),
    }

}

#[must_use]
pub struct Hole<'c, 'm, T: 'm, F: FnOnce() -> T> {
    active_holes: &'c Cell<usize>,
    hole: &'m mut T,
    recovery: Option<F>,
}

impl<'c, 'm, T: 'm, F: FnOnce() -> T> Hole<'c, 'm, T, F> {
    pub fn fill(mut self, t: T) {
        use std::ptr;
        use std::mem;

        unsafe {
            ptr::write(self.hole, t);
        }
        let num_holes = self.active_holes.get();
        self.active_holes.set(num_holes - 1);
        mem::forget(self);
    }
}

impl<'c, 'm, T: 'm, F: FnOnce() -> T> Drop for Hole<'c, 'm, T, F> {
    fn drop(&mut self) {
        use std::ptr;
        use std::mem;

        let t = (self.recovery.take().expect("No recovery function in Hole!"))();
        unsafe {
            ptr::write(self.hole, t);
        }
        let num_holes = self.active_holes.get();
        self.active_holes.set(num_holes - 1);
    }
}

#[test]
fn scope_based_take() {
    #[derive(Debug)]
    struct Foo;

    #[derive(Debug)]
    struct Bar {
        a: Foo,
        b: Foo
    }
    let mut bar = Bar { a: Foo, b: Foo };
    scope(|scope| {
        let (a, a_hole) = scope.take(&mut bar.a);
        let (b, b_hole) = scope.take(&mut bar.b);
        // Imagine consuming a and b
        a_hole.fill(Foo);
        b_hole.fill(Foo);
    });
    println!("{:?}", &bar);
}<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::mem;
use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::thread;

use {spawn_unsafe, FnBox};
use sync::AtomicOption;

pub struct Scope<'a> {
    dtors: RefCell<Option<DtorChain<'a>>>
}

struct DtorChain<'a> {
    dtor: Box<FnBox + 'a>,
    next: Option<Box<DtorChain<'a>>>
}

enum JoinState {
    Running(thread::JoinHandle<()>),
    Joined,
}

impl JoinState {
    fn join(&mut self) {
        let mut state = JoinState::Joined;
        mem::swap(self, &mut state);
        if let JoinState::Running(handle) = state {
            let res = handle.join();

            if !thread::panicking() { res.unwrap(); }
        }
    }
}

pub struct ScopedJoinHandle<T> {
    inner: Rc<RefCell<JoinState>>,
    packet: Arc<AtomicOption<T>>,
    thread: thread::Thread,
}

/// Create a new `scope`, for scoped concurrency operations.
///
/// Using crossbeam for concurrency involves creating a [`Scope`][scope]. That's the job of
/// `scope`.
///
/// [scope]: struct.Scope.html
///
/// # Examples
///
/// Creating a scope:
///
/// ```
/// crossbeam::scope(|scope| {
///     // do stuff with scope here
/// });
/// ```
pub fn scope<'a, F, R>(f: F) -> R where F: FnOnce(&Scope<'a>) -> R {
    let mut scope = Scope { dtors: RefCell::new(None) };
    let ret = f(&scope);
    scope.drop_all();
    ret
}

impl<'a> Scope<'a> {
    // This method is carefully written in a transactional style, so
    // that it can be called directly and, if any dtor panics, can be
    // resumed in the unwinding this causes. By initially running the
    // method outside of any destructor, we avoid any leakage problems
    // due to @rust-lang/rust#14875.
    fn drop_all(&mut self) {
        loop {
            // use a separate scope to ensure that the RefCell borrow
            // is relinquishe before running `dtor`
            let dtor = {
                let mut dtors = self.dtors.borrow_mut();
                if let Some(mut node) = dtors.take() {
                    *dtors = node.next.take().map(|b| *b);
                    node.dtor
                } else {
                    return
                }
            };
            dtor.call_box()
        }
    }

    pub fn defer<F>(&self, f: F) where F: FnOnce() + 'a {
        let mut dtors = self.dtors.borrow_mut();
        *dtors = Some(DtorChain {
            dtor: Box::new(f),
            next: dtors.take().map(Box::new)
        });
    }

    /// Create a scoped thread.
    ///
    /// `spawn` is similar to the [`spawn`][spawn] function in Rust's standard library. The
    /// difference is that this thread is scoped, meaning that it's guaranteed to terminate
    /// before the current stack frame goes away, allowing you to reference the parent stack frame
    /// directly. This is ensured by having the parent thread join on the child thread before the
    /// scope exits.
    ///
    /// [spawn]: http://doc.rust-lang.org/std/thread/fn.spawn.html
    ///
    /// # Examples
    ///
    /// A basic scoped thread:
    ///
    /// ```
    /// crossbeam::scope(|scope| {
    ///     scope.spawn(|| {
    ///         println!("Hello from a scoped thread!");
    ///     });
    /// });
    /// ```
    ///
    /// When writing concurrent Rust programs, you'll sometimes see a pattern like this, using
    /// [`std::thread::spawn`][spawn]:
    ///
    /// ```ignore
    /// let array = [1, 2, 3];
    /// let mut guards = vec![];
    ///
    /// for i in &array {
    ///     let guard = std::thread::spawn(move || {
    ///         println!("element: {}", i);
    ///     });
    ///
    ///     guards.push(guard);
    /// }
    ///
    /// for guard in guards {
    ///     guard.join().unwrap();
    /// }
    /// ```
    ///
    /// The basic pattern is:
    ///
    /// 1. Iterate over some collection.
    /// 2. Spin up a thread to operate on each part of the collection.
    /// 3. Join all the threads.
    ///
    /// However, this code actually gives an error:
    ///
    /// ```text
    /// error: `array` does not live long enough
    /// for i in &array {
    ///           ^~~~~
    /// in expansion of for loop expansion
    /// note: expansion site
    /// note: reference must be valid for the static lifetime...
    /// note: ...but borrowed value is only valid for the block suffix following statement 0 at ...
    ///     let array = [1, 2, 3];
    ///     let mut guards = vec![];
    ///
    ///     for i in &array {
    ///         let guard = std::thread::spawn(move || {
    ///             println!("element: {}", i);
    /// ...
    /// error: aborting due to previous error
    /// ```
    ///
    /// Because [`std::thread::spawn`][spawn] doesn't know about this scope, it requires a
    /// `'static` lifetime. One way of giving it a proper lifetime is to use an [`Arc`][arc]:
    ///
    /// [arc]: http://doc.rust-lang.org/stable/std/sync/struct.Arc.html
    ///
    /// ```
    /// use std::sync::Arc;
    ///
    /// let array = Arc::new([1, 2, 3]);
    /// let mut guards = vec![];
    ///
    /// for i in (0..array.len()) {
    ///     let a = array.clone();
    ///
    ///     let guard = std::thread::spawn(move || {
    ///         println!("element: {}", a[i]);
    ///     });
    ///
    ///     guards.push(guard);
    /// }
    ///
    /// for guard in guards {
    ///     guard.join().unwrap();
    /// }
    /// ```
    ///
    /// But this introduces unnecessary allocation, as `Arc<T>` puts its data on the heap, and we
    /// also end up dealing with reference counts. We know that we're joining the threads before
    /// our function returns, so just taking a reference _should_ be safe. Rust can't know that,
    /// though.
    ///
    /// Enter scoped threads. Here's our original example, using `spawn` from crossbeam rather
    /// than from `std::thread`:
    ///
    /// ```
    /// let array = [1, 2, 3];
    ///
    /// crossbeam::scope(|scope| {
    ///     for i in &array {
    ///         scope.spawn(move || {
    ///             println!("element: {}", i);
    ///         });
    ///     }
    /// });
    /// ```
    ///
    /// Much more straightforward.
    pub fn spawn<F, T>(&self, f: F) -> ScopedJoinHandle<T> where
        F: FnOnce() -> T + Send + 'a, T: Send + 'a
    {
        let their_packet = Arc::new(AtomicOption::new());
        let my_packet = their_packet.clone();

        let join_handle = unsafe {
            spawn_unsafe(move || {
                their_packet.swap(f(), Ordering::Relaxed);
            })
        };

        let thread = join_handle.thread().clone();
        let deferred_handle = Rc::new(RefCell::new(JoinState::Running(join_handle)));
        let my_handle = deferred_handle.clone();

        self.defer(move || {
            let mut state = deferred_handle.borrow_mut();
            state.join();
        });

        ScopedJoinHandle {
            inner: my_handle,
            packet: my_packet,
            thread: thread,
        }
    }
}

impl<T> ScopedJoinHandle<T> {
    pub fn join(self) -> T {
        self.inner.borrow_mut().join();
        self.packet.take(Ordering::Relaxed).unwrap()
    }

    pub fn thread(&self) -> &thread::Thread {
        &self.thread
    }
}

impl<'a> Drop for Scope<'a> {
    fn drop(&mut self) {
        self.drop_all()
    }
}
<commit_msg>Doc improvements around scoped API<commit_after>use std::cell::RefCell;
use std::mem;
use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::thread;

use {spawn_unsafe, FnBox};
use sync::AtomicOption;

pub struct Scope<'a> {
    dtors: RefCell<Option<DtorChain<'a>>>
}

struct DtorChain<'a> {
    dtor: Box<FnBox + 'a>,
    next: Option<Box<DtorChain<'a>>>
}

enum JoinState {
    Running(thread::JoinHandle<()>),
    Joined,
}

impl JoinState {
    fn join(&mut self) {
        let mut state = JoinState::Joined;
        mem::swap(self, &mut state);
        if let JoinState::Running(handle) = state {
            let res = handle.join();

            if !thread::panicking() { res.unwrap(); }
        }
    }
}

/// A handle to a scoped thread
pub struct ScopedJoinHandle<T> {
    inner: Rc<RefCell<JoinState>>,
    packet: Arc<AtomicOption<T>>,
    thread: thread::Thread,
}

/// Create a new `scope`, for deferred destructors.
///
/// Scopes, in particular, support [*scoped thread spaawning*](struct.Scope.html#method.spawn).
///
/// # Examples
///
/// Creating and using a scope:
///
/// ```
/// crossbeam::scope(|scope| {
///     scope.defer(|| println!("Exiting scope"));
///     scope.spawn(|| println!("Running child thread in scope"))
/// });
/// // Prints messages in the reverse order written
/// ```
pub fn scope<'a, F, R>(f: F) -> R where F: FnOnce(&Scope<'a>) -> R {
    let mut scope = Scope { dtors: RefCell::new(None) };
    let ret = f(&scope);
    scope.drop_all();
    ret
}

impl<'a> Scope<'a> {
    // This method is carefully written in a transactional style, so
    // that it can be called directly and, if any dtor panics, can be
    // resumed in the unwinding this causes. By initially running the
    // method outside of any destructor, we avoid any leakage problems
    // due to @rust-lang/rust#14875.
    fn drop_all(&mut self) {
        loop {
            // use a separate scope to ensure that the RefCell borrow
            // is relinquishe before running `dtor`
            let dtor = {
                let mut dtors = self.dtors.borrow_mut();
                if let Some(mut node) = dtors.take() {
                    *dtors = node.next.take().map(|b| *b);
                    node.dtor
                } else {
                    return
                }
            };
            dtor.call_box()
        }
    }

    /// Schedule code to be executed when exiting the scope.
    ///
    /// This is akin to having a destructor on the stack, except that it is
    /// *guaranteed* to be run.
    pub fn defer<F>(&self, f: F) where F: FnOnce() + 'a {
        let mut dtors = self.dtors.borrow_mut();
        *dtors = Some(DtorChain {
            dtor: Box::new(f),
            next: dtors.take().map(Box::new)
        });
    }

    /// Create a scoped thread.
    ///
    /// `spawn` is similar to the [`spawn`][spawn] function in Rust's standard library. The
    /// difference is that this thread is scoped, meaning that it's guaranteed to terminate
    /// before the current stack frame goes away, allowing you to reference the parent stack frame
    /// directly. This is ensured by having the parent thread join on the child thread before the
    /// scope exits.
    ///
    /// [spawn]: http://doc.rust-lang.org/std/thread/fn.spawn.html
    ///
    /// # Examples
    ///
    /// A basic scoped thread:
    ///
    /// ```
    /// crossbeam::scope(|scope| {
    ///     scope.spawn(|| {
    ///         println!("Hello from a scoped thread!");
    ///     });
    /// });
    /// ```
    ///
    /// When writing concurrent Rust programs, you'll sometimes see a pattern like this, using
    /// [`std::thread::spawn`][spawn]:
    ///
    /// ```ignore
    /// let array = [1, 2, 3];
    /// let mut guards = vec![];
    ///
    /// for i in &array {
    ///     let guard = std::thread::spawn(move || {
    ///         println!("element: {}", i);
    ///     });
    ///
    ///     guards.push(guard);
    /// }
    ///
    /// for guard in guards {
    ///     guard.join().unwrap();
    /// }
    /// ```
    ///
    /// The basic pattern is:
    ///
    /// 1. Iterate over some collection.
    /// 2. Spin up a thread to operate on each part of the collection.
    /// 3. Join all the threads.
    ///
    /// However, this code actually gives an error:
    ///
    /// ```text
    /// error: `array` does not live long enough
    /// for i in &array {
    ///           ^~~~~
    /// in expansion of for loop expansion
    /// note: expansion site
    /// note: reference must be valid for the static lifetime...
    /// note: ...but borrowed value is only valid for the block suffix following statement 0 at ...
    ///     let array = [1, 2, 3];
    ///     let mut guards = vec![];
    ///
    ///     for i in &array {
    ///         let guard = std::thread::spawn(move || {
    ///             println!("element: {}", i);
    /// ...
    /// error: aborting due to previous error
    /// ```
    ///
    /// Because [`std::thread::spawn`][spawn] doesn't know about this scope, it requires a
    /// `'static` lifetime. One way of giving it a proper lifetime is to use an [`Arc`][arc]:
    ///
    /// [arc]: http://doc.rust-lang.org/stable/std/sync/struct.Arc.html
    ///
    /// ```
    /// use std::sync::Arc;
    ///
    /// let array = Arc::new([1, 2, 3]);
    /// let mut guards = vec![];
    ///
    /// for i in (0..array.len()) {
    ///     let a = array.clone();
    ///
    ///     let guard = std::thread::spawn(move || {
    ///         println!("element: {}", a[i]);
    ///     });
    ///
    ///     guards.push(guard);
    /// }
    ///
    /// for guard in guards {
    ///     guard.join().unwrap();
    /// }
    /// ```
    ///
    /// But this introduces unnecessary allocation, as `Arc<T>` puts its data on the heap, and we
    /// also end up dealing with reference counts. We know that we're joining the threads before
    /// our function returns, so just taking a reference _should_ be safe. Rust can't know that,
    /// though.
    ///
    /// Enter scoped threads. Here's our original example, using `spawn` from crossbeam rather
    /// than from `std::thread`:
    ///
    /// ```
    /// let array = [1, 2, 3];
    ///
    /// crossbeam::scope(|scope| {
    ///     for i in &array {
    ///         scope.spawn(move || {
    ///             println!("element: {}", i);
    ///         });
    ///     }
    /// });
    /// ```
    ///
    /// Much more straightforward.
    pub fn spawn<F, T>(&self, f: F) -> ScopedJoinHandle<T> where
        F: FnOnce() -> T + Send + 'a, T: Send + 'a
    {
        let their_packet = Arc::new(AtomicOption::new());
        let my_packet = their_packet.clone();

        let join_handle = unsafe {
            spawn_unsafe(move || {
                their_packet.swap(f(), Ordering::Relaxed);
            })
        };

        let thread = join_handle.thread().clone();
        let deferred_handle = Rc::new(RefCell::new(JoinState::Running(join_handle)));
        let my_handle = deferred_handle.clone();

        self.defer(move || {
            let mut state = deferred_handle.borrow_mut();
            state.join();
        });

        ScopedJoinHandle {
            inner: my_handle,
            packet: my_packet,
            thread: thread,
        }
    }
}

impl<T> ScopedJoinHandle<T> {
    /// Join the scoped thread, returning the result it produced.
    pub fn join(self) -> T {
        self.inner.borrow_mut().join();
        self.packet.take(Ordering::Relaxed).unwrap()
    }

    /// Get the underlying thread handle.
    pub fn thread(&self) -> &thread::Thread {
        &self.thread
    }
}

impl<'a> Drop for Scope<'a> {
    fn drop(&mut self) {
        self.drop_all()
    }
}
<|endoftext|>


<commit_before>
/// Hold a score and a scored object in a pair for use with a BinaryHeap.
///
/// MinScored compares in reverse order compared to the score, so that we can
/// use BinaryHeap as a "min-heap" to extract the score, value pair with the
/// lowest score.
///
/// NOTE: MinScored implements a total order (Eq + Ord), so that it is possible
/// to use float types as scores.
pub struct MinScored<K, T>(pub K, pub T);

impl<K: PartialEq, T> PartialEq for MinScored<K, T> {
    #[inline]
    fn eq(&self, other: &MinScored<K, T>) -> bool {
        self.0 == other.0
    }
}

impl<K: PartialEq, T> Eq for MinScored<K, T> {}

impl<K: PartialOrd, T> PartialOrd for MinScored<K, T> {
    #[inline]
    fn partial_cmp(&self, other: &MinScored<K, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<K: PartialOrd + PartialEq, T> Ord for MinScored<K, T> {
    #[inline]
    fn cmp(&self, other: &MinScored<K, T>) -> Ordering {
        // Order NaN first, (NaN is equal to itself and largest)
        let selfnan = self.0 != self.0;
        let othernan = other.0 != other.0;
        if selfnan && othernan {
            Equal
        } else if selfnan {
            Less
        } else if othernan {
            Greater
        // Then order in reverse order
        } else if self.0 < other.0 {
            Greater
        } else if self.0 > other.0 {
            Less
        } else {
            Equal
        }
    }
}

<commit_msg>doc and impl for MinScored<commit_after>
/// **MinScored\<K, T\>** holds a score **K** and a scored object **T** in
/// a pair for use with a **BinaryHeap**.
///
/// MinScored compares in reverse order by the score, so that we can
/// use BinaryHeap as a min-heap to extract the score-value pair with the
/// least score.
///
/// **Note:** MinScored implements a total order (**Ord**), so that it is possible
/// to use float types as scores.
pub struct MinScored<K, T>(pub K, pub T);

impl<K: PartialEq, T> PartialEq for MinScored<K, T> {
    #[inline]
    fn eq(&self, other: &MinScored<K, T>) -> bool {
        self.0 == other.0
    }
}

impl<K: PartialEq, T> Eq for MinScored<K, T> {}

impl<K: PartialOrd, T> PartialOrd for MinScored<K, T> {
    #[inline]
    fn partial_cmp(&self, other: &MinScored<K, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<K: PartialOrd + PartialEq, T> Ord for MinScored<K, T> {
    #[inline]
    fn cmp(&self, other: &MinScored<K, T>) -> Ordering {
        let a = &self.0;
        let b = &other.0;
        if a == b {
            Equal
        } else if a < b {
            Greater
        } else if a > b {
            Less
        } else {
            // these are the NaN cases
            if a != a && b != b {
                Equal
            } else if a != a {
            // Order NaN less, so that it is last in the MinScore order
                Less
            } else {
                Greater
            }
        }
    }
}

<|endoftext|>