<commit_before>//! Server-side Wayland connector
//!
//! # Overview
//!
//! Setting up the listening socket is done by the `create_display`
//! function, providing you a `Display` object and an `EventLoop`.
//!
//! On the event loop, you'll be able to register the globals
//! you want to advertize, as well as handlers for all ressources
//! created by the clients.
//!
//! You then integrate the wayland event loop in your main event
//! loop to run your compositor.
//!
//! # Handlers and event loop
//!
//! This crate mirrors the callback-oriented design of the
//! Wayland C library by using handler structs: each wayland
//! type defines a `Handler` trait in its module, which one
//! method for each possible requests this object can receive.
//!
//! To use it, you need to build a struct (or enum) that will
//! implement all the traits for all the requests you are interested
//! in. All methods of handler traits provide a default
//! implementation foing nothing, so you don't need to write
//! empty methods for events you want to ignore. You also need
//! to declare the handler capability for your struct using
//! the `declare_handler!(..)` macro. A single struct can be
//! handler for several wayland interfaces at once.
//!
//! ## Example of handler
//!
//! ```ignore
//! /*  writing a handler for an wl_foo interface */
//! // import the module of this interface
//! use wl_foo;
//!
//! struct MyHandler { /* some fields to store state */ }
//!
//! // implement handerl trait:
//! impl wl_foo::Handler for MyHandler {
//!     fn a_request(&mut self,
//!                  evlh: &mut EventLoopHandle,
//!                  client: &Client,
//!                  me: &wl_foo::WlFoo,
//!                  arg1, arg2, // the actual args of the request
//!     ) {
//!         /* handle the request */
//!     }
//! }
//!
//! // declare the handler capability
//! // this boring step is necessary because Rust's type system is
//! // not yet magical enough
//! declare_handler!(MyHandler, wl_foo::Handler, wl_foo::WlFoo);
//! ```
//!
//! ## Event Loop and handlers
//!
//! In your initialization code, you'll need to instanciate
//! your handler and give it to the event queue:
//!
//! ```ignore
//! let handler_id = event_loop.add_handler(MyHandler::new());
//! ```
//!
//! Then, you can register your wayland objects to this handler:
//!
//! ```ignore
//! // This type info is necessary for safety, as at registration
//! // time the event_loop will check that the handler you
//! // specified using handler_id has the same type as provided
//! // as argument, and that this type implements the appropriate
//! // handler trait.
//! event_loop.register::<_, MyHandler>(&my_object, handler_id);
//! ```
//!
//! You can have several handlers in the same event loop,
//! but they cannot share their state without synchronisation
//! primitives like `Arc`, `Mutex` and friends, so if two handlers
//! need to share some state, you should consider building them
//! as a single struct.
//!
//! A given wayland object can only be registered to a single
//! handler at a given time, re-registering it to a new handler
//! will overwrite the previous configuration.
//!
//! Handlers can be created, and objects registered to them
//! from within a handler method, using the `&EventLoopHandle`
//! argument.
//!
//! ## Globals declaration
//!
//! Declaring a global is quite similar to declaring a handler
//! for a ressource. But this time via the `GlobalHandler<R>` trait.
//!
//! This trait declares a single method, `bind`, which is called
//! whenever a client binds this global, providing you with
//! a ressource object representing the newly-created global.
//!
//! You can do what you please with this object, storing it for
//! later if you'll need to send it events, or just let it go
//! go out of scope after having registered it to the appropriate
//! handler.
//!
//! To register globals on the event loop, you need the
//! `register_global` method:
//!
//! ```ignore
//! struct MyHandler { /* ... */ }
//!
//! // creating a handler for the global wl_foo
//! impl GlobalHandler<WlFoo> for MyHandler {
//!     fn bind(&mut self,
//!             evlh: &mut EventLoopHandle,
//!             client: &Client,
//!             global: WlFoo
//!     ) {
//!         /* do something with it */
//!     }
//! }
//!
//! /* ... */
//!
//! // then somewhere in the initialization code
//! let handler_id = event_loop.add_handler(MyHandler::new());
//! // bind this handler to a global for interface wl_foo version 3
//! // specifying the types is mandatory, and compability of this
//! // handler with the global is checked at registration time.
//! let foo = event_loop.register_global::<WlFoo, MyHandler>(handler_is, 3);
//! // foo contains a handle to the global, that you can use later
//! // to destroy it:
//! foo.destroy();
//! // if you don't plan to ever destroy this global, you can ignore
//! // this return value, letting it out of scope will not destroy
//! // the global.
//! ```
//!
//! ## Event loop integration
//!
//! Once the setup phase is done, you can integrate the
//! event loop in the main event loop of your program.
//!
//! Either all you need is for it to run indefinitely (external
//! events are checked in an other thread?):
//!
//! ```ignore
//! event_loop.run();
//! ```
//!
//! Or you can integrate it with more control:
//!
//! ```ignore
//! loop {
//!     // flush events to client sockets
//!     display.flush_clients();
//!     // receive request from clients and dispatch them
//!     // blocking if no request is pending for at most
//!     // 10ms
//!     event_loop.dispatch(Some(10)).unwrap();
//!     // then you can check events from other sources if
//!     // you need to
//! }
//! ```
//!
//! # Protocols integration
//!
//! This crate provides the basic primitives as well as the
//! core wayland protocol (in the `protocol` module), but
//! other protocols can be integrated from XML descriptions.
//!
//! The the crate `wayland_scanner` and its documentation for
//! details about how to do so.

#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
#[macro_use] extern crate wayland_sys;
extern crate libc;

pub use generated::server as protocol;
pub use generated::interfaces as protocol_interfaces;

pub use client::Client;
pub use display::{Display, create_display};
pub use event_loop::{EventLoop, EventLoopHandle, StateGuard, Global, GlobalHandler, Init, Destroy,
                     resource_is_registered};

use wayland_sys::server::wl_resource;
use wayland_sys::common::{wl_interface, wl_argument};

mod client;
mod display;
mod event_loop;

/// Common routines for wayland resource objects.
///
/// All wayland objects automatically implement this trait
/// as generated by the scanner.
///
/// It is mostly used for internal use by the library, and you
/// should only need these methods for interfacing with C library
/// working on wayland objects.
pub trait Resource {
    /// Pointer to the underlying wayland proxy object
    fn ptr(&self) -> *mut wl_resource;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland resource
    /// of the appropriate interface, but that have not yet
    /// been seen by the library.
    ///
    /// The library will take control of the object (notably
    /// overwrite its user_data).
    unsafe fn from_ptr_new(*mut wl_resource) -> Self;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland resource
    /// of the appropriate interface, and have already been
    /// initialized by the library (it'll assume this proxy
    /// user_data contains a certain kind of data).
    unsafe fn from_ptr_initialized(*mut wl_resource) -> Self;
    /// Pointer to the interface representation
    fn interface_ptr() -> *const wl_interface;
    /// Internal wayland name of this interface
    fn interface_name() -> &'static str;
    /// Max version of this interface supported
    fn supported_version() -> u32;
    /// Current version of the interface this resource is instanciated with
    fn version(&self) -> i32;
    /// Check if the resource behind this handle is actually still alive
    fn is_alive(&self) -> bool;
    /// Check of two handles are actually the same wayland object
    ///
    /// Returns `false` if any of the objects has already been destroyed
    fn equals(&self, &Self) -> bool;
    /// Set a pointer associated as user data on this resource
    ///
    /// All handles to the same wayland object share the same user data pointer.
    ///
    /// The get/set operations are atomic, no more guarantee is given. If you need
    /// to synchronise access to this data, it is your responsibility to add a Mutex
    /// or any other similar mechanism.
    fn set_user_data(&self, ptr: *mut ());
    /// Get the pointer associated as user data on this resource
    ///
    /// All handles to the same wayland object share the same user data pointer.
    ///
    /// See `set_user_data` for synchronisation guarantee.
    fn get_user_data(&self) -> *mut ();
}

/// Possible outcome of the call of a event on a resource
pub enum EventResult<T> {
    /// Message has been buffered and will be sent to client
    Sent(T),
    /// This resource is already destroyed, request has been ignored
    Destroyed
}

impl<T> EventResult<T> {
    /// Assert that result is successfull and extract the value.
    ///
    /// Panics with provided error message if the result was `Destroyed`.
    pub fn expect(self, error: &str) -> T {
        match self {
            EventResult::Sent(v) => v,
            EventResult::Destroyed => panic!("{}", error)
        }
    }
}

/// Generic handler trait
///
/// This trait is automatically implemented for objects that implement
/// the appropriate interface-specific `Handler` traits. It represents
/// the hability for a type to handle events directed to a given wayland
/// interface.
///
/// For example, implementing `wl_surface::Handler` for you type will
/// automatically provide it with an implementation of
/// `Handler<WlSurface>` as well. This is the only correct way
/// to implement this trait, and you should not attempt to implement it
/// yourself.
pub unsafe trait Handler<T: Resource> {
    /// Dispatch a message.
    unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &T, opcode: u32, args: *const wl_argument) -> Result<(),()>;
}

mod generated {
    #![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
    #![allow(non_upper_case_globals,non_snake_case,unused_imports)]
    #![allow(missing_docs)]

    pub mod interfaces {
        //! Interfaces for the core protocol
        //!
        //! You might need them for the bindings generated for protocol extensions
        include!(concat!(env!("OUT_DIR"), "/wayland_interfaces.rs"));
    }

    pub mod server {
        //! The wayland core protocol
        //!
        //! This module contains all objects of the core wayland protocol.
        //!
        //! It has been generated from the `wayland.xml` protocol file
        //! using `wayland_scanner`.
        // Imports that need to be available to submodules
        // but should not be in public API.
        // Will be fixable with pub(restricted).
        #[doc(hidden)] pub use {Resource, EventLoopHandle, Handler, Client, EventResult};
        #[doc(hidden)] pub use super::interfaces;

        include!(concat!(env!("OUT_DIR"), "/wayland_api.rs"));
    }
}

pub mod sys {
    //! Reexports of types and objects from wayland-sys
    pub use wayland_sys::server::*;
    pub use wayland_sys::common::*;
}
<commit_msg>server: add Resource::prox_error()<commit_after>//! Server-side Wayland connector
//!
//! # Overview
//!
//! Setting up the listening socket is done by the `create_display`
//! function, providing you a `Display` object and an `EventLoop`.
//!
//! On the event loop, you'll be able to register the globals
//! you want to advertize, as well as handlers for all ressources
//! created by the clients.
//!
//! You then integrate the wayland event loop in your main event
//! loop to run your compositor.
//!
//! # Handlers and event loop
//!
//! This crate mirrors the callback-oriented design of the
//! Wayland C library by using handler structs: each wayland
//! type defines a `Handler` trait in its module, which one
//! method for each possible requests this object can receive.
//!
//! To use it, you need to build a struct (or enum) that will
//! implement all the traits for all the requests you are interested
//! in. All methods of handler traits provide a default
//! implementation foing nothing, so you don't need to write
//! empty methods for events you want to ignore. You also need
//! to declare the handler capability for your struct using
//! the `declare_handler!(..)` macro. A single struct can be
//! handler for several wayland interfaces at once.
//!
//! ## Example of handler
//!
//! ```ignore
//! /*  writing a handler for an wl_foo interface */
//! // import the module of this interface
//! use wl_foo;
//!
//! struct MyHandler { /* some fields to store state */ }
//!
//! // implement handerl trait:
//! impl wl_foo::Handler for MyHandler {
//!     fn a_request(&mut self,
//!                  evlh: &mut EventLoopHandle,
//!                  client: &Client,
//!                  me: &wl_foo::WlFoo,
//!                  arg1, arg2, // the actual args of the request
//!     ) {
//!         /* handle the request */
//!     }
//! }
//!
//! // declare the handler capability
//! // this boring step is necessary because Rust's type system is
//! // not yet magical enough
//! declare_handler!(MyHandler, wl_foo::Handler, wl_foo::WlFoo);
//! ```
//!
//! ## Event Loop and handlers
//!
//! In your initialization code, you'll need to instanciate
//! your handler and give it to the event queue:
//!
//! ```ignore
//! let handler_id = event_loop.add_handler(MyHandler::new());
//! ```
//!
//! Then, you can register your wayland objects to this handler:
//!
//! ```ignore
//! // This type info is necessary for safety, as at registration
//! // time the event_loop will check that the handler you
//! // specified using handler_id has the same type as provided
//! // as argument, and that this type implements the appropriate
//! // handler trait.
//! event_loop.register::<_, MyHandler>(&my_object, handler_id);
//! ```
//!
//! You can have several handlers in the same event loop,
//! but they cannot share their state without synchronisation
//! primitives like `Arc`, `Mutex` and friends, so if two handlers
//! need to share some state, you should consider building them
//! as a single struct.
//!
//! A given wayland object can only be registered to a single
//! handler at a given time, re-registering it to a new handler
//! will overwrite the previous configuration.
//!
//! Handlers can be created, and objects registered to them
//! from within a handler method, using the `&EventLoopHandle`
//! argument.
//!
//! ## Globals declaration
//!
//! Declaring a global is quite similar to declaring a handler
//! for a ressource. But this time via the `GlobalHandler<R>` trait.
//!
//! This trait declares a single method, `bind`, which is called
//! whenever a client binds this global, providing you with
//! a ressource object representing the newly-created global.
//!
//! You can do what you please with this object, storing it for
//! later if you'll need to send it events, or just let it go
//! go out of scope after having registered it to the appropriate
//! handler.
//!
//! To register globals on the event loop, you need the
//! `register_global` method:
//!
//! ```ignore
//! struct MyHandler { /* ... */ }
//!
//! // creating a handler for the global wl_foo
//! impl GlobalHandler<WlFoo> for MyHandler {
//!     fn bind(&mut self,
//!             evlh: &mut EventLoopHandle,
//!             client: &Client,
//!             global: WlFoo
//!     ) {
//!         /* do something with it */
//!     }
//! }
//!
//! /* ... */
//!
//! // then somewhere in the initialization code
//! let handler_id = event_loop.add_handler(MyHandler::new());
//! // bind this handler to a global for interface wl_foo version 3
//! // specifying the types is mandatory, and compability of this
//! // handler with the global is checked at registration time.
//! let foo = event_loop.register_global::<WlFoo, MyHandler>(handler_is, 3);
//! // foo contains a handle to the global, that you can use later
//! // to destroy it:
//! foo.destroy();
//! // if you don't plan to ever destroy this global, you can ignore
//! // this return value, letting it out of scope will not destroy
//! // the global.
//! ```
//!
//! ## Event loop integration
//!
//! Once the setup phase is done, you can integrate the
//! event loop in the main event loop of your program.
//!
//! Either all you need is for it to run indefinitely (external
//! events are checked in an other thread?):
//!
//! ```ignore
//! event_loop.run();
//! ```
//!
//! Or you can integrate it with more control:
//!
//! ```ignore
//! loop {
//!     // flush events to client sockets
//!     display.flush_clients();
//!     // receive request from clients and dispatch them
//!     // blocking if no request is pending for at most
//!     // 10ms
//!     event_loop.dispatch(Some(10)).unwrap();
//!     // then you can check events from other sources if
//!     // you need to
//! }
//! ```
//!
//! # Protocols integration
//!
//! This crate provides the basic primitives as well as the
//! core wayland protocol (in the `protocol` module), but
//! other protocols can be integrated from XML descriptions.
//!
//! The the crate `wayland_scanner` and its documentation for
//! details about how to do so.

#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
#[macro_use] extern crate wayland_sys;
extern crate libc;

pub use generated::server as protocol;
pub use generated::interfaces as protocol_interfaces;

pub use client::Client;
pub use display::{Display, create_display};
pub use event_loop::{EventLoop, EventLoopHandle, StateGuard, Global, GlobalHandler, Init, Destroy,
                     resource_is_registered};

use wayland_sys::server::*;
use wayland_sys::common::{wl_interface, wl_argument};

mod client;
mod display;
mod event_loop;

/// Common routines for wayland resource objects.
///
/// All wayland objects automatically implement this trait
/// as generated by the scanner.
///
/// It is mostly used for internal use by the library, and you
/// should only need these methods for interfacing with C library
/// working on wayland objects.
pub trait Resource {
    /// Pointer to the underlying wayland proxy object
    fn ptr(&self) -> *mut wl_resource;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland resource
    /// of the appropriate interface, but that have not yet
    /// been seen by the library.
    ///
    /// The library will take control of the object (notably
    /// overwrite its user_data).
    unsafe fn from_ptr_new(*mut wl_resource) -> Self;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland resource
    /// of the appropriate interface, and have already been
    /// initialized by the library (it'll assume this proxy
    /// user_data contains a certain kind of data).
    unsafe fn from_ptr_initialized(*mut wl_resource) -> Self;
    /// Pointer to the interface representation
    fn interface_ptr() -> *const wl_interface;
    /// Internal wayland name of this interface
    fn interface_name() -> &'static str;
    /// Max version of this interface supported
    fn supported_version() -> u32;
    /// Current version of the interface this resource is instanciated with
    fn version(&self) -> i32;
    /// Check if the resource behind this handle is actually still alive
    fn is_alive(&self) -> bool;
    /// Check of two handles are actually the same wayland object
    ///
    /// Returns `false` if any of the objects has already been destroyed
    fn equals(&self, &Self) -> bool;
    /// Set a pointer associated as user data on this resource
    ///
    /// All handles to the same wayland object share the same user data pointer.
    ///
    /// The get/set operations are atomic, no more guarantee is given. If you need
    /// to synchronise access to this data, it is your responsibility to add a Mutex
    /// or any other similar mechanism.
    fn set_user_data(&self, ptr: *mut ());
    /// Get the pointer associated as user data on this resource
    ///
    /// All handles to the same wayland object share the same user data pointer.
    ///
    /// See `set_user_data` for synchronisation guarantee.
    fn get_user_data(&self) -> *mut ();
    /// Posts a protocol error to this resource
    ///
    /// The error code can be obtained from the various `Error` enums of the protocols.
    ///
    /// An error is fatal to the client that caused it.
    fn post_error(&self, error_code: u32, msg: String) {
        // If `str` contains an interior null, the actuall transmitted message will
        // be truncated at this point.
        unsafe {
            let cstring = ::std::ffi::CString::from_vec_unchecked(msg.into());
            ffi_dispatch!(
                WAYLAND_SERVER_HANDLE,
                wl_resource_post_error,
                self.ptr(),
                error_code,
                cstring.as_ptr()
            )
        }
    }
}

/// Possible outcome of the call of a event on a resource
pub enum EventResult<T> {
    /// Message has been buffered and will be sent to client
    Sent(T),
    /// This resource is already destroyed, request has been ignored
    Destroyed
}

impl<T> EventResult<T> {
    /// Assert that result is successfull and extract the value.
    ///
    /// Panics with provided error message if the result was `Destroyed`.
    pub fn expect(self, error: &str) -> T {
        match self {
            EventResult::Sent(v) => v,
            EventResult::Destroyed => panic!("{}", error)
        }
    }
}

/// Generic handler trait
///
/// This trait is automatically implemented for objects that implement
/// the appropriate interface-specific `Handler` traits. It represents
/// the hability for a type to handle events directed to a given wayland
/// interface.
///
/// For example, implementing `wl_surface::Handler` for you type will
/// automatically provide it with an implementation of
/// `Handler<WlSurface>` as well. This is the only correct way
/// to implement this trait, and you should not attempt to implement it
/// yourself.
pub unsafe trait Handler<T: Resource> {
    /// Dispatch a message.
    unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &T, opcode: u32, args: *const wl_argument) -> Result<(),()>;
}

mod generated {
    #![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
    #![allow(non_upper_case_globals,non_snake_case,unused_imports)]
    #![allow(missing_docs)]

    pub mod interfaces {
        //! Interfaces for the core protocol
        //!
        //! You might need them for the bindings generated for protocol extensions
        include!(concat!(env!("OUT_DIR"), "/wayland_interfaces.rs"));
    }

    pub mod server {
        //! The wayland core protocol
        //!
        //! This module contains all objects of the core wayland protocol.
        //!
        //! It has been generated from the `wayland.xml` protocol file
        //! using `wayland_scanner`.
        // Imports that need to be available to submodules
        // but should not be in public API.
        // Will be fixable with pub(restricted).
        #[doc(hidden)] pub use {Resource, EventLoopHandle, Handler, Client, EventResult};
        #[doc(hidden)] pub use super::interfaces;

        include!(concat!(env!("OUT_DIR"), "/wayland_api.rs"));
    }
}

pub mod sys {
    //! Reexports of types and objects from wayland-sys
    pub use wayland_sys::server::*;
    pub use wayland_sys::common::*;
}
<|endoftext|>


<commit_before>//! A lock-free stack which supports concurrent pushes and a concurrent call to
//! drain the entire stack all at once.

use std::prelude::v1::*;

use std::sync::atomic::AtomicUsize;
use std::mem;
use std::marker;
use std::sync::atomic::Ordering::SeqCst;

use task::EventSet;

pub struct Stack<T> {
    head: AtomicUsize,
    _marker: marker::PhantomData<T>,
}

struct Node<T> {
    data: T,
    next: *mut Node<T>,
}

pub struct Drain<T> {
    head: *mut Node<T>,
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            head: AtomicUsize::new(0),
            _marker: marker::PhantomData,
        }
    }

    pub fn push(&self, data: T) {
        let mut node = Box::new(Node { data: data, next: 0 as *mut _ });
        let mut head = self.head.load(SeqCst);
        loop {
            node.next = head as *mut _;
            let ptr = &*node as *const Node<T> as usize;
            match self.head.compare_exchange(head, ptr, SeqCst, SeqCst) {
                Ok(_) => {
                    mem::forget(node);
                    return
                }
                Err(cur) => head = cur,
            }
        }
    }

    pub fn drain(&self) -> Drain<T> {
        Drain {
            head: self.head.swap(0, SeqCst) as *mut _,
        }
    }
}

impl<T> Drop for Stack<T> {
    fn drop(&mut self) {
        self.drain();
    }
}

impl<T> Iterator for Drain<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        if self.head.is_null() {
            return None
        }
        unsafe {
            let node = Box::from_raw(self.head);
            self.head = node.next;
            return Some(node.data)
        }
    }
}

impl<T> Drop for Drain<T> {
    fn drop(&mut self) {
        for item in self.by_ref() {
            drop(item);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;
    use std::rc::Rc;
    use std::cell::Cell;

    use super::Stack;

    struct Set(Rc<Cell<usize>>, usize);

    impl Drop for Set {
        fn drop(&mut self) {
            self.0.set(self.1);
        }
    }

    #[test]
    fn simple() {
        let s = Stack::new();
        s.push(1);
        s.push(2);
        s.push(4);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![4, 2, 1]);
        s.push(5);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![5]);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![]);
    }

    #[test]
    fn drain_drops() {
        let data = Rc::new(Cell::new(0));
        let s = Stack::new();
        s.push(Set(data.clone(), 1));
        drop(s.drain());
        assert_eq!(data.get(), 1);
    }

    #[test]
    fn drop_drops() {
        let data = Rc::new(Cell::new(0));
        let s = Stack::new();
        s.push(Set(data.clone(), 1));
        drop(s);
        assert_eq!(data.get(), 1);
    }
}

impl EventSet for Stack<usize> {
    fn insert(&self, id: usize) {
        self.push(id);
    }
}
<commit_msg>Add Send/Sync impls to Drain<T><commit_after>//! A lock-free stack which supports concurrent pushes and a concurrent call to
//! drain the entire stack all at once.

use std::prelude::v1::*;

use std::sync::atomic::AtomicUsize;
use std::mem;
use std::marker;
use std::sync::atomic::Ordering::SeqCst;

use task::EventSet;

pub struct Stack<T> {
    head: AtomicUsize,
    _marker: marker::PhantomData<T>,
}

struct Node<T> {
    data: T,
    next: *mut Node<T>,
}

pub struct Drain<T> {
    head: *mut Node<T>,
}

unsafe impl<T: Send> Send for Drain<T> {}
unsafe impl<T: Sync> Sync for Drain<T> {}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack {
            head: AtomicUsize::new(0),
            _marker: marker::PhantomData,
        }
    }

    pub fn push(&self, data: T) {
        let mut node = Box::new(Node { data: data, next: 0 as *mut _ });
        let mut head = self.head.load(SeqCst);
        loop {
            node.next = head as *mut _;
            let ptr = &*node as *const Node<T> as usize;
            match self.head.compare_exchange(head, ptr, SeqCst, SeqCst) {
                Ok(_) => {
                    mem::forget(node);
                    return
                }
                Err(cur) => head = cur,
            }
        }
    }

    pub fn drain(&self) -> Drain<T> {
        Drain {
            head: self.head.swap(0, SeqCst) as *mut _,
        }
    }
}

impl<T> Drop for Stack<T> {
    fn drop(&mut self) {
        self.drain();
    }
}

impl<T> Iterator for Drain<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        if self.head.is_null() {
            return None
        }
        unsafe {
            let node = Box::from_raw(self.head);
            self.head = node.next;
            return Some(node.data)
        }
    }
}

impl<T> Drop for Drain<T> {
    fn drop(&mut self) {
        for item in self.by_ref() {
            drop(item);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;
    use std::rc::Rc;
    use std::cell::Cell;

    use super::Stack;

    struct Set(Rc<Cell<usize>>, usize);

    impl Drop for Set {
        fn drop(&mut self) {
            self.0.set(self.1);
        }
    }

    #[test]
    fn simple() {
        let s = Stack::new();
        s.push(1);
        s.push(2);
        s.push(4);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![4, 2, 1]);
        s.push(5);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![5]);
        assert_eq!(s.drain().collect::<Vec<_>>(), vec![]);
    }

    #[test]
    fn drain_drops() {
        let data = Rc::new(Cell::new(0));
        let s = Stack::new();
        s.push(Set(data.clone(), 1));
        drop(s.drain());
        assert_eq!(data.get(), 1);
    }

    #[test]
    fn drop_drops() {
        let data = Rc::new(Cell::new(0));
        let s = Stack::new();
        s.push(Set(data.clone(), 1));
        drop(s);
        assert_eq!(data.get(), 1);
    }
}

impl EventSet for Stack<usize> {
    fn insert(&self, id: usize) {
        self.push(id);
    }
}
<|endoftext|>


<commit_before>
use std::sync::Mutex;
use std::ptr;
use rand;
use rand::distributions::{IndependentSample, Range};
use std::f32::consts;

#[derive(Clone, Copy)]
struct Particle {
    px : f32,
    py : f32,
    vx : f32,
    vy : f32,
    m  : f32
}

lazy_static! {
    static ref PARTICLES: Mutex<Vec<Particle>> = {
        Mutex::new(Vec::new())
    };
}

#[no_mangle]
pub extern fn nb_random_disk(num_particles: i32) -> () {
    // Place particles with random position and velocity in a disk in the center of the viewport

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let mut rng = rand::thread_rng();
    let vel  = Range::new(-3.5, 3.5);
    let mass = Range::new( 0.1, 1.5);
    let u    = Range::new( 0.0, 1.0);

    for _ in 0..num_particles {
        let mut x : f32 = u.ind_sample(&mut rng);
        let mut y : f32 = u.ind_sample(&mut rng);
        uniform_sample_disk(&mut x, &mut y);
        x *= 20.0;
        y *= 20.0;

        particles.push(Particle { px: x,
                                  py: y,
                                  vx: vel.ind_sample(&mut rng),
                                  vy: vel.ind_sample(&mut rng),
                                  m:  mass.ind_sample(&mut rng) });
    }
}

fn uniform_sample_disk(x: &mut f32, y: &mut f32) {
    let r = x.sqrt();
    let theta = 2.0 * consts::PI * (* y);
    * x = r * theta.cos();
    * y = r * theta.sin();
}

#[no_mangle]
pub extern fn nb_stable_orbits(num_particles: i32, rmin: f32, rmax: f32) -> () {
    // Generate a bunch of 'planets' with a circular orbit around a 'sun'
    //
    // References:
    //
    // http://www.cs.cmu.edu/~./ph/859E/src/nbody/circ.p2
    // www.cs.cmu.edu/~./ph/859E/src/nbody/nbody.cc

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let sun_mass    = 1000.0;
    let planet_mass = 1.0;
    let g : f32     = 1.0;
    let speed       = (g * sun_mass).sqrt();

    let mut rng     = rand::thread_rng();
    let u           = Range::new(0.0, 1.0);

    particles.push( Particle { px: 0.0, py: 0.0, vx: 0.0, vy: 0.0, m: sun_mass } );

    for _ in 0..num_particles {
        let r     = (rmax - rmin) * u.ind_sample(&mut rng) + rmin;
        let theta = 2.0 * consts::PI * u.ind_sample(&mut rng);
        particles.push( Particle { px: r * theta.cos(),
                                   py: r * theta.sin(),
                                   vx: -speed * theta.sin(),
                                   vy:  speed * theta.cos(),
                                   m: planet_mass });
    }
}

#[no_mangle]
pub extern fn nb_step(dt : f32) -> () {
    let mut particles_mtx = PARTICLES.lock().unwrap();

    // Compute forces
    let forces;
    {
        let particles = &(* particles_mtx);

        #[derive(Clone)]
        struct Force {
            fx : f32,
            fy : f32
        }
        let mut mforces = Vec::new();
        mforces.resize(particles.len(), Force { fx: 0.0, fy: 0.0 });

        for i in 0..particles.len() {
            let a = &particles[i];

            for j in 0..particles.len() {
                if i == j { continue; }

                let b = &particles[j];

                let dx = b.px - a.px;
                let dy = b.py - a.py;
                let dist = (dx * dx + dy * dy).sqrt();

                let eps = 0.0001; // Softening factor, prevent singularities
                let f = a.m * b.m / (dist * dist + eps);

                mforces[i].fx += f * dx; // / dist;
                mforces[i].fy += f * dy; // / dist;
            }
        }

        forces = mforces;
    }

    // Update positions and velocities
    {
        let mut particles = &mut (* particles_mtx);

        for i in 0..particles.len() {
            particles[i].vx += dt * forces[i].fx / particles[i].m;
            particles[i].vy += dt * forces[i].fy / particles[i].m;

            particles[i].px += dt * particles[i].vx;
            particles[i].py += dt * particles[i].vy;
        }
    }
}

#[no_mangle]
pub extern fn nb_draw(w: i32, h: i32, fb: *mut u32) -> () {
    // If writing scattered points to write combined memory turns out to be a problem,
    // enabled buffering
    let buffer = false;

    if !buffer {
        // Clear background
        unsafe { ptr::write_bytes(fb, 0, (w * h) as usize); }
    }

    // Specify viewport over simulation to be mapped to the framebuffer
    let vp_wdh   = 100.0;
    let vp_org_x = 0.0;
    let vp_org_y = 0.0;

    // Keep full width of the viewport visible, adjust height as needed
    let aspect = h as f32 / w as f32;

    // Framebuffer viewport in simulation dimensions
    let x1 =  vp_org_x - vp_wdh / 2.0;
    let y1 = (vp_org_y - vp_wdh / 2.0) * aspect;
    let x2 =  vp_org_x + vp_wdh / 2.0;
    let y2 = (vp_org_y + vp_wdh / 2.0) * aspect;

    // Scale factor for translating from simulation to framebuffer
    let vpw    = x2 - x1;
    let vph    = y2 - y1;
    let scalex = (1.0 / vpw) * w as f32;
    let scaley = (1.0 / vph) * h as f32;

    // Optionally allocate buffer
    let buf_ptr;
    if buffer {
        let mut buf = Vec::new();
        buf.resize((w * h) as usize, 0u32);
        buf_ptr = buf.as_mut_ptr();
    } else {
        buf_ptr = fb;
    }

    let particles = PARTICLES.lock().unwrap();
    for p in &(*particles) {
        // Translate from simulation to viewport coordinates
        let x = ((p.px - x1) * scalex) as i32;
        let y = ((p.py - y1) * scaley) as i32;

        // Bounds check
        if x < 0 || x >= w || y < 0 || y >= h { continue; }

        // Draw particle
        let idx = x + y * w;
        unsafe {
            * buf_ptr.offset(idx as isize) = 0x00FFFFFF;
        }
    }

    // Debug draw center cross
    unsafe {
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 1) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 - 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 - 1) * w) as isize) = 0x00FF00FF;
    }

    // Output in one contiguous copy
    if buffer {
        unsafe { ptr::copy_nonoverlapping(buf_ptr, fb, (w * h) as usize); }
    }
}

<commit_msg>Draw particles semi-transparent, add a little tail to show movement better<commit_after>
use std::sync::Mutex;
use std::ptr;
use rand;
use rand::distributions::{IndependentSample, Range};
use std::f32::consts;
use std::cmp::min;

#[derive(Clone, Copy)]
struct Particle {
    px : f32,
    py : f32,
    vx : f32,
    vy : f32,
    m  : f32
}

lazy_static! {
    static ref PARTICLES: Mutex<Vec<Particle>> = {
        Mutex::new(Vec::new())
    };
}

#[no_mangle]
pub extern fn nb_random_disk(num_particles: i32) -> () {
    // Place particles with random position and velocity in a disk in the center of the viewport

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let mut rng = rand::thread_rng();
    let vel  = Range::new(-3.5, 3.5);
    let mass = Range::new( 0.1, 1.5);
    let u    = Range::new( 0.0, 1.0);

    for _ in 0..num_particles {
        let mut x : f32 = u.ind_sample(&mut rng);
        let mut y : f32 = u.ind_sample(&mut rng);
        uniform_sample_disk(&mut x, &mut y);
        x *= 20.0;
        y *= 20.0;

        particles.push(Particle { px: x,
                                  py: y,
                                  vx: vel.ind_sample(&mut rng),
                                  vy: vel.ind_sample(&mut rng),
                                  m:  mass.ind_sample(&mut rng) });
    }
}

fn uniform_sample_disk(x: &mut f32, y: &mut f32) {
    let r = x.sqrt();
    let theta = 2.0 * consts::PI * (* y);
    * x = r * theta.cos();
    * y = r * theta.sin();
}

#[no_mangle]
pub extern fn nb_stable_orbits(num_particles: i32, rmin: f32, rmax: f32) -> () {
    // Generate a bunch of 'planets' with a circular orbit around a 'sun'
    //
    // References:
    //
    // http://www.cs.cmu.edu/~./ph/859E/src/nbody/circ.p2
    // www.cs.cmu.edu/~./ph/859E/src/nbody/nbody.cc

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let sun_mass    = 1000.0;
    let planet_mass = 1.0;
    let g : f32     = 1.0;
    let speed       = (g * sun_mass).sqrt();

    let mut rng     = rand::thread_rng();
    let u           = Range::new(0.0, 1.0);

    particles.push( Particle { px: 0.0, py: 0.0, vx: 0.0, vy: 0.0, m: sun_mass } );

    for _ in 0..num_particles {
        let r     = (rmax - rmin) * u.ind_sample(&mut rng) + rmin;
        let theta = 2.0 * consts::PI * u.ind_sample(&mut rng);
        particles.push( Particle { px: r * theta.cos(),
                                   py: r * theta.sin(),
                                   vx: -speed * theta.sin(),
                                   vy:  speed * theta.cos(),
                                   m: planet_mass });
    }
}

#[no_mangle]
pub extern fn nb_step(dt : f32) -> () {
    let mut particles_mtx = PARTICLES.lock().unwrap();

    // Compute forces
    let forces;
    {
        let particles = &(* particles_mtx);

        #[derive(Clone)]
        struct Force {
            fx : f32,
            fy : f32
        }
        let mut mforces = Vec::new();
        mforces.resize(particles.len(), Force { fx: 0.0, fy: 0.0 });

        for i in 0..particles.len() {
            let a = &particles[i];

            for j in 0..particles.len() {
                if i == j { continue; }

                let b = &particles[j];

                let dx = b.px - a.px;
                let dy = b.py - a.py;
                let dist = (dx * dx + dy * dy).sqrt();

                let eps = 0.0001; // Softening factor, prevent singularities
                let f = a.m * b.m / (dist * dist + eps);

                mforces[i].fx += f * dx; // / dist;
                mforces[i].fy += f * dy; // / dist;
            }
        }

        forces = mforces;
    }

    // Update positions and velocities
    {
        let mut particles = &mut (* particles_mtx);

        for i in 0..particles.len() {
            particles[i].vx += dt * forces[i].fx / particles[i].m;
            particles[i].vy += dt * forces[i].fy / particles[i].m;

            particles[i].px += dt * particles[i].vx;
            particles[i].py += dt * particles[i].vy;
        }
    }
}

#[no_mangle]
pub extern fn nb_draw(w: i32, h: i32, fb: *mut u32) -> () {
    // If writing scattered points to write combined memory turns out to be a problem,
    // enabled buffering
    let buffer = false;

    if !buffer {
        // Clear background
        unsafe { ptr::write_bytes(fb, 0, (w * h) as usize); }
    }

    // Specify viewport over simulation to be mapped to the framebuffer
    let vp_wdh   = 100.0;
    let vp_org_x = 0.0;
    let vp_org_y = 0.0;

    // Keep full width of the viewport visible, adjust height as needed
    let aspect = h as f32 / w as f32;

    // Framebuffer viewport in simulation dimensions
    let x1 =  vp_org_x - vp_wdh / 2.0;
    let y1 = (vp_org_y - vp_wdh / 2.0) * aspect;
    let x2 =  vp_org_x + vp_wdh / 2.0;
    let y2 = (vp_org_y + vp_wdh / 2.0) * aspect;

    // Scale factor for translating from simulation to framebuffer
    let vpw    = x2 - x1;
    let vph    = y2 - y1;
    let scalex = (1.0 / vpw) * w as f32;
    let scaley = (1.0 / vph) * h as f32;

    // Optionally allocate buffer
    let buf_ptr;
    if buffer {
        let mut buf = Vec::new();
        buf.resize((w * h) as usize, 0u32);
        buf_ptr = buf.as_mut_ptr();
    } else {
        buf_ptr = fb;
    }

    let particles = PARTICLES.lock().unwrap();

    for p in &(*particles) {
        // Translate from simulation to viewport coordinates
        let x = ((p.px - x1) * scalex) as i32;
        let y = ((p.py - y1) * scaley) as i32;

        // Draw semi-transparent particle with slightly more transparent tail
        for i in 0..2 {
            let xo;
            let yo;
            let col;
            match i {
                1 => {    // Tail
                          let len = (p.vx * p.vx + p.vy * p.vy).sqrt();
                          let vnx = p.vx / len;
                          let vny = p.vy / len;
                          xo = (x as f32 + 0.5 - vnx) as i32;
                          yo = (y as f32 + 0.5 - vny) as i32;
                          col = 0x00303030;
                     }
                _ => { xo = x; yo = y; col = 0x00404040; }
            }

            // Bounds check
            if xo < 0 || xo >= w || yo < 0 || yo >= h { continue; }

            // Draw particle
            let idx = xo + yo * w;
            unsafe {
                * buf_ptr.offset(idx as isize) =
                    add_abgr32(* buf_ptr.offset(idx as isize), col);
            }
        }
    }

    // Debug draw center cross
    unsafe {
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 1) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 - 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 - 1) * w) as isize) = 0x00FF00FF;
    }

    // Output in one contiguous copy
    if buffer {
        unsafe { ptr::copy_nonoverlapping(buf_ptr, fb, (w * h) as usize); }
    }
}

fn add_abgr32(c1 : u32, c2 : u32) -> u32 {
    let a1 = (c1 & 0xFF000000) >> 24;
    let b1 = (c1 & 0x00FF0000) >> 16;
    let g1 = (c1 & 0x0000FF00) >>  8;
    let r1 = (c1 & 0x000000FF) >>  0;

    let a2 = (c2 & 0xFF000000) >> 24;
    let b2 = (c2 & 0x00FF0000) >> 16;
    let g2 = (c2 & 0x0000FF00) >>  8;
    let r2 = (c2 & 0x000000FF) >>  0;

    let ar = min(255, a1 + a2);
    let gr = min(255, g1 + g2);
    let br = min(255, b1 + b2);
    let rr = min(255, r1 + r2);

    (ar << 24) | (gr << 16) | (br << 8) | (rr << 0)
}

<|endoftext|>


<commit_before>use std::collections::BTreeMap;

pub struct Store<'a> {
  max_offset: u64,
  data: &'a BTreeMap<String, Box<BTreeMap<u64, &'a [u8]>>>
}

impl<'a> Store<'a> {
  pub fn new<'b>() -> Store<'b> {
    Store {
      max_offset: 0,
      data: &'b BTreeMap::new()
    }
  }

  pub fn add(&'a mut self, key: String, value: &'a [u8]) {
    self.max_offset += 1;
    match self.data.get_mut(&key) {
      Some(version_tree) => {
        if version_tree.insert(self.max_offset, value).is_none() {
          panic!("Invariant violation; duplicate offset detected");
        }
      },
      None => {
        let mut new_version_tree = Box::new(BTreeMap::new());
        new_version_tree.insert(self.max_offset, value);
        if self.data.insert(key, new_version_tree).is_none() {
          panic!("Invariant violation; duplicate offset detected");
        }
      }
    }
  }
}<commit_msg>Apply the parmesan.<commit_after>use std::collections::BTreeMap;

pub struct Store<'a> {
  max_offset: u64,
  data: Box<BTreeMap<&'a str, Box<BTreeMap<u64, &'a [u8]>>>>
}

impl<'a> Store<'a> {
  pub fn new<'b>() -> Store<'b> {
    Store {
      max_offset: 0,
      data: Box::new(BTreeMap::new())
    }
  }

  pub fn add(&'a mut self, key: &'a str, value: &'a [u8]) {
    self.max_offset += 1;
    if self.data.get_mut(&key).is_none() {
        if self.data.insert(key, Box::new(BTreeMap::new())).is_none() {
            panic!("Invariant violation; duplicate offset detected");
        }
    }

    if self.data.get_mut(&key).unwrap().insert(self.max_offset, value).is_none() {
      panic!("Invariant violation; duplicate offset detected");
    }
  }
}
<|endoftext|>


<commit_before>use std::default::Default;

use yoga_wrapper;

#[derive(Debug, PartialEq)]
pub enum BackgroundColor<C> {
    Color(C),
    Transparent,
}

impl<C> Default for BackgroundColor<C> {
    fn default() -> BackgroundColor<C> {
        BackgroundColor::Transparent
    }
}

#[derive(Debug, Default)]
pub struct Style<C> {
    color: Option<C>,
    background_color: Option<BackgroundColor<C>>,
    node: yoga_wrapper::Node,
}

impl<C> Style<C> {
    pub fn new() -> Self
        where C: Default
    {
        Style { ..Default::default() }
    }

    pub fn get_layout_width(&self) -> f32 {
        self.node.get_layout_width()
    }

    pub fn get_layout_height(&self) -> f32 {
        self.node.get_layout_height()
    }

    pub fn get_layout_top(&self) -> f32 {
        self.node.get_layout_top()
    }

    pub fn get_layout_left(&self) -> f32 {
        self.node.get_layout_left()
    }

    pub fn get_color(&self) -> &Option<C> {
        &self.color
    }

    pub fn get_background_color(&self) -> &Option<BackgroundColor<C>> {
        &self.background_color
    }

    pub fn set_width(&mut self, width: f32) {
        self.node.set_width(width)
    }

    pub fn set_height(&mut self, height: f32) {
        self.node.set_height(height)
    }

    pub fn calculate_layout(&mut self) {
        self.node.calculate_layout()
    }

    pub fn set_flex_direction(&mut self, flex_direction: yoga_wrapper::FlexDirection) {
        self.node.set_flex_direction(flex_direction)
    }

    pub fn set_padding(&mut self, edge: yoga_wrapper::Edge, value: f32) {
        self.node.set_padding(edge, value)
    }

    pub fn set_margin(&mut self, edge: yoga_wrapper::Edge, value: f32) {
        self.node.set_margin(edge, value)
    }

    pub fn insert_child(&mut self, child: &yoga_wrapper::Node, index: usize) {
        self.node.insert_child(child, index as u32)
    }

    pub fn get_node(&self) -> &yoga_wrapper::Node {
        &self.node
    }

    pub fn set_align_self(&mut self, value: yoga_wrapper::Align) {
        self.node.set_align_self(value)
    }

    pub fn set_flex_grow(&mut self, value: f32) {
        self.node.set_flex_grow(value)
    }
}
<commit_msg>feat(Style): add get_mut_node method<commit_after>use std::default::Default;

use yoga_wrapper;

#[derive(Debug, PartialEq)]
pub enum BackgroundColor<C> {
    Color(C),
    Transparent,
}

impl<C> Default for BackgroundColor<C> {
    fn default() -> BackgroundColor<C> {
        BackgroundColor::Transparent
    }
}

#[derive(Debug, Default)]
pub struct Style<C> {
    color: Option<C>,
    background_color: Option<BackgroundColor<C>>,
    node: yoga_wrapper::Node,
}

impl<C> Style<C> {
    pub fn new() -> Self
        where C: Default
    {
        Style { ..Default::default() }
    }

    pub fn get_layout_width(&self) -> f32 {
        self.node.get_layout_width()
    }

    pub fn get_layout_height(&self) -> f32 {
        self.node.get_layout_height()
    }

    pub fn get_layout_top(&self) -> f32 {
        self.node.get_layout_top()
    }

    pub fn get_layout_left(&self) -> f32 {
        self.node.get_layout_left()
    }

    pub fn get_color(&self) -> &Option<C> {
        &self.color
    }

    pub fn get_background_color(&self) -> &Option<BackgroundColor<C>> {
        &self.background_color
    }

    pub fn set_width(&mut self, width: f32) {
        self.node.set_width(width)
    }

    pub fn set_height(&mut self, height: f32) {
        self.node.set_height(height)
    }

    pub fn calculate_layout(&mut self) {
        self.node.calculate_layout()
    }

    pub fn set_flex_direction(&mut self, flex_direction: yoga_wrapper::FlexDirection) {
        self.node.set_flex_direction(flex_direction)
    }

    pub fn set_padding(&mut self, edge: yoga_wrapper::Edge, value: f32) {
        self.node.set_padding(edge, value)
    }

    pub fn set_margin(&mut self, edge: yoga_wrapper::Edge, value: f32) {
        self.node.set_margin(edge, value)
    }

    pub fn insert_child(&mut self, child: &yoga_wrapper::Node, index: usize) {
        self.node.insert_child(child, index as u32)
    }

    pub fn get_node(&self) -> &yoga_wrapper::Node {
        &self.node
    }

    pub fn get_mut_node(&mut self) -> &mut yoga_wrapper::Node {
        &mut self.node
    }

    pub fn set_align_self(&mut self, value: yoga_wrapper::Align) {
        self.node.set_align_self(value)
    }

    pub fn set_flex_grow(&mut self, value: f32) {
        self.node.set_flex_grow(value)
    }
}
<|endoftext|>


<commit_before>use super::*;
use std::fmt::Debug;
use std::ops::Add;

fn test_empty<T: Array<i32>>(mut arr: T)
{
    assert_eq!(arr.len(), 0);
    assert_eq!(arr.is_empty(), true);
    assert_eq!(arr.first(), None);
    assert_eq!(arr.first_mut(), None);
    assert_eq!(arr.last(), None);
    assert_eq!(arr.last_mut(), None);
    assert_eq!(arr.get(1), None);
    assert_eq!(arr.get_mut(1), None);
}

#[test]
fn methods_empty()
{
    let arr: [i32; 0] = [];
    test_empty(arr);
    assert_eq!(arr.map_(|a| a * 2), []);
    assert_eq!(arr.foldl(0, |a, n| a + n), 0);
}

fn test_arr<T: Array<V>, V: PartialEq + Debug>(mut arr: T, len: usize, mut first: V, mut last: V, mut second: V)
{
    assert_eq!(arr.len(), len);
    assert_eq!(arr.is_empty(), false);
    assert_eq!(arr.first(), Some(&first));
    assert_eq!(arr.first_mut(), Some(&mut first));
    assert_eq!(arr.last(), Some(&last));
    assert_eq!(arr.last_mut(), Some(&mut last));
    assert_eq!(arr.get(1), Some(&second));
    assert_eq!(arr.get(42), None);
    assert_eq!(arr.get_mut(1), Some(&mut second));
    assert_eq!(arr.get_mut(42), None);
}

#[test]
fn methods()
{
    let arr = [1, 2, 3, 4];
    test_arr(arr, 4, 1, 4, 2);
    assert_eq!(arr.map_(|a| a * 2), [2, 4, 6, 8]);
    assert_eq!(arr.foldl(0, |a, n| a + n), 10);

    let arr = ['c', 'd', 'e', 'f', 'g', 'a', 'b'];
    test_arr(arr, 7, 'c', 'b', 'd');
    assert_eq!(arr.map_(|a| a.to_uppercase().next().unwrap()), ['C', 'D', 'E', 'F', 'G', 'A', 'B']);
    assert_eq!(arr.foldl(String::new(), |mut a, c| { a.push(c); a }), "cdefgab");
    assert_eq!(arr.foldr(String::new(), |mut a, c| { a.push(c); a }), "bagfedc");
}

fn sum<T, V>(arr: T, val: V) -> T
    where T: Array<V>, V: Add<Output=V> + Copy
{
    arr.map_(|n| n + val)
}

fn avg<T: Array<f32>>(arr: T) -> f32
{
    let n = arr.len() as f32;
    arr.foldl(0.0, |a, n| a + n) / n
}

#[test]
fn generics()
{
    assert_eq!(sum([], 1), []);
    assert_eq!(sum([1], 10), [11]);
    assert_eq!(sum([1, 2], 20), [21, 22]);
    assert_eq!(sum([1, 2, 3], 30), [31, 32, 33]);
    assert_eq!(sum([1, 2, 3, 4], 40), [41, 42, 43, 44]);

    assert_eq!(avg([3.5, 4.1, 7.0, 1.5]), 4.025);
    assert_eq!(avg([1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]), 102.3);
}

#[test]
fn slice()
{
    assert_eq!([1, 2, 3].as_slice(), &[1, 2, 3]);
    assert_eq!([4, 5, 6].as_mut_slice(), &mut [4, 5, 6]);

    let mut arr = [1, -5, 8, 42, 33];
    arr.as_mut_slice().sort();
    assert_eq!(arr, [-5, 1, 8, 33, 42]);

    let mut v = Vec::new();
    v.extend_from_slice(arr.as_slice());
    assert_eq!(arr, &v[..]);
}

#[test]
fn constructors()
{
    let arr: [usize; 5] = Array::from_fn(|i| i);
    assert_eq!(arr, [0, 1, 2, 3, 4]);

    let mut n = 1;
    let arr: [usize; 5] = Array::from_fn(|i| { n *= 2; i + n });
    assert_eq!(arr, [2, 5, 10, 19, 36]);

    let arr: [usize; 5] = Array::from_iter(1..).unwrap();
    assert_eq!(arr, [1, 2, 3, 4, 5]);

    let iter = (1..).filter(|n| n % 2 == 0).zip("foobar".chars());
    let arr: [(i32, char); 6] = Array::from_iter(iter).unwrap();
    assert_eq!(arr, [(2, 'f'), (4, 'o'), (6, 'o'), (8, 'b'), (10, 'a'), (12, 'r')]);
}

#[test]
fn sized()
{
    let arr = [1, 2, 3];
    assert_eq!(arr.map(|a| a as f32 / 2.0), [0.5, 1.0, 1.5]);
    assert_eq!(arr.zip([30, 20, 10], |a, b| a + b), [31, 22, 13]);
    assert_eq!(arr.zip(['a', 'b', 'c'], |a, b| (a, b)), [(1, 'a'), (2, 'b'), (3, 'c')]);

    let arr = ["foo", "asdf", "a", "very long string"];
    assert_eq!(arr.map(|s| s.len()), [3, 4, 1, 16]);
}

fn sum_boxed(arr: Box<Array<i32>>) -> i32
{
    (0 .. arr.len()).fold(0, |a, i| a + arr.get(i).unwrap())
}

#[test]
fn object_safe()
{
    assert_eq!(sum_boxed(Box::new([1, 3, 5, 7])), 16);
}
<commit_msg>use dyn for trait object<commit_after>use super::*;
use std::fmt::Debug;
use std::ops::Add;

fn test_empty<T: Array<i32>>(mut arr: T)
{
    assert_eq!(arr.len(), 0);
    assert_eq!(arr.is_empty(), true);
    assert_eq!(arr.first(), None);
    assert_eq!(arr.first_mut(), None);
    assert_eq!(arr.last(), None);
    assert_eq!(arr.last_mut(), None);
    assert_eq!(arr.get(1), None);
    assert_eq!(arr.get_mut(1), None);
}

#[test]
fn methods_empty()
{
    let arr: [i32; 0] = [];
    test_empty(arr);
    assert_eq!(arr.map_(|a| a * 2), []);
    assert_eq!(arr.foldl(0, |a, n| a + n), 0);
}

fn test_arr<T: Array<V>, V: PartialEq + Debug>(mut arr: T, len: usize, mut first: V, mut last: V, mut second: V)
{
    assert_eq!(arr.len(), len);
    assert_eq!(arr.is_empty(), false);
    assert_eq!(arr.first(), Some(&first));
    assert_eq!(arr.first_mut(), Some(&mut first));
    assert_eq!(arr.last(), Some(&last));
    assert_eq!(arr.last_mut(), Some(&mut last));
    assert_eq!(arr.get(1), Some(&second));
    assert_eq!(arr.get(42), None);
    assert_eq!(arr.get_mut(1), Some(&mut second));
    assert_eq!(arr.get_mut(42), None);
}

#[test]
fn methods()
{
    let arr = [1, 2, 3, 4];
    test_arr(arr, 4, 1, 4, 2);
    assert_eq!(arr.map_(|a| a * 2), [2, 4, 6, 8]);
    assert_eq!(arr.foldl(0, |a, n| a + n), 10);

    let arr = ['c', 'd', 'e', 'f', 'g', 'a', 'b'];
    test_arr(arr, 7, 'c', 'b', 'd');
    assert_eq!(arr.map_(|a| a.to_uppercase().next().unwrap()), ['C', 'D', 'E', 'F', 'G', 'A', 'B']);
    assert_eq!(arr.foldl(String::new(), |mut a, c| { a.push(c); a }), "cdefgab");
    assert_eq!(arr.foldr(String::new(), |mut a, c| { a.push(c); a }), "bagfedc");
}

fn sum<T, V>(arr: T, val: V) -> T
    where T: Array<V>, V: Add<Output=V> + Copy
{
    arr.map_(|n| n + val)
}

fn avg<T: Array<f32>>(arr: T) -> f32
{
    let n = arr.len() as f32;
    arr.foldl(0.0, |a, n| a + n) / n
}

#[test]
fn generics()
{
    assert_eq!(sum([], 1), []);
    assert_eq!(sum([1], 10), [11]);
    assert_eq!(sum([1, 2], 20), [21, 22]);
    assert_eq!(sum([1, 2, 3], 30), [31, 32, 33]);
    assert_eq!(sum([1, 2, 3, 4], 40), [41, 42, 43, 44]);

    assert_eq!(avg([3.5, 4.1, 7.0, 1.5]), 4.025);
    assert_eq!(avg([1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]), 102.3);
}

#[test]
fn slice()
{
    assert_eq!([1, 2, 3].as_slice(), &[1, 2, 3]);
    assert_eq!([4, 5, 6].as_mut_slice(), &mut [4, 5, 6]);

    let mut arr = [1, -5, 8, 42, 33];
    arr.as_mut_slice().sort();
    assert_eq!(arr, [-5, 1, 8, 33, 42]);

    let mut v = Vec::new();
    v.extend_from_slice(arr.as_slice());
    assert_eq!(arr, &v[..]);
}

#[test]
fn constructors()
{
    let arr: [usize; 5] = Array::from_fn(|i| i);
    assert_eq!(arr, [0, 1, 2, 3, 4]);

    let mut n = 1;
    let arr: [usize; 5] = Array::from_fn(|i| { n *= 2; i + n });
    assert_eq!(arr, [2, 5, 10, 19, 36]);

    let arr: [usize; 5] = Array::from_iter(1..).unwrap();
    assert_eq!(arr, [1, 2, 3, 4, 5]);

    let iter = (1..).filter(|n| n % 2 == 0).zip("foobar".chars());
    let arr: [(i32, char); 6] = Array::from_iter(iter).unwrap();
    assert_eq!(arr, [(2, 'f'), (4, 'o'), (6, 'o'), (8, 'b'), (10, 'a'), (12, 'r')]);
}

#[test]
fn sized()
{
    let arr = [1, 2, 3];
    assert_eq!(arr.map(|a| a as f32 / 2.0), [0.5, 1.0, 1.5]);
    assert_eq!(arr.zip([30, 20, 10], |a, b| a + b), [31, 22, 13]);
    assert_eq!(arr.zip(['a', 'b', 'c'], |a, b| (a, b)), [(1, 'a'), (2, 'b'), (3, 'c')]);

    let arr = ["foo", "asdf", "a", "very long string"];
    assert_eq!(arr.map(|s| s.len()), [3, 4, 1, 16]);
}

fn sum_boxed(arr: Box<dyn Array<i32>>) -> i32
{
    (0 .. arr.len()).fold(0, |a, i| a + arr.get(i).unwrap())
}

#[test]
fn object_safe()
{
    assert_eq!(sum_boxed(Box::new([1, 3, 5, 7])), 16);
}
<|endoftext|>


<commit_before>use std::env::current_exe;
use std::fs::{File, remove_file};
use std::io::Read;
use std::path::Path;
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;
use super::Result;
use team::Team;
use tmux;

const MOB_FILE_PATH: &'static str = "/tmp/mob";

pub fn run(time_per_driver_in_minutes: &f64, team: &mut Team) -> Result<()> {
    let time_per_driver_in_seconds = time_per_driver_in_minutes * 60.0;

    let mut elapsed_time = 0.0;

    loop {
        if is_time_for_next_driver(&time_per_driver_in_seconds, elapsed_time) {
            prompt_user(team)?;
        };

        elapsed_time += 1.0;
        sleep(Duration::from_secs(1))
    }
}

fn prompt_user(team: &mut Team) -> Result<()> {
    let bin = current_exe()?.to_str().expect("Binary path").to_owned();
    let next_driver = team.next_driver();

    let prompt_command = format!("{} prompt {}", bin, next_driver);
    let exit_status = tmux::new_window_with_command(&prompt_command)?;

    wait_for_file();

    if exit_status.success() && is_continue()? {
        team.next_driver();
        Ok(())
    } else {
        exit(1);
    }
}

fn wait_for_file() {
    let path = Path::new(MOB_FILE_PATH);

    while !path.exists() {
        sleep(Duration::from_millis(500));
    }
}

fn is_continue() -> Result<bool> {
    let path = Path::new(MOB_FILE_PATH);

    let mut file = File::open(path)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    remove_file(path)?;

    Ok(contents == "y")
}

fn is_time_for_next_driver(time_per_driver: &f64, elapsed_time: f64) -> bool {
    if elapsed_time != 0.0 && elapsed_time % time_per_driver == 0.0 {
        true
    } else {
        false
    }
}
<commit_msg>fix: Change driver if user chooses to continue<commit_after>use std::env::current_exe;
use std::fs::{File, remove_file};
use std::io::Read;
use std::path::Path;
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;
use super::Result;
use team::Team;
use tmux;

const MOB_FILE_PATH: &'static str = "/tmp/mob";

pub fn run(time_per_driver_in_minutes: &f64, team: &mut Team) -> Result<()> {
    let time_per_driver_in_seconds = time_per_driver_in_minutes * 60.0;

    let mut elapsed_time = 0.0;

    loop {
        if is_time_for_next_driver(&time_per_driver_in_seconds, elapsed_time) {
            prompt_user(team)?;
        };

        elapsed_time += 1.0;
        sleep(Duration::from_secs(1))
    }
}

fn prompt_user(team: &mut Team) -> Result<()> {
    let bin = current_exe()?.to_str().expect("Binary path").to_owned();
    let next_driver = team.next_driver();

    let prompt_command = format!("{} prompt {}", bin, next_driver);
    let exit_status = tmux::new_window_with_command(&prompt_command)?;

    wait_for_file();

    if exit_status.success() && is_continue()? {
        team.change_driver(&next_driver);
        Ok(())
    } else {
        exit(1);
    }
}

fn wait_for_file() {
    let path = Path::new(MOB_FILE_PATH);

    while !path.exists() {
        sleep(Duration::from_millis(500));
    }
}

fn is_continue() -> Result<bool> {
    let path = Path::new(MOB_FILE_PATH);

    let mut file = File::open(path)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    remove_file(path)?;

    Ok(contents == "y")
}

fn is_time_for_next_driver(time_per_driver: &f64, elapsed_time: f64) -> bool {
    if elapsed_time != 0.0 && elapsed_time % time_per_driver == 0.0 {
        true
    } else {
        false
    }
}
<|endoftext|>


<commit_before>extern crate c_ares_sys;
extern crate libc;

use std::net::{
    Ipv4Addr,
    Ipv6Addr,
};
use std::os::unix::io;

/// An invalid file descriptor.  Use this to represent 'no action' when calling
/// `process_fd()` on a channel.
pub const INVALID_FD: io::RawFd = c_ares_sys::ARES_SOCKET_BAD as io::RawFd;

/// Error codes that the library might return.  Use `str_error()` to convert an
/// error code into a description.
#[derive(Debug, Clone, Copy)]
pub enum AresError {
    ENODATA = c_ares_sys::ARES_ENODATA as isize,
    EFORMERR = c_ares_sys::ARES_EFORMERR  as isize,
    ESERVFAIL = c_ares_sys::ARES_ESERVFAIL as isize,
    ENOTFOUND = c_ares_sys::ARES_ENOTFOUND as isize,
    ENOTIMP = c_ares_sys::ARES_ENOTIMP as isize,
    EREFUSED = c_ares_sys::ARES_EREFUSED as isize,
    EBADQUERY = c_ares_sys::ARES_EBADQUERY as isize,
    EBADNAME = c_ares_sys::ARES_EBADNAME as isize,
    EBADFAMILY = c_ares_sys::ARES_EBADFAMILY as isize,
    EBADRESP = c_ares_sys::ARES_EBADRESP as isize,
    ECONNREFUSED = c_ares_sys::ARES_ECONNREFUSED as isize,
    ETIMEOUT = c_ares_sys::ARES_ETIMEOUT as isize,
    EOF = c_ares_sys::ARES_EOF as isize,
    EFILE = c_ares_sys::ARES_EFILE as isize,
    ENOMEM = c_ares_sys::ARES_ENOMEM as isize,
    EDESTRUCTION = c_ares_sys::ARES_EDESTRUCTION as isize,
    EBADSTR = c_ares_sys::ARES_EBADSTR as isize,
    EBADFLAGS = c_ares_sys::ARES_EBADFLAGS as isize,
    ENONAME = c_ares_sys::ARES_ENONAME as isize,
    EBADHINTS = c_ares_sys::ARES_EBADHINTS as isize,
    ENOTINITIALIZED = c_ares_sys::ARES_ENOTINITIALIZED as isize,
    ELOADIPHLPAPI = c_ares_sys::ARES_ELOADIPHLPAPI as isize,
    EADDRGETNETWORKPARAMS = c_ares_sys::ARES_EADDRGETNETWORKPARAMS as isize,
    ECANCELLED = c_ares_sys::ARES_ECANCELLED as isize,
    UNKNOWN,
}

/// Address families.
#[derive(Debug, Clone, Copy)]
pub enum AddressFamily {
    /// IPv4.
    INET = 2,

    /// IPv6.
    INET6 = 10,
}

/// An IP address, either an IPv4 or an IPv6 address.
pub enum IpAddr {
    /// An IPv4 address.
    V4(Ipv4Addr),

    /// An IPv6 address.
    V6(Ipv6Addr),
}

#[repr(C)]
pub struct hostent {
    pub h_name: *mut libc::c_char,
    pub h_aliases: *mut *mut libc::c_char,
    pub h_addrtype: libc::c_int,
    pub h_length: libc::c_int,
    pub h_addr_list: *mut *mut libc::c_char,
}

// See arpa/nameser.h
pub enum QueryType {
    A = 1,
    NS = 2,
    CNAME = 5,
    SOA = 6,
    PTR = 12,
    MX = 15,
    TXT = 16,
    AAAA = 28,
    SRV = 33,
    NAPTR = 35,
}

// See arpa/nameser.h
pub enum DnsClass {
   IN = 1,
}
<commit_msg>Documentation<commit_after>extern crate c_ares_sys;
extern crate libc;

use std::net::{
    Ipv4Addr,
    Ipv6Addr,
};
use std::os::unix::io;

/// An invalid file descriptor.  Use this to represent 'no action' when calling
/// `process_fd()` on a channel.
pub const INVALID_FD: io::RawFd = c_ares_sys::ARES_SOCKET_BAD as io::RawFd;

/// Error codes that the library might return.  Use `str_error()` to convert an
/// error code into a description.
#[derive(Debug, Clone, Copy)]
pub enum AresError {
    /// DNS server returned answer with no data.
    ENODATA = c_ares_sys::ARES_ENODATA as isize,

    /// DNS server claims query was misformatted.
    EFORMERR = c_ares_sys::ARES_EFORMERR  as isize,

    /// DNS server returned general failure.
    ESERVFAIL = c_ares_sys::ARES_ESERVFAIL as isize,

    /// Domain name not found.
    ENOTFOUND = c_ares_sys::ARES_ENOTFOUND as isize,

    /// DNS server does not implement requested operation.
    ENOTIMP = c_ares_sys::ARES_ENOTIMP as isize,

    /// DNS server refused query.
    EREFUSED = c_ares_sys::ARES_EREFUSED as isize,

    /// Misformatted DNS query.
    EBADQUERY = c_ares_sys::ARES_EBADQUERY as isize,

    /// Misformatted domain name.
    EBADNAME = c_ares_sys::ARES_EBADNAME as isize,

    /// Unsupported address family.
    EBADFAMILY = c_ares_sys::ARES_EBADFAMILY as isize,

    /// Misformatted DNS reply.
    EBADRESP = c_ares_sys::ARES_EBADRESP as isize,

    /// Could not contact DNS servers.
    ECONNREFUSED = c_ares_sys::ARES_ECONNREFUSED as isize,

    /// Timeout while contacting DNS servers.
    ETIMEOUT = c_ares_sys::ARES_ETIMEOUT as isize,

    /// End of file.
    EOF = c_ares_sys::ARES_EOF as isize,

    /// Error reading file.
    EFILE = c_ares_sys::ARES_EFILE as isize,

    /// Out of memory.
    ENOMEM = c_ares_sys::ARES_ENOMEM as isize,

    /// Channel is being destroyed.
    EDESTRUCTION = c_ares_sys::ARES_EDESTRUCTION as isize,

    /// Misformatted string.
    EBADSTR = c_ares_sys::ARES_EBADSTR as isize,

    /// Illegal flags specified.
    EBADFLAGS = c_ares_sys::ARES_EBADFLAGS as isize,

    /// Given hostname is not numeric.
    ENONAME = c_ares_sys::ARES_ENONAME as isize,

    /// Illegal hints flags specified.
    EBADHINTS = c_ares_sys::ARES_EBADHINTS as isize,

    /// c-ares library initialization not yet performed.
    ENOTINITIALIZED = c_ares_sys::ARES_ENOTINITIALIZED as isize,

    /// rror loading iphlpapi.dll.
    ELOADIPHLPAPI = c_ares_sys::ARES_ELOADIPHLPAPI as isize,

    /// ould not find GetNetworkParams function.
    EADDRGETNETWORKPARAMS = c_ares_sys::ARES_EADDRGETNETWORKPARAMS as isize,

    /// DNS query cancelled.
    ECANCELLED = c_ares_sys::ARES_ECANCELLED as isize,

    /// Unknown error.
    UNKNOWN,
}

/// Address families.
#[derive(Debug, Clone, Copy)]
pub enum AddressFamily {
    /// IPv4.
    INET = 2,

    /// IPv6.
    INET6 = 10,
}

/// An IP address, either an IPv4 or an IPv6 address.
pub enum IpAddr {
    /// An IPv4 address.
    V4(Ipv4Addr),

    /// An IPv6 address.
    V6(Ipv6Addr),
}

#[repr(C)]
pub struct hostent {
    pub h_name: *mut libc::c_char,
    pub h_aliases: *mut *mut libc::c_char,
    pub h_addrtype: libc::c_int,
    pub h_length: libc::c_int,
    pub h_addr_list: *mut *mut libc::c_char,
}

// See arpa/nameser.h
pub enum QueryType {
    A = 1,
    NS = 2,
    CNAME = 5,
    SOA = 6,
    PTR = 12,
    MX = 15,
    TXT = 16,
    AAAA = 28,
    SRV = 33,
    NAPTR = 35,
}

// See arpa/nameser.h
pub enum DnsClass {
   IN = 1,
}
<|endoftext|>


<commit_before>// Copyright 2015-2016, 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>

//! Runtime type information.

use translate::{FromGlib, FromGlibContainerAsVec, ToGlib, ToGlibPtr, ToGlibPtrMut, ToGlibContainerFromSlice, from_glib, from_glib_none};
use ffi as glib_ffi;
use gobject_ffi;
use value::{Value, FromValue, FromValueOptional, SetValue};

use std::fmt;
use std::mem;
use std::ptr;

/// A GLib or GLib-based library type
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Type {
    /// An invalid `Type` used as error return value in some functions
    Invalid,
    /// The fundamental type corresponding to the unit type `()`
    Unit,
    /// The fundamental type corresponding to `i8`
    I8,
    /// The fundamental type corresponding to `u8`
    U8,
    /// The fundamental type corresponding to `bool`
    Bool,
    /// The fundamental type corresponding to `i32`
    I32,
    /// The fundamental type corresponding to `u32`
    U32,
    /// The fundamental type corresponding to C `long`
    ILong,
    /// The fundamental type corresponding to C `unsigned long`
    ULong,
    /// The fundamental type corresponding to `i64`
    I64,
    /// The fundamental type corresponding to `u64`
    U64,
    /// The fundamental type corresponding to `f32`
    F32,
    /// The fundamental type corresponding to `f64`
    F64,
    /// The fundamental type corresponding to `String`
    String,
    /// The fundamental type corresponding to a pointer
    Pointer,
    /// The fundamental type of GVariant
    Variant,
    /// The fundamental type from which all interfaces are derived
    BaseInterface,
    /// The fundamental type from which all enumeration types are derived
    BaseEnum,
    /// The fundamental type from which all flags types are derived
    BaseFlags,
    /// The fundamental type from which all boxed types are derived
    BaseBoxed,
    /// The fundamental type from which all `GParamSpec` types are derived
    BaseParamSpec,
    /// The fundamental type from which all objects are derived
    BaseObject,
    /// A non-fundamental type identified by value of type `usize`
    Other(usize),
}

impl Type {
    pub fn name(&self) -> String {
        unsafe {
            from_glib_none(gobject_ffi::g_type_name(self.to_glib()))
        }
    }

    pub fn is_a(&self, other: &Type) -> bool {
        unsafe {
            from_glib(gobject_ffi::g_type_is_a(self.to_glib(), other.to_glib()))
        }
    }

    pub fn parent(&self) -> Option<Self> {
        unsafe {
            let parent = gobject_ffi::g_type_parent(self.to_glib());
            if parent == gobject_ffi::G_TYPE_INVALID {
                None
            } else {
                Some(from_glib(parent))
            }
        }
    }

    pub fn children(&self) -> Vec<Self> {
        unsafe {
            let mut n_children = 0u32;
            let children = gobject_ffi::g_type_children(self.to_glib(), &mut n_children);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(children, n_children as usize)
        }
    }

    pub fn interfaces(&self) -> Vec<Self> {
        unsafe {
            let mut n_interfaces = 0u32;
            let interfaces = gobject_ffi::g_type_interfaces(self.to_glib(), &mut n_interfaces);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(interfaces, n_interfaces as usize)
        }
    }
    pub fn interface_prerequisites(&self) -> Vec<Self> {
        unsafe {
            let mut n_prereqs = 0u32;
            let prereqs = gobject_ffi::g_type_interface_prerequisites(self.to_glib(), &mut n_prereqs);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(prereqs, n_prereqs as usize)
        }
    }

    pub fn from_name<'a, P: Into<&'a str>>(name: P) -> Option<Self> {
        unsafe {
            let type_ = gobject_ffi::g_type_from_name(name.into().to_glib_none().0);
            if type_ == gobject_ffi::G_TYPE_INVALID {
                None
            } else {
                Some(from_glib(type_))
            }
        }
    }
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.name())
    }
}

impl fmt::Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.name())
    }
}

/// Types that are supported by GLib dynamic typing.
pub trait StaticType {
    /// Returns the type identifier of `Self`.
    fn static_type() -> Type;
}

impl StaticType for Type {
    fn static_type() -> Type {
        unsafe {
            from_glib(gobject_ffi::g_gtype_get_type())
        }
    }
}

impl<'a> FromValueOptional<'a> for Type {
    unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
        Some(from_glib(gobject_ffi::g_value_get_gtype(value.to_glib_none().0)))
    }
}

impl<'a> FromValue<'a> for Type {
    unsafe fn from_value(value: &'a Value) -> Self {
        from_glib(gobject_ffi::g_value_get_gtype(value.to_glib_none().0))
    }
}

impl SetValue for Type {
    unsafe fn set_value(value: &mut Value, this: &Self) {
        gobject_ffi::g_value_set_gtype(value.to_glib_none_mut().0, this.to_glib())
    }
}

impl<'a, T: ?Sized + StaticType> StaticType for &'a T {
    fn static_type() -> Type {
        T::static_type()
    }
}

macro_rules! builtin {
    ($name:ident, $val:ident) => {
        impl StaticType for $name {
            fn static_type() -> Type {
                Type::$val
            }
        }
    }
}

builtin!(bool, Bool);
builtin!(i8, I8);
builtin!(u8, U8);
builtin!(i32, I32);
builtin!(u32, U32);
builtin!(i64, I64);
builtin!(u64, U64);
builtin!(f32, F32);
builtin!(f64, F64);
builtin!(str, String);
builtin!(String, String);

impl<'a> StaticType for [&'a str] {
    fn static_type() -> Type {
        unsafe {
            from_glib(glib_ffi::g_strv_get_type())
        }
    }
}

impl StaticType for Vec<String> {
    fn static_type() -> Type {
        unsafe {
            from_glib(glib_ffi::g_strv_get_type())
        }
    }
}

#[inline]
pub unsafe fn instance_of<C: StaticType>(ptr: glib_ffi::gconstpointer) -> bool {
    from_glib(
        gobject_ffi::g_type_check_instance_is_a(
            ptr as *mut _, <C as StaticType>::static_type().to_glib()))
}

impl FromGlib<glib_ffi::GType> for Type {
    #[inline]
    fn from_glib(val: glib_ffi::GType) -> Type {
        use self::Type::*;
        match val {
            gobject_ffi::G_TYPE_INVALID => Invalid,
            gobject_ffi::G_TYPE_NONE => Unit,
            gobject_ffi::G_TYPE_INTERFACE => BaseInterface,
            gobject_ffi::G_TYPE_CHAR => I8,
            gobject_ffi::G_TYPE_UCHAR => U8,
            gobject_ffi::G_TYPE_BOOLEAN => Bool,
            gobject_ffi::G_TYPE_INT => I32,
            gobject_ffi::G_TYPE_UINT => U32,
            gobject_ffi::G_TYPE_LONG => ILong,
            gobject_ffi::G_TYPE_ULONG => ULong,
            gobject_ffi::G_TYPE_INT64 => I64,
            gobject_ffi::G_TYPE_UINT64 => U64,
            gobject_ffi::G_TYPE_ENUM => BaseEnum,
            gobject_ffi::G_TYPE_FLAGS => BaseFlags,
            gobject_ffi::G_TYPE_FLOAT => F32,
            gobject_ffi::G_TYPE_DOUBLE => F64,
            gobject_ffi::G_TYPE_STRING => String,
            gobject_ffi::G_TYPE_POINTER => Pointer,
            gobject_ffi::G_TYPE_BOXED => BaseBoxed,
            gobject_ffi::G_TYPE_PARAM => BaseParamSpec,
            gobject_ffi::G_TYPE_OBJECT => BaseObject,
            gobject_ffi::G_TYPE_VARIANT => Variant,
            x => Other(x as usize),
        }
    }
}

impl ToGlib for Type {
    type GlibType = glib_ffi::GType;

    fn to_glib(&self) -> glib_ffi::GType {
        use self::Type::*;
        match *self {
            Invalid => gobject_ffi::G_TYPE_INVALID,
            Unit => gobject_ffi::G_TYPE_NONE,
            BaseInterface => gobject_ffi::G_TYPE_INTERFACE,
            I8 => gobject_ffi::G_TYPE_CHAR,
            U8 => gobject_ffi::G_TYPE_UCHAR,
            Bool => gobject_ffi::G_TYPE_BOOLEAN,
            I32 => gobject_ffi::G_TYPE_INT,
            U32 => gobject_ffi::G_TYPE_UINT,
            ILong => gobject_ffi::G_TYPE_LONG,
            ULong => gobject_ffi::G_TYPE_ULONG,
            I64 => gobject_ffi::G_TYPE_INT64,
            U64 => gobject_ffi::G_TYPE_UINT64,
            BaseEnum => gobject_ffi::G_TYPE_ENUM,
            BaseFlags => gobject_ffi::G_TYPE_FLAGS,
            F32 => gobject_ffi::G_TYPE_FLOAT,
            F64 => gobject_ffi::G_TYPE_DOUBLE,
            String => gobject_ffi::G_TYPE_STRING,
            Pointer => gobject_ffi::G_TYPE_POINTER,
            BaseBoxed => gobject_ffi::G_TYPE_BOXED,
            BaseParamSpec => gobject_ffi::G_TYPE_PARAM,
            BaseObject => gobject_ffi::G_TYPE_OBJECT,
            Variant => gobject_ffi::G_TYPE_VARIANT,
            Other(x) => x as glib_ffi::GType,
        }
    }
}

impl<'a> ToGlibContainerFromSlice<'a, *mut glib_ffi::GType> for Type {
    type Storage = Option<Vec<glib_ffi::GType>>;

    fn to_glib_none_from_slice(t: &'a [Type]) -> (*mut glib_ffi::GType, Self::Storage) {
        let mut vec = t.iter().map(|v| v.to_glib()).collect::<Vec<_>>();

        (vec.as_mut_ptr(), Some(vec))
    }

    fn to_glib_container_from_slice(t: &'a [Type]) -> (*mut glib_ffi::GType, Self::Storage) {
        (Self::to_glib_full_from_slice(t), None)
    }

    fn to_glib_full_from_slice(t: &[Type]) -> *mut glib_ffi::GType {
        if t.is_empty() {
            return ptr::null_mut();
        }

        unsafe {
            let res = glib_ffi::g_malloc0(mem::size_of::<glib_ffi::GType>() * (t.len() + 1)) as *mut glib_ffi::GType;
            for (i, v) in t.iter().enumerate() {
                *res.offset(i as isize) = v.to_glib();
            }
            res
        }
    }
}

impl FromGlibContainerAsVec<Type, *const glib_ffi::GType> for Type {
    unsafe fn from_glib_none_num_as_vec(ptr: *const glib_ffi::GType, num: usize) -> Vec<Self> {
        if num == 0 || ptr.is_null() {
            return Vec::new();
        }

        let mut res = Vec::with_capacity(num);
        for i in 0..num {
            res.push(from_glib(*ptr.offset(i as isize)));
        }
        res
    }

    unsafe fn from_glib_container_num_as_vec(_: *const glib_ffi::GType, _: usize) -> Vec<Self> {
        // Can't really free a *const
        unimplemented!();
    }

    unsafe fn from_glib_full_num_as_vec(_: *const glib_ffi::GType, _: usize) -> Vec<Self> {
        // Can't really free a *const
        unimplemented!();
    }
}

impl FromGlibContainerAsVec<Type, *mut glib_ffi::GType> for Type {
    unsafe fn from_glib_none_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *const _, num)
    }

    unsafe fn from_glib_container_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        let res = FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
        glib_ffi::g_free(ptr as *mut _);
        res
    }

    unsafe fn from_glib_full_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, num)
    }
}
<commit_msg>Implement StaticType for &mut T in addition to the existing &T<commit_after>// Copyright 2015-2016, 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>

//! Runtime type information.

use translate::{FromGlib, FromGlibContainerAsVec, ToGlib, ToGlibPtr, ToGlibPtrMut, ToGlibContainerFromSlice, from_glib, from_glib_none};
use ffi as glib_ffi;
use gobject_ffi;
use value::{Value, FromValue, FromValueOptional, SetValue};

use std::fmt;
use std::mem;
use std::ptr;

/// A GLib or GLib-based library type
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Type {
    /// An invalid `Type` used as error return value in some functions
    Invalid,
    /// The fundamental type corresponding to the unit type `()`
    Unit,
    /// The fundamental type corresponding to `i8`
    I8,
    /// The fundamental type corresponding to `u8`
    U8,
    /// The fundamental type corresponding to `bool`
    Bool,
    /// The fundamental type corresponding to `i32`
    I32,
    /// The fundamental type corresponding to `u32`
    U32,
    /// The fundamental type corresponding to C `long`
    ILong,
    /// The fundamental type corresponding to C `unsigned long`
    ULong,
    /// The fundamental type corresponding to `i64`
    I64,
    /// The fundamental type corresponding to `u64`
    U64,
    /// The fundamental type corresponding to `f32`
    F32,
    /// The fundamental type corresponding to `f64`
    F64,
    /// The fundamental type corresponding to `String`
    String,
    /// The fundamental type corresponding to a pointer
    Pointer,
    /// The fundamental type of GVariant
    Variant,
    /// The fundamental type from which all interfaces are derived
    BaseInterface,
    /// The fundamental type from which all enumeration types are derived
    BaseEnum,
    /// The fundamental type from which all flags types are derived
    BaseFlags,
    /// The fundamental type from which all boxed types are derived
    BaseBoxed,
    /// The fundamental type from which all `GParamSpec` types are derived
    BaseParamSpec,
    /// The fundamental type from which all objects are derived
    BaseObject,
    /// A non-fundamental type identified by value of type `usize`
    Other(usize),
}

impl Type {
    pub fn name(&self) -> String {
        unsafe {
            from_glib_none(gobject_ffi::g_type_name(self.to_glib()))
        }
    }

    pub fn is_a(&self, other: &Type) -> bool {
        unsafe {
            from_glib(gobject_ffi::g_type_is_a(self.to_glib(), other.to_glib()))
        }
    }

    pub fn parent(&self) -> Option<Self> {
        unsafe {
            let parent = gobject_ffi::g_type_parent(self.to_glib());
            if parent == gobject_ffi::G_TYPE_INVALID {
                None
            } else {
                Some(from_glib(parent))
            }
        }
    }

    pub fn children(&self) -> Vec<Self> {
        unsafe {
            let mut n_children = 0u32;
            let children = gobject_ffi::g_type_children(self.to_glib(), &mut n_children);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(children, n_children as usize)
        }
    }

    pub fn interfaces(&self) -> Vec<Self> {
        unsafe {
            let mut n_interfaces = 0u32;
            let interfaces = gobject_ffi::g_type_interfaces(self.to_glib(), &mut n_interfaces);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(interfaces, n_interfaces as usize)
        }
    }
    pub fn interface_prerequisites(&self) -> Vec<Self> {
        unsafe {
            let mut n_prereqs = 0u32;
            let prereqs = gobject_ffi::g_type_interface_prerequisites(self.to_glib(), &mut n_prereqs);

            FromGlibContainerAsVec::from_glib_full_num_as_vec(prereqs, n_prereqs as usize)
        }
    }

    pub fn from_name<'a, P: Into<&'a str>>(name: P) -> Option<Self> {
        unsafe {
            let type_ = gobject_ffi::g_type_from_name(name.into().to_glib_none().0);
            if type_ == gobject_ffi::G_TYPE_INVALID {
                None
            } else {
                Some(from_glib(type_))
            }
        }
    }
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.name())
    }
}

impl fmt::Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.name())
    }
}

/// Types that are supported by GLib dynamic typing.
pub trait StaticType {
    /// Returns the type identifier of `Self`.
    fn static_type() -> Type;
}

impl StaticType for Type {
    fn static_type() -> Type {
        unsafe {
            from_glib(gobject_ffi::g_gtype_get_type())
        }
    }
}

impl<'a> FromValueOptional<'a> for Type {
    unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
        Some(from_glib(gobject_ffi::g_value_get_gtype(value.to_glib_none().0)))
    }
}

impl<'a> FromValue<'a> for Type {
    unsafe fn from_value(value: &'a Value) -> Self {
        from_glib(gobject_ffi::g_value_get_gtype(value.to_glib_none().0))
    }
}

impl SetValue for Type {
    unsafe fn set_value(value: &mut Value, this: &Self) {
        gobject_ffi::g_value_set_gtype(value.to_glib_none_mut().0, this.to_glib())
    }
}

impl<'a, T: ?Sized + StaticType> StaticType for &'a T {
    fn static_type() -> Type {
        T::static_type()
    }
}

impl<'a, T: ?Sized + StaticType> StaticType for &'a mut T {
    fn static_type() -> Type {
        T::static_type()
    }
}

macro_rules! builtin {
    ($name:ident, $val:ident) => {
        impl StaticType for $name {
            fn static_type() -> Type {
                Type::$val
            }
        }
    }
}

builtin!(bool, Bool);
builtin!(i8, I8);
builtin!(u8, U8);
builtin!(i32, I32);
builtin!(u32, U32);
builtin!(i64, I64);
builtin!(u64, U64);
builtin!(f32, F32);
builtin!(f64, F64);
builtin!(str, String);
builtin!(String, String);

impl<'a> StaticType for [&'a str] {
    fn static_type() -> Type {
        unsafe {
            from_glib(glib_ffi::g_strv_get_type())
        }
    }
}

impl StaticType for Vec<String> {
    fn static_type() -> Type {
        unsafe {
            from_glib(glib_ffi::g_strv_get_type())
        }
    }
}

#[inline]
pub unsafe fn instance_of<C: StaticType>(ptr: glib_ffi::gconstpointer) -> bool {
    from_glib(
        gobject_ffi::g_type_check_instance_is_a(
            ptr as *mut _, <C as StaticType>::static_type().to_glib()))
}

impl FromGlib<glib_ffi::GType> for Type {
    #[inline]
    fn from_glib(val: glib_ffi::GType) -> Type {
        use self::Type::*;
        match val {
            gobject_ffi::G_TYPE_INVALID => Invalid,
            gobject_ffi::G_TYPE_NONE => Unit,
            gobject_ffi::G_TYPE_INTERFACE => BaseInterface,
            gobject_ffi::G_TYPE_CHAR => I8,
            gobject_ffi::G_TYPE_UCHAR => U8,
            gobject_ffi::G_TYPE_BOOLEAN => Bool,
            gobject_ffi::G_TYPE_INT => I32,
            gobject_ffi::G_TYPE_UINT => U32,
            gobject_ffi::G_TYPE_LONG => ILong,
            gobject_ffi::G_TYPE_ULONG => ULong,
            gobject_ffi::G_TYPE_INT64 => I64,
            gobject_ffi::G_TYPE_UINT64 => U64,
            gobject_ffi::G_TYPE_ENUM => BaseEnum,
            gobject_ffi::G_TYPE_FLAGS => BaseFlags,
            gobject_ffi::G_TYPE_FLOAT => F32,
            gobject_ffi::G_TYPE_DOUBLE => F64,
            gobject_ffi::G_TYPE_STRING => String,
            gobject_ffi::G_TYPE_POINTER => Pointer,
            gobject_ffi::G_TYPE_BOXED => BaseBoxed,
            gobject_ffi::G_TYPE_PARAM => BaseParamSpec,
            gobject_ffi::G_TYPE_OBJECT => BaseObject,
            gobject_ffi::G_TYPE_VARIANT => Variant,
            x => Other(x as usize),
        }
    }
}

impl ToGlib for Type {
    type GlibType = glib_ffi::GType;

    fn to_glib(&self) -> glib_ffi::GType {
        use self::Type::*;
        match *self {
            Invalid => gobject_ffi::G_TYPE_INVALID,
            Unit => gobject_ffi::G_TYPE_NONE,
            BaseInterface => gobject_ffi::G_TYPE_INTERFACE,
            I8 => gobject_ffi::G_TYPE_CHAR,
            U8 => gobject_ffi::G_TYPE_UCHAR,
            Bool => gobject_ffi::G_TYPE_BOOLEAN,
            I32 => gobject_ffi::G_TYPE_INT,
            U32 => gobject_ffi::G_TYPE_UINT,
            ILong => gobject_ffi::G_TYPE_LONG,
            ULong => gobject_ffi::G_TYPE_ULONG,
            I64 => gobject_ffi::G_TYPE_INT64,
            U64 => gobject_ffi::G_TYPE_UINT64,
            BaseEnum => gobject_ffi::G_TYPE_ENUM,
            BaseFlags => gobject_ffi::G_TYPE_FLAGS,
            F32 => gobject_ffi::G_TYPE_FLOAT,
            F64 => gobject_ffi::G_TYPE_DOUBLE,
            String => gobject_ffi::G_TYPE_STRING,
            Pointer => gobject_ffi::G_TYPE_POINTER,
            BaseBoxed => gobject_ffi::G_TYPE_BOXED,
            BaseParamSpec => gobject_ffi::G_TYPE_PARAM,
            BaseObject => gobject_ffi::G_TYPE_OBJECT,
            Variant => gobject_ffi::G_TYPE_VARIANT,
            Other(x) => x as glib_ffi::GType,
        }
    }
}

impl<'a> ToGlibContainerFromSlice<'a, *mut glib_ffi::GType> for Type {
    type Storage = Option<Vec<glib_ffi::GType>>;

    fn to_glib_none_from_slice(t: &'a [Type]) -> (*mut glib_ffi::GType, Self::Storage) {
        let mut vec = t.iter().map(|v| v.to_glib()).collect::<Vec<_>>();

        (vec.as_mut_ptr(), Some(vec))
    }

    fn to_glib_container_from_slice(t: &'a [Type]) -> (*mut glib_ffi::GType, Self::Storage) {
        (Self::to_glib_full_from_slice(t), None)
    }

    fn to_glib_full_from_slice(t: &[Type]) -> *mut glib_ffi::GType {
        if t.is_empty() {
            return ptr::null_mut();
        }

        unsafe {
            let res = glib_ffi::g_malloc0(mem::size_of::<glib_ffi::GType>() * (t.len() + 1)) as *mut glib_ffi::GType;
            for (i, v) in t.iter().enumerate() {
                *res.offset(i as isize) = v.to_glib();
            }
            res
        }
    }
}

impl FromGlibContainerAsVec<Type, *const glib_ffi::GType> for Type {
    unsafe fn from_glib_none_num_as_vec(ptr: *const glib_ffi::GType, num: usize) -> Vec<Self> {
        if num == 0 || ptr.is_null() {
            return Vec::new();
        }

        let mut res = Vec::with_capacity(num);
        for i in 0..num {
            res.push(from_glib(*ptr.offset(i as isize)));
        }
        res
    }

    unsafe fn from_glib_container_num_as_vec(_: *const glib_ffi::GType, _: usize) -> Vec<Self> {
        // Can't really free a *const
        unimplemented!();
    }

    unsafe fn from_glib_full_num_as_vec(_: *const glib_ffi::GType, _: usize) -> Vec<Self> {
        // Can't really free a *const
        unimplemented!();
    }
}

impl FromGlibContainerAsVec<Type, *mut glib_ffi::GType> for Type {
    unsafe fn from_glib_none_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *const _, num)
    }

    unsafe fn from_glib_container_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        let res = FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
        glib_ffi::g_free(ptr as *mut _);
        res
    }

    unsafe fn from_glib_full_num_as_vec(ptr: *mut glib_ffi::GType, num: usize) -> Vec<Self> {
        FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, num)
    }
}
<|endoftext|>


<commit_before>pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}
<commit_msg>Add `BufferBits` bitflags<commit_after>use super::gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}
<|endoftext|>