<commit_before>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::fmt;
use std::marker;
use std::mem;
use std::ops::{Index, IndexMut};

/// Stride is similar to the slice iterator, but with a certain number of steps
/// (the stride) skipped per iteration.
///
/// Stride does not support zero-sized types for `A`.
///
/// Iterator element type is `&'a A`.
pub struct Stride<'a, A: 'a> {
    /// base pointer -- does not change during iteration
    begin: *const A,
    /// current offset from begin
    offset: isize,
    /// offset where we end (exclusive end).
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a A>,
}

impl<'a, A> Copy for Stride<'a, A> {}
unsafe impl<'a, A> Send for Stride<'a, A> where A: Send {}
unsafe impl<'a, A> Sync for Stride<'a, A> where A: Sync {}

/// StrideMut is like Stride, but with mutable elements.
///
/// Iterator element type is `&'a mut A`.
pub struct StrideMut<'a, A: 'a> {
    begin: *mut A,
    offset: isize,
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a mut A>,
}

unsafe impl<'a, A> Send for StrideMut<'a, A> where A: Send {}
unsafe impl<'a, A> Sync for StrideMut<'a, A> where A: Sync {}

impl<'a, A> Stride<'a, A>
{
    /// Create a Stride iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *const A, nelem: usize, stride: isize) -> Stride<'a, A>
    {
        Stride {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

impl<'a, A> StrideMut<'a, A>
{
    /// Create a StrideMut iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *mut A, nelem: usize, stride: isize) -> StrideMut<'a, A>
    {
        StrideMut {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

fn div_rem(x: usize, d: usize) -> (usize, usize)
{
    (x / d, x % d)
}

macro_rules! stride_impl {
    (struct $name:ident -> $slice:ty, $getptr:ident, $ptr:ty, $elem:ty) => {
        impl<'a, A> $name<'a, A>
        {
            /// Create Stride iterator from a slice and the element step count.
            ///
            /// If `step` is negative, start from the back.
            ///
            /// ## Example
            ///
            /// ```
            /// use itertools::Stride;
            ///
            /// let xs = [0, 1, 2, 3, 4, 5];
            ///
            /// let front = Stride::from_slice(&xs, 2);
            /// assert_eq!(front[0], 0);
            /// assert_eq!(front[1], 2);
            ///
            /// let back = Stride::from_slice(&xs, -2);
            /// assert_eq!(back[0], 5);
            /// assert_eq!(back[1], 3);
            /// ```
            ///
            /// **Panics** if values of type `A` are zero-sized.

            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_slice(xs: $slice, step: isize) -> $name<'a, A>
            {
                assert!(mem::size_of::() != 0);
                let ustep = if step < 0 { -step } else { step } as usize;
                let nelem = if ustep <= 1 {
                    xs.len()
                } else {
                    let (d, r) = div_rem(xs.len(), ustep);
                    d + if r > 0 { 1 } else { 0 }
                };
                let mut begin = xs. $getptr ();
                unsafe {
                    if step > 0 {
                        $name::from_ptr_len(begin, nelem, step)
                    } else {
                        if nelem != 0 {
                            begin = begin.offset(xs.len() as isize - 1)
                        }
                        $name::from_ptr_len(begin, nelem, step)
                    }
                }
            }

            /// Create Stride iterator from an existing Stride iterator
            ///
            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_stride(mut it: $name<'a, A>, mut step: isize) -> $name<'a, A>
            {
                assert!(step != 0);
                if step < 0 {
                    it.swap_ends();
                    step = -step;
                }
                let len = (it.end - it.offset) / it.stride;
                let newstride = it.stride * step;
                let (d, r) = div_rem(len as usize, step as usize);
                let len = d as usize + if r > 0 { 1 } else { 0 };
                unsafe {
                    $name::from_ptr_len(it.begin, len, newstride)
                }
            }

            /// Swap the begin and end and reverse the stride,
            /// in effect reversing the iterator.
            #[inline]
            pub fn swap_ends(&mut self) {
                let len = (self.end - self.offset) / self.stride;
                if len > 0 {
                    unsafe {
                        let endptr = self.begin.offset((len - 1) * self.stride);
                        *self = $name::from_ptr_len(endptr, len as usize, -self.stride);
                    }
                }
            }

            /// Return the number of elements in the iterator.
            #[inline]
            pub fn len(&self) -> usize {
                ((self.end - self.offset) / self.stride) as usize
            }
        }

        impl<'a, A> Iterator for $name<'a, A>
        {
            type Item = $elem;
            #[inline]
            fn next(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        let elt: $elem =
                            mem::transmute(self.begin.offset(self.offset));
                        self.offset += self.stride;
                        Some(elt)
                    }
                }
            }

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

        impl<'a, A> DoubleEndedIterator for $name<'a, A>
        {
            #[inline]
            fn next_back(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        self.end -= self.stride;
                        let elt = mem::transmute(self.begin.offset(self.end));
                        Some(elt)
                    }
                }
            }
        }

        impl<'a, A> ExactSizeIterator for $name<'a, A> { }

        impl<'a, A> Index<usize> for $name<'a, A>
        {
            type Output = A;
            /// Return a reference to the element at a given index.
            ///
            /// **Panics** if the index is out of bounds.
            fn index<'b>(&'b self, i: usize) -> &'b A
            {
                assert!(i < self.len());
                unsafe {
                    let ptr = self.begin.offset(self.offset + self.stride * (i as isize));
                    mem::transmute(ptr)
                }
            }
        }

        impl<'a, A> fmt::Debug for $name<'a, A>
            where A: fmt::Debug
        {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
            {
                try!(write!(f, "["));
                for i in 0..self.len() {
                    if i != 0 {
                        try!(write!(f, ", "));
                    }
                    try!(write!(f, "{:?}", (*self)[i]));
                }
                write!(f, "]")
            }
        }
    }
}

stride_impl!{struct Stride -> &'a [A], as_ptr, *const A, &'a A}
stride_impl!{struct StrideMut -> &'a mut [A], as_mut_ptr, *mut A, &'a mut A}

impl<'a, A> Clone for Stride<'a, A>
{
    fn clone(&self) -> Stride<'a, A>
    {
        *self
    }
}

impl<'a, A> IndexMut<usize> for StrideMut<'a, A>
{
    /// Return a mutable reference to the element at a given index.
    ///
    /// **Panics** if the index is out of bounds.
    fn index_mut<'b>(&'b mut self, i: usize) -> &'b mut A
    {
        assert!(i < self.len());
        unsafe {
            let ptr = self.begin.offset(self.offset + self.stride * (i as isize));
            mem::transmute(ptr)
        }
    }
}
<commit_msg>Fix trivial cast<commit_after>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::fmt;
use std::marker;
use std::mem;
use std::ops::{Index, IndexMut};

/// Stride is similar to the slice iterator, but with a certain number of steps
/// (the stride) skipped per iteration.
///
/// Stride does not support zero-sized types for `A`.
///
/// Iterator element type is `&'a A`.
pub struct Stride<'a, A: 'a> {
    /// base pointer -- does not change during iteration
    begin: *const A,
    /// current offset from begin
    offset: isize,
    /// offset where we end (exclusive end).
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a A>,
}

impl<'a, A> Copy for Stride<'a, A> {}
unsafe impl<'a, A> Send for Stride<'a, A> where A: Send {}
unsafe impl<'a, A> Sync for Stride<'a, A> where A: Sync {}

/// StrideMut is like Stride, but with mutable elements.
///
/// Iterator element type is `&'a mut A`.
pub struct StrideMut<'a, A: 'a> {
    begin: *mut A,
    offset: isize,
    end: isize,
    stride: isize,
    life: marker::PhantomData<&'a mut A>,
}

unsafe impl<'a, A> Send for StrideMut<'a, A> where A: Send {}
unsafe impl<'a, A> Sync for StrideMut<'a, A> where A: Sync {}

impl<'a, A> Stride<'a, A>
{
    /// Create a Stride iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *const A, nelem: usize, stride: isize) -> Stride<'a, A>
    {
        Stride {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

impl<'a, A> StrideMut<'a, A>
{
    /// Create a StrideMut iterator from a raw pointer.
    pub unsafe fn from_ptr_len(begin: *mut A, nelem: usize, stride: isize) -> StrideMut<'a, A>
    {
        StrideMut {
            begin: begin,
            offset: 0,
            end: stride * nelem as isize,
            stride: stride,
            life: marker::PhantomData,
        }
    }
}

fn div_rem(x: usize, d: usize) -> (usize, usize)
{
    (x / d, x % d)
}

macro_rules! stride_impl {
    (struct $name:ident -> $slice:ty, $getptr:ident, $ptr:ty, $elem:ty) => {
        impl<'a, A> $name<'a, A>
        {
            /// Create Stride iterator from a slice and the element step count.
            ///
            /// If `step` is negative, start from the back.
            ///
            /// ## Example
            ///
            /// ```
            /// use itertools::Stride;
            ///
            /// let xs = [0, 1, 2, 3, 4, 5];
            ///
            /// let front = Stride::from_slice(&xs, 2);
            /// assert_eq!(front[0], 0);
            /// assert_eq!(front[1], 2);
            ///
            /// let back = Stride::from_slice(&xs, -2);
            /// assert_eq!(back[0], 5);
            /// assert_eq!(back[1], 3);
            /// ```
            ///
            /// **Panics** if values of type `A` are zero-sized.

            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_slice(xs: $slice, step: isize) -> $name<'a, A>
            {
                assert!(mem::size_of::() != 0);
                let ustep = if step < 0 { -step } else { step } as usize;
                let nelem = if ustep <= 1 {
                    xs.len()
                } else {
                    let (d, r) = div_rem(xs.len(), ustep);
                    d + if r > 0 { 1 } else { 0 }
                };
                let mut begin = xs. $getptr ();
                unsafe {
                    if step > 0 {
                        $name::from_ptr_len(begin, nelem, step)
                    } else {
                        if nelem != 0 {
                            begin = begin.offset(xs.len() as isize - 1)
                        }
                        $name::from_ptr_len(begin, nelem, step)
                    }
                }
            }

            /// Create Stride iterator from an existing Stride iterator
            ///
            /// **Panics** if `step` is 0.
            #[inline]
            pub fn from_stride(mut it: $name<'a, A>, mut step: isize) -> $name<'a, A>
            {
                assert!(step != 0);
                if step < 0 {
                    it.swap_ends();
                    step = -step;
                }
                let len = (it.end - it.offset) / it.stride;
                let newstride = it.stride * step;
                let (d, r) = div_rem(len as usize, step as usize);
                let len = d + if r > 0 { 1 } else { 0 };
                unsafe {
                    $name::from_ptr_len(it.begin, len, newstride)
                }
            }

            /// Swap the begin and end and reverse the stride,
            /// in effect reversing the iterator.
            #[inline]
            pub fn swap_ends(&mut self) {
                let len = (self.end - self.offset) / self.stride;
                if len > 0 {
                    unsafe {
                        let endptr = self.begin.offset((len - 1) * self.stride);
                        *self = $name::from_ptr_len(endptr, len as usize, -self.stride);
                    }
                }
            }

            /// Return the number of elements in the iterator.
            #[inline]
            pub fn len(&self) -> usize {
                ((self.end - self.offset) / self.stride) as usize
            }
        }

        impl<'a, A> Iterator for $name<'a, A>
        {
            type Item = $elem;
            #[inline]
            fn next(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        let elt: $elem =
                            mem::transmute(self.begin.offset(self.offset));
                        self.offset += self.stride;
                        Some(elt)
                    }
                }
            }

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

        impl<'a, A> DoubleEndedIterator for $name<'a, A>
        {
            #[inline]
            fn next_back(&mut self) -> Option<$elem>
            {
                if self.offset == self.end {
                    None
                } else {
                    unsafe {
                        self.end -= self.stride;
                        let elt = mem::transmute(self.begin.offset(self.end));
                        Some(elt)
                    }
                }
            }
        }

        impl<'a, A> ExactSizeIterator for $name<'a, A> { }

        impl<'a, A> Index<usize> for $name<'a, A>
        {
            type Output = A;
            /// Return a reference to the element at a given index.
            ///
            /// **Panics** if the index is out of bounds.
            fn index<'b>(&'b self, i: usize) -> &'b A
            {
                assert!(i < self.len());
                unsafe {
                    let ptr = self.begin.offset(self.offset + self.stride * (i as isize));
                    mem::transmute(ptr)
                }
            }
        }

        impl<'a, A> fmt::Debug for $name<'a, A>
            where A: fmt::Debug
        {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
            {
                try!(write!(f, "["));
                for i in 0..self.len() {
                    if i != 0 {
                        try!(write!(f, ", "));
                    }
                    try!(write!(f, "{:?}", (*self)[i]));
                }
                write!(f, "]")
            }
        }
    }
}

stride_impl!{struct Stride -> &'a [A], as_ptr, *const A, &'a A}
stride_impl!{struct StrideMut -> &'a mut [A], as_mut_ptr, *mut A, &'a mut A}

impl<'a, A> Clone for Stride<'a, A>
{
    fn clone(&self) -> Stride<'a, A>
    {
        *self
    }
}

impl<'a, A> IndexMut<usize> for StrideMut<'a, A>
{
    /// Return a mutable reference to the element at a given index.
    ///
    /// **Panics** if the index is out of bounds.
    fn index_mut<'b>(&'b mut self, i: usize) -> &'b mut A
    {
        assert!(i < self.len());
        unsafe {
            let ptr = self.begin.offset(self.offset + self.stride * (i as isize));
            mem::transmute(ptr)
        }
    }
}
<|endoftext|>


<commit_before>pub use chan_signal::Signal;
pub use chan::{Sender, Receiver};

/// A type implementing the Runner trait has the job of performing some arbitrary
/// work while waiting for a signal indication shutdown. Upon receiving that
/// defined shutdown Signal, the Runner must exit in a finite period of time.
pub trait Runner {
    /// Error type for the Runner.
    type Error;

    /// The run function is called when a user wants to perform work.
    fn run(self, signals: Receiver<Signal>) -> Result<(), Self::Error>;

    /// The setup function is called when a user wants to get ready to work.
    ///
    /// This function should only complete once the type is ready to be run,
    /// and must complete in finite period of time.
    fn setup(&mut self) -> Result<(), Self::Error>;
}

/// A Thread represents are running unit of work. It can be signaled and waited on.
pub trait Thread {
    /// Error type for the Thread.
    type Error;

    /// This function will block until the running Thread has finished its setup and
    /// is ready to run.
    fn ready(&self) -> Result<(), Self::Error>;
    /// This function will wait until the Thread has exited, returning a success or
    /// failure.
    fn wait(&self) -> Result<(), Self::Error>;
    /// This function will signal the running Thread with the specified signal.
    ///
    /// This is a non-blocking function.
    fn signal(&self, signal: Signal);
}

#[cfg(test)]
mod tests {
    use std::thread;
    use std::sync::mpsc;
    use chan;
    use std::error::Error;
    use std::fmt;
    use {Signal, Thread, Runner, Receiver, Sender};

    struct Test {
        data: usize,
    }

    #[derive(Debug, Eq, PartialEq, Clone)]
    struct TestError;

    impl fmt::Display for TestError {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            write!(fmt, "a testing error")
        }
    }
    impl Error for TestError {
        fn description(&self) -> &str {
            "a testing error"
        }
    }

    impl Runner for Test {
        type Error = TestError;

        fn setup(&mut self) -> Result<(), TestError> {
            self.data = 27;
            Ok(())
        }

        fn run(mut self, signals: Receiver<Signal>) -> Result<(), TestError> {
            self.data += 73;
            let sig = signals.recv().unwrap();
            if sig == Signal::INT {
                Ok(())
            } else {
                Err(TestError)
            }
        }
    }

    struct TestThread {
        runner: mpsc::Receiver<bool>,
        signals: Sender<Signal>,
    }

    impl TestThread {
        fn new(runner: Test) -> TestThread {
            let (sn, rc) = mpsc::channel();
            let (send_runner, recv_runner) = mpsc::channel::<Test>();
            // Marid sender/receiver
            let (signals, sig_recv) = chan::async();
            thread::spawn(move || {
                let mut runner = recv_runner.recv().unwrap();
                match runner.setup() {
                    Ok(_) => sn.send(true),
                    Err(_) => sn.send(false),
                }.unwrap();

                match runner.run(sig_recv) {
                    Ok(_) => sn.send(true),
                    Err(_) => sn.send(false),
                }.unwrap();
            });

            send_runner.send(runner).unwrap();

            TestThread{
                runner: rc,
                signals: signals,
            }
        }
    }

    impl Thread for TestThread {
        type Error = TestError;

        fn ready(&self) -> Result<(), Self::Error> {
            if self.runner.recv().unwrap() {
                Ok(())
            } else {
                Err(TestError)
            }
        }

        fn wait(&self) -> Result<(), Self::Error> {
            match self.runner.recv() {
                Ok(b) => if b { Ok(()) } else { Err(TestError) },
                Err(_) => Err(TestError),
            }
        }

        fn signal(&self, signal: Signal) {
            self.signals.send(signal);
        }
    }

    #[test]
    fn test_runner_and_thread() {
        let runner = Test { data: 0 };
        let thread = TestThread::new(runner);
        assert!(thread.ready().is_ok());
        thread.signal(Signal::INT);
        assert!(thread.wait().is_ok());
    }

    #[test]
    fn test_signal() {
        let runner = Test { data: 0 };
        let thread = TestThread::new(runner);
        assert!(thread.ready().is_ok());
        thread.signal(Signal::HUP);
        assert!(thread.wait().is_err());
    }
}
<commit_msg>s/Thread/Process/<commit_after>pub use chan_signal::Signal;
pub use chan::{Sender, Receiver};

/// A type implementing the Runner trait has the job of performing some arbitrary
/// work while waiting for a signal indication shutdown. Upon receiving that
/// defined shutdown Signal, the Runner must exit in a finite period of time.
pub trait Runner {
    /// Error type for the Runner.
    type Error;

    /// The run function is called when a user wants to perform work.
    fn run(self, signals: Receiver<Signal>) -> Result<(), Self::Error>;

    /// The setup function is called when a user wants to get ready to work.
    ///
    /// This function should only complete once the type is ready to be run,
    /// and must complete in finite period of time.
    fn setup(&mut self) -> Result<(), Self::Error>;
}

/// A Process represents are running unit of work. It can be signaled and waited on.
pub trait Process {
    /// Error type for the Process.
    type Error;

    /// This function will block until the running Process has finished its setup and
    /// is ready to run.
    fn ready(&self) -> Result<(), Self::Error>;
    /// This function will wait until the Process has exited, returning a success or
    /// failure.
    fn wait(&self) -> Result<(), Self::Error>;
    /// This function will signal the running Process with the specified signal.
    ///
    /// This is a non-blocking function.
    fn signal(&self, signal: Signal);
}

#[cfg(test)]
mod tests {
    use std::thread;
    use std::sync::mpsc;
    use chan;
    use std::error::Error;
    use std::fmt;
    use {Signal, Process, Runner, Receiver, Sender};

    struct Test {
        data: usize,
    }

    #[derive(Debug, Eq, PartialEq, Clone)]
    struct TestError;

    impl fmt::Display for TestError {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            write!(fmt, "a testing error")
        }
    }
    impl Error for TestError {
        fn description(&self) -> &str {
            "a testing error"
        }
    }

    impl Runner for Test {
        type Error = TestError;

        fn setup(&mut self) -> Result<(), TestError> {
            self.data = 27;
            Ok(())
        }

        fn run(mut self, signals: Receiver<Signal>) -> Result<(), TestError> {
            self.data += 73;
            let sig = signals.recv().unwrap();
            if sig == Signal::INT {
                Ok(())
            } else {
                Err(TestError)
            }
        }
    }

    struct TestProcess {
        runner: mpsc::Receiver<bool>,
        signals: Sender<Signal>,
    }

    impl TestProcess {
        fn new(runner: Test) -> TestProcess {
            let (sn, rc) = mpsc::channel();
            let (send_runner, recv_runner) = mpsc::channel::<Test>();
            // Marid sender/receiver
            let (signals, sig_recv) = chan::async();
            thread::spawn(move || {
                let mut runner = recv_runner.recv().unwrap();
                match runner.setup() {
                    Ok(_) => sn.send(true),
                    Err(_) => sn.send(false),
                }.unwrap();

                match runner.run(sig_recv) {
                    Ok(_) => sn.send(true),
                    Err(_) => sn.send(false),
                }.unwrap();
            });

            send_runner.send(runner).unwrap();

            TestProcess{
                runner: rc,
                signals: signals,
            }
        }
    }

    impl Process for TestProcess {
        type Error = TestError;

        fn ready(&self) -> Result<(), Self::Error> {
            if self.runner.recv().unwrap() {
                Ok(())
            } else {
                Err(TestError)
            }
        }

        fn wait(&self) -> Result<(), Self::Error> {
            match self.runner.recv() {
                Ok(b) => if b { Ok(()) } else { Err(TestError) },
                Err(_) => Err(TestError),
            }
        }

        fn signal(&self, signal: Signal) {
            self.signals.send(signal);
        }
    }

    #[test]
    fn test_runner_and_thread() {
        let runner = Test { data: 0 };
        let thread = TestProcess::new(runner);
        assert!(thread.ready().is_ok());
        thread.signal(Signal::INT);
        assert!(thread.wait().is_ok());
    }

    #[test]
    fn test_signal() {
        let runner = Test { data: 0 };
        let thread = TestProcess::new(runner);
        assert!(thread.ready().is_ok());
        thread.signal(Signal::HUP);
        assert!(thread.wait().is_err());
    }
}
<|endoftext|>


<commit_before>use std::ops::{
  Add, AddAssign,
  Sub, SubAssign,
  Mul, MulAssign,
  Div, DivAssign,
  Index, IndexMut,
};

#[derive(Debug, Copy, Clone)]
pub struct Vec3 {
  pub i : f64,
  pub j : f64,
  pub k : f64,
}

impl Vec3 {
  pub fn length(&self) -> f64 {
    (self.i * self.i + self.j * self.j + self.k * self.k).sqrt()
  }
}

impl Add for Vec3 {
  type Output = Vec3;
  fn add(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i + other.i, j: self.j + other.j, k: self.k + other.k}
  }
}

impl AddAssign for Vec3 {
  fn add_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i + other.i,
      j: self.j + other.j,
      k: self.k + other.k,
    };
  }
}

impl Sub for Vec3 {
  type Output = Vec3;
  fn sub(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i - other.i, j: self.j - other.j, k: self.k - other.k}
  }
}

impl SubAssign for Vec3 {
  fn sub_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i - other.i,
      j: self.j - other.j,
      k: self.k - other.k,
    }
  }
}

impl Mul for Vec3 {
  type Output = Vec3;
  fn mul(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i * rhs.i, j: self.j * rhs.j, k: self.k * rhs.k}
  }
}

impl MulAssign for Vec3 {
  fn mul_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i * rhs.i,
      j: self.j * rhs.j,
      k: self.k * rhs.k,
    }
  }
}

impl Div for Vec3 {
  type Output = Vec3;
  fn div(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i / rhs.i, j: self.j / rhs.j, k: self.k / rhs.k}
  }
}

impl DivAssign for Vec3 {
  fn div_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i / rhs.i,
      j: self.j / rhs.j,
      k: self.k / rhs.k,
    }
  }
}

impl Index<i32> for Vec3 {
  type Output = f64;
  fn index(&self, idx: i32) -> &f64 {
    match idx {
      0 => &self.i,
      1 => &self.j,
      2 => &self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

impl IndexMut<i32> for Vec3 {
  fn index_mut<'a>(&'a mut self, idx: i32) -> &'a mut f64 {
    match idx {
      0 => &mut self.i,
      1 => &mut self.j,
      2 => &mut self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

#[cfg(test)]
mod should {
  use super::Vec3;
  #[test]
  fn add() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let sum = v1 + v2;
    assert_eq!(sum.i, 3.0);
    assert_eq!(sum.j, 3.0);
    assert_eq!(sum.k, 3.0);
  }
  #[test]
  fn add_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 += v2;
    assert_eq!(v1.i, 3.0);
    assert_eq!(v1.j, 3.0);
    assert_eq!(v1.k, 3.0);
  }
  #[test]
  fn subtract() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let diff = v1 - v2;
    assert_eq!(diff.i, -1.0);
    assert_eq!(diff.j, -1.0);
    assert_eq!(diff.k, -1.0);
  }
  #[test]
  fn subtract_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 -= v2;
    assert_eq!(v1.i, -1.0);
    assert_eq!(v1.j, -1.0);
    assert_eq!(v1.k, -1.0);
  }
  #[test]
  fn multiply_elementwise() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let product = v1 * v2;
    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_assign_elementwise() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 *= v2;
    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn divide_elementwise() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let quotient = v1 / v2;
    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_assign_elementwise() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 /= v2;
    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn allow_index_access() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[0], 2.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
  #[test]
  #[should_panic(expected = "index out of range: 9")]
  fn panic_on_bad_index() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[9], 2.0);
  }
  #[test]
  fn allow_index_mut_access() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1[0] = 9.0;

    assert_eq!(v1[0], 9.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
}<commit_msg>Add division by scalar f64 and test<commit_after>use std::ops::{
  Add, AddAssign,
  Sub, SubAssign,
  Mul, MulAssign,
  Div, DivAssign,
  Index, IndexMut,
};

#[derive(Debug, Copy, Clone)]
pub struct Vec3 {
  pub i : f64,
  pub j : f64,
  pub k : f64,
}

impl Vec3 {
  pub fn length(&self) -> f64 {
    (self.i * self.i + self.j * self.j + self.k * self.k).sqrt()
  }
}

impl Add for Vec3 {
  type Output = Vec3;
  fn add(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i + other.i, j: self.j + other.j, k: self.k + other.k}
  }
}

impl AddAssign for Vec3 {
  fn add_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i + other.i,
      j: self.j + other.j,
      k: self.k + other.k,
    };
  }
}

impl Sub for Vec3 {
  type Output = Vec3;
  fn sub(self, other: Vec3) -> Vec3 {
      Vec3 {i: self.i - other.i, j: self.j - other.j, k: self.k - other.k}
  }
}

impl SubAssign for Vec3 {
  fn sub_assign(&mut self, other: Vec3) {
    *self = Vec3 {
      i: self.i - other.i,
      j: self.j - other.j,
      k: self.k - other.k,
    }
  }
}

impl Mul for Vec3 {
  type Output = Vec3;
  fn mul(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i * rhs.i, j: self.j * rhs.j, k: self.k * rhs.k}
  }
}

impl MulAssign for Vec3 {
  fn mul_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i * rhs.i,
      j: self.j * rhs.j,
      k: self.k * rhs.k,
    }
  }
}

impl Div<Vec3> for Vec3 {
  type Output = Vec3;
  fn div(self, rhs: Vec3) -> Vec3 {
    Vec3 {i: self.i / rhs.i, j: self.j / rhs.j, k: self.k / rhs.k}
  }
}

impl Div<f64> for Vec3 {
  type Output = Vec3;
  fn div(self, scalar: f64) -> Vec3 {
    Vec3 {i: self.i / scalar, j: self.j / scalar, k: self.k / scalar}
  }
}

impl DivAssign<Vec3> for Vec3 {
  fn div_assign(&mut self, rhs: Vec3) {
    *self = Vec3 {
      i: self.i / rhs.i,
      j: self.j / rhs.j,
      k: self.k / rhs.k,
    }
  }
}

impl DivAssign<f64> for Vec3 {
  fn div_assign(&mut self, scalar: f64) {
    *self = Vec3 {
      i: self.i / scalar,
      j: self.j / scalar,
      k: self.k / scalar,
    }
  }
}

impl Index<i32> for Vec3 {
  type Output = f64;
  fn index(&self, idx: i32) -> &f64 {
    match idx {
      0 => &self.i,
      1 => &self.j,
      2 => &self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

impl IndexMut<i32> for Vec3 {
  fn index_mut<'a>(&'a mut self, idx: i32) -> &'a mut f64 {
    match idx {
      0 => &mut self.i,
      1 => &mut self.j,
      2 => &mut self.k,
      _ => panic!("index out of range: {}", idx),
    }
  }
}

#[cfg(test)]
mod should {
  use super::Vec3;
  #[test]
  fn add() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let sum = v1 + v2;
    assert_eq!(sum.i, 3.0);
    assert_eq!(sum.j, 3.0);
    assert_eq!(sum.k, 3.0);
  }
  #[test]
  fn add_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 += v2;
    assert_eq!(v1.i, 3.0);
    assert_eq!(v1.j, 3.0);
    assert_eq!(v1.k, 3.0);
  }
  #[test]
  fn subtract() {
    let v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let diff = v1 - v2;
    assert_eq!(diff.i, -1.0);
    assert_eq!(diff.j, -1.0);
    assert_eq!(diff.k, -1.0);
  }
  #[test]
  fn subtract_assign() {
    let mut v1 = Vec3 { i: 1.0, j: 1.0, k: 1.0};
    let v2 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1 -= v2;
    assert_eq!(v1.i, -1.0);
    assert_eq!(v1.j, -1.0);
    assert_eq!(v1.k, -1.0);
  }
  #[test]
  fn multiply_elementwise() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let product = v1 * v2;
    assert_eq!(product.i, 6.0);
    assert_eq!(product.j, 6.0);
    assert_eq!(product.k, 6.0);
  }
  #[test]
  fn multiply_assign_elementwise() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 *= v2;
    assert_eq!(v1.i, 6.0);
    assert_eq!(v1.j, 6.0);
    assert_eq!(v1.k, 6.0);
  }
  #[test]
  fn divide_by_vec3_elementwise() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    let quotient = v1 / v2;
    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_vec3_assign_elementwise() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let v2 = Vec3 { i: 3.0, j: 3.0, k: 3.0};
    v1 /= v2;
    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn divide_by_f64() {
    let v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    let quotient = v1 / 3.0;

    assert_eq!(quotient.i, 2.0);
    assert_eq!(quotient.j, 2.0);
    assert_eq!(quotient.k, 2.0);
  }
  #[test]
  fn divide_by_f64_assign() {
    let mut v1 = Vec3 { i: 6.0, j: 6.0, k: 6.0};
    v1 /= 3.0;

    assert_eq!(v1.i, 2.0);
    assert_eq!(v1.j, 2.0);
    assert_eq!(v1.k, 2.0);
  }
  #[test]
  fn allow_index_access() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[0], 2.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
  #[test]
  #[should_panic(expected = "index out of range: 9")]
  fn panic_on_bad_index() {
    let v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};

    assert_eq!(v1[9], 2.0);
  }
  #[test]
  fn allow_index_mut_access() {
    let mut v1 = Vec3 { i: 2.0, j: 2.0, k: 2.0};
    v1[0] = 9.0;

    assert_eq!(v1[0], 9.0);
    assert_eq!(v1[1], 2.0);
    assert_eq!(v1[2], 2.0);
  }
}<|endoftext|>


<commit_before>use std::ops::Deref;
use std::mem;

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug)]
pub struct Vertex {
    pub id: i64,
    // pointers on both sides, yay
    pub out_edges: Vec<*mut Edge>,
    pub in_edges:  Vec<*mut Edge>,
}

impl Vertex {
    pub fn new(id: i64) -> Box<Vertex> {
        Box::new(Vertex{id:id,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()})
    }
}

pub struct VertexProxy {
    pub id: i64,
    pub v: *mut Vertex,
}

impl VertexProxy {
    pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) -> EdgeProxy {
        let in_vertex: &mut Vertex;
        let out_vertex: &mut Vertex;

        unsafe {
            in_vertex =  &mut *(self.v);
            out_vertex = &mut *(to_vertex.v);
        }

        // create the edge
        let e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

        let edge: *mut Edge = unsafe { mem::transmute(e) };

        in_vertex.out_edges.push(edge);
        out_vertex.in_edges.push(edge);
        EdgeProxy(edge)
    }

    pub fn query(self) {
        unimplemented!()
    }
}

impl Deref for VertexProxy {
    type Target = Vertex;

    fn deref<'a>(&'a self) -> &'a Vertex {
        unsafe {
            &*(self.v)
        }
    }
}

#[derive(Debug)]
pub struct Edge {
    pub from_vertex: *mut Vertex,
    pub to_vertex: *mut Vertex
}

pub struct EdgeProxy(*mut Edge);
<commit_msg>whups. broke tests again<commit_after>use std::ops::Deref;
use std::mem;

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug)]
pub struct Vertex {
    pub id: i64,
    // pointers on both sides, yay
    pub out_edges: Vec<*mut Edge>,
    pub in_edges:  Vec<*mut Edge>,
}

impl Vertex {
    pub fn new(id: i64) -> Box<Vertex> {
        Box::new(Vertex{id:id,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()})
    }
}

pub struct VertexProxy {
    pub id: i64,
    pub v: *mut Vertex,
}

impl VertexProxy {
    pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) -> EdgeProxy {
        let in_vertex: &mut Vertex;
        let out_vertex: &mut Vertex;

        unsafe {
            in_vertex =  &mut *(self.v);
            out_vertex = &mut *(to_vertex.v);
        }

        // create the edge
        let e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

        let edge: *mut Edge = unsafe { mem::transmute(e) };

        in_vertex.out_edges.push(edge);
        out_vertex.in_edges.push(edge);
        EdgeProxy(edge)
    }

    pub fn query(self) {
        unimplemented!()
    }
}

impl Deref for VertexProxy {
    type Target = Vertex;

    fn deref<'a>(&'a self) -> &'a Vertex {
        unsafe {
            &*(self.v)
        }
    }
}

#[derive(Debug)]
pub struct Edge {
    pub from_vertex: *mut Vertex,
    pub to_vertex: *mut Vertex
}

pub struct EdgeProxy(*mut Edge);

impl Deref for EdgeProxy {
    type Target = Edge;
    fn deref<'a>(&'a self) -> &'a Edge {
        unsafe { &*(self.0) }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::os::raw::c_void;
use std::path::Path;
use std::process;
use std::time::Instant;

use cgmath::{ Point3 };
use gl;
use glutin;
use glutin::{
    MouseScrollDelta,
    MouseButton,
    GlContext,
    VirtualKeyCode,
    WindowEvent,
};
use glutin::ElementState::*;

use gltf_importer;
use gltf_importer::config::ValidationStrategy;
use image::{DynamicImage, ImageFormat};

use controls::{CameraControls, OrbitControls, NavState};
use controls::CameraMovement::*;
use framebuffer::Framebuffer;
use render::*;
use render::math::*;
use utils::{print_elapsed, FrameTimer, gl_check_error};

// TODO!: complete and pass through draw calls? or get rid of multiple shaders?
// How about state ordering anyway?
// struct DrawState {
//     current_shader: ShaderFlags,
//     back_face_culling_enabled: bool
// }

pub struct GltfViewer {
    width: u32,
    height: u32,

    controls: CameraControls,
    orbit_controls: OrbitControls,
    first_mouse: bool,
    last_x: f32,
    last_y: f32,
    events_loop: Option<glutin::EventsLoop>,
    gl_window: Option<glutin::GlWindow>,

    // TODO!: get rid of scene?
    root: Root,
    scene: Scene,

    delta_time: f64, // seconds
    last_frame: Instant,

    render_timer: FrameTimer,
}

impl GltfViewer {
    pub fn new(source: &str, width: u32, height: u32, headless: bool, visible: bool) -> GltfViewer {

        let (events_loop, gl_window, width, height) =
            if headless {
                let headless_context = glutin::HeadlessRendererBuilder::new(width, height).build().unwrap();
                unsafe { headless_context.make_current().unwrap() }
                gl::load_with(|symbol| headless_context.get_proc_address(symbol) as *const _);
                let framebuffer = Framebuffer::new(width, height);
                framebuffer.bind();

                (None, None, width, height) // TODO: real height (retina?)
            }
            else {
                // glutin: initialize and configure
                let events_loop = glutin::EventsLoop::new().into();

                // TODO?: hints for 4.1, core profile, forward compat
                let window = glutin::WindowBuilder::new()
                        .with_title("gltf-viewer")
                        .with_dimensions(width, height)
                        .with_visibility(visible);

                let context = glutin::ContextBuilder::new()
                    .with_vsync(true);
                let gl_window = glutin::GlWindow::new(window, context, &events_loop).unwrap();

                // Real dimensions might be much higher on High-DPI displays
                let (real_width, real_height) = gl_window.get_inner_size_pixels().unwrap();

                unsafe { gl_window.make_current().unwrap(); }

                // gl: load all OpenGL function pointers
                gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _);

                (Some(events_loop), Some(gl_window), real_width, real_height)
            };

        // TODO!!: tmp duplicated camera controls
        let mut controls = CameraControls {
            position: Point3::new(0.0, 0.0, 2.0),
            camera: Camera::default(),
            ..CameraControls::default()
        };
        controls.camera.fovy = 60.0;
        controls.camera.update_aspect_ratio(width as f32 / height as f32); // updates projection matrix

        let mut orbit_controls = OrbitControls::new(
            Point3::new(0.0, 0.0, 2.0), width as f32, height as f32
        );
        orbit_controls.camera = Camera::default();
        orbit_controls.camera.fovy = 60.0;
        orbit_controls.camera.update_aspect_ratio(width as f32 / height as f32); // updates projection matrix

        let first_mouse = true;
        let last_x: f32 = width as f32 / 2.0;
        let last_y: f32 = height as f32 / 2.0;

        unsafe {
            gl::ClearColor(1.0, 1.0, 0.0, 1.0); // green for debugging
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            gl::Enable(gl::DEPTH_TEST);

            // TODO: keyboard switch?
            // draw in wireframe
            // gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE);
        };

        let (root, scene) = Self::load(source);
        let mut viewer = GltfViewer {
            width,
            height,

            controls,
            orbit_controls,
            first_mouse, last_x, last_y,

            events_loop,
            gl_window,

            root,
            scene,

            delta_time: 0.0, // seconds
            last_frame: Instant::now(),

            render_timer: FrameTimer::new("rendering", 300),
        };
        unsafe { gl_check_error!(); }

        // TODO!!!: completely broken (using gltf camera)
        if false && !viewer.root.camera_nodes.is_empty() {
            // Take first camera node
            let cam_node = &viewer.root.get_camera_node(0);
            viewer.controls.set_camera(
                cam_node.camera.as_ref().unwrap(),
                &cam_node.final_transform);
        } else {
            viewer.set_camera_from_bounds();
        }

        viewer
    }

    pub fn load(source: &str) -> (Root, Scene) {
        let mut start_time = Instant::now();
        // TODO!: http source
        // let gltf =
        if source.starts_with("http") {
            panic!("not implemented: HTTP support temporarily removed.")
            // let http_source = HttpSource::new(source);
            // let import = gltf::Import::custom(http_source, Default::default());
            // let gltf = import_gltf(import);
            // println!(); // to end the "progress dots"
            // gltf
        }
        //     else {
        let config = gltf_importer::Config { validation_strategy: ValidationStrategy::Complete };
        let (gltf, buffers) = match gltf_importer::import_with_config(source, config) {
            Ok((gltf, buffers)) => (gltf, buffers),
            Err(err) => {
                error!("glTF import failed: {:?}", err);
                if let gltf_importer::Error::Io(_) = err {
                    error!("Hint: Are the .bin file(s) referenced by the .gltf file available?")
                }
                process::exit(1)
            },
        };

        print_elapsed("Imported glTF in ", &start_time);
        start_time = Instant::now();

        // load first scene
        if gltf.scenes().len() > 1 {
            warn!("Found more than 1 scene, can only load first at the moment.")
        }
        let base_path = Path::new(source);
        let mut root = Root::from_gltf(&gltf, &buffers, base_path);
        let scene = Scene::from_gltf(gltf.scenes().nth(0).unwrap(), &mut root);
        print_elapsed(&format!("Loaded scene with {} nodes, {} meshes in ",
                gltf.nodes().count(), root.meshes.len()), &start_time);

        (root, scene)
    }

    /// determine "nice" camera perspective from bounding box. Inspired by donmccurdy/three-gltf-viewer
    fn set_camera_from_bounds(&mut self) {
        // TODO!!: fix bounds/camera computation (many models NOT centered)
        let bounds = &self.scene.bounds;
        let size = bounds.size().magnitude();
        let center = bounds.center();

        // TODO!: move cam instead?
        let _obj_pos_modifier = -center;

        let _max_distance = size * 10.0;
        // TODO: x,y addition optional, z optionally minus instead
        let cam_pos = Point3::new(
            center.x + size / 2.0,
            center.y + size / 5.0,
            center.z + size / 2.0,
        );
        let _near = size / 100.0;
        let _far = size * 100.0;

        // TODO!! TMP duplication (orbit controls)
        self.orbit_controls.position = cam_pos;
        self.orbit_controls.target = Point3::from_vec(center);

        self.controls.position = cam_pos;
        self.controls.center = Some(Point3::from_vec(center));

        // TODO!: set near, far, max_distance, obj_pos_modifier...
    }

    pub fn start_render_loop(&mut self) {
        loop {
            // per-frame time logic
            // NOTE: Deliberately ignoring the seconds of `elapsed()`
            self.delta_time = f64::from(self.last_frame.elapsed().subsec_nanos()) / 1_000_000_000.0;
            self.last_frame = Instant::now();

            // events
            let keep_running = process_events(
                &mut self.events_loop.as_mut().unwrap(), self.gl_window.as_mut().unwrap(),
                &mut self.controls, &mut self.orbit_controls,
                &mut self.width, &mut self.height);
            if !keep_running { break }

            self.controls.update(self.delta_time); // navigation

            self.draw();

            self.gl_window.as_ref().unwrap().swap_buffers().unwrap();
        }
    }

    // Returns whether to keep running
    pub fn draw(&mut self) {
        // render
        unsafe {
            self.render_timer.start();

            gl::ClearColor(0.1, 0.2, 0.3, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            // let cam_params = self.controls.camera_params();
            let cam_params = self.orbit_controls.camera_params();
            self.scene.draw(&mut self.root, &cam_params);

            self.render_timer.end();
        }
    }
    pub fn screenshot(&mut self, filename: &str, _width: u32, _height: u32) {
        self.draw();

        // TODO!: headless case...
        let (width, height) = self.gl_window.as_ref().unwrap().get_inner_size_pixels().unwrap();
        let mut img = DynamicImage::new_rgb8(width, height);
        unsafe {
            let pixels = img.as_mut_rgb8().unwrap();
            gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
            gl::ReadPixels(0, 0, width as i32, height as i32, gl::RGB,
                gl::UNSIGNED_BYTE, pixels.as_mut_ptr() as *mut c_void);
        }

        let img = img.flipv();

        let mut file = File::create(filename).unwrap();
        if let Err(err) = img.save(&mut file, ImageFormat::PNG) {
            error!("{}", err);
        }
        else {
            println!("Saved {}x{} screenshot to {}", width, height, filename);
        }
    }
    pub fn multiscreenshot(&mut self, filename: &str, _width: u32, _height: u32, _number: u32) {
        for x in 0.._number {
            let mut prefixer: String = (x+1).to_string();
            prefixer.to_owned();
            prefixer.push_str(filename);
            self.screenshot(&prefixer[..], _width,_height); // x: i32
        }

    }
}

#[allow(too_many_arguments)]
fn process_events(
    events_loop: &mut glutin::EventsLoop,
    gl_window: &glutin::GlWindow,
    mut controls: &mut CameraControls,
    orbit_controls: &mut OrbitControls,
    width: &mut u32,
    height: &mut u32) -> bool
{
    let mut keep_running = true;
    #[allow(single_match)]
    events_loop.poll_events(|event| {
        match event {
            glutin::Event::WindowEvent{ event, .. } => match event {
                WindowEvent::Closed => keep_running = false,
                WindowEvent::Resized(w, h) => {
                    gl_window.resize(w, h);
                    *width = w;
                    *height = h;
                    let w = w as f32;
                    let h = h as f32;
                    orbit_controls.camera.update_aspect_ratio(w / h);
                    orbit_controls.screen_width = w;
                    orbit_controls.screen_height = h;
                },
                WindowEvent::DroppedFile(_path_buf) => (), // TODO: drag file in
                WindowEvent::MouseInput { button, state: Pressed, ..} => {
                    match button {
                        MouseButton::Left => {
                            orbit_controls.state = NavState::Rotating;
                        },
                        MouseButton::Right => {
                            orbit_controls.state = NavState::Panning;
                        },
                        _ => ()
                    }
                },
                WindowEvent::MouseInput { button, state: Released, ..} => {
                    match (button, orbit_controls.state.clone()) {
                        (MouseButton::Left, NavState::Rotating) => {
                            orbit_controls.state = NavState::None;
                            orbit_controls.handle_mouse_up();
                        },
                        (MouseButton::Right, NavState::Panning) => {
                            orbit_controls.state = NavState::None;
                            orbit_controls.handle_mouse_up();

                        },
                        _ => ()
                    }
                }
                WindowEvent::MouseMoved { position: (xpos, ypos), .. } => {
                    let (xpos, ypos) = (xpos as f32, ypos as f32);
                    orbit_controls.handle_mouse_move(xpos, ypos);
                },
                WindowEvent::MouseWheel { delta: MouseScrollDelta::PixelDelta(_xoffset, yoffset), .. } => {
                    // TODO: need to handle LineDelta case too?
                    orbit_controls.process_mouse_scroll(yoffset);
                }
                WindowEvent::KeyboardInput { input, .. } => {
                    keep_running = process_input(input, &mut controls);
                }
                _ => ()
            },
            _ => ()
        }
    });

    keep_running
}

fn process_input(input: glutin::KeyboardInput, camera: &mut CameraControls) -> bool {
    let pressed = match input.state {
        Pressed => true,
        Released => false
    };
    if let Some(code) = input.virtual_keycode {
        match code {
            VirtualKeyCode::Escape if pressed => return false,
            VirtualKeyCode::W => camera.process_keyboard(FORWARD, pressed),
            VirtualKeyCode::S => camera.process_keyboard(BACKWARD, pressed),
            VirtualKeyCode::A => camera.process_keyboard(LEFT, pressed),
            VirtualKeyCode::D => camera.process_keyboard(RIGHT, pressed),
            _ => ()
        }
    }
    true
}
<commit_msg>unnessecary change<commit_after>use std::fs::File;
use std::os::raw::c_void;
use std::path::Path;
use std::process;
use std::time::Instant;

use cgmath::{ Point3 };
use gl;
use glutin;
use glutin::{
    MouseScrollDelta,
    MouseButton,
    GlContext,
    VirtualKeyCode,
    WindowEvent,
};
use glutin::ElementState::*;

use gltf_importer;
use gltf_importer::config::ValidationStrategy;
use image::{DynamicImage, ImageFormat};

use controls::{CameraControls, OrbitControls, NavState};
use controls::CameraMovement::*;
use framebuffer::Framebuffer;
use render::*;
use render::math::*;
use utils::{print_elapsed, FrameTimer, gl_check_error};

// TODO!: complete and pass through draw calls? or get rid of multiple shaders?
// How about state ordering anyway?
// struct DrawState {
//     current_shader: ShaderFlags,
//     back_face_culling_enabled: bool
// }

pub struct GltfViewer {
    width: u32,
    height: u32,

    controls: CameraControls,
    orbit_controls: OrbitControls,
    first_mouse: bool,
    last_x: f32,
    last_y: f32,
    events_loop: Option<glutin::EventsLoop>,
    gl_window: Option<glutin::GlWindow>,

    // TODO!: get rid of scene?
    root: Root,
    scene: Scene,

    delta_time: f64, // seconds
    last_frame: Instant,

    render_timer: FrameTimer,
}

impl GltfViewer {
    pub fn new(source: &str, width: u32, height: u32, headless: bool, visible: bool) -> GltfViewer {

        let (events_loop, gl_window, width, height) =
            if headless {
                let headless_context = glutin::HeadlessRendererBuilder::new(width, height).build().unwrap();
                unsafe { headless_context.make_current().unwrap() }
                gl::load_with(|symbol| headless_context.get_proc_address(symbol) as *const _);
                let framebuffer = Framebuffer::new(width, height);
                framebuffer.bind();

                (None, None, width, height) // TODO: real height (retina?)
            }
            else {
                // glutin: initialize and configure
                let events_loop = glutin::EventsLoop::new().into();

                // TODO?: hints for 4.1, core profile, forward compat
                let window = glutin::WindowBuilder::new()
                        .with_title("gltf-viewer")
                        .with_dimensions(width, height)
                        .with_visibility(visible);

                let context = glutin::ContextBuilder::new()
                    .with_vsync(true);
                let gl_window = glutin::GlWindow::new(window, context, &events_loop).unwrap();

                // Real dimensions might be much higher on High-DPI displays
                let (real_width, real_height) = gl_window.get_inner_size_pixels().unwrap();

                unsafe { gl_window.make_current().unwrap(); }

                // gl: load all OpenGL function pointers
                gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _);

                (Some(events_loop), Some(gl_window), real_width, real_height)
            };

        // TODO!!: tmp duplicated camera controls
        let mut controls = CameraControls {
            position: Point3::new(0.0, 0.0, 2.0),
            camera: Camera::default(),
            ..CameraControls::default()
        };
        controls.camera.fovy = 60.0;
        controls.camera.update_aspect_ratio(width as f32 / height as f32); // updates projection matrix

        let mut orbit_controls = OrbitControls::new(
            Point3::new(0.0, 0.0, 2.0), width as f32, height as f32
        );
        orbit_controls.camera = Camera::default();
        orbit_controls.camera.fovy = 60.0;
        orbit_controls.camera.update_aspect_ratio(width as f32 / height as f32); // updates projection matrix

        let first_mouse = true;
        let last_x: f32 = width as f32 / 2.0;
        let last_y: f32 = height as f32 / 2.0;

        unsafe {
            gl::ClearColor(0.0, 1.0, 0.0, 1.0); // green for debugging
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            gl::Enable(gl::DEPTH_TEST);

            // TODO: keyboard switch?
            // draw in wireframe
            // gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE);
        };

        let (root, scene) = Self::load(source);
        let mut viewer = GltfViewer {
            width,
            height,

            controls,
            orbit_controls,
            first_mouse, last_x, last_y,

            events_loop,
            gl_window,

            root,
            scene,

            delta_time: 0.0, // seconds
            last_frame: Instant::now(),

            render_timer: FrameTimer::new("rendering", 300),
        };
        unsafe { gl_check_error!(); }

        // TODO!!!: completely broken (using gltf camera)
        if false && !viewer.root.camera_nodes.is_empty() {
            // Take first camera node
            let cam_node = &viewer.root.get_camera_node(0);
            viewer.controls.set_camera(
                cam_node.camera.as_ref().unwrap(),
                &cam_node.final_transform);
        } else {
            viewer.set_camera_from_bounds();
        }

        viewer
    }

    pub fn load(source: &str) -> (Root, Scene) {
        let mut start_time = Instant::now();
        // TODO!: http source
        // let gltf =
        if source.starts_with("http") {
            panic!("not implemented: HTTP support temporarily removed.")
            // let http_source = HttpSource::new(source);
            // let import = gltf::Import::custom(http_source, Default::default());
            // let gltf = import_gltf(import);
            // println!(); // to end the "progress dots"
            // gltf
        }
        //     else {
        let config = gltf_importer::Config { validation_strategy: ValidationStrategy::Complete };
        let (gltf, buffers) = match gltf_importer::import_with_config(source, config) {
            Ok((gltf, buffers)) => (gltf, buffers),
            Err(err) => {
                error!("glTF import failed: {:?}", err);
                if let gltf_importer::Error::Io(_) = err {
                    error!("Hint: Are the .bin file(s) referenced by the .gltf file available?")
                }
                process::exit(1)
            },
        };

        print_elapsed("Imported glTF in ", &start_time);
        start_time = Instant::now();

        // load first scene
        if gltf.scenes().len() > 1 {
            warn!("Found more than 1 scene, can only load first at the moment.")
        }
        let base_path = Path::new(source);
        let mut root = Root::from_gltf(&gltf, &buffers, base_path);
        let scene = Scene::from_gltf(gltf.scenes().nth(0).unwrap(), &mut root);
        print_elapsed(&format!("Loaded scene with {} nodes, {} meshes in ",
                gltf.nodes().count(), root.meshes.len()), &start_time);

        (root, scene)
    }

    /// determine "nice" camera perspective from bounding box. Inspired by donmccurdy/three-gltf-viewer
    fn set_camera_from_bounds(&mut self) {
        // TODO!!: fix bounds/camera computation (many models NOT centered)
        let bounds = &self.scene.bounds;
        let size = bounds.size().magnitude();
        let center = bounds.center();

        // TODO!: move cam instead?
        let _obj_pos_modifier = -center;

        let _max_distance = size * 10.0;
        // TODO: x,y addition optional, z optionally minus instead
        let cam_pos = Point3::new(
            center.x + size / 2.0,
            center.y + size / 5.0,
            center.z + size / 2.0,
        );
        let _near = size / 100.0;
        let _far = size * 100.0;

        // TODO!! TMP duplication (orbit controls)
        self.orbit_controls.position = cam_pos;
        self.orbit_controls.target = Point3::from_vec(center);

        self.controls.position = cam_pos;
        self.controls.center = Some(Point3::from_vec(center));

        // TODO!: set near, far, max_distance, obj_pos_modifier...
    }

    pub fn start_render_loop(&mut self) {
        loop {
            // per-frame time logic
            // NOTE: Deliberately ignoring the seconds of `elapsed()`
            self.delta_time = f64::from(self.last_frame.elapsed().subsec_nanos()) / 1_000_000_000.0;
            self.last_frame = Instant::now();

            // events
            let keep_running = process_events(
                &mut self.events_loop.as_mut().unwrap(), self.gl_window.as_mut().unwrap(),
                &mut self.controls, &mut self.orbit_controls,
                &mut self.width, &mut self.height);
            if !keep_running { break }

            self.controls.update(self.delta_time); // navigation

            self.draw();

            self.gl_window.as_ref().unwrap().swap_buffers().unwrap();
        }
    }

    // Returns whether to keep running
    pub fn draw(&mut self) {
        // render
        unsafe {
            self.render_timer.start();

            gl::ClearColor(0.1, 0.2, 0.3, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            // let cam_params = self.controls.camera_params();
            let cam_params = self.orbit_controls.camera_params();
            self.scene.draw(&mut self.root, &cam_params);

            self.render_timer.end();
        }
    }
    pub fn screenshot(&mut self, filename: &str, _width: u32, _height: u32) {
        self.draw();

        // TODO!: headless case...
        let (width, height) = self.gl_window.as_ref().unwrap().get_inner_size_pixels().unwrap();
        let mut img = DynamicImage::new_rgb8(width, height);
        unsafe {
            let pixels = img.as_mut_rgb8().unwrap();
            gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
            gl::ReadPixels(0, 0, width as i32, height as i32, gl::RGB,
                gl::UNSIGNED_BYTE, pixels.as_mut_ptr() as *mut c_void);
        }

        let img = img.flipv();

        let mut file = File::create(filename).unwrap();
        if let Err(err) = img.save(&mut file, ImageFormat::PNG) {
            error!("{}", err);
        }
        else {
            println!("Saved {}x{} screenshot to {}", width, height, filename);
        }
    }
    pub fn multiscreenshot(&mut self, filename: &str, _width: u32, _height: u32, _number: u32) {
        for x in 0.._number {
            let mut prefixer: String = (x+1).to_string();
            prefixer.to_owned();
            prefixer.push_str(filename);
            self.screenshot(&prefixer[..], _width,_height); // x: i32
        }

    }
}

#[allow(too_many_arguments)]
fn process_events(
    events_loop: &mut glutin::EventsLoop,
    gl_window: &glutin::GlWindow,
    mut controls: &mut CameraControls,
    orbit_controls: &mut OrbitControls,
    width: &mut u32,
    height: &mut u32) -> bool
{
    let mut keep_running = true;
    #[allow(single_match)]
    events_loop.poll_events(|event| {
        match event {
            glutin::Event::WindowEvent{ event, .. } => match event {
                WindowEvent::Closed => keep_running = false,
                WindowEvent::Resized(w, h) => {
                    gl_window.resize(w, h);
                    *width = w;
                    *height = h;
                    let w = w as f32;
                    let h = h as f32;
                    orbit_controls.camera.update_aspect_ratio(w / h);
                    orbit_controls.screen_width = w;
                    orbit_controls.screen_height = h;
                },
                WindowEvent::DroppedFile(_path_buf) => (), // TODO: drag file in
                WindowEvent::MouseInput { button, state: Pressed, ..} => {
                    match button {
                        MouseButton::Left => {
                            orbit_controls.state = NavState::Rotating;
                        },
                        MouseButton::Right => {
                            orbit_controls.state = NavState::Panning;
                        },
                        _ => ()
                    }
                },
                WindowEvent::MouseInput { button, state: Released, ..} => {
                    match (button, orbit_controls.state.clone()) {
                        (MouseButton::Left, NavState::Rotating) => {
                            orbit_controls.state = NavState::None;
                            orbit_controls.handle_mouse_up();
                        },
                        (MouseButton::Right, NavState::Panning) => {
                            orbit_controls.state = NavState::None;
                            orbit_controls.handle_mouse_up();

                        },
                        _ => ()
                    }
                }
                WindowEvent::MouseMoved { position: (xpos, ypos), .. } => {
                    let (xpos, ypos) = (xpos as f32, ypos as f32);
                    orbit_controls.handle_mouse_move(xpos, ypos);
                },
                WindowEvent::MouseWheel { delta: MouseScrollDelta::PixelDelta(_xoffset, yoffset), .. } => {
                    // TODO: need to handle LineDelta case too?
                    orbit_controls.process_mouse_scroll(yoffset);
                }
                WindowEvent::KeyboardInput { input, .. } => {
                    keep_running = process_input(input, &mut controls);
                }
                _ => ()
            },
            _ => ()
        }
    });

    keep_running
}

fn process_input(input: glutin::KeyboardInput, camera: &mut CameraControls) -> bool {
    let pressed = match input.state {
        Pressed => true,
        Released => false
    };
    if let Some(code) = input.virtual_keycode {
        match code {
            VirtualKeyCode::Escape if pressed => return false,
            VirtualKeyCode::W => camera.process_keyboard(FORWARD, pressed),
            VirtualKeyCode::S => camera.process_keyboard(BACKWARD, pressed),
            VirtualKeyCode::A => camera.process_keyboard(LEFT, pressed),
            VirtualKeyCode::D => camera.process_keyboard(RIGHT, pressed),
            _ => ()
        }
    }
    true
}
<|endoftext|>


<commit_before>use std::old_io::{File, Open, Read, Write, ReadWrite};
use std::vec;

use protobuf;
use rustc_serialize::base64::{self, ToBase64};
use sodiumoxide::crypto::sign::ed25519;

use error::{SimplesResult};
use simples_pb::{Wallet, WalletKey};

fn load_proto_from_file<Message: protobuf::MessageStatic>(
    path: &str) -> SimplesResult<Message>
{
    let mut proto_in = File::open(&Path::new(path));
    let wallet_bytes = try!(proto_in.read_to_end());
    Ok(try!(protobuf::parse_from_bytes(&wallet_bytes[])))
}

fn save_proto_to_file<Message: protobuf::MessageStatic>(
    path: &str, msg: &Message) -> SimplesResult<()>
{
    let mut proto_out = File::create(&Path::new(path));
    let wallet_bytes = try!(msg.write_to_bytes());
    Ok(try!(proto_out.write(&wallet_bytes[])))
}

pub fn load_from_file(path: &str) -> SimplesResult<Wallet> {
    load_proto_from_file(path)
}

pub fn save_to_file(path: &str, wallet: &Wallet) -> SimplesResult<()> {
    save_proto_to_file(path, wallet)
}

pub fn pretty_format(wallet_key: &WalletKey) -> String {
    let mut formatted = String::new();
    let pk = wallet_key.get_public_key();
    let sk = wallet_key.get_secret_key();
    formatted.push_str(&format!(
        "[ {} ]\n", pk.to_base64(base64::STANDARD))[]);
    formatted.push_str(&format!(
        " name: {}\n", wallet_key.get_name())[]);
    formatted.push_str(&format!(
        " desc: {}\n", wallet_key.get_description())[]);
    formatted.push_str(&format!(
        "   pk: {}\n", pk.to_base64(base64::STANDARD))[]);
    formatted.push_str(&format!(
        "   sk: {}\n", sk.to_base64(base64::STANDARD))[]);
    formatted
}

pub trait WalletExt {
    fn generate_new_key(
        &mut self, name: &str, description: &str) -> WalletKey;
    fn get_keys_by_name(&self, search_str: &str) -> Vec<&WalletKey>;
}

impl WalletExt for Wallet {
    fn generate_new_key(
        &mut self, name: &str, description: &str) -> WalletKey
    {
        let (pk, sk) = ed25519::gen_keypair();
        let mut key = WalletKey::new();
        key.set_public_key(pk.0.to_vec());
        key.set_secret_key(sk.0.to_vec());
        key.set_name(String::from_str(name));
        key.set_description(String::from_str(description));
        let copy = key.clone();
        self.mut_keys().push(key);
        copy
    }

    fn get_keys_by_name(&self, search_str: &str) -> Vec<&WalletKey> {
        let mut keys = Vec::<&WalletKey>::new();
        self.get_keys().iter()
            .filter(|wkey| {
                let name = &wkey.get_name()[];
                let matches: Vec<(usize, usize)> =
                    name.match_indices(search_str).collect();
                matches.len() > 0
            }).collect()
    }
}
<commit_msg>Search by keys looks at name and public key.<commit_after>use std::old_io::{File, Open, Read, Write, ReadWrite};
use std::vec;

use protobuf;
use rustc_serialize::base64::{self, ToBase64};
use sodiumoxide::crypto::sign::ed25519;

use error::{SimplesResult};
use simples_pb::{Wallet, WalletKey};

fn load_proto_from_file<Message: protobuf::MessageStatic>(
    path: &str) -> SimplesResult<Message>
{
    let mut proto_in = File::open(&Path::new(path));
    let wallet_bytes = try!(proto_in.read_to_end());
    Ok(try!(protobuf::parse_from_bytes(&wallet_bytes[])))
}

fn save_proto_to_file<Message: protobuf::MessageStatic>(
    path: &str, msg: &Message) -> SimplesResult<()>
{
    let mut proto_out = File::create(&Path::new(path));
    let wallet_bytes = try!(msg.write_to_bytes());
    Ok(try!(proto_out.write(&wallet_bytes[])))
}

pub fn load_from_file(path: &str) -> SimplesResult<Wallet> {
    load_proto_from_file(path)
}

pub fn save_to_file(path: &str, wallet: &Wallet) -> SimplesResult<()> {
    save_proto_to_file(path, wallet)
}

pub fn pretty_format(wallet_key: &WalletKey) -> String {
    let mut formatted = String::new();
    let pk = wallet_key.get_public_key();
    let sk = wallet_key.get_secret_key();
    formatted.push_str(&format!(
        "[ {} ]\n", pk.to_base64(base64::STANDARD))[]);
    formatted.push_str(&format!(
        " name: {}\n", wallet_key.get_name())[]);
    formatted.push_str(&format!(
        " desc: {}\n", wallet_key.get_description())[]);
    formatted.push_str(&format!(
        "   pk: {}\n", pk.to_base64(base64::STANDARD))[]);
    formatted.push_str(&format!(
        "   sk: {}\n", sk.to_base64(base64::STANDARD))[]);
    formatted
}

pub trait WalletExt {
    fn generate_new_key(
        &mut self, name: &str, description: &str) -> WalletKey;
    fn search_keys(&self, search_str: &str) -> Vec<&WalletKey>;
}

impl WalletExt for Wallet {
    fn generate_new_key(
        &mut self, name: &str, description: &str) -> WalletKey
    {
        let (pk, sk) = ed25519::gen_keypair();
        let mut key = WalletKey::new();
        key.set_public_key(pk.0.to_vec());
        key.set_secret_key(sk.0.to_vec());
        key.set_name(String::from_str(name));
        key.set_description(String::from_str(description));
        let copy = key.clone();
        self.mut_keys().push(key);
        copy
    }

    fn search_keys(&self, search_str: &str) -> Vec<&WalletKey> {
        self.get_keys().iter()
            .filter(|wkey| {
                let name = &wkey.get_name()[];
                let pk_base64 = wkey.get_public_key()
                    .to_base64(base64::STANDARD);
                name.starts_with(search_str) ||
                    pk_base64.starts_with(search_str)
            }).collect()
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use cairo::{self, Surface};
use gdk_pixbuf;
use gdk_sys;
use glib::object::IsA;
use glib::translate::*;
use libc::{c_char, c_int};
use std::ptr;
use Cursor;
use Visual;
use Window;

use {WindowType, WindowTypeHint, WindowWindowClass};

pub struct WindowAttr {
    pub title: Option<String>,
    pub event_mask: i32,
    pub x: Option<i32>,
    pub y: Option<i32>,
    pub width: i32,
    pub height: i32,
    pub wclass: WindowWindowClass,
    pub visual: Option<Visual>,
    pub window_type: WindowType,
    pub cursor: Option<Cursor>,
    pub override_redirect: bool,
    pub type_hint: Option<WindowTypeHint>,
}

impl Default for WindowAttr {
    fn default() -> WindowAttr {
        skip_assert_initialized!();
        WindowAttr {
            title: None,
            event_mask: 0,
            x: None,
            y: None,
            width: 400,
            height: 300,
            wclass: WindowWindowClass::InputOutput,
            visual: None,
            window_type: WindowType::Toplevel,
            cursor: None,
            override_redirect: false,
            type_hint: None,
        }
    }
}

impl WindowAttr {
    fn get_mask(&self) -> u32 {
        let mut mask: gdk_sys::GdkWindowAttributesType = 0;
        if self.title.is_some() {
            mask |= gdk_sys::GDK_WA_TITLE;
        }
        if self.x.is_some() {
            mask |= gdk_sys::GDK_WA_X;
        }
        if self.y.is_some() {
            mask |= gdk_sys::GDK_WA_Y;
        }
        if self.cursor.is_some() {
            mask |= gdk_sys::GDK_WA_CURSOR;
        }
        if self.visual.is_some() {
            mask |= gdk_sys::GDK_WA_VISUAL;
        }
        if self.override_redirect {
            mask |= gdk_sys::GDK_WA_NOREDIR;
        }
        if self.type_hint.is_some() {
            mask |= gdk_sys::GDK_WA_TYPE_HINT;
        }
        mask
    }
}

#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
impl<'a> ToGlibPtr<'a, *mut gdk_sys::GdkWindowAttr> for WindowAttr {
    type Storage = (
        Box<gdk_sys::GdkWindowAttr>,
        Stash<'a, *mut gdk_sys::GdkVisual, Option<Visual>>,
        Stash<'a, *mut gdk_sys::GdkCursor, Option<Cursor>>,
        Stash<'a, *const c_char, Option<String>>,
    );

    fn to_glib_none(&'a self) -> Stash<'a, *mut gdk_sys::GdkWindowAttr, Self> {
        let title = self.title.to_glib_none();
        let visual = self.visual.to_glib_none();
        let cursor = self.cursor.to_glib_none();

        let mut attrs = Box::new(gdk_sys::GdkWindowAttr {
            title: title.0 as *mut c_char,
            event_mask: self.event_mask,
            x: self.x.unwrap_or(0),
            y: self.y.unwrap_or(0),
            width: self.width,
            height: self.height,
            wclass: self.wclass.to_glib(),
            visual: visual.0,
            window_type: self.window_type.to_glib(),
            cursor: cursor.0,
            wmclass_name: ptr::null_mut(),
            wmclass_class: ptr::null_mut(),
            override_redirect: self.override_redirect.to_glib(),
            type_hint: self.type_hint.unwrap_or(WindowTypeHint::Normal).to_glib(),
        });

        Stash(&mut *attrs, (attrs, visual, cursor, title))
    }
}

impl Window {
    pub fn new(parent: Option<&Window>, attributes: &WindowAttr) -> Window {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_full(gdk_sys::gdk_window_new(
                parent.to_glib_none().0,
                attributes.to_glib_none().0,
                attributes.get_mask() as c_int,
            ))
        }
    }

    pub fn create_similar_surface(
        &self,
        content: cairo::Content,
        width: i32,
        height: i32,
    ) -> Option<Surface> {
        unsafe {
            from_glib_full(gdk_sys::gdk_window_create_similar_surface(
                self.to_glib_none().0,
                content.into(),
                width,
                height,
            ))
        }
    }
}

pub trait WindowExtManual: 'static {
    unsafe fn set_user_data<T>(&self, user_data: &mut T);

    #[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))]
    unsafe fn get_user_data<T>(&self) -> &mut T;

    fn get_default_root_window() -> Window;

    fn offscreen_window_set_embedder(&self, embedder: &Window);

    fn offscreen_window_get_embedder(&self) -> Option<Window>;

    fn offscreen_window_get_surface(&self) -> Option<Surface>;

    fn get_pixbuf(
        &self,
        src_x: i32,
        src_y: i32,
        width: i32,
        height: i32,
    ) -> Option<gdk_pixbuf::Pixbuf>;

    fn get_background_pattern(&self) -> Option<cairo::Pattern>;

    fn set_background_pattern(&self, pattern: Option<&cairo::Pattern>);
}

impl<O: IsA<Window>> WindowExtManual for O {
    unsafe fn set_user_data<T>(&self, user_data: &mut T) {
        gdk_sys::gdk_window_set_user_data(
            self.as_ref().to_glib_none().0,
            user_data as *mut T as *mut _,
        )
    }

    unsafe fn get_user_data<T>(&self) -> &mut T {
        let mut pointer = ::std::ptr::null_mut();
        gdk_sys::gdk_window_get_user_data(self.as_ref().to_glib_none().0, &mut pointer);
        &mut *(pointer as *mut T)
    }

    fn get_default_root_window() -> Window {
        assert_initialized_main_thread!();
        unsafe { from_glib_none(gdk_sys::gdk_get_default_root_window()) }
    }

    fn offscreen_window_set_embedder(&self, embedder: &Window) {
        unsafe {
            gdk_sys::gdk_offscreen_window_set_embedder(
                self.as_ref().to_glib_none().0,
                embedder.to_glib_none().0,
            )
        }
    }

    fn offscreen_window_get_embedder(&self) -> Option<Window> {
        unsafe {
            from_glib_none(gdk_sys::gdk_offscreen_window_get_embedder(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn offscreen_window_get_surface(&self) -> Option<Surface> {
        skip_assert_initialized!();
        unsafe {
            from_glib_none(gdk_sys::gdk_offscreen_window_get_surface(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_pixbuf(
        &self,
        src_x: i32,
        src_y: i32,
        width: i32,
        height: i32,
    ) -> Option<gdk_pixbuf::Pixbuf> {
        skip_assert_initialized!();
        unsafe {
            from_glib_full(gdk_sys::gdk_pixbuf_get_from_window(
                self.as_ref().to_glib_none().0,
                src_x,
                src_y,
                width,
                height,
            ))
        }
    }

    fn get_background_pattern(&self) -> Option<cairo::Pattern> {
        unsafe {
            let ret = gdk_sys::gdk_window_get_background_pattern(self.as_ref().to_glib_none().0);
            if ret.is_null() {
                None
            } else {
                Some(cairo::Pattern::from_raw_none(ret))
            }
        }
    }

    fn set_background_pattern(&self, pattern: Option<&cairo::Pattern>) {
        unsafe {
            let ptr = if let Some(pattern) = pattern {
                pattern.to_raw_none()
            } else {
                ::std::ptr::null_mut()
            };
            gdk_sys::gdk_window_set_background_pattern(self.as_ref().to_glib_none().0, ptr);
        }
    }
}
<commit_msg>window: store event_mask using EventMask<commit_after>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use cairo::{self, Surface};
use gdk_pixbuf;
use gdk_sys;
use glib::object::IsA;
use glib::translate::*;
use libc::{c_char, c_int};
use std::ptr;
use Cursor;
use EventMask;
use Visual;
use Window;

use {WindowType, WindowTypeHint, WindowWindowClass};

pub struct WindowAttr {
    pub title: Option<String>,
    pub event_mask: EventMask,
    pub x: Option<i32>,
    pub y: Option<i32>,
    pub width: i32,
    pub height: i32,
    pub wclass: WindowWindowClass,
    pub visual: Option<Visual>,
    pub window_type: WindowType,
    pub cursor: Option<Cursor>,
    pub override_redirect: bool,
    pub type_hint: Option<WindowTypeHint>,
}

impl Default for WindowAttr {
    fn default() -> WindowAttr {
        skip_assert_initialized!();
        WindowAttr {
            title: None,
            event_mask: EventMask::empty(),
            x: None,
            y: None,
            width: 400,
            height: 300,
            wclass: WindowWindowClass::InputOutput,
            visual: None,
            window_type: WindowType::Toplevel,
            cursor: None,
            override_redirect: false,
            type_hint: None,
        }
    }
}

impl WindowAttr {
    fn get_mask(&self) -> u32 {
        let mut mask: gdk_sys::GdkWindowAttributesType = 0;
        if self.title.is_some() {
            mask |= gdk_sys::GDK_WA_TITLE;
        }
        if self.x.is_some() {
            mask |= gdk_sys::GDK_WA_X;
        }
        if self.y.is_some() {
            mask |= gdk_sys::GDK_WA_Y;
        }
        if self.cursor.is_some() {
            mask |= gdk_sys::GDK_WA_CURSOR;
        }
        if self.visual.is_some() {
            mask |= gdk_sys::GDK_WA_VISUAL;
        }
        if self.override_redirect {
            mask |= gdk_sys::GDK_WA_NOREDIR;
        }
        if self.type_hint.is_some() {
            mask |= gdk_sys::GDK_WA_TYPE_HINT;
        }
        mask
    }
}

#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
impl<'a> ToGlibPtr<'a, *mut gdk_sys::GdkWindowAttr> for WindowAttr {
    type Storage = (
        Box<gdk_sys::GdkWindowAttr>,
        Stash<'a, *mut gdk_sys::GdkVisual, Option<Visual>>,
        Stash<'a, *mut gdk_sys::GdkCursor, Option<Cursor>>,
        Stash<'a, *const c_char, Option<String>>,
    );

    fn to_glib_none(&'a self) -> Stash<'a, *mut gdk_sys::GdkWindowAttr, Self> {
        let title = self.title.to_glib_none();
        let visual = self.visual.to_glib_none();
        let cursor = self.cursor.to_glib_none();

        let mut attrs = Box::new(gdk_sys::GdkWindowAttr {
            title: title.0 as *mut c_char,
            event_mask: self.event_mask.bits() as i32,
            x: self.x.unwrap_or(0),
            y: self.y.unwrap_or(0),
            width: self.width,
            height: self.height,
            wclass: self.wclass.to_glib(),
            visual: visual.0,
            window_type: self.window_type.to_glib(),
            cursor: cursor.0,
            wmclass_name: ptr::null_mut(),
            wmclass_class: ptr::null_mut(),
            override_redirect: self.override_redirect.to_glib(),
            type_hint: self.type_hint.unwrap_or(WindowTypeHint::Normal).to_glib(),
        });

        Stash(&mut *attrs, (attrs, visual, cursor, title))
    }
}

impl Window {
    pub fn new(parent: Option<&Window>, attributes: &WindowAttr) -> Window {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_full(gdk_sys::gdk_window_new(
                parent.to_glib_none().0,
                attributes.to_glib_none().0,
                attributes.get_mask() as c_int,
            ))
        }
    }

    pub fn create_similar_surface(
        &self,
        content: cairo::Content,
        width: i32,
        height: i32,
    ) -> Option<Surface> {
        unsafe {
            from_glib_full(gdk_sys::gdk_window_create_similar_surface(
                self.to_glib_none().0,
                content.into(),
                width,
                height,
            ))
        }
    }
}

pub trait WindowExtManual: 'static {
    unsafe fn set_user_data<T>(&self, user_data: &mut T);

    #[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))]
    unsafe fn get_user_data<T>(&self) -> &mut T;

    fn get_default_root_window() -> Window;

    fn offscreen_window_set_embedder(&self, embedder: &Window);

    fn offscreen_window_get_embedder(&self) -> Option<Window>;

    fn offscreen_window_get_surface(&self) -> Option<Surface>;

    fn get_pixbuf(
        &self,
        src_x: i32,
        src_y: i32,
        width: i32,
        height: i32,
    ) -> Option<gdk_pixbuf::Pixbuf>;

    fn get_background_pattern(&self) -> Option<cairo::Pattern>;

    fn set_background_pattern(&self, pattern: Option<&cairo::Pattern>);
}

impl<O: IsA<Window>> WindowExtManual for O {
    unsafe fn set_user_data<T>(&self, user_data: &mut T) {
        gdk_sys::gdk_window_set_user_data(
            self.as_ref().to_glib_none().0,
            user_data as *mut T as *mut _,
        )
    }

    unsafe fn get_user_data<T>(&self) -> &mut T {
        let mut pointer = ::std::ptr::null_mut();
        gdk_sys::gdk_window_get_user_data(self.as_ref().to_glib_none().0, &mut pointer);
        &mut *(pointer as *mut T)
    }

    fn get_default_root_window() -> Window {
        assert_initialized_main_thread!();
        unsafe { from_glib_none(gdk_sys::gdk_get_default_root_window()) }
    }

    fn offscreen_window_set_embedder(&self, embedder: &Window) {
        unsafe {
            gdk_sys::gdk_offscreen_window_set_embedder(
                self.as_ref().to_glib_none().0,
                embedder.to_glib_none().0,
            )
        }
    }

    fn offscreen_window_get_embedder(&self) -> Option<Window> {
        unsafe {
            from_glib_none(gdk_sys::gdk_offscreen_window_get_embedder(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn offscreen_window_get_surface(&self) -> Option<Surface> {
        skip_assert_initialized!();
        unsafe {
            from_glib_none(gdk_sys::gdk_offscreen_window_get_surface(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_pixbuf(
        &self,
        src_x: i32,
        src_y: i32,
        width: i32,
        height: i32,
    ) -> Option<gdk_pixbuf::Pixbuf> {
        skip_assert_initialized!();
        unsafe {
            from_glib_full(gdk_sys::gdk_pixbuf_get_from_window(
                self.as_ref().to_glib_none().0,
                src_x,
                src_y,
                width,
                height,
            ))
        }
    }

    fn get_background_pattern(&self) -> Option<cairo::Pattern> {
        unsafe {
            let ret = gdk_sys::gdk_window_get_background_pattern(self.as_ref().to_glib_none().0);
            if ret.is_null() {
                None
            } else {
                Some(cairo::Pattern::from_raw_none(ret))
            }
        }
    }

    fn set_background_pattern(&self, pattern: Option<&cairo::Pattern>) {
        unsafe {
            let ptr = if let Some(pattern) = pattern {
                pattern.to_raw_none()
            } else {
                ::std::ptr::null_mut()
            };
            gdk_sys::gdk_window_set_background_pattern(self.as_ref().to_glib_none().0, ptr);
        }
    }
}
<|endoftext|>


<commit_before>use crate::database::Database;
use crate::routes::{courses, courses2, index, login, swagger};
use crate::session::Auth;

use actix_cors::Cors;
use actix_session::CookieSession;
use actix_web::{
    http::header,
    middleware::{Compress, Logger},
    App, HttpServer,
};
use std::sync::Arc;

mod data;

pub use data::*;

pub struct Server;

impl Server {
    pub fn start(database: Arc<Database>) -> std::io::Result<()> {
        std::env::set_var("RUST_LOG", "actix_web=debug");
        env_logger::init();
        let data = Arc::new(Data::new(database));

        HttpServer::new(move || {
            App::new()
                .data(data.clone())
                .service(courses::service())
                .service(courses2::service())
                .service(login::service())
                .service(swagger)
                .service(index)
                .wrap(Auth)
                .wrap(
                    CookieSession::signed(&[0; 32])
                        .name("smmdb")
                        .path("/")
                        .max_age(3600 * 24 * 7)
                        .secure(false),
                )
                .wrap(
                    Cors::new()
                        .allowed_methods(vec!["GET", "POST", "PUT", "OPTIONS"])
                        .allowed_headers(vec![
                            header::AUTHORIZATION,
                            header::ACCEPT,
                            header::CONTENT_TYPE,
                        ])
                        .supports_credentials()
                        .max_age(3600),
                )
                .wrap(Compress::default())
                .wrap(Logger::default())
        })
        .bind("0.0.0.0:3030")?
        .workers(num_cpus::get())
        .run()
    }
}
<commit_msg>fix delete cors<commit_after>use crate::database::Database;
use crate::routes::{courses, courses2, index, login, swagger};
use crate::session::Auth;

use actix_cors::Cors;
use actix_session::CookieSession;
use actix_web::{
    http::header,
    middleware::{Compress, Logger},
    App, HttpServer,
};
use std::sync::Arc;

mod data;

pub use data::*;

pub struct Server;

impl Server {
    pub fn start(database: Arc<Database>) -> std::io::Result<()> {
        std::env::set_var("RUST_LOG", "actix_web=debug");
        env_logger::init();
        let data = Arc::new(Data::new(database));

        HttpServer::new(move || {
            App::new()
                .data(data.clone())
                .service(courses::service())
                .service(courses2::service())
                .service(login::service())
                .service(swagger)
                .service(index)
                .wrap(Auth)
                .wrap(
                    CookieSession::signed(&[0; 32])
                        .name("smmdb")
                        .path("/")
                        .max_age(3600 * 24 * 7)
                        .secure(false),
                )
                .wrap(
                    Cors::new()
                        .allowed_methods(vec!["GET", "POST", "PUT", "OPTIONS", "DELETE"])
                        .allowed_headers(vec![
                            header::AUTHORIZATION,
                            header::ACCEPT,
                            header::CONTENT_TYPE,
                        ])
                        .supports_credentials()
                        .max_age(3600),
                )
                .wrap(Compress::default())
                .wrap(Logger::default())
        })
        .bind("0.0.0.0:3030")?
        .workers(num_cpus::get())
        .run()
    }
}
<|endoftext|>