<commit_before>use std::fmt;

pub struct Instruction(pub u32);

impl Instruction {
    #[inline(always)]
    pub fn opcode(&self) -> u8 {
        ((self.0  >> 26) & 0b11_1111) as u8
    }

    #[inline(always)]
    pub fn subopcode(&self) -> u16 {
        ((self.0 >> 1) & 0b11_1111_1111) as u16
    }

    #[inline(always)]
    pub fn d(&self) -> usize {
        ((self.0 >> 21) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn a(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn b(&self) -> usize {
        ((self.0 >> 11) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn crfd(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn simm(&self) -> u32 { // FIXME: should probably be signed
        (self.0 & 0b1111_1111_1111_1111) as u32
    }

    #[inline(always)]
    pub fn uimm(&self) -> u32 {
        (self.0 & 0b1111_1111_1111_1111) as u32
    }

    #[inline(always)]
    pub fn li(&self) -> u32 {
        ((self.0 >> 2) & 0b1111_1111_1111_1111_1111_1111)
    }

    #[inline(always)]
    pub fn bo(&self) -> u8 {
        ((self.0 >> 21) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn bi(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn bd(&self) -> u32 {
        ((self.0 >> 2) & 0b1111_1111_1111_11)
    }

    #[inline(always)]
    pub fn aa(&self) -> u8 {
        ((self.0 >> 1) & 0b1) as u8
    }

    #[inline(always)]
    pub fn lk(&self) -> u8 {
        (self.0 & 0b1) as u8
    }

    #[inline(always)]
    pub fn s(&self) -> usize {
        ((self.0 >> 21) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn sr(&self) -> usize {
        ((self.0 >> 16) & 0b1111) as usize
    }

    #[inline(always)]
    pub fn sh(&self) -> u8 {
        ((self.0 >> 11) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn mb(&self) -> u8 {
        ((self.0 >> 6) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn me(&self) -> u8 {
        ((self.0 >> 1) & 0b1_1111) as u8
    }

    #[inline(always)]
    //pub fn spr(&self) -> u32 {
    //    (self.0 >> 11) & 0b11_1111_1111
    //}

    #[inline(always)]
    pub fn spr_upper(&self) -> u32 {
        (self.0 >> 11) & 0b1_1111
    }

    #[inline(always)]
    pub fn spr_lower(&self) -> u32 {
        (self.0 >> 16) & 0b1_1111
    }
}

impl fmt::Debug for Instruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:#b}", self.opcode())
    }
}
<commit_msg>fixed type<commit_after>use std::fmt;

pub struct Instruction(pub u32);

impl Instruction {
    #[inline(always)]
    pub fn opcode(&self) -> u8 {
        ((self.0  >> 26) & 0b11_1111) as u8
    }

    #[inline(always)]
    pub fn subopcode(&self) -> u16 {
        ((self.0 >> 1) & 0b11_1111_1111) as u16
    }

    #[inline(always)]
    pub fn d(&self) -> usize {
        ((self.0 >> 21) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn a(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn b(&self) -> usize {
        ((self.0 >> 11) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn crfd(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn simm(&self) -> u32 { // FIXME: should probably be signed
        (self.0 & 0b1111_1111_1111_1111) as u32
    }

    #[inline(always)]
    pub fn uimm(&self) -> u32 {
        (self.0 & 0b1111_1111_1111_1111) as u32
    }

    #[inline(always)]
    pub fn li(&self) -> u32 {
        ((self.0 >> 2) & 0b1111_1111_1111_1111_1111_1111)
    }

    #[inline(always)]
    pub fn bo(&self) -> u8 {
        ((self.0 >> 21) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn bi(&self) -> usize {
        ((self.0 >> 16) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn bd(&self) -> u16 {
        ((self.0 >> 2) & 0b1111_1111_1111_11) as u16
    }

    #[inline(always)]
    pub fn aa(&self) -> u8 {
        ((self.0 >> 1) & 0b1) as u8
    }

    #[inline(always)]
    pub fn lk(&self) -> u8 {
        (self.0 & 0b1) as u8
    }

    #[inline(always)]
    pub fn s(&self) -> usize {
        ((self.0 >> 21) & 0b1_1111) as usize
    }

    #[inline(always)]
    pub fn sr(&self) -> usize {
        ((self.0 >> 16) & 0b1111) as usize
    }

    #[inline(always)]
    pub fn sh(&self) -> u8 {
        ((self.0 >> 11) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn mb(&self) -> u8 {
        ((self.0 >> 6) & 0b1_1111) as u8
    }

    #[inline(always)]
    pub fn me(&self) -> u8 {
        ((self.0 >> 1) & 0b1_1111) as u8
    }

    #[inline(always)]
    //pub fn spr(&self) -> u32 {
    //    (self.0 >> 11) & 0b11_1111_1111
    //}

    #[inline(always)]
    pub fn spr_upper(&self) -> u32 {
        (self.0 >> 11) & 0b1_1111
    }

    #[inline(always)]
    pub fn spr_lower(&self) -> u32 {
        (self.0 >> 16) & 0b1_1111
    }
}

impl fmt::Debug for Instruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:#b}", self.opcode())
    }
}
<|endoftext|>


<commit_before>use super::command::{Command, Query};
use super::command::Command::Extension;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use request_cancellable::RequestCancellable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ExtensionCommand {
    command: Command,
    arguments: HashMap<String, String>,
}

impl Default for ExtensionCommand {
    fn default() -> ExtensionCommand {
        ExtensionCommand {
            command: Extension("".to_string()),
            arguments: HashMap::new(),
        }
    }
}

impl ExtensionCommand {
    pub fn new(command: String) -> ExtensionCommand {
        let default: ExtensionCommand = Default::default();
        ExtensionCommand {
            command: Extension(command),
            arguments: default.arguments,
        }
    }

    pub fn set_arguments(mut self, arguments: HashMap<String, String>) -> ExtensionCommand {
        self.arguments = arguments;
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![];
        for (key, value) in &self.arguments {
            query.push((key.to_owned(), value.to_owned()));
        }
        (self.command, query)
    }
}

impl Queryable for ExtensionCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for ExtensionCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

request_cancellable!(ExtensionCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Extension;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;

    #[test]
    fn test_new() {
        let vanilla_extension = ExtensionCommand::new("Added".to_string());
        let expected = ExtensionCommand {
            command: Extension("Added".to_string()),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, vanilla_extension);
    }

    #[test]
    fn test_set_arguments() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("Added".to_string()).set_arguments(arg.to_owned());
        let expected = ExtensionCommand {
            command: Extension("Added".to_string()),
            arguments: arg,
        };
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_build() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("Added".to_string())
            .set_arguments(arg.to_owned())
            .build();
        let expected_query: Query = vec![("test".to_string(), "element".to_string())];
        let expected = (Extension("Added".to_string()), expected_query);
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_queryable() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("added".to_string())
            .set_arguments(arg.to_owned())
            .to_query();
        let expected = "/d/added?test=element";
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_commandable() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("added".to_string())
            .set_arguments(arg.to_owned())
            .to_command();
        let expected = "added --test element";
        assert_eq!(expected, extension);
    }
}
<commit_msg>extension: use request_timeoutable macro<commit_after>use super::command::{Command, Query};
use super::command::Command::Extension;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use request_cancellable::RequestCancellable;
use request_timeoutable::RequestTimeoutable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ExtensionCommand {
    command: Command,
    arguments: HashMap<String, String>,
}

impl Default for ExtensionCommand {
    fn default() -> ExtensionCommand {
        ExtensionCommand {
            command: Extension("".to_string()),
            arguments: HashMap::new(),
        }
    }
}

impl ExtensionCommand {
    pub fn new(command: String) -> ExtensionCommand {
        let default: ExtensionCommand = Default::default();
        ExtensionCommand {
            command: Extension(command),
            arguments: default.arguments,
        }
    }

    pub fn set_arguments(mut self, arguments: HashMap<String, String>) -> ExtensionCommand {
        self.arguments = arguments;
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![];
        for (key, value) in &self.arguments {
            query.push((key.to_owned(), value.to_owned()));
        }
        (self.command, query)
    }
}

impl Queryable for ExtensionCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for ExtensionCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

request_cancellable!(ExtensionCommand);
request_timeoutable!(ExtensionCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Extension;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;

    #[test]
    fn test_new() {
        let vanilla_extension = ExtensionCommand::new("Added".to_string());
        let expected = ExtensionCommand {
            command: Extension("Added".to_string()),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, vanilla_extension);
    }

    #[test]
    fn test_set_arguments() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("Added".to_string()).set_arguments(arg.to_owned());
        let expected = ExtensionCommand {
            command: Extension("Added".to_string()),
            arguments: arg,
        };
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_build() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("Added".to_string())
            .set_arguments(arg.to_owned())
            .build();
        let expected_query: Query = vec![("test".to_string(), "element".to_string())];
        let expected = (Extension("Added".to_string()), expected_query);
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_queryable() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("added".to_string())
            .set_arguments(arg.to_owned())
            .to_query();
        let expected = "/d/added?test=element";
        assert_eq!(expected, extension);
    }

    #[test]
    fn test_commandable() {
        let mut arg = HashMap::new();
        arg.insert("test".to_string(), "element".to_string());
        let extension = ExtensionCommand::new("added".to_string())
            .set_arguments(arg.to_owned())
            .to_command();
        let expected = "added --test element";
        assert_eq!(expected, extension);
    }
}
<|endoftext|>


<commit_before>//! Asynchronous streams.

use crate::task::{LocalWaker, Poll};
use core::marker::Unpin;
use core::ops;
use core::pin::Pin;

#[cfg(feature = "either")]
use either::Either;

mod stream_obj;
pub use self::stream_obj::{StreamObj,LocalStreamObj,UnsafeStreamObj};

/// A stream of values produced asynchronously.
///
/// If `Future<Output = T>` is an asynchronous version of `T`, then `Stream<Item
/// = T>` is an asynchronous version of `Iterator<Item = T>`. A stream
/// represents a sequence of value-producing events that occur asynchronously to
/// the caller.
///
/// The trait is modeled after `Future`, but allows `poll_next` to be called
/// even after a value has been produced, yielding `None` once the stream has
/// been fully exhausted.
pub trait Stream {
    /// Values yielded by the stream.
    type Item;

    /// Attempt to pull out the next value of this stream, registering the
    /// current task for wakeup if the value is not yet available, and returning
    /// `None` if the stream is exhausted.
    ///
    /// # Return value
    ///
    /// There are several possible return values, each indicating a distinct
    /// stream state:
    ///
    /// - `Poll::Pending` means that this stream's next value is not ready
    /// yet. Implementations will ensure that the current task will be notified
    /// when the next value may be ready.
    ///
    /// - `Poll::Ready(Some(val))` means that the stream has successfully
    /// produced a value, `val`, and may produce further values on subsequent
    /// `poll_next` calls.
    ///
    /// - `Poll::Ready(None)` means that the stream has terminated, and
    /// `poll_next` should not be invoked again.
    ///
    /// # Panics
    ///
    /// Once a stream is finished, i.e. `Ready(None)` has been returned, further
    /// calls to `poll_next` may result in a panic or other "bad behavior".  If
    /// this is difficult to guard against then the `fuse` adapter can be used
    /// to ensure that `poll_next` always returns `Ready(None)` in subsequent
    /// calls.
    fn poll_next(
        self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>>;
}

impl<'a, S: ?Sized + Stream + Unpin> Stream for &'a mut S {
    type Item = S::Item;

    fn poll_next(
        mut self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>> {
        S::poll_next(Pin::new(&mut **self), lw)
    }
}

impl
 Stream for Pin

where
    P: ops::DerefMut,
    P::Target: Stream,
{
    type Item =
::Item;

    fn poll_next(
        self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>> {
        Pin::get_mut(self).as_mut().poll_next(lw)
    }
}

#[cfg(feature = "either")]
impl Stream for Either
    where A: Stream,
          B: Stream<Item = A::Item>
{
    type Item = A::Item;

    fn poll_next(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Option> {
        unsafe {
            match Pin::get_unchecked_mut(self) {
                Either::Left(a) => Pin::new_unchecked(a).poll_next(lw),
                Either::Right(b) => Pin::new_unchecked(b).poll_next(lw),
            }
        }
    }
}

/// A `Stream` or `TryStream` which tracks whether or not the underlying stream
/// should no longer be polled.
///
/// `is_terminated` will return `true` if a future should no longer be polled.
/// Usually, this state occurs after `poll_next` (or `try_poll_next`) returned
/// `Poll::Ready(None)`. However, `is_terminated` may also return `true` if a
/// stream has become inactive and can no longer make progress and should be
/// ignored or dropped rather than being polled again.
pub trait FusedStream {
    /// Returns `true` if the stream should no longer be polled.
    fn is_terminated(&self) -> bool;
}

/// A convenience for streams that return `Result` values that includes
/// a variety of adapters tailored to such futures.
pub trait TryStream {
    /// The type of successful values yielded by this future
    type Ok;

    /// The type of failures yielded by this future
    type Error;

    /// Poll this `TryStream` as if it were a `Stream`.
    ///
    /// This method is a stopgap for a compiler limitation that prevents us from
    /// directly inheriting from the `Stream` trait; in the future it won't be
    /// needed.
    fn try_poll_next(self: Pin<&mut Self>, lw: &LocalWaker)
        -> Poll<Option<Result<Self::Ok, Self::Error>>>;
}

impl<S, T, E> TryStream for S
    where S: Stream<Item = Result<T, E>>
{
    type Ok = T;
    type Error = E;

    fn try_poll_next(self: Pin<&mut Self>, lw: &LocalWaker)
        -> Poll<Option<Result<Self::Ok, Self::Error>>>
    {
        self.poll_next(lw)
    }
}

#[cfg(feature = "std")]
mod if_std {
    use std::boxed::Box;
    use super::*;

    impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
        type Item = S::Item;

        fn poll_next(
            mut self: Pin<&mut Self>,
            lw: &LocalWaker,
        ) -> Poll<Option<Self::Item>> {
            Pin::new(&mut **self).poll_next(lw)
        }
    }

    impl<S: Stream> Stream for ::std::panic::AssertUnwindSafe<S> {
        type Item = S::Item;

        fn poll_next(
            self: Pin<&mut Self>,
            lw: &LocalWaker,
        ) -> Poll<Option<S::Item>> {
            unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) }.poll_next(lw)
        }
    }

    impl<T: Unpin> Stream for ::std::collections::VecDeque<T> {
        type Item = T;

        fn poll_next(
            mut self: Pin<&mut Self>,
            _lw: &LocalWaker,
        ) -> Poll<Option<Self::Item>> {
            Poll::Ready(self.pop_front())
        }
    }
}
<commit_msg>Add Unpin bound<commit_after>//! Asynchronous streams.

use crate::task::{LocalWaker, Poll};
use core::marker::Unpin;
use core::ops;
use core::pin::Pin;

#[cfg(feature = "either")]
use either::Either;

mod stream_obj;
pub use self::stream_obj::{StreamObj,LocalStreamObj,UnsafeStreamObj};

/// A stream of values produced asynchronously.
///
/// If `Future<Output = T>` is an asynchronous version of `T`, then `Stream<Item
/// = T>` is an asynchronous version of `Iterator<Item = T>`. A stream
/// represents a sequence of value-producing events that occur asynchronously to
/// the caller.
///
/// The trait is modeled after `Future`, but allows `poll_next` to be called
/// even after a value has been produced, yielding `None` once the stream has
/// been fully exhausted.
pub trait Stream {
    /// Values yielded by the stream.
    type Item;

    /// Attempt to pull out the next value of this stream, registering the
    /// current task for wakeup if the value is not yet available, and returning
    /// `None` if the stream is exhausted.
    ///
    /// # Return value
    ///
    /// There are several possible return values, each indicating a distinct
    /// stream state:
    ///
    /// - `Poll::Pending` means that this stream's next value is not ready
    /// yet. Implementations will ensure that the current task will be notified
    /// when the next value may be ready.
    ///
    /// - `Poll::Ready(Some(val))` means that the stream has successfully
    /// produced a value, `val`, and may produce further values on subsequent
    /// `poll_next` calls.
    ///
    /// - `Poll::Ready(None)` means that the stream has terminated, and
    /// `poll_next` should not be invoked again.
    ///
    /// # Panics
    ///
    /// Once a stream is finished, i.e. `Ready(None)` has been returned, further
    /// calls to `poll_next` may result in a panic or other "bad behavior".  If
    /// this is difficult to guard against then the `fuse` adapter can be used
    /// to ensure that `poll_next` always returns `Ready(None)` in subsequent
    /// calls.
    fn poll_next(
        self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>>;
}

impl<'a, S: ?Sized + Stream + Unpin> Stream for &'a mut S {
    type Item = S::Item;

    fn poll_next(
        mut self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>> {
        S::poll_next(Pin::new(&mut **self), lw)
    }
}

impl
 Stream for Pin

where
    P: ops::DerefMut + Unpin,
    P::Target: Stream,
{
    type Item =
::Item;

    fn poll_next(
        self: Pin<&mut Self>,
        lw: &LocalWaker,
    ) -> Poll<Option<Self::Item>> {
        Pin::get_mut(self).as_mut().poll_next(lw)
    }
}

#[cfg(feature = "either")]
impl Stream for Either
    where A: Stream,
          B: Stream<Item = A::Item>
{
    type Item = A::Item;

    fn poll_next(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Option> {
        unsafe {
            match Pin::get_unchecked_mut(self) {
                Either::Left(a) => Pin::new_unchecked(a).poll_next(lw),
                Either::Right(b) => Pin::new_unchecked(b).poll_next(lw),
            }
        }
    }
}

/// A `Stream` or `TryStream` which tracks whether or not the underlying stream
/// should no longer be polled.
///
/// `is_terminated` will return `true` if a future should no longer be polled.
/// Usually, this state occurs after `poll_next` (or `try_poll_next`) returned
/// `Poll::Ready(None)`. However, `is_terminated` may also return `true` if a
/// stream has become inactive and can no longer make progress and should be
/// ignored or dropped rather than being polled again.
pub trait FusedStream {
    /// Returns `true` if the stream should no longer be polled.
    fn is_terminated(&self) -> bool;
}

/// A convenience for streams that return `Result` values that includes
/// a variety of adapters tailored to such futures.
pub trait TryStream {
    /// The type of successful values yielded by this future
    type Ok;

    /// The type of failures yielded by this future
    type Error;

    /// Poll this `TryStream` as if it were a `Stream`.
    ///
    /// This method is a stopgap for a compiler limitation that prevents us from
    /// directly inheriting from the `Stream` trait; in the future it won't be
    /// needed.
    fn try_poll_next(self: Pin<&mut Self>, lw: &LocalWaker)
        -> Poll<Option<Result<Self::Ok, Self::Error>>>;
}

impl<S, T, E> TryStream for S
    where S: Stream<Item = Result<T, E>>
{
    type Ok = T;
    type Error = E;

    fn try_poll_next(self: Pin<&mut Self>, lw: &LocalWaker)
        -> Poll<Option<Result<Self::Ok, Self::Error>>>
    {
        self.poll_next(lw)
    }
}

#[cfg(feature = "std")]
mod if_std {
    use std::boxed::Box;
    use super::*;

    impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
        type Item = S::Item;

        fn poll_next(
            mut self: Pin<&mut Self>,
            lw: &LocalWaker,
        ) -> Poll<Option<Self::Item>> {
            Pin::new(&mut **self).poll_next(lw)
        }
    }

    impl<S: Stream> Stream for ::std::panic::AssertUnwindSafe<S> {
        type Item = S::Item;

        fn poll_next(
            self: Pin<&mut Self>,
            lw: &LocalWaker,
        ) -> Poll<Option<S::Item>> {
            unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) }.poll_next(lw)
        }
    }

    impl<T: Unpin> Stream for ::std::collections::VecDeque<T> {
        type Item = T;

        fn poll_next(
            mut self: Pin<&mut Self>,
            _lw: &LocalWaker,
        ) -> Poll<Option<Self::Item>> {
            Poll::Ready(self.pop_front())
        }
    }
}
<|endoftext|>


<commit_before>#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

struct A<const N: &u8>;
//~^ ERROR `&` without an explicit lifetime name cannot be used here
trait B {}

impl<const N: &u8> A<N> { //~ ERROR `&` without an explicit lifetime name cannot be used here
    fn foo<const M: &u8>(&self) {}
    //~^ ERROR `&` without an explicit lifetime name cannot be used here
}

impl<const N: &u8> B for A<N> {}
//~^ ERROR `&` without an explicit lifetime name cannot be used here

fn bar<const N: &u8>() {}
//~^ ERROR `&` without an explicit lifetime name cannot be used here

fn main() {}
<commit_msg>Added comment about behaviour.<commit_after>// Elided lifetimes within the type of a const generic parameters is disallowed. This matches the
// behaviour of trait bounds where `fn foo<T: Ord<&u8>>() {}` is illegal. Though we could change
// elided lifetimes within the type of a const generic parameters to be 'static, like elided
// lifetimes within const/static items.

#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

struct A<const N: &u8>;
//~^ ERROR `&` without an explicit lifetime name cannot be used here
trait B {}

impl<const N: &u8> A<N> { //~ ERROR `&` without an explicit lifetime name cannot be used here
    fn foo<const M: &u8>(&self) {}
    //~^ ERROR `&` without an explicit lifetime name cannot be used here
}

impl<const N: &u8> B for A<N> {}
//~^ ERROR `&` without an explicit lifetime name cannot be used here

fn bar<const N: &u8>() {}
//~^ ERROR `&` without an explicit lifetime name cannot be used here

fn main() {}
<|endoftext|>


<commit_before>// (c) 2016 Productize SPRL <joost@productize.be>

use std::io;

use Sexp;
use symbolic_expressions::Result;
use symbolic_expressions::Formatter;

// custom symbolic_expressions formatter that aims to be
// kicad compatible

struct Indent {
    newline_before:i64,
    closing_on_new_line:bool,
    newline_after:i64,
}

impl Default for Indent {
    fn default() -> Indent {
        Indent {
            newline_before:0,
            closing_on_new_line:false,
            newline_after:0,
        }
    }
}

impl Indent {

    fn before(&mut self) {
        self.newline_before = 1;
    }

    fn close_on_new_line(&mut self) {
        self.closing_on_new_line = true;
    }

    fn before_double(&mut self) {
        self.newline_before = 2;
    }

    fn newline_after_closing(&mut self) {
        self.newline_after = 1;
    }
}

pub struct KicadFormatter {
    indent:i64,
    stack:Vec<Option<(String,Option<Indent>)>>,
    ind:Vec<u8>,
    pts_xy_count:i64,
}

impl KicadFormatter {

    pub fn new(initial_indent_level:i64) -> KicadFormatter {
        KicadFormatter {
            indent:initial_indent_level,
            stack:vec![],
            ind:vec![b' ',b' '], // two spaces
            pts_xy_count:0,
        }
    }

    fn is(&self, what:&'static str) -> bool {
        for x in &self.stack {
            if let Some((ref name,_)) = *x {
                if name == what {
                    return true
                }
            }
        }
        false
    }

    fn parent_is(&self, what:&'static str) -> bool {
        if let Some(s) = self.stack.last() {
            if let Some((ref t,_)) = *s {
                return t == what
            }
        }
        false
    }

    fn indent<W:io::Write>(&self, writer:&mut W, nls:i64) -> Result<()> {
        for _ in 0..nls {
            try!(writer.write_all(b"\n"));
        }
        for _ in 0..self.indent {
            try!(writer.write_all(&self.ind));
        }
        Ok(())
    }

    fn indent_plus<W:io::Write>(&mut self, writer:&mut W, nls:i64) -> Result<()> {
        self.indent+=1;
        let res = self.indent(writer, nls);
        self.indent-=1;
        res
    }

    fn want_indent_module(&self, ele:&str) -> Option<Indent> {
        //if !self.is("module") {
        //    return None
        //}
        let mut indent = Indent::default();
        indent.before();
        if self.parent_is("module") {
            match ele {
                "at" | "descr" | "fp_line" | "fp_poly" |
                "pad" | "path" | "fp_circle"
                    => return Some(indent),
                "model" | "fp_text" => {
                    indent.close_on_new_line();
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("fp_text") | self.parent_is("gr_text") {
            if let "effects" = ele {
                return Some(indent)
            }
        }
        if self.parent_is("pts") {
            if let "xy" = ele {
                if self.pts_xy_count > 0 && self.pts_xy_count % 4 == 0 {
                    return Some(indent)
                } else if self.pts_xy_count == 0 && (self.is("polygon") || self.is("filled_polygon") ) {
                    return Some(indent)
                }
            }
        }
        if self.parent_is("model") {
            match ele {
                "at" | "scale" | "rotate" => {
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("pad") {
            if let "net" = ele {
                return Some(indent)
            }
        }
        None
    }

    fn want_indent_layout(&self, ele:&str) -> Option<Indent> {
        if !self.is("kicad_pcb") {
            return None
        }
        let mut indent = Indent::default();
        indent.before();
        if self.parent_is("kicad_pcb") {
            match ele {
                "page" | "gr_circle"
                    => {
                        indent.before_double();
                        return Some(indent)
                    },
                "module"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                "net" | "gr_line" | "gr_arc" | "segment" | "via"
                    => return Some(indent),
                "layers" | "gr_text" | "dimension"
                    => {
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                "setup"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        indent.newline_after_closing();
                        return Some(indent)
                    },
                "general" | "net_class" | "zone"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                _ => (),
            }
        }
        if self.parent_is("general") {
            return Some(indent)
        }
        if self.parent_is("layers") {
            return Some(indent)
        }
        if self.parent_is("setup") {
            return Some(indent)
        }
        if self.parent_is("pcbplotparams") {
            return Some(indent)
        }
        if self.parent_is("net_class") {
            return Some(indent)
        }
        if self.parent_is("dimension") {
            match ele {
                "gr_text" | "feature1" |
                "feature2" | "crossbar" |
                "arrow1a" | "arrow1b" |
                "arrow2a" | "arrow2b" => {
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("zone") {
            match ele {
                "connect_pads" | "min_thickness" | "fill"
                    => return Some(indent),
                "polygon" | "filled_polygon"
                    => {
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                _ => (),
            }
        }
        if self.parent_is("polygon") | self.parent_is("filled_polygon") {
            return Some(indent)
        }
        None
    }

    fn want_indent(&self, value:&Sexp) -> Option<Indent> {
        let first = match *value {
            Sexp::List(ref l) => {
                if l.is_empty() {
                    return None
                }
                (&l[0]).clone()
            },
            Sexp::Empty => return None,
            Sexp::String(ref l) => Sexp::String(l.clone()),
        };
        if let Sexp::String(ref ele) = first {
            let i = self.want_indent_module(ele);
            if i.is_some() {
                return i
            }
            let i = self.want_indent_layout(ele);
            if i.is_some() {
                return i
            }
        }
        None
    }
}

impl Formatter for KicadFormatter {

    fn open<W>(&mut self, writer: &mut W, value:Option<&Sexp>) -> Result<()>
        where W: io::Write
    {
        let mut ele = String::new();
        // if first element is string
        if let Some(ref sexp) = value {
            if let Sexp::String(ref s) = **sexp {
                ele.push_str(s);
            }
        }
        let exp = Sexp::String(ele.clone());
        let want_indent = self.want_indent(&exp);
        if let Some(ref want_indent) = want_indent {
            self.indent += 1;
            if want_indent.newline_before > 0 {
                try!(self.indent(writer, want_indent.newline_before));
            }
        }

        // special handling for breaking after 4 elements of xy
        if let "pts" = &ele[..] {
            self.pts_xy_count = 0;
        }
        if self.parent_is("pts") {
            if let "xy" = &ele[..] {
                self.pts_xy_count += 1;
                if self.pts_xy_count == 5 {
                    self.pts_xy_count = 1;
                }
            }
        }

        if !ele.is_empty() {
            self.stack.push(Some((ele, want_indent)))
        } else {
            self.stack.push(None)
        }
        writer.write_all(b"(").map_err(From::from)
    }

    fn element<W>(&mut self, writer: &mut W, value:&Sexp) -> Result<()>
        where W: io::Write
    {
        // get rid of the space if we will be putting a newline next
        if self.want_indent(value).is_none() {
            try!(writer.write_all(b" "));
        } else if let Sexp::String(_) = *value {
            try!(writer.write_all(b" "));
        }
        Ok(())

    }

    fn close<W>(&mut self, writer: &mut W) -> Result<()>
        where W: io::Write
    {
        if let Some(Some((s, want_indent))) = self.stack.pop() {
            if let Some(indent) = want_indent {
                self.indent -= 1;
                if indent.closing_on_new_line {
                    try!(self.indent_plus(writer, 1));
                }
                // special handling of toplevel module...
                // which doesn't work, because it is not indented
                if &s == "module" && self.stack.is_empty() {
                    try!(writer.write_all(b"\n"));
                }
                try!(writer.write_all(b")"));
                for _ in 0..indent.newline_after {
                    try!(writer.write_all(b"\n"));
                }
                return Ok(())
            } else {
                if self.stack.is_empty() && (&s == "module" || &s == "kicad_pcb") {
                    try!(writer.write_all(b"\n"));
                }
            }
        }
        try!(writer.write_all(b")"));
        Ok(())
    }
}

<commit_msg>formatting output fixes<commit_after>// (c) 2016 Productize SPRL <joost@productize.be>

use std::io;

use Sexp;
use symbolic_expressions::Result;
use symbolic_expressions::Formatter;

// custom symbolic_expressions formatter that aims to be
// kicad compatible

struct Indent {
    newline_before:i64,
    closing_on_new_line:bool,
    newline_after:i64,
}

impl Default for Indent {
    fn default() -> Indent {
        Indent {
            newline_before:0,
            closing_on_new_line:false,
            newline_after:0,
        }
    }
}

impl Indent {

    fn before(&mut self) {
        self.newline_before = 1;
    }

    fn close_on_new_line(&mut self) {
        self.closing_on_new_line = true;
    }

    fn before_double(&mut self) {
        self.newline_before = 2;
    }

    fn newline_after_closing(&mut self) {
        self.newline_after = 1;
    }
}

pub struct KicadFormatter {
    indent:i64,
    stack:Vec<Option<(String,Option<Indent>)>>,
    ind:Vec<u8>,
    pts_xy_count:i64,
}

impl KicadFormatter {

    pub fn new(initial_indent_level:i64) -> KicadFormatter {
        KicadFormatter {
            indent:initial_indent_level,
            stack:vec![],
            ind:vec![b' ',b' '], // two spaces
            pts_xy_count:0,
        }
    }

    fn is(&self, what:&'static str) -> bool {
        for x in &self.stack {
            if let Some((ref name,_)) = *x {
                if name == what {
                    return true
                }
            }
        }
        false
    }

    fn parent_is(&self, what:&'static str) -> bool {
        if let Some(s) = self.stack.last() {
            if let Some((ref t,_)) = *s {
                return t == what
            }
        }
        false
    }

    fn indent<W:io::Write>(&self, writer:&mut W, nls:i64) -> Result<()> {
        for _ in 0..nls {
            try!(writer.write_all(b"\n"));
        }
        for _ in 0..self.indent {
            try!(writer.write_all(&self.ind));
        }
        Ok(())
    }

    fn indent_plus<W:io::Write>(&mut self, writer:&mut W, nls:i64) -> Result<()> {
        self.indent+=1;
        let res = self.indent(writer, nls);
        self.indent-=1;
        res
    }

    fn want_indent_module(&self, ele:&str) -> Option<Indent> {
        //if !self.is("module") {
        //    return None
        //}
        let mut indent = Indent::default();
        indent.before();
        if self.parent_is("module") {
            match ele {
                "at" | "descr" | "fp_line" | "fp_poly" |
                "pad" | "path" | "fp_circle" | "attr"
                    => return Some(indent),
                "model" | "fp_text" => {
                    indent.close_on_new_line();
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("fp_text") | self.parent_is("gr_text") {
            if let "effects" = ele {
                return Some(indent)
            }
        }
        if self.parent_is("pts") {
            if let "xy" = ele {
                if self.pts_xy_count > 0 && self.pts_xy_count % 4 == 0 {
                    return Some(indent)
                } else if self.pts_xy_count == 0 && (self.is("polygon") || self.is("filled_polygon") ) {
                    return Some(indent)
                }
            }
        }
        if self.parent_is("model") {
            match ele {
                "at" | "scale" | "rotate" => {
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("pad") {
            if let "net" = ele {
                return Some(indent)
            }
        }
        None
    }

    fn want_indent_layout(&self, ele:&str) -> Option<Indent> {
        if !self.is("kicad_pcb") {
            return None
        }
        let mut indent = Indent::default();
        indent.before();
        if self.parent_is("kicad_pcb") {
            match ele {
                "page" | "gr_circle"
                    => {
                        indent.before_double();
                        return Some(indent)
                    },
                "module"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                "net" | "gr_line" | "gr_arc" | "segment" | "via"
                    => return Some(indent),
                "layers" | "gr_text" | "dimension"
                    => {
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                "setup"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        indent.newline_after_closing();
                        return Some(indent)
                    },
                "general" | "net_class" | "zone"
                    => {
                        indent.before_double();
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                _ => (),
            }
        }
        if self.parent_is("general") {
            return Some(indent)
        }
        if self.parent_is("layers") {
            return Some(indent)
        }
        if self.parent_is("setup") {
            return Some(indent)
        }
        if self.parent_is("pcbplotparams") {
            return Some(indent)
        }
        if self.parent_is("net_class") {
            return Some(indent)
        }
        if self.parent_is("dimension") {
            match ele {
                "gr_text" | "feature1" |
                "feature2" | "crossbar" |
                "arrow1a" | "arrow1b" |
                "arrow2a" | "arrow2b" => {
                    return Some(indent)
                },
                _ => (),
            }
        }
        if self.parent_is("zone") {
            match ele {
                "connect_pads" | "min_thickness" | "fill"
                    | "keepout" | "priority"
                    => return Some(indent),
                "polygon" | "filled_polygon"
                    => {
                        indent.close_on_new_line();
                        return Some(indent)
                    },
                _ => (),
            }
        }
        if self.parent_is("polygon") | self.parent_is("filled_polygon") {
            return Some(indent)
        }
        None
    }

    fn want_indent(&self, value:&Sexp) -> Option<Indent> {
        let first = match *value {
            Sexp::List(ref l) => {
                if l.is_empty() {
                    return None
                }
                (&l[0]).clone()
            },
            Sexp::Empty => return None,
            Sexp::String(ref l) => Sexp::String(l.clone()),
        };
        if let Sexp::String(ref ele) = first {
            let i = self.want_indent_module(ele);
            if i.is_some() {
                return i
            }
            let i = self.want_indent_layout(ele);
            if i.is_some() {
                return i
            }
        }
        None
    }
}

impl Formatter for KicadFormatter {

    fn open<W>(&mut self, writer: &mut W, value:Option<&Sexp>) -> Result<()>
        where W: io::Write
    {
        let mut ele = String::new();
        // if first element is string
        if let Some(ref sexp) = value {
            if let Sexp::String(ref s) = **sexp {
                ele.push_str(s);
            }
        }
        let exp = Sexp::String(ele.clone());
        let want_indent = self.want_indent(&exp);
        if let Some(ref want_indent) = want_indent {
            self.indent += 1;
            if want_indent.newline_before > 0 {
                try!(self.indent(writer, want_indent.newline_before));
            }
        }

        // special handling for breaking after 4 elements of xy
        if let "pts" = &ele[..] {
            self.pts_xy_count = 0;
        }
        if self.parent_is("pts") {
            if let "xy" = &ele[..] {
                self.pts_xy_count += 1;
                if self.pts_xy_count == 5 {
                    self.pts_xy_count = 1;
                }
            }
        }

        if !ele.is_empty() {
            self.stack.push(Some((ele, want_indent)))
        } else {
            self.stack.push(None)
        }
        writer.write_all(b"(").map_err(From::from)
    }

    fn element<W>(&mut self, writer: &mut W, value:&Sexp) -> Result<()>
        where W: io::Write
    {
        // get rid of the space if we will be putting a newline next
        if self.want_indent(value).is_none() {
            try!(writer.write_all(b" "));
        } else if let Sexp::String(_) = *value {
            try!(writer.write_all(b" "));
        }
        Ok(())

    }

    fn close<W>(&mut self, writer: &mut W) -> Result<()>
        where W: io::Write
    {
        if let Some(Some((s, want_indent))) = self.stack.pop() {
            if let Some(indent) = want_indent {
                self.indent -= 1;
                if indent.closing_on_new_line {
                    try!(self.indent_plus(writer, 1));
                }
                // special handling of toplevel module...
                // which doesn't work, because it is not indented
                if &s == "module" && self.stack.is_empty() {
                    try!(writer.write_all(b"\n"));
                }
                try!(writer.write_all(b")"));
                for _ in 0..indent.newline_after {
                    try!(writer.write_all(b"\n"));
                }
                return Ok(())
            } else {
                if self.stack.is_empty() && (&s == "module" || &s == "kicad_pcb") {
                    try!(writer.write_all(b"\n"));
                }
            }
        }
        try!(writer.write_all(b")"));
        Ok(())
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2018-2020, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use num_derive::FromPrimitive;

use crate::api::Opaque;
use crate::context::SB_SIZE;
use crate::mc::SUBPEL_FILTER_SIZE;
use crate::util::*;

use crate::tiling::*;

mod plane;
pub use plane::*;

const FRAME_MARGIN: usize = 16 + SUBPEL_FILTER_SIZE;
const LUMA_PADDING: usize = SB_SIZE + FRAME_MARGIN;

/// Override the frame type decision
///
/// Only certain frame types can be selected.
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive)]
#[repr(C)]
pub enum FrameTypeOverride {
  /// Do not force any decision.
  No,
  /// Force the frame to be a Keyframe.
  Key,
}

/// Optional per-frame encoder parameters
#[derive(Debug)]
pub struct FrameParameters {
  /// Force emitted frame to be of the type selected
  pub frame_type_override: FrameTypeOverride,
  /// Output the provided data in the matching encoded Packet
  pub opaque: Option<Opaque>,
}

pub use v_frame::frame::Frame;

/// Public Trait Interface for Frame Allocation
pub(crate) trait FrameAlloc {
  /// Initialise new frame default type
  fn new(width: usize, height: usize, chroma_sampling: ChromaSampling)
    -> Self;
}

impl<T: Pixel> FrameAlloc for Frame<T> {
  /// Creates a new frame with the given parameters.
  /// new function calls new_with_padding function which takes luma_padding
  /// as parameter
  fn new(
    width: usize, height: usize, chroma_sampling: ChromaSampling,
  ) -> Self {
    v_frame::frame::Frame::new_with_padding(
      width,
      height,
      chroma_sampling,
      LUMA_PADDING,
    )
  }
}

/// Public Trait for calulating Padding
pub(crate) trait FramePad {
  fn pad(&mut self, w: usize, h: usize, planes: usize);
}

impl<T: Pixel> FramePad for Frame<T> {
  fn pad(&mut self, w: usize, h: usize, planes: usize) {
    for pli in 0..planes {
      self.planes[pli].pad(w, h);
    }
  }
}

/// Public Trait for new Tile of a frame
pub(crate) trait AsTile<T: Pixel> {
  fn as_tile(&self) -> Tile<'_, T>;
  fn as_tile_mut(&mut self) -> TileMut<'_, T>;
}

impl<T: Pixel> AsTile<T> for Frame<T> {
  #[inline(always)]
  fn as_tile(&self) -> Tile<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    Tile::new(self, TileRect { x: 0, y: 0, width, height })
  }
  #[inline(always)]
  fn as_tile_mut(&mut self) -> TileMut<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    TileMut::new(self, TileRect { x: 0, y: 0, width, height })
  }
}
<commit_msg>frame: mod: fix typo<commit_after>// Copyright (c) 2018-2020, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use num_derive::FromPrimitive;

use crate::api::Opaque;
use crate::context::SB_SIZE;
use crate::mc::SUBPEL_FILTER_SIZE;
use crate::util::*;

use crate::tiling::*;

mod plane;
pub use plane::*;

const FRAME_MARGIN: usize = 16 + SUBPEL_FILTER_SIZE;
const LUMA_PADDING: usize = SB_SIZE + FRAME_MARGIN;

/// Override the frame type decision
///
/// Only certain frame types can be selected.
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive)]
#[repr(C)]
pub enum FrameTypeOverride {
  /// Do not force any decision.
  No,
  /// Force the frame to be a Keyframe.
  Key,
}

/// Optional per-frame encoder parameters
#[derive(Debug)]
pub struct FrameParameters {
  /// Force emitted frame to be of the type selected
  pub frame_type_override: FrameTypeOverride,
  /// Output the provided data in the matching encoded Packet
  pub opaque: Option<Opaque>,
}

pub use v_frame::frame::Frame;

/// Public Trait Interface for Frame Allocation
pub(crate) trait FrameAlloc {
  /// Initialise new frame default type
  fn new(width: usize, height: usize, chroma_sampling: ChromaSampling)
    -> Self;
}

impl<T: Pixel> FrameAlloc for Frame<T> {
  /// Creates a new frame with the given parameters.
  /// new function calls new_with_padding function which takes luma_padding
  /// as parameter
  fn new(
    width: usize, height: usize, chroma_sampling: ChromaSampling,
  ) -> Self {
    v_frame::frame::Frame::new_with_padding(
      width,
      height,
      chroma_sampling,
      LUMA_PADDING,
    )
  }
}

/// Public Trait for calculating Padding
pub(crate) trait FramePad {
  fn pad(&mut self, w: usize, h: usize, planes: usize);
}

impl<T: Pixel> FramePad for Frame<T> {
  fn pad(&mut self, w: usize, h: usize, planes: usize) {
    for pli in 0..planes {
      self.planes[pli].pad(w, h);
    }
  }
}

/// Public Trait for new Tile of a frame
pub(crate) trait AsTile<T: Pixel> {
  fn as_tile(&self) -> Tile<'_, T>;
  fn as_tile_mut(&mut self) -> TileMut<'_, T>;
}

impl<T: Pixel> AsTile<T> for Frame<T> {
  #[inline(always)]
  fn as_tile(&self) -> Tile<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    Tile::new(self, TileRect { x: 0, y: 0, width, height })
  }
  #[inline(always)]
  fn as_tile_mut(&mut self) -> TileMut<'_, T> {
    let PlaneConfig { width, height, .. } = self.planes[0].cfg;
    TileMut::new(self, TileRect { x: 0, y: 0, width, height })
  }
}
<|endoftext|>


<commit_before>//! OpenGL back-end for Piston-Graphics.

// External crates.
use std::ffi::CString;
use shader_version::{ OpenGL, Shaders };
use shader_version::glsl::GLSL;
use graphics::{ Context, DrawState, Graphics, Viewport };
use graphics::color::gamma_srgb_to_linear;
use gl;
use gl::types::{
    GLint,
    GLsizei,
    GLuint,
};

// Local crate.
use draw_state;
use Texture;
use shader_utils::{
    compile_shader,
    DynamicAttribute,
};

struct Colored {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    pos: DynamicAttribute,
    color: GLint,
}

impl Drop for Colored {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Colored {
    fn new(glsl: GLSL) -> Self {
        use shaders::colored;

        let src = |bytes| unsafe { ::std::str::from_utf8_unchecked(bytes) };

        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            Shaders::new().set(GLSL::V1_20, src(colored::VERTEX_GLSL_120))
                          .set(GLSL::V1_50, src(colored::VERTEX_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            Shaders::new().set(GLSL::V1_20, src(colored::FRAGMENT_GLSL_120))
                          .set(GLSL::V1_50, src(colored::FRAGMENT_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            gl::BindFragDataLocation(program, 0,
                CString::new("o_Color").unwrap().as_ptr());
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                gl::GetUniformLocation(program,
                    CString::new("color").unwrap().as_ptr())
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        Colored {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
        }
    }
}

struct Textured {
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    vao: GLuint,
    color: GLint,
    pos: DynamicAttribute,
    uv: DynamicAttribute,
}

impl Drop for Textured {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Textured {
    fn new(glsl: GLSL) -> Self {
        use shaders::textured;

        let src = |bytes| unsafe { ::std::str::from_utf8_unchecked(bytes) };

        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            Shaders::new().set(GLSL::V1_20, src(textured::VERTEX_GLSL_120))
                          .set(GLSL::V1_50, src(textured::VERTEX_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            Shaders::new().set(GLSL::V1_20, src(textured::FRAGMENT_GLSL_120))
                          .set(GLSL::V1_50, src(textured::FRAGMENT_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            gl::BindFragDataLocation(program, 0,
                CString::new("o_Color").unwrap().as_ptr());
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                gl::GetUniformLocation(program,
                    CString::new("color").unwrap().as_ptr())
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        let uv = DynamicAttribute::uv(
                program,
                "uv",
                vao
            ).unwrap();
        Textured {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

// Newlines and indents for cleaner panic message.
const GL_FUNC_NOT_LOADED: &'static str = "
    OpenGL function pointers must be loaded before creating the `Gl` backend!
    For more info, see the following issue on GitHub:
    https://github.com/PistonDevelopers/opengl_graphics/issues/103
";

/// Contains OpenGL data.
pub struct GlGraphics {
    colored: Colored,
    textured: Textured,
    // Keeps track of the current shader program.
    current_program: Option<GLuint>,
    // Keeps track of the current draw state.
    current_draw_state: Option<DrawState>,
}

impl<'a> GlGraphics {
    /// Creates a new OpenGL back-end.
    ///
    /// # Panics
    /// If the OpenGL function pointers have not been loaded yet.
    /// See https://github.com/PistonDevelopers/opengl_graphics/issues/103 for more info.
    pub fn new(opengl: OpenGL) -> Self {
        assert!(gl::Enable::is_loaded(), GL_FUNC_NOT_LOADED);

        let glsl = opengl.to_glsl();
        // Load the vertices, color and texture coord buffers.
        GlGraphics {
            colored: Colored::new(glsl),
            textured: Textured::new(glsl),
            current_program: None,
            current_draw_state: None,
       }
    }

    /// Sets viewport with normalized coordinates and center as origin.
    pub fn viewport(
        &mut self,
        x: i32,
        y: i32,
        w: i32,
        h: i32
    ) {
        unsafe {
            gl::Viewport(x as GLint, y as GLint, w as GLsizei, h as GLsizei);
        }
    }

    /// Sets the current program only if the program is not in use.
    pub fn use_program(&mut self, program: GLuint) {
        match self.current_program {
            None => {},
            Some(current_program) => {
                if program == current_program { return }
            },
        }

        unsafe {
            gl::UseProgram(program);
        }
        self.current_program = Some(program);
    }

    /// Unset the current program.
    ///
    /// This forces the current program to be set on next drawing call.
    pub fn clear_program(&mut self) {
        self.current_program = None
    }

    /// Sets the current draw state, by detecting changes.
    pub fn use_draw_state(&mut self, draw_state: &DrawState) {
        match self.current_draw_state {
            None => {
                draw_state::bind_scissor(draw_state.scissor);
                draw_state::bind_stencil(draw_state.stencil);
                draw_state::bind_blend(draw_state.blend);
            }
            Some(ref old_state) => {
                draw_state::bind_state(old_state, draw_state);
            }
        }
        self.current_draw_state = Some(*draw_state);
    }

    /// Unsets the current draw state.
    ///
    /// This forces the current draw state to be set on next drawing call.
    pub fn clear_draw_state(&mut self) {
        self.current_draw_state = None;
    }

    /// Draws graphics.
    pub fn draw<F>(&mut self, viewport: Viewport, f: F)
        where
            F: FnOnce(Context, &mut Self)
    {
        let rect = viewport.rect;
        let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
        self.viewport(x, y, w, h);
        self.clear_program();
        unsafe { gl::Enable(gl::FRAMEBUFFER_SRGB); }
        self.enable_alpha_blend();
        let c = Context::new_viewport(viewport);
        f(c, self);
        self.disable_alpha_blend();
    }

    /// Assume all textures has alpha channel for now.
    pub fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }

    /// Enabled alpha blending.
    pub fn enable_alpha_blend(&mut self) {
        unsafe {
            gl::Enable(gl::BLEND);
            gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
        }
    }

    /// Disables alpha blending.
    pub fn disable_alpha_blend(&mut self) {
        unsafe {
            gl::Disable(gl::BLEND);
        }
    }
}

impl Graphics for GlGraphics {
    type Texture = Texture;

    fn clear_color(&mut self, color: [f32; 4]) {
        let color = gamma_srgb_to_linear(color);
        unsafe {
            let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
            gl::ClearColor(r, g, b, a);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
    }

    fn clear_stencil(&mut self, value: u8) {
        unsafe {
            gl::ClearStencil(value as i32);
        }
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let color = gamma_srgb_to_linear(*color);
        {
            // Set shader program and draw state.
            let shader_program = self.colored.program;
            self.use_program(shader_program);
            self.use_draw_state(draw_state);
        }
        let ref mut shader = self.colored;

        unsafe {
            gl::BindVertexArray(shader.vao);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::Disable(gl::CULL_FACE);
        }

        f(&mut |vertices: &[f32]| {
            // xy makes two floats.
            let size_vertices: i32 = 2;
            let items: i32 = vertices.len() as i32 / size_vertices;

            unsafe {
                shader.pos.set(vertices);
                gl::DrawArrays(gl::TRIANGLES, 0, items);
            }
        });

        unsafe {
            gl::BindVertexArray(0);
        }
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let color = gamma_srgb_to_linear(*color);
        {
            // Set shader program and draw state.
            let shader_program = self.textured.program;
            self.use_program(shader_program);
            self.use_draw_state(draw_state);
        }
        let ref mut shader = self.textured;

        let texture = texture.get_id();
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, texture);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::Disable(gl::CULL_FACE);
            gl::BindVertexArray(shader.vao);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
        }

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            let size_vertices: i32 = 2;
            let items: i32 = vertices.len() as i32 / size_vertices;

            unsafe {
                shader.pos.set(vertices);
                shader.uv.set(texture_coords);
                gl::DrawArrays(gl::TRIANGLES, 0, items);
            }
        });

        unsafe {
            gl::BindVertexArray(0);
        }
    }
}

// Might not fail if previous tests loaded functions.
#[test]
#[should_panic]
fn test_gl_loaded() {
    GlGraphics::new(OpenGL::V3_2);
}
<commit_msg>Removed `enable_alpha_blend` and `disable_alpha_blend`<commit_after>//! OpenGL back-end for Piston-Graphics.

// External crates.
use std::ffi::CString;
use shader_version::{ OpenGL, Shaders };
use shader_version::glsl::GLSL;
use graphics::{ Context, DrawState, Graphics, Viewport };
use graphics::color::gamma_srgb_to_linear;
use gl;
use gl::types::{
    GLint,
    GLsizei,
    GLuint,
};

// Local crate.
use draw_state;
use Texture;
use shader_utils::{
    compile_shader,
    DynamicAttribute,
};

struct Colored {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    pos: DynamicAttribute,
    color: GLint,
}

impl Drop for Colored {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Colored {
    fn new(glsl: GLSL) -> Self {
        use shaders::colored;

        let src = |bytes| unsafe { ::std::str::from_utf8_unchecked(bytes) };

        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            Shaders::new().set(GLSL::V1_20, src(colored::VERTEX_GLSL_120))
                          .set(GLSL::V1_50, src(colored::VERTEX_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            Shaders::new().set(GLSL::V1_20, src(colored::FRAGMENT_GLSL_120))
                          .set(GLSL::V1_50, src(colored::FRAGMENT_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            gl::BindFragDataLocation(program, 0,
                CString::new("o_Color").unwrap().as_ptr());
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                gl::GetUniformLocation(program,
                    CString::new("color").unwrap().as_ptr())
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        Colored {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
        }
    }
}

struct Textured {
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    vao: GLuint,
    color: GLint,
    pos: DynamicAttribute,
    uv: DynamicAttribute,
}

impl Drop for Textured {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Textured {
    fn new(glsl: GLSL) -> Self {
        use shaders::textured;

        let src = |bytes| unsafe { ::std::str::from_utf8_unchecked(bytes) };

        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            Shaders::new().set(GLSL::V1_20, src(textured::VERTEX_GLSL_120))
                          .set(GLSL::V1_50, src(textured::VERTEX_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            Shaders::new().set(GLSL::V1_20, src(textured::FRAGMENT_GLSL_120))
                          .set(GLSL::V1_50, src(textured::FRAGMENT_GLSL_150_CORE))
                          .get(glsl).unwrap()
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            gl::BindFragDataLocation(program, 0,
                CString::new("o_Color").unwrap().as_ptr());
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                gl::GetUniformLocation(program,
                    CString::new("color").unwrap().as_ptr())
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        let uv = DynamicAttribute::uv(
                program,
                "uv",
                vao
            ).unwrap();
        Textured {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

// Newlines and indents for cleaner panic message.
const GL_FUNC_NOT_LOADED: &'static str = "
    OpenGL function pointers must be loaded before creating the `Gl` backend!
    For more info, see the following issue on GitHub:
    https://github.com/PistonDevelopers/opengl_graphics/issues/103
";

/// Contains OpenGL data.
pub struct GlGraphics {
    colored: Colored,
    textured: Textured,
    // Keeps track of the current shader program.
    current_program: Option<GLuint>,
    // Keeps track of the current draw state.
    current_draw_state: Option<DrawState>,
}

impl<'a> GlGraphics {
    /// Creates a new OpenGL back-end.
    ///
    /// # Panics
    /// If the OpenGL function pointers have not been loaded yet.
    /// See https://github.com/PistonDevelopers/opengl_graphics/issues/103 for more info.
    pub fn new(opengl: OpenGL) -> Self {
        assert!(gl::Enable::is_loaded(), GL_FUNC_NOT_LOADED);

        let glsl = opengl.to_glsl();
        // Load the vertices, color and texture coord buffers.
        GlGraphics {
            colored: Colored::new(glsl),
            textured: Textured::new(glsl),
            current_program: None,
            current_draw_state: None,
       }
    }

    /// Sets viewport with normalized coordinates and center as origin.
    pub fn viewport(
        &mut self,
        x: i32,
        y: i32,
        w: i32,
        h: i32
    ) {
        unsafe {
            gl::Viewport(x as GLint, y as GLint, w as GLsizei, h as GLsizei);
        }
    }

    /// Sets the current program only if the program is not in use.
    pub fn use_program(&mut self, program: GLuint) {
        match self.current_program {
            None => {},
            Some(current_program) => {
                if program == current_program { return }
            },
        }

        unsafe {
            gl::UseProgram(program);
        }
        self.current_program = Some(program);
    }

    /// Unset the current program.
    ///
    /// This forces the current program to be set on next drawing call.
    pub fn clear_program(&mut self) {
        self.current_program = None
    }

    /// Sets the current draw state, by detecting changes.
    pub fn use_draw_state(&mut self, draw_state: &DrawState) {
        match self.current_draw_state {
            None => {
                draw_state::bind_scissor(draw_state.scissor);
                draw_state::bind_stencil(draw_state.stencil);
                draw_state::bind_blend(draw_state.blend);
            }
            Some(ref old_state) => {
                draw_state::bind_state(old_state, draw_state);
            }
        }
        self.current_draw_state = Some(*draw_state);
    }

    /// Unsets the current draw state.
    ///
    /// This forces the current draw state to be set on next drawing call.
    pub fn clear_draw_state(&mut self) {
        self.current_draw_state = None;
    }

    /// Draws graphics.
    pub fn draw<F>(&mut self, viewport: Viewport, f: F)
        where
            F: FnOnce(Context, &mut Self)
    {
        let rect = viewport.rect;
        let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
        self.viewport(x, y, w, h);
        self.clear_program();
        unsafe { gl::Enable(gl::FRAMEBUFFER_SRGB); }
        let c = Context::new_viewport(viewport);
        f(c, self);
    }

    /// Assume all textures has alpha channel for now.
    pub fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }
}

impl Graphics for GlGraphics {
    type Texture = Texture;

    fn clear_color(&mut self, color: [f32; 4]) {
        let color = gamma_srgb_to_linear(color);
        unsafe {
            let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
            gl::ClearColor(r, g, b, a);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
    }

    fn clear_stencil(&mut self, value: u8) {
        unsafe {
            gl::ClearStencil(value as i32);
        }
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let color = gamma_srgb_to_linear(*color);
        {
            // Set shader program and draw state.
            let shader_program = self.colored.program;
            self.use_program(shader_program);
            self.use_draw_state(draw_state);
        }
        let ref mut shader = self.colored;

        unsafe {
            gl::BindVertexArray(shader.vao);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::Disable(gl::CULL_FACE);
        }

        f(&mut |vertices: &[f32]| {
            // xy makes two floats.
            let size_vertices: i32 = 2;
            let items: i32 = vertices.len() as i32 / size_vertices;

            unsafe {
                shader.pos.set(vertices);
                gl::DrawArrays(gl::TRIANGLES, 0, items);
            }
        });

        unsafe {
            gl::BindVertexArray(0);
        }
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let color = gamma_srgb_to_linear(*color);
        {
            // Set shader program and draw state.
            let shader_program = self.textured.program;
            self.use_program(shader_program);
            self.use_draw_state(draw_state);
        }
        let ref mut shader = self.textured;

        let texture = texture.get_id();
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, texture);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::Disable(gl::CULL_FACE);
            gl::BindVertexArray(shader.vao);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
        }

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            let size_vertices: i32 = 2;
            let items: i32 = vertices.len() as i32 / size_vertices;

            unsafe {
                shader.pos.set(vertices);
                shader.uv.set(texture_coords);
                gl::DrawArrays(gl::TRIANGLES, 0, items);
            }
        });

        unsafe {
            gl::BindVertexArray(0);
        }
    }
}

// Might not fail if previous tests loaded functions.
#[test]
#[should_panic]
fn test_gl_loaded() {
    GlGraphics::new(OpenGL::V3_2);
}
<|endoftext|>


<commit_before>use base::world::ChunkProvider;
use ghost::Ghost;
use event_manager::{CloseHandler, EventManager, EventResponse};
use glium::backend::glutin_backend::GlutinFacade;
use glium::{self, DisplayBuild, glutin};
use super::Renderer;
use super::{Config, GameContext, WorldManager};
use config::WindowMode;
use base::gen::WorldGenerator;
use std::time::{Duration, Instant};
use std::rc::Rc;
use std::net::{SocketAddr, TcpStream};
use std::error::Error;
use base::world::World;
use camera::Camera;
use base::world::PillarSection;
use base::world;
//use base::world::HeightType; //WILL BE USED LATER
use base::math::*;
use base::world::PillarIndex;
use view::{SkyView, Sun};
use super::DayTime;
use super::weather::Weather;
use player::Player;
use control_switcher::ControlSwitcher;
use base::world::HexPillar;

pub struct Game {
    renderer: Renderer,
    event_manager: EventManager,
    world_manager: WorldManager,
    #[allow(dead_code)]
    server: TcpStream,
    sun: Sun,
    sky_view: SkyView,
    daytime: DayTime,
    weather: Weather,
    control_switcher: ControlSwitcher,
}

impl Game {
    pub fn new(config: Config, server: SocketAddr) -> Result<Self, Box<Error>> {
        info!("connecting to {}", server);
        let server = try!(TcpStream::connect(server));
        let facade = try!(create_context(&config));
        let context = Rc::new(GameContext::new(facade, config.clone()));
        let world_manager = WorldManager::new(create_chunk_provider(context.get_config()),
                                              context.clone());
        let world_weather = Weather::new(context.clone());

        Ok(Game {
            renderer: Renderer::new(context.clone()),
            event_manager: EventManager::new(context.get_facade().clone()),
            world_manager: world_manager.clone(),
            server: server,
            sun: Sun::new(context.clone()),
            sky_view: SkyView::new(context.clone()),
            daytime: DayTime::default(),
            weather: world_weather,
            control_switcher: ControlSwitcher::new(Player::new(context.clone(), world_manager),
                                                   Ghost::new(context.clone())),
        })
    }

    /// Main game function: contains the main render loop and owns all important
    /// components. This function should remain rather small, all heavy lifting
    /// should be done in other functions.
    pub fn run(mut self) -> Result<(), Box<Error>> {
        let mut frames = 0;
        let mut next_fps_measure = Instant::now() + Duration::from_secs(1);
        let mut time_prev = Instant::now();
        loop {
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            let time_now = Instant::now();
            let duration_delta = time_now.duration_since(time_prev);
            // delta in seconds
            let delta = ((duration_delta.subsec_nanos() / 1_000) as f32) / 1_000_000.0 +
                        duration_delta.as_secs() as f32;
            time_prev = Instant::now();

            self.weather.update(&self.control_switcher.get_camera(),
                                delta,
                                &self.world_manager);
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            self.daytime.update(delta);
            self.sky_view.update(self.daytime.get_sun_position());
            self.sun.update(self.daytime.get_sun_position());
            // Display Outline of Hexagon looking at
            let vec = get_pillarsectionpos_looking_at(&self.world_manager.get_world(),
                                                      self.control_switcher.get_camera());
            match vec {
                Some(n) => {
                    // self.remove_hexagon_at(n.1, n.0.z);
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = true;
                    view.outline.pos = n.0;
                }
                None => {
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = false;
                }
            }

            try!(self.renderer.render(&*self.world_manager.get_view(),
                                      &self.control_switcher.get_camera(),
                                      &self.sun,
                                      &mut self.weather,
                                      &self.sky_view));

            let event_resp = self.event_manager
                .poll_events(vec![&mut CloseHandler,
                                  &mut self.control_switcher,
                                  &mut self.daytime]);
            if event_resp == EventResponse::Quit {
                break;
            }

            self.control_switcher.update(delta);

            frames += 1;
            if next_fps_measure < Instant::now() {
                info!("{} FPS", frames);
                next_fps_measure = Instant::now() + Duration::from_secs(1);
                frames = 0;
            }
        }

        Ok(())
    }

    // // need sorted pillars
    // fn remove_hexagon_at(&mut self, pos: AxialPoint, height: f32) {
    //     let pillar_index = PillarIndex(pos);

    //     match self.world_manager.mut_world().pillar_at_mut(pillar_index) {
    //         Some(pillar) => {
    //             let target_height = height - height % world::PILLAR_STEP_HEIGHT;

    //             for mut section in pillar.sections_mut() {
    //                 if section.bottom.to_real() <= target_height &&
    //                    section.top.to_real() >= target_height {
    //                     section.top = HeightType::from_units((HeightType::from_real((section.top
    //                         .to_real() -
    //                                                                            1.0))) as u16);
    //                 } else {
    //                     continue;
    //                 }

    //             }
    //         }
    //         None => return,
    //     };
    //     self.world_manager.recalculate_chunk(pos);
    // }
}

fn get_pillarsectionpos_looking_at(world: &World,
                                   cam: Camera)
                                   -> Option<(Vector3f, AxialPoint, f32)> {
    let cam_pos = cam.position;
    let mut look_vec = cam.get_look_at_vector().normalize();
    let view_distance = 12.0;

    let mut step = 0.0;
    while (look_vec.x * look_vec.x + look_vec.y * look_vec.y + look_vec.z * look_vec.z).sqrt() <=
          view_distance {
        step += 0.0005;
        look_vec = cam.get_look_at_vector().normalize() * step;

        let view_pos = Point2f::new(cam_pos.x + look_vec.x, cam_pos.y + look_vec.y);
        let ax_point = AxialPoint::from_real(view_pos);

        let pillar_index = PillarIndex(ax_point.clone());

        let mut height = cam_pos.z + look_vec.z;
        height -= height % world::PILLAR_STEP_HEIGHT;

        let final_pos = match world.pillar_at(pillar_index) {
            Some(n) => get_pillar_section_at_position(n, height),
            None => None,
        };

        match final_pos {
            Some(_) => {
                return Some((Vector3f::new(ax_point.to_real().x, ax_point.to_real().y, height),
                             ax_point,
                             height));
            }
            None => {}
        };
    }
    None
}

fn get_pillar_section_at_position(pillar: &HexPillar, pos_z: f32) -> Option<&PillarSection> {
    for section in pillar.sections() {
        if section.top.to_real() > pos_z && section.bottom.to_real() < pos_z {
            return Some(section);
        }
    }
    None
}

fn create_chunk_provider(config: &Config) -> Box<ChunkProvider> {
    Box::new(WorldGenerator::with_seed(config.seed))
}

/// Creates the OpenGL context and prints useful information about the
/// success or failure of said action.
fn create_context(config: &Config) -> Result<GlutinFacade, Box<Error>> {

    // initialize window builder
    let mut window_builder = glutin::WindowBuilder::new();
    // check for window mode and set params
    match config.window_mode {
        WindowMode::Windowed => (),
        // TODO: if we add a fullscreen window mode
        // FullScreenWindow => (),
        WindowMode::FullScreen => {
            window_builder = window_builder.with_fullscreen(glutin::get_primary_monitor());
            window_builder = window_builder.with_decorations(false);
        }
    }
    // check for vsync
    if config.vsync {
        window_builder = window_builder.with_vsync();
    }
    // set title, resolution & create glium context
    window_builder = window_builder.with_title(config.window_title.clone());
    window_builder =
        window_builder.with_dimensions(config.resolution.width, config.resolution.height);
    let context = window_builder.with_depth_buffer(24).build_glium();

    match context {
        Err(e) => {
            // TODO: print more user friendly output
            error!("OpenGL context creation failed! Detailed error:");
            error!("{}", e);

            Err(e.into())
        }
        Ok(context) => {
            // Print some information about the acquired OpenGL context
            info!("OpenGL context was successfully built");

            let glium::Version(api, major, minor) = *context.get_opengl_version();
            info!("Version of context: {} {}.{}",
                  if api == glium::Api::Gl { "OpenGL" } else { "OpenGL ES" },
                  major,
                  minor);

            let glium::Version(api, major, minor) = context.get_supported_glsl_version();
            info!("Supported GLSL version: {} {}.{}",
                  if api == glium::Api::Gl { "GLSL" } else { "GLSL ES" },
                  major,
                  minor);

            if let Some(mem) = context.get_free_video_memory().map(|mem| mem as u64) {
                let (mem, unit) = match () {
                    _ if mem < (1 << 12) => (mem, "B"),
                    _ if mem < (1 << 22) => (mem >> 10, "KB"),
                    _ if mem < (1 << 32) => (mem >> 20, "MB"),
                    _ => (mem >> 30, "GB"),
                };
                info!("Free GPU memory (estimated): {}{}", mem, unit);
            }

            Ok(context)
        }
    }
}
<commit_msg>Fix errors/warnings<commit_after>use base::world::ChunkProvider;
use ghost::Ghost;
use event_manager::{CloseHandler, EventManager, EventResponse};
use glium::backend::glutin_backend::GlutinFacade;
use glium::{self, DisplayBuild, glutin};
use super::Renderer;
use super::{Config, GameContext, WorldManager};
use config::WindowMode;
use base::gen::WorldGenerator;
use std::time::{Duration, Instant};
use std::rc::Rc;
use std::net::{SocketAddr, TcpStream};
use std::error::Error;
use base::world::World;
use camera::Camera;
use base::world::PillarSection;
use base::world;
use base::math::*;
use base::world::PillarIndex;
use view::{SkyView, Sun};
use super::DayTime;
use super::weather::Weather;
use player::Player;
use control_switcher::ControlSwitcher;
use base::world::HexPillar;

pub struct Game {
    renderer: Renderer,
    event_manager: EventManager,
    world_manager: WorldManager,
    #[allow(dead_code)]
    server: TcpStream,
    sun: Sun,
    sky_view: SkyView,
    daytime: DayTime,
    weather: Weather,
    control_switcher: ControlSwitcher,
}

impl Game {
    pub fn new(config: Config, server: SocketAddr) -> Result<Self, Box<Error>> {
        info!("connecting to {}", server);
        let server = try!(TcpStream::connect(server));
        let facade = try!(create_context(&config));
        let context = Rc::new(GameContext::new(facade, config.clone()));
        let world_manager = WorldManager::new(create_chunk_provider(context.get_config()),
                                              context.clone());
        let world_weather = Weather::new(context.clone());

        Ok(Game {
            renderer: Renderer::new(context.clone()),
            event_manager: EventManager::new(context.get_facade().clone()),
            world_manager: world_manager.clone(),
            server: server,
            sun: Sun::new(context.clone()),
            sky_view: SkyView::new(context.clone()),
            daytime: DayTime::default(),
            weather: world_weather,
            control_switcher: ControlSwitcher::new(Player::new(context.clone(), world_manager),
                                                   Ghost::new(context.clone())),
        })
    }

    /// Main game function: contains the main render loop and owns all important
    /// components. This function should remain rather small, all heavy lifting
    /// should be done in other functions.
    pub fn run(mut self) -> Result<(), Box<Error>> {
        let mut frames = 0;
        let mut next_fps_measure = Instant::now() + Duration::from_secs(1);
        let mut time_prev = Instant::now();
        loop {
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            let time_now = Instant::now();
            let duration_delta = time_now.duration_since(time_prev);
            // delta in seconds
            let delta = ((duration_delta.subsec_nanos() / 1_000) as f32) / 1_000_000.0 +
                        duration_delta.as_secs() as f32;
            time_prev = Instant::now();

            self.weather.update(&self.control_switcher.get_camera(),
                                delta,
                                &self.world_manager);
            self.world_manager.update_world(self.control_switcher.get_camera().position);

            self.daytime.update(delta);
            self.sky_view.update(self.daytime.get_sun_position());
            self.sun.update(self.daytime.get_sun_position());
            // Display Outline of Hexagon looking at
            let vec = get_pillarsectionpos_looking_at(&self.world_manager.get_world(),
                                                      self.control_switcher.get_camera());
            match vec {
                Some(n) => {
                    // self.remove_hexagon_at(n.1, n.0.z);
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = true;
                    view.outline.pos = n.0;
                }
                None => {
                    let mut view = self.world_manager.get_mut_view();
                    view.outline.display = false;
                }
            }

            try!(self.renderer.render(&*self.world_manager.get_view(),
                                      &self.control_switcher.get_camera(),
                                      &self.sun,
                                      &mut self.weather,
                                      &self.sky_view));

            let event_resp = self.event_manager
                .poll_events(vec![&mut CloseHandler,
                                  &mut self.control_switcher,
                                  &mut self.daytime]);
            if event_resp == EventResponse::Quit {
                break;
            }

            self.control_switcher.update(delta);

            frames += 1;
            if next_fps_measure < Instant::now() {
                info!("{} FPS", frames);
                next_fps_measure = Instant::now() + Duration::from_secs(1);
                frames = 0;
            }
        }

        Ok(())
    }
}

fn get_pillarsectionpos_looking_at(world: &World,
                                   cam: Camera)
                                   -> Option<(Vector3f, AxialPoint, f32)> {
    let cam_pos = cam.position;
    let mut look_vec = cam.get_look_at_vector().normalize();
    let view_distance = 12.0;

    let mut step = 0.0;
    while (look_vec.x * look_vec.x + look_vec.y * look_vec.y + look_vec.z * look_vec.z).sqrt() <=
          view_distance {
        step += 0.0005;
        look_vec = cam.get_look_at_vector().normalize() * step;

        let view_pos = Point2f::new(cam_pos.x + look_vec.x, cam_pos.y + look_vec.y);
        let ax_point = AxialPoint::from_real(view_pos);

        let pillar_index = PillarIndex(ax_point.clone());

        let mut height = cam_pos.z + look_vec.z;
        height -= height % world::PILLAR_STEP_HEIGHT;

        let final_pos = match world.pillar_at(pillar_index) {
            Some(n) => get_pillar_section_at_position(n, height),
            None => None,
        };

        match final_pos {
            Some(_) => {
                return Some((Vector3f::new(ax_point.to_real().x, ax_point.to_real().y, height),
                             ax_point,
                             height));
            }
            None => {}
        };
    }
    None
}

fn get_pillar_section_at_position(pillar: &HexPillar, pos_z: f32) -> Option<&PillarSection> {
    for section in pillar.sections() {
        if section.top.to_real() > pos_z && section.bottom.to_real() < pos_z {
            return Some(section);
        }
    }
    None
}

fn create_chunk_provider(config: &Config) -> Box<ChunkProvider> {
    Box::new(WorldGenerator::with_seed(config.seed))
}

/// Creates the OpenGL context and prints useful information about the
/// success or failure of said action.
fn create_context(config: &Config) -> Result<GlutinFacade, Box<Error>> {

    // initialize window builder
    let mut window_builder = glutin::WindowBuilder::new();
    // check for window mode and set params
    match config.window_mode {
        WindowMode::Windowed => (),
        // TODO: if we add a fullscreen window mode
        // FullScreenWindow => (),
        WindowMode::FullScreen => {
            window_builder = window_builder.with_fullscreen(glutin::get_primary_monitor());
            window_builder = window_builder.with_decorations(false);
        }
    }
    // check for vsync
    if config.vsync {
        window_builder = window_builder.with_vsync();
    }
    // set title, resolution & create glium context
    window_builder = window_builder.with_title(config.window_title.clone());
    window_builder =
        window_builder.with_dimensions(config.resolution.width, config.resolution.height);
    let context = window_builder.with_depth_buffer(24).build_glium();

    match context {
        Err(e) => {
            // TODO: print more user friendly output
            error!("OpenGL context creation failed! Detailed error:");
            error!("{}", e);

            Err(e.into())
        }
        Ok(context) => {
            // Print some information about the acquired OpenGL context
            info!("OpenGL context was successfully built");

            let glium::Version(api, major, minor) = *context.get_opengl_version();
            info!("Version of context: {} {}.{}",
                  if api == glium::Api::Gl { "OpenGL" } else { "OpenGL ES" },
                  major,
                  minor);

            let glium::Version(api, major, minor) = context.get_supported_glsl_version();
            info!("Supported GLSL version: {} {}.{}",
                  if api == glium::Api::Gl { "GLSL" } else { "GLSL ES" },
                  major,
                  minor);

            if let Some(mem) = context.get_free_video_memory().map(|mem| mem as u64) {
                let (mem, unit) = match () {
                    _ if mem < (1 << 12) => (mem, "B"),
                    _ if mem < (1 << 22) => (mem >> 10, "KB"),
                    _ if mem < (1 << 32) => (mem >> 20, "MB"),
                    _ => (mem >> 30, "GB"),
                };
                info!("Free GPU memory (estimated): {}{}", mem, unit);
            }

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