<commit_before>use super::raw;
use std::fmt;
use std::cell::RefCell;

pub struct Document<'d> {
    storage: &'d raw::Storage,
    connections: RefCell<&'d raw::Connections>,
}

impl<'d> Document<'d> {
    pub fn new(storage: &'d raw::Storage, connections: &'d raw::Connections) -> Document<'d> {
        Document {
            storage: storage,
            connections: RefCell::new(connections),
        }
    }

    fn wrap_element(&'d self, node: *mut raw::Element) -> Element<'d> {
        Element {
            document: self,
            node: node,
        }
    }

    pub fn create_element(&'d self, name: &str) -> Element<'d> {
        self.wrap_element(self.storage.create_element(name))
    }
}

pub struct Element<'d> {
    document: &'d Document<'d>,
    node: *mut raw::Element,
}

impl<'d> Element<'d> {
    fn node(&self) -> &raw::Element { unsafe { &*self.node } }

    pub fn name(&self) -> &str { self.node().name() }

    pub fn set_name(&self, name: &str) {
        self.document.storage.element_set_name(self.node, name)
    }

    pub fn parent(&'d self) -> Option<ParentOfChild<'d>> {
        let connections = self.document.connections.borrow();

        connections.element_parent(self.node).map(|n| {
            match n {
                raw::ElementPOC(n) => ElementPOC(self.document.wrap_element(n)),
            }
        })
    }

    pub fn append_child(&self, child: Element) {
        let connections = self.document.connections.borrow_mut();
        connections.append_element_child(self.node, child.node)
    }

    pub fn children(&'d self) -> Vec<ChildOfElement<'d>> {
        let connections = self.document.connections.borrow();
        // This is safe because we copy of the children, and the
        // children are never deallocated.
        unsafe {
            let raw_children = connections.element_children(self.node);
            raw_children.iter().map(|n| match n {
                &raw::ElementCOE(n) => ElementCOE(self.document.wrap_element(n)),
            }).collect()
        }
    }
}

impl<'d> PartialEq for Element<'d> {
    fn eq(&self, other: &Element<'d>) -> bool {
        self.node == other.node
    }
}

impl<'d> fmt::Show for Element<'d> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let node = unsafe { &* self.node };
        write!(f, "Element {{ name: {}  }}", node.name())
    }
}

#[deriving(PartialEq,Show)]
pub enum ChildOfElement<'d> {
    ElementCOE(Element<'d>)
}

impl<'d> ChildOfElement<'d> {
    pub fn element(self) -> Option<Element<'d>> {
        match self {
            ElementCOE(n) => Some(n),
        }
    }
}

#[deriving(PartialEq,Show)]
pub enum ParentOfChild<'d> {
    ElementPOC(Element<'d>),
}

#[cfg(test)]
mod test {
    use super::super::Package;
    use super::{ElementCOE};
    use super::{ElementPOC};

    #[test]
    fn elements_can_have_element_children() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        let beta  = doc.create_element("beta");

        alpha.append_child(beta);

        let children = alpha.children();

        assert_eq!(children[0], ElementCOE(beta));
    }

    #[test]
    fn element_children_are_ordered() {
        let package = Package::new();
        let doc = package.as_document();

        let greek = doc.create_element("greek");
        let alpha = doc.create_element("alpha");
        let omega = doc.create_element("omega");

        greek.append_child(alpha);
        greek.append_child(omega);

        let children = greek.children();

        assert_eq!(children[0], ElementCOE(alpha));
        assert_eq!(children[1], ElementCOE(omega));
    }

    #[test]
    fn element_children_know_their_parent() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        let beta  = doc.create_element("beta");

        alpha.append_child(beta);

        assert_eq!(Some(ElementPOC(alpha)), beta.parent());
    }

    #[test]
    fn changing_parent_of_element_removes_element_from_original_parent() {
        let package = Package::new();
        let doc = package.as_document();

        let parent1 = doc.create_element("parent1");
        let parent2 = doc.create_element("parent2");
        let child = doc.create_element("child");

        parent1.append_child(child);
        parent2.append_child(child);

        assert!(parent1.children().is_empty());
        assert_eq!(1, parent2.children().len());
    }

    #[test]
    fn elements_can_be_renamed() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        alpha.set_name("beta");
        assert_eq!(alpha.name(), "beta");
    }
}
<commit_msg>Fat DOM elements belong to a document<commit_after>use super::raw;
use std::fmt;
use std::cell::RefCell;

pub struct Document<'d> {
    storage: &'d raw::Storage,
    connections: RefCell<&'d raw::Connections>,
}

impl<'d> Document<'d> {
    pub fn new(storage: &'d raw::Storage, connections: &'d raw::Connections) -> Document<'d> {
        Document {
            storage: storage,
            connections: RefCell::new(connections),
        }
    }

    fn wrap_element(&'d self, node: *mut raw::Element) -> Element<'d> {
        Element {
            document: self,
            node: node,
        }
    }

    pub fn create_element(&'d self, name: &str) -> Element<'d> {
        self.wrap_element(self.storage.create_element(name))
    }
}

impl<'d> PartialEq for Document<'d> {
    fn eq(&self, other: &Document<'d>) -> bool {
        self as *const Document == other as *const Document
    }
}

impl<'d> fmt::Show for Document<'d> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Document {{ {} }}", self as *const Document)
    }
}

pub struct Element<'d> {
    document: &'d Document<'d>,
    node: *mut raw::Element,
}

impl<'d> Element<'d> {
    fn node(&self) -> &raw::Element { unsafe { &*self.node } }

    pub fn document(&self) -> &'d Document<'d> { self.document }
    pub fn name(&self) -> &str { self.node().name() }

    pub fn set_name(&self, name: &str) {
        self.document.storage.element_set_name(self.node, name)
    }

    pub fn parent(&'d self) -> Option<ParentOfChild<'d>> {
        let connections = self.document.connections.borrow();

        connections.element_parent(self.node).map(|n| {
            match n {
                raw::ElementPOC(n) => ElementPOC(self.document.wrap_element(n)),
            }
        })
    }

    pub fn append_child(&self, child: Element) {
        let connections = self.document.connections.borrow_mut();
        connections.append_element_child(self.node, child.node)
    }

    pub fn children(&'d self) -> Vec<ChildOfElement<'d>> {
        let connections = self.document.connections.borrow();
        // This is safe because we copy of the children, and the
        // children are never deallocated.
        unsafe {
            let raw_children = connections.element_children(self.node);
            raw_children.iter().map(|n| match n {
                &raw::ElementCOE(n) => ElementCOE(self.document.wrap_element(n)),
            }).collect()
        }
    }
}

impl<'d> PartialEq for Element<'d> {
    fn eq(&self, other: &Element<'d>) -> bool {
        self.node == other.node
    }
}

impl<'d> fmt::Show for Element<'d> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let node = unsafe { &* self.node };
        write!(f, "Element {{ name: {}  }}", node.name())
    }
}

#[deriving(PartialEq,Show)]
pub enum ChildOfElement<'d> {
    ElementCOE(Element<'d>)
}

impl<'d> ChildOfElement<'d> {
    pub fn element(self) -> Option<Element<'d>> {
        match self {
            ElementCOE(n) => Some(n),
        }
    }
}

#[deriving(PartialEq,Show)]
pub enum ParentOfChild<'d> {
    ElementPOC(Element<'d>),
}

#[cfg(test)]
mod test {
    use super::super::Package;
    use super::{ElementCOE};
    use super::{ElementPOC};

    #[test]
    fn elements_belong_to_a_document() {
        let package = Package::new();
        let doc = package.as_document();

        let element = doc.create_element("alpha");

        assert_eq!(&doc, element.document());
    }

    #[test]
    fn elements_can_have_element_children() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        let beta  = doc.create_element("beta");

        alpha.append_child(beta);

        let children = alpha.children();

        assert_eq!(children[0], ElementCOE(beta));
    }

    #[test]
    fn element_children_are_ordered() {
        let package = Package::new();
        let doc = package.as_document();

        let greek = doc.create_element("greek");
        let alpha = doc.create_element("alpha");
        let omega = doc.create_element("omega");

        greek.append_child(alpha);
        greek.append_child(omega);

        let children = greek.children();

        assert_eq!(children[0], ElementCOE(alpha));
        assert_eq!(children[1], ElementCOE(omega));
    }

    #[test]
    fn element_children_know_their_parent() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        let beta  = doc.create_element("beta");

        alpha.append_child(beta);

        assert_eq!(Some(ElementPOC(alpha)), beta.parent());
    }

    #[test]
    fn changing_parent_of_element_removes_element_from_original_parent() {
        let package = Package::new();
        let doc = package.as_document();

        let parent1 = doc.create_element("parent1");
        let parent2 = doc.create_element("parent2");
        let child = doc.create_element("child");

        parent1.append_child(child);
        parent2.append_child(child);

        assert!(parent1.children().is_empty());
        assert_eq!(1, parent2.children().len());
    }

    #[test]
    fn elements_can_be_renamed() {
        let package = Package::new();
        let doc = package.as_document();

        let alpha = doc.create_element("alpha");
        alpha.set_name("beta");
        assert_eq!(alpha.name(), "beta");
    }
}
<|endoftext|>


<commit_before>use cairo;
use cairo::MatrixTrait;

use aspect_ratio::AspectRatio;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;
use util::*;
use viewbox::*;

pub fn draw_in_viewport<F>(vx: f64, vy: f64, vw: f64, vh: f64,
                           clip_before_layer_push: bool,
                           do_clip: bool,
                           vbox: Option<ViewBox>,
                           preserve_aspect_ratio: AspectRatio,
                           affine: cairo::Matrix,
                           draw_ctx: *const RsvgDrawingCtx,
                           draw_fn: F)
    where F: FnOnce()
{
    let mut ctx = RsvgDrawingCtxWrapper(draw_ctx);

    in_viewport(&mut ctx,
                vx, vy, vw, vh,
                clip_before_layer_push,
                do_clip,
                vbox,
                preserve_aspect_ratio,
                affine,
                draw_fn);
}

trait ViewportCtx {
    fn push_view_box(&mut self, width: f64, height: f64);
    fn pop_view_box(&mut self, );
    fn push_discrete_layer(&mut self);
    fn pop_discrete_layer(&mut self);
    fn add_clipping_rect(&mut self, x: f64, y: f64, w: f64, h: f64);
    fn set_affine(&mut self, affine: cairo::Matrix);
}

struct RsvgDrawingCtxWrapper(pub *const RsvgDrawingCtx);

impl ViewportCtx for RsvgDrawingCtxWrapper {
    fn push_view_box(&mut self, width: f64, height: f64) {
        drawing_ctx::push_view_box(self.0, width, height);
    }

    fn pop_view_box(&mut self) {
        drawing_ctx::pop_view_box(self.0);
    }

    fn push_discrete_layer(&mut self) {
        drawing_ctx::push_discrete_layer(self.0);
    }

    fn pop_discrete_layer(&mut self) {
        drawing_ctx::pop_discrete_layer(self.0);
    }

    fn add_clipping_rect(&mut self, x: f64, y: f64, w: f64, h: f64) {
        drawing_ctx::add_clipping_rect(self.0, x, y, w, h);
    }

    fn set_affine(&mut self, affine: cairo::Matrix) {
        drawing_ctx::set_current_state_affine(self.0, affine);
    }
}

fn in_viewport<F>(ctx: &mut ViewportCtx,
                  vx: f64, vy: f64, vw: f64, vh: f64,
                  clip_before_layer_push: bool,
                  do_clip: bool,
                  vbox: Option<ViewBox>,
                  preserve_aspect_ratio: AspectRatio,
                  mut affine: cairo::Matrix,
                  draw_fn: F)
    where F: FnOnce()
{
    // width or height set to 0 disables rendering of the element
    // https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
    // https://www.w3.org/TR/SVG/struct.html#UseElementWidthAttribute
    // https://www.w3.org/TR/SVG/struct.html#ImageElementWidthAttribute
    // https://www.w3.org/TR/SVG/painting.html#MarkerWidthAttribute

    if double_equals(vw, 0.0) || double_equals(vh, 0.0) {
        return;
    }

    let vbox_size;

    if let Some(vbox) = vbox {
        // the preserveAspectRatio attribute is only used if viewBox is specified
        // https://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute

        let (x, y, w, h) = preserve_aspect_ratio.compute(vbox.0.width, vbox.0.height,
                                                         vx, vy, vw, vh);

        affine.translate(x, y);
        affine.scale(w / vbox.0.width, h / vbox.0.height);
        affine.translate(-vbox.0.x, -vbox.0.y);

        vbox_size = (vbox.0.width, vbox.0.height);

        if clip_before_layer_push && do_clip {
            ctx.add_clipping_rect(vbox.0.x, vbox.0.y, vbox.0.width, vbox.0.height);
        }
    } else {
        affine.translate(vx, vy);
        vbox_size = (vw, vh);
    }

    ctx.push_view_box(vbox_size.0, vbox_size.1);
    ctx.push_discrete_layer();

    if !clip_before_layer_push && do_clip {
        ctx.add_clipping_rect(vx, vy, vw, vh);
    }

    ctx.set_affine(affine);

    draw_fn();

    ctx.pop_discrete_layer();
    ctx.pop_view_box();
}
<commit_msg>viewport.rs: Start adding tests<commit_after>use cairo;
use cairo::MatrixTrait;

use aspect_ratio::AspectRatio;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;
use util::*;
use viewbox::*;

pub fn draw_in_viewport<F>(vx: f64, vy: f64, vw: f64, vh: f64,
                           clip_before_layer_push: bool,
                           do_clip: bool,
                           vbox: Option<ViewBox>,
                           preserve_aspect_ratio: AspectRatio,
                           affine: cairo::Matrix,
                           draw_ctx: *const RsvgDrawingCtx,
                           draw_fn: F)
    where F: FnOnce()
{
    let mut ctx = RsvgDrawingCtxWrapper(draw_ctx);

    in_viewport(&mut ctx,
                vx, vy, vw, vh,
                clip_before_layer_push,
                do_clip,
                vbox,
                preserve_aspect_ratio,
                affine,
                draw_fn);
}

trait ViewportCtx {
    fn push_view_box(&mut self, width: f64, height: f64);
    fn pop_view_box(&mut self, );
    fn push_discrete_layer(&mut self);
    fn pop_discrete_layer(&mut self);
    fn add_clipping_rect(&mut self, x: f64, y: f64, w: f64, h: f64);
    fn set_affine(&mut self, affine: cairo::Matrix);
}

struct RsvgDrawingCtxWrapper(pub *const RsvgDrawingCtx);

impl ViewportCtx for RsvgDrawingCtxWrapper {
    fn push_view_box(&mut self, width: f64, height: f64) {
        drawing_ctx::push_view_box(self.0, width, height);
    }

    fn pop_view_box(&mut self) {
        drawing_ctx::pop_view_box(self.0);
    }

    fn push_discrete_layer(&mut self) {
        drawing_ctx::push_discrete_layer(self.0);
    }

    fn pop_discrete_layer(&mut self) {
        drawing_ctx::pop_discrete_layer(self.0);
    }

    fn add_clipping_rect(&mut self, x: f64, y: f64, w: f64, h: f64) {
        drawing_ctx::add_clipping_rect(self.0, x, y, w, h);
    }

    fn set_affine(&mut self, affine: cairo::Matrix) {
        drawing_ctx::set_current_state_affine(self.0, affine);
    }
}

fn in_viewport<F>(ctx: &mut ViewportCtx,
                  vx: f64, vy: f64, vw: f64, vh: f64,
                  clip_before_layer_push: bool,
                  do_clip: bool,
                  vbox: Option<ViewBox>,
                  preserve_aspect_ratio: AspectRatio,
                  mut affine: cairo::Matrix,
                  draw_fn: F)
    where F: FnOnce()
{
    // width or height set to 0 disables rendering of the element
    // https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
    // https://www.w3.org/TR/SVG/struct.html#UseElementWidthAttribute
    // https://www.w3.org/TR/SVG/struct.html#ImageElementWidthAttribute
    // https://www.w3.org/TR/SVG/painting.html#MarkerWidthAttribute

    if double_equals(vw, 0.0) || double_equals(vh, 0.0) {
        return;
    }

    let vbox_size;

    if let Some(vbox) = vbox {
        // the preserveAspectRatio attribute is only used if viewBox is specified
        // https://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute

        let (x, y, w, h) = preserve_aspect_ratio.compute(vbox.0.width, vbox.0.height,
                                                         vx, vy, vw, vh);

        affine.translate(x, y);
        affine.scale(w / vbox.0.width, h / vbox.0.height);
        affine.translate(-vbox.0.x, -vbox.0.y);

        vbox_size = (vbox.0.width, vbox.0.height);

        if clip_before_layer_push && do_clip {
            ctx.add_clipping_rect(vbox.0.x, vbox.0.y, vbox.0.width, vbox.0.height);
        }
    } else {
        affine.translate(vx, vy);
        vbox_size = (vw, vh);
    }

    ctx.push_view_box(vbox_size.0, vbox_size.1);
    ctx.push_discrete_layer();

    if !clip_before_layer_push && do_clip {
        ctx.add_clipping_rect(vx, vy, vw, vh);
    }

    ctx.set_affine(affine);

    draw_fn();

    ctx.pop_discrete_layer();
    ctx.pop_view_box();
}

#[cfg(test)]
mod tests {
    use super::*;
    use parsers::Parse;

    #[derive(Default, PartialEq)]
    struct Ctx {
        pub view_box_size: Option<(f64, f64)>,
        pub clipping_rect: Option<(f64, f64, f64, f64)>,
        pub affine:        Option<cairo::Matrix>,

        pub expected_view_box_size: Option<(f64, f64)>,
        pub expected_clipping_rect: Option<(f64, f64, f64, f64)>,
        pub expected_affine:        Option<cairo::Matrix>,
    }

    impl ViewportCtx for Ctx {
        fn push_view_box(&mut self, width: f64, height: f64) {
            self.view_box_size = Some((width, height));
        }

        fn pop_view_box(&mut self) {
        }

        fn push_discrete_layer(&mut self) {
        }

        fn pop_discrete_layer(&mut self) {
        }

        fn add_clipping_rect(&mut self, x: f64, y: f64, w: f64, h: f64) {
            self.clipping_rect = Some((x, y, w, h));
        }

        fn set_affine(&mut self, affine: cairo::Matrix) {
            self.affine = Some(affine);
        }
    }

    fn call_in_viewport(vx: f64, vy: f64, vw: f64, vh: f64,
                        clip_before_layer_push: bool,
                        do_clip: bool,
                        vbox: Option<ViewBox>,
                        preserve_aspect_ratio: AspectRatio,
                        affine: cairo::Matrix,
                        ctx: &mut Ctx) {
        in_viewport(ctx,
                    vx, vy, vw, vh,
                    clip_before_layer_push,
                    do_clip,
                    vbox,
                    preserve_aspect_ratio,
                    affine,
                    || ());

        assert_eq!(ctx.view_box_size, ctx.expected_view_box_size);
        assert_eq!(ctx.clipping_rect, ctx.expected_clipping_rect);
        assert_eq!(ctx.affine, ctx.expected_affine);
    }

    #[test]
    fn clip_after_layer_push() {
        let mut affine = cairo::Matrix::identity();
        affine.scale(0.20, 0.20);

        let mut ctx = Ctx {
            view_box_size: None,
            clipping_rect: None,
            affine:        None,

            expected_view_box_size: Some((50.0, 50.0)),
            expected_clipping_rect: Some((10.0, 10.0, 10.0, 10.0)),
            expected_affine: Some(affine)
        };

        call_in_viewport(10.0, 10.0, 10.0, 10.0,
                         false,
                         true,
                         Some(ViewBox(cairo::Rectangle {
                             x: 50.0,
                             y: 50.0,
                             width: 50.0,
                             height: 50.0,
                         })),
                         AspectRatio::parse("xMidYMid meet", ()).unwrap(),
                         cairo::Matrix::identity(),
                         &mut ctx);
    }

    #[test]
    fn clip_before_layer_push() {
        let mut affine = cairo::Matrix::identity();
        affine.translate(10.0, 10.0);
        affine.scale(0.40, 0.40);

        let mut ctx = Ctx {
            view_box_size: None,
            clipping_rect: None,
            affine:        None,

            expected_view_box_size: Some((50.0, 50.0)),
            expected_clipping_rect: Some((0.0, 0.0, 50.0, 50.0)),
            expected_affine: Some(affine)
        };

        call_in_viewport(10.0, 10.0, 20.0, 20.0,
                         true,
                         true,
                         Some(ViewBox(cairo::Rectangle {
                             x: 0.0,
                             y: 0.0,
                             width: 50.0,
                             height: 50.0,
                         })),
                         AspectRatio::parse("xMidYMid meet", ()).unwrap(),
                         cairo::Matrix::identity(),
                         &mut ctx);
    }
}
<|endoftext|>


<commit_before><commit_msg>ARM  ARM DSP/SIMD32: Sum of 8-bit absolute differences (#537)<commit_after><|endoftext|>


<commit_before>extern crate hwloc;
extern crate libc;

use hwloc::{Topology, ObjectType, CPUBIND_THREAD, CpuSet};
use std::thread;
use std::sync::{Arc,Mutex};

/// Example which spawns one thread per core and then assigns it to each.
fn main() {
    let topo = Arc::new(Mutex::new(Topology::new()));

    // Grab the number of cores in a block so that the lock is removed once
    // the end of the block is reached.
    let num_cores = {
        let topo_rc = topo.clone();
        let topo_locked = topo_rc.lock().unwrap();
        (*topo_locked).objects_with_type(&ObjectType::Core).unwrap().len()
    };
    println!("Found {} cores.", num_cores);

    // Spawn one thread for each and pass the topology down into scope.
    let handles: Vec<_> = (0..num_cores).map(|i| {
            let child_topo = topo.clone();
            thread::spawn(move || {
                // Get the current thread id and lock the topology to use.
                let tid = get_thread_id();
                let mut locked_topo = child_topo.lock().unwrap();

                // Thread binding before explicit set.
                let before = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);

                // Create a CPU binding for the current thread.
                let mut bind_to = CpuSet::new();
                bind_to.set((i as u32));

                // Set the binding.
                locked_topo.set_cpubinding_for_thread(tid, bind_to, CPUBIND_THREAD).unwrap();

                // Thread binding after explicit set.
                let after = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);
                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
            })
        }).collect();

        // Wait for all threads to complete before ending the program.
        for h in handles {
            h.join().unwrap();
        }
}

/// Helper method to get the thread id through libc, with current rust stable (1.5.0) its not
/// possible otherwise I think.
fn get_thread_id() -> u64 {
    unsafe { libc::pthread_self() }
}
<commit_msg>example output<commit_after>extern crate hwloc;
extern crate libc;

use hwloc::{Topology, ObjectType, CPUBIND_THREAD, CpuSet};
use std::thread;
use std::sync::{Arc,Mutex};

/// Example which spawns one thread per core and then assigns it to each.
///
/// Example Output with 2 cores (no HT) on linux:
///
/// ```
/// Found 2 cores.
/// Thread 0: Before Some(0-1), After Some(0)
/// Thread 1: Before Some(0-1), After Some(1)
/// ```
fn main() {
    let topo = Arc::new(Mutex::new(Topology::new()));

    // Grab the number of cores in a block so that the lock is removed once
    // the end of the block is reached.
    let num_cores = {
        let topo_rc = topo.clone();
        let topo_locked = topo_rc.lock().unwrap();
        (*topo_locked).objects_with_type(&ObjectType::Core).unwrap().len()
    };
    println!("Found {} cores.", num_cores);

    // Spawn one thread for each and pass the topology down into scope.
    let handles: Vec<_> = (0..num_cores).map(|i| {
            let child_topo = topo.clone();
            thread::spawn(move || {
                // Get the current thread id and lock the topology to use.
                let tid = get_thread_id();
                let mut locked_topo = child_topo.lock().unwrap();

                // Thread binding before explicit set.
                let before = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);

                // Create a CPU binding for the current thread.
                let mut bind_to = CpuSet::new();
                bind_to.set((i as u32));

                // Set the binding.
                locked_topo.set_cpubinding_for_thread(tid, bind_to, CPUBIND_THREAD).unwrap();

                // Thread binding after explicit set.
                let after = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);
                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
            })
        }).collect();

        // Wait for all threads to complete before ending the program.
        for h in handles {
            h.join().unwrap();
        }
}

/// Helper method to get the thread id through libc, with current rust stable (1.5.0) its not
/// possible otherwise I think.
fn get_thread_id() -> u64 {
    unsafe { libc::pthread_self() }
}
<|endoftext|>


<commit_before>extern crate hwloc;
extern crate libc;

use hwloc::{Topology, ObjectType, CPUBIND_THREAD, CpuSet};
use std::thread;
use std::sync::{Arc,Mutex};

/// Example which spawns one thread per core and then assigns it to each.
///
/// Example Output with 2 cores (no HT) on linux:
///
/// ```
/// Found 2 cores.
/// Thread 0: Before Some(0-1), After Some(0)
/// Thread 1: Before Some(0-1), After Some(1)
/// ```
fn main() {
    let topo = Arc::new(Mutex::new(Topology::new()));

    // Grab the number of cores in a block so that the lock is removed once
    // the end of the block is reached.
    let num_cores = {
        let topo_rc = topo.clone();
        let topo_locked = topo_rc.lock().unwrap();
        (*topo_locked).objects_with_type(&ObjectType::Core).unwrap().len()
    };
    println!("Found {} cores.", num_cores);

    // Spawn one thread for each and pass the topology down into scope.
    let handles: Vec<_> = (0..num_cores).map(|i| {
            let child_topo = topo.clone();
            thread::spawn(move || {
                // Get the current thread id and lock the topology to use.
                let tid = get_thread_id();
                let mut locked_topo = child_topo.lock().unwrap();

                // Thread binding before explicit set.
                let before = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);

                // Create a CPU binding for the current thread.
                let mut bind_to = CpuSet::new();
                bind_to.set((i as u32));

                // Set the binding.
                locked_topo.set_cpubinding_for_thread(tid, bind_to, CPUBIND_THREAD).unwrap();

                // Thread binding after explicit set.
                let after = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);
                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
            })
        }).collect();

        // Wait for all threads to complete before ending the program.
        for h in handles {
            h.join().unwrap();
        }
}

/// Helper method to get the thread id through libc, with current rust stable (1.5.0) its not
/// possible otherwise I think.
fn get_thread_id() -> u64 {
    unsafe { libc::pthread_self() }
}
<commit_msg>dont assume pthread_t type<commit_after>extern crate hwloc;
extern crate libc;

use hwloc::{Topology, ObjectType, CPUBIND_THREAD, CpuSet};
use std::thread;
use std::sync::{Arc,Mutex};

/// Example which spawns one thread per core and then assigns it to each.
///
/// Example Output with 2 cores (no HT) on linux:
///
/// ```
/// Found 2 cores.
/// Thread 0: Before Some(0-1), After Some(0)
/// Thread 1: Before Some(0-1), After Some(1)
/// ```
fn main() {
    let topo = Arc::new(Mutex::new(Topology::new()));

    // Grab the number of cores in a block so that the lock is removed once
    // the end of the block is reached.
    let num_cores = {
        let topo_rc = topo.clone();
        let topo_locked = topo_rc.lock().unwrap();
        (*topo_locked).objects_with_type(&ObjectType::Core).unwrap().len()
    };
    println!("Found {} cores.", num_cores);

    // Spawn one thread for each and pass the topology down into scope.
    let handles: Vec<_> = (0..num_cores).map(|i| {
            let child_topo = topo.clone();
            thread::spawn(move || {
                // Get the current thread id and lock the topology to use.
                let tid = get_thread_id();
                let mut locked_topo = child_topo.lock().unwrap();

                // Thread binding before explicit set.
                let before = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);

                // Create a CPU binding for the current thread.
                let mut bind_to = CpuSet::new();
                bind_to.set((i as u32));

                // Set the binding.
                locked_topo.set_cpubinding_for_thread(tid, bind_to, CPUBIND_THREAD).unwrap();

                // Thread binding after explicit set.
                let after = locked_topo.get_cpubinding_for_thread(tid, CPUBIND_THREAD);
                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
            })
        }).collect();

        // Wait for all threads to complete before ending the program.
        for h in handles {
            h.join().unwrap();
        }
}

/// Helper method to get the thread id through libc, with current rust stable (1.5.0) its not
/// possible otherwise I think.
fn get_thread_id() -> libc::pthread_t {
    unsafe { libc::pthread_self() }
}
<|endoftext|>


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

//! An example of using simplex noise

extern crate noise;

use noise::{open_simplex2, open_simplex3, Seed, Point2};

mod debug;

fn main() {
    debug::render_png("open_simplex2.png", &Seed::new(0), 1024, 1024, scaled_open_simplex2);
    debug::render_png("open_simplex3.png", &Seed::new(0), 1024, 1024, scaled_open_simplex3);
    println!("\nGenerated open_simplex2.png and open_simplex3.png");
}

fn scaled_open_simplex2(seed: &Seed, point: &Point2<f64>) -> f64 {
    open_simplex2(seed, &[point[0] / 16.0, point[1] / 16.0])
}

fn scaled_open_simplex3(seed: &Seed, point: &Point2<f64>) -> f64 {
    open_simplex3(seed, &[point[0] / 16.0, point[1] / 16.0, point[0] / 32.0])
}
<commit_msg>Add examples<commit_after>// Copyright 2015 The Noise-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using simplex noise

extern crate noise;

use noise::{open_simplex2, open_simplex3, open_simplex4, Seed, Point2};

mod debug;

fn main() {
    debug::render_png("open_simplex2.png", &Seed::new(0), 1024, 1024, scaled_open_simplex2);
    debug::render_png("open_simplex3.png", &Seed::new(0), 1024, 1024, scaled_open_simplex3);
    debug::render_png("open_simplex4.png", &Seed::new(0), 1024, 1024, scaled_open_simplex4);
    println!("\nGenerated open_simplex2.png, open_simplex3.png and open_simplex4.png");
}

fn scaled_open_simplex2(seed: &Seed, point: &Point2<f64>) -> f64 {
    open_simplex2(seed, &[point[0] / 16.0, point[1] / 16.0])
}

fn scaled_open_simplex3(seed: &Seed, point: &Point2<f64>) -> f64 {
    open_simplex3(seed, &[point[0] / 16.0, point[1] / 16.0, point[0] / 32.0])
}

fn scaled_open_simplex4(seed: &Seed, point: &Point2<f64>) -> f64 {
    open_simplex4(seed, &[point[0] / 16.0, point[1] / 16.0, point[0] / 32.0, point[1] / 32.0])
}
<|endoftext|>


<commit_before>extern crate c_ares_sys;
extern crate libc;

use std::ffi::CStr;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;
use std::str;

use types::AresError;
use utils::ares_error;

/// The result of a successful lookup for an MX record.
pub struct MXResults {
    // A list of replies.
    mx_reply: *mut c_ares_sys::Struct_ares_mx_reply,
}

/// The contents of a single MX record.
pub struct MXResult<'a> {
    // A single reply.
    mx_reply: *mut c_ares_sys::Struct_ares_mx_reply,
    phantom: PhantomData<&'a MXResults>,
}

impl MXResults {
    /// Obtain an `MXResults` from the response to an MX lookup.
    pub fn parse_from(data: &[u8]) -> Result<MXResults, AresError> {
        let mut mx_reply: *mut c_ares_sys::Struct_ares_mx_reply = ptr::null_mut();
        let parse_status = unsafe {
            c_ares_sys::ares_parse_mx_reply(
                data.as_ptr(),
                data.len() as libc::c_int,
                &mut mx_reply)
        };
        if parse_status != c_ares_sys::ARES_SUCCESS {
            Err(ares_error(parse_status))
        } else {
            let result = MXResults::new(mx_reply);
            Ok(result)
        }
    }
    fn new(mx_reply: *mut c_ares_sys::Struct_ares_mx_reply) -> MXResults {
        MXResults {
            mx_reply: mx_reply,
        }
    }

    /// Returns an iterator over the `MXResult` values in this `MXResults`.
    pub fn iter(&self) -> MXResultsIterator {
        MXResultsIterator {
            next: self.mx_reply,
            phantom: PhantomData,
        }
    }
}

pub struct MXResultsIterator<'a> {
    next: *mut c_ares_sys::Struct_ares_mx_reply,
    phantom: PhantomData<&'a MXResults>,
}

impl<'a> Iterator for MXResultsIterator<'a> {
    type Item = MXResult<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        let mx_reply = self.next;
        if mx_reply.is_null() {
            None
        } else {
            unsafe {
                self.next = (*mx_reply).next;
                let mx_result = MXResult {
                    mx_reply: mx_reply,
                    phantom: PhantomData,
                };
                Some(mx_result)
            }
        }
    }
}

impl Drop for MXResults {
    fn drop(&mut self) {
        unsafe {
            c_ares_sys::ares_free_data(self.mx_reply as *mut libc::c_void);
        }
    }
}

impl<'a> MXResult<'a> {
    pub fn host(&self) -> &str {
        unsafe {
            let c_str = CStr::from_ptr((*self.mx_reply).host);
            str::from_utf8_unchecked(c_str.to_bytes())
        }
    }

    pub fn priority(&self) -> u16 {
        unsafe { (*self.mx_reply).priority }
    }
}

pub unsafe extern "C" fn query_mx_callback<F>(
    arg: *mut libc::c_void,
    status: libc::c_int,
    _timeouts: libc::c_int,
    abuf: *mut libc::c_uchar,
    alen: libc::c_int)
    where F: FnOnce(Result<MXResults, AresError>) + 'static {
    let result = if status != c_ares_sys::ARES_SUCCESS {
        Err(ares_error(status))
    } else {
        let data = slice::from_raw_parts(abuf, alen as usize);
        MXResults::parse_from(data)
    };
    let handler: Box<F> = mem::transmute(arg);
    handler(result);
}
<commit_msg>Documentation<commit_after>extern crate c_ares_sys;
extern crate libc;

use std::ffi::CStr;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;
use std::str;

use types::AresError;
use utils::ares_error;

/// The result of a successful lookup for an MX record.
pub struct MXResults {
    // A list of replies.  Owned by the `MXResults`.
    mx_reply: *mut c_ares_sys::Struct_ares_mx_reply,
}

/// The contents of a single MX record.
pub struct MXResult<'a> {
    // A single reply.  Just a reference to a value in an `MXResults`.
    mx_reply: *mut c_ares_sys::Struct_ares_mx_reply,
    phantom: PhantomData<&'a MXResults>,
}

impl MXResults {
    /// Obtain an `MXResults` from the response to an MX lookup.
    pub fn parse_from(data: &[u8]) -> Result<MXResults, AresError> {
        let mut mx_reply: *mut c_ares_sys::Struct_ares_mx_reply = ptr::null_mut();
        let parse_status = unsafe {
            c_ares_sys::ares_parse_mx_reply(
                data.as_ptr(),
                data.len() as libc::c_int,
                &mut mx_reply)
        };
        if parse_status != c_ares_sys::ARES_SUCCESS {
            Err(ares_error(parse_status))
        } else {
            let result = MXResults::new(mx_reply);
            Ok(result)
        }
    }
    fn new(mx_reply: *mut c_ares_sys::Struct_ares_mx_reply) -> MXResults {
        MXResults {
            mx_reply: mx_reply,
        }
    }

    /// Returns an iterator over the `MXResult` values in this `MXResults`.
    pub fn iter(&self) -> MXResultsIterator {
        MXResultsIterator {
            next: self.mx_reply,
            phantom: PhantomData,
        }
    }
}

pub struct MXResultsIterator<'a> {
    next: *mut c_ares_sys::Struct_ares_mx_reply,
    phantom: PhantomData<&'a MXResults>,
}

impl<'a> Iterator for MXResultsIterator<'a> {
    type Item = MXResult<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        let mx_reply = self.next;
        if mx_reply.is_null() {
            None
        } else {
            unsafe {
                self.next = (*mx_reply).next;
                let mx_result = MXResult {
                    mx_reply: mx_reply,
                    phantom: PhantomData,
                };
                Some(mx_result)
            }
        }
    }
}

impl Drop for MXResults {
    fn drop(&mut self) {
        unsafe {
            c_ares_sys::ares_free_data(self.mx_reply as *mut libc::c_void);
        }
    }
}

impl<'a> MXResult<'a> {
    /// Returns the hostname in this `MXResult`.
    pub fn host(&self) -> &str {
        unsafe {
            let c_str = CStr::from_ptr((*self.mx_reply).host);
            str::from_utf8_unchecked(c_str.to_bytes())
        }
    }

    /// Returns the priority from this `MXResult`.
    pub fn priority(&self) -> u16 {
        unsafe { (*self.mx_reply).priority }
    }
}

pub unsafe extern "C" fn query_mx_callback<F>(
    arg: *mut libc::c_void,
    status: libc::c_int,
    _timeouts: libc::c_int,
    abuf: *mut libc::c_uchar,
    alen: libc::c_int)
    where F: FnOnce(Result<MXResults, AresError>) + 'static {
    let result = if status != c_ares_sys::ARES_SUCCESS {
        Err(ares_error(status))
    } else {
        let data = slice::from_raw_parts(abuf, alen as usize);
        MXResults::parse_from(data)
    };
    let handler: Box<F> = mem::transmute(arg);
    handler(result);
}
<|endoftext|>


<commit_before>use error::RuntimeError;
use frame::GPUFrame;

use sys::win32;
use sys::wgl;
use sys::gl;

pub struct WglContext {
   pub context: wgl::Context,
}

impl WglContext {
   pub fn new(device_context: &win32::DeviceContext) -> Result<Self, RuntimeError> {
      try!(wgl::init_pixel_format(device_context));

      let context = try!(wgl::Context::create(device_context));

      try!(Self::init_gl());

      try!(wgl::swap_interval(0));

      Ok(WglContext {
         context: context,
      })
   }

   #[inline]
   pub fn init_gl() -> Result<(), RuntimeError> {
      let loader = wgl::Loader::new();
      gl::load(&loader);
      wgl::load(&loader);

      try!(gl::reset_pixelstore_alignment());
      try!(gl::enable_framebuffer_srgb());

      Ok(())
   }

   #[inline]
   pub fn create_gpu_frame(
      &self, width: u32, height: u32
   ) -> Result<Box<GPUFrame>, RuntimeError> {

      match gl::gl_frame::GLFrame::new(width, height) {
         Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
         Err(e) => Err(e)
      }
   }
}
<commit_msg>Fixing a Windows compilation error after last commit<commit_after>use error::RuntimeError;
use frame::GPUFrame;

use sys::win32;
use sys::wgl;
use sys::gl;

pub struct WglContext {
   pub context: wgl::Context,
}

impl WglContext {
   pub fn new(device_context: &win32::DeviceContext) -> Result<Self, RuntimeError> {
      try!(wgl::init_pixel_format(device_context));

      let context = try!(wgl::Context::create(device_context));

      try!(Self::init_gl());

      try!(wgl::swap_interval(0));

      Ok(WglContext {
         context: context,
      })
   }

   #[inline]
   pub fn init_gl() -> Result<(), RuntimeError> {
      let loader = wgl::Loader::new();
      gl::load(&loader);
      wgl::load(&loader);

      try!(gl::reset_pixelstore_alignment());
      try!(gl::enable_framebuffer_srgb());

      Ok(())
   }

   #[inline]
   pub fn create_gpu_frame(
      &self, width: u32, height: u32
   ) -> Result<Box<GPUFrame>, RuntimeError> {

      match gl::frame::buffer::BufferFrame::new(width, height) {
         Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
         Err(e) => Err(e)
      }
   }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use std::io;
    use std::fs::File;
    use Rng;
    use read::ReadRng;
    use std::mem;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64",
                  target_arch = "x86",
                  target_arch = "arm",
                  target_arch = "aarch64",
                  target_arch = "powerpc")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
        const NR_GETRANDOM: libc::c_long = 384;
        #[cfg(target_arch = "powerpc")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64",
                      target_arch = "x86",
                      target_arch = "arm",
                      target_arch = "aarch64",
                      target_arch = "powerpc"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(&mut v[read..]);
            if result == -1 {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::Interrupted {
                    continue
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as usize;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8; 4] = [0u8; 4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8; 4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8; 8] = [0u8; 8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8; 8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64",
                  target_arch = "x86",
                  target_arch = "arm",
                  target_arch = "aarch64",
                  target_arch = "powerpc")))]
    fn is_getrandom_available() -> bool {
        use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};

        static GETRANDOM_CHECKED: AtomicBool = ATOMIC_BOOL_INIT;
        static GETRANDOM_AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;

        if !GETRANDOM_CHECKED.load(Ordering::Relaxed) {
            let mut buf: [u8; 0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = io::Error::last_os_error().raw_os_error();
                err != Some(libc::ENOSYS)
            } else {
                true
            };
            GETRANDOM_AVAILABLE.store(available, Ordering::Relaxed);
            GETRANDOM_CHECKED.store(true, Ordering::Relaxed);
            available
        } else {
            GETRANDOM_AVAILABLE.load(Ordering::Relaxed)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64",
                      target_arch = "x86",
                      target_arch = "arm",
                      target_arch = "aarch64",
                      target_arch = "powerpc"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReadRng(ReadRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open("/dev/urandom"));
            let reader_rng = ReadRng::new(reader);

            Ok(OsRng { inner: OsReadRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReadRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReadRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReadRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use std::io;
    use std::mem;
    use Rng;
    use self::libc::{c_int, size_t};

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        // dummy field to ensure that this struct cannot be constructed outside of this module
        _dummy: (),
    }

    #[repr(C)]
    struct SecRandom;

    #[allow(non_upper_case_globals)]
    const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            Ok(OsRng { _dummy: () })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8; 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8; 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use std::io;
    use std::mem;
    use Rng;
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    const PROV_RSA_FULL: DWORD = 1;
    const CRYPT_SILENT: DWORD = 64;
    const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8; 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8; 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}",
                       io::Error::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}",
                       io::Error::last_os_error());
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::sync::mpsc::channel;
    use Rng;
    use OsRng;
    use std::thread;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8; 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in 0..20 {
            let (tx, rx) = channel();
            txs.push(tx);

            thread::spawn(move|| {
                // wait until all the tasks are ready to go.
                rx.recv().unwrap();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                thread::yield_now();
                let mut v = [0u8; 1000];

                for _ in 0..100 {
                    r.next_u32();
                    thread::yield_now();
                    r.next_u64();
                    thread::yield_now();
                    r.fill_bytes(&mut v);
                    thread::yield_now();
                }
            });
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(()).unwrap();
        }
    }
}
<commit_msg>os: Fix race condition of atomics<commit_after>// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use std::io;
    use std::fs::File;
    use Rng;
    use read::ReadRng;
    use std::mem;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64",
                  target_arch = "x86",
                  target_arch = "arm",
                  target_arch = "aarch64",
                  target_arch = "powerpc")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
        const NR_GETRANDOM: libc::c_long = 384;
        #[cfg(target_arch = "powerpc")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64",
                      target_arch = "x86",
                      target_arch = "arm",
                      target_arch = "aarch64",
                      target_arch = "powerpc"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(&mut v[read..]);
            if result == -1 {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::Interrupted {
                    continue
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as usize;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8; 4] = [0u8; 4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8; 4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8; 8] = [0u8; 8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8; 8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64",
                  target_arch = "x86",
                  target_arch = "arm",
                  target_arch = "aarch64",
                  target_arch = "powerpc")))]
    fn is_getrandom_available() -> bool {
        use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
        use std::sync::{Once, ONCE_INIT};

        static CHECKER: Once = ONCE_INIT;
        static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;

        CHECKER.call_once(|| {
            let mut buf: [u8; 0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = io::Error::last_os_error().raw_os_error();
                err != Some(libc::ENOSYS)
            } else {
                true
            };
            AVAILABLE.store(available, Ordering::Relaxed);
        });

        AVAILABLE.load(Ordering::Relaxed)
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64",
                      target_arch = "x86",
                      target_arch = "arm",
                      target_arch = "aarch64",
                      target_arch = "powerpc"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReadRng(ReadRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open("/dev/urandom"));
            let reader_rng = ReadRng::new(reader);

            Ok(OsRng { inner: OsReadRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReadRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReadRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReadRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use std::io;
    use std::mem;
    use Rng;
    use self::libc::{c_int, size_t};

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        // dummy field to ensure that this struct cannot be constructed outside of this module
        _dummy: (),
    }

    #[repr(C)]
    struct SecRandom;

    #[allow(non_upper_case_globals)]
    const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            Ok(OsRng { _dummy: () })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8; 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8; 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use std::io;
    use std::mem;
    use Rng;
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    const PROV_RSA_FULL: DWORD = 1;
    const CRYPT_SILENT: DWORD = 64;
    const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> io::Result<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8; 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8; 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}",
                       io::Error::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}",
                       io::Error::last_os_error());
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::sync::mpsc::channel;
    use Rng;
    use OsRng;
    use std::thread;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8; 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in 0..20 {
            let (tx, rx) = channel();
            txs.push(tx);

            thread::spawn(move|| {
                // wait until all the tasks are ready to go.
                rx.recv().unwrap();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                thread::yield_now();
                let mut v = [0u8; 1000];

                for _ in 0..100 {
                    r.next_u32();
                    thread::yield_now();
                    r.next_u64();
                    thread::yield_now();
                    r.fill_bytes(&mut v);
                    thread::yield_now();
                }
            });
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(()).unwrap();
        }
    }
}
<|endoftext|>


<commit_before>use ruby_sys::class;
use ruby_sys::value::RubySpecialConsts::Nil;

pub use ruby_sys::types::{CallbackPtr, Value};
pub const RB_NIL: Value = Value { value: Nil as usize };

//
// Helper functions/macros for dealing with Ruby and CStrings
//

macro_rules! str2cstr {
  ($s:expr) => { ::std::ffi::CString::new($s).unwrap() }
}

macro_rules! str2cstrp {
  ($s:expr) => { str2cstr!($s).as_ptr() }
}

macro_rules! rbstr2cstrp {
  ($s:expr) => { ::ruby_sys::string::rb_string_value_cstr($s) }
}

macro_rules! rbstr2str {
  ($s:expr) => {
    unsafe { ::std::ffi::CStr::from_ptr(rbstr2cstrp!($s)).to_str().unwrap() }
  }
}

macro_rules! str2sym {
  ($s:expr) => {
    unsafe {
      let id = ::ruby_sys::util::rb_intern(str2cstrp!($s));
      ::ruby_sys::symbol::rb_id2sym(id)
    }
  }
}

pub fn define_module(name: &str) -> Value {
  unsafe { class::rb_define_module(str2cstrp!(name)) }
}

pub fn define_module_under(parent: &Value, name: &str) -> Value {
  unsafe { class::rb_define_module_under(*parent, str2cstrp!(name)) }
}

pub fn define_method(module: &Value, name: &str, method: CallbackPtr, argc: i32) {
  unsafe { class::rb_define_method(*module, str2cstrp!(name), method, argc) }
}

pub fn extend_object(object: &Value, module: &Value) {
  unsafe { class::rb_extend_object(*object, *module) }
}
<commit_msg>Split str2sym macro into two simpler macros.<commit_after>use ruby_sys::class;
use ruby_sys::value::RubySpecialConsts::Nil;

pub use ruby_sys::types::{CallbackPtr, Value};
pub const RB_NIL: Value = Value { value: Nil as usize };

//
// Helper functions/macros for dealing with Ruby and CStrings
//

macro_rules! str2cstr {
  ($s:expr) => { ::std::ffi::CString::new($s).unwrap() }
}

macro_rules! str2cstrp {
  ($s:expr) => { str2cstr!($s).as_ptr() }
}

macro_rules! rbstr2cstrp {
  ($s:expr) => { ::ruby_sys::string::rb_string_value_cstr($s) }
}

macro_rules! rbstr2str {
  ($s:expr) => {
    unsafe { ::std::ffi::CStr::from_ptr(rbstr2cstrp!($s)).to_str().unwrap() }
  }
}

macro_rules! str2rbid {
  ($s:expr) => { ::ruby_sys::util::rb_intern(str2cstrp!($s)) }
}

macro_rules! str2sym {
  ($s:expr) => {
    unsafe { ::ruby_sys::symbol::rb_id2sym(str2rbid!($s)) }
  }
}

pub fn define_module(name: &str) -> Value {
  unsafe { class::rb_define_module(str2cstrp!(name)) }
}

pub fn define_module_under(parent: &Value, name: &str) -> Value {
  unsafe { class::rb_define_module_under(*parent, str2cstrp!(name)) }
}

pub fn define_method(module: &Value, name: &str, method: CallbackPtr, argc: i32) {
  unsafe { class::rb_define_method(*module, str2cstrp!(name), method, argc) }
}

pub fn extend_object(object: &Value, module: &Value) {
  unsafe { class::rb_extend_object(*object, *module) }
}
<|endoftext|>


<commit_before>use find_folder;
use conrod::{
    Button, Canvas, Colorable, Frameable, Positionable, Labelable, Sizeable, Theme,
    Ui, UiCell, Text, Widget, color
};
use piston_window::{G2d, Glyphs, Graphics, PistonWindow};

use game::{Rustris, GameState};
use stats::GameStats;
use settings::*;
use tetromino::Piece;

pub type Backend = (<G2d<'static> as Graphics>::Texture, Glyphs);
pub type UI = Ui<Backend>;
pub type UICell<'a> = UiCell<'a, Backend>;

pub fn create_ui(window: &PistonWindow) -> UI {
    let assets = find_folder::Search::KidsThenParents(3, 5)
        .for_folder("assets").unwrap();
    let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
    let theme = Theme::default();
    let glyph_cache = Glyphs::new(&font_path, window.factory.clone());
    UI::new(glyph_cache.unwrap(), theme)
}

pub fn set_ui(ref mut ui: UICell, game: &mut Rustris) {
    Canvas::new().flow_right(&[
        (LEFT_COLUMN, Canvas::new().color(color::DARK_CHARCOAL).pad(20.0)),
        (MIDDLE_COLUMN, Canvas::new().color(color::TRANSPARENT).length(300.0)),
        (RIGHT_COLUMN, Canvas::new().color(color::DARK_CHARCOAL).pad(20.0)),
    ]).set(MASTER, ui);
    set_scoreboard(ui, game.get_game_stats());
    set_next_piece(ui, game.get_next_piece());

    if game.is_paused() {
        set_pause_menu(ui, game);
    } else if game.is_game_over() {
        set_game_over_menu(ui, game);
    }

}

fn set_pause_menu(ui: &mut UICell, game: &mut Rustris) {
    Canvas::new()
      .w_h(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64)
      .floating(true)
      .middle_of(MASTER)
      .rgba(0.0, 0.0, 0.0, 0.3)
      .set(PAUSE_OVERLAY, ui);

    Canvas::new().flow_down(&[
        (RESUME_CANVAS, Canvas::new()),
        (QUIT_CANVAS, Canvas::new())
    ]).label("Paused")
      .label_color(color::WHITE)
      .w_h(200.0, 200.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .middle_of(PAUSE_OVERLAY)
      .set(PAUSE_MENU, ui);

    Button::new()
        .label("Resume")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(RESUME_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {
            game.set_game_state(GameState::Playing);
        })
        .set(RESUME_BUTTON, ui);

    Button::new()
        .label("Quit")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(QUIT_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {})
        .set(QUIT_BUTTON, ui);
}

fn set_game_over_menu(ui: &mut UICell, game: &mut Rustris) {
    Canvas::new()
      .w_h(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64)
      .floating(true)
      .middle_of(MASTER)
      .rgba(0.0, 0.0, 0.0, 0.3)
      .set(GAME_OVER_OVERLAY, ui);

    Canvas::new().flow_down(&[
        (FINAL_SCORE_CANVAS, Canvas::new()),
        (RESTART_CANVAS, Canvas::new())
    ]).label("Game Over")
      .label_color(color::WHITE)
      .w_h(200.0, 200.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .middle_of(GAME_OVER_OVERLAY)
      .set(GAME_OVER_MENU, ui);

    {
        let stats = game.get_game_stats();
        Text::new(
            &format!("Final Score: {}", stats.get_score().to_string()))
            .color(color::WHITE)
            .middle_of(FINAL_SCORE_CANVAS)
            .set(FINAL_SCORE_TEXT, ui);
    }

    Button::new()
        .label("New Game?")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(RESTART_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {
            game.reset();
        })
        .set(NEW_GAME_BUTTON, ui);
}

fn set_scoreboard(ui: &mut UICell, stats: &GameStats) {
    Canvas::new().flow_down(&[
        (SCORE_CANVAS, Canvas::new().label("Score").label_color(color::WHITE)),
        (LEVEL_CANVAS, Canvas::new().label("Level").label_color(color::WHITE)),
        (LINES_CANVAS, Canvas::new().label("Lines").label_color(color::WHITE))
    ]).w_h(150.0, 250.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .mid_bottom_of(LEFT_COLUMN)
      .set(SCOREBOARD, ui);

    Text::new(&stats.get_score().to_string())
        .color(color::WHITE)
        .middle_of(SCORE_CANVAS)
        .set(SCORE, ui);
    Text::new(&stats.get_level().to_string())
        .color(color::WHITE)
        .middle_of(LEVEL_CANVAS)
        .set(LEVEL, ui);
    Text::new(&stats.get_lines().to_string())
        .color(color::WHITE)
        .middle_of(LINES_CANVAS)
        .set(LINES, ui);
}

fn set_next_piece(ui: &mut UICell, next_piece: &Piece) {
    Canvas::new()
        .label("Next Piece")
        .label_color(color::WHITE)
        .w_h(150.0, 150.0)
        .frame(1.0)
        .frame_color(color::WHITE)
        .pad(1.0)
        .mid_top_of(RIGHT_COLUMN)
        .set(NEXT_PIECE, ui);
}

widget_ids! {
    // Canvas IDs
    MASTER,
    LEFT_COLUMN,
    MIDDLE_COLUMN,
    RIGHT_COLUMN,

    // Scoreboard IDs
    SCOREBOARD,
    SCORE_CANVAS,
    LEVEL_CANVAS,
    LINES_CANVAS,
    SCORE,
    LEVEL,
    LINES,

    // Pause Menu
    PAUSE_OVERLAY,
    PAUSE_MENU,
    RESUME_CANVAS,
    RESUME_BUTTON,
    QUIT_CANVAS,
    QUIT_BUTTON,

    // Game Over Menu
    GAME_OVER_OVERLAY,
    GAME_OVER_MENU,
    NEW_GAME_BUTTON,
    RESTART_CANVAS,
    FINAL_SCORE_CANVAS,
    FINAL_SCORE_TEXT,

    // Next Piece IDs
    NEXT_PIECE
}
<commit_msg>remove the extraneous next piece<commit_after>use find_folder;
use conrod::{
    Button, Canvas, Colorable, Frameable, Positionable, Labelable, Sizeable, Theme,
    Ui, UiCell, Text, Widget, color
};
use piston_window::{G2d, Glyphs, Graphics, PistonWindow};

use game::{Rustris, GameState};
use stats::GameStats;
use settings::*;

pub type Backend = (<G2d<'static> as Graphics>::Texture, Glyphs);
pub type UI = Ui<Backend>;
pub type UICell<'a> = UiCell<'a, Backend>;

pub fn create_ui(window: &PistonWindow) -> UI {
    let assets = find_folder::Search::KidsThenParents(3, 5)
        .for_folder("assets").unwrap();
    let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
    let theme = Theme::default();
    let glyph_cache = Glyphs::new(&font_path, window.factory.clone());
    UI::new(glyph_cache.unwrap(), theme)
}

pub fn set_ui(ref mut ui: UICell, game: &mut Rustris) {
    Canvas::new().flow_right(&[
        (LEFT_COLUMN, Canvas::new().color(color::DARK_CHARCOAL).pad(20.0)),
        (MIDDLE_COLUMN, Canvas::new().color(color::TRANSPARENT).length(300.0)),
        (RIGHT_COLUMN, Canvas::new().color(color::DARK_CHARCOAL).pad(20.0)),
    ]).set(MASTER, ui);
    set_scoreboard(ui, game.get_game_stats());
    set_next_piece(ui);

    if game.is_paused() {
        set_pause_menu(ui, game);
    } else if game.is_game_over() {
        set_game_over_menu(ui, game);
    }

}

fn set_pause_menu(ui: &mut UICell, game: &mut Rustris) {
    Canvas::new()
      .w_h(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64)
      .floating(true)
      .middle_of(MASTER)
      .rgba(0.0, 0.0, 0.0, 0.3)
      .set(PAUSE_OVERLAY, ui);

    Canvas::new().flow_down(&[
        (RESUME_CANVAS, Canvas::new()),
        (QUIT_CANVAS, Canvas::new())
    ]).label("Paused")
      .label_color(color::WHITE)
      .w_h(200.0, 200.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .middle_of(PAUSE_OVERLAY)
      .set(PAUSE_MENU, ui);

    Button::new()
        .label("Resume")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(RESUME_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {
            game.set_game_state(GameState::Playing);
        })
        .set(RESUME_BUTTON, ui);

    Button::new()
        .label("Quit")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(QUIT_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {})
        .set(QUIT_BUTTON, ui);
}

fn set_game_over_menu(ui: &mut UICell, game: &mut Rustris) {
    Canvas::new()
      .w_h(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64)
      .floating(true)
      .middle_of(MASTER)
      .rgba(0.0, 0.0, 0.0, 0.3)
      .set(GAME_OVER_OVERLAY, ui);

    Canvas::new().flow_down(&[
        (FINAL_SCORE_CANVAS, Canvas::new()),
        (RESTART_CANVAS, Canvas::new())
    ]).label("Game Over")
      .label_color(color::WHITE)
      .w_h(200.0, 200.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .middle_of(GAME_OVER_OVERLAY)
      .set(GAME_OVER_MENU, ui);

    {
        let stats = game.get_game_stats();
        Text::new(
            &format!("Final Score: {}", stats.get_score().to_string()))
            .color(color::WHITE)
            .middle_of(FINAL_SCORE_CANVAS)
            .set(FINAL_SCORE_TEXT, ui);
    }

    Button::new()
        .label("New Game?")
        .label_color(color::WHITE)
        .color(color::CHARCOAL)
        .middle_of(RESTART_CANVAS)
        .w_h(150.0, 30.0)
        .react(|| {
            game.reset();
        })
        .set(NEW_GAME_BUTTON, ui);
}

fn set_scoreboard(ui: &mut UICell, stats: &GameStats) {
    Canvas::new().flow_down(&[
        (SCORE_CANVAS, Canvas::new().label("Score").label_color(color::WHITE)),
        (LEVEL_CANVAS, Canvas::new().label("Level").label_color(color::WHITE)),
        (LINES_CANVAS, Canvas::new().label("Lines").label_color(color::WHITE))
    ]).w_h(150.0, 250.0)
      .frame(1.0)
      .frame_color(color::WHITE)
      .pad(1.0)
      .mid_bottom_of(LEFT_COLUMN)
      .set(SCOREBOARD, ui);

    Text::new(&stats.get_score().to_string())
        .color(color::WHITE)
        .middle_of(SCORE_CANVAS)
        .set(SCORE, ui);
    Text::new(&stats.get_level().to_string())
        .color(color::WHITE)
        .middle_of(LEVEL_CANVAS)
        .set(LEVEL, ui);
    Text::new(&stats.get_lines().to_string())
        .color(color::WHITE)
        .middle_of(LINES_CANVAS)
        .set(LINES, ui);
}

fn set_next_piece(ui: &mut UICell) {
    Canvas::new()
        .label("Next Piece")
        .label_color(color::WHITE)
        .w_h(150.0, 150.0)
        .frame(1.0)
        .frame_color(color::WHITE)
        .pad(1.0)
        .mid_top_of(RIGHT_COLUMN)
        .set(NEXT_PIECE, ui);
}

widget_ids! {
    // Canvas IDs
    MASTER,
    LEFT_COLUMN,
    MIDDLE_COLUMN,
    RIGHT_COLUMN,

    // Scoreboard IDs
    SCOREBOARD,
    SCORE_CANVAS,
    LEVEL_CANVAS,
    LINES_CANVAS,
    SCORE,
    LEVEL,
    LINES,

    // Pause Menu
    PAUSE_OVERLAY,
    PAUSE_MENU,
    RESUME_CANVAS,
    RESUME_BUTTON,
    QUIT_CANVAS,
    QUIT_BUTTON,

    // Game Over Menu
    GAME_OVER_OVERLAY,
    GAME_OVER_MENU,
    NEW_GAME_BUTTON,
    RESTART_CANVAS,
    FINAL_SCORE_CANVAS,
    FINAL_SCORE_TEXT,

    // Next Piece IDs
    NEXT_PIECE
}
<|endoftext|>


<commit_before>#![feature(pin, arbitrary_self_types, futures_api)]

#[macro_use]
extern crate futures;

use futures::channel::oneshot;
use futures::prelude::*;
use std::sync::mpsc;
use std::thread;

mod support;
use self::support::RunInBackgroundExt;

#[test]
fn oneshot_send1() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    let t = thread::spawn(|| tx1.send(1).unwrap());
    rx1.map_ok(move |x| tx2.send(x)).run_in_background();
    assert_eq!(1, rx2.recv().unwrap());
    t.join().unwrap();
}

#[test]
fn oneshot_send2() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    thread::spawn(|| tx1.send(1).unwrap()).join().unwrap();
    rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background();
    assert_eq!(1, rx2.recv().unwrap());
}

#[test]
fn oneshot_send3() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background();
    thread::spawn(|| tx1.send(1).unwrap()).join().unwrap();
    assert_eq!(1, rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_tx1() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    drop(tx1);
    rx1.map(move |result| tx2.send(result).unwrap()).run_in_background();

    assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_tx2() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    let t = thread::spawn(|| drop(tx1));
    rx1.map(move |result| tx2.send(result).unwrap()).run_in_background();
    t.join().unwrap();

    assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_rx() {
    let (tx, rx) = oneshot::channel::<i32>();
    drop(rx);
    assert_eq!(Err(2), tx.send(2));
}

// #[test]
// fn join1() {
//     let (tx, rx) = mpsc::channel();
//     ok::<i32, i32>(1).join(ok(2))
//                            .map(move |v| tx.send(v).unwrap())
//                            .forget();
//     assert_eq!(rx.recv(), Ok((1, 2)));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn join2() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.join(p2).map(move |v| tx.send(v).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     c1.send(1).unwrap();
//     assert!(rx.try_recv().is_err());
//     c2.send(2).unwrap();
//     assert_eq!(rx.recv(), Ok((1, 2)));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn join3() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.join(p2).map_err(move |_v| tx.send(1).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     drop(c1);
//     assert_eq!(rx.recv(), Ok(1));
//     assert!(rx.recv().is_err());
//     drop(c2);
// }

// #[test]
// fn join4() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.join(p2).map_err(move |v| tx.send(v).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     drop(c1);
//     assert!(rx.recv().is_ok());
//     drop(c2);
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn join5() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (c3, p3) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.join(p2).join(p3).map(move |v| tx.send(v).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     c1.send(1).unwrap();
//     assert!(rx.try_recv().is_err());
//     c2.send(2).unwrap();
//     assert!(rx.try_recv().is_err());
//     c3.send(3).unwrap();
//     assert_eq!(rx.recv(), Ok(((1, 2), 3)));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn select1() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.select(p2).map(move |v| tx.send(v).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     c1.send(1).unwrap();
//     let (v, p2) = rx.recv().unwrap().into_inner();
//     assert_eq!(v, 1);
//     assert!(rx.recv().is_err());

//     let (tx, rx) = mpsc::channel();
//     p2.map(move |v| tx.send(v).unwrap()).forget();
//     c2.send(2).unwrap();
//     assert_eq!(rx.recv(), Ok(2));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn select2() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.select(p2).map_err(move |v| tx.send((1, v.into_inner().1)).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     drop(c1);
//     let (v, p2) = rx.recv().unwrap();
//     assert_eq!(v, 1);
//     assert!(rx.recv().is_err());

//     let (tx, rx) = mpsc::channel();
//     p2.map(move |v| tx.send(v).unwrap()).forget();
//     c2.send(2).unwrap();
//     assert_eq!(rx.recv(), Ok(2));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn select3() {
//     let (c1, p1) = oneshot::channel::<i32>();
//     let (c2, p2) = oneshot::channel::<i32>();
//     let (tx, rx) = mpsc::channel();
//     p1.select(p2).map_err(move |v| tx.send((1, v.into_inner().1)).unwrap()).forget();
//     assert!(rx.try_recv().is_err());
//     drop(c1);
//     let (v, p2) = rx.recv().unwrap();
//     assert_eq!(v, 1);
//     assert!(rx.recv().is_err());

//     let (tx, rx) = mpsc::channel();
//     p2.map_err(move |_v| tx.send(2).unwrap()).forget();
//     drop(c2);
//     assert_eq!(rx.recv(), Ok(2));
//     assert!(rx.recv().is_err());
// }

// #[test]
// fn select4() {
//     let (tx, rx) = mpsc::channel::<oneshot::Sender<i32>>();

//     let t = thread::spawn(move || {
//         for c in rx {
//             c.send(1).unwrap();
//         }
//     });

//     let (tx2, rx2) = mpsc::channel();
//     for _ in 0..10000 {
//         let (c1, p1) = oneshot::channel::<i32>();
//         let (c2, p2) = oneshot::channel::<i32>();

//         let tx3 = tx2.clone();
//         p1.select(p2).map(move |_| tx3.send(()).unwrap()).forget();
//         tx.send(c1).unwrap();
//         rx2.recv().unwrap();
//         drop(c2);
//     }
//     drop(tx);

//     t.join().unwrap();
// }
<commit_msg>Remove accidentally included tests from oneshot.rs<commit_after>#![feature(pin, arbitrary_self_types, futures_api)]

#[macro_use]
extern crate futures;

use futures::channel::oneshot;
use futures::prelude::*;
use std::sync::mpsc;
use std::thread;

mod support;
use self::support::RunInBackgroundExt;

#[test]
fn oneshot_send1() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    let t = thread::spawn(|| tx1.send(1).unwrap());
    rx1.map_ok(move |x| tx2.send(x)).run_in_background();
    assert_eq!(1, rx2.recv().unwrap());
    t.join().unwrap();
}

#[test]
fn oneshot_send2() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    thread::spawn(|| tx1.send(1).unwrap()).join().unwrap();
    rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background();
    assert_eq!(1, rx2.recv().unwrap());
}

#[test]
fn oneshot_send3() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background();
    thread::spawn(|| tx1.send(1).unwrap()).join().unwrap();
    assert_eq!(1, rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_tx1() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    drop(tx1);
    rx1.map(move |result| tx2.send(result).unwrap()).run_in_background();

    assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_tx2() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = mpsc::channel();

    let t = thread::spawn(|| drop(tx1));
    rx1.map(move |result| tx2.send(result).unwrap()).run_in_background();
    t.join().unwrap();

    assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
}

#[test]
fn oneshot_drop_rx() {
    let (tx, rx) = oneshot::channel::<i32>();
    drop(rx);
    assert_eq!(Err(2), tx.send(2));
}
<|endoftext|>