<commit_before>use std::result::Result;

use super::super::lex::lex_tool::*;
use super::script::*;

///
/// Represents a parse error
///
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

impl ParseError {
    pub fn new() -> ParseError {
        ParseError { }
    }
}

struct ParseState<'a> {
    remaining: &'a [ScriptToken]
}

impl<'a> ParseState<'a> {
    ///
    /// Returns true if a token is considered syntax (gets returned from lookahead)
    ///
    fn is_syntax(token: &ScriptToken) -> bool {
        match token.token {
            ScriptLexerToken::Whitespace    |
            ScriptLexerToken::Comment       => false,

            _                               => true
        }
    }

    ///
    /// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
    ///
    fn lookahead(&self) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
        let mut index   = 0;
        let len         = self.remaining.len();

        loop {
            if index >= len {
                return None;
            } else if ParseState::is_syntax(&self.remaining[index]) {
                let token       = &self.remaining[index];
                let remaining   = &self.remaining[index+1..len];
                return Some((token, remaining));
            }

            index += 1;
        }
    }

    ///
    /// If the next token matches the specified token, consumes it and returns
    /// its content.
    ///
    fn lookahead_is(&self, token: ScriptLexerToken) -> bool {
        if let Some((lookahead, _remaining)) = self.lookahead() {
            if lookahead.token == token {
                // Token matches
                true
            } else {
                // Token does not match
                false
            }
        } else {
            // End of file
            if token == ScriptLexerToken::EndOfFile {
                // With lookahead_is we can look for the end of file (but we can't accept it because there's no token data associated with it)
                true
            } else {
                false
            }
        }
    }

    ///
    /// If the next token matches the specified token, consumes it and returns
    /// its content.
    ///
    fn accept(&mut self, token: ScriptLexerToken) -> Option<&'a ScriptToken> {
        if let Some((lookahead, remaining)) = self.lookahead() {
            if lookahead.token == token {
                // Token matches: remove it from the input and return it
                self.remaining = remaining;
                Some(lookahead)
            } else {
                // Next token does not match
                None
            }
        } else {
            // Reached the end of file
            None
        }
    }

    ///
    /// Parses a statement
    ///
    pub fn parse_statement(&mut self) -> Result<Script, ParseError> {
        if self.accept(ScriptLexerToken::Newline).is_some() {
            // Newlines are ignored
            self.parse_statement()

        } else if self.accept(ScriptLexerToken::Let).is_some() {
            // let identifier = expression
            self.parse_let()

        } else if self.accept(ScriptLexerToken::Var).is_some() {
            // var identifier = expression
            self.parse_var()

        } else if self.accept(ScriptLexerToken::Def).is_some() {
            // def fn args { statements }
            self.parse_def()

        } else if self.accept(ScriptLexerToken::If).is_some() {
            // if expression { statements }
            self.parse_if()

        } else if self.accept(ScriptLexerToken::Using).is_some() {
            // using expression { statements }
            self.parse_using()

        } else if self.accept(ScriptLexerToken::While).is_some() {
            // while expression { statements }
            self.parse_while()

        } else if self.accept(ScriptLexerToken::Loop).is_some() {
            // loop { statements }
            self.parse_loop()

        } else if self.accept(ScriptLexerToken::For).is_some() {
            // for identifier in expression { statements }
            self.parse_for()

        } else if self.lookahead_is(ScriptLexerToken::Identifier) {
            // While commands are either <Expression> or <Expression> <Expression>, we
            // force the first expression to be an identifier at the moment
            self.parse_command()

        } else {
            // Unrecognised token
            Err(ParseError::new())
        }
    }

    ///
    /// Parses a command
    ///
    /// Syntax '<expression>', '<expression> <expression>'
    ///
    pub fn parse_command(&mut self) -> Result<Script, ParseError> {
        // Starts with an expression specifying the command to run
        self.parse_expression().and_then(move |command_expression| {
            // Followed by arguments (or an end-of-expression marker)
            if self.accept(ScriptLexerToken::Newline).is_some()
               || self.lookahead_is(ScriptLexerToken::EndOfFile) {
                // Newline or EOF ends a command
                Ok(Script::RunCommand(command_expression, None))

            } else {
                // Anything else should be an argument expression
                self.parse_expression().and_then(move |argument_expression| {
                    Ok(Script::RunCommand(command_expression, Some(argument_expression)))

                }).and_then(move |command| {
                    // Command must be followed by a newline
                    if self.accept(ScriptLexerToken::Newline).is_some()
                       || self.lookahead_is(ScriptLexerToken::EndOfFile) {
                        Ok(command)
                    } else {
                        Err(ParseError::new())
                    }

                })

            }
        })
    }

    ///
    /// Parses an Expression
    ///
    pub fn parse_expression(&mut self) -> Result<Expression, ParseError> {
        if self.accept(ScriptLexerToken::Newline).is_some() {
            // Ignore newlines within an expression
            self.parse_expression()

        } else if let Some(identifier) = self.accept(ScriptLexerToken::Identifier) {
            // Simple expression
            Ok(Expression::Identifier(identifier.clone()))

        } else if let Some(number) = self.accept(ScriptLexerToken::Number) {
            // Simple expression
            Ok(Expression::Number(number.clone()))

        } else if let Some(number) = self.accept(ScriptLexerToken::HexNumber) {
            // Hex numbers work like normal numbers
            Ok(Expression::Number(number.clone()))

        } else if let Some(string) = self.accept(ScriptLexerToken::String) {
            // Simple expression
            Ok(Expression::String(string.clone()))

        } else {
            // Syntax error
            Err(ParseError::new())

        }
    }

    pub fn parse_let(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_var(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_def(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_if(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_using(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_while(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_loop(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_for(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }
}

impl ParseScriptTool {
    ///
    /// Creates a new script parsing tool
    ///
    pub fn new() -> ParseScriptTool {
        ParseScriptTool { }
    }

    ///
    /// Tries to parse a script from the output of the lexer
    ///
    pub fn parse(input: &[LexerMatch]) -> Result<Vec<Script>, ParseError> {
        // Convert to script tokens
        let as_script_token: Vec<ScriptToken> = input
            .iter()
            .map(|token| ScriptToken::from_lexer_match(token))
            .collect();

        // Parse until we reach the end of the file
        let mut parser = ParseState { remaining: &as_script_token };
        let mut result = vec![];

        while !parser.lookahead_is(ScriptLexerToken::EndOfFile) {
            let next_statement = parser.parse_statement();

            match next_statement {
                // Fail out if we get a parse failure
                Err(failure)        => return Err(failure),

                // Build out the result otherwise
                Ok(next_statement)  => result.push(next_statement)
            }

            // Swallow any trailing newlines
            while parser.accept(ScriptLexerToken::Newline).is_some() { }
        }

        Ok(result)
    }
}
<commit_msg>Make it possible to make a tool from the script parser<commit_after>use std::result::Result;

use silkthread_base::*;
use silkthread_base::basic::*;

use super::super::lex::lex_tool::*;
use super::script::*;

///
/// Represents a parse error
///
#[derive(Serialize, Deserialize)]
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

impl ParseError {
    pub fn new() -> ParseError {
        ParseError { }
    }
}

struct ParseState<'a> {
    remaining: &'a [ScriptToken]
}

impl<'a> ParseState<'a> {
    ///
    /// Returns true if a token is considered syntax (gets returned from lookahead)
    ///
    fn is_syntax(token: &ScriptToken) -> bool {
        match token.token {
            ScriptLexerToken::Whitespace    |
            ScriptLexerToken::Comment       => false,

            _                               => true
        }
    }

    ///
    /// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
    ///
    fn lookahead(&self) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
        let mut index   = 0;
        let len         = self.remaining.len();

        loop {
            if index >= len {
                return None;
            } else if ParseState::is_syntax(&self.remaining[index]) {
                let token       = &self.remaining[index];
                let remaining   = &self.remaining[index+1..len];
                return Some((token, remaining));
            }

            index += 1;
        }
    }

    ///
    /// If the next token matches the specified token, consumes it and returns
    /// its content.
    ///
    fn lookahead_is(&self, token: ScriptLexerToken) -> bool {
        if let Some((lookahead, _remaining)) = self.lookahead() {
            if lookahead.token == token {
                // Token matches
                true
            } else {
                // Token does not match
                false
            }
        } else {
            // End of file
            if token == ScriptLexerToken::EndOfFile {
                // With lookahead_is we can look for the end of file (but we can't accept it because there's no token data associated with it)
                true
            } else {
                false
            }
        }
    }

    ///
    /// If the next token matches the specified token, consumes it and returns
    /// its content.
    ///
    fn accept(&mut self, token: ScriptLexerToken) -> Option<&'a ScriptToken> {
        if let Some((lookahead, remaining)) = self.lookahead() {
            if lookahead.token == token {
                // Token matches: remove it from the input and return it
                self.remaining = remaining;
                Some(lookahead)
            } else {
                // Next token does not match
                None
            }
        } else {
            // Reached the end of file
            None
        }
    }

    ///
    /// Parses a statement
    ///
    pub fn parse_statement(&mut self) -> Result<Script, ParseError> {
        if self.accept(ScriptLexerToken::Newline).is_some() {
            // Newlines are ignored
            self.parse_statement()

        } else if self.accept(ScriptLexerToken::Let).is_some() {
            // let identifier = expression
            self.parse_let()

        } else if self.accept(ScriptLexerToken::Var).is_some() {
            // var identifier = expression
            self.parse_var()

        } else if self.accept(ScriptLexerToken::Def).is_some() {
            // def fn args { statements }
            self.parse_def()

        } else if self.accept(ScriptLexerToken::If).is_some() {
            // if expression { statements }
            self.parse_if()

        } else if self.accept(ScriptLexerToken::Using).is_some() {
            // using expression { statements }
            self.parse_using()

        } else if self.accept(ScriptLexerToken::While).is_some() {
            // while expression { statements }
            self.parse_while()

        } else if self.accept(ScriptLexerToken::Loop).is_some() {
            // loop { statements }
            self.parse_loop()

        } else if self.accept(ScriptLexerToken::For).is_some() {
            // for identifier in expression { statements }
            self.parse_for()

        } else if self.lookahead_is(ScriptLexerToken::Identifier) {
            // While commands are either <Expression> or <Expression> <Expression>, we
            // force the first expression to be an identifier at the moment
            self.parse_command()

        } else {
            // Unrecognised token
            Err(ParseError::new())
        }
    }

    ///
    /// Parses a command
    ///
    /// Syntax '<expression>', '<expression> <expression>'
    ///
    pub fn parse_command(&mut self) -> Result<Script, ParseError> {
        // Starts with an expression specifying the command to run
        self.parse_expression().and_then(move |command_expression| {
            // Followed by arguments (or an end-of-expression marker)
            if self.accept(ScriptLexerToken::Newline).is_some()
               || self.lookahead_is(ScriptLexerToken::EndOfFile) {
                // Newline or EOF ends a command
                Ok(Script::RunCommand(command_expression, None))

            } else {
                // Anything else should be an argument expression
                self.parse_expression().and_then(move |argument_expression| {
                    Ok(Script::RunCommand(command_expression, Some(argument_expression)))

                }).and_then(move |command| {
                    // Command must be followed by a newline
                    if self.accept(ScriptLexerToken::Newline).is_some()
                       || self.lookahead_is(ScriptLexerToken::EndOfFile) {
                        Ok(command)
                    } else {
                        Err(ParseError::new())
                    }

                })

            }
        })
    }

    ///
    /// Parses an Expression
    ///
    pub fn parse_expression(&mut self) -> Result<Expression, ParseError> {
        if self.accept(ScriptLexerToken::Newline).is_some() {
            // Ignore newlines within an expression
            self.parse_expression()

        } else if let Some(identifier) = self.accept(ScriptLexerToken::Identifier) {
            // Simple expression
            Ok(Expression::Identifier(identifier.clone()))

        } else if let Some(number) = self.accept(ScriptLexerToken::Number) {
            // Simple expression
            Ok(Expression::Number(number.clone()))

        } else if let Some(number) = self.accept(ScriptLexerToken::HexNumber) {
            // Hex numbers work like normal numbers
            Ok(Expression::Number(number.clone()))

        } else if let Some(string) = self.accept(ScriptLexerToken::String) {
            // Simple expression
            Ok(Expression::String(string.clone()))

        } else {
            // Syntax error
            Err(ParseError::new())

        }
    }

    pub fn parse_let(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_var(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_def(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_if(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_using(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_while(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_loop(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }

    pub fn parse_for(&mut self) -> Result<Script, ParseError> {
        unimplemented!()
    }
}

impl ParseScriptTool {
    ///
    /// Creates a new tool from the parse script tool
    ///
    pub fn new_tool() -> Box<Tool> {
        Box::new(make_tool(move |script: Vec<LexerMatch>| -> Result<Vec<Script>, ParseError> {
            ParseScriptTool::parse(&script)
        }))
    }

    ///
    /// Tries to parse a script from the output of the lexer
    ///
    pub fn parse(input: &[LexerMatch]) -> Result<Vec<Script>, ParseError> {
        // Convert to script tokens
        let as_script_token: Vec<ScriptToken> = input
            .iter()
            .map(|token| ScriptToken::from_lexer_match(token))
            .collect();

        // Parse until we reach the end of the file
        let mut parser = ParseState { remaining: &as_script_token };
        let mut result = vec![];

        while !parser.lookahead_is(ScriptLexerToken::EndOfFile) {
            let next_statement = parser.parse_statement();

            match next_statement {
                // Fail out if we get a parse failure
                Err(failure)        => return Err(failure),

                // Build out the result otherwise
                Ok(next_statement)  => result.push(next_statement)
            }

            // Swallow any trailing newlines
            while parser.accept(ScriptLexerToken::Newline).is_some() { }
        }

        Ok(result)
    }
}
<|endoftext|>


<commit_before>use robot_name as robot;

fn assert_name_matches_pattern(n: &str) {
    assert!(n.len() == 5, "name is exactly 5 characters long");
    assert!(
        n[0..2].chars().all(|c| ('A'..='Z').contains(&c)),
        "name starts with 2 uppercase letters"
    );
    assert!(
        n[2..].chars().all(|c| ('0'..='9').contains(&c)),
        "name ends with 3 numbers"
    );
}

fn assert_name_is_persistent(r: &robot::Robot) {
    // The type system already proves this, but why not.
    let n1 = r.name();
    let n2 = r.name();
    let n3 = r.name();
    assert_eq!(n1, n2);
    assert_eq!(n2, n3);
}

#[test]
fn test_name_should_match_expected_pattern() {
    let r = robot::Robot::new();
    assert_name_matches_pattern(r.name());
}

#[test]
#[ignore]
fn test_name_is_persistent() {
    assert_name_is_persistent(&robot::Robot::new());
}

#[test]
#[ignore]
fn test_different_robots_have_different_names() {
    let r1 = robot::Robot::new();
    let r2 = robot::Robot::new();
    assert_ne!(r1.name(), r2.name(), "Robot names should be different");
}

#[test]
#[ignore]
fn test_new_name_should_match_expected_pattern() {
    let mut r = robot::Robot::new();
    assert_name_matches_pattern(r.name());
    r.reset_name();
    assert_name_matches_pattern(r.name());
}

#[test]
#[ignore]
fn test_new_name_is_persistent() {
    let mut r = robot::Robot::new();
    r.reset_name();
    assert_name_is_persistent(&r);
}

#[test]
#[ignore]
fn test_new_name_is_different_from_old_name() {
    let mut r = robot::Robot::new();
    let n1 = r.name().to_string();
    r.reset_name();
    let n2 = r.name().to_string();
    assert_ne!(n1, n2, "Robot name should change when reset");
}
<commit_msg>[Robot Name] Add test_many_different_robots_have_different_names()<commit_after>use robot_name as robot;

fn assert_name_matches_pattern(n: &str) {
    assert!(n.len() == 5, "name is exactly 5 characters long");
    assert!(
        n[0..2].chars().all(|c| ('A'..='Z').contains(&c)),
        "name starts with 2 uppercase letters"
    );
    assert!(
        n[2..].chars().all(|c| ('0'..='9').contains(&c)),
        "name ends with 3 numbers"
    );
}

fn assert_name_is_persistent(r: &robot::Robot) {
    // The type system already proves this, but why not.
    let n1 = r.name();
    let n2 = r.name();
    let n3 = r.name();
    assert_eq!(n1, n2);
    assert_eq!(n2, n3);
}

#[test]
fn test_name_should_match_expected_pattern() {
    let r = robot::Robot::new();
    assert_name_matches_pattern(r.name());
}

#[test]
#[ignore]
fn test_name_is_persistent() {
    assert_name_is_persistent(&robot::Robot::new());
}

#[test]
#[ignore]
fn test_different_robots_have_different_names() {
    let r1 = robot::Robot::new();
    let r2 = robot::Robot::new();
    assert_ne!(r1.name(), r2.name(), "Robot names should be different");
}

#[test]
#[ignore]
fn test_many_different_robots_have_different_names() {
    use std::collections::HashSet;

    // In 3,529 random robot names, there is ~99.99% chance of a name collision
    let vec: Vec<_> = (0..3529).map(|_| robot::Robot::new()).collect();
    let set: HashSet<_> = vec.iter().map(|robot| robot.name()).collect();

    // If the lengths are different, there was a name collision
    assert_eq!(set.len(), vec.len());
}

#[test]
#[ignore]
fn test_new_name_should_match_expected_pattern() {
    let mut r = robot::Robot::new();
    assert_name_matches_pattern(r.name());
    r.reset_name();
    assert_name_matches_pattern(r.name());
}

#[test]
#[ignore]
fn test_new_name_is_persistent() {
    let mut r = robot::Robot::new();
    r.reset_name();
    assert_name_is_persistent(&r);
}

#[test]
#[ignore]
fn test_new_name_is_different_from_old_name() {
    let mut r = robot::Robot::new();
    let n1 = r.name().to_string();
    r.reset_name();
    let n2 = r.name().to_string();
    assert_ne!(n1, n2, "Robot name should change when reset");
}
<|endoftext|>


<commit_before>use std::collections::TreeMap;
use std::iter::AdditiveIterator;
use std::mem::swap;
use window_manager::ScreenDetail;
use window_system::Window;

#[deriving(Clone)]
pub struct RationalRect(f32, f32, f32, f32);

/// Handles focus tracking on a workspace.
/// `focus` keeps track of the focused window's id
/// and `up` and `down` are the windows above or
/// below the focus stack respectively.
#[deriving(Clone)]
pub struct Stack<T> {
    pub focus: T,
    pub up:    Vec<T>,
    pub down:  Vec<T>
}

impl<T: Clone + Eq> Stack<T> {
    /// Create a new stack with the given values
    pub fn new<T>(f: T, up: Vec<T>, down: Vec<T>) -> Stack<T> {
        Stack {
            focus: f,
            up:    up,
            down:  down
        }
    }

    /// Create a new stack with only the given element
    /// as the focused one and initialize the rest to empty.
    pub fn from_element(t: T) -> Stack<T> {
        Stack {
            focus: t,
            up:    Vec::new(),
            down:  Vec::new()
        }
    }

    pub fn add(&self, t: T) -> Stack<T> {
        let mut s = self.clone();
        s.down.push(self.focus.clone());
        s.focus = t;
        s
    }

    /// Flatten the stack into a list
    pub fn integrate(&self) -> Vec<T> {
        self.up.iter()
            .rev()
            .chain((vec!(self.focus.clone())).iter())
            .chain(self.down.iter())
            .map(|x| x.clone())
            //.rev()
            .collect()
    }

    /// Filter the stack to retain only windows
    /// that yield true in the given filter function
    pub fn filter<'r>(&self, f: |&T| : 'r -> bool) -> Option<Stack<T>> {
        let lrs : Vec<T> = (vec!(self.focus.clone())).iter()
            .chain(self.down.iter())
            .map(|x| x.clone())
            .filter(|x| f(x))
            .collect();

        if lrs.len() > 0 {
            let first : T         = lrs.head().unwrap().clone();
            let rest : Vec<T>     = lrs.iter().skip(1).map(|x| x.clone()).collect();
            let filtered : Vec<T> = self.up.iter().map(|x| x.clone()).filter(f).map(|x| x.clone()).collect();
            let stack : Stack<T>  = Stack::<T>::new(first, filtered, rest);

            Some(stack)
        } else {
            let filtered : Vec<T> = self.up.iter().map(|x| x.clone()).filter(f).collect();
            if filtered.len() > 0 {
                let first : T        = filtered.head().unwrap().clone();
                let rest : Vec<T>    = filtered.iter().skip(1).map(|x| x.clone()).collect();
                let stack : Stack<T> = Stack::<T>::new(first, rest, Vec::new());

                Some(stack)
            } else {
                None
            }
        }
    }

    /// Move the focus to the next element in the `down` list
    pub fn focus_down(&self) -> Stack<T> {
        let mut s = self.clone();
        if self.up.is_empty() {
            let tmp : Vec<T> = (vec!(s.focus.clone())).iter()
                .chain(s.down.iter())
                .rev()
                .map(|x| x.clone())
                .collect();
            let x = tmp.head().unwrap();
            let xs : Vec<T> = tmp.iter()
                .skip(1)
                .map(|x| x.clone())
                .collect();

            s.focus = x.clone();
            s.up = xs;
            s.down = Vec::new();
        } else {
            s.down.insert(0, s.focus.clone());
            s.focus = s.up.head().unwrap().clone();
            s.up.remove(0);
        }

        s
    }

    /// Move the focus up
    pub fn focus_up(&self) -> Stack<T> {
        self.reverse().focus_down().reverse()
    }

    /// Reverse the stack by exchanging
    /// the `up` and `down` lists
    pub fn reverse(&self) -> Stack<T> {
        let mut s = self.clone();
        swap(&mut s.up, &mut s.down);
        s
    }

    /// Return the number of elements tracked by the stack
    pub fn len(&self) -> uint {
        1 + self.up.len() + self.down.len()
    }

    /// Checks if the given window is tracked by the stack
    pub fn contains(&self, window: T) -> bool {
        self.focus == window || self.up.contains(&window) || self.down.contains(&window)
    }
}

/// Represents a single workspace with a `tag` (name),
/// `id`, a `layout` and a `stack` for all windows
#[deriving(Clone)]
pub struct Workspace {
    pub id:     u32,
    pub tag:    String,
    pub layout: String,
    pub stack:  Option<Stack<Window>>
}

#[deriving(Clone)]
impl Workspace {
    /// Create a new workspace
    pub fn new(id: u32, tag: String, layout: String, stack: Option<Stack<Window>>) -> Workspace {
        Workspace {
            id: id,
            tag: tag,
            layout: layout,
            stack: stack
        }
    }

    pub fn add(&self, window: Window) -> Workspace {
        let mut w = self.clone();
        w.stack = Some(self.stack.clone().map_or(Stack::from_element(window), |s| s.add(window)));
        w
    }

    /// Returns the number of windows contained in this workspace
    pub fn len(&self) -> uint {
        self.stack.clone().map_or(0, |x| x.len())
    }

    /// Checks if the workspace contains the given window
    pub fn contains(&self, window: Window) -> bool {
        self.stack.clone().map_or(false, |x| x.contains(window))
    }
}

#[deriving(Clone)]
pub struct Screen {
    pub workspace:     Workspace,
    pub screen_id:     u32,
    pub screen_detail: ScreenDetail
}

impl Screen {
    pub fn new(workspace: Workspace, screen_id: u32, screen_detail: ScreenDetail) -> Screen {
        Screen {
            workspace: workspace,
            screen_id: screen_id,
            screen_detail: screen_detail
        }
    }

    /// Checks if the screen's workspace contains
    /// the given window
    pub fn contains(&self, window: Window) -> bool {
        self.workspace.contains(window)
    }

    /// Returns the number of windows in the
    /// screen's workspace
    pub fn len(&self) -> uint {
        self.workspace.len()
    }
}

#[deriving(Clone)]
pub struct Workspaces {
    pub current:  Screen,
    pub visible:  Vec<Screen>,
    pub hidden:   Vec<Workspace>,
    pub floating: TreeMap<Window, RationalRect>
}

impl Workspaces {
    /// Create a new stackset, of empty stacks, with given tags,
    /// with physical screens whose descriptions are given by 'm'. The
    /// number of physical screens (@length 'm'@) should be less than or
    /// equal to the number of workspace tags.  The first workspace in the
    /// list will be current.
    ///
    /// Xinerama: Virtual workspaces are assigned to physical screens, starting at 0.
    pub fn new(layout: String, tags: Vec<String>, screens: Vec<ScreenDetail>) -> Workspaces {
        debug!("creating new workspaces with {} screen(s)", screens.len());
        let workspaces : Vec<Workspace> = tags.iter()
            .enumerate()
            .map(|(id, tag)| Workspace::new(id as u32, tag.clone(), layout.clone(), None))
            .collect();
        let seen   : Vec<Workspace> = workspaces.iter()
            .take(screens.len())
            .map(|x| x.clone())
            .collect();
        let unseen : Vec<Workspace> = workspaces.iter()
            .skip(screens.len())
            .map(|x| x.clone())
            .collect();
        let current : Vec<Screen> = seen.iter()
            .enumerate()
            .zip(screens.iter())
            .map(|((a, b), c)| Screen::new(b.clone(), a as u32, c.clone()))
            .collect();

        Workspaces {
            current: current.head().unwrap().clone(),
            visible: current.iter().skip(1).map(|x| x.clone()).collect(),
            hidden: unseen,
            floating: TreeMap::new()
        }
    }

    /// Set focus to the workspace with index \'i\'.
    /// If the index is out of range, return the original 'StackSet'.
    ///
    /// Xinerama: If the workspace is not visible on any Xinerama screen, it
    /// becomes the current screen. If it is in the visible list, it becomes
    /// current.
    pub fn view(&self, index: u32) -> Workspaces {
        debug!("setting focus to {}", index);
        if self.current.workspace.id == index {
            return self.clone();
        }

        let mut w = self.clone();

        match w.visible.iter().position(|s| s.workspace.id == index) {
            Some(screen_pos) => {
                let screen = self.visible[screen_pos].clone();
                w.visible.remove(screen_pos);
                w.visible.insert(0, self.current.clone());
                w.current = screen;
                return w;
            },
            _ => ()
        }

        match self.hidden.iter().position(|w| w.id == index) {
            Some(workspace_pos) => {
                let current_workspace = self.current.workspace.clone();
                w.current.workspace = self.hidden[workspace_pos].clone();
                w.hidden.remove(workspace_pos);
                w.hidden.insert(0, current_workspace);
                w
            },
            _ => w
        }
    }

    /// Set focus to the given workspace.  If that workspace does not exist
    /// in the stackset, the original workspace is returned.  If that workspace is
    /// 'hidden', then display that workspace on the current screen, and move the
    /// current workspace to 'hidden'.  If that workspace is 'visible' on another
    /// screen, the workspaces of the current screen and the other screen are
    /// swapped.
    pub fn greedy_view(&self, _: uint) {

    }

    pub fn sink(&self, window: Window) -> Workspaces {
        let mut w = self.clone();
        w.floating.remove(&window);
        w
    }

    pub fn delete(&self, window: Window) -> Workspaces {
        self.delete_p(window).sink(window)
    }

    pub fn delete_p(&self, window: Window) -> Workspaces {
        let mut w = self.clone();

        let remove_from_workspace = |workspace: &mut Workspace| {
            if workspace.stack.is_some() {
                workspace.stack = workspace.clone().stack.unwrap().filter(|&x| x != window);
            }
        };

        remove_from_workspace(&mut w.current.workspace);

        w.hidden.iter_mut().fold((), |_, workspace| {
            remove_from_workspace(workspace)
        });

        w.visible.iter_mut().fold((), |_, screen| {
            remove_from_workspace(&mut screen.workspace)
        });

        w
    }

    /// Move the focus of the currently focused workspace down
    pub fn focus_down(&self) -> Workspaces {
        let mut w = self.clone();
        w.current.workspace.stack = w.current.workspace.stack.map(|s| s.focus_down());
        w
    }

    pub fn focus_up(&self) -> Workspaces {
        let mut w = self.clone();
        w.current.workspace.stack = w.current.workspace.stack.map(|s| s.focus_up());
        w
    }

    pub fn get_focus_window(&self) -> Option<Window> {
        self.current.workspace.stack.clone().map(|s| s.focus)
    }

    pub fn peek(&self) -> Option<Window> {
        self.with(None, |s| Some(s.focus))
    }

    pub fn with<T>(&self, default: T, f: |&Stack<Window>| -> T) -> T {
        match self.current.workspace.stack {
            Some(ref s) => f(s),
            None        => default
        }
    }

    pub fn len(&self) -> uint {
        self.current.len() +
        self.visible.iter().map(|x| x.len()).sum() +
        self.hidden.iter().map(|x| x.len()).sum() +
        self.floating.len()
    }

    pub fn contains(&self, window: Window) -> bool {
        self.current.contains(window) ||
        self.visible.iter().any(|x| x.contains(window)) ||
        self.hidden.iter().any(|x| x.contains(window)) ||
        self.floating.contains_key(&window)
    }

    pub fn number_workspaces(&self) -> u32 {
        (1 + self.visible.len() + self.hidden.len()) as u32
    }

    pub fn shift(&self, index: u32) -> Workspaces {
        self.peek().map_or(self.clone(), |w| self.shift_window(index, w))
    }

    pub fn insert_up(&self, window: Window) -> Workspaces {
        if self.contains(window) {
            return self.clone();
        }

        let mut w = self.clone();
        match w.current.workspace.stack {
            Some(ref mut s) => {
                s.down.insert(0, s.focus.clone());
                s.focus = window;
            },
            None => w.current.workspace.stack = Some(Stack::from_element(window))
        }
        w
    }

    pub fn current_tag(&self) -> u32 {
        self.current.workspace.id as u32
    }

    pub fn find_tag(&self, window: Window) -> Option<u32> {
        self.workspaces().iter()
            .filter(|x| x.contains(window))
            .map(|x| x.id as u32)
            .nth(0)
    }

    pub fn workspaces(&self) -> Vec<Workspace> {
        let v : Vec<Workspace> = self.visible.iter().map(|x| x.workspace.clone()).collect();
        (vec!(self.current.workspace.clone())).iter()
            .chain(v.iter())
            .chain(self.hidden.iter())
            .map(|x| x.clone())
            .collect()
    }

    pub fn shift_window(&self, index: u32, window: Window) -> Workspaces {
        let first_closure = (box move |&: w: Workspaces| {
            w.delete(window)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>;

        let second_closure = (box move |&: w: Workspaces| {
            w.insert_up(window)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>;

        match self.find_tag(window) {
            Some(from) => {
                let a = self.on_workspace(from, first_closure);
                let b = self.on_workspace(index, second_closure);

                debug!("shifting window from {} to {}", from, index);
                (*b).call(((*a).call((self.clone(),)),))
            },
            None => self.clone()
        }
    }

    pub fn on_workspace(&self, index: u32, f: Box<Fn<(Workspaces,), Workspaces> + 'static>)
            -> Box<Fn<(Workspaces,), Workspaces> + 'static> {
        (box move |&: x: Workspaces| {
            let current_tag = x.current_tag();
            (*f).call((x.view(index),)).view(current_tag)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>
    }
}
<commit_msg>added more documentation<commit_after>use std::collections::TreeMap;
use std::iter::AdditiveIterator;
use std::mem::swap;
use window_manager::ScreenDetail;
use window_system::Window;

#[deriving(Clone)]
pub struct RationalRect(f32, f32, f32, f32);

/// Handles focus tracking on a workspace.
/// `focus` keeps track of the focused window's id
/// and `up` and `down` are the windows above or
/// below the focus stack respectively.
#[deriving(Clone)]
pub struct Stack<T> {
    pub focus: T,
    pub up:    Vec<T>,
    pub down:  Vec<T>
}

impl<T: Clone + Eq> Stack<T> {
    /// Create a new stack with the given values
    pub fn new<T>(f: T, up: Vec<T>, down: Vec<T>) -> Stack<T> {
        Stack {
            focus: f,
            up:    up,
            down:  down
        }
    }

    /// Create a new stack with only the given element
    /// as the focused one and initialize the rest to empty.
    pub fn from_element(t: T) -> Stack<T> {
        Stack {
            focus: t,
            up:    Vec::new(),
            down:  Vec::new()
        }
    }

    /// Add a new element to the stack
    /// and automatically focus it.
    pub fn add(&self, t: T) -> Stack<T> {
        let mut s = self.clone();
        s.down.push(self.focus.clone());
        s.focus = t;
        s
    }

    /// Flatten the stack into a list
    pub fn integrate(&self) -> Vec<T> {
        self.up.iter()
            .rev()
            .chain((vec!(self.focus.clone())).iter())
            .chain(self.down.iter())
            .map(|x| x.clone())
            //.rev()
            .collect()
    }

    /// Filter the stack to retain only windows
    /// that yield true in the given filter function
    pub fn filter<'r>(&self, f: |&T| : 'r -> bool) -> Option<Stack<T>> {
        let lrs : Vec<T> = (vec!(self.focus.clone())).iter()
            .chain(self.down.iter())
            .map(|x| x.clone())
            .filter(|x| f(x))
            .collect();

        if lrs.len() > 0 {
            let first : T         = lrs.head().unwrap().clone();
            let rest : Vec<T>     = lrs.iter().skip(1).map(|x| x.clone()).collect();
            let filtered : Vec<T> = self.up.iter().map(|x| x.clone()).filter(f).map(|x| x.clone()).collect();
            let stack : Stack<T>  = Stack::<T>::new(first, filtered, rest);

            Some(stack)
        } else {
            let filtered : Vec<T> = self.up.iter().map(|x| x.clone()).filter(f).collect();
            if filtered.len() > 0 {
                let first : T        = filtered.head().unwrap().clone();
                let rest : Vec<T>    = filtered.iter().skip(1).map(|x| x.clone()).collect();
                let stack : Stack<T> = Stack::<T>::new(first, rest, Vec::new());

                Some(stack)
            } else {
                None
            }
        }
    }

    /// Move the focus to the next element in the `down` list
    pub fn focus_down(&self) -> Stack<T> {
        let mut s = self.clone();
        if self.up.is_empty() {
            let tmp : Vec<T> = (vec!(s.focus.clone())).iter()
                .chain(s.down.iter())
                .rev()
                .map(|x| x.clone())
                .collect();
            let x = tmp.head().unwrap();
            let xs : Vec<T> = tmp.iter()
                .skip(1)
                .map(|x| x.clone())
                .collect();

            s.focus = x.clone();
            s.up = xs;
            s.down = Vec::new();
        } else {
            s.down.insert(0, s.focus.clone());
            s.focus = s.up.head().unwrap().clone();
            s.up.remove(0);
        }

        s
    }

    /// Move the focus up
    pub fn focus_up(&self) -> Stack<T> {
        self.reverse().focus_down().reverse()
    }

    /// Reverse the stack by exchanging
    /// the `up` and `down` lists
    pub fn reverse(&self) -> Stack<T> {
        let mut s = self.clone();
        swap(&mut s.up, &mut s.down);
        s
    }

    /// Return the number of elements tracked by the stack
    pub fn len(&self) -> uint {
        1 + self.up.len() + self.down.len()
    }

    /// Checks if the given window is tracked by the stack
    pub fn contains(&self, window: T) -> bool {
        self.focus == window || self.up.contains(&window) || self.down.contains(&window)
    }
}

/// Represents a single workspace with a `tag` (name),
/// `id`, a `layout` and a `stack` for all windows
#[deriving(Clone)]
pub struct Workspace {
    pub id:     u32,
    pub tag:    String,
    pub layout: String,
    pub stack:  Option<Stack<Window>>
}

#[deriving(Clone)]
impl Workspace {
    /// Create a new workspace
    pub fn new(id: u32, tag: String, layout: String, stack: Option<Stack<Window>>) -> Workspace {
        Workspace {
            id: id,
            tag: tag,
            layout: layout,
            stack: stack
        }
    }

    /// Add a new window to the workspace by adding it to the stack.
    /// If the stack doesn't exist yet, create one.
    pub fn add(&self, window: Window) -> Workspace {
        let mut w = self.clone();
        w.stack = Some(self.stack.clone().map_or(Stack::from_element(window), |s| s.add(window)));
        w
    }

    /// Returns the number of windows contained in this workspace
    pub fn len(&self) -> uint {
        self.stack.clone().map_or(0, |x| x.len())
    }

    /// Checks if the workspace contains the given window
    pub fn contains(&self, window: Window) -> bool {
        self.stack.clone().map_or(false, |x| x.contains(window))
    }
}

#[deriving(Clone)]
pub struct Screen {
    pub workspace:     Workspace,
    pub screen_id:     u32,
    pub screen_detail: ScreenDetail
}

impl Screen {
    /// Create a new screen for the given workspace
    /// and the given dimensions
    pub fn new(workspace: Workspace, screen_id: u32, screen_detail: ScreenDetail) -> Screen {
        Screen {
            workspace: workspace,
            screen_id: screen_id,
            screen_detail: screen_detail
        }
    }

    /// Checks if the screen's workspace contains
    /// the given window
    pub fn contains(&self, window: Window) -> bool {
        self.workspace.contains(window)
    }

    /// Returns the number of windows in the
    /// screen's workspace
    pub fn len(&self) -> uint {
        self.workspace.len()
    }
}

#[deriving(Clone)]
pub struct Workspaces {
    /// The currently focused and visible screen
    pub current:  Screen,
    /// The other visible, but non-focused screens
    pub visible:  Vec<Screen>,
    /// All remaining workspaces that are currently hidden
    pub hidden:   Vec<Workspace>,
    /// A list of all floating windows
    pub floating: TreeMap<Window, RationalRect>
}

impl Workspaces {
    /// Create a new stackset, of empty stacks, with given tags,
    /// with physical screens whose descriptions are given by 'm'. The
    /// number of physical screens (@length 'm'@) should be less than or
    /// equal to the number of workspace tags.  The first workspace in the
    /// list will be current.
    ///
    /// Xinerama: Virtual workspaces are assigned to physical screens, starting at 0.
    pub fn new(layout: String, tags: Vec<String>, screens: Vec<ScreenDetail>) -> Workspaces {
        debug!("creating new workspaces with {} screen(s)", screens.len());
        let workspaces : Vec<Workspace> = tags.iter()
            .enumerate()
            .map(|(id, tag)| Workspace::new(id as u32, tag.clone(), layout.clone(), None))
            .collect();
        let seen   : Vec<Workspace> = workspaces.iter()
            .take(screens.len())
            .map(|x| x.clone())
            .collect();
        let unseen : Vec<Workspace> = workspaces.iter()
            .skip(screens.len())
            .map(|x| x.clone())
            .collect();
        let current : Vec<Screen> = seen.iter()
            .enumerate()
            .zip(screens.iter())
            .map(|((a, b), c)| Screen::new(b.clone(), a as u32, c.clone()))
            .collect();

        Workspaces {
            current: current.head().unwrap().clone(),
            visible: current.iter().skip(1).map(|x| x.clone()).collect(),
            hidden: unseen,
            floating: TreeMap::new()
        }
    }

    /// Set focus to the workspace with index \'i\'.
    /// If the index is out of range, return the original 'StackSet'.
    ///
    /// Xinerama: If the workspace is not visible on any Xinerama screen, it
    /// becomes the current screen. If it is in the visible list, it becomes
    /// current.
    pub fn view(&self, index: u32) -> Workspaces {
        debug!("setting focus to {}", index);
        if self.current.workspace.id == index {
            return self.clone();
        }

        let mut w = self.clone();

        match w.visible.iter().position(|s| s.workspace.id == index) {
            Some(screen_pos) => {
                let screen = self.visible[screen_pos].clone();
                w.visible.remove(screen_pos);
                w.visible.insert(0, self.current.clone());
                w.current = screen;
                return w;
            },
            _ => ()
        }

        match self.hidden.iter().position(|w| w.id == index) {
            Some(workspace_pos) => {
                let current_workspace = self.current.workspace.clone();
                w.current.workspace = self.hidden[workspace_pos].clone();
                w.hidden.remove(workspace_pos);
                w.hidden.insert(0, current_workspace);
                w
            },
            _ => w
        }
    }

    /// Set focus to the given workspace.  If that workspace does not exist
    /// in the stackset, the original workspace is returned.  If that workspace is
    /// 'hidden', then display that workspace on the current screen, and move the
    /// current workspace to 'hidden'.  If that workspace is 'visible' on another
    /// screen, the workspaces of the current screen and the other screen are
    /// swapped.
    pub fn greedy_view(&self, _: uint) {

    }

    pub fn sink(&self, window: Window) -> Workspaces {
        let mut w = self.clone();
        w.floating.remove(&window);
        w
    }

    pub fn delete(&self, window: Window) -> Workspaces {
        self.delete_p(window).sink(window)
    }

    pub fn delete_p(&self, window: Window) -> Workspaces {
        let mut w = self.clone();

        let remove_from_workspace = |workspace: &mut Workspace| {
            if workspace.stack.is_some() {
                workspace.stack = workspace.clone().stack.unwrap().filter(|&x| x != window);
            }
        };

        remove_from_workspace(&mut w.current.workspace);

        w.hidden.iter_mut().fold((), |_, workspace| {
            remove_from_workspace(workspace)
        });

        w.visible.iter_mut().fold((), |_, screen| {
            remove_from_workspace(&mut screen.workspace)
        });

        w
    }

    /// Move the focus of the currently focused workspace down
    pub fn focus_down(&self) -> Workspaces {
        let mut w = self.clone();
        w.current.workspace.stack = w.current.workspace.stack.map(|s| s.focus_down());
        w
    }

    pub fn focus_up(&self) -> Workspaces {
        let mut w = self.clone();
        w.current.workspace.stack = w.current.workspace.stack.map(|s| s.focus_up());
        w
    }

    pub fn get_focus_window(&self) -> Option<Window> {
        self.current.workspace.stack.clone().map(|s| s.focus)
    }

    /// Retrieve the currently focused workspace's
    /// focus element. If there is none, return None.
    pub fn peek(&self) -> Option<Window> {
        self.with(None, |s| Some(s.focus))
    }

    /// Apply the given function to the currently focused stack
    /// or return a default if the stack is empty
    pub fn with<T>(&self, default: T, f: |&Stack<Window>| -> T) -> T {
        match self.current.workspace.stack {
            Some(ref s) => f(s),
            None        => default
        }
    }

    /// Return the number of windows
    /// contained in all workspaces, including floating windows
    pub fn len(&self) -> uint {
        self.current.len() +
        self.visible.iter().map(|x| x.len()).sum() +
        self.hidden.iter().map(|x| x.len()).sum() +
        self.floating.len()
    }

    /// Checks if any of the workspaces contains the
    /// given window
    pub fn contains(&self, window: Window) -> bool {
        self.current.contains(window) ||
        self.visible.iter().any(|x| x.contains(window)) ||
        self.hidden.iter().any(|x| x.contains(window)) ||
        self.floating.contains_key(&window)
    }

    /// Get the number of managed workspaces.
    /// This is mostly used for out-of-bounds checking.
    pub fn number_workspaces(&self) -> u32 {
        (1 + self.visible.len() + self.hidden.len()) as u32
    }

    /// Shift the currently focused window to the given workspace
    pub fn shift(&self, index: u32) -> Workspaces {
        // Get current window
        self.peek()
            // and move it
            .map_or(self.clone(), |w| self.shift_window(index, w))
    }

    pub fn insert_up(&self, window: Window) -> Workspaces {
        if self.contains(window) {
            return self.clone();
        }

        let mut w = self.clone();
        match w.current.workspace.stack {
            Some(ref mut s) => {
                s.down.insert(0, s.focus.clone());
                s.focus = window;
            },
            None => w.current.workspace.stack = Some(Stack::from_element(window))
        }
        w
    }

    /// Retrieve the currently focused workspace's id
    pub fn current_tag(&self) -> u32 {
        self.current.workspace.id as u32
    }

    /// Retrieve the tag of the workspace the given window
    /// is contained in. If it is not contained anywhere,
    /// return None.
    pub fn find_tag(&self, window: Window) -> Option<u32> {
        self.workspaces().iter()
            .filter(|x| x.contains(window))
            .map(|x| x.id as u32)
            .nth(0)
    }

    pub fn workspaces(&self) -> Vec<Workspace> {
        let v : Vec<Workspace> = self.visible.iter().map(|x| x.workspace.clone()).collect();
        (vec!(self.current.workspace.clone())).iter()
            .chain(v.iter())
            .chain(self.hidden.iter())
            .map(|x| x.clone())
            .collect()
    }

    pub fn shift_window(&self, index: u32, window: Window) -> Workspaces {
        let first_closure = (box move |&: w: Workspaces| {
            w.delete(window)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>;

        let second_closure = (box move |&: w: Workspaces| {
            w.insert_up(window)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>;

        match self.find_tag(window) {
            Some(from) => {
                let a = self.on_workspace(from, first_closure);
                let b = self.on_workspace(index, second_closure);

                debug!("shifting window from {} to {}", from, index);
                (*b).call(((*a).call((self.clone(),)),))
            },
            None => self.clone()
        }
    }

    pub fn on_workspace(&self, index: u32, f: Box<Fn<(Workspaces,), Workspaces> + 'static>)
            -> Box<Fn<(Workspaces,), Workspaces> + 'static> {
        (box move |&: x: Workspaces| {
            let current_tag = x.current_tag();
            (*f).call((x.view(index),)).view(current_tag)
        }) as Box<Fn<(Workspaces,), Workspaces> + 'static>
    }
}
<|endoftext|>


<commit_before>
use ndarray::*;

use super::error::*;
use super::layout::*;

use impl2::{LapackScalar, UPLO};

pub trait Eigh<EigVal, EigVec> {
    fn eigh(self, UPLO) -> Result<(EigVal, EigVec)>;
}

impl<A, S, Se> Eigh<ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

impl<'a, A, S, Se> Eigh<ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>> for &'a mut ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

pub trait EigValsh<EigVal> {
    fn eigvalsh(self, UPLO) -> Result<EigVal>;
}
<commit_msg>impl Eigh for &ArrayBase<commit_after>
use ndarray::*;

use super::error::*;
use super::layout::*;

use impl2::{LapackScalar, UPLO};

pub trait Eigh<EigVal, EigVec> {
    fn eigh(self, UPLO) -> Result<(EigVal, EigVec)>;
}

impl<A, S, Se> Eigh<ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

impl<'a, A, S, Se, So> Eigh<ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Copy,
          S: Data<Elem = A>,
          Se: DataOwned<Elem = A::Real>,
          So: DataOwned<Elem = A> + DataMut
{
    fn eigh(self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>)> {
        let mut a = replicate(self);
        let s = A::eigh(true, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), a))
    }
}

impl<'a, A, S, Se> Eigh<ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>> for &'a mut ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

pub trait EigValsh<EigVal> {
    fn eigvalsh(self, UPLO) -> Result<EigVal>;
}
<|endoftext|>


<commit_before>
use std::ops::{Not};

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum PlayerColor {
    White,
    Black
}

// This implementation allows PlayerColor::White == !PlayerColor::Black.
impl Not for PlayerColor {
    type Output = PlayerColor;

    fn not(self) -> PlayerColor {
        match self {
            PlayerColor::White => PlayerColor::Black,
            PlayerColor::Black => PlayerColor::White
        }
    }
}

#[allow(dead_code)] // Dead code is allowed, because I want x, y, z even if I don't use it.
#[derive(Debug)]
pub struct Point {
    pub x : i8,
    pub y : i8,
    pub z : i8,
    pub flat_coordinate : i8,
    pub lines : Vec<i8> // This vector stores the IDs of all lines through it.
}

impl Point {
    // constructor, by convention
    pub fn new(x:i8, y:i8, z:i8) -> Point {
        Point {x:x, y:y, z:z, flat_coordinate:flatten(x, y, z), lines:Vec::new()} //, lines : Vec::new()}
    }
}

pub fn flatten(x:i8, y:i8, z:i8) -> i8 {
    return x + 4*y + 16*z
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum Action {
    Play {x : i8, y : i8},
    Surrender
}

impl Action {
    pub fn new(x : i8, y : i8) -> Action {
        Action::Play {x:x, y:y}
    }
}

pub struct Line {
    points : [Point; 4]
}

impl Line {
    // constructor, by convention
    pub fn new(x:i8, y:i8, z:i8, dx:i8, dy:i8, dz:i8) -> Line {
        let point1 = Point::new(x, y, z);
        let point2 = Point::new(x+1*dx, y+1*dy, z+1*dz);
        let point3 = Point::new(x+2*dx, y+2*dy, z+2*dz);
        let point4 = Point::new(x+3*dx, y+3*dy, z+3*dz);
        Line { points : [point1, point2, point3, point4]}
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum PointState {
    Piece(PlayerColor),
    Empty
}

#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum LineState {
    Empty,
    Pure { color: PlayerColor, count: i8 },
    Mixed,
    Win(PlayerColor),
}

impl LineState {
    fn add_ball_functional(line_state : LineState, new_color : PlayerColor) -> LineState {
        match line_state {
            LineState::Empty => LineState::Pure { color : new_color, count : 1},
            LineState::Pure { color : current_color, count : old_count} =>
                if current_color != new_color { LineState::Mixed } else {
                    if old_count == 3 {LineState::Win(current_color)}
                    else {LineState::Pure {color : current_color, count : old_count+1}}
                },
            LineState::Mixed => LineState::Mixed,
            LineState::Win(_) => panic!("A filled line can't accept any more balls.")
        }
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum VictoryState {
    Undecided,
    Win(PlayerColor),
    Draw
}

#[derive(Debug, Copy, Clone)]
pub struct VictoryStats {
    pub white : i32,
    pub black : i32,
    pub draws : i32,
}

impl VictoryStats {
    pub fn new() -> VictoryStats {
        VictoryStats { white : 0, black : 0, draws : 0}
    }
}

// TODO: Recomputing this and passing it around gets boring at some point.
// Once we abstract over several different game structures
// this should be moved to a macro and be created once at compile time.
pub struct GameStructure {
    pub points : Vec<Point>,
    pub lines  : Vec<Line>
}

impl GameStructure {
    pub fn new() -> GameStructure {
        // Initialize a vector of all Points.
        let mut point_box = Vec::new();
        for z in 0..4 {
            for y in 0..4 {
                for x in 0..4 {
                    point_box.push(Point::new(x, y, z));
                }
            }
        }

        // Initialize a vector of all Lines.
        let mut line_box = Vec::new();
        for a in 0..4 {
            for b in 0..4 {
                line_box.push(Line::new(a, b, 0, 0, 0, 1));
                line_box.push(Line::new(0, a, b, 1, 0, 0));
                line_box.push(Line::new(b, 0, a, 0, 1, 0))
            }
            // Diagonals in two spacial directions
            line_box.push(Line::new(a, 0, 0, 0, 1, 1));
            line_box.push(Line::new(0, a, 0, 1, 0, 1));
            line_box.push(Line::new(0, 0, a, 1, 1, 0));
            line_box.push(Line::new(a, 3, 0, 0,-1, 1));
            line_box.push(Line::new(0, a, 3, 1, 0,-1));
            line_box.push(Line::new(3, 0, a,-1, 1, 0));
        }
        // Diagonals in all three directions at once
        line_box.push(Line::new(0, 0, 0, 1, 1, 1));
        line_box.push(Line::new(3, 0, 0,-1, 1, 1));
        line_box.push(Line::new(3, 3, 0,-1,-1, 1));
        line_box.push(Line::new(0, 3, 0, 1,-1, 1));

        // Refenence the line ID in the points.
        let mut i = 0;
        for line in &line_box {
            for point in line.points.iter() {
                point_box[point.flat_coordinate as usize].lines.push(i);
            }
            i += 1;
        }
        GameStructure { points : point_box, lines : line_box }
    }
}

pub struct GameState {
    pub points : [PointState; 64], // Maybe we want to change this into a Vector.
    pub lines  : [LineState; 76],
    pub current_color : PlayerColor,
    pub victory_state : VictoryState,
    pub age : i8, // how many balls were played?
    pub legal_actions : Vec<Action>,
}

impl Clone for GameState {
    fn clone(&self) -> GameState {
        let mut point_clone = [PointState::Empty; 64];
        let mut line_clone  = [LineState::Empty; 76];
        for i in 0..64 {
            point_clone[i] = self.points[i].clone();
        }
        for i in 0..76 {
            line_clone[i] = self.lines[i].clone();
        }
        GameState {
            points : point_clone,
            lines  : line_clone,
            current_color : self.current_color.clone(),
            victory_state : self.victory_state.clone(),
            age : self.age.clone(),
            legal_actions : self.legal_actions.clone(),
        }
    }
}

impl GameState {
    pub fn new() -> GameState {
        // The board is empty and all actions are legal
        let mut legal = Vec::new();
        for x in 0..4 {
            for y in 0..4 {
                legal.push(Action::new(x,y));
            }
        }
        GameState {
            points : [PointState::Empty; 64],
            lines : [LineState::Empty; 76],
            current_color : PlayerColor::White,
            victory_state : VictoryState::Undecided,
            age : 0,
            legal_actions : legal,
        }
    }

    pub fn execute_action(&mut self, structure : &GameStructure, play : &Action) {
        match play {
            &Action::Surrender   => self.victory_state = VictoryState::Win(!self.current_color),
            &Action::Play {x, y} => self.play_at(structure, x, y),
        }
    }
    pub fn execute_action_functional(&self, structure : &GameStructure, play : &Action) -> GameState {
        let mut result = self.clone();
        result.execute_action(structure, &play);
        return result;
    }

    // Idea: This could be cached inside each gamestate.
    fn z_value(&self, x : i8, y : i8) -> Option<i8> {
        for z in 0..4 {
            if self.points[flatten(x, y, z) as usize] == PointState::Empty {
                return Some(z)
            }
        }
        return None
    }

    fn play_at(&mut self, structure : &GameStructure, x:i8, y:i8) {
        let z = self.z_value(x, y);
        let flat_coordinate = match z {
            Some(z) => flatten(x, y, z),
            None => panic!("Added a ball at ({}, {}), which is already full.", x, y)
        };
        // Place a colored piece at the coordinate
        self.points[flat_coordinate as usize] = PointState::Piece(self.current_color);
        // Update the legal actions, if the z-coordinate is 3
        // I make use of the fact that the z coordinate is occupying the top two bits.
        if flat_coordinate >= 4*4*3 {
            // As the legal actions will be mixed up during play, we need to search through all.
            for i in 0..self.legal_actions.len() {
                // TODO: Don't construct a new Action object just to compare.
                if self.legal_actions[i] == Action::new(x, y) {
                    self.legal_actions.swap_remove(i);
                    // Removes an element from anywhere in the vector and return it, replacing it with the last element.
                    // This does not preserve ordering, but is O(1).
                    break;
                }
            }
        }
        for line in structure.points[flat_coordinate as usize].lines.clone() {
            let line_state = LineState::add_ball_functional(self.lines[line as usize], self.current_color);
            match line_state {
                LineState::Win(color) => self.victory_state = VictoryState::Win(color),
                _ => (),
            }
            self.lines[line as usize] = line_state;
        }
        self.age += 1;
        if self.age == 64 && self.victory_state == VictoryState::Undecided {
            self.victory_state = VictoryState::Draw;
        }
        self.current_color = !self.current_color;
    }
}
<commit_msg>The GameState now uses Vectors instead of Arrays.<commit_after>use std::ops::{Not};

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum PlayerColor {
    White,
    Black
}

// This implementation allows PlayerColor::White == !PlayerColor::Black.
impl Not for PlayerColor {
    type Output = PlayerColor;

    fn not(self) -> PlayerColor {
        match self {
            PlayerColor::White => PlayerColor::Black,
            PlayerColor::Black => PlayerColor::White
        }
    }
}

#[allow(dead_code)] // Dead code is allowed, because I want x, y, z even if I don't use it.
#[derive(Debug)]
pub struct Point {
    pub x : i8,
    pub y : i8,
    pub z : i8,
    pub flat_coordinate : i8,
    pub lines : Vec<i8> // This vector stores the IDs of all lines through it.
}

impl Point {
    // constructor, by convention
    pub fn new(x:i8, y:i8, z:i8) -> Point {
        Point {x:x, y:y, z:z, flat_coordinate:flatten(x, y, z), lines:Vec::new()} //, lines : Vec::new()}
    }
}

pub fn flatten(x:i8, y:i8, z:i8) -> i8 {
    return x + 4*y + 16*z
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum Action {
    Play {x : i8, y : i8},
    Surrender
}

impl Action {
    pub fn new(x : i8, y : i8) -> Action {
        Action::Play {x:x, y:y}
    }
}

pub struct Line {
    points : [Point; 4]
}

impl Line {
    // constructor, by convention
    pub fn new(x:i8, y:i8, z:i8, dx:i8, dy:i8, dz:i8) -> Line {
        let point1 = Point::new(x, y, z);
        let point2 = Point::new(x+1*dx, y+1*dy, z+1*dz);
        let point3 = Point::new(x+2*dx, y+2*dy, z+2*dz);
        let point4 = Point::new(x+3*dx, y+3*dy, z+3*dz);
        Line { points : [point1, point2, point3, point4]}
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum PointState {
    Piece(PlayerColor),
    Empty
}

#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum LineState {
    Empty,
    Pure { color: PlayerColor, count: i8 },
    Mixed,
    Win(PlayerColor),
}

impl LineState {
    fn add_ball_functional(line_state : LineState, new_color : PlayerColor) -> LineState {
        match line_state {
            LineState::Empty => LineState::Pure { color : new_color, count : 1},
            LineState::Pure { color : current_color, count : old_count} =>
                if current_color != new_color { LineState::Mixed } else {
                    if old_count == 3 {LineState::Win(current_color)}
                    else {LineState::Pure {color : current_color, count : old_count+1}}
                },
            LineState::Mixed => LineState::Mixed,
            LineState::Win(_) => panic!("A filled line can't accept any more balls.")
        }
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum VictoryState {
    Undecided,
    Win(PlayerColor),
    Draw
}

#[derive(Debug, Copy, Clone)]
pub struct VictoryStats {
    pub white : i32,
    pub black : i32,
    pub draws : i32,
}

impl VictoryStats {
    pub fn new() -> VictoryStats {
        VictoryStats { white : 0, black : 0, draws : 0}
    }
}

// TODO: Recomputing this and passing it around gets boring at some point.
// Once we abstract over several different game structures
// this should be moved to a macro and be created once at compile time.
pub struct GameStructure {
    pub points : Vec<Point>,
    pub lines  : Vec<Line>
}

impl GameStructure {
    pub fn new() -> GameStructure {
        // Initialize a vector of all Points.
        let mut point_box = Vec::new();
        for z in 0..4 {
            for y in 0..4 {
                for x in 0..4 {
                    point_box.push(Point::new(x, y, z));
                }
            }
        }

        // Initialize a vector of all Lines.
        let mut line_box = Vec::new();
        for a in 0..4 {
            for b in 0..4 {
                line_box.push(Line::new(a, b, 0, 0, 0, 1));
                line_box.push(Line::new(0, a, b, 1, 0, 0));
                line_box.push(Line::new(b, 0, a, 0, 1, 0))
            }
            // Diagonals in two spacial directions
            line_box.push(Line::new(a, 0, 0, 0, 1, 1));
            line_box.push(Line::new(0, a, 0, 1, 0, 1));
            line_box.push(Line::new(0, 0, a, 1, 1, 0));
            line_box.push(Line::new(a, 3, 0, 0,-1, 1));
            line_box.push(Line::new(0, a, 3, 1, 0,-1));
            line_box.push(Line::new(3, 0, a,-1, 1, 0));
        }
        // Diagonals in all three directions at once
        line_box.push(Line::new(0, 0, 0, 1, 1, 1));
        line_box.push(Line::new(3, 0, 0,-1, 1, 1));
        line_box.push(Line::new(3, 3, 0,-1,-1, 1));
        line_box.push(Line::new(0, 3, 0, 1,-1, 1));

        // Refenence the line ID in the points.
        let mut i = 0;
        for line in &line_box {
            for point in line.points.iter() {
                point_box[point.flat_coordinate as usize].lines.push(i);
            }
            i += 1;
        }
        GameStructure { points : point_box, lines : line_box }
    }
}

#[derive(Clone)]
pub struct GameState {
    pub points : Vec<PointState>, // Maybe we want to change this into a Vector.
    pub lines  : Vec<LineState>,
    pub current_color : PlayerColor,
    pub victory_state : VictoryState,
    pub age : i8, // how many balls were played?
    pub legal_actions : Vec<Action>,
}

impl GameState {
    pub fn new() -> GameState {
        // The board is empty and all actions are legal
        let mut legal = Vec::new();
        for x in 0..4 {
            for y in 0..4 {
                legal.push(Action::new(x,y));
            }
        }
        GameState {
            points : vec![PointState::Empty; 64],
            lines : vec![LineState::Empty; 76],
            current_color : PlayerColor::White,
            victory_state : VictoryState::Undecided,
            age : 0,
            legal_actions : legal,
        }
    }

    pub fn execute_action(&mut self, structure : &GameStructure, play : &Action) {
        match play {
            &Action::Surrender   => self.victory_state = VictoryState::Win(!self.current_color),
            &Action::Play {x, y} => self.play_at(structure, x, y),
        }
    }
    pub fn execute_action_functional(&self, structure : &GameStructure, play : &Action) -> GameState {
        let mut result = self.clone();
        result.execute_action(structure, &play);
        return result;
    }

    // Idea: This could be cached inside each gamestate.
    fn z_value(&self, x : i8, y : i8) -> Option<i8> {
        for z in 0..4 {
            if self.points[flatten(x, y, z) as usize] == PointState::Empty {
                return Some(z)
            }
        }
        return None
    }

    fn play_at(&mut self, structure : &GameStructure, x:i8, y:i8) {
        let z = self.z_value(x, y);
        let flat_coordinate = match z {
            Some(z) => flatten(x, y, z),
            None => panic!("Added a ball at ({}, {}), which is already full.", x, y)
        };
        // Place a colored piece at the coordinate
        self.points[flat_coordinate as usize] = PointState::Piece(self.current_color);
        // Update the legal actions, if the z-coordinate is 3
        // I make use of the fact that the z coordinate is occupying the top two bits.
        if flat_coordinate >= 4*4*3 {
            // As the legal actions will be mixed up during play, we need to search through all.
            for i in 0..self.legal_actions.len() {
                // TODO: Don't construct a new Action object just to compare.
                if self.legal_actions[i] == Action::new(x, y) {
                    self.legal_actions.swap_remove(i);
                    // Removes an element from anywhere in the vector and return it, replacing it with the last element.
                    // This does not preserve ordering, but is O(1).
                    break;
                }
            }
        }
        for line in structure.points[flat_coordinate as usize].lines.clone() {
            let line_state = LineState::add_ball_functional(self.lines[line as usize], self.current_color);
            match line_state {
                LineState::Win(color) => self.victory_state = VictoryState::Win(color),
                _ => (),
            }
            self.lines[line as usize] = line_state;
        }
        self.age += 1;
        if self.age == 64 && self.victory_state == VictoryState::Undecided {
            self.victory_state = VictoryState::Draw;
        }
        self.current_color = !self.current_color;
    }
}
<|endoftext|>


<commit_before>use sdl::{event,render,pixels,video,keycode};
use sdl::rect::Point;
use std::default::Default;

type Renderer = render::Renderer<video::Window>;

pub struct Loop {
    renderer : Renderer,
    state : State,
}

impl Loop {
    pub fn new(renderer : Renderer) -> Loop {
        let output_size = renderer.get_output_size().unwrap();
        Loop {
            renderer : renderer,
            state : State::new(output_size)
        }
    }

    pub fn handlekey(&mut self, keyDown : bool, key : keycode::KeyCode) {
        let mut dummy = false;
        let keys = &mut self.state.keys;
        let oldkeys = *keys;
        *match key {
            keycode::UpKey => &mut keys.up,
            keycode::DownKey => &mut keys.down,
            keycode::LeftKey => &mut keys.left,
            keycode::RightKey => &mut keys.right,
            keycode::SpaceKey => &mut keys.space,
            _ => &mut dummy // Ignore any other keys
        } = keyDown;
        if *keys != oldkeys {
            println!("{}",*keys);
        }
    }

    pub fn update(&mut self) {
        {
            let keys = self.state.keys;
            let player = &mut self.state.player1;
            if keys.up { player.accelerate() }
            if keys.down { player.decelerate() }
            if keys.left { player.turn_left() }
            if keys.right { player.turn_right() }
        }
        self.draw();
    }

    pub fn draw(&self) {
        let renderer = &self.renderer;
        renderer.set_draw_color(pixels::RGB(0,0,0)).unwrap();
        renderer.clear().unwrap();
        renderer.set_draw_color(pixels::RGB(255,255,255)).unwrap();
        renderer.draw_point(self.state.player1.real_pos()).unwrap();
        renderer.present();
    }
}

struct State {
    keys : KeyState,
    player1 : PlayerShip
}

impl State {
    fn new(dims : (int,int)) -> State {
        let midpoint = {
        };
        State {
            keys : Default::default(),
            player1 : PlayerShip::new(dims)
        }
    }
}

#[deriving(Default,PartialEq,Eq,Show)]
struct KeyState {
    down : bool,
    left : bool,
    right : bool,
    up: bool,
    space: bool,
}

// For smoother movement, everything is stored to 64th of a pixel accuracy
struct PlayerShip {
    pos : Point,
    vel : Point,
    angle : f32, // Zero points upwards.
    dimensions : (int,int),
}

impl PlayerShip {
    fn new(dims : (int,int)) -> PlayerShip {
        PlayerShip {
            pos : Point::new(0,0),
            vel : Point::new(0,0),
            angle : 0.0,
            dimensions : dims
        }
    }

    fn real_pos(&self) -> Point {
        self.pos
    }

    fn update(&mut self) {
    }
    fn accelerate(&mut self) {
    }
    fn decelerate(&mut self) {
    }
    fn turn_left(&mut self) {
    }
    fn turn_right(&mut self) {
    }
}
<commit_msg>Have the ship draw itself.<commit_after>use sdl::{event,render,pixels,video,keycode};
use sdl::rect::Point;
use std::default::Default;

type Renderer = render::Renderer<video::Window>;

pub struct Loop {
    renderer : Renderer,
    state : State,
}

impl Loop {
    pub fn new(renderer : Renderer) -> Loop {
        let output_size = renderer.get_output_size().unwrap();
        Loop {
            renderer : renderer,
            state : State::new(output_size)
        }
    }

    pub fn handlekey(&mut self, keyDown : bool, key : keycode::KeyCode) {
        // I'm feeling a bit iffy about this. Ideally, no dummy variable
        // should be needed.
        let mut dummy = false;
        let keys = &mut self.state.keys;
        let oldkeys = *keys;
        *match key {
            keycode::UpKey => &mut keys.up,
            keycode::DownKey => &mut keys.down,
            keycode::LeftKey => &mut keys.left,
            keycode::RightKey => &mut keys.right,
            keycode::SpaceKey => &mut keys.space,
            _ => &mut dummy // Ignore any other keys
        } = keyDown;
        if *keys != oldkeys {
            println!("{}",*keys);
        }
    }

    pub fn update(&mut self) {
        {
            let keys = self.state.keys;
            let player = &mut self.state.player1;
            if keys.up { player.accelerate() }
            if keys.down { player.decelerate() }
            if keys.left { player.turn_left() }
            if keys.right { player.turn_right() }
        }
        self.draw();
    }

    pub fn draw(&self) {
        let renderer = &self.renderer;
        renderer.set_draw_color(pixels::RGB(0,0,0)).unwrap();
        renderer.clear().unwrap();
        self.state.player1.draw(renderer);
        renderer.present();
    }
}

struct State {
    keys : KeyState,
    player1 : PlayerShip
}

impl State {
    fn new(dims : (int,int)) -> State {
        let midpoint = {
        };
        State {
            keys : Default::default(),
            player1 : PlayerShip::new(dims)
        }
    }
}

#[deriving(Default,PartialEq,Eq,Show)]
struct KeyState {
    down : bool,
    left : bool,
    right : bool,
    up: bool,
    space: bool,
}

// For smoother movement, everything is stored to 64th of a pixel accuracy
struct PlayerShip {
    pos : Point,
    vel : Point,
    angle : f32, // Zero points upwards.
    dimensions : (int,int),
}

impl PlayerShip {
    fn new((xmax,ymax) : (int,int)) -> PlayerShip {
        PlayerShip {
            pos : Point::new(0,0),
            vel : Point::new(0,0),
            angle : 0.0,
            dimensions : (xmax*64,ymax*64)
        }
    }

    fn accelerate(&mut self) {
    }
    fn decelerate(&mut self) {
    }
    fn turn_left(&mut self) {
    }
    fn turn_right(&mut self) {
    }

    fn update(&mut self) {
    }

    fn draw(&self, renderer : &Renderer) {
        renderer.set_draw_color(pixels::RGB(255,255,255)).unwrap();
    }
}
<|endoftext|>