<commit_before>// Copyright 2015 The Gfx-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.

#![deny(missing_docs, missing_copy_implementations)]

//! Memory mapping

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::{Mutex, MutexGuard};
use {Resources, Factory};
use {memory, handle};

/// Unsafe, backend-provided operations for a buffer mapping
#[doc(hidden)]
pub trait Gate<R: Resources> {
    /// Set the element at `index` to `val`. Not bounds-checked.
    unsafe fn set<T>(&self, index: usize, val: T);
    /// Returns a slice of the specified length.
    unsafe fn slice<'a, 'b, T>(&'a self, len: usize) -> &'b [T];
    /// Returns a mutable slice of the specified length.
    unsafe fn mut_slice<'a, 'b, T>(&'a self, len: usize) -> &'b mut [T];

    /// Hook before user read access
    fn before_read(&mut RawInner<R>) {}
    /// Hook before user write access
    fn before_write(&mut RawInner<R>) {}
}

fn valid_access(access: memory::Access, usage: memory::Usage) -> Result<(), Error> {
    use memory::Usage::*;
    match usage {
        Persistent(a) if a.contains(access) => Ok(()),
        _ => Err(Error::InvalidAccess(access, usage)),
    }
}

/// Would mapping this buffer with this memory access be an error ?
fn is_ok<R: Resources>(access: memory::Access, buffer: &handle::RawBuffer<R>) -> Result<(), Error> {
    try!(valid_access(access, buffer.get_info().usage));
    if buffer.mapping().is_some() { Err(Error::AlreadyMapped) }
    else { Ok(()) }
}

#[derive(Debug)]
#[doc(hidden)]
pub struct Status<R: Resources> {
    pub cpu_write: bool,
    pub gpu_access: Option<handle::Fence<R>>,
}

impl<R: Resources> Status<R> {
    fn clean() -> Self {
        Status {
            cpu_write: false,
            gpu_access: None,
        }
    }

    fn access(&mut self) {
        self.gpu_access.take().map(|fence| fence.wait());
    }

    fn write_access(&mut self) {
        self.access();
        self.cpu_write = true;
    }
}

/// Error mapping a buffer.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// The requested mapping access did not match the expected usage.
    InvalidAccess(memory::Access, memory::Usage),
    /// The memory was already mapped
    AlreadyMapped,
}

#[derive(Debug)]
#[doc(hidden)]
pub struct RawInner<R: Resources> {
    pub resource: R::Mapping,
    pub buffer: handle::RawBuffer<R>,
    pub access: memory::Access,
    pub status: Status<R>,
}

impl<R: Resources> Drop for RawInner<R> {
    fn drop(&mut self) {
        self.buffer.was_unmapped();
    }
}

/// Raw mapping providing status tracking
#[derive(Debug)]
pub struct Raw<R: Resources>(Mutex<RawInner<R>>);

impl<R: Resources> Raw<R> {
    #[doc(hidden)]
    pub fn new<F>(access: memory::Access, buffer: &handle::RawBuffer<R>, f: F) -> Result<Self, Error>
        where F: FnOnce() -> R::Mapping
    {
        try!(is_ok(access, buffer));
        Ok(Raw(Mutex::new(RawInner {
            resource: f(),
            buffer: buffer.clone(),
            access: access,
            status: Status::clean(),
        })))
    }

    #[doc(hidden)]
    pub fn access(&self) -> Option<MutexGuard<RawInner<R>>> {
        self.0.try_lock().ok()
    }

    unsafe fn read<T: Copy>(&self, len: usize) -> Reader<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        inner.status.access();

        Reader {
            slice: inner.resource.slice(len),
            inner: inner,
        }
    }

    unsafe fn write<T: Copy>(&self, len: usize) -> Writer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        Writer {
            len: len,
            inner: inner,
            phantom: PhantomData,
        }
    }

    unsafe fn read_write<T: Copy>(&self, len: usize) -> RWer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        RWer {
            slice: inner.resource.mut_slice(len),
            inner: inner,
        }
    }
}

/// Mapping reader
pub struct Reader<'a, R: Resources, T: 'a + Copy> {
    slice: &'a [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for Reader<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { self.slice }
}

/// Mapping writer
pub struct Writer<'a, R: Resources, T: 'a + Copy> {
    len: usize,
    inner: MutexGuard<'a, RawInner<R>>,
    phantom: PhantomData<T>,
}

impl<'a, R: Resources, T: 'a + Copy> Writer<'a, R, T> {
    /// Set a value in the buffer
    pub fn set(&mut self, index: usize, value: T) {
        if index >= self.len {
            panic!("tried to write out of bounds of a mapped buffer");
        }
        unsafe { self.inner.resource.set(index, value); }
    }
}

/// Mapping reader & writer
pub struct RWer<'a, R: Resources, T: 'a + Copy> {
    slice: &'a mut [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for RWer<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { &*self.slice }
}

impl<'a, R: Resources, T: Copy> DerefMut for RWer<'a, R, T> {
    fn deref_mut(&mut self) -> &mut [T] { self.slice }
}

/// Readable mapping.
pub struct Readable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Readable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }
}

/// Writable mapping.
pub struct Writable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Writable<R, T> {
    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }
}

/// Readable & writable mapping.
pub struct RWable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>
}

impl<R: Resources, T: Copy> RWable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }

    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }

    /// Acquire a mapping reader & writer
    pub fn read_write(&mut self) -> RWer<R, T> {
        unsafe { self.raw.read_write::<T>(self.len) }
    }
}

/// A service trait with methods for mapping already implemented.
/// To be used by device back ends.
#[doc(hidden)]
pub trait Builder<R: Resources>: Factory<R> {
    fn map_readable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Readable<R, T>;
    fn map_writable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Writable<R, T>;
    fn map_read_write<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> RWable<R, T>;
}

impl<R: Resources, F: Factory<R>> Builder<R> for F {
    fn map_readable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Readable<R, T> {
        Readable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_writable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Writable<R, T> {
        Writable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_read_write<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> RWable<R, T> {
        RWable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }
}
<commit_msg>Auto merge of #1078 - jplatte:master, r=kvark<commit_after>// Copyright 2015 The Gfx-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.

#![deny(missing_docs, missing_copy_implementations)]

//! Memory mapping

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::{Mutex, MutexGuard};
use {Resources, Factory};
use {memory, handle};

/// Unsafe, backend-provided operations for a buffer mapping
#[doc(hidden)]
pub trait Gate<R: Resources> {
    /// Set the element at `index` to `val`. Not bounds-checked.
    unsafe fn set<T>(&self, index: usize, val: T);
    /// Returns a slice of the specified length.
    unsafe fn slice<'a, 'b, T>(&'a self, len: usize) -> &'b [T];
    /// Returns a mutable slice of the specified length.
    unsafe fn mut_slice<'a, 'b, T>(&'a self, len: usize) -> &'b mut [T];

    /// Hook before user read access
    fn before_read(&mut RawInner<R>) {}
    /// Hook before user write access
    fn before_write(&mut RawInner<R>) {}
}

fn valid_access(access: memory::Access, usage: memory::Usage) -> Result<(), Error> {
    use memory::Usage::*;
    match usage {
        Persistent(a) if a.contains(access) => Ok(()),
        _ => Err(Error::InvalidAccess(access, usage)),
    }
}

/// Would mapping this buffer with this memory access be an error ?
fn is_ok<R: Resources>(access: memory::Access, buffer: &handle::RawBuffer<R>) -> Result<(), Error> {
    try!(valid_access(access, buffer.get_info().usage));
    if buffer.mapping().is_some() { Err(Error::AlreadyMapped) }
    else { Ok(()) }
}

#[derive(Debug)]
#[doc(hidden)]
pub struct Status<R: Resources> {
    pub cpu_write: bool,
    pub gpu_access: Option<handle::Fence<R>>,
}

impl<R: Resources> Status<R> {
    fn clean() -> Self {
        Status {
            cpu_write: false,
            gpu_access: None,
        }
    }

    fn access(&mut self) {
        self.gpu_access.take().map(|fence| fence.wait());
    }

    fn write_access(&mut self) {
        self.access();
        self.cpu_write = true;
    }
}

/// Error mapping a buffer.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// The requested mapping access did not match the expected usage.
    InvalidAccess(memory::Access, memory::Usage),
    /// The memory was already mapped
    AlreadyMapped,
}

#[derive(Debug)]
#[doc(hidden)]
pub struct RawInner<R: Resources> {
    pub resource: R::Mapping,
    pub buffer: handle::RawBuffer<R>,
    pub access: memory::Access,
    pub status: Status<R>,
}

impl<R: Resources> Drop for RawInner<R> {
    fn drop(&mut self) {
        self.buffer.was_unmapped();
    }
}

/// Raw mapping providing status tracking
#[derive(Debug)]
pub struct Raw<R: Resources>(Mutex<RawInner<R>>);

impl<R: Resources> Raw<R> {
    #[doc(hidden)]
    pub fn new<F>(access: memory::Access, buffer: &handle::RawBuffer<R>, f: F) -> Result<Self, Error>
        where F: FnOnce() -> R::Mapping
    {
        try!(is_ok(access, buffer));
        Ok(Raw(Mutex::new(RawInner {
            resource: f(),
            buffer: buffer.clone(),
            access: access,
            status: Status::clean(),
        })))
    }

    #[doc(hidden)]
    pub fn access(&self) -> Option<MutexGuard<RawInner<R>>> {
        self.0.try_lock().ok()
    }

    unsafe fn read<T: Copy>(&self, len: usize) -> Reader<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        inner.status.access();

        Reader {
            slice: inner.resource.slice(len),
            inner: inner,
        }
    }

    unsafe fn write<T: Copy>(&self, len: usize) -> Writer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        Writer {
            len: len,
            inner: inner,
            phantom: PhantomData,
        }
    }

    unsafe fn read_write<T: Copy>(&self, len: usize) -> RWer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        RWer {
            slice: inner.resource.mut_slice(len),
            inner: inner,
        }
    }
}

/// Mapping reader
pub struct Reader<'a, R: Resources, T: 'a + Copy> {
    slice: &'a [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for Reader<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { self.slice }
}

/// Mapping writer
pub struct Writer<'a, R: Resources, T: 'a + Copy> {
    len: usize,
    inner: MutexGuard<'a, RawInner<R>>,
    phantom: PhantomData<T>,
}

impl<'a, R: Resources, T: 'a + Copy> Writer<'a, R, T> {
    /// Set a value in the buffer
    pub fn set(&mut self, index: usize, value: T) {
        if index >= self.len {
            panic!("tried to write out of bounds of a mapped buffer");
        }
        unsafe { self.inner.resource.set(index, value); }
    }
}

/// Mapping reader & writer
pub struct RWer<'a, R: Resources, T: 'a + Copy> {
    slice: &'a mut [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for RWer<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { &*self.slice }
}

impl<'a, R: Resources, T: 'a + Copy> DerefMut for RWer<'a, R, T> {
    fn deref_mut(&mut self) -> &mut [T] { self.slice }
}

/// Readable mapping.
pub struct Readable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Readable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }
}

/// Writable mapping.
pub struct Writable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Writable<R, T> {
    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }
}

/// Readable & writable mapping.
pub struct RWable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>
}

impl<R: Resources, T: Copy> RWable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }

    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }

    /// Acquire a mapping reader & writer
    pub fn read_write(&mut self) -> RWer<R, T> {
        unsafe { self.raw.read_write::<T>(self.len) }
    }
}

/// A service trait with methods for mapping already implemented.
/// To be used by device back ends.
#[doc(hidden)]
pub trait Builder<R: Resources>: Factory<R> {
    fn map_readable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Readable<R, T>;
    fn map_writable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Writable<R, T>;
    fn map_read_write<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> RWable<R, T>;
}

impl<R: Resources, F: Factory<R>> Builder<R> for F {
    fn map_readable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Readable<R, T> {
        Readable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_writable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Writable<R, T> {
        Writable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_read_write<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> RWable<R, T> {
        RWable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

//! The `Default` trait for types which may have meaningful default values.

#![stable(feature = "rust1", since = "1.0.0")]

/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
/// don't particularly care what it is. This comes up often with `struct`s
/// that define a set of options:
///
/// ```
/// # #[allow(dead_code)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
///
/// How can we define some default values? You can use `Default`:
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
///
/// fn main() {
///     let options: SomeOptions = Default::default();
/// }
/// ```
///
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
///
/// If you want to override a particular option, but still retain the other defaults:
///
/// ```
/// # #[allow(dead_code)]
/// # #[derive(Default)]
/// # struct SomeOptions {
/// #     foo: i32,
/// #     bar: f32,
/// # }
/// fn main() {
///     let options = SomeOptions { foo: 42, ..Default::default() };
/// }
/// ```
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr, $doc:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            #[doc = $doc]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), (), "Returns the default value of `()`" }
default_impl! { bool, false, "Returns the default value of `false`" }
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }

default_impl! { usize, 0, "Returns the default value of `0`" }
default_impl! { u8, 0, "Returns the default value of `0`" }
default_impl! { u16, 0, "Returns the default value of `0`" }
default_impl! { u32, 0, "Returns the default value of `0`" }
default_impl! { u64, 0, "Returns the default value of `0`" }
default_impl! { u128, 0, "Returns the default value of `0`" }

default_impl! { isize, 0, "Returns the default value of `0`" }
default_impl! { i8, 0, "Returns the default value of `0`" }
default_impl! { i16, 0, "Returns the default value of `0`" }
default_impl! { i32, 0, "Returns the default value of `0`" }
default_impl! { i64, 0, "Returns the default value of `0`" }
default_impl! { i128, 0, "Returns the default value of `0`" }

default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
<commit_msg>Rollup merge of #43292 - kennytm:fix-quasi-quoting-warning-in-rustbuild, r=alexcrichton<commit_after>// Copyright 2013 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.

//! The `Default` trait for types which may have meaningful default values.

#![stable(feature = "rust1", since = "1.0.0")]

/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
/// don't particularly care what it is. This comes up often with `struct`s
/// that define a set of options:
///
/// ```
/// # #[allow(dead_code)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
///
/// How can we define some default values? You can use `Default`:
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
///
/// fn main() {
///     let options: SomeOptions = Default::default();
/// }
/// ```
///
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
///
/// If you want to override a particular option, but still retain the other defaults:
///
/// ```
/// # #[allow(dead_code)]
/// # #[derive(Default)]
/// # struct SomeOptions {
/// #     foo: i32,
/// #     bar: f32,
/// # }
/// fn main() {
///     let options = SomeOptions { foo: 42, ..Default::default() };
/// }
/// ```
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr, $doc:tt) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            #[doc = $doc]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), (), "Returns the default value of `()`" }
default_impl! { bool, false, "Returns the default value of `false`" }
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }

default_impl! { usize, 0, "Returns the default value of `0`" }
default_impl! { u8, 0, "Returns the default value of `0`" }
default_impl! { u16, 0, "Returns the default value of `0`" }
default_impl! { u32, 0, "Returns the default value of `0`" }
default_impl! { u64, 0, "Returns the default value of `0`" }
default_impl! { u128, 0, "Returns the default value of `0`" }

default_impl! { isize, 0, "Returns the default value of `0`" }
default_impl! { i8, 0, "Returns the default value of `0`" }
default_impl! { i16, 0, "Returns the default value of `0`" }
default_impl! { i32, 0, "Returns the default value of `0`" }
default_impl! { i64, 0, "Returns the default value of `0`" }
default_impl! { i128, 0, "Returns the default value of `0`" }

default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
<|endoftext|>


<commit_before><commit_msg>add error checking to commands handler<commit_after><|endoftext|>


<commit_before><commit_msg>removed unused stuff<commit_after><|endoftext|>


<commit_before><commit_msg>Create an example for the client module.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

fn main() -> std::io::Result<()> {
    fleetspeak::client::startup("0.0.1")?;

    loop {
        let request = fleetspeak::client::receive::<String>()?;
        let response = format!("Hello {}!", request);
        fleetspeak::client::send("greeter", "greeting", response)?;
    }
}
<|endoftext|>


<commit_before>
use rust_manifest::{Component, Manifest};
use component::{Components, Transaction, ChangeSet, TarGzPackage};
use temp;
use errors::*;
use utils;
use install::InstallPrefix;
use openssl::crypto::hash::{Type, Hasher};
use itertools::Itertools;

pub struct Changes {
	pub add_extensions: Vec<Component>,
	pub remove_extensions: Vec<Component>,
}

impl Changes {
	pub fn none() -> Self {
		Changes {
			add_extensions: Vec::new(),
			remove_extensions: Vec::new(),
		}
	}
}

pub const DIST_MANIFEST: &'static str = "dist.toml";
pub const PACKAGES_MANIFEST: &'static str = "packages.toml";

pub struct Manifestation(Components);

impl Manifestation {
	pub fn new(prefix: InstallPrefix) -> Option<Self> {
		if utils::is_file(prefix.manifest_file(PACKAGES_MANIFEST)) {
			Components::new(prefix).map(Manifestation)
		} else {
			None
		}
	}

	pub fn init(prefix: InstallPrefix, root_package: &str, target: &str) -> Result<Manifestation> {
		let packages_path = prefix.manifest_file(PACKAGES_MANIFEST);
		let new_manifest = Manifest::init(root_package, target);
		let new_manifest_str = new_manifest.stringify();

		try!(utils::write_file("packages manifest", &packages_path, &new_manifest_str));

		Components::init(prefix).map(Manifestation)
	}

	pub fn update(&self, changes: Changes, temp_cfg: &temp::Cfg, notify_handler: NotifyHandler) -> Result<()> {
		let components = &self.0;

		// First load dist and packages manifests
		let prefix = components.prefix();
		let dist_path = prefix.manifest_file(DIST_MANIFEST);
		let dist_manifest = try!(Manifest::parse(&*try!(utils::read_file("dist manifest", &dist_path))));
		let rel_packages_path = prefix.rel_manifest_file(PACKAGES_MANIFEST);
		let packages_path = prefix.abs_path(&rel_packages_path);
		let packages_manifest = try!(Manifest::parse(&*try!(utils::read_file("packages manifest", &packages_path))));

		// Find out which extensions are already installed
		let mut old_extensions = Vec::new();
		packages_manifest.flatten_extensions(&mut old_extensions);

		// Warn if trying to remove an extension which is not installed
		for e in &changes.remove_extensions {
			if !old_extensions.contains(e) {
				notify_handler.call(Notification::ExtensionNotInstalled(e));
			}
		}

		// Compute new set of extensions, given requested changes
		let mut new_extensions = old_extensions.clone();
		new_extensions.retain(|e| !changes.remove_extensions.contains(e));
		new_extensions.extend(changes.add_extensions.iter().cloned());

		// Find root package and target of existing installation
		let old_root = try!(packages_manifest.get_root());
		let old_package = try!(packages_manifest.get_package(&old_root));
		let old_target = try!(old_package.root_target());

		// Compute the updated packages manifest
		let new_manifest = try!(dist_manifest.for_root(&old_root, &old_target, |e| {
			new_extensions.contains(e)
		}));

		// Error out if any requested extensions were not added
		new_extensions.clear();
		new_manifest.flatten_extensions(&mut new_extensions);

		for e in &changes.add_extensions {
			if !old_extensions.contains(e) {
				return Err(Error::ExtensionNotFound(e.clone()));
			}
		}

		// Compute component-wise diff between the two manifests
		let diff = new_manifest.compute_diff(&packages_manifest);

		// Serialize new packages manifest
		let new_manifest_str = new_manifest.stringify();

		// Download required packages
		let mut change_set = ChangeSet::new();
		for p in diff.packages {
			// Download each package to temp file
			let temp_file = try!(temp_cfg.new_file());
			let url = try!(utils::parse_url(&p.url));

			let mut hasher = Hasher::new(Type::SHA256);
			try!(utils::download_file(url, &temp_file, Some(&mut hasher), ntfy!(&notify_handler)));
			let actual_hash = hasher.finish().iter()
				.map(|b| format!("{:02x}", b))
				.join("");

			if p.hash != actual_hash {
				// Incorrect hash
				return Err(Error::ChecksumFailed { url: p.url, expected: p.hash, calculated: actual_hash });
			} else {
				notify_handler.call(Notification::ChecksumValid(&p.url));
			}

			// And tell components system where to find it
			let package = try!(TarGzPackage::new_file(&temp_file, temp_cfg));
			change_set.add_package(package);
		}

		// Mark required component changes
		for c in diff.to_install {
			change_set.install(c.name());
		}
		for c in diff.to_uninstall {
			change_set.uninstall(c.name());
		}

		// Begin transaction
		let mut tx = Transaction::new(prefix, temp_cfg, notify_handler);

		// Apply changes
		tx = try!(components.apply_change_set(&change_set, &old_target, tx));

		// Update packages manifest
		try!(tx.modify_file(rel_packages_path));
		try!(utils::write_file("packages manifest", &packages_path, &new_manifest_str));

		// End transaction
		tx.commit();

		Ok(())
	}

	pub fn uninstall(self, temp_cfg: &temp::Cfg, notify_handler: NotifyHandler) -> Result<()> {
		let components = &self.0;

		// First load dist and packages manifests
		let prefix = components.prefix();
		let dist_path = prefix.manifest_file(DIST_MANIFEST);
		let dist_manifest = try!(Manifest::parse(&*try!(utils::read_file("dist manifest", &dist_path))));
		let rel_packages_path = prefix.rel_manifest_file(PACKAGES_MANIFEST);
		let packages_path = prefix.abs_path(&rel_packages_path);
		let packages_manifest = try!(Manifest::parse(&*try!(utils::read_file("packages manifest", &packages_path))));

		// Compute change-set
		let mut change_set = ChangeSet::new();
		let mut old_components = Vec::new();
		packages_manifest.flatten_components(&mut old_components);
		for c in old_components {
			change_set.uninstall(c.name());
		}

		// Find root package and target of existing installation
		let old_root = try!(packages_manifest.get_root());
		let old_package = try!(packages_manifest.get_package(&old_root));
		let old_target = try!(old_package.root_target());

		// Begin transaction
		let mut tx = Transaction::new(prefix, temp_cfg, notify_handler);

		// Apply changes
		tx = try!(components.apply_change_set(&change_set, &old_target, tx));

		// Update packages manifest
		try!(tx.modify_file(rel_packages_path));
		try!(utils::write_file("packages manifest", &packages_path, &new_manifest_str));

		// End transaction
		tx.commit();

		Ok(())
	}
}
<commit_msg>Finish writing manifest-level uninstall functionality<commit_after>
use rust_manifest::{Component, Manifest};
use component::{Components, Transaction, ChangeSet, TarGzPackage};
use temp;
use errors::*;
use utils;
use install::InstallPrefix;
use openssl::crypto::hash::{Type, Hasher};
use itertools::Itertools;

pub struct Changes {
	pub add_extensions: Vec<Component>,
	pub remove_extensions: Vec<Component>,
}

impl Changes {
	pub fn none() -> Self {
		Changes {
			add_extensions: Vec::new(),
			remove_extensions: Vec::new(),
		}
	}
}

pub const DIST_MANIFEST: &'static str = "dist.toml";
pub const PACKAGES_MANIFEST: &'static str = "packages.toml";

pub struct Manifestation(Components);

impl Manifestation {
	pub fn new(prefix: InstallPrefix) -> Option<Self> {
		if utils::is_file(prefix.manifest_file(PACKAGES_MANIFEST)) {
			Components::new(prefix).map(Manifestation)
		} else {
			None
		}
	}

	pub fn init(prefix: InstallPrefix, root_package: &str, target: &str) -> Result<Manifestation> {
		let packages_path = prefix.manifest_file(PACKAGES_MANIFEST);
		let new_manifest = Manifest::init(root_package, target);
		let new_manifest_str = new_manifest.stringify();

		try!(utils::write_file("packages manifest", &packages_path, &new_manifest_str));

		Components::init(prefix).map(Manifestation)
	}

	pub fn update(&self, changes: Changes, temp_cfg: &temp::Cfg, notify_handler: NotifyHandler) -> Result<()> {
		let components = &self.0;

		// First load dist and packages manifests
		let prefix = components.prefix();
		let dist_path = prefix.manifest_file(DIST_MANIFEST);
		let dist_manifest = try!(Manifest::parse(&*try!(utils::read_file("dist manifest", &dist_path))));
		let rel_packages_path = prefix.rel_manifest_file(PACKAGES_MANIFEST);
		let packages_path = prefix.abs_path(&rel_packages_path);
		let packages_manifest = try!(Manifest::parse(&*try!(utils::read_file("packages manifest", &packages_path))));

		// Find out which extensions are already installed
		let mut old_extensions = Vec::new();
		packages_manifest.flatten_extensions(&mut old_extensions);

		// Warn if trying to remove an extension which is not installed
		for e in &changes.remove_extensions {
			if !old_extensions.contains(e) {
				notify_handler.call(Notification::ExtensionNotInstalled(e));
			}
		}

		// Compute new set of extensions, given requested changes
		let mut new_extensions = old_extensions.clone();
		new_extensions.retain(|e| !changes.remove_extensions.contains(e));
		new_extensions.extend(changes.add_extensions.iter().cloned());

		// Find root package and target of existing installation
		let old_root = try!(packages_manifest.get_root());
		let old_package = try!(packages_manifest.get_package(&old_root));
		let old_target = try!(old_package.root_target());

		// Compute the updated packages manifest
		let new_manifest = try!(dist_manifest.for_root(&old_root, &old_target, |e| {
			new_extensions.contains(e)
		}));

		// Error out if any requested extensions were not added
		new_extensions.clear();
		new_manifest.flatten_extensions(&mut new_extensions);

		for e in &changes.add_extensions {
			if !old_extensions.contains(e) {
				return Err(Error::ExtensionNotFound(e.clone()));
			}
		}

		// Compute component-wise diff between the two manifests
		let diff = new_manifest.compute_diff(&packages_manifest);

		// Serialize new packages manifest
		let new_manifest_str = new_manifest.stringify();

		// Download required packages
		let mut change_set = ChangeSet::new();
		for p in diff.packages {
			// Download each package to temp file
			let temp_file = try!(temp_cfg.new_file());
			let url = try!(utils::parse_url(&p.url));

			let mut hasher = Hasher::new(Type::SHA256);
			try!(utils::download_file(url, &temp_file, Some(&mut hasher), ntfy!(&notify_handler)));
			let actual_hash = hasher.finish().iter()
				.map(|b| format!("{:02x}", b))
				.join("");

			if p.hash != actual_hash {
				// Incorrect hash
				return Err(Error::ChecksumFailed { url: p.url, expected: p.hash, calculated: actual_hash });
			} else {
				notify_handler.call(Notification::ChecksumValid(&p.url));
			}

			// And tell components system where to find it
			let package = try!(TarGzPackage::new_file(&temp_file, temp_cfg));
			change_set.add_package(package);
		}

		// Mark required component changes
		for c in diff.to_install {
			change_set.install(c.name());
		}
		for c in diff.to_uninstall {
			change_set.uninstall(c.name());
		}

		// Begin transaction
		let mut tx = Transaction::new(prefix, temp_cfg, notify_handler);

		// Apply changes
		tx = try!(components.apply_change_set(&change_set, &old_target, tx));

		// Update packages manifest
		try!(tx.modify_file(rel_packages_path));
		try!(utils::write_file("packages manifest", &packages_path, &new_manifest_str));

		// End transaction
		tx.commit();

		Ok(())
	}

	pub fn uninstall(self, temp_cfg: &temp::Cfg, notify_handler: NotifyHandler) -> Result<()> {
		let components = &self.0;

		// First load dist and packages manifests
		let prefix = components.prefix();
		let rel_packages_path = prefix.rel_manifest_file(PACKAGES_MANIFEST);
		let packages_path = prefix.abs_path(&rel_packages_path);
		let packages_manifest = try!(Manifest::parse(&*try!(utils::read_file("packages manifest", &packages_path))));

		// Compute change-set
		let mut change_set = ChangeSet::new();
		let mut old_components = Vec::new();
		packages_manifest.flatten_components(&mut old_components);
		for c in old_components {
			change_set.uninstall(c.name());
		}

		// Find root package and target of existing installation
		let old_root = try!(packages_manifest.get_root());
		let old_package = try!(packages_manifest.get_package(&old_root));
		let old_target = try!(old_package.root_target());

		// Begin transaction
		let mut tx = Transaction::new(prefix, temp_cfg, notify_handler);

		// Apply changes
		tx = try!(components.apply_change_set(&change_set, &old_target, tx));

		// Update packages manifest
		try!(tx.modify_file(rel_packages_path));
		try!(utils::remove_file("packages manifest", &packages_path));

		// End transaction
		tx.commit();

		Ok(())
	}
}
<|endoftext|>


<commit_before><commit_msg>Adjust frame rate<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::HTMLDocumentBinding;
use dom::bindings::utils::{DOMString, ErrorResult, null_string};
use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache};
use dom::document::{AbstractDocument, Document, WrappableDocument, HTML};
use dom::element::Element;
use dom::htmlcollection::HTMLCollection;
use dom::node::{AbstractNode, ScriptView};
use dom::window::Window;

use js::jsapi::{JSObject, JSContext};

use servo_util::tree::TreeUtils;

use std::libc;
use std::ptr;
use std::str::eq_slice;

pub struct HTMLDocument {
    parent: Document
}

impl HTMLDocument {
    pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> AbstractDocument {
        let doc = @mut HTMLDocument {
            parent: Document::new(root, window, HTML)
        };

        let compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
        AbstractDocument::as_abstract(compartment.cx.ptr, doc)
    }

    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let win = self.parent.window.get_ref();
        let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr};
        let cache = win.get_wrappercache();
        let scope = cache.get_wrapper();
        (scope, cx)
    }
}

impl WrappableDocument for HTMLDocument {
    pub fn init_wrapper(@mut self, cx: *JSContext) {
        self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
    }
}

impl HTMLDocument {
    pub fn GetDomain(&self, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn SetDomain(&self, _domain: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn GetCookie(&self, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn SetCookie(&self, _cookie: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn GetHead(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn Images(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "img"))
    }

    pub fn Embeds(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "embed"))
    }

    pub fn Plugins(&self) -> @mut HTMLCollection {
        self.Embeds()
    }

    pub fn Links(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| {
            if eq_slice(elem.tag_name, "a") || eq_slice(elem.tag_name, "area") {
                match elem.get_attr("href") {
                    Some(_val) => true,
                    None() => false
                }
            }
            else { false }
        })
    }

    pub fn Forms(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "form"))
    }

    pub fn Scripts(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "script"))
    }

    pub fn Close(&self, _rv: &mut ErrorResult) {
    }

    pub fn DesignMode(&self) -> DOMString {
        null_string
    }

    pub fn SetDesignMode(&self, _mode: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn ExecCommand(&self, _command_id: &DOMString, _show_ui: bool, _value: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandEnabled(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandIndeterm(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandState(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandSupported(&self, _command_id: &DOMString) -> bool {
        false
    }

    pub fn QueryCommandValue(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn FgColor(&self) -> DOMString {
        null_string
    }

    pub fn SetFgColor(&self, _color: &DOMString) {
    }

    pub fn LinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetLinkColor(&self, _color: &DOMString) {
    }

    pub fn VlinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetVlinkColor(&self, _color: &DOMString) {
    }

    pub fn AlinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetAlinkColor(&self, _color: &DOMString) {
    }

    pub fn BgColor(&self) -> DOMString {
        null_string
    }

    pub fn SetBgColor(&self, _color: &DOMString) {
    }

    pub fn Anchors(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| {
            if eq_slice(elem.tag_name, "a") {
                match elem.get_attr("name") {
                    Some(_val) => true,
                    None() => false
                }
            }
            else { false }
        })
    }

    pub fn Applets(&self) -> @mut HTMLCollection {
        // FIXME: This should be return OBJECT elements containing applets.
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "applet"))
    }

    pub fn Clear(&self) {
    }

    pub fn GetAll(&self, _cx: *JSContext, _rv: &mut ErrorResult) -> *libc::c_void {
        ptr::null()
    }

    fn createHTMLCollection(&self, callback: &fn(elem: &Element) -> bool) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        let mut elements = ~[];
        let _ = for self.parent.root.traverse_preorder |child| {
            if child.is_element() {
                do child.with_imm_element |elem| {
                    if callback(elem) {
                        elements.push(child);
                    }
                }
            }
        };
        HTMLCollection::new(elements, cx, scope)
    }
}

impl CacheableWrapper for HTMLDocument {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        self.parent.get_wrappercache()
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        let mut unused = false;
        HTMLDocumentBinding::Wrap(cx, scope, self, &mut unused)
    }
}

impl BindingObject for HTMLDocument {
    fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
        self.parent.GetParentObject(cx)
    }
}

<commit_msg>auto merge of #666 : kmcallister/servo/htmldocument, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::HTMLDocumentBinding;
use dom::bindings::utils::{DOMString, ErrorResult, null_string};
use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache};
use dom::document::{AbstractDocument, Document, WrappableDocument, HTML};
use dom::element::Element;
use dom::htmlcollection::HTMLCollection;
use dom::node::{AbstractNode, ScriptView};
use dom::window::Window;

use js::jsapi::{JSObject, JSContext};

use servo_util::tree::TreeUtils;

use std::libc;
use std::ptr;
use std::str::eq_slice;

pub struct HTMLDocument {
    parent: Document
}

impl HTMLDocument {
    pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> AbstractDocument {
        let doc = @mut HTMLDocument {
            parent: Document::new(root, window, HTML)
        };

        let compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
        AbstractDocument::as_abstract(compartment.cx.ptr, doc)
    }

    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let win = self.parent.window.get_ref();
        let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr};
        let cache = win.get_wrappercache();
        let scope = cache.get_wrapper();
        (scope, cx)
    }
}

impl WrappableDocument for HTMLDocument {
    pub fn init_wrapper(@mut self, cx: *JSContext) {
        self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
    }
}

impl HTMLDocument {
    pub fn GetDomain(&self, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn SetDomain(&self, _domain: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn GetCookie(&self, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn SetCookie(&self, _cookie: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn GetHead(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn Images(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "img"))
    }

    pub fn Embeds(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "embed"))
    }

    pub fn Plugins(&self) -> @mut HTMLCollection {
        self.Embeds()
    }

    pub fn Links(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem|
            (eq_slice(elem.tag_name, "a") || eq_slice(elem.tag_name, "area"))
            && elem.get_attr("href").is_some())
    }

    pub fn Forms(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "form"))
    }

    pub fn Scripts(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "script"))
    }

    pub fn Close(&self, _rv: &mut ErrorResult) {
    }

    pub fn DesignMode(&self) -> DOMString {
        null_string
    }

    pub fn SetDesignMode(&self, _mode: &DOMString, _rv: &mut ErrorResult) {
    }

    pub fn ExecCommand(&self, _command_id: &DOMString, _show_ui: bool, _value: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandEnabled(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandIndeterm(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandState(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
        false
    }

    pub fn QueryCommandSupported(&self, _command_id: &DOMString) -> bool {
        false
    }

    pub fn QueryCommandValue(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> DOMString {
        null_string
    }

    pub fn FgColor(&self) -> DOMString {
        null_string
    }

    pub fn SetFgColor(&self, _color: &DOMString) {
    }

    pub fn LinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetLinkColor(&self, _color: &DOMString) {
    }

    pub fn VlinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetVlinkColor(&self, _color: &DOMString) {
    }

    pub fn AlinkColor(&self) -> DOMString {
        null_string
    }

    pub fn SetAlinkColor(&self, _color: &DOMString) {
    }

    pub fn BgColor(&self) -> DOMString {
        null_string
    }

    pub fn SetBgColor(&self, _color: &DOMString) {
    }

    pub fn Anchors(&self) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem|
            eq_slice(elem.tag_name, "a") && elem.get_attr("name").is_some())
    }

    pub fn Applets(&self) -> @mut HTMLCollection {
        // FIXME: This should be return OBJECT elements containing applets.
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, "applet"))
    }

    pub fn Clear(&self) {
    }

    pub fn GetAll(&self, _cx: *JSContext, _rv: &mut ErrorResult) -> *libc::c_void {
        ptr::null()
    }

    fn createHTMLCollection(&self, callback: &fn(elem: &Element) -> bool) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        let mut elements = ~[];
        let _ = for self.parent.root.traverse_preorder |child| {
            if child.is_element() {
                do child.with_imm_element |elem| {
                    if callback(elem) {
                        elements.push(child);
                    }
                }
            }
        };
        HTMLCollection::new(elements, cx, scope)
    }
}

impl CacheableWrapper for HTMLDocument {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        self.parent.get_wrappercache()
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        let mut unused = false;
        HTMLDocumentBinding::Wrap(cx, scope, self, &mut unused)
    }
}

impl BindingObject for HTMLDocument {
    fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
        self.parent.GetParentObject(cx)
    }
}

<|endoftext|>


<commit_before><commit_msg>Initial commit of transform module<commit_after>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

pub trait Transform<S> {
    fn transform_vec(&self, point: Point3<S>) -> Point3<S>;
    fn transform_point(&self, point: Point3<S>) -> Point3<S>;
    fn transform_ray(&self, ray: Ray3<S>) -> Ray3<S>;
}

/// A homogeneous transformation matrix.
pub struct AffineMatrix3<S> {
    mat: Mat4<S>,
}

/// A transformation in three dimensions consisting of a rotation,
/// displacement vector and scale amount.
pub struct Transform3<S, R> {
    rot: R,
    disp: Vec3<S>,
    scale: S,
}

impl<S: Float, R: Rotation3<S>> Transform3<S, R> {
    #[inline]
    pub fn new(rot: R, disp: Vec3<S>, scale: S) -> Transform3<S, R> {
        Transform3 { rot: rot, disp: disp, scale: S }
    }
}
<|endoftext|>


<commit_before><commit_msg>[idna] Enable code to fail on IDNA2008 Bidi Rule 6 [B6]<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for deprecated phase(syntax)<commit_after>// Copyright 2013-2014 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.

#![feature(phase)]

//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin)
#[phase(syntax, link)]
extern crate log;

fn main() {
    debug!("foo");
}
<|endoftext|>


<commit_before><commit_msg>Refactor if let chains to matches! macro<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use command_line::command_line_init;
use interfaces::cef_app_t;
use types::{cef_main_args_t, cef_settings_t};

use geom::size::TypedSize2D;
use libc::{c_char, c_int, c_void};
use util::opts;
use std::borrow::ToOwned;
use std::ffi;
use std::str;
use browser;

const MAX_RENDERING_THREADS: uint = 128;

// TODO(pcwalton): Get the home page via the CEF API.
static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";

static CEF_API_HASH_UNIVERSAL: &'static [u8] = b"8efd129f4afc344bd04b2feb7f73a149b6c4e27f\0";
#[cfg(target_os="windows")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"5c7f3e50ff5265985d11dc1a466513e25748bedd\0";
#[cfg(target_os="macos")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"6813214accbf2ebfb6bdcf8d00654650b251bf3d\0";
#[cfg(target_os="linux")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"2bc564c3871965ef3a2531b528bda3e17fa17a6d\0";

#[cfg(target_os="linux")]
fn resources_path() -> Option<String> {
    Some("../../servo/resources".to_owned())
}

#[cfg(not(target_os="linux"))]
fn resources_path() -> Option<String> {
    None
}

#[no_mangle]
pub extern "C" fn cef_initialize(args: *const cef_main_args_t,
                                 settings: *mut cef_settings_t,
                                 application: *mut cef_app_t,
                                 _windows_sandbox_info: *const c_void)
                                 -> c_int {
    if args.is_null() {
        return 0;
    }

    unsafe {
        command_line_init((*args).argc, (*args).argv);

        if !application.is_null() {
            (*application).get_browser_process_handler.map(|cb| {
                    let handler = cb(application);
                    if !handler.is_null() {
                        (*handler).on_context_initialized.map(|hcb| hcb(handler));
                    }
            });
        }
    }

    let rendering_threads = unsafe {
        if ((*settings).rendering_threads as uint) < 1 {
            1
        } else if (*settings).rendering_threads as uint > MAX_RENDERING_THREADS {
            MAX_RENDERING_THREADS
        } else {
            (*settings).rendering_threads as uint
        }
    };

    let urls = vec![HOME_URL.to_owned()];
    let mut temp_opts = opts::default_opts();

    temp_opts.paint_threads = rendering_threads;
    temp_opts.layout_threads = rendering_threads;
    temp_opts.headless = false;
    temp_opts.hard_fail = false;
    temp_opts.enable_text_antialiasing = true;
    temp_opts.resources_path = resources_path();
    opts::set_opts(temp_opts);

    return 1
}

#[no_mangle]
pub extern "C" fn cef_shutdown() {
}

#[no_mangle]
pub extern "C" fn cef_run_message_loop() {
    // GWTODO: Support blocking message loop
    // again. Although, will it ever actually
    // be used or will everything use the
    // cef_do_message_loop_work function below
    // as our current miniservo apps do?
    unimplemented!()
}

#[no_mangle]
pub extern "C" fn cef_do_message_loop_work() {
    browser::update();
}

#[no_mangle]
pub extern "C" fn cef_quit_message_loop() {
}

#[no_mangle]
pub extern "C" fn cef_execute_process(_args: *const cef_main_args_t,
                                      _app: *mut cef_app_t,
                                      _windows_sandbox_info: *mut c_void)
                                      -> c_int {
   -1
}

#[no_mangle]
pub extern "C" fn cef_api_hash(entry: c_int) -> *const c_char {
    if entry == 0 {
        &CEF_API_HASH_PLATFORM[0] as *const u8 as *const c_char
    } else {
        &CEF_API_HASH_UNIVERSAL[0] as *const u8 as *const c_char
    }
}

#[no_mangle]
pub extern "C" fn cef_log(_file: *const c_char,
                          _line: c_int,
                          _severity: c_int,
                          message: *const c_char) {
    unsafe {
        let slice = ffi::c_str_to_bytes(&message);
        println!("{}", str::from_utf8(slice).unwrap())
    }
}

#[no_mangle]
pub extern "C" fn cef_get_min_log_level() -> c_int {
    0
}

<commit_msg>auto merge of #5024 : Ms2ger/servo/cef-warnings, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use command_line::command_line_init;
use interfaces::cef_app_t;
use types::{cef_main_args_t, cef_settings_t};

use libc::{c_char, c_int, c_void};
use util::opts;
use std::borrow::ToOwned;
use std::ffi;
use std::str;
use browser;

const MAX_RENDERING_THREADS: uint = 128;

// TODO(pcwalton): Get the home page via the CEF API.
static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";

static CEF_API_HASH_UNIVERSAL: &'static [u8] = b"8efd129f4afc344bd04b2feb7f73a149b6c4e27f\0";
#[cfg(target_os="windows")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"5c7f3e50ff5265985d11dc1a466513e25748bedd\0";
#[cfg(target_os="macos")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"6813214accbf2ebfb6bdcf8d00654650b251bf3d\0";
#[cfg(target_os="linux")]
static CEF_API_HASH_PLATFORM: &'static [u8] = b"2bc564c3871965ef3a2531b528bda3e17fa17a6d\0";

#[cfg(target_os="linux")]
fn resources_path() -> Option<String> {
    Some("../../servo/resources".to_owned())
}

#[cfg(not(target_os="linux"))]
fn resources_path() -> Option<String> {
    None
}

#[no_mangle]
pub extern "C" fn cef_initialize(args: *const cef_main_args_t,
                                 settings: *mut cef_settings_t,
                                 application: *mut cef_app_t,
                                 _windows_sandbox_info: *const c_void)
                                 -> c_int {
    if args.is_null() {
        return 0;
    }

    unsafe {
        command_line_init((*args).argc, (*args).argv);

        if !application.is_null() {
            (*application).get_browser_process_handler.map(|cb| {
                    let handler = cb(application);
                    if !handler.is_null() {
                        (*handler).on_context_initialized.map(|hcb| hcb(handler));
                    }
            });
        }
    }

    let rendering_threads = unsafe {
        if ((*settings).rendering_threads as uint) < 1 {
            1
        } else if (*settings).rendering_threads as uint > MAX_RENDERING_THREADS {
            MAX_RENDERING_THREADS
        } else {
            (*settings).rendering_threads as uint
        }
    };

    let mut temp_opts = opts::default_opts();
    temp_opts.urls = vec![HOME_URL.to_owned()];
    temp_opts.paint_threads = rendering_threads;
    temp_opts.layout_threads = rendering_threads;
    temp_opts.headless = false;
    temp_opts.hard_fail = false;
    temp_opts.enable_text_antialiasing = true;
    temp_opts.resources_path = resources_path();
    opts::set_opts(temp_opts);

    return 1
}

#[no_mangle]
pub extern "C" fn cef_shutdown() {
}

#[no_mangle]
pub extern "C" fn cef_run_message_loop() {
    // GWTODO: Support blocking message loop
    // again. Although, will it ever actually
    // be used or will everything use the
    // cef_do_message_loop_work function below
    // as our current miniservo apps do?
    unimplemented!()
}

#[no_mangle]
pub extern "C" fn cef_do_message_loop_work() {
    browser::update();
}

#[no_mangle]
pub extern "C" fn cef_quit_message_loop() {
}

#[no_mangle]
pub extern "C" fn cef_execute_process(_args: *const cef_main_args_t,
                                      _app: *mut cef_app_t,
                                      _windows_sandbox_info: *mut c_void)
                                      -> c_int {
   -1
}

#[no_mangle]
pub extern "C" fn cef_api_hash(entry: c_int) -> *const c_char {
    if entry == 0 {
        &CEF_API_HASH_PLATFORM[0] as *const u8 as *const c_char
    } else {
        &CEF_API_HASH_UNIVERSAL[0] as *const u8 as *const c_char
    }
}

#[no_mangle]
pub extern "C" fn cef_log(_file: *const c_char,
                          _line: c_int,
                          _severity: c_int,
                          message: *const c_char) {
    unsafe {
        let slice = ffi::c_str_to_bytes(&message);
        println!("{}", str::from_utf8(slice).unwrap())
    }
}

#[no_mangle]
pub extern "C" fn cef_get_min_log_level() -> c_int {
    0
}

<|endoftext|>


<commit_before><commit_msg>Started work on memory allocation... Incomplete<commit_after><|endoftext|>


<commit_before><commit_msg>Add rustdoc regression test for the unused_braces lint<commit_after>// check-pass

// This tests the bug in #70814, where the unused_braces lint triggered on the following code
// without providing a span.

#![deny(unused_braces)]

fn main() {
    {
        {
            use std;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>tests: Added requirement override tests<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Gfx-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.

//! Slices
//!
//! See `Slice`-structure documentation for more information on this module.

use core::{handle, buffer};
use core::{Primitive, Resources, VertexCount};
use core::command::InstanceParams;
use core::factory::Factory;
use core::memory::Bind;
use format::Format;
use pso;

/// A `Slice` dictates in which and in what order vertices get processed. It is required for
/// processing a PSO.
///
/// # Overview
/// A `Slice` object in essence dictates in what order the vertices in a `VertexBuffer` get
/// processed. To do this, it contains an internal index-buffer. This `Buffer` is a list of
/// indices into this `VertexBuffer` (vertex-index). A vertex-index of 0 represents the first
/// vertex in the `VertexBuffer`, a vertex-index of 1 represents the second, 2 represents the
/// third, and so on. The vertex-indices in the index-buffer are read in order; every vertex-index
/// tells the pipeline which vertex to process next.
///
/// Because the same index can re-appear multiple times, duplicate-vertices can be avoided. For
/// instance, if you want to draw a square, you need two triangles, and thus six vertices. Because
/// the same index can reappear multiple times, this means we can instead use 4 vertices, and 6
/// vertex-indices.
///
/// This index-buffer has a few variants. See the `IndexBuffer` documentation for a detailed
/// description.
///
/// The `start` and `end` fields say where in the index-buffer to start and stop reading.
/// Setting `start` to 0, and `end` to the length of the index-buffer, will cause the entire
/// index-buffer to be processed. The `base_vertex` dictates the index of the first vertex
/// in the `VertexBuffer`. This essentially moves the the start of the `VertexBuffer`, to the
/// vertex with this index.
///
/// # Constuction & Handling
/// The `Slice` structure can be constructed automatically when using a `Factory` to create a
/// vertex buffer. If needed, it can also be created manually.
///
/// A `Slice` is required to process a PSO, as it contains the needed information on in what order
/// to draw which vertices. As such, every `draw` call on an `Encoder` requires a `Slice`.
#[derive(Clone, Debug, PartialEq)]
pub struct Slice<R: Resources> {
    /// The start index of the index-buffer. Processing will start at this location in the
    /// index-buffer.
    pub start: VertexCount,
    /// The end index in the index-buffer. Processing will stop at this location (exclusive) in
    /// the index buffer.
    pub end: VertexCount,
    /// This is the index of the first vertex in the `VertexBuffer`. This value will be added to
    /// every index in the index-buffer, effectively moving the start of the `VertexBuffer` to this
    /// base-vertex.
    pub base_vertex: VertexCount,
    /// Instancing configuration.
    pub instances: Option<InstanceParams>,
    /// Represents the type of index-buffer used.
    pub buffer: IndexBuffer<R>,
}

impl<R: Resources> Slice<R> {
    /// Creates a new `Slice` to match the supplied vertex buffer, from start to end, in order.
    pub fn new_match_vertex_buffer<V>(vbuf: &handle::Buffer<R, V>) -> Self
                                      where V: pso::buffer::Structure<Format> {
        Slice {
            start: 0,
            end: vbuf.len() as u32,
            base_vertex: 0,
            instances: None,
            buffer: IndexBuffer::Auto,
        }
    }

    /// Calculates the number of primitives of the specified type in this `Slice`.
    pub fn get_prim_count(&self, prim: Primitive) -> u32 {
        use core::Primitive as p;
        let nv = (self.end - self.start) as u32;
        match prim {
            p::PointList => nv,
            p::LineList => nv / 2,
            p::LineStrip => (nv-1),
            p::TriangleList => nv / 3,
            p::TriangleStrip => (nv-2) / 3,
            p::LineListAdjacency => nv / 4,
            p::LineStripAdjacency => (nv-3),
            p::TriangleListAdjacency => nv / 6,
            p::TriangleStripAdjacency => (nv-4) / 2,
            p::PatchList(num) => nv / (num as u32),
        }
    }

    /// Divides one slice into two at an index.
    ///
    /// The first will contain the range in the index-buffer [self.start, mid) (excluding the index mid itself) and the
    /// second will contain the range [mid, self.end).
    pub fn split_at(&self, mid: VertexCount) -> (Self, Self) {
        let mut first = self.clone();
        let mut second = self.clone();
        first.end = mid;
        second.start = mid;

        (first, second)
    }
}

/// Type of index-buffer used in a Slice.
///
/// The `Auto` variant represents a hypothetical index-buffer from 0 to infinity. In other words,
/// all vertices get processed in order. Do note that the `Slice`' `start` and `end` restrictions
/// still apply for this variant. To render every vertex in the `VertexBuffer`, you would set
/// `start` to 0, and `end` to the `VertexBuffer`'s length.
///
/// The `Index*` variants represent an actual `Buffer` with a list of vertex-indices. The numeric
/// suffix specifies the amount of bits to use per index. Each of these also contains a
/// base-vertex. This is the index of the first vertex in the `VertexBuffer`. This value will be
/// added to every index in the index-buffer, effectively moving the start of the `VertexBuffer` to
/// this base-vertex.
///
/// # Construction & Handling
/// A `IndexBuffer` can be constructed using the `IntoIndexBuffer` trait, from either a slice or a
/// `Buffer` of integers, using a factory.
///
/// An `IndexBuffer` is exclusively used to create `Slice`s.
#[derive(Clone, Debug, PartialEq)]
pub enum IndexBuffer<R: Resources> {
    /// Represents a hypothetical index-buffer from 0 to infinity. In other words, all vertices
    /// get processed in order.
    Auto,
    /// An index-buffer with unsigned 16 bit indices.
    Index16(handle::Buffer<R, u16>),
    /// An index-buffer with unsigned 32 bit indices.
    Index32(handle::Buffer<R, u32>),
}

impl<R: Resources> Default for IndexBuffer<R> {
    fn default() -> Self {
        IndexBuffer::Auto
    }
}
/// A helper trait to create `IndexBuffers` from different kinds of data.
pub trait IntoIndexBuffer<R: Resources> {
    /// Turns self into an `IndexBuffer`.
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R>;
}

impl<R: Resources> IntoIndexBuffer<R> for IndexBuffer<R> {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        self
    }
}

impl<R: Resources> IntoIndexBuffer<R> for () {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        IndexBuffer::Auto
    }
}

macro_rules! impl_index_buffer {
    ($prim_ty:ty, $buf_ty:ident) => (
        impl<R: Resources> IntoIndexBuffer<R> for handle::Buffer<R, $prim_ty> {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
                IndexBuffer::$buf_ty(self)
            }
        }

        impl<'s, R: Resources> IntoIndexBuffer<R> for &'s [$prim_ty] {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R> {
                factory.create_buffer_immutable(self, buffer::Role::Index, Bind::empty())
                       .unwrap()
                       .into_index_buffer(factory)
            }
        }
    )
}

impl_index_buffer!(u16, Index16);
impl_index_buffer!(u32, Index32);
<commit_msg>Derive Hash and Eq for Slice and IndexBuffer<commit_after>// Copyright 2014 The Gfx-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.

//! Slices
//!
//! See `Slice`-structure documentation for more information on this module.

use core::{handle, buffer};
use core::{Primitive, Resources, VertexCount};
use core::command::InstanceParams;
use core::factory::Factory;
use core::memory::Bind;
use format::Format;
use pso;

/// A `Slice` dictates in which and in what order vertices get processed. It is required for
/// processing a PSO.
///
/// # Overview
/// A `Slice` object in essence dictates in what order the vertices in a `VertexBuffer` get
/// processed. To do this, it contains an internal index-buffer. This `Buffer` is a list of
/// indices into this `VertexBuffer` (vertex-index). A vertex-index of 0 represents the first
/// vertex in the `VertexBuffer`, a vertex-index of 1 represents the second, 2 represents the
/// third, and so on. The vertex-indices in the index-buffer are read in order; every vertex-index
/// tells the pipeline which vertex to process next.
///
/// Because the same index can re-appear multiple times, duplicate-vertices can be avoided. For
/// instance, if you want to draw a square, you need two triangles, and thus six vertices. Because
/// the same index can reappear multiple times, this means we can instead use 4 vertices, and 6
/// vertex-indices.
///
/// This index-buffer has a few variants. See the `IndexBuffer` documentation for a detailed
/// description.
///
/// The `start` and `end` fields say where in the index-buffer to start and stop reading.
/// Setting `start` to 0, and `end` to the length of the index-buffer, will cause the entire
/// index-buffer to be processed. The `base_vertex` dictates the index of the first vertex
/// in the `VertexBuffer`. This essentially moves the the start of the `VertexBuffer`, to the
/// vertex with this index.
///
/// # Constuction & Handling
/// The `Slice` structure can be constructed automatically when using a `Factory` to create a
/// vertex buffer. If needed, it can also be created manually.
///
/// A `Slice` is required to process a PSO, as it contains the needed information on in what order
/// to draw which vertices. As such, every `draw` call on an `Encoder` requires a `Slice`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Slice<R: Resources> {
    /// The start index of the index-buffer. Processing will start at this location in the
    /// index-buffer.
    pub start: VertexCount,
    /// The end index in the index-buffer. Processing will stop at this location (exclusive) in
    /// the index buffer.
    pub end: VertexCount,
    /// This is the index of the first vertex in the `VertexBuffer`. This value will be added to
    /// every index in the index-buffer, effectively moving the start of the `VertexBuffer` to this
    /// base-vertex.
    pub base_vertex: VertexCount,
    /// Instancing configuration.
    pub instances: Option<InstanceParams>,
    /// Represents the type of index-buffer used.
    pub buffer: IndexBuffer<R>,
}

impl<R: Resources> Slice<R> {
    /// Creates a new `Slice` to match the supplied vertex buffer, from start to end, in order.
    pub fn new_match_vertex_buffer<V>(vbuf: &handle::Buffer<R, V>) -> Self
                                      where V: pso::buffer::Structure<Format> {
        Slice {
            start: 0,
            end: vbuf.len() as u32,
            base_vertex: 0,
            instances: None,
            buffer: IndexBuffer::Auto,
        }
    }

    /// Calculates the number of primitives of the specified type in this `Slice`.
    pub fn get_prim_count(&self, prim: Primitive) -> u32 {
        use core::Primitive as p;
        let nv = (self.end - self.start) as u32;
        match prim {
            p::PointList => nv,
            p::LineList => nv / 2,
            p::LineStrip => (nv-1),
            p::TriangleList => nv / 3,
            p::TriangleStrip => (nv-2) / 3,
            p::LineListAdjacency => nv / 4,
            p::LineStripAdjacency => (nv-3),
            p::TriangleListAdjacency => nv / 6,
            p::TriangleStripAdjacency => (nv-4) / 2,
            p::PatchList(num) => nv / (num as u32),
        }
    }

    /// Divides one slice into two at an index.
    ///
    /// The first will contain the range in the index-buffer [self.start, mid) (excluding the index mid itself) and the
    /// second will contain the range [mid, self.end).
    pub fn split_at(&self, mid: VertexCount) -> (Self, Self) {
        let mut first = self.clone();
        let mut second = self.clone();
        first.end = mid;
        second.start = mid;

        (first, second)
    }
}

/// Type of index-buffer used in a Slice.
///
/// The `Auto` variant represents a hypothetical index-buffer from 0 to infinity. In other words,
/// all vertices get processed in order. Do note that the `Slice`' `start` and `end` restrictions
/// still apply for this variant. To render every vertex in the `VertexBuffer`, you would set
/// `start` to 0, and `end` to the `VertexBuffer`'s length.
///
/// The `Index*` variants represent an actual `Buffer` with a list of vertex-indices. The numeric
/// suffix specifies the amount of bits to use per index. Each of these also contains a
/// base-vertex. This is the index of the first vertex in the `VertexBuffer`. This value will be
/// added to every index in the index-buffer, effectively moving the start of the `VertexBuffer` to
/// this base-vertex.
///
/// # Construction & Handling
/// A `IndexBuffer` can be constructed using the `IntoIndexBuffer` trait, from either a slice or a
/// `Buffer` of integers, using a factory.
///
/// An `IndexBuffer` is exclusively used to create `Slice`s.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum IndexBuffer<R: Resources> {
    /// Represents a hypothetical index-buffer from 0 to infinity. In other words, all vertices
    /// get processed in order.
    Auto,
    /// An index-buffer with unsigned 16 bit indices.
    Index16(handle::Buffer<R, u16>),
    /// An index-buffer with unsigned 32 bit indices.
    Index32(handle::Buffer<R, u32>),
}

impl<R: Resources> Default for IndexBuffer<R> {
    fn default() -> Self {
        IndexBuffer::Auto
    }
}
/// A helper trait to create `IndexBuffers` from different kinds of data.
pub trait IntoIndexBuffer<R: Resources> {
    /// Turns self into an `IndexBuffer`.
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R>;
}

impl<R: Resources> IntoIndexBuffer<R> for IndexBuffer<R> {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        self
    }
}

impl<R: Resources> IntoIndexBuffer<R> for () {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        IndexBuffer::Auto
    }
}

macro_rules! impl_index_buffer {
    ($prim_ty:ty, $buf_ty:ident) => (
        impl<R: Resources> IntoIndexBuffer<R> for handle::Buffer<R, $prim_ty> {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
                IndexBuffer::$buf_ty(self)
            }
        }

        impl<'s, R: Resources> IntoIndexBuffer<R> for &'s [$prim_ty] {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R> {
                factory.create_buffer_immutable(self, buffer::Role::Index, Bind::empty())
                       .unwrap()
                       .into_index_buffer(factory)
            }
        }
    )
}

impl_index_buffer!(u16, Index16);
impl_index_buffer!(u32, Index32);
<|endoftext|>