<commit_before>//! Window creation using glutin for gfx.
//!
//! # Examples
//!
//! The following code creates a `gfx::Surface` using glutin.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//!
//! fn main() {
//!     use gfx_backend_gl::Surface;
//!     use glutin::{EventsLoop, WindowBuilder, ContextBuilder, GlWindow};
//!
//!     // First create a window using glutin.
//!     let mut events_loop = EventsLoop::new();
//!     let wb = WindowBuilder::new();
//!     let cb = ContextBuilder::new().with_vsync(true);
//!     let glutin_window = GlWindow::new(wb, cb, &events_loop).unwrap();
//!
//!     // Then use the glutin window to create a gfx surface.
//!     let surface = Surface::from_window(glutin_window);
//! }
//! ```
//!
//! Headless initialization without a window.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//! extern crate gfx_hal;
//!
//! use gfx_hal::Instance;
//! use gfx_backend_gl::Headless;
//! use glutin::{HeadlessRendererBuilder};
//!
//! fn main() {
//!     let context = HeadlessRendererBuilder::new(256, 256)
//!         .build()
//!         .expect("Failed to build headless context");
//!     let headless = Headless(context);
//!     let _adapters = headless.enumerate_adapters();
//! }
//! ```

use hal::{self, format as f, image};

use {native as n, Backend as B, Device, PhysicalDevice, QueueFamily};

use glutin::{self, GlContext};
use std::rc::Rc;

fn get_window_dimensions(window: &glutin::GlWindow) -> image::Dimensions {
    let (width, height) = window.get_inner_size().unwrap();
    let aa = window.get_pixel_format().multisampling
                   .unwrap_or(0) as image::NumSamples;
    ((width as f32 * window.hidpi_factor()) as image::Size, (height as f32 * window.hidpi_factor()) as image::Size, 1, aa.into())
}

pub struct Swapchain {
    // Underlying window, required for presentation
    window: Rc<glutin::GlWindow>,
}

impl hal::Swapchain<B> for Swapchain {
    fn acquire_frame(&mut self, _sync: hal::FrameSync<B>) -> hal::Frame {
        // TODO: sync
        hal::Frame::new(0)
    }

    fn present<C>(&mut self, _: &mut hal::CommandQueue<B, C>, _: &[&n::Semaphore]) {
        self.window.swap_buffers().unwrap();
    }
}

//TODO: if we make `Surface` a `WindowBuilder` instead of `GlWindow`,
// we could spawn window + GL context when a swapchain is requested
// and actually respect the swapchain configuration provided by the user.
pub struct Surface {
    window: Rc<glutin::GlWindow>,
}

impl Surface {
    pub fn from_window(window: glutin::GlWindow) -> Self {
        Surface {
            window: Rc::new(window)
        }
    }

    fn swapchain_formats(&self) -> Vec<f::Format> {
        use hal::format::ChannelType::*;
        use hal::format::SurfaceType::*;

        let pixel_format = self.window.get_pixel_format();
        let color_bits = pixel_format.color_bits;
        let alpha_bits = pixel_format.alpha_bits;
        let srgb = pixel_format.srgb;

        // TODO: expose more formats
        match (color_bits, alpha_bits, srgb) {
            (24, 8, true) => vec![
                f::Format(R8_G8_B8_A8, Srgb),
                f::Format(B8_G8_R8_A8, Srgb),
            ],
            (24, 8, false) => vec![
                f::Format(R8_G8_B8_A8, Unorm),
                f::Format(B8_G8_R8_A8, Unorm),
            ],
            _ => vec![],
        }
    }
}

impl hal::Surface<B> for Surface {
    fn get_kind(&self) -> hal::image::Kind {
        let (w, h, _, a) = get_window_dimensions(&self.window);
        hal::image::Kind::D2(w, h, a)
    }

    fn capabilities_and_formats(&self, _: &PhysicalDevice) -> (hal::SurfaceCapabilities, Vec<f::Format>) {
        let _formats = self.swapchain_formats();
        unimplemented!()
    }

    fn supports_queue_family(&self, _: &QueueFamily) -> bool { true }
}

impl Device {
    pub(crate) fn create_swapchain_impl(
        &self,
        surface: &mut Surface,
        _config: hal::SwapchainConfig,
    ) -> (Swapchain, hal::Backbuffer<B>) {
        let swapchain = Swapchain {
            window: surface.window.clone(),
        };
        let backbuffer = hal::Backbuffer::Framebuffer(0);
        (swapchain, backbuffer)
    }
}

impl hal::Instance for Surface {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.window.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(|s| self.window.get_proc_address(s) as *const _);
        vec![adapter]
    }
}

pub fn config_context(
    builder: glutin::ContextBuilder,
    color_format: f::Format,
    ds_format: Option<f::Format>,
) -> glutin::ContextBuilder
{
    let color_bits = color_format.0.describe_bits();
    let depth_bits = match ds_format {
        Some(fm) => fm.0.describe_bits(),
        None => f::BITS_ZERO,
    };
    builder
        .with_depth_buffer(depth_bits.depth)
        .with_stencil_buffer(depth_bits.stencil)
        .with_pixel_format(color_bits.color, color_bits.alpha)
        .with_srgb(color_format.1 == f::ChannelType::Srgb)
}

pub struct Headless(pub glutin::HeadlessContext);

impl hal::Instance for Headless {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.0.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(|s| self.0.get_proc_address(s) as *const _);
        vec![adapter]
    }
}
<commit_msg>gl: Initial implementation of `capabilities_and_formats`<commit_after>//! Window creation using glutin for gfx.
//!
//! # Examples
//!
//! The following code creates a `gfx::Surface` using glutin.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//!
//! fn main() {
//!     use gfx_backend_gl::Surface;
//!     use glutin::{EventsLoop, WindowBuilder, ContextBuilder, GlWindow};
//!
//!     // First create a window using glutin.
//!     let mut events_loop = EventsLoop::new();
//!     let wb = WindowBuilder::new();
//!     let cb = ContextBuilder::new().with_vsync(true);
//!     let glutin_window = GlWindow::new(wb, cb, &events_loop).unwrap();
//!
//!     // Then use the glutin window to create a gfx surface.
//!     let surface = Surface::from_window(glutin_window);
//! }
//! ```
//!
//! Headless initialization without a window.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//! extern crate gfx_hal;
//!
//! use gfx_hal::Instance;
//! use gfx_backend_gl::Headless;
//! use glutin::{HeadlessRendererBuilder};
//!
//! fn main() {
//!     let context = HeadlessRendererBuilder::new(256, 256)
//!         .build()
//!         .expect("Failed to build headless context");
//!     let headless = Headless(context);
//!     let _adapters = headless.enumerate_adapters();
//! }
//! ```

use hal::{self, format as f, image};

use {native as n, Backend as B, Device, PhysicalDevice, QueueFamily};

use glutin::{self, GlContext};
use std::rc::Rc;

fn get_window_dimensions(window: &glutin::GlWindow) -> image::Dimensions {
    let (width, height) = window.get_inner_size().unwrap();
    let aa = window.get_pixel_format().multisampling
                   .unwrap_or(0) as image::NumSamples;
    ((width as f32 * window.hidpi_factor()) as image::Size, (height as f32 * window.hidpi_factor()) as image::Size, 1, aa.into())
}

pub struct Swapchain {
    // Underlying window, required for presentation
    window: Rc<glutin::GlWindow>,
}

impl hal::Swapchain<B> for Swapchain {
    fn acquire_frame(&mut self, _sync: hal::FrameSync<B>) -> hal::Frame {
        // TODO: sync
        hal::Frame::new(0)
    }

    fn present<C>(&mut self, _: &mut hal::CommandQueue<B, C>, _: &[&n::Semaphore]) {
        self.window.swap_buffers().unwrap();
    }
}

//TODO: if we make `Surface` a `WindowBuilder` instead of `GlWindow`,
// we could spawn window + GL context when a swapchain is requested
// and actually respect the swapchain configuration provided by the user.
pub struct Surface {
    window: Rc<glutin::GlWindow>,
}

impl Surface {
    pub fn from_window(window: glutin::GlWindow) -> Self {
        Surface {
            window: Rc::new(window)
        }
    }

    fn swapchain_formats(&self) -> Vec<f::Format> {
        use hal::format::ChannelType::*;
        use hal::format::SurfaceType::*;

        let pixel_format = self.window.get_pixel_format();
        let color_bits = pixel_format.color_bits;
        let alpha_bits = pixel_format.alpha_bits;
        let srgb = pixel_format.srgb;

        // TODO: expose more formats
        match (color_bits, alpha_bits, srgb) {
            (24, 8, true) => vec![
                f::Format(R8_G8_B8_A8, Srgb),
                f::Format(B8_G8_R8_A8, Srgb),
            ],
            (24, 8, false) => vec![
                f::Format(R8_G8_B8_A8, Unorm),
                f::Format(B8_G8_R8_A8, Unorm),
            ],
            _ => vec![],
        }
    }
}

impl hal::Surface<B> for Surface {
    fn get_kind(&self) -> hal::image::Kind {
        let (w, h, _, a) = get_window_dimensions(&self.window);
        hal::image::Kind::D2(w, h, a)
    }

    fn capabilities_and_formats(&self, _: &PhysicalDevice) -> (hal::SurfaceCapabilities, Vec<f::Format>) {
        let dim = get_window_dimensions(&self.window);
        let extent = hal::window::Extent2d {
            width: dim.0 as u32,
            height: dim.1 as u32,
        };

        (hal::SurfaceCapabilities {
            image_count: if self.window.get_pixel_format().double_buffer { 2..3 } else { 1..2 },
            current_extent: Some(extent),
            extents: extent..hal::window::Extent2d {
                width: dim.0 as u32 + 1,
                height: dim.1 as u32 + 1
            },
            max_image_layers: 1,
        }, self.swapchain_formats())
    }

    fn supports_queue_family(&self, _: &QueueFamily) -> bool { true }
}

impl Device {
    pub(crate) fn create_swapchain_impl(
        &self,
        surface: &mut Surface,
        _config: hal::SwapchainConfig,
    ) -> (Swapchain, hal::Backbuffer<B>) {
        let swapchain = Swapchain {
            window: surface.window.clone(),
        };
        let backbuffer = hal::Backbuffer::Framebuffer(0);
        (swapchain, backbuffer)
    }
}

impl hal::Instance for Surface {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.window.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(|s| self.window.get_proc_address(s) as *const _);
        vec![adapter]
    }
}

pub fn config_context(
    builder: glutin::ContextBuilder,
    color_format: f::Format,
    ds_format: Option<f::Format>,
) -> glutin::ContextBuilder
{
    let color_bits = color_format.0.describe_bits();
    let depth_bits = match ds_format {
        Some(fm) => fm.0.describe_bits(),
        None => f::BITS_ZERO,
    };
    builder
        .with_depth_buffer(depth_bits.depth)
        .with_stencil_buffer(depth_bits.stencil)
        .with_pixel_format(color_bits.color, color_bits.alpha)
        .with_srgb(color_format.1 == f::ChannelType::Srgb)
}

pub struct Headless(pub glutin::HeadlessContext);

impl hal::Instance for Headless {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.0.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(|s| self.0.get_proc_address(s) as *const _);
        vec![adapter]
    }
}
<|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/. */

//! Common handling for the specified value CSS url() values.

use cssparser::Parser;
use gecko_bindings::bindings;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
use gecko_bindings::sugar::refptr::RefPtr;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use nsstring::nsCString;
use parser::{Parse, ParserContext};
use servo_arc::{Arc, RawOffsetArc};
use std::fmt::{self, Write};
use std::mem;
use style_traits::{CssWriter, ParseError, ToCss};
use stylesheets::UrlExtraData;
use values::computed::{Context, ToComputedValue};

/// A CSS url() value for gecko.
#[css(function = "url")]
#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)]
pub struct CssUrl {
    /// The URL in unresolved string form.
    ///
    /// Refcounted since cloning this should be cheap and data: uris can be
    /// really large.
    serialization: Arc<String>,

    /// The URL extra data.
    #[css(skip)]
    pub extra_data: UrlExtraData,
}

impl CssUrl {
    /// Try to parse a URL from a string value that is a valid CSS token for a
    /// URL.
    pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
        CssUrl {
            serialization: Arc::new(url),
            extra_data: context.url_data.clone(),
        }
    }

    /// Returns true if the URL is definitely invalid. We don't eagerly resolve
    /// URLs in gecko, so we just return false here.
    /// use its |resolved| status.
    pub fn is_invalid(&self) -> bool {
        false
    }

    /// Convert from URLValueData to SpecifiedUrl.
    unsafe fn from_url_value_data(url: &URLValueData) -> Self {
        let arc_type = &url.mString as *const _ as *const RawOffsetArc<String>;
        CssUrl {
            serialization: Arc::from_raw_offset((*arc_type).clone()),
            extra_data: UrlExtraData(url.mExtraData.to_safe()),
        }
    }

    /// Returns true if this URL looks like a fragment.
    /// See https://drafts.csswg.org/css-values/#local-urls
    pub fn is_fragment(&self) -> bool {
        self.as_str().chars().next().map_or(false, |c| c == '#')
    }

    /// Return the unresolved url as string, or the empty string if it's
    /// invalid.
    pub fn as_str(&self) -> &str {
        &*self.serialization
    }

    /// Little helper for Gecko's ffi.
    pub fn as_slice_components(&self) -> (*const u8, usize) {
        (
            self.serialization.as_str().as_ptr(),
            self.serialization.as_str().len(),
        )
    }

    /// Create a bundled URI suitable for sending to Gecko
    /// to be constructed into a css::URLValue
    pub fn for_ffi(&self) -> ServoBundledURI {
        let arc_offset = Arc::into_raw_offset(self.serialization.clone());
        ServoBundledURI {
            mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) },
            mExtraData: self.extra_data.0.get(),
        }
    }
}

impl Parse for CssUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        let url = input.expect_url()?;
        Ok(Self::parse_from_string(url.as_ref().to_owned(), context))
    }
}

impl Eq for CssUrl {}

impl MallocSizeOf for CssUrl {
    fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
        // XXX: measure `serialization` once bug 1397971 lands

        // We ignore `extra_data`, because RefPtr is tricky, and there aren't
        // many of them in practise (sharing is common).

        0
    }
}

/// A specified url() value for general usage.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedUrl {
    /// The specified url value.
    pub url: CssUrl,
    /// Gecko's URLValue so that we can reuse it while rematching a
    /// property with this specified value.
    #[css(skip)]
    pub url_value: RefPtr<URLValue>,
}

impl SpecifiedUrl {
    fn from_css_url(url: CssUrl) -> Self {
        let url_value = unsafe {
            let ptr = bindings::Gecko_NewURLValue(url.for_ffi());
            // We do not expect Gecko_NewURLValue returns null.
            debug_assert!(!ptr.is_null());
            RefPtr::from_addrefed(ptr)
        };
        Self { url, url_value }
    }
}

impl PartialEq for SpecifiedUrl {
    fn eq(&self, other: &Self) -> bool {
        self.url.eq(&other.url)
    }
}

impl Eq for SpecifiedUrl {}

impl Parse for SpecifiedUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        CssUrl::parse(context, input).map(Self::from_css_url)
    }
}

impl MallocSizeOf for SpecifiedUrl {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let mut n = self.url.size_of(ops);
        // Although this is a RefPtr, this is the primary reference because
        // SpecifiedUrl is responsible for creating the url_value. So we
        // measure unconditionally here.
        n += unsafe { bindings::Gecko_URLValue_SizeOfIncludingThis(self.url_value.get()) };
        n
    }
}

/// A specified url() value for image.
///
/// This exists so that we can construct `ImageValue` and reuse it.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedImageUrl {
    /// The specified url value.
    pub url: CssUrl,
    /// Gecko's ImageValue so that we can reuse it while rematching a
    /// property with this specified value.
    #[css(skip)]
    pub image_value: RefPtr<ImageValue>,
}

impl SpecifiedImageUrl {
    /// Parse a URL from a string value. See SpecifiedUrl::parse_from_string.
    pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
        Self::from_css_url(CssUrl::parse_from_string(url, context))
    }

    fn from_css_url(url: CssUrl) -> Self {
        let image_value = unsafe {
            let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi());
            // We do not expect Gecko_ImageValue_Create returns null.
            debug_assert!(!ptr.is_null());
            RefPtr::from_addrefed(ptr)
        };
        Self { url, image_value }
    }
}

impl Parse for SpecifiedImageUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        CssUrl::parse(context, input).map(Self::from_css_url)
    }
}

impl PartialEq for SpecifiedImageUrl {
    fn eq(&self, other: &Self) -> bool {
        self.url.eq(&other.url)
    }
}

impl Eq for SpecifiedImageUrl {}

impl MallocSizeOf for SpecifiedImageUrl {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let mut n = self.url.size_of(ops);
        // Although this is a RefPtr, this is the primary reference because
        // SpecifiedUrl is responsible for creating the image_value. So we
        // measure unconditionally here.
        n += unsafe { bindings::Gecko_ImageValue_SizeOfIncludingThis(self.image_value.get()) };
        n
    }
}

impl ToComputedValue for SpecifiedUrl {
    type ComputedValue = ComputedUrl;

    #[inline]
    fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
        ComputedUrl(self.clone())
    }

    #[inline]
    fn from_computed_value(computed: &Self::ComputedValue) -> Self {
        computed.0.clone()
    }
}

impl ToComputedValue for SpecifiedImageUrl {
    type ComputedValue = ComputedImageUrl;

    #[inline]
    fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
        ComputedImageUrl(self.clone())
    }

    #[inline]
    fn from_computed_value(computed: &Self::ComputedValue) -> Self {
        computed.0.clone()
    }
}

fn serialize_computed_url<W>(url_value_data: &URLValueData, dest: &mut CssWriter<W>) -> fmt::Result
where
    W: Write,
{
    dest.write_str("url(")?;
    unsafe {
        let mut string = nsCString::new();
        bindings::Gecko_GetComputedURLSpec(url_value_data, &mut string);
        string.as_str_unchecked().to_css(dest)?;
    }
    dest.write_char(')')
}

/// The computed value of a CSS `url()`.
///
/// The only difference between specified and computed URLs is the
/// serialization.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub struct ComputedUrl(pub SpecifiedUrl);

impl ToCss for ComputedUrl {
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    where
        W: Write,
    {
        serialize_computed_url(&self.0.url_value._base, dest)
    }
}

impl ComputedUrl {
    /// Convert from RefPtr<URLValue> to ComputedUrl.
    pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> Self {
        let url = CssUrl::from_url_value_data(&url_value._base);
        ComputedUrl(SpecifiedUrl { url, url_value })
    }
}

/// The computed value of a CSS `url()` for image.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub struct ComputedImageUrl(pub SpecifiedImageUrl);

impl ToCss for ComputedImageUrl {
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    where
        W: Write,
    {
        serialize_computed_url(&self.0.image_value._base, dest)
    }
}

impl ComputedImageUrl {
    /// Convert from nsStyleImageReques to ComputedImageUrl.
    pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self {
        let image_value = image_request.mImageValue.to_safe();
        let url = CssUrl::from_url_value_data(&image_value._base);
        ComputedImageUrl(SpecifiedImageUrl { url, image_value })
    }
}
<commit_msg>style: Change Gecko_ImageValue_Create to take a CORS mode argument.<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/. */

//! Common handling for the specified value CSS url() values.

use cssparser::Parser;
use gecko_bindings::bindings;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::CORSMode;
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
use gecko_bindings::sugar::refptr::RefPtr;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use nsstring::nsCString;
use parser::{Parse, ParserContext};
use servo_arc::{Arc, RawOffsetArc};
use std::fmt::{self, Write};
use std::mem;
use style_traits::{CssWriter, ParseError, ToCss};
use stylesheets::UrlExtraData;
use values::computed::{Context, ToComputedValue};

/// A CSS url() value for gecko.
#[css(function = "url")]
#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)]
pub struct CssUrl {
    /// The URL in unresolved string form.
    ///
    /// Refcounted since cloning this should be cheap and data: uris can be
    /// really large.
    serialization: Arc<String>,

    /// The URL extra data.
    #[css(skip)]
    pub extra_data: UrlExtraData,
}

impl CssUrl {
    /// Try to parse a URL from a string value that is a valid CSS token for a
    /// URL.
    pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
        CssUrl {
            serialization: Arc::new(url),
            extra_data: context.url_data.clone(),
        }
    }

    /// Returns true if the URL is definitely invalid. We don't eagerly resolve
    /// URLs in gecko, so we just return false here.
    /// use its |resolved| status.
    pub fn is_invalid(&self) -> bool {
        false
    }

    /// Convert from URLValueData to SpecifiedUrl.
    unsafe fn from_url_value_data(url: &URLValueData) -> Self {
        let arc_type = &url.mString as *const _ as *const RawOffsetArc<String>;
        CssUrl {
            serialization: Arc::from_raw_offset((*arc_type).clone()),
            extra_data: UrlExtraData(url.mExtraData.to_safe()),
        }
    }

    /// Returns true if this URL looks like a fragment.
    /// See https://drafts.csswg.org/css-values/#local-urls
    pub fn is_fragment(&self) -> bool {
        self.as_str().chars().next().map_or(false, |c| c == '#')
    }

    /// Return the unresolved url as string, or the empty string if it's
    /// invalid.
    pub fn as_str(&self) -> &str {
        &*self.serialization
    }

    /// Little helper for Gecko's ffi.
    pub fn as_slice_components(&self) -> (*const u8, usize) {
        (
            self.serialization.as_str().as_ptr(),
            self.serialization.as_str().len(),
        )
    }

    /// Create a bundled URI suitable for sending to Gecko
    /// to be constructed into a css::URLValue
    pub fn for_ffi(&self) -> ServoBundledURI {
        let arc_offset = Arc::into_raw_offset(self.serialization.clone());
        ServoBundledURI {
            mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) },
            mExtraData: self.extra_data.0.get(),
        }
    }
}

impl Parse for CssUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        let url = input.expect_url()?;
        Ok(Self::parse_from_string(url.as_ref().to_owned(), context))
    }
}

impl Eq for CssUrl {}

impl MallocSizeOf for CssUrl {
    fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
        // XXX: measure `serialization` once bug 1397971 lands

        // We ignore `extra_data`, because RefPtr is tricky, and there aren't
        // many of them in practise (sharing is common).

        0
    }
}

/// A specified url() value for general usage.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedUrl {
    /// The specified url value.
    pub url: CssUrl,
    /// Gecko's URLValue so that we can reuse it while rematching a
    /// property with this specified value.
    #[css(skip)]
    pub url_value: RefPtr<URLValue>,
}

impl SpecifiedUrl {
    fn from_css_url(url: CssUrl) -> Self {
        let url_value = unsafe {
            let ptr = bindings::Gecko_NewURLValue(url.for_ffi());
            // We do not expect Gecko_NewURLValue returns null.
            debug_assert!(!ptr.is_null());
            RefPtr::from_addrefed(ptr)
        };
        Self { url, url_value }
    }
}

impl PartialEq for SpecifiedUrl {
    fn eq(&self, other: &Self) -> bool {
        self.url.eq(&other.url)
    }
}

impl Eq for SpecifiedUrl {}

impl Parse for SpecifiedUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        CssUrl::parse(context, input).map(Self::from_css_url)
    }
}

impl MallocSizeOf for SpecifiedUrl {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let mut n = self.url.size_of(ops);
        // Although this is a RefPtr, this is the primary reference because
        // SpecifiedUrl is responsible for creating the url_value. So we
        // measure unconditionally here.
        n += unsafe { bindings::Gecko_URLValue_SizeOfIncludingThis(self.url_value.get()) };
        n
    }
}

/// A specified url() value for image.
///
/// This exists so that we can construct `ImageValue` and reuse it.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedImageUrl {
    /// The specified url value.
    pub url: CssUrl,
    /// Gecko's ImageValue so that we can reuse it while rematching a
    /// property with this specified value.
    #[css(skip)]
    pub image_value: RefPtr<ImageValue>,
}

impl SpecifiedImageUrl {
    /// Parse a URL from a string value. See SpecifiedUrl::parse_from_string.
    pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
        Self::from_css_url(CssUrl::parse_from_string(url, context))
    }

    fn from_css_url_with_cors(url: CssUrl, cors: CORSMode) -> Self {
        let image_value = unsafe {
            let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi(), cors);
            // We do not expect Gecko_ImageValue_Create returns null.
            debug_assert!(!ptr.is_null());
            RefPtr::from_addrefed(ptr)
        };
        Self { url, image_value }
    }

    fn from_css_url(url: CssUrl) -> Self {
        use gecko_bindings::structs::root::mozilla::CORSMode_CORS_NONE;
        Self::from_css_url_with_cors(url, CORSMode_CORS_NONE)
    }
}

impl Parse for SpecifiedImageUrl {
    fn parse<'i, 't>(
        context: &ParserContext,
        input: &mut Parser<'i, 't>,
    ) -> Result<Self, ParseError<'i>> {
        CssUrl::parse(context, input).map(Self::from_css_url)
    }
}

impl PartialEq for SpecifiedImageUrl {
    fn eq(&self, other: &Self) -> bool {
        self.url.eq(&other.url)
    }
}

impl Eq for SpecifiedImageUrl {}

impl MallocSizeOf for SpecifiedImageUrl {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let mut n = self.url.size_of(ops);
        // Although this is a RefPtr, this is the primary reference because
        // SpecifiedUrl is responsible for creating the image_value. So we
        // measure unconditionally here.
        n += unsafe { bindings::Gecko_ImageValue_SizeOfIncludingThis(self.image_value.get()) };
        n
    }
}

impl ToComputedValue for SpecifiedUrl {
    type ComputedValue = ComputedUrl;

    #[inline]
    fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
        ComputedUrl(self.clone())
    }

    #[inline]
    fn from_computed_value(computed: &Self::ComputedValue) -> Self {
        computed.0.clone()
    }
}

impl ToComputedValue for SpecifiedImageUrl {
    type ComputedValue = ComputedImageUrl;

    #[inline]
    fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
        ComputedImageUrl(self.clone())
    }

    #[inline]
    fn from_computed_value(computed: &Self::ComputedValue) -> Self {
        computed.0.clone()
    }
}

fn serialize_computed_url<W>(url_value_data: &URLValueData, dest: &mut CssWriter<W>) -> fmt::Result
where
    W: Write,
{
    dest.write_str("url(")?;
    unsafe {
        let mut string = nsCString::new();
        bindings::Gecko_GetComputedURLSpec(url_value_data, &mut string);
        string.as_str_unchecked().to_css(dest)?;
    }
    dest.write_char(')')
}

/// The computed value of a CSS `url()`.
///
/// The only difference between specified and computed URLs is the
/// serialization.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub struct ComputedUrl(pub SpecifiedUrl);

impl ToCss for ComputedUrl {
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    where
        W: Write,
    {
        serialize_computed_url(&self.0.url_value._base, dest)
    }
}

impl ComputedUrl {
    /// Convert from RefPtr<URLValue> to ComputedUrl.
    pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> Self {
        let url = CssUrl::from_url_value_data(&url_value._base);
        ComputedUrl(SpecifiedUrl { url, url_value })
    }
}

/// The computed value of a CSS `url()` for image.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub struct ComputedImageUrl(pub SpecifiedImageUrl);

impl ToCss for ComputedImageUrl {
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    where
        W: Write,
    {
        serialize_computed_url(&self.0.image_value._base, dest)
    }
}

impl ComputedImageUrl {
    /// Convert from nsStyleImageReques to ComputedImageUrl.
    pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self {
        let image_value = image_request.mImageValue.to_safe();
        let url = CssUrl::from_url_value_data(&image_value._base);
        ComputedImageUrl(SpecifiedImageUrl { url, image_value })
    }
}
<|endoftext|>


<commit_before>use std::f64;
use std::from_str::FromStr;
use std::os;
use std::vec;

#[inline]
fn A(i: i32, j: i32) -> i32 {
    (i+j) * (i+j+1) / 2 + i + 1
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    let mut sum = 0.0;
    for v.iter().enumerate().advance |(i, &v_i)| {
        sum += v_i * u[i];
    }
    sum
}

fn mult_Av(v: &mut [f64], out: &mut [f64]) {
    for out.mut_iter().enumerate().advance |(i, out_i)| {
        let mut sum = 0.0;
        for v.mut_iter().enumerate().advance |(j, &v_j)| {
            sum += v_j / (A(i as i32, j as i32) as f64);
        }
        *out_i = sum;
    }
}

fn mult_Atv(v: &mut [f64], out: &mut [f64]) {
    for out.mut_iter().enumerate().advance |(i, out_i)| {
        let mut sum = 0.0;
        for v.mut_iter().enumerate().advance |(j, &v_j)| {
            sum += v_j / (A(j as i32, i as i32) as f64);
        }
        *out_i = sum;
    }
}

fn mult_AtAv(v: &mut [f64], out: &mut [f64], tmp: &mut [f64]) {
    mult_Av(v, tmp);
    mult_Atv(tmp, out);
}

#[fixed_stack_segment]
fn main() {
    let n: uint = FromStr::from_str(os::args()[1]).get();
    let mut u = vec::from_elem(n, 1f64);
    let mut v = u.clone();
    let mut tmp = u.clone();
    for 8.times {
        mult_AtAv(u, v, tmp);
        mult_AtAv(v, u, tmp);
    }

    println(fmt!("%.9f", f64::sqrt(dot(u,v) / dot(v,v)) as float));
}
<commit_msg>Added missing copyright notice to shootout-spectralnorm.<commit_after>// Copyright 2012-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.

use std::f64;
use std::from_str::FromStr;
use std::os;
use std::vec;

#[inline]
fn A(i: i32, j: i32) -> i32 {
    (i+j) * (i+j+1) / 2 + i + 1
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    let mut sum = 0.0;
    for v.iter().enumerate().advance |(i, &v_i)| {
        sum += v_i * u[i];
    }
    sum
}

fn mult_Av(v: &mut [f64], out: &mut [f64]) {
    for out.mut_iter().enumerate().advance |(i, out_i)| {
        let mut sum = 0.0;
        for v.mut_iter().enumerate().advance |(j, &v_j)| {
            sum += v_j / (A(i as i32, j as i32) as f64);
        }
        *out_i = sum;
    }
}

fn mult_Atv(v: &mut [f64], out: &mut [f64]) {
    for out.mut_iter().enumerate().advance |(i, out_i)| {
        let mut sum = 0.0;
        for v.mut_iter().enumerate().advance |(j, &v_j)| {
            sum += v_j / (A(j as i32, i as i32) as f64);
        }
        *out_i = sum;
    }
}

fn mult_AtAv(v: &mut [f64], out: &mut [f64], tmp: &mut [f64]) {
    mult_Av(v, tmp);
    mult_Atv(tmp, out);
}

#[fixed_stack_segment]
fn main() {
    let n: uint = FromStr::from_str(os::args()[1]).get();
    let mut u = vec::from_elem(n, 1f64);
    let mut v = u.clone();
    let mut tmp = u.clone();
    for 8.times {
        mult_AtAv(u, v, tmp);
        mult_AtAv(v, u, tmp);
    }

    println(fmt!("%.9f", f64::sqrt(dot(u,v) / dot(v,v)) as float));
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate version;

extern crate libimagbookmark;
extern crate libimagentrylink;
extern crate libimagentrytag;
extern crate libimagrt;
extern crate libimagerror;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagbookmark::collection::BookmarkCollection;
use libimagbookmark::link::Link as BookmarkLink;
use libimagerror::trace::{trace_error, trace_error_exit};

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-bookmark",
                                    &version!()[..],
                                    "Bookmark collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "add"        => add(&rt),
                "collection" => collection(&rt),
                "list"       => list(&rt),
                "remove"     => remove(&rt),
                _            => {
                    debug!("Unknown command"); // More error handling
                },
            }
        });
}

fn add(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("add").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|mut collection| {
            for url in scmd.values_of("urls").unwrap() { // enforced by clap
                collection.add_link(BookmarkLink::from(url)).map_err(|e| trace_error(&e));
            }
        });
    info!("Ready");
}

fn collection(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("collection").unwrap();

    if scmd.is_present("add") { // adding a new collection
        let name = scmd.value_of("add").unwrap();
        if let Ok(_) = BookmarkCollection::new(rt.store(), name) {
            info!("Created: {}", name);
        } else {
            warn!("Creating collection {} failed", name);
            exit(1);
        }
    }

    if scmd.is_present("remove") { // remove a collection
        let name = scmd.value_of("remove").unwrap();
        if let Ok(_) = BookmarkCollection::delete(rt.store(), name) {
            info!("Deleted: {}", name);
        } else {
            warn!("Deleting collection {} failed", name);
            exit(1);
        }
    }
}

fn list(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("list").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|collection| {
            match collection.links() {
                Ok(links) => {
                    debug!("Listing...");
                    for (i, link) in links.iter().enumerate() {
                        println!("{: >3}: {}", i, link);
                    };
                    debug!("... ready with listing");
                },
                Err(e) => trace_error_exit(&e, 1),
            }
        });
    info!("Ready");
}

fn remove(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("remove").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|mut collection| {
            for url in scmd.values_of("urls").unwrap() { // enforced by clap
                collection.remove_link(BookmarkLink::from(url)).map_err(|e| trace_error(&e));
            }
        });
    info!("Ready");
}

<commit_msg>Use unused results<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate version;

extern crate libimagbookmark;
extern crate libimagentrylink;
extern crate libimagentrytag;
extern crate libimagrt;
extern crate libimagerror;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagbookmark::collection::BookmarkCollection;
use libimagbookmark::link::Link as BookmarkLink;
use libimagerror::trace::{trace_error, trace_error_exit};

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-bookmark",
                                    &version!()[..],
                                    "Bookmark collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "add"        => add(&rt),
                "collection" => collection(&rt),
                "list"       => list(&rt),
                "remove"     => remove(&rt),
                _            => {
                    debug!("Unknown command"); // More error handling
                },
            }
        });
}

fn add(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("add").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|mut collection| {
            for url in scmd.values_of("urls").unwrap() { // enforced by clap
                collection.add_link(BookmarkLink::from(url)).map_err(|e| trace_error(&e)).ok();
            }
        });
    info!("Ready");
}

fn collection(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("collection").unwrap();

    if scmd.is_present("add") { // adding a new collection
        let name = scmd.value_of("add").unwrap();
        if let Ok(_) = BookmarkCollection::new(rt.store(), name) {
            info!("Created: {}", name);
        } else {
            warn!("Creating collection {} failed", name);
            exit(1);
        }
    }

    if scmd.is_present("remove") { // remove a collection
        let name = scmd.value_of("remove").unwrap();
        if let Ok(_) = BookmarkCollection::delete(rt.store(), name) {
            info!("Deleted: {}", name);
        } else {
            warn!("Deleting collection {} failed", name);
            exit(1);
        }
    }
}

fn list(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("list").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|collection| {
            match collection.links() {
                Ok(links) => {
                    debug!("Listing...");
                    for (i, link) in links.iter().enumerate() {
                        println!("{: >3}: {}", i, link);
                    };
                    debug!("... ready with listing");
                },
                Err(e) => trace_error_exit(&e, 1),
            }
        })
        .ok();
    info!("Ready");
}

fn remove(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("remove").unwrap();
    let coll = scmd.value_of("collection").unwrap(); // enforced by clap

    BookmarkCollection::get(rt.store(), coll)
        .map(|mut collection| {
            for url in scmd.values_of("urls").unwrap() { // enforced by clap
                collection.remove_link(BookmarkLink::from(url)).map_err(|e| trace_error(&e)).ok();
            }
        })
        .ok();
    info!("Ready");
}

<|endoftext|>


<commit_before>use super::camera::*;
use super::event_manager::*;
use glium::backend::glutin_backend::GlutinFacade;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};

pub struct Ghost {
    cam: Camera,
    prev_mouse_pos: Option<(i32, i32)>,
    context: GlutinFacade,
}

impl Ghost {
    pub fn new(context: GlutinFacade) -> Self {
        Ghost {
            cam: Camera::default(),
            prev_mouse_pos: None,
            context: context,
        }
    }

    pub fn get_camera(&self) -> Camera {
        self.cam
    }
}

/// **Implements Controls**
/// *W => FORWARD
/// *A => LEFT
/// *S => BACKWARDS
/// *D => RIGHT
/// *'Space' => UP
/// *'LControl' => DOWN (only accepts one keystroke (cannot hold LControl to go
/// down))
/// *'C' => DOWN (as a replacement for 'LControl')

/// MouseMovement for changing the direction the camera looks
impl EventHandler for Ghost {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.cam.move_forward(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.cam.move_backward(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.cam.move_left(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.cam.move_right(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.cam.move_up(1.0);
                EventResponse::Continue
            }
            // X only for the fact, that you cannot hold LControl to go down,
            // because holding the key only counts as one keystroke
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::C)) => {
                self.cam.move_down(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                self.cam.move_down(1.0);
                EventResponse::Continue
            }

            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                info!("clicked");
                if let Some(window) = self.context.get_window() {
                    let res = window.set_cursor_state(CursorState::Grab);
                    warn!("{:?}", res);
                } else {
                    warn!("Failed to obtain window from facade");
                }
                EventResponse::Continue
            }
            Event::MouseMoved(x, y) => {

                if let Some((prev_x, prev_y)) = self.prev_mouse_pos {
                    let x_diff = x - prev_x;
                    let y_diff = y - prev_y;
                    info!("x = {}, y = {}", x_diff, y_diff);
                    self.cam.change_dir(y_diff as f32 / 300.0, x_diff as f32 / 300.0);
                }

                self.prev_mouse_pos = Some((x, y));

                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }
    }
}
<commit_msg>fix left and right MouseMovement (it was the other way around)<commit_after>use super::camera::*;
use super::event_manager::*;
use glium::backend::glutin_backend::GlutinFacade;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};

pub struct Ghost {
    cam: Camera,
    prev_mouse_pos: Option<(i32, i32)>,
    context: GlutinFacade,
}

impl Ghost {
    pub fn new(context: GlutinFacade) -> Self {
        Ghost {
            cam: Camera::default(),
            prev_mouse_pos: None,
            context: context,
        }
    }

    pub fn get_camera(&self) -> Camera {
        self.cam
    }
}

/// **Implements Controls**
/// *W => FORWARD
/// *A => LEFT
/// *S => BACKWARDS
/// *D => RIGHT
/// *'Space' => UP
/// *'LControl' => DOWN (only accepts one keystroke (cannot hold LControl to go
/// down))
/// *'C' => DOWN (as a replacement for 'LControl')

/// MouseMovement for changing the direction the camera looks
impl EventHandler for Ghost {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.cam.move_forward(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.cam.move_backward(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.cam.move_left(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.cam.move_right(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.cam.move_up(1.0);
                EventResponse::Continue
            }
            // X only for the fact, that you cannot hold LControl to go down,
            // because holding the key only counts as one keystroke
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::C)) => {
                self.cam.move_down(1.0);
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                self.cam.move_down(1.0);
                EventResponse::Continue
            }

            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                info!("clicked");
                if let Some(window) = self.context.get_window() {
                    let res = window.set_cursor_state(CursorState::Hide);
                    warn!("{:?}", res);
                } else {
                    warn!("Failed to obtain window from facade");
                }
                EventResponse::Continue
            }
            Event::MouseMoved(x, y) => {

                if let Some((prev_x, prev_y)) = self.prev_mouse_pos {
                    let x_diff = x - prev_x;
                    let y_diff = y - prev_y;
                    info!("x = {}, y = {}", x_diff, y_diff);
                    self.cam.change_dir(y_diff as f32 / 300.0, -x_diff as f32 / 300.0);
                }

                self.prev_mouse_pos = Some((x, y));

                EventResponse::Continue
            }
            // Event::MouseMoved(x, y) => {
            //     if let Some(window) = self.context.get_window() {
            //         // Possibility of mouse being outside of window without it reseting to the
            //         // middle?
            //         if let Some(middle) = window.get_inner_size_pixels() {
            //             let middle_x = (middle.0 as i32) / 2;
            //             let middle_y = (middle.1 as i32) / 2;
            //             let x_diff = x - middle_x;
            //             let y_diff = y - middle_y;
            //             self.cam.change_dir(y_diff as f32 / 300.0, x_diff as f32 / 300.0);
            //             window.set_cursor_position(middle_x as i32, middle_y as i32);
            //         }
            //     }
            //     EventResponse::Continue
            // }

            _ => EventResponse::NotHandled,
        }
    }
}
<|endoftext|>


<commit_before>//! Client optimized Event Queue

use std::io::Cursor;

use mio;
use mio::{TryRead, TryWrite};
use mio::tcp::TcpStream;
use mio::util::Slab;

struct Connection
{
    socket: TcpStream,
    token: mio::Token,
    state: State,
}

impl mio::Handler for Connection
{
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Connection>, token: mio::Token, events: mio::EventSet)
    {

        match self.state
        {
            State::Reading(_) =>
            {
                self.read(event_loop)
            },
            State::Writing(_) =>
            {
                self.write(event_loop)
            },
            State::Closed =>
            {
                event_loop.shutdown();
            }
        }
    }
}

impl Connection
{
    fn read(&mut self, event_loop: &mut mio::EventLoop<Connection>)
    {
        match self.socket.try_read_buf(self.state.mut_read_buf())
        {
            Ok(Some(0)) =>
            {
                // Socket is closed
                self.state = State::Closed;
            },
            Ok(Some(n)) =>
            {
                self.reregister(event_loop)
            },
            Ok(None) =>
            {
                self.reregister(event_loop)
            }
            Err(e) =>
            {
                panic!("Got an error: {:?}", e);
            },
        }
    }

    fn write(&mut self, event_loop: &mut mio::EventLoop<Connection>)
    {

    }

    fn reregister(&mut self, event_loop: &mut mio::EventLoop<Connection>)
    {

    }
}

enum State
{
    Reading(Vec<u8>),
    Writing(Cursor<Vec<u8>>),
    Closed,
}

impl State
{
    fn mut_read_buf(&mut self) -> &mut Vec<u8>
    {
        match *self
        {
            State::Reading(ref mut buf) => buf,
            // FIXME
            _ => panic!()
        }
    }
}
<commit_msg>Reworked Client Queue<commit_after>//! Client optimized Event Queue

use std::io::Cursor;
use std::io::{Read, Write};

use mio;
use mio::{TryRead, TryWrite};
use mio::tcp::TcpStream;
use mio::util::Slab;

use protocol::ber::common::Tag;
use protocol::ber::encode;

struct Connection
{
    socket: TcpStream,
    //token: mio::Token,
    readbuf: Vec<u8>,
    writebuf: Vec<u8>,
}

impl mio::Handler for Connection
{
    type Timeout = ();
    type Message = (i32, Tag);

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Connection>, token: mio::Token, events: mio::EventSet)
    {
        if self.writebuf.len() > 0 && events.is_writable()
        {
            self.socket.write(self.writebuf.as_slice());
        }

        if events.is_readable()
        {
            self.socket.read_to_end(&mut self.readbuf);
        }
    }

    fn notify(&mut self, event_loop: &mut mio::EventLoop<Connection>, msg: Self::Message)
    {
        if let Ok(bytes) = encode(msg.1, msg.0)
        {
            self.writebuf.write(&bytes);
        }
    }
}
<|endoftext|>


<commit_before>use bincode;
use bls::Keypair;
use clap::ArgMatches;
use std::fs;
use std::fs::File;
use std::io::{Error, ErrorKind};
use std::path::PathBuf;
use slog::{debug, info, error};
use types::ChainSpec;

/// Stores the core configuration for this validator instance.
#[derive(Clone)]
pub struct Config {
    /// The data directory, which stores all validator databases
    pub data_dir: PathBuf,
    /// The server at which the Beacon Node can be contacted
    pub server: String,
    /// The chain specification that we are connecting to
    pub spec: ChainSpec,
}

const DEFAULT_PRIVATE_KEY_FILENAME: &str = "private.key";

impl Default for Config {
    fn default() -> Self {
        let data_dir = {
            let home = dirs::home_dir().expect("Unable to determine home directory.");
            home.join(".lighthouse-validator")
        };
        fs::create_dir_all(&data_dir)
            .unwrap_or_else(|_| panic!("Unable to create {:?}", &data_dir));

        let server = "localhost:50051".to_string();

        let spec = ChainSpec::foundation();

        Self {
            data_dir,
            server,
            spec,
        }
    }
}

impl Config {
    /// Build a new configuration from defaults, which are overrided by arguments provided.
    pub fn parse_args(args: &ArgMatches, log: &slog::Logger) -> Result<Self, Error> {
        let mut config = Config::default();

        // Use the specified datadir, or default in the home directory
        if let Some(datadir) = args.value_of("datadir") {
            config.data_dir = PathBuf::from(datadir);
            fs::create_dir_all(&config.data_dir)
                .unwrap_or_else(|_| panic!("Unable to create {:?}", &config.data_dir));
            info!(log, "Using custom data dir: {:?}", &config.data_dir);
        };

        if let Some(srv) = args.value_of("server") {
            //TODO: I don't think this parses correctly a server & port combo
            config.server = srv.to_string();
            info!(log, "Using custom server: {:?}", &config.server);
        };

        // TODO: Permit loading a custom spec from file.
        if let Some(spec_str) = args.value_of("spec") {
            info!(log, "Using custom spec: {:?}", spec_str);
            config.spec = match spec_str {
                "foundation" => ChainSpec::foundation(),
                "few_validators" => ChainSpec::few_validators(),
                // Should be impossible due to clap's `possible_values(..)` function.
                _ => unreachable!(),
            };
        };

        Ok(config)
    }

    /// Try to load keys from validator_dir, returning None if none are found or an error.
    pub fn fetch_keys(&self, log: &slog::Logger) -> Option<Vec<Keypair>> {

        let key_pairs: Vec<Keypair> = fs::read_dir(&self.data_dir)
            .unwrap()
            .filter_map( |validator_dir| {

                let validator_dir = validator_dir.ok()?;

                if !(validator_dir.file_type().ok()?.is_dir()) {
                    // Skip non-directories (i.e. no files/symlinks)
                    return None;
                }

                let key_filename = validator_dir.path().join(DEFAULT_PRIVATE_KEY_FILENAME);

                if !(key_filename.is_file()) {
                    info!(log, "Private key is not a file: {:?}", key_filename.to_str());
                    return None;
                }

                debug!(log, "Deserializing private key from file: {:?}", key_filename.to_str());

                let mut key_file = File::open(key_filename.clone()).ok()?;

                let key: Keypair = if let Ok(key_ok) = bincode::deserialize_from(&mut key_file) {
                        key_ok
                    } else {
                        error!(log, "Unable to deserialize the private key file: {:?}", key_filename);
                        return None;
                    };

                let ki = key.identifier();
                if ki != validator_dir.file_name().into_string().ok()? {
                    error!(log, "The validator key ({:?}) did not match the directory filename {:?}.", ki, &validator_dir.path().to_string_lossy());
                    return None;
                }
                Some(key)
            })
            .collect();

        // Check if it's an empty vector, and return none.
        if key_pairs.is_empty() {
            None
        } else {
            Some(key_pairs)
        }

    }

    /// Saves a keypair to a file inside the appropriate validator directory. Returns the saved path filename.
    pub fn save_key(&self, key: &Keypair) -> Result<PathBuf, Error> {
        let validator_config_path = self.data_dir.join(key.identifier());
        let key_path = validator_config_path.join(DEFAULT_PRIVATE_KEY_FILENAME);

        fs::create_dir_all(&validator_config_path)?;

        let mut key_file = File::create(&key_path)?;

        bincode::serialize_into(&mut key_file, &key)
            .map_err(|e| Error::new(ErrorKind::InvalidData, e))?;
        Ok(key_path)
    }
}
<commit_msg>Fixed formatting with rustfmt.<commit_after>use bincode;
use bls::Keypair;
use clap::ArgMatches;
use slog::{debug, error, info};
use std::fs;
use std::fs::File;
use std::io::{Error, ErrorKind};
use std::path::PathBuf;
use types::ChainSpec;

/// Stores the core configuration for this validator instance.
#[derive(Clone)]
pub struct Config {
    /// The data directory, which stores all validator databases
    pub data_dir: PathBuf,
    /// The server at which the Beacon Node can be contacted
    pub server: String,
    /// The chain specification that we are connecting to
    pub spec: ChainSpec,
}

const DEFAULT_PRIVATE_KEY_FILENAME: &str = "private.key";

impl Default for Config {
    fn default() -> Self {
        let data_dir = {
            let home = dirs::home_dir().expect("Unable to determine home directory.");
            home.join(".lighthouse-validator")
        };
        fs::create_dir_all(&data_dir)
            .unwrap_or_else(|_| panic!("Unable to create {:?}", &data_dir));

        let server = "localhost:50051".to_string();

        let spec = ChainSpec::foundation();

        Self {
            data_dir,
            server,
            spec,
        }
    }
}

impl Config {
    /// Build a new configuration from defaults, which are overrided by arguments provided.
    pub fn parse_args(args: &ArgMatches, log: &slog::Logger) -> Result<Self, Error> {
        let mut config = Config::default();

        // Use the specified datadir, or default in the home directory
        if let Some(datadir) = args.value_of("datadir") {
            config.data_dir = PathBuf::from(datadir);
            fs::create_dir_all(&config.data_dir)
                .unwrap_or_else(|_| panic!("Unable to create {:?}", &config.data_dir));
            info!(log, "Using custom data dir: {:?}", &config.data_dir);
        };

        if let Some(srv) = args.value_of("server") {
            //TODO: I don't think this parses correctly a server & port combo
            config.server = srv.to_string();
            info!(log, "Using custom server: {:?}", &config.server);
        };

        // TODO: Permit loading a custom spec from file.
        if let Some(spec_str) = args.value_of("spec") {
            info!(log, "Using custom spec: {:?}", spec_str);
            config.spec = match spec_str {
                "foundation" => ChainSpec::foundation(),
                "few_validators" => ChainSpec::few_validators(),
                // Should be impossible due to clap's `possible_values(..)` function.
                _ => unreachable!(),
            };
        };

        Ok(config)
    }

    /// Try to load keys from validator_dir, returning None if none are found or an error.
    pub fn fetch_keys(&self, log: &slog::Logger) -> Option<Vec<Keypair>> {
        let key_pairs: Vec<Keypair> = fs::read_dir(&self.data_dir)
            .unwrap()
            .filter_map(|validator_dir| {
                let validator_dir = validator_dir.ok()?;

                if !(validator_dir.file_type().ok()?.is_dir()) {
                    // Skip non-directories (i.e. no files/symlinks)
                    return None;
                }

                let key_filename = validator_dir.path().join(DEFAULT_PRIVATE_KEY_FILENAME);

                if !(key_filename.is_file()) {
                    info!(
                        log,
                        "Private key is not a file: {:?}",
                        key_filename.to_str()
                    );
                    return None;
                }

                debug!(
                    log,
                    "Deserializing private key from file: {:?}",
                    key_filename.to_str()
                );

                let mut key_file = File::open(key_filename.clone()).ok()?;

                let key: Keypair = if let Ok(key_ok) = bincode::deserialize_from(&mut key_file) {
                    key_ok
                } else {
                    error!(
                        log,
                        "Unable to deserialize the private key file: {:?}", key_filename
                    );
                    return None;
                };

                let ki = key.identifier();
                if ki != validator_dir.file_name().into_string().ok()? {
                    error!(
                        log,
                        "The validator key ({:?}) did not match the directory filename {:?}.",
                        ki,
                        &validator_dir.path().to_string_lossy()
                    );
                    return None;
                }
                Some(key)
            })
            .collect();

        // Check if it's an empty vector, and return none.
        if key_pairs.is_empty() {
            None
        } else {
            Some(key_pairs)
        }
    }

    /// Saves a keypair to a file inside the appropriate validator directory. Returns the saved path filename.
    pub fn save_key(&self, key: &Keypair) -> Result<PathBuf, Error> {
        let validator_config_path = self.data_dir.join(key.identifier());
        let key_path = validator_config_path.join(DEFAULT_PRIVATE_KEY_FILENAME);

        fs::create_dir_all(&validator_config_path)?;

        let mut key_file = File::create(&key_path)?;

        bincode::serialize_into(&mut key_file, &key)
            .map_err(|e| Error::new(ErrorKind::InvalidData, e))?;
        Ok(key_path)
    }
}
<|endoftext|>


<commit_before>//! The libcore prelude
//!
//! This module is intended for users of libcore which do not link to libstd as
//! well. This module is imported by default when `#![no_std]` is used in the
//! same manner as the standard library's prelude.

#![stable(feature = "core_prelude", since = "1.4.0")]

pub mod v1;

/// The 2015 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2015", issue = "85684")]
pub mod rust_2015 {
    #[unstable(feature = "prelude_2015", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;
}

/// The 2018 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2018", issue = "85684")]
pub mod rust_2018 {
    #[unstable(feature = "prelude_2018", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;
}

/// The 2021 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2021", issue = "85684")]
pub mod rust_2021 {
    #[unstable(feature = "prelude_2021", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;

    // FIXME: Add more things.
}
<commit_msg>Add new traits to 2021 prelude.<commit_after>//! The libcore prelude
//!
//! This module is intended for users of libcore which do not link to libstd as
//! well. This module is imported by default when `#![no_std]` is used in the
//! same manner as the standard library's prelude.

#![stable(feature = "core_prelude", since = "1.4.0")]

pub mod v1;

/// The 2015 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2015", issue = "85684")]
pub mod rust_2015 {
    #[unstable(feature = "prelude_2015", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;
}

/// The 2018 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2018", issue = "85684")]
pub mod rust_2018 {
    #[unstable(feature = "prelude_2018", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;
}

/// The 2021 version of the core prelude.
///
/// See the [module-level documentation](self) for more.
#[unstable(feature = "prelude_2021", issue = "85684")]
pub mod rust_2021 {
    #[unstable(feature = "prelude_2021", issue = "85684")]
    #[doc(no_inline)]
    pub use super::v1::*;

    #[unstable(feature = "prelude_2021", issue = "85684")]
    #[doc(no_inline)]
    pub use crate::iter::FromIterator;

    #[unstable(feature = "prelude_2021", issue = "85684")]
    #[doc(no_inline)]
    pub use crate::convert::{TryFrom, TryInto};
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests;

use crate::fmt;
use crate::sync::{Condvar, Mutex};

/// A barrier enables multiple threads to synchronize the beginning
/// of some computation.
///
/// # Examples
///
/// ```
/// use std::sync::{Arc, Barrier};
/// use std::thread;
///
/// let mut handles = Vec::with_capacity(10);
/// let barrier = Arc::new(Barrier::new(10));
/// for _ in 0..10 {
///     let c = Arc::clone(&barrier);
///     // The same messages will be printed together.
///     // You will NOT see any interleaving.
///     handles.push(thread::spawn(move|| {
///         println!("before wait");
///         c.wait();
///         println!("after wait");
///     }));
/// }
/// // Wait for other threads to finish.
/// for handle in handles {
///     handle.join().unwrap();
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Barrier {
    lock: Mutex<BarrierState>,
    cvar: Condvar,
    num_threads: usize,
}

// The inner state of a double barrier
struct BarrierState {
    count: usize,
    generation_id: usize,
}

/// A `BarrierWaitResult` is returned by [`Barrier::wait()`] when all threads
/// in the [`Barrier`] have rendezvoused.
///
/// # Examples
///
/// ```
/// use std::sync::Barrier;
///
/// let barrier = Barrier::new(1);
/// let barrier_wait_result = barrier.wait();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BarrierWaitResult(bool);

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Barrier {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Barrier").finish_non_exhaustive()
    }
}

impl Barrier {
    /// Creates a new barrier that can block a given number of threads.
    ///
    /// A barrier will block `n`-1 threads which call [`wait()`] and then wake
    /// up all threads at once when the `n`th thread calls [`wait()`].
    ///
    /// [`wait()`]: Barrier::wait
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Barrier;
    ///
    /// let barrier = Barrier::new(10);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[must_use]
    pub fn new(n: usize) -> Barrier {
        Barrier {
            lock: Mutex::new(BarrierState { count: 0, generation_id: 0 }),
            cvar: Condvar::new(),
            num_threads: n,
        }
    }

    /// Blocks the current thread until all threads have rendezvoused here.
    ///
    /// Barriers are re-usable after all threads have rendezvoused once, and can
    /// be used continuously.
    ///
    /// A single (arbitrary) thread will receive a [`BarrierWaitResult`] that
    /// returns `true` from [`BarrierWaitResult::is_leader()`] when returning
    /// from this function, and all other threads will receive a result that
    /// will return `false` from [`BarrierWaitResult::is_leader()`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::{Arc, Barrier};
    /// use std::thread;
    ///
    /// let mut handles = Vec::with_capacity(10);
    /// let barrier = Arc::new(Barrier::new(10));
    /// for _ in 0..10 {
    ///     let c = Arc::clone(&barrier);
    ///     // The same messages will be printed together.
    ///     // You will NOT see any interleaving.
    ///     handles.push(thread::spawn(move|| {
    ///         println!("before wait");
    ///         c.wait();
    ///         println!("after wait");
    ///     }));
    /// }
    /// // Wait for other threads to finish.
    /// for handle in handles {
    ///     handle.join().unwrap();
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn wait(&self) -> BarrierWaitResult {
        let mut lock = self.lock.lock().unwrap();
        let local_gen = lock.generation_id;
        lock.count += 1;
        if lock.count < self.num_threads {
            // We need a while loop to guard against spurious wakeups.
            // https://en.wikipedia.org/wiki/Spurious_wakeup
            while local_gen == lock.generation_id && lock.count < self.num_threads {
                lock = self.cvar.wait(lock).unwrap();
            }
            BarrierWaitResult(false)
        } else {
            lock.count = 0;
            lock.generation_id = lock.generation_id.wrapping_add(1);
            self.cvar.notify_all();
            BarrierWaitResult(true)
        }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for BarrierWaitResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("BarrierWaitResult").field("is_leader", &self.is_leader()).finish()
    }
}

impl BarrierWaitResult {
    /// Returns `true` if this thread is the "leader thread" for the call to
    /// [`Barrier::wait()`].
    ///
    /// Only one thread will have `true` returned from their result, all other
    /// threads will have `false` returned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Barrier;
    ///
    /// let barrier = Barrier::new(1);
    /// let barrier_wait_result = barrier.wait();
    /// println!("{:?}", barrier_wait_result.is_leader());
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[must_use]
    pub fn is_leader(&self) -> bool {
        self.0
    }
}
<commit_msg>Rollup merge of #87440 - twetzel59:fix-barrier-no-op, r=yaahc<commit_after>#[cfg(test)]
mod tests;

use crate::fmt;
use crate::sync::{Condvar, Mutex};

/// A barrier enables multiple threads to synchronize the beginning
/// of some computation.
///
/// # Examples
///
/// ```
/// use std::sync::{Arc, Barrier};
/// use std::thread;
///
/// let mut handles = Vec::with_capacity(10);
/// let barrier = Arc::new(Barrier::new(10));
/// for _ in 0..10 {
///     let c = Arc::clone(&barrier);
///     // The same messages will be printed together.
///     // You will NOT see any interleaving.
///     handles.push(thread::spawn(move|| {
///         println!("before wait");
///         c.wait();
///         println!("after wait");
///     }));
/// }
/// // Wait for other threads to finish.
/// for handle in handles {
///     handle.join().unwrap();
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Barrier {
    lock: Mutex<BarrierState>,
    cvar: Condvar,
    num_threads: usize,
}

// The inner state of a double barrier
struct BarrierState {
    count: usize,
    generation_id: usize,
}

/// A `BarrierWaitResult` is returned by [`Barrier::wait()`] when all threads
/// in the [`Barrier`] have rendezvoused.
///
/// # Examples
///
/// ```
/// use std::sync::Barrier;
///
/// let barrier = Barrier::new(1);
/// let barrier_wait_result = barrier.wait();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BarrierWaitResult(bool);

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Barrier {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Barrier").finish_non_exhaustive()
    }
}

impl Barrier {
    /// Creates a new barrier that can block a given number of threads.
    ///
    /// A barrier will block `n`-1 threads which call [`wait()`] and then wake
    /// up all threads at once when the `n`th thread calls [`wait()`].
    ///
    /// [`wait()`]: Barrier::wait
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Barrier;
    ///
    /// let barrier = Barrier::new(10);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[must_use]
    pub fn new(n: usize) -> Barrier {
        Barrier {
            lock: Mutex::new(BarrierState { count: 0, generation_id: 0 }),
            cvar: Condvar::new(),
            num_threads: n,
        }
    }

    /// Blocks the current thread until all threads have rendezvoused here.
    ///
    /// Barriers are re-usable after all threads have rendezvoused once, and can
    /// be used continuously.
    ///
    /// A single (arbitrary) thread will receive a [`BarrierWaitResult`] that
    /// returns `true` from [`BarrierWaitResult::is_leader()`] when returning
    /// from this function, and all other threads will receive a result that
    /// will return `false` from [`BarrierWaitResult::is_leader()`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::{Arc, Barrier};
    /// use std::thread;
    ///
    /// let mut handles = Vec::with_capacity(10);
    /// let barrier = Arc::new(Barrier::new(10));
    /// for _ in 0..10 {
    ///     let c = Arc::clone(&barrier);
    ///     // The same messages will be printed together.
    ///     // You will NOT see any interleaving.
    ///     handles.push(thread::spawn(move|| {
    ///         println!("before wait");
    ///         c.wait();
    ///         println!("after wait");
    ///     }));
    /// }
    /// // Wait for other threads to finish.
    /// for handle in handles {
    ///     handle.join().unwrap();
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn wait(&self) -> BarrierWaitResult {
        let mut lock = self.lock.lock().unwrap();
        let local_gen = lock.generation_id;
        lock.count += 1;
        if lock.count < self.num_threads {
            // We need a while loop to guard against spurious wakeups.
            // https://en.wikipedia.org/wiki/Spurious_wakeup
            while local_gen == lock.generation_id {
                lock = self.cvar.wait(lock).unwrap();
            }
            BarrierWaitResult(false)
        } else {
            lock.count = 0;
            lock.generation_id = lock.generation_id.wrapping_add(1);
            self.cvar.notify_all();
            BarrierWaitResult(true)
        }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for BarrierWaitResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("BarrierWaitResult").field("is_leader", &self.is_leader()).finish()
    }
}

impl BarrierWaitResult {
    /// Returns `true` if this thread is the "leader thread" for the call to
    /// [`Barrier::wait()`].
    ///
    /// Only one thread will have `true` returned from their result, all other
    /// threads will have `false` returned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Barrier;
    ///
    /// let barrier = Barrier::new(1);
    /// let barrier_wait_result = barrier.wait();
    /// println!("{:?}", barrier_wait_result.is_leader());
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[must_use]
    pub fn is_leader(&self) -> bool {
        self.0
    }
}
<|endoftext|>


<commit_before>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// after [`IntoIterator` is implemented for arrays][array-into-iter].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is a `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in self.as_slice().iter().zip(&mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<commit_msg>implement TrustedRandomAccess for array::IntoIter<commit_after>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// after [`IntoIterator` is implemented for arrays][array-into-iter].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is a `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }

    #[inline]
    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
    where
        Self: TrustedRandomAccess,
    {
        // SAFETY: Callers are only allowed to pass an index that is in bounds
        // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
        // multiple repeated reads of the same index would be safe and the
        // values aree !Drop, thus won't suffer from double drops.
        unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
// and thus we can't implement drop-handling
unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
where
    T: Copy,
{
    const MAY_HAVE_SIDE_EFFECT: bool = false;
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in self.as_slice().iter().zip(&mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<|endoftext|>


<commit_before><commit_msg>Allow deprecations when compiling code<commit_after><|endoftext|>