<commit_before>use parametric::{Param, ReParam};
use super::{Invariant, InvariantOnce};

pub trait Iso<A, B> {
    fn to(&self, A) -> B;
    fn from(&self, B) -> A;
}

pub trait IsoOnce<A, B> {
    fn to_once(self, A) -> B;
    fn from_once(self, B) -> A;
}

impl<A, B, F, G> Iso<A, B> for (F, G) where F: Fn(A) -> B, G: Fn(B) -> A {
    fn to(&self, a: A) -> B { self.0(a) }
    fn from(&self, b: B) -> A { self.1(b) }
}

impl<A, B, F, G> IsoOnce<A, B> for (F, G) where F: FnOnce(A) -> B, G: FnOnce(B) -> A {
    fn to_once(self, a: A) -> B { self.0(a) }
    fn from_once(self, b: B) -> A { self.1(b) }
}
<commit_msg>remove unused imports<commit_after>pub trait Iso<A, B> {
    fn to(&self, A) -> B;
    fn from(&self, B) -> A;
}

pub trait IsoOnce<A, B> {
    fn to_once(self, A) -> B;
    fn from_once(self, B) -> A;
}

impl<A, B, F, G> Iso<A, B> for (F, G) where F: Fn(A) -> B, G: Fn(B) -> A {
    fn to(&self, a: A) -> B { self.0(a) }
    fn from(&self, b: B) -> A { self.1(b) }
}

impl<A, B, F, G> IsoOnce<A, B> for (F, G) where F: FnOnce(A) -> B, G: FnOnce(B) -> A {
    fn to_once(self, a: A) -> B { self.0(a) }
    fn from_once(self, b: B) -> A { self.1(b) }
}
<|endoftext|>


<commit_before>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::{WlcView, WlcOutput, Geometry, Point, ResizeEdge};

pub type TreeErr = TryLockError<MutexGuard<'static, Tree>>;
pub type TreeResult = Result<MutexGuard<'static, Tree>, TreeErr>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

// NOTE Make an actual image of this, embed in documentation
/* An example Tree:

      Root
        |
    ____|____
   /         \
   |         |
 Output    Output
   |         |
 Workspace   |
   |        / \
   |       /   \
   | Workspace Workspace
   |     |         |
   |  Container Container
 Container
    |
   / \
  /   \
  |    \
  |     \
  |      \
  |       \
 Container \
     |      \
   View    View
 */

/// A Tree of Nodes.
///
/// There are various invariants that the tree upholds:
///
///   + Root
///       - There is only one Root
///       - The root can only have Outputs (monitors) as children
///   + Output
///       - An Output must have at least one Workspace associated with it
///       - An Output must be associated with a WlcOutput (real monitor)
///       - An Output can only have Workspaces as children
///   + Workspace
///       - A Workspace must have at least one Container, even if it doesn't
///         contain any views
///       - A Workspace can only have Containers as children
///   + Container
///       - A Container can only have other Containers or Views as children
///   + View
///       - A View must be associated with a WlcView
///       - A View cannot have any children
#[derive(Debug)]
pub struct Tree {
    root: Node,
    active_container: *const Node,
}

unsafe impl Send for Tree {}

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

impl Tree {

    /// Moves the current active container to a new workspace
    pub fn move_container_to_workspace(&mut self, name: &str) {
        if self.get_active_container().is_none() {
            return;
        }
        if let Some(workspace) = self.get_active_workspace() {
            if workspace.get_children().len() == 1 {
                if workspace.get_children()[0].get_children().len() == 0 {
                    warn!("Tried to move a container not made by the user");
                    return;
                }
            }
            if workspace.get_val().get_name().unwrap() == name {
                warn!("Tried to switch to already current workspace");
                return;
            }
        }
        match self.get_active_container().unwrap().get_val().get_type() {
            //ContainerType::Container => {},
            ContainerType::View => {},
            _ => {
                warn!("Tried to switch workspace on a non-view/container");
                return
            }
        }
        if self.get_workspace_by_name(name).is_none() {
            self.add_workspace(name.to_string());
        }
        info!("Moving container {:?} to workspace {}", self.get_active_container(), name);
        let new_active_container = self.get_active_container().unwrap().get_parent().unwrap()
            as *const Node;
        let moved_container: Node;
        {
            let container = self.get_active_container().unwrap().as_mut();

            // Make view invisible, switch focus
            {
                let parent = container.get_parent().expect("Had no parent");
                // There is another view we can focus on
                if parent.get_children().len() > 1 {
                    trace!("Attempting to focus on a view");
                    let mut children_pool: Vec<&Node>  = parent.get_children().iter()
                        .filter(|child| *child != container).collect();
                    while children_pool.len() > 0 {
                        let child = children_pool.pop().unwrap();
                        if child.get_val().get_type() == ContainerType::View {
                            trace!("Focused on a view");
                            match child.get_val().get_handle().unwrap() {
                                Handle::View(view) => view.focus(),
                                _ => panic!("Expect WlcView, got WlcOutput"),
                            }
                            break;
                        } else {
                            let more_children: Vec<&Node> = child.get_children().iter()
                                .collect();
                            children_pool.extend(more_children);
                        }
                    }
                } else {
                    trace!("Focusing on root, because no other views");
                    WlcView::root().focus();
                }
            }
            moved_container = container.remove_from_parent()
                .expect("Could not remove container, was not part of tree");
            container.set_visibility(false);
            trace!("Removed container {:?}", moved_container);
        }
        if let Some(workspace) = self.get_workspace_by_name(name) {
            let new_parent_container = &mut workspace.as_mut().get_children_mut()[0];
            new_parent_container.new_child(moved_container.get_val().clone())
                .expect("Could not moved container to other a workspace");
            trace!("Added previously removed container to {:?} in workspace {}",
                    new_parent_container,
                    name);
        }
        self.active_container = new_active_container;
    }

    /// Switch to the workspace with the give name
    pub fn switch_workspace(&mut self, name: &str ) {
        if self.active_container.is_null() {
            warn!("No current active container, cannot switch workspace");
            return;
        }
        if let Some(old_workspace) = self.get_active_workspace() {
            trace!("Switching to workspace {}", name);
            old_workspace.as_mut().set_visibility(false);
        } else {
            warn!("Could not find old workspace, could not set invisible");
            return;
        }
        if let Some(_) = self.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            self.add_workspace(name.to_string());
        }
        let new_active_container: *const Node;
        {
            if let Some(_) = self.get_workspace_by_name(name) {
                trace!("Found workspace {}", name);
            } else {
                trace!("Adding workspace {}", name);
                self.add_workspace(name.to_string());
            }
            let new_current_workspace = self.get_workspace_by_name_mut(name)
                .expect(ERR_BAD_TREE).as_mut();
            new_current_workspace.set_visibility(true);
            /* Set the first view to be focused, so the screen refreshes itself */
            if new_current_workspace.get_children()[0].get_children().len() > 0 {
                trace!("Focusing view");
                let view_container = &new_current_workspace.get_children_mut()[0]
                    .get_children_mut()[0];
                match view_container.get_val().get_handle().expect(ERR_BAD_TREE) {
                    Handle::View(view) => view.focus(),
                    _ => {panic!("Expected view, got Wlc Output")},
                }
                new_active_container = view_container as *const Node;
            }
            /* If there is no view in the new workspace, just set the focused container
               to be the workspace */
            else {
                new_active_container = new_current_workspace as *const Node;
                WlcView::root().focus();
            }
        }
        // Update the tree's pointer to the currently focused container
        self.active_container = new_active_container;
    }

    /// Returns the currently active container.
    ///
    /// Note that this might be at certain times this might simply be
    /// an Output or a Workspace to ensure other methods work.
    ///
    /// NOTE This should change because a nice invariant to have would
    /// be that `get_active_container` only returns either a container
    /// or a view, since those are the only nodes that can be "active".
    pub fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    /// Get the monitor (output) that the active container is located on
    pub fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            if node.get_val().get_type() == ContainerType::Output {
                Some(node)
            } else {
                node.get_ancestor_of_type(ContainerType::Output)
            }
        } else {
            None
        }
    }

    /// Get the workspace that the active container is located on
    pub fn get_active_workspace(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            if node.get_val().get_type() == ContainerType::Workspace {
                return Some(node)
            }
            if let Some(workspace) = node.get_ancestor_of_type(ContainerType::Workspace) {
                return Some(workspace)
            }
        }
        return None
    }

    /// Find the workspace node that has the given name
    pub fn get_workspace_by_name(&mut self, name: &str) -> Option<&Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Find the workspace node that has the given name, with a mutable reference
    pub fn get_workspace_by_name_mut(&mut self, name: &str) -> Option<&Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Make a new output container with the given WlcOutput.
    ///
    /// A new workspace is automatically added to the output, to ensure
    /// consistency with the tree. By default, it sets this new workspace to
    /// be workspace "1". This will later change to be the first available
    /// workspace if using i3-style workspaces.
    pub fn add_output(&mut self, wlc_output: WlcOutput) {
        trace!("Adding new output with WlcOutput: {:?}", wlc_output);
        match self.root.new_child(Container::new_output(wlc_output)) {
            Ok(output) => {
                // Need to set active container to this output so that
                // add_workspace know where to put the new workspace
                self.active_container = output as *const Node;
            },
            Err(e) => {
                error!("Could not add output: {:?}", e);
                return;
            }
        }
        // NOTE Should probably not be "1", should be the next unclaimed number
        self.active_container = self.add_workspace("1".to_string()).unwrap() as *const Node;
    }

    /// Make a new workspace container with the given name.
    ///
    /// A new container is automatically added to the workspace, to ensure
    /// consistency with the tree. This container has no children, and should
    /// not be moved.
    ///
    /// NOTE Consider changing it to be a different type, something that will not and can
    /// not be moved? Another container type to check against then?
    pub fn add_workspace(&mut self, name: String) -> Option<&Node> {
        let mut new_active_container: *const Node = ptr::null();
        if let Some(output) = self.get_active_output() {
            let size = output.get_val().get_geometry()
                .expect("Output did not have a geometry").size;
            let workspace = Container::new_workspace(name.to_string(),
                                                     size.clone());
            match output.as_mut().new_child(workspace) {
                Ok(workspace) => {
                    trace!("Added workspace {:?}", workspace);
                    let geometry = Geometry {
                        size: size,
                        origin: Point { x: 0, y: 0}
                    };
                    match workspace.new_child(Container::new_container(geometry)) {
                        Err(e) => error!("Could not add container to workspace: {:?}",e ),
                        // New active container should be this container of the new workspace
                        Ok(container) => new_active_container = container as *const Node,
                    };
                    return Some(workspace);
                },
                Err(e) => error!("Could not add workspace: {:?}", e),
            }
        } else {
            warn!("Could not get active output");
        }
        None
    }

    /// Make a new view container with the given WlcView, and adds it to
    /// the active workspace.
    pub fn add_view(&mut self, wlc_view: WlcView) {
        let mut maybe_new_view: *const Node = ptr::null();
        if let Some(current_workspace) = self.get_active_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            if current_workspace.get_children().len() == 0 {
                let output = self.get_active_output()
                    .expect("Could not get active output");
                let output_size = output.get_val().get_geometry()
                    .expect("Could not get geometry from output").size;
                let mut geometry = wlc_view.get_geometry()
                    .expect("Could not get geometry from wlc view").clone();
                // Ensure that it starts within the bounds
                // Width
                if geometry.origin.x > output_size.w as i32 {
                    geometry.origin.x = output_size.w as i32 ;
                } else if geometry.origin.x < 0 {
                    geometry.origin.x = 0;
                }
                // Height
                if geometry.origin.y > output_size.h as i32 {
                    geometry.origin.y = output_size.h as i32;
                } else if geometry.origin.y < 0 {
                    geometry.origin.y = 0;
                }
                wlc_view.set_geometry(ResizeEdge::empty(), &geometry);
                match current_workspace.as_mut().new_child(Container::new_container(geometry)) {
                    Ok(_) => {},
                    Err(e) => {
                        error!("Could not add workspace: {:?}", e);
                        return;
                    }
                }
            }
            let container = &mut current_workspace.as_mut().get_children_mut()[0];
            match container.new_child(Container::new_view(wlc_view)) {
                Ok(view_node) => {
                    maybe_new_view = view_node as *const Node;
                },
                Err(e) => {
                    error!("Could not add view to current workspace: {:?}", e);
                    return;
                }
            }
        };
        if ! maybe_new_view.is_null() {
            self.active_container = maybe_new_view as *const Node;
        }
    }

    /// Remove the view container with the given view
    ///
    /// If this is the only view of that container, and that container
    /// is not the only one in the workspace, then that container is also
    /// removed.
    ///
    /// NOTE Implement \^\^\^
    pub fn remove_view(&self, wlc_view: WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

/// Attempts to lock the tree. If the Result is Err, then a thread that
/// previously had the lock panicked and potentially left the tree in a bad state
pub fn try_lock_tree() -> TreeResult {
    trace!("Locking the tree!");
    TREE.try_lock()
}
<commit_msg>Removed get_workspace_by_name_mut<commit_after>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::{WlcView, WlcOutput, Geometry, Point, ResizeEdge};

pub type TreeErr = TryLockError<MutexGuard<'static, Tree>>;
pub type TreeResult = Result<MutexGuard<'static, Tree>, TreeErr>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

// NOTE Make an actual image of this, embed in documentation
/* An example Tree:

      Root
        |
    ____|____
   /         \
   |         |
 Output    Output
   |         |
 Workspace   |
   |        / \
   |       /   \
   | Workspace Workspace
   |     |         |
   |  Container Container
 Container
    |
   / \
  /   \
  |    \
  |     \
  |      \
  |       \
 Container \
     |      \
   View    View
 */

/// A Tree of Nodes.
///
/// There are various invariants that the tree upholds:
///
///   + Root
///       - There is only one Root
///       - The root can only have Outputs (monitors) as children
///   + Output
///       - An Output must have at least one Workspace associated with it
///       - An Output must be associated with a WlcOutput (real monitor)
///       - An Output can only have Workspaces as children
///   + Workspace
///       - A Workspace must have at least one Container, even if it doesn't
///         contain any views
///       - A Workspace can only have Containers as children
///   + Container
///       - A Container can only have other Containers or Views as children
///   + View
///       - A View must be associated with a WlcView
///       - A View cannot have any children
#[derive(Debug)]
pub struct Tree {
    root: Node,
    active_container: *const Node,
}

unsafe impl Send for Tree {}

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

impl Tree {

    /// Moves the current active container to a new workspace
    pub fn move_container_to_workspace(&mut self, name: &str) {
        if self.get_active_container().is_none() {
            return;
        }
        if let Some(workspace) = self.get_active_workspace() {
            if workspace.get_children().len() == 1 {
                if workspace.get_children()[0].get_children().len() == 0 {
                    warn!("Tried to move a container not made by the user");
                    return;
                }
            }
            if workspace.get_val().get_name().unwrap() == name {
                warn!("Tried to switch to already current workspace");
                return;
            }
        }
        match self.get_active_container().unwrap().get_val().get_type() {
            //ContainerType::Container => {},
            ContainerType::View => {},
            _ => {
                warn!("Tried to switch workspace on a non-view/container");
                return
            }
        }
        if self.get_workspace_by_name(name).is_none() {
            self.add_workspace(name.to_string());
        }
        info!("Moving container {:?} to workspace {}", self.get_active_container(), name);
        let new_active_container = self.get_active_container().unwrap().get_parent().unwrap()
            as *const Node;
        let moved_container: Node;
        {
            let container = self.get_active_container().unwrap().as_mut();

            // Make view invisible, switch focus
            {
                let parent = container.get_parent().expect("Had no parent");
                // There is another view we can focus on
                if parent.get_children().len() > 1 {
                    trace!("Attempting to focus on a view");
                    let mut children_pool: Vec<&Node>  = parent.get_children().iter()
                        .filter(|child| *child != container).collect();
                    while children_pool.len() > 0 {
                        let child = children_pool.pop().unwrap();
                        if child.get_val().get_type() == ContainerType::View {
                            trace!("Focused on a view");
                            match child.get_val().get_handle().unwrap() {
                                Handle::View(view) => view.focus(),
                                _ => panic!("Expect WlcView, got WlcOutput"),
                            }
                            break;
                        } else {
                            let more_children: Vec<&Node> = child.get_children().iter()
                                .collect();
                            children_pool.extend(more_children);
                        }
                    }
                } else {
                    trace!("Focusing on root, because no other views");
                    WlcView::root().focus();
                }
            }
            moved_container = container.remove_from_parent()
                .expect("Could not remove container, was not part of tree");
            container.set_visibility(false);
            trace!("Removed container {:?}", moved_container);
        }
        if let Some(workspace) = self.get_workspace_by_name(name) {
            let new_parent_container = &mut workspace.as_mut().get_children_mut()[0];
            new_parent_container.new_child(moved_container.get_val().clone())
                .expect("Could not moved container to other a workspace");
            trace!("Added previously removed container to {:?} in workspace {}",
                    new_parent_container,
                    name);
        }
        self.active_container = new_active_container;
    }

    /// Switch to the workspace with the give name
    pub fn switch_workspace(&mut self, name: &str ) {
        if self.active_container.is_null() {
            warn!("No current active container, cannot switch workspace");
            return;
        }
        if let Some(old_workspace) = self.get_active_workspace() {
            trace!("Switching to workspace {}", name);
            old_workspace.as_mut().set_visibility(false);
        } else {
            warn!("Could not find old workspace, could not set invisible");
            return;
        }
        if let Some(_) = self.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            self.add_workspace(name.to_string());
        }
        let new_active_container: *const Node;
        {
            if let Some(_) = self.get_workspace_by_name(name) {
                trace!("Found workspace {}", name);
            } else {
                trace!("Adding workspace {}", name);
                self.add_workspace(name.to_string());
            }
            let new_current_workspace = self.get_workspace_by_name(name)
                .expect(ERR_BAD_TREE).as_mut();
            new_current_workspace.set_visibility(true);
            /* Set the first view to be focused, so the screen refreshes itself */
            if new_current_workspace.get_children()[0].get_children().len() > 0 {
                trace!("Focusing view");
                let view_container = &new_current_workspace.get_children_mut()[0]
                    .get_children_mut()[0];
                match view_container.get_val().get_handle().expect(ERR_BAD_TREE) {
                    Handle::View(view) => view.focus(),
                    _ => {panic!("Expected view, got Wlc Output")},
                }
                new_active_container = view_container as *const Node;
            }
            /* If there is no view in the new workspace, just set the focused container
               to be the workspace */
            else {
                new_active_container = new_current_workspace as *const Node;
                WlcView::root().focus();
            }
        }
        // Update the tree's pointer to the currently focused container
        self.active_container = new_active_container;
    }

    /// Returns the currently active container.
    ///
    /// Note that this might be at certain times this might simply be
    /// an Output or a Workspace to ensure other methods work.
    ///
    /// NOTE This should change because a nice invariant to have would
    /// be that `get_active_container` only returns either a container
    /// or a view, since those are the only nodes that can be "active".
    pub fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    /// Get the monitor (output) that the active container is located on
    pub fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            if node.get_val().get_type() == ContainerType::Output {
                Some(node)
            } else {
                node.get_ancestor_of_type(ContainerType::Output)
            }
        } else {
            None
        }
    }

    /// Get the workspace that the active container is located on
    pub fn get_active_workspace(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            if node.get_val().get_type() == ContainerType::Workspace {
                return Some(node)
            }
            if let Some(workspace) = node.get_ancestor_of_type(ContainerType::Workspace) {
                return Some(workspace)
            }
        }
        return None
    }

    /// Find the workspace node that has the given name
    pub fn get_workspace_by_name(&mut self, name: &str) -> Option<&Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Make a new output container with the given WlcOutput.
    ///
    /// A new workspace is automatically added to the output, to ensure
    /// consistency with the tree. By default, it sets this new workspace to
    /// be workspace "1". This will later change to be the first available
    /// workspace if using i3-style workspaces.
    pub fn add_output(&mut self, wlc_output: WlcOutput) {
        trace!("Adding new output with WlcOutput: {:?}", wlc_output);
        match self.root.new_child(Container::new_output(wlc_output)) {
            Ok(output) => {
                // Need to set active container to this output so that
                // add_workspace know where to put the new workspace
                self.active_container = output as *const Node;
            },
            Err(e) => {
                error!("Could not add output: {:?}", e);
                return;
            }
        }
        // NOTE Should probably not be "1", should be the next unclaimed number
        self.active_container = self.add_workspace("1".to_string()).unwrap() as *const Node;
    }

    /// Make a new workspace container with the given name.
    ///
    /// A new container is automatically added to the workspace, to ensure
    /// consistency with the tree. This container has no children, and should
    /// not be moved.
    ///
    /// NOTE Consider changing it to be a different type, something that will not and can
    /// not be moved? Another container type to check against then?
    pub fn add_workspace(&mut self, name: String) -> Option<&Node> {
        let mut new_active_container: *const Node = ptr::null();
        if let Some(output) = self.get_active_output() {
            let size = output.get_val().get_geometry()
                .expect("Output did not have a geometry").size;
            let workspace = Container::new_workspace(name.to_string(),
                                                     size.clone());
            match output.as_mut().new_child(workspace) {
                Ok(workspace) => {
                    trace!("Added workspace {:?}", workspace);
                    let geometry = Geometry {
                        size: size,
                        origin: Point { x: 0, y: 0}
                    };
                    match workspace.new_child(Container::new_container(geometry)) {
                        Err(e) => error!("Could not add container to workspace: {:?}",e ),
                        // New active container should be this container of the new workspace
                        Ok(container) => new_active_container = container as *const Node,
                    };
                    return Some(workspace);
                },
                Err(e) => error!("Could not add workspace: {:?}", e),
            }
        } else {
            warn!("Could not get active output");
        }
        None
    }

    /// Make a new view container with the given WlcView, and adds it to
    /// the active workspace.
    pub fn add_view(&mut self, wlc_view: WlcView) {
        let mut maybe_new_view: *const Node = ptr::null();
        if let Some(current_workspace) = self.get_active_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            if current_workspace.get_children().len() == 0 {
                let output = self.get_active_output()
                    .expect("Could not get active output");
                let output_size = output.get_val().get_geometry()
                    .expect("Could not get geometry from output").size;
                let mut geometry = wlc_view.get_geometry()
                    .expect("Could not get geometry from wlc view").clone();
                // Ensure that it starts within the bounds
                // Width
                if geometry.origin.x > output_size.w as i32 {
                    geometry.origin.x = output_size.w as i32 ;
                } else if geometry.origin.x < 0 {
                    geometry.origin.x = 0;
                }
                // Height
                if geometry.origin.y > output_size.h as i32 {
                    geometry.origin.y = output_size.h as i32;
                } else if geometry.origin.y < 0 {
                    geometry.origin.y = 0;
                }
                wlc_view.set_geometry(ResizeEdge::empty(), &geometry);
                match current_workspace.as_mut().new_child(Container::new_container(geometry)) {
                    Ok(_) => {},
                    Err(e) => {
                        error!("Could not add workspace: {:?}", e);
                        return;
                    }
                }
            }
            let container = &mut current_workspace.as_mut().get_children_mut()[0];
            match container.new_child(Container::new_view(wlc_view)) {
                Ok(view_node) => {
                    maybe_new_view = view_node as *const Node;
                },
                Err(e) => {
                    error!("Could not add view to current workspace: {:?}", e);
                    return;
                }
            }
        };
        if ! maybe_new_view.is_null() {
            self.active_container = maybe_new_view as *const Node;
        }
    }

    /// Remove the view container with the given view
    ///
    /// If this is the only view of that container, and that container
    /// is not the only one in the workspace, then that container is also
    /// removed.
    ///
    /// NOTE Implement \^\^\^
    pub fn remove_view(&self, wlc_view: WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

/// Attempts to lock the tree. If the Result is Err, then a thread that
/// previously had the lock panicked and potentially left the tree in a bad state
pub fn try_lock_tree() -> TreeResult {
    trace!("Locking the tree!");
    TREE.try_lock()
}
<|endoftext|>


<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(missing_docs, missing_copy_implementations)]

//! Device resource handles

use std::mem;
use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::Arc;
use super::{shade, tex, Resources, BufferInfo};

/// Stores reference-counted resources used in a command buffer.
/// Seals actual resource names behind the interface, automatically
/// referencing them both by the Factory on resource creation
/// and the Renderer during CommandBuffer population.
#[allow(missing_docs)]
pub struct RefStorage<R: Resources> {
    buffers: Vec<Arc<R::Buffer>>,
    array_buffers: Vec<Arc<R::ArrayBuffer>>,
    //TODO
}

/// A service trait to be used by the device implementation
pub trait HandleFactory<R: Resources> {
    /// Create a new raw buffer handle
    fn new_buffer(&mut self, R::Buffer, BufferInfo) -> RawBuffer<R>;
    /// Create a new array buffer
    fn new_array_buffer(&mut self, R::ArrayBuffer) -> ArrayBuffer<R>;
}

impl<R: Resources> HandleFactory<R> for RefStorage<R> {
    fn new_buffer(&mut self, name: R::Buffer, info: BufferInfo) -> RawBuffer<R> {
        let r = Arc::new(name);
        self.buffers.push(r.clone());
        RawBuffer(r, info)
    }

    fn new_array_buffer(&mut self, name: R::ArrayBuffer) -> ArrayBuffer<R> {
        let r = Arc::new(name);
        self.array_buffers.push(r.clone());
        ArrayBuffer(r)
    }
}

impl<R: Resources> RefStorage<R> {
    /// Create a new reference storage
    pub fn new() -> RefStorage<R> {
        RefStorage {
            buffers: Vec::new(),
            array_buffers: Vec::new(),
        }
    }
    /// Remove all references
    pub fn reset(&mut self) {
        self.buffers.clear();
    }
    /// Extend with references from another buffer
    pub fn extend(&mut self, other: &RefStorage<R>) {
        self.buffers.extend(other.buffers.iter().map(|b| b.clone()));
    }
    /// Reference a buffer inside the storage
    pub fn ref_buffer(&mut self, handle: &RawBuffer<R>) -> R::Buffer {
        self.buffers.push(handle.0.clone());
        *handle.0.deref()
    }
    /// Reference am array buffer inside the storage
    pub fn ref_array_buffer(&mut self, handle: &ArrayBuffer<R>) -> R::ArrayBuffer {
        self.array_buffers.push(handle.0.clone());
        *handle.0.deref()
    }
}

/// Type-safe buffer handle
#[derive(Clone, PartialEq, Debug)]
pub struct Buffer<R: Resources, T> {
    raw: RawBuffer<R>,
    phantom_t: PhantomData<T>,
}

impl<R: Resources, T> Buffer<R, T> {
    /// Create a type-safe BufferHandle from a RawBufferHandle
    pub fn from_raw(handle: RawBuffer<R>) -> Buffer<R, T> {
        Buffer {
            raw: handle,
            phantom_t: PhantomData,
        }
    }

    /// Cast the type this Buffer references
    pub fn cast<U>(self) -> Buffer<R, U> {
        Buffer::from_raw(self.raw)
    }

    /// Get the underlying raw Handle
    pub fn raw(&self) -> &RawBuffer<R> {
        &self.raw
    }

    /// Get the associated information about the buffer
    pub fn get_info(&self) -> &BufferInfo {
        self.raw.get_info()
    }

    /// Get the number of elements in the buffer.
    ///
    /// Fails if `T` is zero-sized.
    pub fn len(&self) -> usize {
        assert!(mem::size_of::<T>() != 0, "Cannot determine the length of zero-sized buffers.");
        self.get_info().size / mem::size_of::<T>()
    }
}

/// Raw (untyped) Buffer Handle
#[derive(Clone, PartialEq, Debug)]
pub struct RawBuffer<R: Resources>(Arc<R::Buffer>, BufferInfo);

impl<R: Resources> RawBuffer<R> {
    /// Get raw buffer info
    pub fn get_info(&self) -> &BufferInfo { &self.1 }
}

/// Array Buffer Handle
#[derive(Clone, PartialEq, Debug)]
pub struct ArrayBuffer<R: Resources>(Arc<R::ArrayBuffer>);

/// Shader Handle
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Shader<R: Resources>(R::Shader, shade::Stage);

impl<R: Resources> Shader<R> {
    /// Creates a new shader (used by device)
    pub unsafe fn new(name: R::Shader, info: shade::Stage)
        -> Shader<R> {
        Shader(name, info)
    }
    /// Get shader name
    pub fn get_name(&self) -> R::Shader { self.0 }
    /// Get shader info
    pub fn get_info(&self) -> &shade::Stage { &self.1 }
}

/// Program Handle
#[derive(Clone, PartialEq, Debug)]
pub struct Program<R: Resources>(
    R::Program,
    shade::ProgramInfo,
);

impl<R: Resources> Program<R> {
    /// Creates a new program (used by device)
    pub unsafe fn new(name: <R as Resources>::Program, info: shade::ProgramInfo)
        -> Program<R> {
        Program(name, info)
    }
    /// Get program name
    pub fn get_name(&self) -> R::Program { self.0 }
    /// Get program info
    pub fn get_info(&self) -> &shade::ProgramInfo { &self.1 }
}

/// Frame Buffer Handle
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct FrameBuffer<R: Resources>(<R as Resources>::FrameBuffer);

impl<R: Resources> FrameBuffer<R> {
    /// Creates a new frame buffer (used by device)
    pub unsafe fn new(name: <R as Resources>::FrameBuffer)
        -> FrameBuffer<R> {
        FrameBuffer(name)
    }
    /// Get frame buffer name
    pub fn get_name(&self) -> <R as Resources>::FrameBuffer { self.0 }
}

/// Surface Handle
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Surface<R: Resources>(
    <R as Resources>::Surface,
    tex::SurfaceInfo,
);

impl<R: Resources> Surface<R> {
    /// Creates a new surface (used by device)
    pub unsafe fn new(name: <R as Resources>::Surface, info: tex::SurfaceInfo)
        -> Surface<R> {
        Surface(name, info)
    }
    /// Get surface name
    pub fn get_name(&self) -> <R as Resources>::Surface { self.0 }
    /// Get surface info
    pub fn get_info(&self) -> &tex::SurfaceInfo { &self.1 }
}

/// Texture Handle
#[derive(PartialEq, Debug)]
pub struct Texture<R: Resources>(
    <R as Resources>::Texture,
    tex::TextureInfo,
);

impl<R: Resources> Copy for Texture<R> {}

impl<R: Resources> Clone for Texture<R> {
    fn clone(&self) -> Texture<R> {
        Texture(self.0, self.1.clone())
    }
}

impl<R: Resources> Texture<R> {
    /// Creates a new texture (used by device)
    pub unsafe fn new(name: <R as Resources>::Texture, info: tex::TextureInfo)
        -> Texture<R> {
        Texture(name, info)
    }
    /// Get texture name
    pub fn get_name(&self) -> <R as Resources>::Texture { self.0 }
    /// Get texture info
    pub fn get_info(&self) -> &tex::TextureInfo { &self.1 }
}

/// Sampler Handle
#[derive(PartialEq, Debug)]
pub struct Sampler<R: Resources>(
    <R as Resources>::Sampler,
    tex::SamplerInfo,
);

impl<R: Resources> Copy for Sampler<R> {}

impl<R: Resources> Clone for Sampler<R> {
    fn clone(&self) -> Sampler<R> {
        Sampler(self.0, self.1.clone())
    }
}

impl<R: Resources> Sampler<R> {
    /// Creates a new sampler (used by device)
    pub unsafe fn new(name: <R as Resources>::Sampler, info: tex::SamplerInfo)
        -> Sampler<R> {
        Sampler(name, info)
    }
    /// Get sampler name
    pub fn get_name(&self) -> <R as Resources>::Sampler { self.0 }
    /// Get sampler info
    pub fn get_info(&self) -> &tex::SamplerInfo { &self.1 }
}

#[cfg(test)]
mod test {
    use std::mem;
    use std::marker::PhantomData;
    use device::{BufferInfo, BufferUsage, Resources};

    #[derive(Clone, Debug, PartialEq)]
    enum TestResources {}
    impl Resources for TestResources {
        type Buffer = ();
        type ArrayBuffer = ();
        type Shader = ();
        type Program = ();
        type FrameBuffer = ();
        type Surface = ();
        type Texture = ();
        type Sampler = ();
    }

    fn mock_buffer<T>(len: usize) -> super::Buffer<TestResources, T> {
        super::Buffer {
            raw: unsafe { super::RawBuffer::new(
                (),
                BufferInfo {
                    usage: BufferUsage::Static,
                    size: mem::size_of::<T>() * len,
                },
            ) },
            phantom_t: PhantomData,
        }
    }

    #[test]
    fn test_buffer_len() {
        assert_eq!(mock_buffer::<u8>(8).len(), 8);
        assert_eq!(mock_buffer::<u16>(8).len(), 8);
    }

    #[test]
    #[should_fail]
    fn test_buffer_zero_len() {
        let _ = mock_buffer::<()>(0).len();
    }
}
<commit_msg>Enabled tracking for shader objects<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(missing_docs, missing_copy_implementations)]

//! Device resource handles

use std::mem;
use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::Arc;
use super::{shade, tex, Resources, BufferInfo};

/// Stores reference-counted resources used in a command buffer.
/// Seals actual resource names behind the interface, automatically
/// referencing them both by the Factory on resource creation
/// and the Renderer during CommandBuffer population.
#[allow(missing_docs)]
pub struct RefStorage<R: Resources> {
    buffers: Vec<Arc<R::Buffer>>,
    array_buffers: Vec<Arc<R::ArrayBuffer>>,
    shaders: Vec<Arc<R::Shader>>,
    //TODO
}

/// A service trait to be used by the device implementation
pub trait HandleFactory<R: Resources> {
    /// Create a new raw buffer handle
    fn new_buffer(&mut self, R::Buffer, BufferInfo) -> RawBuffer<R>;
    /// Create a new array buffer
    fn new_array_buffer(&mut self, R::ArrayBuffer) -> ArrayBuffer<R>;
    /// Create a new shader
    fn new_shader(&mut self, R::Shader, shade::Stage) -> Shader<R>;
}

impl<R: Resources> HandleFactory<R> for RefStorage<R> {
    fn new_buffer(&mut self, name: R::Buffer, info: BufferInfo) -> RawBuffer<R> {
        let r = Arc::new(name);
        self.buffers.push(r.clone());
        RawBuffer(r, info)
    }

    fn new_array_buffer(&mut self, name: R::ArrayBuffer) -> ArrayBuffer<R> {
        let r = Arc::new(name);
        self.array_buffers.push(r.clone());
        ArrayBuffer(r)
    }

    fn new_shader(&mut self, name: R::Shader, info: shade::Stage) -> Shader<R> {
        let r = Arc::new(name);
        self.shaders.push(r.clone());
        Shader(r, info)
    }
}

impl<R: Resources> RefStorage<R> {
    /// Create a new reference storage
    pub fn new() -> RefStorage<R> {
        RefStorage {
            buffers: Vec::new(),
            array_buffers: Vec::new(),
            shaders: Vec::new(),
        }
    }
    /// Remove all references
    pub fn reset(&mut self) {
        self.buffers.clear();
    }
    /// Extend with references from another buffer
    pub fn extend(&mut self, other: &RefStorage<R>) {
        self.buffers.extend(other.buffers.iter().map(|b| b.clone()));
    }
    /// Reference a buffer
    pub fn ref_buffer(&mut self, handle: &RawBuffer<R>) -> R::Buffer {
        self.buffers.push(handle.0.clone());
        *handle.0.deref()
    }
    /// Reference am array buffer
    pub fn ref_array_buffer(&mut self, handle: &ArrayBuffer<R>) -> R::ArrayBuffer {
        self.array_buffers.push(handle.0.clone());
        *handle.0.deref()
    }
    /// Reference a shader
    pub fn ref_shader(&mut self, handle: &Shader<R>) -> R::Shader {
        self.shaders.push(handle.0.clone());
        *handle.0.deref()
    }
}

/// Type-safe buffer handle
#[derive(Clone, PartialEq, Debug)]
pub struct Buffer<R: Resources, T> {
    raw: RawBuffer<R>,
    phantom_t: PhantomData<T>,
}

impl<R: Resources, T> Buffer<R, T> {
    /// Create a type-safe BufferHandle from a RawBufferHandle
    pub fn from_raw(handle: RawBuffer<R>) -> Buffer<R, T> {
        Buffer {
            raw: handle,
            phantom_t: PhantomData,
        }
    }

    /// Cast the type this Buffer references
    pub fn cast<U>(self) -> Buffer<R, U> {
        Buffer::from_raw(self.raw)
    }

    /// Get the underlying raw Handle
    pub fn raw(&self) -> &RawBuffer<R> {
        &self.raw
    }

    /// Get the associated information about the buffer
    pub fn get_info(&self) -> &BufferInfo {
        self.raw.get_info()
    }

    /// Get the number of elements in the buffer.
    ///
    /// Fails if `T` is zero-sized.
    pub fn len(&self) -> usize {
        assert!(mem::size_of::<T>() != 0, "Cannot determine the length of zero-sized buffers.");
        self.get_info().size / mem::size_of::<T>()
    }
}

/// Raw (untyped) Buffer Handle
#[derive(Clone, PartialEq, Debug)]
pub struct RawBuffer<R: Resources>(Arc<R::Buffer>, BufferInfo);

impl<R: Resources> RawBuffer<R> {
    /// Get raw buffer info
    pub fn get_info(&self) -> &BufferInfo { &self.1 }
}

/// Array Buffer Handle
#[derive(Clone, PartialEq, Debug)]
pub struct ArrayBuffer<R: Resources>(Arc<R::ArrayBuffer>);

/// Shader Handle
#[derive(Clone, PartialEq, Debug)]
pub struct Shader<R: Resources>(Arc<R::Shader>, shade::Stage);

impl<R: Resources> Shader<R> {
    /// Get shader info
    pub fn get_info(&self) -> &shade::Stage { &self.1 }
}

/// Program Handle
#[derive(Clone, PartialEq, Debug)]
pub struct Program<R: Resources>(
    R::Program,
    shade::ProgramInfo,
);

impl<R: Resources> Program<R> {
    /// Creates a new program (used by device)
    pub unsafe fn new(name: <R as Resources>::Program, info: shade::ProgramInfo)
        -> Program<R> {
        Program(name, info)
    }
    /// Get program name
    pub fn get_name(&self) -> R::Program { self.0 }
    /// Get program info
    pub fn get_info(&self) -> &shade::ProgramInfo { &self.1 }
}

/// Frame Buffer Handle
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct FrameBuffer<R: Resources>(<R as Resources>::FrameBuffer);

impl<R: Resources> FrameBuffer<R> {
    /// Creates a new frame buffer (used by device)
    pub unsafe fn new(name: <R as Resources>::FrameBuffer)
        -> FrameBuffer<R> {
        FrameBuffer(name)
    }
    /// Get frame buffer name
    pub fn get_name(&self) -> <R as Resources>::FrameBuffer { self.0 }
}

/// Surface Handle
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Surface<R: Resources>(
    <R as Resources>::Surface,
    tex::SurfaceInfo,
);

impl<R: Resources> Surface<R> {
    /// Creates a new surface (used by device)
    pub unsafe fn new(name: <R as Resources>::Surface, info: tex::SurfaceInfo)
        -> Surface<R> {
        Surface(name, info)
    }
    /// Get surface name
    pub fn get_name(&self) -> <R as Resources>::Surface { self.0 }
    /// Get surface info
    pub fn get_info(&self) -> &tex::SurfaceInfo { &self.1 }
}

/// Texture Handle
#[derive(PartialEq, Debug)]
pub struct Texture<R: Resources>(
    <R as Resources>::Texture,
    tex::TextureInfo,
);

impl<R: Resources> Copy for Texture<R> {}

impl<R: Resources> Clone for Texture<R> {
    fn clone(&self) -> Texture<R> {
        Texture(self.0, self.1.clone())
    }
}

impl<R: Resources> Texture<R> {
    /// Creates a new texture (used by device)
    pub unsafe fn new(name: <R as Resources>::Texture, info: tex::TextureInfo)
        -> Texture<R> {
        Texture(name, info)
    }
    /// Get texture name
    pub fn get_name(&self) -> <R as Resources>::Texture { self.0 }
    /// Get texture info
    pub fn get_info(&self) -> &tex::TextureInfo { &self.1 }
}

/// Sampler Handle
#[derive(PartialEq, Debug)]
pub struct Sampler<R: Resources>(
    <R as Resources>::Sampler,
    tex::SamplerInfo,
);

impl<R: Resources> Copy for Sampler<R> {}

impl<R: Resources> Clone for Sampler<R> {
    fn clone(&self) -> Sampler<R> {
        Sampler(self.0, self.1.clone())
    }
}

impl<R: Resources> Sampler<R> {
    /// Creates a new sampler (used by device)
    pub unsafe fn new(name: <R as Resources>::Sampler, info: tex::SamplerInfo)
        -> Sampler<R> {
        Sampler(name, info)
    }
    /// Get sampler name
    pub fn get_name(&self) -> <R as Resources>::Sampler { self.0 }
    /// Get sampler info
    pub fn get_info(&self) -> &tex::SamplerInfo { &self.1 }
}

#[cfg(test)]
mod test {
    use std::mem;
    use std::marker::PhantomData;
    use device::{BufferInfo, BufferUsage, Resources};

    #[derive(Clone, Debug, PartialEq)]
    enum TestResources {}
    impl Resources for TestResources {
        type Buffer = ();
        type ArrayBuffer = ();
        type Shader = ();
        type Program = ();
        type FrameBuffer = ();
        type Surface = ();
        type Texture = ();
        type Sampler = ();
    }

    fn mock_buffer<T>(len: usize) -> super::Buffer<TestResources, T> {
        super::Buffer {
            raw: unsafe { super::RawBuffer::new(
                (),
                BufferInfo {
                    usage: BufferUsage::Static,
                    size: mem::size_of::<T>() * len,
                },
            ) },
            phantom_t: PhantomData,
        }
    }

    #[test]
    fn test_buffer_len() {
        assert_eq!(mock_buffer::<u8>(8).len(), 8);
        assert_eq!(mock_buffer::<u16>(8).len(), 8);
    }

    #[test]
    #[should_fail]
    fn test_buffer_zero_len() {
        let _ = mock_buffer::<()>(0).len();
    }
}
<|endoftext|>


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

use {Ix, Ixs};
use error::{from_kind, ErrorKind, ShapeError};
use {zipsl, ZipExt};

pub use self::dim::*;
pub use self::axis::Axis;
pub use self::conversion::IntoDimension;
pub use self::dimension_trait::Dimension;
pub use self::ndindex::NdIndex;
pub use self::remove_axis::RemoveAxis;

#[macro_use] mod macros;
mod axis;
mod conversion;
pub mod dim;
mod dimension_trait;
mod ndindex;
mod remove_axis;

/// Private constructor and accessors for Dim
pub trait DimPrivate<I> {
    fn new(index: I) -> Self;
    fn ix(&self) -> &I;
    fn ixm(&mut self) -> &mut I;
}

/// Calculate offset from `Ix` stride converting sign properly
#[inline(always)]
pub fn stride_offset(n: Ix, stride: Ix) -> isize {
    (n as isize) * ((stride as Ixs) as isize)
}

/// Check whether the given `dim` and `stride` lead to overlapping indices
///
/// There is overlap if, when iterating through the dimensions in the order
/// of maximum variation, the current stride is inferior to the sum of all
/// preceding strides multiplied by their corresponding dimensions.
///
/// The current implementation assumes strides to be positive
pub fn dim_stride_overlap<D: Dimension>(dim: &D, strides: &D) -> bool {
    let order = strides._fastest_varying_stride_order();

    let dim = dim.slice();
    let strides = strides.slice();
    let mut prev_offset = 1;
    for &index in order.slice() {
        let d = dim[index];
        let s = strides[index];
        // any stride is ok if dimension is 1
        if d != 1 && (s as isize) < prev_offset {
            return true;
        }
        prev_offset = stride_offset(d, s);
    }
    false
}

/// Check whether the given dimension and strides are memory safe
/// to index the provided slice.
///
/// To be safe, no stride may be negative, and the offset corresponding
/// to the last element of each dimension should be smaller than the length
/// of the slice. Also, the strides should not allow a same element to be
/// referenced by two different index.
pub fn can_index_slice<A, D: Dimension>(data: &[A], dim: &D, strides: &D)
    -> Result<(), ShapeError>
{
    // check lengths of axes.
    let len = match dim.size_checked() {
        Some(l) => l,
        None => return Err(from_kind(ErrorKind::OutOfBounds)),
    };
    // check if strides are strictly positive (zero ok for len 0)
    for &s in strides.slice() {
        let s = s as Ixs;
        if s < 1 && (len != 0 || s < 0) {
            return Err(from_kind(ErrorKind::Unsupported));
        }
    }
    if len == 0 {
        return Ok(());
    }
    // check that the maximum index is in bounds
    let mut last_index = dim.clone();
    for mut index in last_index.slice_mut().iter_mut() {
        *index -= 1;
    }
    if let Some(offset) = stride_offset_checked_arithmetic(dim,
                                                           strides,
                                                           &last_index)
    {
        // offset is guaranteed to be positive so no issue converting
        // to usize here
        if (offset as usize) >= data.len() {
            return Err(from_kind(ErrorKind::OutOfBounds));
        }
        if dim_stride_overlap(dim, strides) {
            return Err(from_kind(ErrorKind::Unsupported));
        }
    } else {
        return Err(from_kind(ErrorKind::OutOfBounds));
    }
    Ok(())
}

/// Return stride offset for this dimension and index.
///
/// Return None if the indices are out of bounds, or the calculation would wrap
/// around.
fn stride_offset_checked_arithmetic<D>(dim: &D, strides: &D, index: &D)
    -> Option<isize>
    where D: Dimension
{
    let mut offset = 0;
    for (&d, &i, &s) in zipsl(dim.slice(), index.slice()).zip_cons(strides.slice()) {
        if i >= d {
            return None;
        }

        if let Some(offset_) = (i as isize)
                                   .checked_mul((s as Ixs) as isize)
                                   .and_then(|x| x.checked_add(offset)) {
            offset = offset_;
        } else {
            return None;
        }
    }
    Some(offset)
}

/// Stride offset checked general version (slices)
pub fn stride_offset_checked(dim: &[Ix], strides: &[Ix], index: &[Ix]) -> Option<isize> {
    if index.len() != dim.len() {
        return None;
    }
    let mut offset = 0;
    for (&d, &i, &s) in zipsl(dim, index).zip_cons(strides)
    {
        if i >= d {
            return None;
        }
        offset += stride_offset(i, s);
    }
    Some(offset)
}

/// Implementation-specific extensions to `Dimension`
pub trait DimensionExt {
// note: many extensions go in the main trait if they need to be special-
// cased per dimension
    /// Get the dimension at `axis`.
    ///
    /// *Panics* if `axis` is out of bounds.
    #[inline]
    fn axis(&self, axis: Axis) -> Ix;

    /// Set the dimension at `axis`.
    ///
    /// *Panics* if `axis` is out of bounds.
    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix);
}

impl<D> DimensionExt for D
    where D: Dimension
{
    #[inline]
    fn axis(&self, axis: Axis) -> Ix {
        self.slice()[axis.axis()]
    }

    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix) {
        self.slice_mut()[axis.axis()] = value;
    }
}

impl<'a> DimensionExt for [Ix]
{
    #[inline]
    fn axis(&self, axis: Axis) -> Ix {
        self[axis.axis()]
    }

    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix) {
        self[axis.axis()] = value;
    }
}

/// Collapse axis `axis` and shift so that only subarray `index` is
/// available.
///
/// **Panics** if `index` is larger than the size of the axis
// FIXME: Move to Dimension trait
pub fn do_sub<A, D: Dimension>(dims: &mut D, ptr: &mut *mut A, strides: &D,
                               axis: usize, index: Ix) {
    let dim = dims.slice()[axis];
    let stride = strides.slice()[axis];
    assert!(index < dim);
    dims.slice_mut()[axis] = 1;
    let off = stride_offset(index, stride);
    unsafe {
        *ptr = ptr.offset(off);
    }
}

// NOTE: These tests are not compiled & tested
#[cfg(test)]
mod test {
    use super::Dimension;
    use error::{from_kind, ErrorKind};

    #[test]
    fn slice_indexing_uncommon_strides() {
        let v: Vec<_> = (0..12).collect();
        let dim = (2, 3, 2);
        let strides = (1, 2, 6);
        assert!(super::can_index_slice(&v, &dim, &strides).is_ok());

        let strides = (2, 4, 12);
        assert_eq!(super::can_index_slice(&v, &dim, &strides),
                   Err(from_kind(ErrorKind::OutOfBounds)));
    }

    #[test]
    fn overlapping_strides_dim() {
        let dim = (2, 3, 2);
        let strides = (5, 2, 1);
        assert!(super::dim_stride_overlap(&dim, &strides));
        let strides = (6, 2, 1);
        assert!(!super::dim_stride_overlap(&dim, &strides));
        let strides = (6, 0, 1);
        assert!(super::dim_stride_overlap(&dim, &strides));
    }
}

<commit_msg>Simplify DimensionExt<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use {Ix, Ixs};
use error::{from_kind, ErrorKind, ShapeError};
use {zipsl, ZipExt};

pub use self::dim::*;
pub use self::axis::Axis;
pub use self::conversion::IntoDimension;
pub use self::dimension_trait::Dimension;
pub use self::ndindex::NdIndex;
pub use self::remove_axis::RemoveAxis;

#[macro_use] mod macros;
mod axis;
mod conversion;
pub mod dim;
mod dimension_trait;
mod ndindex;
mod remove_axis;

/// Private constructor and accessors for Dim
pub trait DimPrivate<I> {
    fn new(index: I) -> Self;
    fn ix(&self) -> &I;
    fn ixm(&mut self) -> &mut I;
}

/// Calculate offset from `Ix` stride converting sign properly
#[inline(always)]
pub fn stride_offset(n: Ix, stride: Ix) -> isize {
    (n as isize) * ((stride as Ixs) as isize)
}

/// Check whether the given `dim` and `stride` lead to overlapping indices
///
/// There is overlap if, when iterating through the dimensions in the order
/// of maximum variation, the current stride is inferior to the sum of all
/// preceding strides multiplied by their corresponding dimensions.
///
/// The current implementation assumes strides to be positive
pub fn dim_stride_overlap<D: Dimension>(dim: &D, strides: &D) -> bool {
    let order = strides._fastest_varying_stride_order();

    let dim = dim.slice();
    let strides = strides.slice();
    let mut prev_offset = 1;
    for &index in order.slice() {
        let d = dim[index];
        let s = strides[index];
        // any stride is ok if dimension is 1
        if d != 1 && (s as isize) < prev_offset {
            return true;
        }
        prev_offset = stride_offset(d, s);
    }
    false
}

/// Check whether the given dimension and strides are memory safe
/// to index the provided slice.
///
/// To be safe, no stride may be negative, and the offset corresponding
/// to the last element of each dimension should be smaller than the length
/// of the slice. Also, the strides should not allow a same element to be
/// referenced by two different index.
pub fn can_index_slice<A, D: Dimension>(data: &[A], dim: &D, strides: &D)
    -> Result<(), ShapeError>
{
    // check lengths of axes.
    let len = match dim.size_checked() {
        Some(l) => l,
        None => return Err(from_kind(ErrorKind::OutOfBounds)),
    };
    // check if strides are strictly positive (zero ok for len 0)
    for &s in strides.slice() {
        let s = s as Ixs;
        if s < 1 && (len != 0 || s < 0) {
            return Err(from_kind(ErrorKind::Unsupported));
        }
    }
    if len == 0 {
        return Ok(());
    }
    // check that the maximum index is in bounds
    let mut last_index = dim.clone();
    for mut index in last_index.slice_mut().iter_mut() {
        *index -= 1;
    }
    if let Some(offset) = stride_offset_checked_arithmetic(dim,
                                                           strides,
                                                           &last_index)
    {
        // offset is guaranteed to be positive so no issue converting
        // to usize here
        if (offset as usize) >= data.len() {
            return Err(from_kind(ErrorKind::OutOfBounds));
        }
        if dim_stride_overlap(dim, strides) {
            return Err(from_kind(ErrorKind::Unsupported));
        }
    } else {
        return Err(from_kind(ErrorKind::OutOfBounds));
    }
    Ok(())
}

/// Return stride offset for this dimension and index.
///
/// Return None if the indices are out of bounds, or the calculation would wrap
/// around.
fn stride_offset_checked_arithmetic<D>(dim: &D, strides: &D, index: &D)
    -> Option<isize>
    where D: Dimension
{
    let mut offset = 0;
    for (&d, &i, &s) in zipsl(dim.slice(), index.slice()).zip_cons(strides.slice()) {
        if i >= d {
            return None;
        }

        if let Some(offset_) = (i as isize)
                                   .checked_mul((s as Ixs) as isize)
                                   .and_then(|x| x.checked_add(offset)) {
            offset = offset_;
        } else {
            return None;
        }
    }
    Some(offset)
}

/// Stride offset checked general version (slices)
pub fn stride_offset_checked(dim: &[Ix], strides: &[Ix], index: &[Ix]) -> Option<isize> {
    if index.len() != dim.len() {
        return None;
    }
    let mut offset = 0;
    for (&d, &i, &s) in zipsl(dim, index).zip_cons(strides)
    {
        if i >= d {
            return None;
        }
        offset += stride_offset(i, s);
    }
    Some(offset)
}

/// Implementation-specific extensions to `Dimension`
pub trait DimensionExt {
// note: many extensions go in the main trait if they need to be special-
// cased per dimension
    /// Get the dimension at `axis`.
    ///
    /// *Panics* if `axis` is out of bounds.
    #[inline]
    fn axis(&self, axis: Axis) -> Ix;

    /// Set the dimension at `axis`.
    ///
    /// *Panics* if `axis` is out of bounds.
    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix);
}

impl<D> DimensionExt for D
    where D: Dimension
{
    #[inline]
    fn axis(&self, axis: Axis) -> Ix {
        self[axis.axis()]
    }

    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix) {
        self[axis.axis()] = value;
    }
}

impl<'a> DimensionExt for [Ix]
{
    #[inline]
    fn axis(&self, axis: Axis) -> Ix {
        self[axis.axis()]
    }

    #[inline]
    fn set_axis(&mut self, axis: Axis, value: Ix) {
        self[axis.axis()] = value;
    }
}

/// Collapse axis `axis` and shift so that only subarray `index` is
/// available.
///
/// **Panics** if `index` is larger than the size of the axis
// FIXME: Move to Dimension trait
pub fn do_sub<A, D: Dimension>(dims: &mut D, ptr: &mut *mut A, strides: &D,
                               axis: usize, index: Ix) {
    let dim = dims.slice()[axis];
    let stride = strides.slice()[axis];
    assert!(index < dim);
    dims.slice_mut()[axis] = 1;
    let off = stride_offset(index, stride);
    unsafe {
        *ptr = ptr.offset(off);
    }
}

// NOTE: These tests are not compiled & tested
#[cfg(test)]
mod test {
    use super::Dimension;
    use error::{from_kind, ErrorKind};

    #[test]
    fn slice_indexing_uncommon_strides() {
        let v: Vec<_> = (0..12).collect();
        let dim = (2, 3, 2);
        let strides = (1, 2, 6);
        assert!(super::can_index_slice(&v, &dim, &strides).is_ok());

        let strides = (2, 4, 12);
        assert_eq!(super::can_index_slice(&v, &dim, &strides),
                   Err(from_kind(ErrorKind::OutOfBounds)));
    }

    #[test]
    fn overlapping_strides_dim() {
        let dim = (2, 3, 2);
        let strides = (5, 2, 1);
        assert!(super::dim_stride_overlap(&dim, &strides));
        let strides = (6, 2, 1);
        assert!(!super::dim_stride_overlap(&dim, &strides));
        let strides = (6, 0, 1);
        assert!(super::dim_stride_overlap(&dim, &strides));
    }
}

<|endoftext|>


<commit_before>extern crate libc;
extern crate notify;

use notify::{Error, Event, RecommendedWatcher, Watcher};
use std::sync::mpsc::{channel, Receiver, RecvError};

use std::collections::HashMap;
use std::io;
use std::path::PathBuf;

use actions::Action;

pub struct FilesWatcher {
    watcher: Box<RecommendedWatcher>,
    rx: Receiver<Event>,
    watches: HashMap<PathBuf, Vec<Box<dyn Action>>>,
}

impl FilesWatcher {
    pub fn new() -> FilesWatcher {
        let (tx, rx) = channel();
        let watcher: Result<RecommendedWatcher, Error> = Watcher::new(tx);

        FilesWatcher {
            watcher: Box::new(watcher.unwrap()),
            rx: rx,
            watches: HashMap::new(),
        }
    }

    // TODO: accept a Vec of paths
    pub fn add_file(&mut self, path: PathBuf, actions: Vec<Box<dyn Action>>) {
        let result = self.watcher.watch(&path);

        if result.is_ok() {
            println!("Watching file: {:?}", path);
            self.watches.insert(path, actions);
        } else {
            println!("Error adding watch for file: {:?}", result.err());
        }
    }

    pub fn wait_for_events(&mut self) -> Result<Event, RecvError> {
        self.rx.recv()
    }

    pub fn wait_and_execute(&mut self) -> Result<i32, io::Error> {
        let mut num_actions = 0;
        let event_result = self.rx.recv();

        match event_result {
            Err(_) => Err(io::Error::new(
                io::ErrorKind::Other,
                "Error receiving event",
            )),
            Ok(event) => {
                match event.path {
                    None => println!("Warning: event has no path"),
                    Some(ref path) => {
                        let actions = self.watches.get(path);
                        if actions.is_some() {
                            for action in actions.unwrap() {
                                match action.handle_change(&event) {
                                    Ok(_) => num_actions += 1,
                                    Err(_) => {}
                                }
                            }
                        } else {
                            println!("Error: no actions found for path: {:?}", path.display());
                        }
                    }
                }

                Ok(num_actions)
            }
        }
    }
}

#[cfg(test)]
mod test {
    extern crate rand;

    use super::*;

    use self::rand::distributions::Alphanumeric;
    use self::rand::{thread_rng, Rng};
    use actions::print::PrintAction;
    use actions::Action;
    use std::env::temp_dir;
    use std::fs::remove_file;
    use std::fs::File;
    use std::io::Write;
    use std::path::Path;
    use std::path::PathBuf;

    #[test]
    fn watch_a_single_file() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<dyn Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath, event_path);
                }
            }
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_two_files() {
        let (path1, mut file1) = create_temp_file();
        let (path2, mut file2) = create_temp_file();

        let filepath1 = path1.clone();
        let filepath2 = path2.clone();
        let actions1: Vec<Box<dyn Action + 'static>> = Vec::new();
        let actions2: Vec<Box<dyn Action + 'static>> = Vec::new();

        let mut fw = FilesWatcher::new();
        fw.add_file(path1, actions1);
        fw.add_file(path2, actions2);

        write_to(&mut file1);
        write_to(&mut file2);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath1, event_path);
                }
            }

            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath2, event_path);
                }
            }
        }

        remove_temp_file(&filepath1);
        remove_temp_file(&filepath2);
    }

    #[test]
    fn watch_file_and_execute_no_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<dyn Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(0, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_one_print_action() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print = PrintAction::new();
        let actions: Vec<Box<dyn Action + 'static>> = vec![Box::new(print)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(1, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_five_print_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print1 = PrintAction::new();
        let print2 = PrintAction::new();
        let print3 = PrintAction::new();
        let print4 = PrintAction::new();
        let print5 = PrintAction::new();

        let actions: Vec<Box<dyn Action + 'static>> = vec![
            Box::new(print1),
            Box::new(print2),
            Box::new(print3),
            Box::new(print4),
            Box::new(print5),
        ];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(5, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    fn create_temp_file() -> (PathBuf, File) {
        let rand_part: String = thread_rng()
            .sample_iter(&Alphanumeric)
            .take(8)
            .map(char::from)
            .collect();

        let filename = "eagleeye-test-".to_string() + &rand_part;
        let path = temp_dir().join(filename);
        let file = File::create(&path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
        let path_buf = PathBuf::from(path);

        (path_buf, file)
    }

    fn remove_temp_file(path: &Path) {
        remove_file(path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
    }

    fn write_to(file: &mut File) {
        file.write_all(b"This should trigger an inotify event.")
            .unwrap_or_else(|error| panic!("Failed to write to file: {}", error));

        file.flush().unwrap();
    }
}
<commit_msg>Use shorthand struct initialization<commit_after>extern crate libc;
extern crate notify;

use notify::{Error, Event, RecommendedWatcher, Watcher};
use std::sync::mpsc::{channel, Receiver, RecvError};

use std::collections::HashMap;
use std::io;
use std::path::PathBuf;

use actions::Action;

pub struct FilesWatcher {
    watcher: Box<RecommendedWatcher>,
    rx: Receiver<Event>,
    watches: HashMap<PathBuf, Vec<Box<dyn Action>>>,
}

impl FilesWatcher {
    pub fn new() -> FilesWatcher {
        let (tx, rx) = channel();
        let watcher: Result<RecommendedWatcher, Error> = Watcher::new(tx);

        FilesWatcher {
            watcher: Box::new(watcher.unwrap()),
            rx,
            watches: HashMap::new(),
        }
    }

    // TODO: accept a Vec of paths
    pub fn add_file(&mut self, path: PathBuf, actions: Vec<Box<dyn Action>>) {
        let result = self.watcher.watch(&path);

        if result.is_ok() {
            println!("Watching file: {:?}", path);
            self.watches.insert(path, actions);
        } else {
            println!("Error adding watch for file: {:?}", result.err());
        }
    }

    pub fn wait_for_events(&mut self) -> Result<Event, RecvError> {
        self.rx.recv()
    }

    pub fn wait_and_execute(&mut self) -> Result<i32, io::Error> {
        let mut num_actions = 0;
        let event_result = self.rx.recv();

        match event_result {
            Err(_) => Err(io::Error::new(
                io::ErrorKind::Other,
                "Error receiving event",
            )),
            Ok(event) => {
                match event.path {
                    None => println!("Warning: event has no path"),
                    Some(ref path) => {
                        let actions = self.watches.get(path);
                        if actions.is_some() {
                            for action in actions.unwrap() {
                                match action.handle_change(&event) {
                                    Ok(_) => num_actions += 1,
                                    Err(_) => {}
                                }
                            }
                        } else {
                            println!("Error: no actions found for path: {:?}", path.display());
                        }
                    }
                }

                Ok(num_actions)
            }
        }
    }
}

#[cfg(test)]
mod test {
    extern crate rand;

    use super::*;

    use self::rand::distributions::Alphanumeric;
    use self::rand::{thread_rng, Rng};
    use actions::print::PrintAction;
    use actions::Action;
    use std::env::temp_dir;
    use std::fs::remove_file;
    use std::fs::File;
    use std::io::Write;
    use std::path::Path;
    use std::path::PathBuf;

    #[test]
    fn watch_a_single_file() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<dyn Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath, event_path);
                }
            }
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_two_files() {
        let (path1, mut file1) = create_temp_file();
        let (path2, mut file2) = create_temp_file();

        let filepath1 = path1.clone();
        let filepath2 = path2.clone();
        let actions1: Vec<Box<dyn Action + 'static>> = Vec::new();
        let actions2: Vec<Box<dyn Action + 'static>> = Vec::new();

        let mut fw = FilesWatcher::new();
        fw.add_file(path1, actions1);
        fw.add_file(path2, actions2);

        write_to(&mut file1);
        write_to(&mut file2);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath1, event_path);
                }
            }

            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath2, event_path);
                }
            }
        }

        remove_temp_file(&filepath1);
        remove_temp_file(&filepath2);
    }

    #[test]
    fn watch_file_and_execute_no_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<dyn Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(0, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_one_print_action() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print = PrintAction::new();
        let actions: Vec<Box<dyn Action + 'static>> = vec![Box::new(print)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(1, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_five_print_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print1 = PrintAction::new();
        let print2 = PrintAction::new();
        let print3 = PrintAction::new();
        let print4 = PrintAction::new();
        let print5 = PrintAction::new();

        let actions: Vec<Box<dyn Action + 'static>> = vec![
            Box::new(print1),
            Box::new(print2),
            Box::new(print3),
            Box::new(print4),
            Box::new(print5),
        ];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(5, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    fn create_temp_file() -> (PathBuf, File) {
        let rand_part: String = thread_rng()
            .sample_iter(&Alphanumeric)
            .take(8)
            .map(char::from)
            .collect();

        let filename = "eagleeye-test-".to_string() + &rand_part;
        let path = temp_dir().join(filename);
        let file = File::create(&path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
        let path_buf = PathBuf::from(path);

        (path_buf, file)
    }

    fn remove_temp_file(path: &Path) {
        remove_file(path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
    }

    fn write_to(file: &mut File) {
        file.write_all(b"This should trigger an inotify event.")
            .unwrap_or_else(|error| panic!("Failed to write to file: {}", error));

        file.flush().unwrap();
    }
}
<|endoftext|>


<commit_before>use frame::ChannelAssignment;

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => unimplemented!(),
    ChannelAssignment::RightSide   => unimplemented!(),
    ChannelAssignment::MiddleSide  => unimplemented!(),
  }
}
<commit_msg>Add implementation for `LeftSide` decoding<commit_after>use frame::ChannelAssignment;

fn decode_left_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let left = buffer[i];
    let side = buffer[i + block_size];

    // right channel
    buffer[i + block_size] = left - side;
  }
}

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => unimplemented!(),
    ChannelAssignment::RightSide   => unimplemented!(),
    ChannelAssignment::MiddleSide  => unimplemented!(),
  }
}
<|endoftext|>


<commit_before>//! Definition of the Shared combinator, a future that is cloneable,
//! and can be polled in multiple threads.
//!
//! # Examples
//!
//! ```
//! use futures::future::*;
//!
//! let future = ok::<_, bool>(6);
//! let shared1 = future.shared();
//! let shared2 = shared1.clone();
//! assert_eq!(6, *shared1.wait().unwrap());
//! assert_eq!(6, *shared2.wait().unwrap());
//! ```

use {Future, Poll, Async};
use task::{self, Task, Spawn};
use executor::{Notify, NotifyHandle};

use std::{fmt, mem, ops};
use std::cell::UnsafeCell;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::collections::HashMap;

/// A future that is cloneable and can be polled in multiple threads.
/// Use Future::shared() method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<F: Future> {
    inner: Arc<Inner<F>>,
    waiter: usize,
}

impl<F> fmt::Debug for Shared<F>
    where F: Future + fmt::Debug,
          F::Item: fmt::Debug,
          F::Error: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waiter", &self.waiter)
            .finish()
    }
}

struct Inner<F: Future> {
    next_clone_id: AtomicUsize,
    future: UnsafeCell<Option<Spawn<F>>>,
    result: UnsafeCell<Option<Result<SharedItem<F::Item>, SharedError<F::Error>>>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    waiters: Mutex<HashMap<usize, Task>>,
}

const IDLE: usize = 0;
const POLLING: usize = 1;
const REPOLL: usize = 2;
const COMPLETE: usize = 3;
const POISONED: usize = 4;

pub fn new<F: Future>(future: F) -> Shared<F> {
    Shared {
        inner: Arc::new(Inner {
            next_clone_id: AtomicUsize::new(1),
            notifier: Arc::new(Notifier {
                state: AtomicUsize::new(IDLE),
                waiters: Mutex::new(HashMap::new()),
            }),
            future: UnsafeCell::new(Some(task::spawn(future))),
            result: UnsafeCell::new(None),
        }),
        waiter: 0,
    }
}

impl<F> Shared<F> where F: Future {
    // TODO: make this private
    #[deprecated(since = "0.1.12", note = "use `Future::shared` instead")]
    #[cfg(feature = "with-deprecated")]
    #[doc(hidden)]
    pub fn new(future: F) -> Self {
        new(future)
    }

    /// If any clone of this `Shared` has completed execution, returns its result immediately
    /// without blocking. Otherwise, returns None without triggering the work represented by
    /// this `Shared`.
    pub fn peek(&self) -> Option<Result<SharedItem<F::Item>, SharedError<F::Error>>> {
        match self.inner.notifier.state.load(SeqCst) {
            COMPLETE => {
                Some(unsafe { self.clone_result() })
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => None,
        }
    }

    fn set_waiter(&mut self) {
        let mut waiters = self.inner.notifier.waiters.lock().unwrap();
        waiters.insert(self.waiter, task::current());
    }

    unsafe fn clone_result(&self) -> Result<SharedItem<F::Item>, SharedError<F::Error>> {
        match *self.inner.result.get() {
            Some(Ok(ref item)) => Ok(SharedItem { item: item.item.clone() }),
            Some(Err(ref e)) => Err(SharedError { error: e.error.clone() }),
            _ => unreachable!(),
        }
    }

    fn complete(&self) {
        unsafe { *self.inner.future.get() = None };
        self.inner.notifier.state.store(COMPLETE, SeqCst);
        self.inner.notifier.notify(0);
    }
}

impl<F> Future for Shared<F>
    where F: Future
{
    type Item = SharedItem<F::Item>;
    type Error = SharedError<F::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        self.set_waiter();

        match self.inner.notifier.state.compare_and_swap(IDLE, POLLING, SeqCst) {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING | REPOLL => {
                // Another task is currently polling, at this point we just want
                // to ensure that our task handle is currently registered

                return Ok(Async::NotReady);
            }
            COMPLETE => {
                return unsafe { self.clone_result().map(Async::Ready) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        loop {
            struct Reset<'a>(&'a AtomicUsize);

            impl<'a> Drop for Reset<'a> {
                fn drop(&mut self) {
                    use std::thread;

                    if thread::panicking() {
                        self.0.store(POISONED, SeqCst);
                    }
                }
            }

            let _reset = Reset(&self.inner.notifier.state);

            // Poll the future
            let res = unsafe {
                let notify  = NotifyHandle::from(self.inner.notifier.clone());
                (*self.inner.future.get()).as_mut().unwrap()
                    .poll_future_notify(&notify, 0)
            };
            match res {
                Ok(Async::NotReady) => {
                    // Not ready, try to release the handle
                    match self.inner.notifier.state.compare_and_swap(POLLING, IDLE, SeqCst) {
                        POLLING => {
                            // Success
                            return Ok(Async::NotReady);
                        }
                        REPOLL => {
                            // Gotta poll again!
                            let prev = self.inner.notifier.state.swap(POLLING, SeqCst);
                            assert_eq!(prev, REPOLL);
                        }
                        _ => unreachable!(),
                    }

                }
                Ok(Async::Ready(i)) => {
                    unsafe {
                        (*self.inner.result.get()) = Some(Ok(SharedItem { item: Arc::new(i) }));
                    }

                    break;
                }
                Err(e) => {
                    unsafe {
                        (*self.inner.result.get()) = Some(Err(SharedError { error: Arc::new(e) }));
                    }

                    break;
                }
            }
        }

        self.complete();
        unsafe { self.clone_result().map(Async::Ready) }
    }
}

impl<F> Clone for Shared<F> where F: Future {
    fn clone(&self) -> Self {
        let next_clone_id = self.inner.next_clone_id.fetch_add(1, SeqCst);

        Shared {
            inner: self.inner.clone(),
            waiter: next_clone_id,
        }
    }
}

impl<F> Drop for Shared<F> where F: Future {
    fn drop(&mut self) {
        let mut waiters = self.inner.notifier.waiters.lock().unwrap();
        waiters.remove(&self.waiter);
    }
}

impl Notify for Notifier {
    fn notify(&self, _id: u64) {
        self.state.compare_and_swap(POLLING, REPOLL, SeqCst);

        let waiters = mem::replace(&mut *self.waiters.lock().unwrap(), HashMap::new());

        for (_, waiter) in waiters {
            waiter.notify();
        }
    }
}

unsafe impl<F: Future> Sync for Inner<F> {}
unsafe impl<F: Future> Send for Inner<F> {}

impl<F> fmt::Debug for Inner<F>
    where F: Future + fmt::Debug,
          F::Item: fmt::Debug,
          F::Error: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Inner")
            .finish()
    }
}

/// A wrapped item of the original future that is clonable and implements Deref
/// for ease of use.
#[derive(Debug)]
pub struct SharedItem<T> {
    item: Arc<T>,
}

impl<T> ops::Deref for SharedItem<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item.as_ref()
    }
}

/// A wrapped error of the original future that is clonable and implements Deref
/// for ease of use.
#[derive(Debug)]
pub struct SharedError<E> {
    error: Arc<E>,
}

impl<E> ops::Deref for SharedError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.error.as_ref()
    }
}
<commit_msg>Fix up imports in `shared.rs`<commit_after>//! Definition of the Shared combinator, a future that is cloneable,
//! and can be polled in multiple threads.
//!
//! # Examples
//!
//! ```
//! use futures::future::*;
//!
//! let future = ok::<_, bool>(6);
//! let shared1 = future.shared();
//! let shared2 = shared1.clone();
//! assert_eq!(6, *shared1.wait().unwrap());
//! assert_eq!(6, *shared2.wait().unwrap());
//! ```

use {Future, Poll, Async};
use task::{self, Task};
use executor::{self, Notify, NotifyHandle, Spawn};

use std::{fmt, mem, ops};
use std::cell::UnsafeCell;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::collections::HashMap;

/// A future that is cloneable and can be polled in multiple threads.
/// Use Future::shared() method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<F: Future> {
    inner: Arc<Inner<F>>,
    waiter: usize,
}

impl<F> fmt::Debug for Shared<F>
    where F: Future + fmt::Debug,
          F::Item: fmt::Debug,
          F::Error: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waiter", &self.waiter)
            .finish()
    }
}

struct Inner<F: Future> {
    next_clone_id: AtomicUsize,
    future: UnsafeCell<Option<Spawn<F>>>,
    result: UnsafeCell<Option<Result<SharedItem<F::Item>, SharedError<F::Error>>>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    waiters: Mutex<HashMap<usize, Task>>,
}

const IDLE: usize = 0;
const POLLING: usize = 1;
const REPOLL: usize = 2;
const COMPLETE: usize = 3;
const POISONED: usize = 4;

pub fn new<F: Future>(future: F) -> Shared<F> {
    Shared {
        inner: Arc::new(Inner {
            next_clone_id: AtomicUsize::new(1),
            notifier: Arc::new(Notifier {
                state: AtomicUsize::new(IDLE),
                waiters: Mutex::new(HashMap::new()),
            }),
            future: UnsafeCell::new(Some(executor::spawn(future))),
            result: UnsafeCell::new(None),
        }),
        waiter: 0,
    }
}

impl<F> Shared<F> where F: Future {
    // TODO: make this private
    #[deprecated(since = "0.1.12", note = "use `Future::shared` instead")]
    #[cfg(feature = "with-deprecated")]
    #[doc(hidden)]
    pub fn new(future: F) -> Self {
        new(future)
    }

    /// If any clone of this `Shared` has completed execution, returns its result immediately
    /// without blocking. Otherwise, returns None without triggering the work represented by
    /// this `Shared`.
    pub fn peek(&self) -> Option<Result<SharedItem<F::Item>, SharedError<F::Error>>> {
        match self.inner.notifier.state.load(SeqCst) {
            COMPLETE => {
                Some(unsafe { self.clone_result() })
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => None,
        }
    }

    fn set_waiter(&mut self) {
        let mut waiters = self.inner.notifier.waiters.lock().unwrap();
        waiters.insert(self.waiter, task::current());
    }

    unsafe fn clone_result(&self) -> Result<SharedItem<F::Item>, SharedError<F::Error>> {
        match *self.inner.result.get() {
            Some(Ok(ref item)) => Ok(SharedItem { item: item.item.clone() }),
            Some(Err(ref e)) => Err(SharedError { error: e.error.clone() }),
            _ => unreachable!(),
        }
    }

    fn complete(&self) {
        unsafe { *self.inner.future.get() = None };
        self.inner.notifier.state.store(COMPLETE, SeqCst);
        self.inner.notifier.notify(0);
    }
}

impl<F> Future for Shared<F>
    where F: Future
{
    type Item = SharedItem<F::Item>;
    type Error = SharedError<F::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        self.set_waiter();

        match self.inner.notifier.state.compare_and_swap(IDLE, POLLING, SeqCst) {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING | REPOLL => {
                // Another task is currently polling, at this point we just want
                // to ensure that our task handle is currently registered

                return Ok(Async::NotReady);
            }
            COMPLETE => {
                return unsafe { self.clone_result().map(Async::Ready) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        loop {
            struct Reset<'a>(&'a AtomicUsize);

            impl<'a> Drop for Reset<'a> {
                fn drop(&mut self) {
                    use std::thread;

                    if thread::panicking() {
                        self.0.store(POISONED, SeqCst);
                    }
                }
            }

            let _reset = Reset(&self.inner.notifier.state);

            // Poll the future
            let res = unsafe {
                let notify  = NotifyHandle::from(self.inner.notifier.clone());
                (*self.inner.future.get()).as_mut().unwrap()
                    .poll_future_notify(&notify, 0)
            };
            match res {
                Ok(Async::NotReady) => {
                    // Not ready, try to release the handle
                    match self.inner.notifier.state.compare_and_swap(POLLING, IDLE, SeqCst) {
                        POLLING => {
                            // Success
                            return Ok(Async::NotReady);
                        }
                        REPOLL => {
                            // Gotta poll again!
                            let prev = self.inner.notifier.state.swap(POLLING, SeqCst);
                            assert_eq!(prev, REPOLL);
                        }
                        _ => unreachable!(),
                    }

                }
                Ok(Async::Ready(i)) => {
                    unsafe {
                        (*self.inner.result.get()) = Some(Ok(SharedItem { item: Arc::new(i) }));
                    }

                    break;
                }
                Err(e) => {
                    unsafe {
                        (*self.inner.result.get()) = Some(Err(SharedError { error: Arc::new(e) }));
                    }

                    break;
                }
            }
        }

        self.complete();
        unsafe { self.clone_result().map(Async::Ready) }
    }
}

impl<F> Clone for Shared<F> where F: Future {
    fn clone(&self) -> Self {
        let next_clone_id = self.inner.next_clone_id.fetch_add(1, SeqCst);

        Shared {
            inner: self.inner.clone(),
            waiter: next_clone_id,
        }
    }
}

impl<F> Drop for Shared<F> where F: Future {
    fn drop(&mut self) {
        let mut waiters = self.inner.notifier.waiters.lock().unwrap();
        waiters.remove(&self.waiter);
    }
}

impl Notify for Notifier {
    fn notify(&self, _id: u64) {
        self.state.compare_and_swap(POLLING, REPOLL, SeqCst);

        let waiters = mem::replace(&mut *self.waiters.lock().unwrap(), HashMap::new());

        for (_, waiter) in waiters {
            waiter.notify();
        }
    }
}

unsafe impl<F: Future> Sync for Inner<F> {}
unsafe impl<F: Future> Send for Inner<F> {}

impl<F> fmt::Debug for Inner<F>
    where F: Future + fmt::Debug,
          F::Item: fmt::Debug,
          F::Error: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Inner")
            .finish()
    }
}

/// A wrapped item of the original future that is clonable and implements Deref
/// for ease of use.
#[derive(Debug)]
pub struct SharedItem<T> {
    item: Arc<T>,
}

impl<T> ops::Deref for SharedItem<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item.as_ref()
    }
}

/// A wrapped error of the original future that is clonable and implements Deref
/// for ease of use.
#[derive(Debug)]
pub struct SharedError<E> {
    error: Arc<E>,
}

impl<E> ops::Deref for SharedError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.error.as_ref()
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::time::Duration;
use std::thread;

use game::*;
use ecs::*;
use frontends::ansi;
use util::{LeakyReserver, Schedule};
use math::Coord;

struct TurnEnv<'a, 'b, 'c: 'a> {
    turn_id: u64,
    entity_id: EntityId,
    pc_id: EntityId,
    renderer: &'a mut AnsiRenderer<'c>,
    ecs: &'b mut EcsCtx,
    spatial_hash: &'b mut SpatialHashTable,
    behaviour_ctx: &'a BehaviourCtx,
    rules: &'a Vec<Box<Rule>>,
    rule_resolution: &'a mut RuleResolution,
    ecs_action: &'a mut EcsAction,
    action_schedule: &'a mut Schedule<ActionArgs>,
}

impl<'a, 'b, 'c: 'a> TurnEnv<'a, 'b, 'c> {
    pub fn turn(&mut self) -> Result<TurnResolution> {
        unimplemented!()
    }
}

<commit_msg>Removed unused file<commit_after><|endoftext|>