<commit_before>//! Two- and three-dimensional array support.

use cl::*;
use cl::ll::*;
use mem::*;
use std::marker::PhantomData;
use std::mem;
use std::vec::Vec;
use libc::{size_t, c_void};

use hl::KernelArg;

pub struct Array3D<T> {
    width: usize,
    height: usize,
    depth: usize,
    dat: Vec<T>
}

pub struct Array3DCL<T> {
    width: usize,
    height: usize,
    depth: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array3D<T> {
    pub fn new<F>(width: usize, height: usize, depth: usize,
                  val: F)
               -> Array3D<T>
        where F: Fn(usize, usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in range(0, width) {
            for y in range(0, height) {
                for z in range(0, depth) {
                    dat.push(val(x, y, z));
                }
            }
        }

        Array3D {
            width: width,
            height: height,
            depth: depth,
            dat: dat
        }
    }

    pub fn set(&mut self, x: usize, y: usize, z: usize, val: T)
    {
        self.dat.as_mut_slice()[self.width*self.height*z + self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize, z: usize) -> T
    {
        (&self.dat[..])[self.width*self.height*z + self.width*y + x].clone()
    }
}

#[unsafe_destructor]
impl<T> Drop for Array3DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array3D<T>, Array3DCL<T>> for &'r Array3D<T>
{
    fn put<F>(&self, f: F)
           -> Array3DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array3DCL{
            width: self.width,
            height: self.height,
            depth: self.depth,
            buf: out,
            phantom: PhantomData,
        }
    }
}

impl<T> Get<Array3DCL<T>, Array3D<T>> for Array3D<T>
{
    fn get<F>(arr: &Array3DCL<T>, f: F)
           -> Array3D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len());
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array3D {
            width: arr.width,
            height: arr.height,
            depth: arr.depth,
            dat: v,
        }
    }
}

impl<T> Write for Array3D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array3D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array3DCL<T> {
    fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height * self.depth
    }
}

impl<T> KernelArg for Array3DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}

pub struct Array2D<T> {
    width: usize,
    height: usize,
    dat: Vec<T>,
}

pub struct Array2DCL<T> {
    width: usize,
    height: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array2D<T> {
    pub fn new<F>(width: usize, height: usize, val: F) -> Array2D<T>
        where F: Fn(usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in range(0, width) {
            for y in range(0, height) {
                dat.push(val(x, y));
            }
        }
        Array2D {
            width: width,
            height: height,
            dat: dat,
        }
    }

    pub fn set(&mut self, x: usize, y: usize, val: T) {
        self.dat.as_mut_slice()[self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize) -> T {
        (&self.dat[..])[self.width*y + x].clone()
    }
}

#[unsafe_destructor]
impl<T> Drop for Array2DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array2D<T>, Array2DCL<T>> for &'r Array2D<T>
{
    fn put<F>(&self, f: F) -> Array2DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array2DCL{
            width: self.width,
            height: self.height,
            buf: out,
            phantom: PhantomData,
        }
    }
}

impl<T> Get<Array2DCL<T>, Array2D<T>> for Array2D<T>
{
    fn get<F>(arr: &Array2DCL<T>, f: F)
           -> Array2D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len())
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array2D {
            width: arr.width,
            height: arr.height,
            dat: v
        }
    }
}

impl<T> Write for Array2D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array2D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array2DCL<T> {
    fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height
    }
}

impl<T> KernelArg for Array2DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}
<commit_msg>upgraded to more recent rust<commit_after>//! Two- and three-dimensional array support.

use cl::*;
use cl::ll::*;
use mem::*;
use std::marker::PhantomData;
use std::mem;
use std::vec::Vec;
use libc::{size_t, c_void};

use hl::KernelArg;

pub struct Array3D<T> {
    width: usize,
    height: usize,
    depth: usize,
    dat: Vec<T>
}

pub struct Array3DCL<T> {
    width: usize,
    height: usize,
    depth: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array3D<T> {
    pub fn new<F>(width: usize, height: usize, depth: usize,
                  val: F)
               -> Array3D<T>
        where F: Fn(usize, usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in 0 .. width {
            for y in 0 .. height {
                for z in 0 .. depth {
                    dat.push(val(x, y, z));
                }
            }
        }

        Array3D {
            width: width,
            height: height,
            depth: depth,
            dat: dat
        }
    }

    pub fn set(&mut self, x: usize, y: usize, z: usize, val: T)
    {
        (&mut self.dat[..])[self.width*self.height*z + self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize, z: usize) -> T
    {
        (&self.dat[..])[self.width*self.height*z + self.width*y + x].clone()
    }
}

#[unsafe_destructor]
impl<T> Drop for Array3DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array3D<T>, Array3DCL<T>> for &'r Array3D<T>
{
    fn put<F>(&self, f: F)
           -> Array3DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array3DCL{
            width: self.width,
            height: self.height,
            depth: self.depth,
            buf: out,
            phantom: PhantomData,
        }
    }
}

impl<T> Get<Array3DCL<T>, Array3D<T>> for Array3D<T>
{
    fn get<F>(arr: &Array3DCL<T>, f: F)
           -> Array3D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len());
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array3D {
            width: arr.width,
            height: arr.height,
            depth: arr.depth,
            dat: v,
        }
    }
}

impl<T> Write for Array3D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array3D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array3DCL<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height * self.depth
    }
}

impl<T> KernelArg for Array3DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}

pub struct Array2D<T> {
    width: usize,
    height: usize,
    dat: Vec<T>,
}

pub struct Array2DCL<T> {
    width: usize,
    height: usize,
    buf: cl_mem,
    phantom: PhantomData<T>,
}

impl<T: Clone> Array2D<T> {
    pub fn new<F>(width: usize, height: usize, val: F) -> Array2D<T>
        where F: Fn(usize, usize) -> T
    {
        let mut dat: Vec<T> = Vec::new();
        for x in 0 .. width {
            for y in 0 .. height {
                dat.push(val(x, y));
            }
        }
        Array2D {
            width: width,
            height: height,
            dat: dat,
        }
    }

    pub fn set(&mut self, x: usize, y: usize, val: T) {
        (&mut self.dat[..])[self.width*y + x] = val;
    }

    pub fn get(&self, x: usize, y: usize) -> T {
        (&self.dat[..])[self.width*y + x].clone()
    }
}

#[unsafe_destructor]
impl<T> Drop for Array2DCL<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.buf);
        }
    }
}

impl<'r, T> Put<Array2D<T>, Array2DCL<T>> for &'r Array2D<T>
{
    fn put<F>(&self, f: F) -> Array2DCL<T>
        where F: FnOnce(*const c_void, size_t) -> cl_mem
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        let out = f(p as *const c_void, (len * mem::size_of::<T>()) as size_t);

        Array2DCL{
            width: self.width,
            height: self.height,
            buf: out,
            phantom: PhantomData,
        }
    }
}

impl<T> Get<Array2DCL<T>, Array2D<T>> for Array2D<T>
{
    fn get<F>(arr: &Array2DCL<T>, f: F)
           -> Array2D<T>
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let mut v: Vec<T> = Vec::with_capacity(arr.len());
        unsafe {
            v.set_len(arr.len())
        }

        let p = v.as_mut_ptr();
        let len = v.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t);

        Array2D {
            width: arr.width,
            height: arr.height,
            dat: v
        }
    }
}

impl<T> Write for Array2D<T> {
    fn write<F>(&self, f: F)
        where F: FnOnce(size_t, *const c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *const c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Read for Array2D<T> {
    fn read<F>(&mut self, f: F)
        where F: FnOnce(size_t, *mut c_void, size_t)
    {
        let p = self.dat.as_ptr();
        let len = self.dat.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

impl<T> Buffer<T> for Array2DCL<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem {
        &self.buf as *const cl_mem
    }

    fn len(&self) -> usize {
        self.width * self.height
    }
}

impl<T> KernelArg for Array2DCL<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        (mem::size_of::<cl_mem>() as size_t,
         unsafe { self.id_ptr() } as *const c_void)
    }
}
<|endoftext|>


<commit_before>//! generic types for GPX

use geo::{Geometry, ToGeo};
use geo::{Bbox, LineString, MultiLineString, Point};

use chrono::DateTime;
use chrono::prelude::Utc;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum GpxVersion {
    Unknown,
    Gpx10,
    Gpx11,
}

impl Default for GpxVersion {
    fn default() -> GpxVersion {
        GpxVersion::Unknown
    }
}

/// Gpx is the root element in the XML file.
#[derive(Clone, Default, Debug)]
pub struct Gpx {
    /// Version of the Gpx file.
    pub version: GpxVersion,

    /// Metadata about the file.
    pub metadata: Option<Metadata>,

    /// A list of waypoints.
    pub waypoints: Vec<Waypoint>,

    /// A list of tracks.
    pub tracks: Vec<Track>,
}

/// Metadata is information about the GPX file, author, and copyright restrictions.
///
/// Providing rich, meaningful information about your GPX files allows others to
/// search for and use your GPS data.
#[derive(Clone, Default, Debug)]
pub struct Metadata {
    /// The name of the GPX file.
    pub name: Option<String>,

    /// A description of the contents of the GPX file.
    pub description: Option<String>,

    /// The person or organization who created the GPX file.
    pub author: Option<Person>,

    /// URLs associated with the location described in the file.
    pub links: Vec<Link>,

    /// The creation date of the file.
    pub time: Option<DateTime<Utc>>,

    /// Keywords associated with the file. Search engines or databases can use
    /// this information to classify the data.
    pub keywords: Option<String>,
    /*copyright: GpxCopyrightType,*/
    /// Bounds for the tracks in the GPX.
    pub bounds: Option<Bbox<f64>>,
    /*extensions: GpxExtensionsType,*/
}

/// Track represents an ordered list of points describing a path.
#[derive(Clone, Default, Debug)]
pub struct Track {
    /// GPS name of track.
    pub name: Option<String>,

    /// GPS comment for track.
    pub comment: Option<String>,

    /// User description of track.
    pub description: Option<String>,

    /// Source of data. Included to give user some idea of reliability
    /// and accuracy of data.
    pub source: Option<String>,

    /// Links to external information about the track.
    pub links: Vec<Link>,

    /// Type (classification) of track.
    pub _type: Option<String>,

    /// A Track Segment holds a list of Track Points which are logically
    /// connected in order. To represent a single GPS track where GPS reception
    /// was lost, or the GPS receiver was turned off, start a new Track Segment
    /// for each continuous span of track data.
    pub segments: Vec<TrackSegment>,
    /* pub number: u8,*/
    /* extensions */
    /* trkSeg */
}

impl Track {
    /// Gives the multi-linestring that this track represents, which is multiple
    /// linestrings.
    pub fn multilinestring(&self) -> MultiLineString<f64> {
        self.segments.iter().map(|seg| seg.linestring()).collect()
    }

    /// Creates a new Track with default values.
    ///
    /// ```
    /// use gpx::{Track, TrackSegment};
    ///
    /// let mut track: Track = Track::new();
    ///
    /// let segment = TrackSegment::new();
    /// track.segments.push(segment);
    pub fn new() -> Track {
        Default::default()
    }
}

impl ToGeo<f64> for Track {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::MultiLineString(self.multilinestring())
    }
}

/// TrackSegment represents a list of track points.
///
/// This TrackSegment holds a list of Track Points which are logically
/// connected in order. To represent a single GPS track where GPS reception
/// was lost, or the GPS receiver was turned off, start a new Track Segment
/// for each continuous span of track data.
#[derive(Clone, Default, Debug)]
pub struct TrackSegment {
    /// Each Waypoint holds the coordinates, elevation, timestamp, and metadata
    /// for a single point in a track.
    pub points: Vec<Waypoint>,
    /* extensions */
}

impl TrackSegment {
    /// Gives the linestring of the segment's points, the sequence of points that
    /// comprises the track segment.
    pub fn linestring(&self) -> LineString<f64> {
        self.points.iter().map(|wpt| wpt.point()).collect()
    }

    /// Creates a new TrackSegment with default values.
    ///
    /// ```
    /// extern crate gpx;
    /// extern crate geo;
    ///
    /// use gpx::{TrackSegment, Waypoint};
    /// use geo::Point;
    ///
    /// fn main() {
    ///     let mut trkseg: TrackSegment = TrackSegment::new();
    ///
    ///     let point = Waypoint::new(Point::new(-121.97, 37.24));
    ///     trkseg.points.push(point);
    /// }
    pub fn new() -> TrackSegment {
        Default::default()
    }
}

impl ToGeo<f64> for TrackSegment {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::LineString(self.linestring())
    }
}

/// Waypoint represents a waypoint, point of interest, or named feature on a
/// map.
#[derive(Clone, Debug)]
pub struct Waypoint {
    /// The geographical point.
    point: Point<f64>,

    /// Elevation (in meters) of the point.
    pub elevation: Option<f64>,

    /// Speed (in meters per second) (only in GPX 1.0)
    pub speed: Option<f64>,

    /// Creation/modification timestamp for element. Date and time in are in
    /// Univeral Coordinated Time (UTC), not local time! Conforms to ISO 8601
    /// specification for date/time representation. Fractional seconds are
    /// allowed for millisecond timing in tracklogs.
    pub time: Option<DateTime<Utc>>,

    /// The GPS name of the waypoint. This field will be transferred to and
    /// from the GPS. GPX does not place restrictions on the length of this
    /// field or the characters contained in it. It is up to the receiving
    /// application to validate the field before sending it to the GPS.
    pub name: Option<String>,

    /// GPS waypoint comment. Sent to GPS as comment.
    pub comment: Option<String>,

    /// A text description of the element. Holds additional information about
    /// the element intended for the user, not the GPS.
    pub description: Option<String>,

    /// Source of data. Included to give user some idea of reliability and
    /// accuracy of data. "Garmin eTrex", "USGS quad Boston North", e.g.
    pub source: Option<String>,

    /// Links to additional information about the waypoint.
    pub links: Vec<Link>,

    /// Text of GPS symbol name. For interchange with other programs, use the
    /// exact spelling of the symbol as displayed on the GPS. If the GPS
    /// abbreviates words, spell them out.
    pub symbol: Option<String>,

    /// Type (classification) of the waypoint.
    pub _type: Option<String>,

    // <magvar> degreesType </magvar> [0..1] ?
    // <geoidheight> xsd:decimal </geoidheight> [0..1] ?
    /// Type of GPS fix. `none` means GPS had no fix. To signify "the fix info
    /// is unknown", leave out `fix` entirely. Value comes from the list
    /// `{'none'|'2d'|'3d'|'dgps'|'pps'}`, where `pps` means that the military
    /// signal was used.
    pub fix: Option<Fix>,

    /// Number of satellites used to calculate the GPX fix.
    pub sat: Option<u64>,

    /// Horizontal dilution of precision.
    pub hdop: Option<f64>,

    /// Vertical dilution of precision.
    pub vdop: Option<f64>,

    /// Positional dilution of precision.
    pub pdop: Option<f64>,

    /// Number of seconds since last DGPS update, from the <ageofgpsdata> element.
    pub age: Option<f64>,

    /// ID of DGPS station used in differential correction, in the range [0, 1023].
    pub dgpsid: Option<u16>,
    // <extensions> extensionsType </extensions> [0..1] ?
}

impl Waypoint {
    /// Gives the geographical point of the waypoint.
    ///
    /// ```
    /// extern crate geo;
    /// extern crate gpx;
    ///
    /// use gpx::Waypoint;
    /// use geo::Point;
    ///
    /// fn main() {
    ///     // Kind of useless, but it shows the point.
    ///     let wpt = Waypoint::new(Point::new(-121.97, 37.24));
    ///     let point = wpt.point();
    ///
    ///     println!("waypoint latitude: {}, longitude: {}", point.lat(), point.lng());
    /// }
    /// ```
    pub fn point(&self) -> Point<f64> {
        self.point
    }

    /// Creates a new Waypoint from a given geographical point.
    ///
    /// ```
    /// extern crate geo;
    /// extern crate gpx;
    ///
    /// use gpx::Waypoint;
    /// use geo::Point;
    ///
    /// fn main() {
    ///     let point = Point::new(-121.97, 37.24);
    ///
    ///     let mut wpt = Waypoint::new(point);
    ///     wpt.elevation = Some(553.21);
    /// }
    /// ```
    pub fn new(point: Point<f64>) -> Waypoint {
        // Unfortunately we don't have an easy way to write this.
        Waypoint {
            point: point,
            elevation: None,
            speed: None,
            time: None,
            name: None,
            comment: None,
            description: None,
            source: None,
            links: vec![],
            symbol: None,
            _type: None,
            fix: None,
            sat: None,
            hdop: None,
            vdop: None,
            pdop: None,
            age: None,
            dgpsid: None,
        }
    }
}

impl ToGeo<f64> for Waypoint {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::Point(self.point())
    }
}

/// Person represents a person or organization.
#[derive(Clone, Default, Debug)]
pub struct Person {
    /// Name of person or organization.
    pub name: Option<String>,

    /// Email address.
    pub email: Option<String>,

    /// Link to Web site or other external information about person.
    pub link: Option<Link>,
}

/// Link represents a link to an external resource.
///
/// An external resource could be a web page, digital photo,
/// video clip, etc., with additional information.
#[derive(Clone, Default, Debug)]
pub struct Link {
    /// URL of hyperlink.
    pub href: String,

    /// Text of hyperlink.
    pub text: Option<String>,

    /// Mime type of content (image/jpeg)
    pub _type: Option<String>,
}

/// Type of the GPS fix.
#[derive(Clone, Debug, PartialEq)]
pub enum Fix {
    /// The GPS had no fix. To signify "the fix info is unknown", leave out the Fix entirely.
    None,
    /// 2D fix gives only longitude and latitude. It needs a minimum of 3 satellites.
    TwoDimensional,
    /// 3D fix gives longitude, latitude and altitude. It needs a minimum of 4 satellites.
    ThreeDimensional,
    /// Differential Global Positioning System.
    DGPS,
    /// Military signal.
    PPS,
    /// Other values that are not in the specification.
    Other(String),
}
<commit_msg>Work around geo::Point not having impl Default - Use custom OwnPoint type encapsulating geo::Point, and implement Default   for this. - Use OwnPoint instead of geo::Point in Waypoint struct<commit_after>//! generic types for GPX

use geo::{Geometry, ToGeo};
use geo::{Bbox, LineString, MultiLineString, Point};

use chrono::DateTime;
use chrono::prelude::Utc;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum GpxVersion {
    Unknown,
    Gpx10,
    Gpx11,
}

impl Default for GpxVersion {
    fn default() -> GpxVersion {
        GpxVersion::Unknown
    }
}

/// Gpx is the root element in the XML file.
#[derive(Clone, Default, Debug)]
pub struct Gpx {
    /// Version of the Gpx file.
    pub version: GpxVersion,

    /// Metadata about the file.
    pub metadata: Option<Metadata>,

    /// A list of waypoints.
    pub waypoints: Vec<Waypoint>,

    /// A list of tracks.
    pub tracks: Vec<Track>,
}

/// Metadata is information about the GPX file, author, and copyright restrictions.
///
/// Providing rich, meaningful information about your GPX files allows others to
/// search for and use your GPS data.
#[derive(Clone, Default, Debug)]
pub struct Metadata {
    /// The name of the GPX file.
    pub name: Option<String>,

    /// A description of the contents of the GPX file.
    pub description: Option<String>,

    /// The person or organization who created the GPX file.
    pub author: Option<Person>,

    /// URLs associated with the location described in the file.
    pub links: Vec<Link>,

    /// The creation date of the file.
    pub time: Option<DateTime<Utc>>,

    /// Keywords associated with the file. Search engines or databases can use
    /// this information to classify the data.
    pub keywords: Option<String>,
    /*copyright: GpxCopyrightType,*/
    /// Bounds for the tracks in the GPX.
    pub bounds: Option<Bbox<f64>>,
    /*extensions: GpxExtensionsType,*/
}

/// Track represents an ordered list of points describing a path.
#[derive(Clone, Default, Debug)]
pub struct Track {
    /// GPS name of track.
    pub name: Option<String>,

    /// GPS comment for track.
    pub comment: Option<String>,

    /// User description of track.
    pub description: Option<String>,

    /// Source of data. Included to give user some idea of reliability
    /// and accuracy of data.
    pub source: Option<String>,

    /// Links to external information about the track.
    pub links: Vec<Link>,

    /// Type (classification) of track.
    pub _type: Option<String>,

    /// A Track Segment holds a list of Track Points which are logically
    /// connected in order. To represent a single GPS track where GPS reception
    /// was lost, or the GPS receiver was turned off, start a new Track Segment
    /// for each continuous span of track data.
    pub segments: Vec<TrackSegment>,
    /* pub number: u8,*/
    /* extensions */
    /* trkSeg */
}

impl Track {
    /// Gives the multi-linestring that this track represents, which is multiple
    /// linestrings.
    pub fn multilinestring(&self) -> MultiLineString<f64> {
        self.segments.iter().map(|seg| seg.linestring()).collect()
    }

    /// Creates a new Track with default values.
    ///
    /// ```
    /// use gpx::{Track, TrackSegment};
    ///
    /// let mut track: Track = Track::new();
    ///
    /// let segment = TrackSegment::new();
    /// track.segments.push(segment);
    pub fn new() -> Track {
        Default::default()
    }
}

impl ToGeo<f64> for Track {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::MultiLineString(self.multilinestring())
    }
}

/// TrackSegment represents a list of track points.
///
/// This TrackSegment holds a list of Track Points which are logically
/// connected in order. To represent a single GPS track where GPS reception
/// was lost, or the GPS receiver was turned off, start a new Track Segment
/// for each continuous span of track data.
#[derive(Clone, Default, Debug)]
pub struct TrackSegment {
    /// Each Waypoint holds the coordinates, elevation, timestamp, and metadata
    /// for a single point in a track.
    pub points: Vec<Waypoint>,
    /* extensions */
}

impl TrackSegment {
    /// Gives the linestring of the segment's points, the sequence of points that
    /// comprises the track segment.
    pub fn linestring(&self) -> LineString<f64> {
        self.points.iter().map(|wpt| wpt.point()).collect()
    }

    /// Creates a new TrackSegment with default values.
    ///
    /// ```
    /// extern crate gpx;
    /// extern crate geo;
    ///
    /// use gpx::{TrackSegment, Waypoint};
    /// use geo::Point;
    ///
    /// fn main() {
    ///     let mut trkseg: TrackSegment = TrackSegment::new();
    ///
    ///     let point = Waypoint::new(Point::new(-121.97, 37.24));
    ///     trkseg.points.push(point);
    /// }
    pub fn new() -> TrackSegment {
        Default::default()
    }
}

impl ToGeo<f64> for TrackSegment {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::LineString(self.linestring())
    }
}

// A Version of geo::Point that has the Default trait implemented
#[derive(Clone, Debug)]
struct OurPoint {
    point: Point<f64>,
}

impl Default for OurPoint {
    fn default() -> OurPoint {
        OurPoint {
            point: Point::new(0 as f64, 0 as f64),
        }
    }
}

/// Waypoint represents a waypoint, point of interest, or named feature on a
/// map.
#[derive(Clone, Default, Debug)]
pub struct Waypoint {
    /// The geographical point.
    point: OurPoint,

    /// Elevation (in meters) of the point.
    pub elevation: Option<f64>,

    /// Speed (in meters per second) (only in GPX 1.0)
    pub speed: Option<f64>,

    /// Creation/modification timestamp for element. Date and time in are in
    /// Univeral Coordinated Time (UTC), not local time! Conforms to ISO 8601
    /// specification for date/time representation. Fractional seconds are
    /// allowed for millisecond timing in tracklogs.
    pub time: Option<DateTime<Utc>>,

    /// The GPS name of the waypoint. This field will be transferred to and
    /// from the GPS. GPX does not place restrictions on the length of this
    /// field or the characters contained in it. It is up to the receiving
    /// application to validate the field before sending it to the GPS.
    pub name: Option<String>,

    /// GPS waypoint comment. Sent to GPS as comment.
    pub comment: Option<String>,

    /// A text description of the element. Holds additional information about
    /// the element intended for the user, not the GPS.
    pub description: Option<String>,

    /// Source of data. Included to give user some idea of reliability and
    /// accuracy of data. "Garmin eTrex", "USGS quad Boston North", e.g.
    pub source: Option<String>,

    /// Links to additional information about the waypoint.
    pub links: Vec<Link>,

    /// Text of GPS symbol name. For interchange with other programs, use the
    /// exact spelling of the symbol as displayed on the GPS. If the GPS
    /// abbreviates words, spell them out.
    pub symbol: Option<String>,

    /// Type (classification) of the waypoint.
    pub _type: Option<String>,

    // <magvar> degreesType </magvar> [0..1] ?
    // <geoidheight> xsd:decimal </geoidheight> [0..1] ?
    /// Type of GPS fix. `none` means GPS had no fix. To signify "the fix info
    /// is unknown", leave out `fix` entirely. Value comes from the list
    /// `{'none'|'2d'|'3d'|'dgps'|'pps'}`, where `pps` means that the military
    /// signal was used.
    pub fix: Option<Fix>,

    /// Number of satellites used to calculate the GPX fix.
    pub sat: Option<u64>,

    /// Horizontal dilution of precision.
    pub hdop: Option<f64>,

    /// Vertical dilution of precision.
    pub vdop: Option<f64>,

    /// Positional dilution of precision.
    pub pdop: Option<f64>,

    /// Number of seconds since last DGPS update, from the <ageofgpsdata> element.
    pub age: Option<f64>,

    /// ID of DGPS station used in differential correction, in the range [0, 1023].
    pub dgpsid: Option<u16>,
    // <extensions> extensionsType </extensions> [0..1] ?
}

impl Waypoint {
    /// Gives the geographical point of the waypoint.
    ///
    /// ```
    /// extern crate geo;
    /// extern crate gpx;
    ///
    /// use gpx::Waypoint;
    /// use geo::Point;
    ///
    /// fn main() {
    ///     // Kind of useless, but it shows the point.
    ///     let wpt = Waypoint::new(Point::new(-121.97, 37.24));
    ///     let point = wpt.point();
    ///
    ///     println!("waypoint latitude: {}, longitude: {}", point.lat(), point.lng());
    /// }
    /// ```
    pub fn point(&self) -> Point<f64> {
        self.point.point
    }

    /// Creates a new Waypoint from a given geographical point.
    ///
    /// ```
    /// extern crate geo;
    /// extern crate gpx;
    ///
    /// use gpx::Waypoint;
    /// use geo::Point;
    ///
    /// fn main() {
    ///     let point = Point::new(-121.97, 37.24);
    ///
    ///     let mut wpt = Waypoint::new(point);
    ///     wpt.elevation = Some(553.21);
    /// }
    /// ```
    pub fn new(point: Point<f64>) -> Waypoint {
        Waypoint {
            point: OurPoint { point },
            ..Default::default()
        }
    }
}

impl ToGeo<f64> for Waypoint {
    fn to_geo(&self) -> Geometry<f64> {
        Geometry::Point(self.point())
    }
}

/// Person represents a person or organization.
#[derive(Clone, Default, Debug)]
pub struct Person {
    /// Name of person or organization.
    pub name: Option<String>,

    /// Email address.
    pub email: Option<String>,

    /// Link to Web site or other external information about person.
    pub link: Option<Link>,
}

/// Link represents a link to an external resource.
///
/// An external resource could be a web page, digital photo,
/// video clip, etc., with additional information.
#[derive(Clone, Default, Debug)]
pub struct Link {
    /// URL of hyperlink.
    pub href: String,

    /// Text of hyperlink.
    pub text: Option<String>,

    /// Mime type of content (image/jpeg)
    pub _type: Option<String>,
}

/// Type of the GPS fix.
#[derive(Clone, Debug, PartialEq)]
pub enum Fix {
    /// The GPS had no fix. To signify "the fix info is unknown", leave out the Fix entirely.
    None,
    /// 2D fix gives only longitude and latitude. It needs a minimum of 3 satellites.
    TwoDimensional,
    /// 3D fix gives longitude, latitude and altitude. It needs a minimum of 4 satellites.
    ThreeDimensional,
    /// Differential Global Positioning System.
    DGPS,
    /// Military signal.
    PPS,
    /// Other values that are not in the specification.
    Other(String),
}
<|endoftext|>


<commit_before>use std::hash;
use std::hash::Hash;
use std::int::MAX;
use std::num::Int;
use std::result::Result;

trait FpFn {
    // Fixed-point Function.
    //
    /// The Self type need not be stateful at all.
    ///
    /// Instead, a FpFn exposes its state (abstractly) to the loop
    /// that contains it.  There are two parts:
    //
    ///  - The loop iteration's current state (type `St`)
    //
    ///  - Any "meta-state" needed to explore the space of states
    ///  (type `Sys`)
    //
    /// Our fixed-point loop needs a way of hashing the "current
    /// state" (type `St`).  The details of what states are and how
    /// they relate need not be revealed.  We hide all of these
    /// details in a "state system" (type `Sys`).  `next` checks for
    /// unstepped states to become the "current state", or returns Err
    /// if no unexplored states exist.  `step` updates the system at
    /// the "current state".

    type St : Hash ;
    type Sys ;
    fn step (self:& Self, st:Self::St, sys:Self::Sys) -> Self::Sys ;
    fn next (self:& Self, sys:Self::Sys) -> Result<(Self::St, Self::Sys), Self::Sys> ;
}

trait FpLp<F:FpFn> {
    fn work_tree (self:&Self, f:&F, left_lev:int, sys:F::Sys, parent_lev:int) -> F::Sys {
        let nxt = f.next(sys) ;
        match nxt {
            Err(sys) => sys,
            Ok((st,sys)) => {
                let st_lev = Int::trailing_zeros(hash::hash(&st)) as int ;
                if ( left_lev <= st_lev &&
                     st_lev   <= parent_lev )
                {
                    let sys : F::Sys = f.step(st, sys) ;
                    let sys : F::Sys = self.work_tree (f, -1,     sys, st_lev );
                    let sys : F::Sys = self.work_tree (f, st_lev, sys, parent_lev );
                    sys
                }
                else {
                    sys
                }
            }
        }
    }
    fn compute (self:&Self, f:&F, sys:F::Sys) -> F::Sys {
        self.work_tree (f, -1, sys, MAX )
    }
}
<commit_msg>exposing tree structure of balfp, abstractly<commit_after>use std::hash;
use std::hash::Hash;
use std::int::MAX;
use std::num::Int;
use std::result::Result;

trait FpFn {
    // Fixed-point Function.
    //
    /// The Self type need not be stateful at all.
    ///
    /// Instead, a FpFn exposes its state (abstractly) to the loop
    /// that contains it.  There are two parts:
    //
    ///  - The loop iteration's current state (type `St`)
    //
    ///  - Any "meta-state" needed to explore the space of states
    ///  (type `Sys`)
    //
    /// Our fixed-point loop needs a way of hashing the "current
    /// state" (type `St`).  The details of what states are and how
    /// they relate need not be revealed.  We hide all of these
    /// details in a "state system" (type `Sys`).  `next` checks for
    /// unstepped states to become the "current state", or returns Err
    /// if no unexplored states exist.  `step` updates the system at
    /// the "current state".

    type St : Hash ;
    type Sys ;
    fn step (self:& Self, st:Self::St, sys:Self::Sys) -> Self::Sys ;
    fn next (self:& Self, sys:Self::Sys) -> Result<(Self::St, Self::Sys), Self::Sys> ;
}

trait BuildTree<T> {
    fn leaf(data:&T) -> Self;
    fn bin(left:Self,data:&T,right:Self) -> Self;
}

trait FpLp<F:FpFn, BT:BuildTree<F::St>> {
    fn work_tree (self:&Self, f:&F, left_lev:int, sys:F::Sys, parent_lev:int) -> F::Sys {
        let nxt = f.next(sys) ;
        match nxt {
            Err(sys) => sys,
            Ok((st,sys)) => {
                let st_lev = Int::trailing_zeros(hash::hash(&st)) as int ;
                if ( left_lev <= st_lev &&
                     st_lev   <= parent_lev )
                {
                    let sys : F::Sys = f.step(st, sys) ;
                    let sys : F::Sys = self.work_tree (f, -1,     sys, st_lev );
                    let sys : F::Sys = self.work_tree (f, st_lev, sys, parent_lev );
                    sys
                }
                else {
                    sys
                }
            }
        }
    }
    fn compute (self:&Self, f:&F, sys:F::Sys) -> F::Sys {
        self.work_tree (f, -1, sys, MAX )
    }
}
<|endoftext|>


<commit_before>use bytes::{Buf, Bytes};
use futures::stream;
use futures::sync::mpsc;
use futures::{Async, AsyncSink, Future, Poll, Sink, Stream};
use std::io::{self, BufRead, Cursor, Read};
use std::marker::PhantomData;
use tokio_postgres::types::{ToSql, Type};
use tokio_postgres::{Error, Row};
#[cfg(feature = "runtime")]
use tokio_postgres::{MakeTlsMode, Socket, TlsMode};

#[cfg(feature = "runtime")]
use crate::Builder;
use crate::{Query, Statement, Transaction};

pub struct Client(tokio_postgres::Client);

impl Client {
    #[cfg(feature = "runtime")]
    pub fn connect<T>(params: &str, tls_mode: T) -> Result<Client, Error>
    where
        T: MakeTlsMode<Socket> + 'static + Send,
        T::TlsMode: Send,
        T::Stream: Send,
        T::Future: Send,
        <T::TlsMode as TlsMode<Socket>>::Future: Send,
    {
        params.parse::<Builder>()?.connect(tls_mode)
    }

    #[cfg(feature = "runtime")]
    pub fn builder() -> Builder {
        Builder::new()
    }

    pub fn prepare(&mut self, query: &str) -> Result<Statement, Error> {
        self.0.prepare(query).wait().map(Statement)
    }

    pub fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result<Statement, Error> {
        self.0.prepare_typed(query, types).wait().map(Statement)
    }

    pub fn execute<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<u64, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        self.0.execute(&statement.0, params).wait()
    }

    pub fn query<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<Vec<Row>, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        self.0.query(&statement.0, params).collect().wait()
    }

    pub fn copy_in<T, R>(
        &mut self,
        query: &T,
        params: &[&dyn ToSql],
        reader: R,
    ) -> Result<u64, Error>
    where
        T: ?Sized + Query,
        R: Read,
    {
        let statement = query.__statement(self)?;
        let (sender, receiver) = mpsc::channel(1);
        let future = self.0.copy_in(&statement.0, params, CopyInStream(receiver));

        CopyInFuture {
            future,
            sender,
            reader,
            pending: None,
            done: false,
        }
        .wait()
    }

    pub fn copy_out<T>(
        &mut self,
        query: &T,
        params: &[&dyn ToSql],
    ) -> Result<CopyOutReader<'_>, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        let mut stream = self.0.copy_out(&statement.0, params).wait();

        let cur = match stream.next() {
            Some(Ok(cur)) => cur,
            Some(Err(e)) => return Err(e),
            None => Bytes::new(),
        };

        Ok(CopyOutReader {
            stream,
            cur: Cursor::new(cur),
            _p: PhantomData,
        })
    }

    pub fn batch_execute(&mut self, query: &str) -> Result<(), Error> {
        self.0.batch_execute(query).wait()
    }

    pub fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
        self.batch_execute("BEGIN")?;
        Ok(Transaction::new(self))
    }

    pub fn is_closed(&self) -> bool {
        self.0.is_closed()
    }
}

impl From<tokio_postgres::Client> for Client {
    fn from(c: tokio_postgres::Client) -> Client {
        Client(c)
    }
}

enum CopyData {
    Data(Vec<u8>),
    Error(io::Error),
    Done,
}

struct CopyInStream(mpsc::Receiver<CopyData>);

impl Stream for CopyInStream {
    type Item = Vec<u8>;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Vec<u8>>, io::Error> {
        match self.0.poll().expect("mpsc::Receiver can't error") {
            Async::Ready(Some(CopyData::Data(buf))) => Ok(Async::Ready(Some(buf))),
            Async::Ready(Some(CopyData::Error(e))) => Err(e),
            Async::Ready(Some(CopyData::Done)) => Ok(Async::Ready(None)),
            Async::Ready(None) => Err(io::Error::new(io::ErrorKind::Other, "writer disconnected")),
            Async::NotReady => Ok(Async::NotReady),
        }
    }
}

struct CopyInFuture<R> {
    future: tokio_postgres::CopyIn<CopyInStream>,
    sender: mpsc::Sender<CopyData>,
    reader: R,
    pending: Option<CopyData>,
    done: bool,
}

impl<R> Future for CopyInFuture<R>
where
    R: Read,
{
    type Item = u64;
    type Error = Error;

    fn poll(&mut self) -> Poll<u64, Error> {
        loop {
            if let Async::Ready(n) = self.future.poll()? {
                return Ok(Async::Ready(n));
            }

            let data = match self.pending.take() {
                Some(pending) => pending,
                None => {
                    if self.done {
                        continue;
                    }

                    let mut buf = vec![];
                    match self.reader.by_ref().take(4096).read_to_end(&mut buf) {
                        Ok(0) => {
                            self.done = true;
                            CopyData::Done
                        }
                        Ok(_) => CopyData::Data(buf),
                        Err(e) => {
                            self.done = true;
                            CopyData::Error(e)
                        }
                    }
                }
            };

            match self.sender.start_send(data) {
                Ok(AsyncSink::Ready) => {}
                Ok(AsyncSink::NotReady(pending)) => {
                    self.pending = Some(pending);
                    return Ok(Async::NotReady);
                }
                // the future's hung up on its end of the channel, so we'll wait for it to error
                Err(_) => {
                    self.done = true;
                    return Ok(Async::NotReady);
                }
            }
        }
    }
}

pub struct CopyOutReader<'a> {
    stream: stream::Wait<tokio_postgres::CopyOut>,
    cur: Cursor<Bytes>,
    _p: PhantomData<&'a mut ()>,
}

// no-op impl to extend borrow until drop
impl<'a> Drop for CopyOutReader<'a> {
    fn drop(&mut self) {}
}

impl<'a> Read for CopyOutReader<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let b = self.fill_buf()?;
        let len = usize::min(buf.len(), b.len());
        buf[..len].copy_from_slice(&b[..len]);
        self.consume(len);
        Ok(len)
    }
}

impl<'a> BufRead for CopyOutReader<'a> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.cur.remaining() == 0 {
            match self.stream.next() {
                Some(Ok(cur)) => self.cur = Cursor::new(cur),
                Some(Err(e)) => return Err(io::Error::new(io::ErrorKind::Other, e)),
                None => {}
            };
        }

        Ok(Buf::bytes(&self.cur))
    }

    fn consume(&mut self, amt: usize) {
        self.cur.advance(amt);
    }
}
<commit_msg>Simplify sync copy_in<commit_after>use bytes::{Buf, Bytes};
use futures::stream;
use futures::{Async, Future, Poll, Stream};
use std::io::{self, BufRead, Cursor, Read};
use std::marker::PhantomData;
use tokio_postgres::types::{ToSql, Type};
use tokio_postgres::{Error, Row};
#[cfg(feature = "runtime")]
use tokio_postgres::{MakeTlsMode, Socket, TlsMode};

#[cfg(feature = "runtime")]
use crate::Builder;
use crate::{Query, Statement, Transaction};

pub struct Client(tokio_postgres::Client);

impl Client {
    #[cfg(feature = "runtime")]
    pub fn connect<T>(params: &str, tls_mode: T) -> Result<Client, Error>
    where
        T: MakeTlsMode<Socket> + 'static + Send,
        T::TlsMode: Send,
        T::Stream: Send,
        T::Future: Send,
        <T::TlsMode as TlsMode<Socket>>::Future: Send,
    {
        params.parse::<Builder>()?.connect(tls_mode)
    }

    #[cfg(feature = "runtime")]
    pub fn builder() -> Builder {
        Builder::new()
    }

    pub fn prepare(&mut self, query: &str) -> Result<Statement, Error> {
        self.0.prepare(query).wait().map(Statement)
    }

    pub fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result<Statement, Error> {
        self.0.prepare_typed(query, types).wait().map(Statement)
    }

    pub fn execute<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<u64, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        self.0.execute(&statement.0, params).wait()
    }

    pub fn query<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<Vec<Row>, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        self.0.query(&statement.0, params).collect().wait()
    }

    pub fn copy_in<T, R>(
        &mut self,
        query: &T,
        params: &[&dyn ToSql],
        reader: R,
    ) -> Result<u64, Error>
    where
        T: ?Sized + Query,
        R: Read,
    {
        let statement = query.__statement(self)?;
        self.0
            .copy_in(&statement.0, params, CopyInStream(reader))
            .wait()
    }

    pub fn copy_out<T>(
        &mut self,
        query: &T,
        params: &[&dyn ToSql],
    ) -> Result<CopyOutReader<'_>, Error>
    where
        T: ?Sized + Query,
    {
        let statement = query.__statement(self)?;
        let mut stream = self.0.copy_out(&statement.0, params).wait();

        let cur = match stream.next() {
            Some(Ok(cur)) => cur,
            Some(Err(e)) => return Err(e),
            None => Bytes::new(),
        };

        Ok(CopyOutReader {
            stream,
            cur: Cursor::new(cur),
            _p: PhantomData,
        })
    }

    pub fn batch_execute(&mut self, query: &str) -> Result<(), Error> {
        self.0.batch_execute(query).wait()
    }

    pub fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
        self.batch_execute("BEGIN")?;
        Ok(Transaction::new(self))
    }

    pub fn is_closed(&self) -> bool {
        self.0.is_closed()
    }
}

impl From<tokio_postgres::Client> for Client {
    fn from(c: tokio_postgres::Client) -> Client {
        Client(c)
    }
}

struct CopyInStream<R>(R);

impl<R> Stream for CopyInStream<R>
where
    R: Read,
{
    type Item = Vec<u8>;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Vec<u8>>, io::Error> {
        let mut buf = vec![];
        match self.0.by_ref().take(4096).read_to_end(&mut buf)? {
            0 => Ok(Async::Ready(None)),
            _ => Ok(Async::Ready(Some(buf))),
        }
    }
}

pub struct CopyOutReader<'a> {
    stream: stream::Wait<tokio_postgres::CopyOut>,
    cur: Cursor<Bytes>,
    _p: PhantomData<&'a mut ()>,
}

// no-op impl to extend borrow until drop
impl<'a> Drop for CopyOutReader<'a> {
    fn drop(&mut self) {}
}

impl<'a> Read for CopyOutReader<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let b = self.fill_buf()?;
        let len = usize::min(buf.len(), b.len());
        buf[..len].copy_from_slice(&b[..len]);
        self.consume(len);
        Ok(len)
    }
}

impl<'a> BufRead for CopyOutReader<'a> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.cur.remaining() == 0 {
            match self.stream.next() {
                Some(Ok(cur)) => self.cur = Cursor::new(cur),
                Some(Err(e)) => return Err(io::Error::new(io::ErrorKind::Other, e)),
                None => {}
            };
        }

        Ok(Buf::bytes(&self.cur))
    }

    fn consume(&mut self, amt: usize) {
        self.cur.advance(amt);
    }
}
<|endoftext|>


<commit_before>use time::{Duration, PreciseTime};

use vec3::Vec3;
use camera::Camera;

// Benchmarks sample scene
// Prints iteration execution time and average
pub fn bench_rays_per_sec<F>(n: i32) {
    let mut runs: Vec<f64> = Vec::new();
    for _ in 0..n {
        let bench_params = (100, 50, 5);
        let (_, runtime) = time(|| {
            bench_scene(bench_params.0, bench_params.1, bench_params.2)
        });
        let rays = bench_params.0 * bench_params.1 * bench_params.2;
        let rays_per_sec = rays as f64 / runtime;
        println!("{} rays in {} sec, {:.2} rays/sec", rays, runtime, rays_per_sec);
        runs.push(rays_per_sec);
    }
    println!("Avg: {:.2} rays/sec from {} runs", runs.iter().sum::<f64>() / (runs.len() as f64), runs.len());

}

// Run function and return result with seconds duration
pub fn time<F, T>(f: F) -> (T, f64)
    where F: FnOnce() -> T {
    let start = PreciseTime::now();
    let res = f();
    let end = PreciseTime::now();

    let runtime_nanos = start.to(end).num_nanoseconds().expect("Benchmark iter took greater than 2^63 nanoseconds");
    let runtime_secs = runtime_nanos as f64 / 1_000_000_000.0;
    (res, runtime_secs)
}

fn bench_scene(nx: i32, ny: i32, spp: i32) {
    let lookfrom = Vec3::new(16.0, 2.0, 4.0);
    let lookat = Vec3::new(-3.0, 0.5, -1.0);
    let camera = Camera::new(
        lookfrom,
        lookat,
        Vec3::new(0.0, 1.0, 0.0),
        15.0,
        (nx as f64) / (ny as f64),
        0.1,
        (lookfrom - lookat).length(),
    );

    let scene = ::render::random_scene();

    ::render::render(&scene, &camera, nx, ny, spp);
}

<commit_msg>Fix unneeded type parameter in bench_rays_per_sec<commit_after>use time::{Duration, PreciseTime};

use vec3::Vec3;
use camera::Camera;

// Benchmarks sample scene
// Prints iteration execution time and average
pub fn bench_rays_per_sec(n: i32) {
    let mut runs: Vec<f64> = Vec::new();
    for _ in 0..n {
        let bench_params = (100, 50, 5);
        let (_, runtime) = time(|| {
            bench_scene(bench_params.0, bench_params.1, bench_params.2)
        });
        let rays = bench_params.0 * bench_params.1 * bench_params.2;
        let rays_per_sec = rays as f64 / runtime;
        println!("{} rays in {} sec, {:.2} rays/sec", rays, runtime, rays_per_sec);
        runs.push(rays_per_sec);
    }
    println!("Avg: {:.2} rays/sec from {} runs", runs.iter().sum::<f64>() / (runs.len() as f64), runs.len());

}

// Run function and return result with seconds duration
pub fn time<F, T>(f: F) -> (T, f64)
    where F: FnOnce() -> T {
    let start = PreciseTime::now();
    let res = f();
    let end = PreciseTime::now();

    let runtime_nanos = start.to(end).num_nanoseconds().expect("Benchmark iter took greater than 2^63 nanoseconds");
    let runtime_secs = runtime_nanos as f64 / 1_000_000_000.0;
    (res, runtime_secs)
}

fn bench_scene(nx: i32, ny: i32, spp: i32) {
    let lookfrom = Vec3::new(16.0, 2.0, 4.0);
    let lookat = Vec3::new(-3.0, 0.5, -1.0);
    let camera = Camera::new(
        lookfrom,
        lookat,
        Vec3::new(0.0, 1.0, 0.0),
        15.0,
        (nx as f64) / (ny as f64),
        0.1,
        (lookfrom - lookat).length(),
    );

    let scene = ::render::random_scene();

    ::render::render(&scene, &camera, nx, ny, spp);
}

<|endoftext|>


<commit_before>use builder;
use ffi;
use util;
use libc;
use std::{cmp, fmt};

#[derive(Copy,Clone)]
/// A Ruby value.
pub struct Value(pub ffi::VALUE);

impl Value
{
    /// Gets `nil`.
    pub fn nil() -> Self {
        Self::from(ffi::Qnil)
    }

    /// Gets a boolean value.
    pub fn boolean(b: bool) -> Self {
        if b { Value::boolean_true() } else { Value::boolean_false() }
    }

    /// Gets the boolean `true` value.
    pub fn boolean_true() -> Self {
        Self::from(ffi::Qtrue)
    }

    /// Gets the boolean `false` value.
    pub fn boolean_false() -> Self {
        Self::from(ffi::Qfalse)
    }

    /// Creates a new symbol.
    pub fn symbol(name: &str) -> Self {
        Self::from(unsafe { ffi::rb_id2sym(Self::intern(name)) })
    }

    /// Creates a new String.
    pub fn string(s: &str) -> Self {
        Self::from(unsafe { ffi::rb_id2str(Self::intern(s)) })
    }

    /// Creates a new `Integer`.
    pub fn integer(v: i64) -> Self {
        Self::from(ffi::INT2FIX(v as _))
    }

    /// Creates a new `Float`.
    pub fn float(v: f64) -> Self {
        Self::from(unsafe { ffi::rb_float_new(v as libc::c_double) })
    }

    /// Converts the value into a symbol.
    pub fn to_sym(&self) -> Value {
        Self::from(unsafe { ffi::rb_to_symbol(self.0) })
    }

    /// Converts the value to a 64-bit signed integer.
    pub fn to_i64(&self) -> i64 {
        unsafe { ffi::rb_num2long(self.0) as i64 }
    }

    /// Converts the value to a 64-bit unsigned integer.
    pub fn to_u64(&self) -> u64 {
        unsafe { ffi::rb_num2ulong(self.0) as u64 }
    }

    /// Converts the value into a 64-bit float.
    pub fn to_f64(&self) -> f64 {
        unsafe { ffi::rb_num2dbl(self.0) as f64 }
    }

    /// Gets the class.
    pub fn class(&self) -> Value {
        Self::from(unsafe { ffi::rb_class_of(self.0) })
    }

    /// Creates a nested class.
    pub fn nested_class<S>(self, name: S) -> builder::Class
        where S: Into<String> {
        builder::Class::new_under(name, Some(self))
    }

    /// Creates a nested module.
    pub fn nested_module<S>(self, name: S) -> builder::Module
        where S: Into<String> {
        builder::Module::new_under(name, Some(self))
    }

    /// The value of `Object#to_s`.
    pub fn display_string(&self) -> String {
        self.call_no_args("to_s").as_string().expect("Object#to_s did not return a String")
    }

    /// The value of `Object#inspect`.
    pub fn inspect_string(&self) -> String {
        self.call_no_args("inspect").as_string().expect("Object#inspect did not return a String")
    }

    /// Gets the name of the class of the object.
    pub fn class_name(&self) -> String {
        unsafe { util::string(ffi::rb_obj_classname(self.0)) }
    }

    /// Checks if the value is `nil`.
    pub fn is_nil(&self)   -> bool { self.0 == ffi::Qnil }
    /// Checks if the value is `true`.
    pub fn is_true(&self)  -> bool { self.0 == ffi::Qtrue }
    /// Checks if the value is `false.`
    pub fn is_false(&self) -> bool { self.0 == ffi::Qfalse }

    /// Checks if the value is a `String` type.
    pub fn is_string(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_STRING) }
    /// Checks if the value is a regex.
    pub fn is_regex(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_REGEXP) }
    /// Checks if the value is an `Integer` type.
    pub fn is_integer(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_FIXNUM) }
    /// Checks if the value is a complex number.
    pub fn is_complex_number(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_COMPLEX) }
    /// Checks if the value is a rational number.
    pub fn is_rational(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_RATIONAL) }
    /// Checks if the value is a symbol.
    pub fn is_symbol(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_SYMBOL) }
    /// Checks if the value is a float.
    pub fn is_float(&self)  -> bool { ffi::TYPE_P(self.0, ffi::T_FLOAT) }
    /// Checks if the value is an array.
    pub fn is_array(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_ARRAY) }
    /// Checks if the value is a hash.
    pub fn is_hash(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_HASH) }
    /// Checks if the value is an object.
    pub fn is_object(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_OBJECT) }
    /// Checks if the value is a class.
    pub fn is_class(&self)  -> bool { ffi::TYPE_P(self.0, ffi::T_CLASS) }
    /// Checks if the value is a `Struct`.
    pub fn is_struct(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_STRUCT) }
    /// Checks if the value is a module.
    pub fn is_module(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_MODULE) }

    /// Ruby's version of '=='
    pub fn is_equal_to(&self, other: Self) -> Self {
        Self::from(unsafe { ffi::rb_equal(self.0, other.0) })
    }

    /// Converts a Ruby `String` into a Rust `String`.
    /// Returns `None` if the value is not a Ruby `String`.
    pub fn as_string(&self) -> Option<String> {
        if self.is_string() {
            let c_str = unsafe { ffi::rb_string_value_cstr(&self.0 as *const _) };
            Some(util::string(c_str))
        } else {
            None
        }
    }

    /// Calls a method with no args.
    pub fn call_no_args(&self, method_name: &str) -> Self {
        Self::from(unsafe { ffi::rb_funcall(self.0, Self::intern(method_name), 0) })
    }

    /// Sends a message to the value.
    pub fn send(&self, method_name: &str, args: &[Self]) -> Self {
        Self::from(unsafe {
            ffi::rb_funcallv(
                self.0,
                Self::intern(method_name),
                args.len() as libc::c_int,
                args.as_ptr() as *const _,
            )
        })
    }

    /// Gets the value of an instance variable by name.
    /// Returns `nil` if it doesn't exist.
    pub fn get_ivar(&self, name: &str) -> Self {
        Self::from(unsafe { ffi::rb_iv_get(self.0, util::c_string(name).as_ptr()) })
    }

    /// Sets the value of an instance variable (or creates a new one).
    pub fn set_ivar(&self, name: &str, value: Self) -> Self {
        Self::from(unsafe { ffi::rb_iv_set(self.0, util::c_string(name).as_ptr(), value.0) })
    }

    fn intern(s: &str) -> ffi::ID {
        unsafe { ffi::rb_intern(util::c_string(s).as_ptr()) }
    }
}

impl cmp::PartialEq for Value
{
    fn eq(&self, rhs: &Value) -> bool {
        self.is_equal_to(*rhs).is_true()
    }
}

impl cmp::Eq for Value { }

impl fmt::Display for Value
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.display_string().fmt(fmt)
    }
}

impl fmt::Debug for Value
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.display_string().fmt(fmt)
    }
}

impl From<ffi::VALUE> for Value
{
    fn from(value: ffi::VALUE) -> Value {
        Value(value)
    }
}

#[cfg(test)]
mod test {
    use super::Value;

    #[test]
    fn can_create_booleans() {
        assert!(Value::boolean_true().is_true());
        assert!(Value::boolean_false().is_false());
        assert!(Value::boolean(true).is_true());
        assert!(Value::boolean(false).is_false());
    }

    #[test]
    fn can_create_integers() {
        assert_eq!(50, Value::integer(50).to_u64());
        assert_eq!(0xdeadbeef, Value::integer(0xdeadbeef).to_u64());
    }
}

<commit_msg>Generalise value constructors<commit_after>use builder;
use ffi;
use util;
use libc;
use std::{cmp, fmt};

#[derive(Copy,Clone)]
/// A Ruby value.
pub struct Value(pub ffi::VALUE);

impl Value
{
    /// Gets `nil`.
    pub fn nil() -> Self {
        Self::from(ffi::Qnil)
    }

    /// Gets a boolean value.
    pub fn boolean(b: bool) -> Self {
        if b { Value::boolean_true() } else { Value::boolean_false() }
    }

    /// Gets the boolean `true` value.
    pub fn boolean_true() -> Self {
        Self::from(ffi::Qtrue)
    }

    /// Gets the boolean `false` value.
    pub fn boolean_false() -> Self {
        Self::from(ffi::Qfalse)
    }

    /// Creates a new symbol.
    pub fn symbol<S>(name: S) -> Self where S: AsRef<str> {
        Self::from(unsafe { ffi::rb_id2sym(Self::intern(name.as_ref())) })
    }

    /// Creates a new String.
    pub fn string<S>(s: S) -> Self where S: AsRef<String> {
        Self::from(unsafe { ffi::rb_id2str(Self::intern(s.as_ref())) })
    }

    /// Creates a new `Integer`.
    pub fn integer(v: i64) -> Self {
        Self::from(ffi::INT2FIX(v as _))
    }

    /// Creates a new `Float`.
    pub fn float(v: f64) -> Self {
        Self::from(unsafe { ffi::rb_float_new(v as libc::c_double) })
    }

    /// Converts the value into a symbol.
    pub fn to_sym(&self) -> Value {
        Self::from(unsafe { ffi::rb_to_symbol(self.0) })
    }

    /// Converts the value to a 64-bit signed integer.
    pub fn to_i64(&self) -> i64 {
        unsafe { ffi::rb_num2long(self.0) as i64 }
    }

    /// Converts the value to a 64-bit unsigned integer.
    pub fn to_u64(&self) -> u64 {
        unsafe { ffi::rb_num2ulong(self.0) as u64 }
    }

    /// Converts the value into a 64-bit float.
    pub fn to_f64(&self) -> f64 {
        unsafe { ffi::rb_num2dbl(self.0) as f64 }
    }

    /// Gets the class.
    pub fn class(&self) -> Value {
        Self::from(unsafe { ffi::rb_class_of(self.0) })
    }

    /// Creates a nested class.
    pub fn nested_class<S>(self, name: S) -> builder::Class
        where S: Into<String> {
        builder::Class::new_under(name, Some(self))
    }

    /// Creates a nested module.
    pub fn nested_module<S>(self, name: S) -> builder::Module
        where S: Into<String> {
        builder::Module::new_under(name, Some(self))
    }

    /// The value of `Object#to_s`.
    pub fn display_string(&self) -> String {
        self.call_no_args("to_s").as_string().expect("Object#to_s did not return a String")
    }

    /// The value of `Object#inspect`.
    pub fn inspect_string(&self) -> String {
        self.call_no_args("inspect").as_string().expect("Object#inspect did not return a String")
    }

    /// Gets the name of the class of the object.
    pub fn class_name(&self) -> String {
        unsafe { util::string(ffi::rb_obj_classname(self.0)) }
    }

    /// Checks if the value is `nil`.
    pub fn is_nil(&self)   -> bool { self.0 == ffi::Qnil }
    /// Checks if the value is `true`.
    pub fn is_true(&self)  -> bool { self.0 == ffi::Qtrue }
    /// Checks if the value is `false.`
    pub fn is_false(&self) -> bool { self.0 == ffi::Qfalse }

    /// Checks if the value is a `String` type.
    pub fn is_string(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_STRING) }
    /// Checks if the value is a regex.
    pub fn is_regex(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_REGEXP) }
    /// Checks if the value is an `Integer` type.
    pub fn is_integer(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_FIXNUM) }
    /// Checks if the value is a complex number.
    pub fn is_complex_number(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_COMPLEX) }
    /// Checks if the value is a rational number.
    pub fn is_rational(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_RATIONAL) }
    /// Checks if the value is a symbol.
    pub fn is_symbol(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_SYMBOL) }
    /// Checks if the value is a float.
    pub fn is_float(&self)  -> bool { ffi::TYPE_P(self.0, ffi::T_FLOAT) }
    /// Checks if the value is an array.
    pub fn is_array(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_ARRAY) }
    /// Checks if the value is a hash.
    pub fn is_hash(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_HASH) }
    /// Checks if the value is an object.
    pub fn is_object(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_OBJECT) }
    /// Checks if the value is a class.
    pub fn is_class(&self)  -> bool { ffi::TYPE_P(self.0, ffi::T_CLASS) }
    /// Checks if the value is a `Struct`.
    pub fn is_struct(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_STRUCT) }
    /// Checks if the value is a module.
    pub fn is_module(&self) -> bool { ffi::TYPE_P(self.0, ffi::T_MODULE) }

    /// Ruby's version of '=='
    pub fn is_equal_to(&self, other: Self) -> Self {
        Self::from(unsafe { ffi::rb_equal(self.0, other.0) })
    }

    /// Converts a Ruby `String` into a Rust `String`.
    /// Returns `None` if the value is not a Ruby `String`.
    pub fn as_string(&self) -> Option<String> {
        if self.is_string() {
            let c_str = unsafe { ffi::rb_string_value_cstr(&self.0 as *const _) };
            Some(util::string(c_str))
        } else {
            None
        }
    }

    /// Calls a method with no args.
    pub fn call_no_args(&self, method_name: &str) -> Self {
        Self::from(unsafe { ffi::rb_funcall(self.0, Self::intern(method_name), 0) })
    }

    /// Sends a message to the value.
    pub fn send(&self, method_name: &str, args: &[Self]) -> Self {
        Self::from(unsafe {
            ffi::rb_funcallv(
                self.0,
                Self::intern(method_name),
                args.len() as libc::c_int,
                args.as_ptr() as *const _,
            )
        })
    }

    /// Gets the value of an instance variable by name.
    /// Returns `nil` if it doesn't exist.
    pub fn get_ivar(&self, name: &str) -> Self {
        Self::from(unsafe { ffi::rb_iv_get(self.0, util::c_string(name).as_ptr()) })
    }

    /// Sets the value of an instance variable (or creates a new one).
    pub fn set_ivar(&self, name: &str, value: Self) -> Self {
        Self::from(unsafe { ffi::rb_iv_set(self.0, util::c_string(name).as_ptr(), value.0) })
    }

    fn intern(s: &str) -> ffi::ID {
        unsafe { ffi::rb_intern(util::c_string(s).as_ptr()) }
    }
}

impl cmp::PartialEq for Value
{
    fn eq(&self, rhs: &Value) -> bool {
        self.is_equal_to(*rhs).is_true()
    }
}

impl cmp::Eq for Value { }

impl fmt::Display for Value
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.display_string().fmt(fmt)
    }
}

impl fmt::Debug for Value
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.display_string().fmt(fmt)
    }
}

impl From<ffi::VALUE> for Value
{
    fn from(value: ffi::VALUE) -> Value {
        Value(value)
    }
}

#[cfg(test)]
mod test {
    use super::Value;

    #[test]
    fn can_create_booleans() {
        assert!(Value::boolean_true().is_true());
        assert!(Value::boolean_false().is_false());
        assert!(Value::boolean(true).is_true());
        assert!(Value::boolean(false).is_false());
    }

    #[test]
    fn can_create_integers() {
        assert_eq!(50, Value::integer(50).to_u64());
        assert_eq!(0xdeadbeef, Value::integer(0xdeadbeef).to_u64());
    }
}

<|endoftext|>


<commit_before>
//! Management of entities, components, systems, and managers

use std::cell::{RefMut, RefCell};
use std::collections::HashMap;
use std::intrinsics::TypeId;

use {Component, ComponentId};
use {Entity, EntityBuilder};
use {Manager, MutableManager};
use {Passive, System};
use component::ComponentList;
use entity::EntityManager;

pub struct World
{
    entities: RefCell<EntityManager>,
    components: RefCell<ComponentManager>,
    systems: RefCell<SystemManager>,
    mut_managers: Vec<RefCell<Box<MutableManager>>>,
    managers: Vec<Box<Manager>>,
    locked: bool,
}

pub struct Components<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

struct ComponentManager
{
    components: HashMap<ComponentId, ComponentList>,
}

struct SystemManager
{
    systems: Vec<Box<System>>,
    passive: HashMap<&'static str, Box<Passive>>,
}

impl World
{
    pub fn new() -> World
    {
        World
        {
            entities: RefCell::new(EntityManager::new()),
            components: RefCell::new(ComponentManager::new()),
            systems: RefCell::new(SystemManager::new()),
            mut_managers: Vec::new(),
            managers: Vec::new(),
            locked: false,
        }
    }

    /// Lock down the managers and systems, and components of a world.
    ///
    /// This must be called before entities can be created and modified.
    /// After it is called, no systems/managers/components may be registered.
    pub fn finalise(&mut self)
    {
        if self.locked
        {
            fail!("World is already finalised")
        }
        self.locked = true;
    }

    /// Returns if an entity has been activated.
    #[inline]
    pub fn is_active(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_activated(entity)
    }

    /// Returns if an entity is valid (registered with the entity manager).
    #[inline]
    pub fn is_valid(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_valid(entity)
    }

    /// Registers a mutable manager.
    ///
    /// # Failure
    ///
    /// If the world has been finalised
    #[experimental]
    pub fn register_manager_mut(&mut self, manager: Box<MutableManager>)
    {
        if self.locked
        {
            fail!("World is locked. Managers may not be registered")
        }
        self.mut_managers.push(RefCell::new(manager));
    }

    /// Registers an immutable manager.
    ///
    /// # Failure
    ///
    /// If the world has been finalised
    #[experimental]
    pub fn register_manager(&mut self, manager: Box<Manager>)
    {
        if self.locked
        {
            fail!("World is locked. Managers may not be registered")
        }
        self.managers.push(manager);
    }

    /// Registers a component.
    ///
    /// # Failure
    ///
    /// If the world has been finalised
    pub fn register_component<T: Component>(&mut self)
    {
        if self.locked
        {
            fail!("World is locked. Components may not be registered")
        }
        self.components.borrow_mut().register(ComponentList::new::<T>());
    }

    /// Registers a system.
    ///
    /// # Failure
    ///
    /// If the world has been finalised
    pub fn register_system(&mut self, sys: Box<System>)
    {
        if self.locked
        {
            fail!("World is locked. Systems may not be registered")
        }
        self.systems.borrow_mut().register(sys);
    }

    /// Registers a passive system.
    ///
    /// # Failure
    ///
    /// If the world has been finalised
    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        if self.locked
        {
            fail!("World is locked. Systems may not be registered")
        }
        self.systems.borrow_mut().register_passive(key, sys);
    }

    /// Updates the world by processing all systems.
    ///
    /// # Failure
    ///
    /// If the world has not been finalised
    pub fn update(&mut self)
    {
        if !self.locked
        {
            fail!("World must be locked before updating")
        }
        self.systems.borrow_mut().preprocess(self);
        self.systems.borrow().process(self.components());
        self.systems.borrow_mut().postprocess(self);
    }

    /// Updates the passive system corresponding to `key`
    ///
    /// # Failure
    ///
    /// If the world has not been finalised
    pub fn update_passive(&mut self, key: &'static str)
    {
        if !self.locked
        {
            fail!("World must be locked before updating")
        }
        self.systems.borrow_mut().update_passive(key, self);
    }

    fn components(&self) -> Components
    {
        Components
        {
            inner: self.components.borrow_mut()
        }
    }

    /// Creates an entity
    ///
    /// # Failure
    ///
    /// If the world has not been finalised
    pub fn create_entity(&mut self) -> Entity
    {
        if !self.locked
        {
            fail!("World must be locked before creating entities")
        }
        let ret = self.entities.borrow_mut().create_entity();
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().added(&ret, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.added(&ret, self);
        }
        ret
    }

    /// Builds an entity
    pub fn build_entity<T: EntityBuilder>(&mut self, builder: T)
    {
        let entity = self.create_entity();
        let ret = builder.build(self, entity);
        self.activate_entity(&entity);
        ret
    }

    /// Activates an entity
    ///
    /// Once activated, components cannot be added to the entity,
    /// and systems will be able to process it.
    ///
    /// # Failure
    ///
    /// If the entity is invalid or already activated
    pub fn activate_entity(&mut self, entity: &Entity)
    {
        if self.is_active(entity)
        {
            fail!("Entity is already activated")
        }
        if !self.is_valid(entity)
        {
            fail!("Cannot activate invalid entity")
        }
        self.entities.borrow_mut().activate_entity(entity);
        self.systems.borrow_mut().activated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().activated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.activated(entity, self);
        }
    }

    /// Deactivates an entity
    ///
    /// It will then be ignored by all systems.
    /// Components can only be added/removed from an entity while deactivated.
    ///
    /// # Failure
    ///
    /// If the entity is not already activated
    pub fn deactivate_entity(&mut self, entity: &Entity)
    {
        if !self.is_active(entity)
        {
            fail!("Cannot deactivate unactivated entity")
        }
        self.entities.borrow_mut().deactivate_entity(entity);
        self.systems.borrow_mut().deactivated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().deactivated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.deactivated(entity, self);
        }
    }

    /// Deletes an entity, deactivating it if it is activated
    ///
    /// # Failure
    ///
    /// If an entity is invalid
    pub fn delete_entity(&mut self, entity: &Entity)
    {
        if !self.is_valid(entity)
        {
            fail!("Cannot delete invalid entity")
        }
        if self.is_active(entity)
        {
            self.deactivate_entity(entity);
        }
        self.entities.borrow_mut().delete_entity(entity);
        self.components.borrow_mut().delete_entity(entity);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().removed(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.removed(entity, self);
        }
    }

    /// Add a component to an entity
    ///
    /// Returns false if the component could not be added (entity invalid or activated).
    pub fn add_component<T: Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.is_valid(entity)
        && !self.is_active(entity)
        && self.components.borrow_mut().add::<T>(entity, component)
    }

    /// Removes a component from an entity.
    ///
    /// Returns false if the component could not be removed (entity invalid or activated).
    pub fn remove_component<T: Component>(&mut self, entity: &Entity) -> bool
    {
        self.is_valid(entity)
        && !self.is_active(entity)
        && self.components.borrow_mut().remove::<T>(entity)
    }

    /// Set the value of a component for an entity
    ///
    /// Returns false if the entity does not contain that component.
    pub fn set_component<T: Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.is_valid(entity)
        && self.components.borrow_mut().set::<T>(entity, component)
    }

    /// Returns the value of a component for an entity (or None)
    pub fn get_component<T: Component>(&self, entity: &Entity) -> Option<T>
    {
        if self.is_valid(entity)
        {
            self.components.borrow().get::<T>(entity)
        }
        else
        {
            None
        }
    }

    /// Returns if an entity contains a component.
    pub fn has_component(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components.borrow().has(entity, id)
    }
}

impl SystemManager
{
    pub fn new() -> SystemManager
    {
        SystemManager
        {
            systems: Vec::new(),
            passive: HashMap::new(),
        }
    }

    pub fn register(&mut self, sys: Box<System>)
    {
        self.systems.push(sys);
    }

    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.passive.insert(key, sys);
    }

    pub fn preprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.preprocess(world);
        }
    }

    pub fn process(&self, mut components: Components)
    {
        for sys in self.systems.iter()
        {
            sys.process(&mut components);
        }
    }

    pub fn postprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.postprocess(world);
        }
    }

    pub fn update_passive(&mut self, key: &'static str, world: &World)
    {
        if self.passive.contains_key(&key)
        {
            self.passive.get_mut(&key).process(world);
        }
        else
        {
            fail!("No passive system registered for key '{}'", key);
        }
    }
}

impl MutableManager for SystemManager
{
    fn added(&mut self, _: &Entity, _: &World)
    {

    }

    fn removed(&mut self, _: &Entity, _: &World)
    {

    }

    fn activated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.activated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.activated(e, w);
        }
    }

    fn deactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.deactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.deactivated(e, w);
        }
    }
}

impl ComponentManager
{
    pub fn new() -> ComponentManager
    {
        ComponentManager
        {
            components: HashMap::new(),
        }
    }

    pub fn register(&mut self, list: ComponentList)
    {
        self.components.insert(list.get_cid(), list);
    }

    fn delete_entity(&mut self, entity: &Entity)
    {
        for (_, list) in self.components.iter_mut()
        {
            list.rm(entity);
        }
    }

    fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).add::<T>(entity, &component)
    }

    fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).set::<T>(entity, &component)
    }

    fn get<T:Component>(&self, entity: &Entity) -> Option<T>
    {
        self.components[TypeId::of::<T>().hash()].get::<T>(entity)
    }

    pub fn has(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components[id].has(entity)
    }

    fn borrow_mut<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).borrow_mut::<T>(entity)
    }

    fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).rm(entity)
    }
}

impl<'a> Components<'a>
{
    pub fn borrow<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.inner.borrow_mut::<T>(entity)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }
}
<commit_msg>Remove lock boolean flag from World and enforce configuration via WorldBuilder<commit_after>
//! Management of entities, components, systems, and managers

use std::cell::{RefMut, RefCell};
use std::collections::HashMap;
use std::intrinsics::TypeId;

use {Component, ComponentId};
use {Entity, EntityBuilder};
use {Manager, MutableManager};
use {Passive, System};
use component::ComponentList;
use entity::EntityManager;

pub struct World
{
    entities: RefCell<EntityManager>,
    components: RefCell<ComponentManager>,
    systems: RefCell<SystemManager>,
    mut_managers: Vec<RefCell<Box<MutableManager>>>,
    managers: Vec<Box<Manager>>,
}

pub struct WorldBuilder
{
    world: World
}

impl WorldBuilder
{
    pub fn new() -> WorldBuilder
    {
        WorldBuilder
        {
            world: World::new()
        }
    }

    pub fn build(self) -> World
    {
        self.world
    }

    /// Registers a mutable manager.
    #[experimental]
    pub fn register_manager_mut(&mut self, manager: Box<MutableManager>)
    {
        self.world.mut_managers.push(RefCell::new(manager));
    }

    /// Registers an immutable manager.
    #[experimental]
    pub fn register_manager(&mut self, manager: Box<Manager>)
    {
        self.world.managers.push(manager);
    }

    /// Registers a component.
    pub fn register_component<T: Component>(&mut self)
    {
        self.world.components.borrow_mut().register(ComponentList::new::<T>());
    }

    /// Registers a system.
    pub fn register_system(&mut self, sys: Box<System>)
    {
        self.world.systems.borrow_mut().register(sys);
    }

    /// Registers a passive system.
    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.world.systems.borrow_mut().register_passive(key, sys);
    }
}

pub struct Components<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

struct ComponentManager
{
    components: HashMap<ComponentId, ComponentList>,
}

struct SystemManager
{
    systems: Vec<Box<System>>,
    passive: HashMap<&'static str, Box<Passive>>,
}

impl World
{
    fn new() -> World
    {
        World
        {
            entities: RefCell::new(EntityManager::new()),
            components: RefCell::new(ComponentManager::new()),
            systems: RefCell::new(SystemManager::new()),
            mut_managers: Vec::new(),
            managers: Vec::new(),
        }
    }

    /// Returns if an entity has been activated.
    #[inline]
    pub fn is_active(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_activated(entity)
    }

    /// Returns if an entity is valid (registered with the entity manager).
    #[inline]
    pub fn is_valid(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_valid(entity)
    }

    /// Updates the world by processing all systems.
    pub fn update(&mut self)
    {
        self.systems.borrow_mut().preprocess(self);
        self.systems.borrow().process(self.components());
        self.systems.borrow_mut().postprocess(self);
    }

    /// Updates the passive system corresponding to `key`
    pub fn update_passive(&mut self, key: &'static str)
    {
        self.systems.borrow_mut().update_passive(key, self);
    }

    fn components(&self) -> Components
    {
        Components
        {
            inner: self.components.borrow_mut()
        }
    }

    /// Creates an entity
    pub fn create_entity(&mut self) -> Entity
    {
        let ret = self.entities.borrow_mut().create_entity();
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().added(&ret, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.added(&ret, self);
        }
        ret
    }

    /// Builds an entity
    pub fn build_entity<T: EntityBuilder>(&mut self, builder: T)
    {
        let entity = self.create_entity();
        let ret = builder.build(self, entity);
        self.activate_entity(&entity);
        ret
    }

    /// Activates an entity
    ///
    /// Once activated, components cannot be added to the entity,
    /// and systems will be able to process it.
    ///
    /// # Failure
    ///
    /// If the entity is invalid or already activated
    pub fn activate_entity(&mut self, entity: &Entity)
    {
        if self.is_active(entity)
        {
            fail!("Entity is already activated")
        }
        if !self.is_valid(entity)
        {
            fail!("Cannot activate invalid entity")
        }
        self.entities.borrow_mut().activate_entity(entity);
        self.systems.borrow_mut().activated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().activated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.activated(entity, self);
        }
    }

    /// Deactivates an entity
    ///
    /// It will then be ignored by all systems.
    /// Components can only be added/removed from an entity while deactivated.
    ///
    /// # Failure
    ///
    /// If the entity is not already activated
    pub fn deactivate_entity(&mut self, entity: &Entity)
    {
        if !self.is_active(entity)
        {
            fail!("Cannot deactivate unactivated entity")
        }
        self.entities.borrow_mut().deactivate_entity(entity);
        self.systems.borrow_mut().deactivated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().deactivated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.deactivated(entity, self);
        }
    }

    /// Deletes an entity, deactivating it if it is activated
    ///
    /// # Failure
    ///
    /// If an entity is invalid
    pub fn delete_entity(&mut self, entity: &Entity)
    {
        if !self.is_valid(entity)
        {
            fail!("Cannot delete invalid entity")
        }
        if self.is_active(entity)
        {
            self.deactivate_entity(entity);
        }
        self.entities.borrow_mut().delete_entity(entity);
        self.components.borrow_mut().delete_entity(entity);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().removed(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.removed(entity, self);
        }
    }

    /// Add a component to an entity
    ///
    /// Returns false if the component could not be added (entity invalid or activated).
    pub fn add_component<T: Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.is_valid(entity)
        && !self.is_active(entity)
        && self.components.borrow_mut().add::<T>(entity, component)
    }

    /// Removes a component from an entity.
    ///
    /// Returns false if the component could not be removed (entity invalid or activated).
    pub fn remove_component<T: Component>(&mut self, entity: &Entity) -> bool
    {
        self.is_valid(entity)
        && !self.is_active(entity)
        && self.components.borrow_mut().remove::<T>(entity)
    }

    /// Set the value of a component for an entity
    ///
    /// Returns false if the entity does not contain that component.
    pub fn set_component<T: Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.is_valid(entity)
        && self.components.borrow_mut().set::<T>(entity, component)
    }

    /// Returns the value of a component for an entity (or None)
    pub fn get_component<T: Component>(&self, entity: &Entity) -> Option<T>
    {
        if self.is_valid(entity)
        {
            self.components.borrow().get::<T>(entity)
        }
        else
        {
            None
        }
    }

    /// Returns if an entity contains a component.
    pub fn has_component(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components.borrow().has(entity, id)
    }
}

impl SystemManager
{
    pub fn new() -> SystemManager
    {
        SystemManager
        {
            systems: Vec::new(),
            passive: HashMap::new(),
        }
    }

    pub fn register(&mut self, sys: Box<System>)
    {
        self.systems.push(sys);
    }

    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.passive.insert(key, sys);
    }

    pub fn preprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.preprocess(world);
        }
    }

    pub fn process(&self, mut components: Components)
    {
        for sys in self.systems.iter()
        {
            sys.process(&mut components);
        }
    }

    pub fn postprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.postprocess(world);
        }
    }

    pub fn update_passive(&mut self, key: &'static str, world: &World)
    {
        if self.passive.contains_key(&key)
        {
            self.passive.get_mut(&key).process(world);
        }
        else
        {
            fail!("No passive system registered for key '{}'", key);
        }
    }
}

impl MutableManager for SystemManager
{
    fn added(&mut self, _: &Entity, _: &World)
    {

    }

    fn removed(&mut self, _: &Entity, _: &World)
    {

    }

    fn activated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.activated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.activated(e, w);
        }
    }

    fn deactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.deactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.deactivated(e, w);
        }
    }
}

impl ComponentManager
{
    pub fn new() -> ComponentManager
    {
        ComponentManager
        {
            components: HashMap::new(),
        }
    }

    pub fn register(&mut self, list: ComponentList)
    {
        self.components.insert(list.get_cid(), list);
    }

    fn delete_entity(&mut self, entity: &Entity)
    {
        for (_, list) in self.components.iter_mut()
        {
            list.rm(entity);
        }
    }

    fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).add::<T>(entity, &component)
    }

    fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).set::<T>(entity, &component)
    }

    fn get<T:Component>(&self, entity: &Entity) -> Option<T>
    {
        self.components[TypeId::of::<T>().hash()].get::<T>(entity)
    }

    pub fn has(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components[id].has(entity)
    }

    fn borrow_mut<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).borrow_mut::<T>(entity)
    }

    fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).rm(entity)
    }
}

impl<'a> Components<'a>
{
    pub fn borrow<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.inner.borrow_mut::<T>(entity)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }
}
<|endoftext|>