<commit_before>//! Input sessions for simplified collection updates.
//!
//! Although users can directly manipulate timely dataflow streams as collection inputs,
//! the `InputSession` type can make this more efficient and less error-prone. Specifically,
//! the type batches up updates with their logical times and ships them with coarsened
//! timely dataflow capabilities, exposing more concurrency to the operator implementations
//! than are evident from the logical times, which appear to execute in sequence.

use timely::progress::Timestamp;
use timely::dataflow::operators::Input as TimelyInput;
use timely::dataflow::operators::input::Handle;
use timely::dataflow::scopes::ScopeParent;

use ::{Data, Diff};
use collection::{Collection, AsCollection};

/// Create a new collection and input handle to control the collection.
pub trait Input : TimelyInput {
    /// Create a new collection and input handle to subsequently control the collection.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use timely::Configuration;
    /// use differential_dataflow::input::Input;
    ///
    /// fn main() {
    ///     ::timely::execute(Configuration::Thread, |worker| {
    ///
    ///			let (mut handle, probe) = worker.dataflow::<(),_,_>(|scope| {
    ///				// create input handle and collection.
    ///				let (handle, data) = scope.new_collection();
    ///         	let probe = data.map(|x| x * 2)
    ///				            	.inspect(|x| println!("{:?}", x))
    ///				            	.probe();
    ///				(handle, probe)
    ///     	});
    ///
    ///			handle.insert(1);
    ///			handle.insert(5);
    ///
    ///		}).unwrap();
    /// }
    /// ```
    fn new_collection<D, R>(&mut self) -> (InputSession<<Self as ScopeParent>::Timestamp, D, R>, Collection<Self, D, R>)
    where D: Data, R: Diff;
    /// Create a new collection and input handle from initial data.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use timely::Configuration;
    /// use differential_dataflow::input::Input;
    ///
    /// fn main() {
    ///     ::timely::execute(Configuration::Thread, |worker| {
    ///
    ///			let (mut handle, probe) = worker.dataflow::<(),_,_>(|scope| {
    ///				// create input handle and collection.
    ///				let (handle, data) = scope.new_collection_from(0 .. 10);
    ///         	let probe = data.map(|x| x * 2)
    ///				            	.inspect(|x| println!("{:?}", x))
    ///				            	.probe();
    ///				(handle, probe)
    ///     	});
    ///
    ///			handle.insert(1);
    ///			handle.insert(5);
    ///
    ///		}).unwrap();
    /// }
    /// ```
    fn new_collection_from<I>(&mut self, data: I) -> (InputSession<<Self as ScopeParent>::Timestamp, I::Item, isize>, Collection<Self, I::Item, isize>)
    where I: IntoIterator+'static, I::Item: Data;
}

use lattice::Lattice;
impl<G: TimelyInput> Input for G where <G as ScopeParent>::Timestamp: Lattice {
    fn new_collection<D, R>(&mut self) -> (InputSession<<G as ScopeParent>::Timestamp, D, R>, Collection<G, D, R>)
    where D: Data, R: Diff{
		let (handle, stream) = self.new_input();
		(InputSession::from(handle), stream.as_collection())
    }
    fn new_collection_from<I>(&mut self, data: I) -> (InputSession<<G as ScopeParent>::Timestamp, I::Item, isize>, Collection<G, I::Item, isize>)
    where I: IntoIterator+'static, I::Item: Data {

    	use timely::dataflow::operators::ToStream;

		let (handle, stream) = self.new_input();
		let source = data.into_iter().map(|d| (d, Default::default(), 1)).to_stream(self).as_collection();

		(InputSession::from(handle), stream.as_collection().concat(&source))
    }
}

/// An input session wrapping a single timely dataflow capability.
///
/// Each timely dataflow message has a corresponding capability, which is a logical time in the
/// timely dataflow system. Differential dataflow updates can happen at a much higher rate than
/// timely dataflow's progress tracking infrastructure supports, because the logical times are
/// promoted to data and updates are batched together. The `InputSession` type does this batching.
///
/// # Examples
///
/// ```
/// extern crate timely;
/// extern crate differential_dataflow;
///
/// use timely::Configuration;
/// use differential_dataflow::input::Input;
///
/// fn main() {
///     ::timely::execute(Configuration::Thread, |worker| {
///
///			let (mut handle, probe) = worker.dataflow(|scope| {
///				// create input handle and collection.
///				let (handle, data) = scope.new_collection_from(0 .. 10);
///         	let probe = data.map(|x| x * 2)
///				            	.inspect(|x| println!("{:?}", x))
///				            	.probe();
///				(handle, probe)
///     	});
///
///			handle.insert(3);
///			handle.advance_to(1);
///			handle.insert(5);
///			handle.advance_to(2);
///			handle.flush();
///
///			while probe.less_than(handle.time()) {
///				worker.step();
///			}
///
///			handle.remove(5);
///			handle.advance_to(3);
///			handle.flush();
///
///			while probe.less_than(handle.time()) {
///				worker.step();
///			}
///
///		}).unwrap();
/// }
/// ```
pub struct InputSession<T: Timestamp+Clone, D: Data, R: Diff> {
	time: T,
	buffer: Vec<(D, T, R)>,
	handle: Handle<T,(D,T,R)>,
}

impl<T: Timestamp+Clone, D: Data> InputSession<T, D, isize> {
	/// Adds an element to the collection.
	pub fn insert(&mut self, element: D) { self.update(element, 1); }
	/// Removes an element from the collection.
	pub fn remove(&mut self, element: D) { self.update(element,-1); }
}

// impl<T: Timestamp+Clone, D: Data> InputSession<T, D, i64> {
//     /// Adds an element to the collection.
//     pub fn insert(&mut self, element: D) { self.update(element, 1); }
//     /// Removes an element from the collection.
//     pub fn remove(&mut self, element: D) { self.update(element,-1); }
// }

// impl<T: Timestamp+Clone, D: Data> InputSession<T, D, i32> {
//     /// Adds an element to the collection.
//     pub fn insert(&mut self, element: D) { self.update(element, 1); }
//     /// Removes an element from the collection.
//     pub fn remove(&mut self, element: D) { self.update(element,-1); }
// }

impl<T: Timestamp+Clone, D: Data, R: Diff> InputSession<T, D, R> {

    /// Introduces a handle as collection.
    pub fn to_collection<G: TimelyInput>(&mut self, scope: &mut G) -> Collection<G, D, R>
    where
        G: ScopeParent<Timestamp=T>,
    {
        scope
            .input_from(&mut self.handle)
            .as_collection()
    }

    /// Allocates a new input handle.
    pub fn new() -> Self {
        let handle: Handle<T,_> = Handle::new();
        InputSession {
            time: handle.time().clone(),
            buffer: Vec::new(),
            handle,
        }
    }

	/// Creates a new session from a reference to an input handle.
	pub fn from(handle: Handle<T,(D,T,R)>) -> Self {
		InputSession {
			time: handle.time().clone(),
			buffer: Vec::new(),
			handle,
		}
	}

	/// Adds to the weight of an element in the collection.
	pub fn update(&mut self, element: D, change: R) {
        if self.buffer.len() == self.buffer.capacity() {
            if self.buffer.len() > 0 {
                self.handle.send_batch(&mut self.buffer);
            }
            // TODO : This is a fairly arbitrary choice; should probably use `Context::default_size()` or such.
            self.buffer.reserve(1024);
        }
		self.buffer.push((element, self.time.clone(), change));
	}

    /// Adds to the weight of an element in the collection at a future time.
    pub fn update_at(&mut self, element: D, time: T, change: R) {
        assert!(self.time.less_equal(&time));
        if self.buffer.len() == self.buffer.capacity() {
            if self.buffer.len() > 0 {
                self.handle.send_batch(&mut self.buffer);
            }
            // TODO : This is a fairly arbitrary choice; should probably use `Context::default_size()` or such.
            self.buffer.reserve(1024);
        }
        self.buffer.push((element, time, change));
    }

	/// Forces buffered data into the timely dataflow input, and advances its time to match that of the session.
	///
	/// It is important to call `flush` before expecting timely dataflow to report progress. Until this method is
	/// called, all updates may still be in internal buffers and not exposed to timely dataflow. Once the method is
	/// called, all buffers are flushed and timely dataflow is advised that some logical times are no longer possible.
	pub fn flush(&mut self) {
		self.handle.send_batch(&mut self.buffer);
		if self.handle.epoch().less_than(&self.time) {
			self.handle.advance_to(self.time.clone());
		}
	}

	/// Advances the logical time for future records.
	///
	/// Importantly, this method does **not** immediately inform timely dataflow of the change. This happens only when
	/// the session is dropped or flushed. It is not correct to use this time as a basis for a computation's `step_while`
	/// method unless the session has just been flushed.
	pub fn advance_to(&mut self, time: T) {
		assert!(self.handle.epoch().less_equal(&time));
		assert!(&self.time.less_equal(&time));
		self.time = time;
	}

	/// Reveals the current time of the session.
	pub fn epoch(&self) -> &T { &self.time }
	/// Reveals the current time of the session.
	pub fn time(&self) -> &T { &self.time }

	/// Closes the input, flushing and sealing the wrapped timely input.
	pub fn close(self) { }
}

impl<T: Timestamp+Clone, D: Data, R: Diff> Drop for InputSession<T, D, R> {
	fn drop(&mut self) {
		self.flush();
	}
}
<commit_msg>raw input method<commit_after>//! Input sessions for simplified collection updates.
//!
//! Although users can directly manipulate timely dataflow streams as collection inputs,
//! the `InputSession` type can make this more efficient and less error-prone. Specifically,
//! the type batches up updates with their logical times and ships them with coarsened
//! timely dataflow capabilities, exposing more concurrency to the operator implementations
//! than are evident from the logical times, which appear to execute in sequence.

use timely::progress::Timestamp;
use timely::dataflow::operators::Input as TimelyInput;
use timely::dataflow::operators::input::Handle;
use timely::dataflow::scopes::ScopeParent;

use ::{Data, Diff};
use collection::{Collection, AsCollection};

/// Create a new collection and input handle to control the collection.
pub trait Input : TimelyInput {
    /// Create a new collection and input handle to subsequently control the collection.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use timely::Configuration;
    /// use differential_dataflow::input::Input;
    ///
    /// fn main() {
    ///     ::timely::execute(Configuration::Thread, |worker| {
    ///
    ///			let (mut handle, probe) = worker.dataflow::<(),_,_>(|scope| {
    ///				// create input handle and collection.
    ///				let (handle, data) = scope.new_collection();
    ///         	let probe = data.map(|x| x * 2)
    ///				            	.inspect(|x| println!("{:?}", x))
    ///				            	.probe();
    ///				(handle, probe)
    ///     	});
    ///
    ///			handle.insert(1);
    ///			handle.insert(5);
    ///
    ///		}).unwrap();
    /// }
    /// ```
    fn new_collection<D, R>(&mut self) -> (InputSession<<Self as ScopeParent>::Timestamp, D, R>, Collection<Self, D, R>)
    where D: Data, R: Diff;
    /// Create a new collection and input handle from initial data.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use timely::Configuration;
    /// use differential_dataflow::input::Input;
    ///
    /// fn main() {
    ///     ::timely::execute(Configuration::Thread, |worker| {
    ///
    ///			let (mut handle, probe) = worker.dataflow::<(),_,_>(|scope| {
    ///				// create input handle and collection.
    ///				let (handle, data) = scope.new_collection_from(0 .. 10);
    ///         	let probe = data.map(|x| x * 2)
    ///				            	.inspect(|x| println!("{:?}", x))
    ///				            	.probe();
    ///				(handle, probe)
    ///     	});
    ///
    ///			handle.insert(1);
    ///			handle.insert(5);
    ///
    ///		}).unwrap();
    /// }
    /// ```
    fn new_collection_from<I>(&mut self, data: I) -> (InputSession<<Self as ScopeParent>::Timestamp, I::Item, isize>, Collection<Self, I::Item, isize>)
    where I: IntoIterator+'static, I::Item: Data;
    /// Create a new collection and input handle from initial data.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use timely::Configuration;
    /// use differential_dataflow::input::Input;
    ///
    /// fn main() {
    ///     ::timely::execute(Configuration::Thread, |worker| {
    ///
    ///         let (mut handle, probe) = worker.dataflow::<(),_,_>(|scope| {
    ///             // create input handle and collection.
    ///             let (handle, data) = scope.new_collection_from(0 .. 10);
    ///             let probe = data.map(|x| x * 2)
    ///                             .inspect(|x| println!("{:?}", x))
    ///                             .probe();
    ///             (handle, probe)
    ///         });
    ///
    ///         handle.insert(1);
    ///         handle.insert(5);
    ///
    ///     }).unwrap();
    /// }
    /// ```
    fn new_collection_from_raw<D, R, I>(&mut self, data: I) -> (InputSession<<Self as ScopeParent>::Timestamp, D, R>, Collection<Self, D, R>)
    where I: IntoIterator<Item=(D,<Self as ScopeParent>::Timestamp,R)>+'static, D: Data, R: Diff+Data;
}

use lattice::Lattice;
impl<G: TimelyInput> Input for G where <G as ScopeParent>::Timestamp: Lattice {
    fn new_collection<D, R>(&mut self) -> (InputSession<<G as ScopeParent>::Timestamp, D, R>, Collection<G, D, R>)
    where D: Data, R: Diff{
		let (handle, stream) = self.new_input();
		(InputSession::from(handle), stream.as_collection())
    }
    fn new_collection_from<I>(&mut self, data: I) -> (InputSession<<G as ScopeParent>::Timestamp, I::Item, isize>, Collection<G, I::Item, isize>)
    where I: IntoIterator+'static, I::Item: Data {
        self.new_collection_from_raw(data.into_iter().map(|d| (d, Default::default(), 1)))
    }
    fn new_collection_from_raw<D,R,I>(&mut self, data: I) -> (InputSession<<G as ScopeParent>::Timestamp, D, R>, Collection<G, D, R>)
    where
        D: Data,
        R: Diff+Data,
        I: IntoIterator<Item=(D,<Self as ScopeParent>::Timestamp,R)>+'static,
    {
        use timely::dataflow::operators::ToStream;

        let (handle, stream) = self.new_input();
        let source = data.to_stream(self).as_collection();

        (InputSession::from(handle), stream.as_collection().concat(&source))
    }}

/// An input session wrapping a single timely dataflow capability.
///
/// Each timely dataflow message has a corresponding capability, which is a logical time in the
/// timely dataflow system. Differential dataflow updates can happen at a much higher rate than
/// timely dataflow's progress tracking infrastructure supports, because the logical times are
/// promoted to data and updates are batched together. The `InputSession` type does this batching.
///
/// # Examples
///
/// ```
/// extern crate timely;
/// extern crate differential_dataflow;
///
/// use timely::Configuration;
/// use differential_dataflow::input::Input;
///
/// fn main() {
///     ::timely::execute(Configuration::Thread, |worker| {
///
///			let (mut handle, probe) = worker.dataflow(|scope| {
///				// create input handle and collection.
///				let (handle, data) = scope.new_collection_from(0 .. 10);
///         	let probe = data.map(|x| x * 2)
///				            	.inspect(|x| println!("{:?}", x))
///				            	.probe();
///				(handle, probe)
///     	});
///
///			handle.insert(3);
///			handle.advance_to(1);
///			handle.insert(5);
///			handle.advance_to(2);
///			handle.flush();
///
///			while probe.less_than(handle.time()) {
///				worker.step();
///			}
///
///			handle.remove(5);
///			handle.advance_to(3);
///			handle.flush();
///
///			while probe.less_than(handle.time()) {
///				worker.step();
///			}
///
///		}).unwrap();
/// }
/// ```
pub struct InputSession<T: Timestamp+Clone, D: Data, R: Diff> {
	time: T,
	buffer: Vec<(D, T, R)>,
	handle: Handle<T,(D,T,R)>,
}

impl<T: Timestamp+Clone, D: Data> InputSession<T, D, isize> {
	/// Adds an element to the collection.
	pub fn insert(&mut self, element: D) { self.update(element, 1); }
	/// Removes an element from the collection.
	pub fn remove(&mut self, element: D) { self.update(element,-1); }
}

// impl<T: Timestamp+Clone, D: Data> InputSession<T, D, i64> {
//     /// Adds an element to the collection.
//     pub fn insert(&mut self, element: D) { self.update(element, 1); }
//     /// Removes an element from the collection.
//     pub fn remove(&mut self, element: D) { self.update(element,-1); }
// }

// impl<T: Timestamp+Clone, D: Data> InputSession<T, D, i32> {
//     /// Adds an element to the collection.
//     pub fn insert(&mut self, element: D) { self.update(element, 1); }
//     /// Removes an element from the collection.
//     pub fn remove(&mut self, element: D) { self.update(element,-1); }
// }

impl<T: Timestamp+Clone, D: Data, R: Diff> InputSession<T, D, R> {

    /// Introduces a handle as collection.
    pub fn to_collection<G: TimelyInput>(&mut self, scope: &mut G) -> Collection<G, D, R>
    where
        G: ScopeParent<Timestamp=T>,
    {
        scope
            .input_from(&mut self.handle)
            .as_collection()
    }

    /// Allocates a new input handle.
    pub fn new() -> Self {
        let handle: Handle<T,_> = Handle::new();
        InputSession {
            time: handle.time().clone(),
            buffer: Vec::new(),
            handle,
        }
    }

	/// Creates a new session from a reference to an input handle.
	pub fn from(handle: Handle<T,(D,T,R)>) -> Self {
		InputSession {
			time: handle.time().clone(),
			buffer: Vec::new(),
			handle,
		}
	}

	/// Adds to the weight of an element in the collection.
	pub fn update(&mut self, element: D, change: R) {
        if self.buffer.len() == self.buffer.capacity() {
            if self.buffer.len() > 0 {
                self.handle.send_batch(&mut self.buffer);
            }
            // TODO : This is a fairly arbitrary choice; should probably use `Context::default_size()` or such.
            self.buffer.reserve(1024);
        }
		self.buffer.push((element, self.time.clone(), change));
	}

    /// Adds to the weight of an element in the collection at a future time.
    pub fn update_at(&mut self, element: D, time: T, change: R) {
        assert!(self.time.less_equal(&time));
        if self.buffer.len() == self.buffer.capacity() {
            if self.buffer.len() > 0 {
                self.handle.send_batch(&mut self.buffer);
            }
            // TODO : This is a fairly arbitrary choice; should probably use `Context::default_size()` or such.
            self.buffer.reserve(1024);
        }
        self.buffer.push((element, time, change));
    }

	/// Forces buffered data into the timely dataflow input, and advances its time to match that of the session.
	///
	/// It is important to call `flush` before expecting timely dataflow to report progress. Until this method is
	/// called, all updates may still be in internal buffers and not exposed to timely dataflow. Once the method is
	/// called, all buffers are flushed and timely dataflow is advised that some logical times are no longer possible.
	pub fn flush(&mut self) {
		self.handle.send_batch(&mut self.buffer);
		if self.handle.epoch().less_than(&self.time) {
			self.handle.advance_to(self.time.clone());
		}
	}

	/// Advances the logical time for future records.
	///
	/// Importantly, this method does **not** immediately inform timely dataflow of the change. This happens only when
	/// the session is dropped or flushed. It is not correct to use this time as a basis for a computation's `step_while`
	/// method unless the session has just been flushed.
	pub fn advance_to(&mut self, time: T) {
		assert!(self.handle.epoch().less_equal(&time));
		assert!(&self.time.less_equal(&time));
		self.time = time;
	}

	/// Reveals the current time of the session.
	pub fn epoch(&self) -> &T { &self.time }
	/// Reveals the current time of the session.
	pub fn time(&self) -> &T { &self.time }

	/// Closes the input, flushing and sealing the wrapped timely input.
	pub fn close(self) { }
}

impl<T: Timestamp+Clone, D: Data, R: Diff> Drop for InputSession<T, D, R> {
	fn drop(&mut self) {
		self.flush();
	}
}
<|endoftext|>


<commit_before>use token;
use peekable_string_iterator as peek;

/// The Lexer struct represents a lexer that tokenizes
/// the string input.
pub struct Lexer<'a> {
    iter: peek::PeekableStringIterator<'a>,
    sign: Option<char>,
    pub ast: Vec<token::Token>,
    pub errors: Vec<String>
}

impl<'a> Lexer<'a> {
    pub fn new(input: &str) -> Lexer {
        let mut l = Lexer {
            ast: Vec::new(),
            errors: vec![],
            iter: peek::PeekableStringIterator::new(input),
            sign: None
        };
        l.lex();
        l
    }

    fn lex(&mut self) {
        self.consume_input();
    }

    // Recursively consume the input
    fn consume_input(&mut self) {
        // Should we skip advancing if a sub method has done it for us?
        let mut skip_advance = false;

        // Peek the next character
        let peeked: Option<char> = match self.iter.peek() {
            Some(&c) => Some(c),
            None => None
        };

        // Decide what to do
        match peeked {
            Some(c) if c.is_whitespace() => {
                // Reset the sign
                self.sign = None;

                self.ast.push(token::Token::Whitespace);
            },
            Some(c) if c.is_numeric() => {
                // Grab the number (allowing for possible decimals)
                let number = self.consume_number();
                // Add a numeric token to the list of tokens
                match number.parse() {
                    Ok(val) => {
                        self.ast.push(token::Token::DecimalNumber(val));
                    },
                    Err(e) => self.errors.push(format!("FATAL: {}", e))
                }
                skip_advance = true;
            },
            Some(c) if c == '+' || c == '-' => {
                // Add the operator and advance the iterator
                self.ast.push(token::Token::Operator(c, token::LEFT_ASSOCIATIVE, 2));
            },
            Some(c) if c == '*' || c == '/' => {
                // Add the operator and advance the iterator
                self.ast.push(token::Token::Operator(c, token::LEFT_ASSOCIATIVE, 3));
            },
            Some(c) if c == '(' => self.ast.push(token::Token::LeftParenthesis),
            Some(c) if c == ')' => self.ast.push(token::Token::RightParenthesis),
            Some(c) if c == '^' => self.ast.push(token::Token::Operator(c, token::RIGHT_ASSOCIATIVE, 4)),
            Some(c) => self.errors.push(format!("Unknown identifier: {}", c)),
            None => return
        }
        // Advance the iterator and continue consuming the input
        if !skip_advance {
            self.iter.advance();
        }
        self.consume_input();
    }

    // Consumes the iterator until it reaches the end of a number
    fn consume_number(&mut self) -> String {
        // If the last operator was a sign ... prefix the number with it
        let last_op = self.ast.pop();
        match last_op {
            Some(token::Token::Operator(o, _, _)) => {
                if o == '+' || o == '-' {
                    // Pop the operator and set our sign
                    self.sign = Some(o);
                }
            },
            None => (),
            Some(_) => self.ast.push(last_op.unwrap())
        }

        let mut chars = vec![self.sign.unwrap_or('+')];

        self.sign = None;

        // Loop over every character until we reach a non-numeric one
        loop {
            match self.iter.peek() {
                Some(c) if c.is_numeric() || *c == '.' => chars.push(*c),
                Some(c) if !c.is_numeric() => break,
                //Some(c) => println!("Peeking at: {}", c),
                None => break,
                _ => break
            }
            self.iter.advance();
        }

        // Return out number as a String
        chars.into_iter().collect()
    }
}

<commit_msg>Move decipher sign to its own method<commit_after>use token;
use peekable_string_iterator as peek;

/// The Lexer struct represents a lexer that tokenizes
/// the string input.
pub struct Lexer<'a> {
    iter: peek::PeekableStringIterator<'a>,
    sign: Option<char>,
    pub ast: Vec<token::Token>,
    pub errors: Vec<String>
}

impl<'a> Lexer<'a> {
    pub fn new(input: &str) -> Lexer {
        let mut l = Lexer {
            ast: Vec::new(),
            errors: vec![],
            iter: peek::PeekableStringIterator::new(input),
            sign: None
        };
        l.lex();
        l
    }

    fn lex(&mut self) {
        self.consume_input();
    }

    // Recursively consume the input
    fn consume_input(&mut self) {
        // Should we skip advancing if a sub method has done it for us?
        let mut skip_advance = false;

        // Peek the next character
        let peeked: Option<char> = match self.iter.peek() {
            Some(&c) => Some(c),
            None => None
        };

        // Decide what to do
        match peeked {
            Some(c) if c.is_whitespace() => {
                // Reset the sign
                self.sign = None;

                self.ast.push(token::Token::Whitespace);
            },
            Some(c) if c.is_numeric() => {
                // Grab the number (allowing for possible decimals)
                let number = self.consume_number();
                // Add a numeric token to the list of tokens
                match number.parse() {
                    Ok(val) => {
                        self.ast.push(token::Token::DecimalNumber(val));
                    },
                    Err(e) => self.errors.push(format!("FATAL: {}", e))
                }
                skip_advance = true;
            },
            Some(c) if c == '+' || c == '-' => {
                // Add the operator and advance the iterator
                self.ast.push(token::Token::Operator(c, token::LEFT_ASSOCIATIVE, 2));
            },
            Some(c) if c == '*' || c == '/' => {
                // Add the operator and advance the iterator
                self.ast.push(token::Token::Operator(c, token::LEFT_ASSOCIATIVE, 3));
            },
            Some(c) if c == '(' => self.ast.push(token::Token::LeftParenthesis),
            Some(c) if c == ')' => self.ast.push(token::Token::RightParenthesis),
            Some(c) if c == '^' => self.ast.push(token::Token::Operator(c, token::RIGHT_ASSOCIATIVE, 4)),
            Some(c) => self.errors.push(format!("Unknown identifier: {}", c)),
            None => return
        }
        // Advance the iterator and continue consuming the input
        if !skip_advance {
            self.iter.advance();
        }
        self.consume_input();
    }

    // Consumes the iterator until it reaches the end of a number
    fn consume_number(&mut self) -> String {
        // Decipher the sign of the number we want to consume
        self.decipher_sign();

        // Initialize our number with the given sign
        let mut chars = vec![self.sign.unwrap_or('+')];

        // Reset the sign
        self.sign = None;

        // Loop over every character until we reach a non-numeric one
        loop {
            match self.iter.peek() {
                Some(c) if c.is_numeric() || *c == '.' => chars.push(*c),
                Some(c) if !c.is_numeric() => break,
                //Some(c) => println!("Peeking at: {}", c),
                None => break,
                _ => break
            }
            self.iter.advance();
        }

        // Return out number as a String
        chars.into_iter().collect()
    }

    fn decipher_sign(&mut self) {
        // If the last operator was a sign ... set the sign
        let last_op = self.ast.last().cloned();
        match last_op {
            Some(token::Token::Operator(o, _, _)) => {
                if o == '+' || o == '-' {
                    // Pop the operator (because its not an operator .. its indicating the numbers'
                    // sign) and store our sign
                    self.ast.pop();
                    self.sign = Some(o);
                }
            },
            _ => ()
        }
    }
}

<|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    LParen,
    RParen,
    Symbol(String),
    Number(i64),
    EOF,
}

pub struct LexerState {
    pub s: String,
    pub pos: usize,
    pub col: usize,
    pub line_num: usize,
    pub tok_buf: Option<Token>,
}

fn is_valid_in_symbol(c: char) -> bool {
    c.is_alphabetic() ||
    match c {
        '+' | '-' | '*' | '/' | '#' | '<' | '>' | '=' => true,
        _ => false,
    }
}

pub fn get_token(ls: &mut LexerState) -> Token {
    if let Some(tok) = ls.tok_buf.clone() {
        ls.tok_buf = None;
        return tok;
    }
    else {
        let mut iter = ls.s[ls.pos..].chars().peekable();
        while let Some(&c) = iter.peek() {
            if c.is_numeric() {
                let mut acc = String::new();
                let mut n = c;
                while n.is_numeric() {
                    acc.push(n);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    n = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Number(acc.parse().unwrap());
            }
            else if is_valid_in_symbol(c) {
                let mut acc = String::new();
                let mut s = c;
                while s.is_alphanumeric() || is_valid_in_symbol(s) {
                    acc.push(s);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    s = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Symbol(acc);
            }
            else {
                match c {
                    '\n' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col = 0;
                        ls.line_num += 1;
                        continue;
                    },
                    ';' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        while let Some(c) = iter.next() {
                            ls.pos += 1;
                            if c.clone() == '\n' {
                                break;
                            }
                        }
                        ls.line_num += 1;
                        ls.col = 0;
                    },
                    ' ' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        continue
                    },
                    '(' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::LParen
                    },
                    ')' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::RParen
                    },

                    _ => panic!("line {}:{} unexpected char: {}", ls.line_num, ls.col, c),
                }
            }
        }
        return Token::EOF;
    }
}
<commit_msg>Use str's in Lexer and add an Iterator impl<commit_after>#[derive(Debug, PartialEq, Clone)]
pub enum Token<'input> {
    LParen,
    RParen,
    Symbol(&'input str),
    Number(i64),
    EOF,
}

pub struct Lexer<'input> {
    pub s: &'input str,
    pub pos: usize,
    pub col: usize,
    pub line_num: usize,
    pub tok_buf: Option<Token<'input>>,
}

fn is_valid_in_symbol(c: char) -> bool {
    c.is_alphabetic() ||
    match c {
        '+' | '-' | '*' | '/' | '#' | '<' | '>' | '=' => true,
        _ => false,
    }
}

impl<'input> Lexer<'input> {
    pub fn new(source: &'input str) -> Lexer<'input> {
        Lexer { s: source,
                pos: 0,
                col: 0,
                line_num: 1,
                tok_buf: None}
    }

    pub fn get_token(&mut self) -> Token<'input> {
        if let Some(tok) = self.tok_buf.clone() {
            self.tok_buf = None;
            return tok;
        }
        else {
            let mut iter = self.s[self.pos..].chars().peekable();
            while let Some(&c) = iter.peek() {
                if c.is_numeric() {
                    let mut n = c;
                    let start = self.pos;
                    while n.is_numeric() {
                        iter.next();
                        self.pos += 1;
                        self.col += 1;
                        n = match iter.peek() {
                            Some(&x) => x,
                            None => break,
                        };
                    }
                    return Token::Number(self.s[start..self.pos].parse().unwrap());
                }
                else if is_valid_in_symbol(c) {
                    let mut s = c;
                    let start = self.pos;
                    while s.is_alphanumeric() || is_valid_in_symbol(s) {
                        iter.next();
                        self.pos += 1;
                        self.col += 1;
                        s = match iter.peek() {
                            Some(&x) => x,
                            None => break,
                        };
                    }
                    return Token::Symbol(&self.s[start..self.pos]);
                }
                else {
                    match c {
                        '\n' => {
                            iter.next();
                            self.pos += 1;
                            self.col = 0;
                            self.line_num += 1;
                            continue;
                        },
                        ';' => {
                            iter.next();
                            self.pos += 1;
                            self.col += 1;
                            while let Some(c) = iter.next() {
                                self.pos += 1;
                                if c.clone() == '\n' {
                                    break;
                                }
                            }
                            self.line_num += 1;
                            self.col = 0;
                        },
                        ' ' => {
                            iter.next();
                            self.pos += 1;
                            self.col += 1;
                            continue
                        },
                        '(' => {
                            iter.next();
                            self.pos += 1;
                            self.col += 1;
                            return Token::LParen
                        },
                        ')' => {
                            iter.next();
                            self.pos += 1;
                            self.col += 1;
                            return Token::RParen
                        },

                        _ => panic!("line {}:{} unexpected char: {}", self.line_num, self.col, c),
                    }
                }
            }
            return Token::EOF;
        }
    }
}

impl<'input> Iterator for Lexer<'input> {
    type Item = Token<'input>;

    fn next(&mut self) -> Option<Token<'input>> {
        match self.get_token() {
            Token::EOF => None,
            t => Some(t),
        }
    }
}
<|endoftext|>


<commit_before>use std::io::stdin;
use std::io::prelude::*;
use std::iter::once;
use regex::Regex;

pub struct MessageIter {
    buf: String,
    terminated: bool,
    pub errors: u16,
    pub warnings: u16,
}

pub enum Message {
    Header(String, String),
    Warning(String),
    Note(String),
    Error(String),
    Help(String),
    FollowUp(String),
    Source(String, String),
    Marker(String),
    NewLine,
    Wat,
    Aborting,
}

impl<'a> Iterator for &'a mut MessageIter {
    type Item = Vec<Message>;

    fn next(&mut self) -> Option<Vec<Message>> {
        use self::Message::*;

        if self.terminated {
            return None;
        }

        let mut res = Vec::new();
        let mut file = String::new();
        let mut stop = false;
        let si = stdin();
        let stdin = si.lock().lines().map(|x| x.expect("Stdin failed"));

        for l in once(self.buf.clone()).chain(stdin) {
            let re_header = Regex::new(r"([0-9A-Za-z_\.\\/>< ]+):(\d+):\d+: .*(warning: |note: |error: |help: )(.*)").unwrap();
            let re_source = Regex::new(r"(\d+) (.*)").unwrap();
            if re_header.is_match(&l) {

                res.push(NewLine);

                let caps = re_header.captures(&l).unwrap();
                file = caps.at(1).unwrap_or("?").to_string();

                res.push(Header(file.clone(), caps.at(2).unwrap_or("?").to_string()));

                let msg = caps.at(4).unwrap_or("?").to_string();

                // Warning, header or note?
                match caps.at(3).unwrap_or("?") {
                    "warning: " => {
                        self.warnings += 1;
                        res.push(Warning(msg));
                    },
                    "note: " =>    res.push(Note(msg)),
                    "error: " => {
                        self.errors += 1;
                        res.push(Error(msg));
                    },
                    "help: " =>    res.push(Help(msg)),
                    _ =>           res.push(Wat),
                }

                if !stop {
                    stop = true;
                } else {
                    self.buf = l.to_string();
                    return Some(res);
                }
            } else if l.len() > file.len() && re_source.is_match(&l[file.len()..]) && is_not_cmd(&l) {
                let caps = re_source.captures(&l).unwrap();

                res.push(Source(caps.at(1).unwrap_or("?").to_string(), caps.at(2).unwrap_or("????").to_string()));
            } else if l.starts_with(' ') && l.contains("^") {

                let offset = file.len() - 4; //+ 5 - 5;

                if offset < l.len() {
                    res.push(Marker(l[offset..].to_string()));
                }
            } else if l.contains("Aborting due to previous") || l.contains("Build failed") || l.contains("Could not compile") {
                res.push(Aborting);
                stop = true;
                self.terminated = true;
            } else if l.contains("Compilining ") || l.contains("file:///home/") || l.is_empty() {
                // todo
            } else if is_not_cmd(&l){
                res.push(FollowUp(l.to_string()));
            }
        }

        self.terminated = true;
        if stop {
            Some(res)
        } else {
            None
        }
    }
}

fn is_not_cmd(l: &str) -> bool {
    l.len() < 30 || !(l.starts_with("rustc ") || l.starts_with("cargo ") || l.starts_with("make ") || l.contains(" --") || l.contains(" --target=") || l.contains(" -C ") || l.contains(" -L ") || l.contains(" -A ") || l.contains(" -Z ") || l.contains(" -o ") || l.starts_with("sed ") || l.starts_with("mkdir ") || l.starts_with("cd "))
}

impl MessageIter {
    pub fn new() -> Self {
        MessageIter {
            buf: String::new(),
            terminated: false,
            errors: 0,
            warnings: 0,
        }
    }
}

<commit_msg>Fix duplicates<commit_after>use std::io::stdin;
use std::io::prelude::*;
use std::iter::once;
use regex::Regex;

pub struct MessageIter {
    buf: String,
    terminated: bool,
    pub errors: u16,
    pub warnings: u16,
}

pub enum Message {
    Header(String, String),
    Warning(String),
    Note(String),
    Error(String),
    Help(String),
    FollowUp(String),
    Source(String, String),
    Marker(String),
    NewLine,
    Wat,
    Aborting,
}

impl<'a> Iterator for &'a mut MessageIter {
    type Item = Vec<Message>;

    fn next(&mut self) -> Option<Vec<Message>> {
        use self::Message::*;

        if self.terminated {
            return None;
        }

        let mut res = Vec::new();
        let mut file = String::new();
        let mut stop = false;
        let si = stdin();
        let stdin = si.lock().lines().map(|x| x.expect("Stdin failed"));

        for l in once(self.buf.clone()).chain(stdin) {
            let re_header = Regex::new(r"([0-9A-Za-z_\.\\/>< ]+):(\d+):\d+: .*(warning: |note: |error: |help: )(.*)").unwrap();
            let re_source = Regex::new(r"(\d+) (.*)").unwrap();
            if re_header.is_match(&l) {

                if !stop {
                    stop = true;
                } else {
                    self.buf = l.to_string();
                    return Some(res);
                }

                res.push(NewLine);

                let caps = re_header.captures(&l).unwrap();
                file = caps.at(1).unwrap_or("?").to_string();

                res.push(Header(file.clone(), caps.at(2).unwrap_or("?").to_string()));

                let msg = caps.at(4).unwrap_or("?").to_string();

                // Warning, header or note?
                match caps.at(3).unwrap_or("?") {
                    "warning: " => {
                        self.warnings += 1;
                        res.push(Warning(msg));
                    },
                    "note: " =>    res.push(Note(msg)),
                    "error: " => {
                        self.errors += 1;
                        res.push(Error(msg));
                    },
                    "help: " =>    res.push(Help(msg)),
                    _ =>           res.push(Wat),
                }

            } else if l.len() > file.len() && re_source.is_match(&l[file.len()..]) && is_not_cmd(&l) {
                let caps = re_source.captures(&l).unwrap();

                res.push(Source(caps.at(1).unwrap_or("?").to_string(), caps.at(2).unwrap_or("????").to_string()));
            } else if l.starts_with(' ') && l.contains("^") {

                let offset = file.len() - 4; //+ 5 - 5;

                if offset < l.len() {
                    res.push(Marker(l[offset..].to_string()));
                }
            } else if l.contains("aborting due to previous") || l.contains("Build failed") || l.contains("Could not compile") {
                res.push(Aborting);
                stop = true;
                self.terminated = true;
            } else if l.contains("Compilining ") || l.contains("file:///home/") || l.is_empty() {
                // todo
            } else if is_not_cmd(&l){
                res.push(FollowUp(l.to_string()));
            }
        }

        self.terminated = true;
        if stop {
            Some(res)
        } else {
            None
        }
    }
}

fn is_not_cmd(l: &str) -> bool {
    l.len() < 30 || !(l.starts_with("rustc ") || l.starts_with("cargo ") || l.starts_with("make ") || l.contains(" --") || l.contains(" --target=") || l.contains(" -C ") || l.contains(" -L ") || l.contains(" -A ") || l.contains(" -Z ") || l.contains(" -o ") || l.starts_with("sed ") || l.starts_with("mkdir ") || l.starts_with("cd "))
}

impl MessageIter {
    pub fn new() -> Self {
        MessageIter {
            buf: String::new(),
            terminated: false,
            errors: 0,
            warnings: 0,
        }
    }
}

<|endoftext|>


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

use token::Token;

use std::cell::Cell;
use std::rc::Rc;
use regex::Regex;
use context::Context;
use token::Posn;

pub trait ESCharExt {
    fn is_es_newline(self) -> bool;
    fn is_es_whitespace(self) -> bool;
}

impl ESCharExt for char {
    fn is_es_newline(self) -> bool {
        match self {
            '\u{000a}' | '\u{000d}' | '\u{2028}' | '\u{2029}' => true,
            _ => false
        }
    }

    fn is_es_whitespace(self) -> bool {
        match self {
              '\u{0009}' | '\u{000b}' | '\u{000c}' | '\u{0020}' | '\u{00a0}'
            | '\u{1680}' | '\u{2000}' | '\u{2001}' | '\u{2002}' | '\u{2003}' | '\u{2004}'
            | '\u{2005}' | '\u{2006}' | '\u{2009}' | '\u{200a}' | '\u{202f}' | '\u{205f}'
            | '\u{3000}' | '\u{feff}' => true,
            _ => false
        }
    }
}

struct LineOrientedReader<I> {
    chars: I,
    curr_char: Option<char>,
    next_char: Option<char>,
    curr_posn: Posn
}

impl<I> LineOrientedReader<I> where I: Iterator<Item=char> {
    pub fn new(mut chars: I) -> LineOrientedReader<I> {
        let curr_char = chars.next();
        let next_char = if curr_char.is_some() { chars.next() } else { None };
        LineOrientedReader {
            chars: chars,
            curr_char: curr_char,
            next_char: next_char,
            curr_posn: Posn {
                offset: 0,
                line: 0,
                column: 0
            }
        }
    }

    pub fn curr_char(&mut self) -> Option<char> { self.curr_char }
    pub fn curr_posn(&mut self) -> Posn { self.curr_posn }

    pub fn bump(&mut self) {
        let curr_char = self.next_char;
        let next_char = if curr_char.is_some() { self.chars.next() } else { None };

        self.curr_char = curr_char;
        self.next_char = next_char;

        if (curr_char == Some('\r') && next_char != Some('\n')) ||
           curr_char == Some('\n') ||
           curr_char == Some('\u{2028}') ||
           curr_char == Some('\u{2029}') {
            self.curr_posn.line += 1;
            self.curr_posn.column = 0;
        } else {
            self.curr_posn.column += 1;
        }

        self.curr_posn.offset += 1;
    }
}

struct TokenBuffer {
    tokens: LinkedList<Token>
}

impl TokenBuffer {
    fn new() -> TokenBuffer {
        TokenBuffer {
            tokens: LinkedList::new()
        }
    }

    fn ensure_nonempty<F: FnMut() -> Token>(&mut self, mut get: F) {
        if self.tokens.len() == 0 {
            self.tokens.push_back(get());
        }
    }

    fn read_token(&mut self) -> Token {
        assert!(self.tokens.len() > 0);
        self.tokens.pop_front().unwrap()
    }
}

pub struct Lexer<I> {
    reader: LineOrientedReader<I>,
    cx: Rc<Cell<Context>>,
    lookahead: TokenBuffer
}

impl<I> Lexer<I> where I: Iterator<Item=char> {
    // constructor

    pub fn new(chars: I, cx: Rc<Cell<Context>>) -> Lexer<I> {
        Lexer {
            reader: LineOrientedReader::new(chars),
            cx: cx,
            lookahead: TokenBuffer::new()
        }
    }

    // public methods

    pub fn read_token(&mut self) -> Token {
        self.lookahead.ensure_nonempty(|| {
            self.read_next_token()
        });
        unimplemented!()
    }

    // private methods

    fn read_next_token(&mut self) -> Token {
        unimplemented!()
    }

    fn is_whitespace(&mut self) -> bool {
        match self.reader.curr_char() {
            Some(ch) => ch.is_es_whitespace(),
            None => false
        }
    }

    fn eat(&mut self) -> Option<char> {
        let ch = self.reader.curr_char();
        self.reader.bump();
        ch
    }

    fn skip_whitespace(&mut self) {
        while self.is_whitespace() {
            self.reader.bump();
        }
    }
}

impl<I> Iterator for Lexer<I> where I: Iterator<Item=char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.skip_whitespace();
        self.eat()
            .map(|ch| {
                match ch {
                    '1' => Token::DecimalInt(String::from_str("1")),
                    '+' => Token::Plus,
                    _ => Token::Error(ch)
                }
            })
    }
}
<commit_msg>fine, giving up on the HOF. oops, nested borrow leaks out: src/lexer.rs:129:39: 129:43 error: cannot borrow `*self` as mutable more than once at a time src/lexer.rs:129             self.lookahead.push_token(self.read_next_token());                                                        ^~~~ src/lexer.rs:129:13: 129:27 note: previous borrow of `self.lookahead` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `self.lookahead` until the borrow ends src/lexer.rs:129             self.lookahead.push_token(self.read_next_token());                              ^~~~~~~~~~~~~~ src/lexer.rs:129:62: 129:62 note: previous borrow ends here src/lexer.rs:129             self.lookahead.push_token(self.read_next_token());<commit_after>use std::collections::LinkedList;

use token::Token;

use std::cell::Cell;
use std::rc::Rc;
use regex::Regex;
use context::Context;
use token::Posn;

pub trait ESCharExt {
    fn is_es_newline(self) -> bool;
    fn is_es_whitespace(self) -> bool;
}

impl ESCharExt for char {
    fn is_es_newline(self) -> bool {
        match self {
            '\u{000a}' | '\u{000d}' | '\u{2028}' | '\u{2029}' => true,
            _ => false
        }
    }

    fn is_es_whitespace(self) -> bool {
        match self {
              '\u{0009}' | '\u{000b}' | '\u{000c}' | '\u{0020}' | '\u{00a0}'
            | '\u{1680}' | '\u{2000}' | '\u{2001}' | '\u{2002}' | '\u{2003}' | '\u{2004}'
            | '\u{2005}' | '\u{2006}' | '\u{2009}' | '\u{200a}' | '\u{202f}' | '\u{205f}'
            | '\u{3000}' | '\u{feff}' => true,
            _ => false
        }
    }
}

struct LineOrientedReader<I> {
    chars: I,
    curr_char: Option<char>,
    next_char: Option<char>,
    curr_posn: Posn
}

impl<I> LineOrientedReader<I> where I: Iterator<Item=char> {
    pub fn new(mut chars: I) -> LineOrientedReader<I> {
        let curr_char = chars.next();
        let next_char = if curr_char.is_some() { chars.next() } else { None };
        LineOrientedReader {
            chars: chars,
            curr_char: curr_char,
            next_char: next_char,
            curr_posn: Posn {
                offset: 0,
                line: 0,
                column: 0
            }
        }
    }

    pub fn curr_char(&mut self) -> Option<char> { self.curr_char }
    pub fn curr_posn(&mut self) -> Posn { self.curr_posn }

    pub fn bump(&mut self) {
        let curr_char = self.next_char;
        let next_char = if curr_char.is_some() { self.chars.next() } else { None };

        self.curr_char = curr_char;
        self.next_char = next_char;

        if (curr_char == Some('\r') && next_char != Some('\n')) ||
           curr_char == Some('\n') ||
           curr_char == Some('\u{2028}') ||
           curr_char == Some('\u{2029}') {
            self.curr_posn.line += 1;
            self.curr_posn.column = 0;
        } else {
            self.curr_posn.column += 1;
        }

        self.curr_posn.offset += 1;
    }
}

struct TokenBuffer {
    tokens: LinkedList<Token>
}

impl TokenBuffer {
    fn new() -> TokenBuffer {
        TokenBuffer {
            tokens: LinkedList::new()
        }
    }

    fn is_empty(&mut self) -> bool {
        self.tokens.len() == 0
    }

    fn push_token(&mut self, token: Token) {
        assert!(self.tokens.len() == 0);
        self.tokens.push_back(token);
    }

    fn read_token(&mut self) -> Token {
        assert!(self.tokens.len() > 0);
        self.tokens.pop_front().unwrap()
    }
}

pub struct Lexer<I> {
    reader: LineOrientedReader<I>,
    cx: Rc<Cell<Context>>,
    lookahead: TokenBuffer
}

impl<I> Lexer<I> where I: Iterator<Item=char> {
    // constructor

    pub fn new(chars: I, cx: Rc<Cell<Context>>) -> Lexer<I> {
        Lexer {
            reader: LineOrientedReader::new(chars),
            cx: cx,
            lookahead: TokenBuffer::new()
        }
    }

    // public methods

    pub fn read_token(&mut self) -> Token {
        if self.lookahead.is_empty() {
            self.lookahead.push_token(self.read_next_token());
        }
        unimplemented!()
    }

    // private methods

    fn read_next_token(&mut self) -> Token {
        unimplemented!()
    }

    fn is_whitespace(&mut self) -> bool {
        match self.reader.curr_char() {
            Some(ch) => ch.is_es_whitespace(),
            None => false
        }
    }

    fn eat(&mut self) -> Option<char> {
        let ch = self.reader.curr_char();
        self.reader.bump();
        ch
    }

    fn skip_whitespace(&mut self) {
        while self.is_whitespace() {
            self.reader.bump();
        }
    }
}

impl<I> Iterator for Lexer<I> where I: Iterator<Item=char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.skip_whitespace();
        self.eat()
            .map(|ch| {
                match ch {
                    '1' => Token::DecimalInt(String::from_str("1")),
                    '+' => Token::Plus,
                    _ => Token::Error(ch)
                }
            })
    }
}
<|endoftext|>


<commit_before>#![allow(unstable)]
#![allow(dead_code)]
use std::intrinsics::get_tydesc;

struct Zero;
struct Succ<T: NonNeg>;
struct Pred<T: NonPos>;

trait Peano {}
trait NonZero: Peano {}
trait NonNeg: Peano {}
trait NonPos: Peano {}
trait Pos: Peano + NonZero + NonNeg {}
trait Neg: Peano + NonZero + NonPos {}

impl Peano for Zero {}
impl NonNeg for Zero {}
impl NonPos for Zero {}

impl<T: NonNeg> Peano for Succ<T> {}
impl<T: NonNeg> NonNeg for Succ<T> {}
impl<T: NonNeg> NonZero for Succ<T> {}
impl<T: NonNeg> Pos for Succ<T> {}

impl<T: NonPos> Peano for Pred<T> {}
impl<T: NonPos> NonPos for Pred<T> {}
impl<T: NonPos> NonZero for Pred<T> {}
impl<T: NonPos> Neg for Pred<T> {}

// trait AddPeano<Rhs> {
//     type Result;
// }

// impl<Rhs: Peano> AddPeano<Rhs> for Zero {
//     type Result = Rhs;
// }

// /// Adding two non-negative integers (e.g. 1 + 1)
// impl<Rhs: NonNeg, T: AddPeano<Rhs> + NonNeg> AddPeano<Rhs> for Succ<T> {
//     type Result = Succ<<T as AddPeano<Rhs>>::Result>;
// }

// /// Adding two non-positive integers (e.g. -1 + -1)
// impl<Rhs: NonPos, T: AddPeano<Rhs> + NonPos> AddPeano<Rhs> for Pred<T> {
//     type Result = Pred<<T as AddPeano<Rhs>>::Result>;
// }

trait AddOne {
    type Result;
}
impl AddOne for Zero {
    type Result = Succ<Zero>;
}
impl<T: NonNeg> AddOne for Succ<T> {
    type Result = Succ<Succ<T>>;
}
impl<T: NonPos> AddOne for Pred<T> {
    type Result = T;
}

trait SubOne {
    type Result;
}
impl SubOne for Zero {
    type Result = Pred<Zero>;
}
impl<T: NonNeg> SubOne for Succ<T> {
    type Result = T;
}
impl<T: NonPos> SubOne for Pred<T> {
    type Result = Pred<Pred<T>>;
}

trait AddPeano<Rhs> {
    type Result;
}

impl<Rhs: Peano> AddPeano<Rhs> for Zero {
    type Result = Rhs;
}

impl<Rhs, T> AddPeano<Rhs> for Succ<T>
    where T: AddPeano<<Rhs as AddOne>::Result> + NonNeg, Rhs: AddOne {
        // Result: T + Rhs as AddOne
        type Result = <T as AddPeano<<Rhs as AddOne>::Result>>::Result;
}

fn print_type<T>() {
    let type_name = unsafe { (*get_tydesc::<T>()).name };
    println!("{}", type_name);
}

#[test]
fn count() {
    type One = Succ<Zero>;
    print!("      1 = ");
    print_type::<One>();
    type NegOne = Pred<Zero>;
    print!("     -1 = ");
    print_type::<NegOne>();

    print!("  0 + 1 = ");
    print_type::<<Zero as AddOne>::Result>();
    print!("  1 + 1 = ");
    type Two = <One as AddOne>::Result;
    print_type::<Two>();
    print!(" -1 + 1 = ");
    print_type::<<NegOne as AddOne>::Result>();

    print!("  0 - 1 = ");
    print_type::<<Zero as SubOne>::Result>();
    print!("  1 - 1 = ");
    print_type::<<One as SubOne>::Result>();
    print!(" -1 - 1 = ");
    type NegTwo = <NegOne as SubOne>::Result;
    print_type::<NegTwo>();

    print!("1 + 2 = ");
    print_type::<<One as AddPeano<Two>>::Sum>();
}
<commit_msg>The set of integers under addition and subtraction are now implemented and working.<commit_after>#![allow(dead_code)]
use std::intrinsics::get_tydesc;

struct Zero;
struct Succ<T: NonNeg>;
struct Pred<T: NonPos>;

trait Peano {}
trait NonZero: Peano {}
trait NonNeg: Peano {}
trait NonPos: Peano {}
trait Pos: Peano + NonZero + NonNeg {}
trait Neg: Peano + NonZero + NonPos {}

impl Peano for Zero {}
impl NonNeg for Zero {}
impl NonPos for Zero {}

impl<T: NonNeg> Peano for Succ<T> {}
impl<T: NonNeg> NonNeg for Succ<T> {}
impl<T: NonNeg> NonZero for Succ<T> {}
impl<T: NonNeg> Pos for Succ<T> {}

impl<T: NonPos> Peano for Pred<T> {}
impl<T: NonPos> NonPos for Pred<T> {}
impl<T: NonPos> NonZero for Pred<T> {}
impl<T: NonPos> Neg for Pred<T> {}

trait AddPeano<Rhs> {
    type Result;
}

/// Adding things to zero (e.g. 0 + 3)
impl<Rhs: Peano> AddPeano<Rhs> for Zero {
    type Result = Rhs;
}

/// Adding positive numbers (e.g. 1 + 2)
impl<T: NonNeg + AddPeano<Succ<Rhs>>, Rhs: NonNeg> AddPeano<Succ<Rhs>> for Succ<T> {
    type Result = Succ<<T as AddPeano<Succ<Rhs>>>::Result>;
}
/// Adding zero to positive numbers (e.g. 3 + 0)
impl<T: NonNeg> AddPeano<Zero> for Succ<T> {
    type Result = Succ<T>;
}
/// Adding negative numbers to positive numbers (e.g. 2 + -3)
impl<T: NonNeg + AddPeano<Rhs>, Rhs: NonPos> AddPeano<Pred<Rhs>> for Succ<T> {
    type Result = <T as AddPeano<Rhs>>::Result;
}

/// Adding negative numbers (e.g. -1 + -2)
impl<T: NonPos + AddPeano<Pred<Rhs>>, Rhs: NonPos> AddPeano<Pred<Rhs>> for Pred<T> {
    type Result = Pred<<T as AddPeano<Pred<Rhs>>>::Result>;
}
/// Adding zero to negative numbers (e.g. -3 + 0)
impl<T: NonPos> AddPeano<Zero> for Pred<T> {
    type Result = Pred<T>;
}
/// Adding positive numbers to negative numbers (e.g. -2 + 3)
impl<T: NonPos + AddPeano<Rhs>, Rhs: NonNeg> AddPeano<Succ<Rhs>> for Pred<T> {
    type Result = <T as AddPeano<Rhs>>::Result;
}

fn print_type<T>() {
    let type_name = unsafe { (*get_tydesc::<T>()).name };
    println!("{}", type_name);
}

#[test]
fn count() {
    type One = Succ<Zero>;
    type Two = Succ<One>;
    type Three = Succ<Two>;

    type NegOne = Pred<Zero>;
    type NegTwo = Pred<NegOne>;
    type NegThree = Pred<NegTwo>;

    print!("      1 = ");
    print_type::<One>();

    print!("     -1 = ");
    print_type::<NegOne>();

    print!(" 0 +  2 = ");
    print_type::<<Zero as AddPeano<Two>>::Result>();
    print!(" 2 +  0 = ");
    print_type::<<Two as AddPeano<Zero>>::Result>();

    print!(" 1 +  2 = ");
    print_type::<<One as AddPeano<Two>>::Result>();
    print!(" 2 +  1 = ");
    print_type::<<Two as AddPeano<One>>::Result>();

    print!(" 1 + -1 = ");
    print_type::<<One as AddPeano<NegOne>>::Result>();
    print!(" 1 + -2 = ");
    print_type::<<One as AddPeano<NegTwo>>::Result>();
    print!(" 2 + -1 = ");
    print_type::<<Two as AddPeano<NegOne>>::Result>();

    print!("-2 +  0 = ");
    print_type::<<NegTwo as AddPeano<Zero>>::Result>();

    print!("-1 + -2 = ");
    print_type::<<NegOne as AddPeano<NegTwo>>::Result>();
    print!("-2 + -1 = ");
    print_type::<<NegTwo as AddPeano<NegOne>>::Result>();

    print!("-1 +  1 = ");
    print_type::<<NegOne as AddPeano<One>>::Result>();
    print!("-1 +  2 = ");
    print_type::<<NegOne as AddPeano<Two>>::Result>();
    print!("-2 +  1 = ");
    print_type::<<NegTwo as AddPeano<One>>::Result>();
}
<|endoftext|>


<commit_before>
use ggez;
use ggez::GameResult;
use ggez::conf;
use ggez::event;
use ggez::event::EventHandler;

use std::collections::BTreeMap;
use std::time::Duration;

pub trait SavedScene {
    fn load(&self) -> Box<Scene>;
    fn name(&self) -> &str;
}

pub trait Scene: EventHandler {
    fn unload(&mut self) -> Box<SavedScene>;
}

/// A SceneManager is a GameState that handles Scene's
/// and switches from one to another when requested.
///
/// The stuff you would normally store in your GameState
/// type should go into the T type.
pub struct SceneManager<T> {
    states: BTreeMap<String, Box<SavedScene>>,
    pub game_data: T,
    current: Box<Scene>,
    next_scene: Option<String>,
}

impl<T> EventHandler for SceneManager<T>
{
    fn update(&mut self, ctx: &mut ggez::Context, dt: Duration) -> GameResult<()> {
        // TODO: Get rid of this hacky clone!
        if let Some(ref scene_name) = self.next_scene.clone() {
            self.switch_scene(&scene_name)?;
        }
        self.current.update(ctx, dt)?;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut ggez::Context) -> GameResult<()> {
        self.current.draw(ctx)
    }

    fn mouse_button_down_event(&mut self, button: event::MouseButton, x: i32, y: i32) {
        self.current.mouse_button_down_event(button, x, y)
    }

    fn mouse_button_up_event(&mut self, button: event::MouseButton, x: i32, y: i32) {
        self.current.mouse_button_up_event(button, x, y)
    }

    fn mouse_motion_event(&mut self,
                          _state: event::MouseState,
                          _x: i32,
                          _y: i32,
                          _xrel: i32,
                          _yrel: i32) {
        self.current.mouse_motion_event(_state, _x, _y, _xrel, _yrel)
    }

    fn mouse_wheel_event(&mut self, _x: i32, _y: i32) {
        self.current.mouse_wheel_event(_x, _y)
    }

    fn key_down_event(&mut self,
                      _keycode: event::Keycode,
                      _keymod: event::Mod,
                      _repeat: bool) {
        self.current.key_down_event(_keycode, _keymod, _repeat)
    }

    fn key_up_event(&mut self,
                    _keycode: event::Keycode,
                    _keymod: event::Mod,
                    _repeat: bool) {
        self.current.key_up_event(_keycode, _keymod, _repeat)
    }

    fn focus_event(&mut self, _gained: bool) {
        self.current.focus_event(_gained)
    }

    /// Called upon a quit event.  If it returns true,
    /// the game does not exit.
    fn quit_event(&mut self) -> bool {
        self.current.quit_event()
    }
}

impl<T> SceneManager<T> {
    /// This lets us create a SceneManager by providing the data for it.
    fn new(starting_scene_state: Box<SavedScene>, game_data: T) -> Self {
        let starting_scene = starting_scene_state.load();
        let mut scenes: BTreeMap<String, Box<SavedScene>> = BTreeMap::new();
        scenes.insert(starting_scene_state.name().to_string(),
                      starting_scene_state);
        let sm = SceneManager {
            states: scenes,
            current: starting_scene,
            next_scene: None,
            game_data: game_data,
        };
        sm
    }

    pub fn add<S: SavedScene + 'static>(&mut self, scene_state: S) {
        self.states.insert(scene_state.name().to_string(), Box::new(scene_state));
    }

    pub fn current(&self) -> &Scene {
        &*self.current
    }

    pub fn current_mut(&mut self) -> &mut Scene {
        &mut *self.current
    }

    pub fn switch_scene(&mut self, scene_name: &str) -> GameResult<()> {
        // Save current scene
        let old_scene_state = self.current.unload();
        let old_scene_name = old_scene_state.name().to_string();
        self.states.insert(old_scene_name, old_scene_state);
        // Then load the new one.
        if let Some(scene_state) = self.states.get_mut(scene_name) {
            let new_scene = scene_state.load();
            self.current = new_scene;
            Ok(())
        } else {
            let msg = format!("SceneManager: Asked to load scene {} but it did not exist?",
                              scene_name);
            Err(ggez::GameError::ResourceNotFound(msg, vec![]))
        }
    }
}

#[cfg(test)]
mod tests {

    use ggez;
    use ggez::GameResult;
    use ggez::event::EventHandler;

    use std::time::Duration;

    use super::{Scene, SavedScene, SceneManager};

    #[derive(Clone, Debug)]
    struct TestSavedScene {
        value: i32,
        name: String,
    }

    impl SavedScene for TestSavedScene {
        fn load(&self) -> Box<Scene> {
            Box::new(TestScene(self.clone()))
        }
        fn name(&self) -> &str {
            &self.name
        }
    }

    #[derive(Clone, Debug)]
    struct TestScene(TestSavedScene);

    impl EventHandler for TestScene {
        fn update(&mut self,
                  _ctx: &mut ggez::Context,
                  _dt: Duration)
                  -> GameResult<()> {
            Ok(())
        }

        fn draw(&mut self,
                _ctx: &mut ggez::Context)
                -> GameResult<()> {
            Ok(())
        }

    }

    impl Scene for TestScene {
        fn unload(&mut self) -> Box<SavedScene> {
            Box::new(self.0.clone())
        }
    }

    #[test]
    fn test_scene_switching() {
        let default_scene = TestSavedScene {
            name: "default scene".to_string(),
            value: 42,
        };
        let new_scene = TestSavedScene {
            name: "other scene".to_string(),
            value: 23,
        };
        let mut sm = SceneManager::new(Box::new(default_scene), ());
        sm.add(new_scene);

        {
            let s = sm.current_mut().unload();
            assert_eq!(s.name(), "default scene");
        }
        let res = sm.switch_scene("other scene");
        assert!(res.is_ok());

        {
            let s = sm.current_mut().unload();
            assert_eq!(s.name(), "other scene");
        }

        let res = sm.switch_scene("non existent scene");
        assert!(res.is_err());
    }

}
<commit_msg>Updating and simplifying scene code.<commit_after>
use ggez;
use ggez::GameResult;
use ggez::conf;
use ggez::event;
use ggez::event::EventHandler;

use std::collections::BTreeMap;
use std::time::Duration;

pub trait SavedScene {
    fn load(&self) -> Box<Scene>;
    fn name(&self) -> &str;
}

// Perhaps next_scene() should really return a command
// to manipulate the scene state?
// It would be nicer to do this via a callback maybe but
// that's quite Hard since the SceneManager owns the
// current Scene.
//
// But I could certainly imagine it returning:
// Nothing, Push(NewScene), Pop, Switch(NewScene)
pub trait Scene: EventHandler {
    fn unload(&mut self) -> Box<SavedScene>;
    fn next_scene(&self) -> Option<String>;
}

/// A SceneManager is a GameState that handles Scene's
/// and switches from one to another when requested.
pub struct SceneManager {
    states: BTreeMap<String, Box<SavedScene>>,
    //pub game_data: T,
    current: Box<Scene>,
    next_scene: Option<String>,
}

impl EventHandler for SceneManager
{
    fn update(&mut self, ctx: &mut ggez::Context, dt: Duration) -> GameResult<()> {
        // TODO: Get rid of this hacky clone!
        if let Some(ref scene_name) = self.next_scene.clone() {
            self.switch_scene(&scene_name)?;
        }
        self.current.update(ctx, dt)?;
        self.next_scene = self.current.next_scene();
        Ok(())
    }

    fn draw(&mut self, ctx: &mut ggez::Context) -> GameResult<()> {
        self.current.draw(ctx)
    }

    fn mouse_button_down_event(&mut self, button: event::MouseButton, x: i32, y: i32) {
        self.current.mouse_button_down_event(button, x, y)
    }

    fn mouse_button_up_event(&mut self, button: event::MouseButton, x: i32, y: i32) {
        self.current.mouse_button_up_event(button, x, y)
    }

    fn mouse_motion_event(&mut self,
                          _state: event::MouseState,
                          _x: i32,
                          _y: i32,
                          _xrel: i32,
                          _yrel: i32) {
        self.current.mouse_motion_event(_state, _x, _y, _xrel, _yrel)
    }

    fn mouse_wheel_event(&mut self, _x: i32, _y: i32) {
        self.current.mouse_wheel_event(_x, _y)
    }

    fn key_down_event(&mut self,
                      _keycode: event::Keycode,
                      _keymod: event::Mod,
                      _repeat: bool) {
        self.current.key_down_event(_keycode, _keymod, _repeat)
    }

    fn key_up_event(&mut self,
                    _keycode: event::Keycode,
                    _keymod: event::Mod,
                    _repeat: bool) {
        self.current.key_up_event(_keycode, _keymod, _repeat)
    }

    fn focus_event(&mut self, _gained: bool) {
        self.current.focus_event(_gained)
    }

    /// Called upon a quit event.  If it returns true,
    /// the game does not exit.
    fn quit_event(&mut self) -> bool {
        self.current.quit_event()
    }
}

impl SceneManager {
    /// This lets us create a SceneManager by providing the data for it.
    fn new<T>(starting_scene_state: Box<SavedScene>, game_data: T) -> Self {
        let starting_scene = starting_scene_state.load();
        let mut scenes: BTreeMap<String, Box<SavedScene>> = BTreeMap::new();
        scenes.insert(starting_scene_state.name().to_string(),
                      starting_scene_state);
        let sm = SceneManager {
            states: scenes,
            current: starting_scene,
            next_scene: None,
        };
        sm
    }

    pub fn add<S: SavedScene + 'static>(&mut self, scene_state: S) {
        self.states.insert(scene_state.name().to_string(), Box::new(scene_state));
    }

    pub fn current(&self) -> &Scene {
        &*self.current
    }

    pub fn current_mut(&mut self) -> &mut Scene {
        &mut *self.current
    }

    pub fn switch_scene(&mut self, scene_name: &str) -> GameResult<()> {
        // Save current scene
        let old_scene_state = self.current.unload();
        let old_scene_name = old_scene_state.name().to_string();
        self.states.insert(old_scene_name, old_scene_state);
        // Then load the new one.
        if let Some(scene_state) = self.states.get_mut(scene_name) {
            let new_scene = scene_state.load();
            self.current = new_scene;
            Ok(())
        } else {
            let msg = format!("SceneManager: Asked to load scene {} but it did not exist?",
                              scene_name);
            Err(ggez::GameError::ResourceNotFound(msg, vec![]))
        }
    }
}

#[cfg(test)]
mod tests {

    use ggez;
    use ggez::GameResult;
    use ggez::event::EventHandler;

    use std::time::Duration;

    use super::{Scene, SavedScene, SceneManager};

    #[derive(Clone, Debug)]
    struct TestSavedScene {
        value: i32,
        name: String,
    }

    impl SavedScene for TestSavedScene {
        fn load(&self) -> Box<Scene> {
            Box::new(TestScene(self.clone()))
        }
        fn name(&self) -> &str {
            &self.name
        }
    }

    #[derive(Clone, Debug)]
    struct TestScene(TestSavedScene);

    impl EventHandler for TestScene {
        fn update(&mut self,
                  _ctx: &mut ggez::Context,
                  _dt: Duration)
                  -> GameResult<()> {
            Ok(())
        }

        fn draw(&mut self,
                _ctx: &mut ggez::Context)
                -> GameResult<()> {
            Ok(())
        }

    }

    impl Scene for TestScene {
        fn unload(&mut self) -> Box<SavedScene> {
            Box::new(self.0.clone())
        }

        fn next_scene(&self) -> Option<String> {
            None
        }
    }

    #[test]
    fn test_scene_switching() {
        let default_scene = TestSavedScene {
            name: "default scene".to_string(),
            value: 42,
        };
        let new_scene = TestSavedScene {
            name: "other scene".to_string(),
            value: 23,
        };
        let mut sm = SceneManager::new(Box::new(default_scene), ());
        sm.add(new_scene);

        {
            let s = sm.current_mut().unload();
            assert_eq!(s.name(), "default scene");
        }
        let res = sm.switch_scene("other scene");
        assert!(res.is_ok());

        {
            let s = sm.current_mut().unload();
            assert_eq!(s.name(), "other scene");
        }

        let res = sm.switch_scene("non existent scene");
        assert!(res.is_err());
    }

}
<|endoftext|>


<commit_before>use alloc::boxed::Box;

use hash_map::HashMap;
use vector::Vector;
use iterable::Iterable;
use iterable_mut::IterableMut;
use map::Map;
use stack::Stack;
use insert::Insert;
use remove::Remove;
use shared::Shared;

use id::Id;
use entity::Entity;
use component::Component;
use component_manager::ComponentManager;
use plugin::Plugin;

struct SceneData {
    initted: bool,

    entities: Vector<Entity>,

    component_managers_map: HashMap<Id, Shared<Box<ComponentManager>>>,
    component_managers: Vector<Shared<Box<ComponentManager>>>,

    plugins_map: HashMap<Id, Shared<Box<Plugin>>>,
    plugins: Vector<Shared<Box<Plugin>>>,
}

#[derive(Clone)]
pub struct Scene {
    data: Shared<SceneData>,
}

impl Scene {

    pub fn new() -> Self {
        Scene {
            data: Shared::new(SceneData {
                initted: false,

                entities: Vector::new(),

                component_managers_map: HashMap::new(),
                component_managers: Vector::new(),

                plugins_map: HashMap::new(),
                plugins: Vector::new(),
            })
        }
    }

    pub fn clear(&mut self) -> &mut Self {
        for entity in self.data.entities.iter_mut() {
            entity.clear();
        }
        for plugin in self.data.plugins.iter_mut() {
            plugin.clear();
        }
        {
            let ref mut data = self.data;
            data.initted = false;

            data.entities.clear();

            data.component_managers_map.clear();
            data.component_managers.clear();

            data.plugins_map.clear();
            data.plugins.clear();
        }
        self
    }

    pub fn initted(&self) -> bool {
        self.data.initted
    }

    pub fn init(&mut self) -> &Self {
        if !self.initted() {
            self.data.initted = true;

            self.sort_plugins();
            self.sort_component_managers();

            for plugin in self.data.plugins.iter_mut() {
                plugin.init();
            }
            for component_manager in self.data.component_managers.iter_mut() {
                component_manager.init();
            }
        }
        self
    }

    pub fn update(&mut self) -> &Self {
        for plugin in self.data.plugins.iter_mut() {
            plugin.before();
        }
        for component_manager in self.data.component_managers.iter_mut() {
            component_manager.update();
        }
        for plugin in self.data.plugins.iter_mut() {
            plugin.after();
        }
        self
    }

    pub fn add_entity(&mut self, entity: &mut Entity) -> &mut Self {
        if let Some(ref mut scene) = entity.get_scene() {
            if *scene != *self {
                scene.remove_entity(entity);
            } else {
                return self;
            }
        }

        self.data.entities.push(entity.clone());
        entity.__set_scene(self);

        self
    }
    pub fn has_entity(&self, entity: &Entity) -> bool {
        match self.data.entities.iter().position(|e| *e == *entity) {
            Some(_) => true,
            None => false,
        }
    }
    pub fn remove_entity(&mut self, entity: &mut Entity) -> &mut Self {
        if self.__remove_entity(entity) {
            entity.__remove_scene(self);
        }
        self
    }

    pub fn for_each_entity<F>(&mut self, func: F) where F: Fn(&mut Entity) {
        for entity in self.data.entities.iter_mut() {
            func(entity);
        }
    }

    pub fn get_component_manager<T: ComponentManager + Clone>(&self) -> Option<T> {
        let ref component_managers_map = self.data.component_managers_map;
        let id = Id::of::<T>();

        if component_managers_map.contains_key(&id) {
            let ref_component_manager = component_managers_map.get(&id).unwrap();
            let component_manager = ref_component_manager.downcast_ref::<T>().unwrap();
            Some(component_manager.clone())
        } else {
            None
        }
    }
    pub fn for_each_component_manager<F>(&mut self, func: F) where F: Fn(&mut Box<ComponentManager>) {
        for component_manager in self.data.component_managers.iter_mut() {
            func(component_manager);
        }
    }
    fn sort_component_managers(&mut self) {
        self.data.component_managers.sort_by(|a, b| {
            a.get_order().cmp(&b.get_order())
        });
    }

    pub fn add_plugin<T: Plugin + Clone>(&mut self, mut plugin: T) -> &mut Self {
        let shared_plugin = Shared::new(Box::new(plugin.clone()) as Box<Plugin>);

        self.data.plugins_map.insert(plugin.get_id(), shared_plugin.clone());
        self.data.plugins.push(shared_plugin);

        plugin.set_scene(Some(self.clone()));

        self
    }
    pub fn has_plugin<T: Plugin>(&self) -> bool {
        self.data.plugins_map.contains_key(&Id::of::<T>())
    }
    pub fn remove_plugin<T: Plugin + Clone>(&mut self, mut plugin: T) -> &mut Self {
        if plugin.get_scene().is_none() {
            return self;
        }
        let id = plugin.get_id();

        self.data.plugins_map.remove(&id);
        {
            let ref mut plugins = self.data.plugins;
            match plugins.iter().position(|p| p.get_id() == id) {
                Some(i) => {
                    plugins.remove(&i);
                },
                None => {},
            }
        }
        plugin.set_scene(None);
        plugin.clear();

        self
    }

    pub fn get_plugin<T: Plugin + Clone>(&self) -> Option<T> {
        let ref plugins_map = self.data.plugins_map;
        let id = Id::of::<T>();

        if plugins_map.contains_key(&id) {
            let ref_plugin = plugins_map.get(&id).unwrap();
            let plugin = ref_plugin.downcast_ref::<T>().unwrap();
            Some(plugin.clone())
        } else {
            None
        }
    }
    pub fn for_each_plugin<F>(&mut self, func: F) where F: Fn(&mut Box<Plugin>) {
        for plugin in self.data.plugins.iter_mut() {
            func(plugin);
        }
    }
    fn sort_plugins(&mut self) {
        self.data.plugins.sort_by(|a, b| {
            a.get_order().cmp(&b.get_order())
        });
    }

    pub fn __remove_entity(&mut self, entity: &mut Entity) -> bool {
        let removed;
        {
            let ref mut entities = self.data.entities;

            match entities.iter().position(|e| *e == *entity) {
                Some(i) => {
                    entities.remove(&i);
                    removed = true;
                },
                None => {
                    removed = false
                },
            }
        }

        if removed {
            entity.__remove_scene_children(self);
        }

        removed
    }

    pub fn __add_component(&mut self, component: &mut Box<Component>) {
        let id = component.get_component_manager_id();
        let contains_key = self.data.component_managers_map.contains_key(&id);
        let mut component_manager_ref;

        if !contains_key {
            let component_manager = component.new_component_manager();

            component_manager_ref = Shared::new(component_manager);

            component_manager_ref.set_scene(Some(self.clone()));

            self.data.component_managers_map.insert(id, component_manager_ref.clone());
            self.data.component_managers.push(component_manager_ref.clone());

            if self.initted() {
                self.sort_component_managers();
            }
        } else {
            component_manager_ref = self.data.component_managers_map.get(&id).unwrap().clone();
        }

        component_manager_ref.add_component(component);

        if self.initted() {
            component_manager_ref.init();
        }
    }
    pub fn __remove_component(&mut self, component: &mut Box<Component>) {
        let id = component.get_component_manager_id();
        let is_empty;

        component.set_entity(None);

        {
            let ref mut component_managers_map = self.data.component_managers_map;
            let component_manager = component_managers_map.get_mut(&id).unwrap();
            is_empty = component_manager.is_empty();
            component_manager.remove_component(component);
        }

        if is_empty {
            {
                let ref mut component_managers = self.data.component_managers;
                match component_managers.iter().position(|c| c.get_id() == id) {
                    Some(i) => {
                        {
                            let ref mut component_manager = component_managers[i];
                            component_manager.set_scene(None);
                            component_manager.clear();
                        }
                        component_managers.remove(&i);
                    },
                    None => {},
                }
            }
            self.data.component_managers_map.remove(&id);
        }
    }
}

impl PartialEq<Scene> for Scene {
    fn eq(&self, other: &Scene) -> bool {
        (&*self.data as *const _) == (&*other.data as *const _)
    }
    fn ne(&self, other: &Scene) -> bool {
        !self.eq(other)
    }
}
<commit_msg>updates<commit_after>use alloc::boxed::Box;

use hash_map::HashMap;
use vector::Vector;
use iterable::Iterable;
use iterable_mut::IterableMut;
use map::Map;
use stack::Stack;
use insert::Insert;
use remove::Remove;
use shared::Shared;

use id::Id;
use entity::Entity;
use component::Component;
use component_manager::ComponentManager;
use plugin::Plugin;

struct SceneData {
    initted: bool,

    entities: Vector<Entity>,

    component_managers_map: HashMap<Id, Shared<Box<ComponentManager>>>,
    component_managers: Vector<Shared<Box<ComponentManager>>>,

    plugins_map: HashMap<Id, Shared<Box<Plugin>>>,
    plugins: Vector<Shared<Box<Plugin>>>,
}

#[derive(Clone)]
pub struct Scene {
    data: Shared<SceneData>,
}

impl Scene {

    pub fn new() -> Self {
        Scene {
            data: Shared::new(SceneData {
                initted: false,

                entities: Vector::new(),

                component_managers_map: HashMap::new(),
                component_managers: Vector::new(),

                plugins_map: HashMap::new(),
                plugins: Vector::new(),
            })
        }
    }

    pub fn clear(&mut self) -> &mut Self {
        for entity in self.data.entities.iter_mut() {
            entity.clear();
        }
        for plugin in self.data.plugins.iter_mut() {
            plugin.clear();
        }
        {
            let ref mut data = self.data;
            data.initted = false;

            data.entities.clear();

            data.component_managers_map.clear();
            data.component_managers.clear();

            data.plugins_map.clear();
            data.plugins.clear();
        }
        self
    }

    pub fn initted(&self) -> bool {
        self.data.initted
    }

    pub fn init(&mut self) -> &Self {
        if !self.initted() {
            self.data.initted = true;

            self.sort_plugins();
            self.sort_component_managers();

            for plugin in self.data.plugins.iter_mut() {
                plugin.init();
            }
            for component_manager in self.data.component_managers.iter_mut() {
                component_manager.init();
            }
        }
        self
    }

    pub fn update(&mut self) -> &Self {
        for plugin in self.data.plugins.iter_mut() {
            plugin.before();
        }
        for component_manager in self.data.component_managers.iter_mut() {
            component_manager.update();
        }
        for plugin in self.data.plugins.iter_mut() {
            plugin.after();
        }
        self
    }

    pub fn add_entity(&mut self, entity: &mut Entity) -> &mut Self {
        if let Some(ref mut scene) = entity.get_scene() {
            if *scene != *self {
                scene.remove_entity(entity);
            } else {
                return self;
            }
        }

        self.data.entities.push(entity.clone());
        entity.__set_scene(self);

        self
    }
    pub fn has_entity(&self, entity: &Entity) -> bool {
        match self.data.entities.iter().position(|e| *e == *entity) {
            Some(_) => true,
            None => false,
        }
    }
    pub fn remove_entity(&mut self, entity: &mut Entity) -> &mut Self {
        if self.__remove_entity(entity) {
            entity.__remove_scene(self);
        }
        self
    }

    pub fn for_each_entity<F>(&mut self, func: F) where F: Fn(&mut Entity) {
        for entity in self.data.entities.iter_mut() {
            func(entity);
        }
    }

    pub fn get_component_manager<T: ComponentManager + Clone>(&self) -> Option<T> {
        let ref component_managers_map = self.data.component_managers_map;
        let id = Id::of::<T>();

        if component_managers_map.contains_key(&id) {
            let ref_component_manager = component_managers_map.get(&id).unwrap();
            let component_manager = ref_component_manager.downcast_ref::<T>().unwrap();
            Some(component_manager.clone())
        } else {
            None
        }
    }
    pub fn for_each_component_manager<F>(&mut self, func: F) where F: Fn(&mut Box<ComponentManager>) {
        for component_manager in self.data.component_managers.iter_mut() {
            func(component_manager);
        }
    }
    fn sort_component_managers(&mut self) {
        self.data.component_managers.sort_by(|a, b| {
            a.get_order().cmp(&b.get_order())
        });
    }

    pub fn add_plugin<T: Plugin + Clone>(&mut self, mut plugin: T) -> &mut Self {
        let shared_plugin = Shared::new(Box::new(plugin.clone()) as Box<Plugin>);

        self.data.plugins_map.insert(plugin.get_id(), shared_plugin.clone());
        self.data.plugins.push(shared_plugin);

        plugin.set_scene(Some(self.clone()));

        if self.data.initted {
            self.sort_plugins();
        }

        self
    }
    pub fn has_plugin<T: Plugin>(&self) -> bool {
        self.data.plugins_map.contains_key(&Id::of::<T>())
    }
    pub fn remove_plugin<T: Plugin + Clone>(&mut self, mut plugin: T) -> &mut Self {
        if plugin.get_scene().is_none() {
            return self;
        }
        let id = plugin.get_id();

        self.data.plugins_map.remove(&id);
        {
            let ref mut plugins = self.data.plugins;
            match plugins.iter().position(|p| p.get_id() == id) {
                Some(i) => {
                    plugins.remove(&i);
                },
                None => {},
            }
        }
        plugin.set_scene(None);
        plugin.clear();

        self
    }

    pub fn get_plugin<T: Plugin + Clone>(&self) -> Option<T> {
        let ref plugins_map = self.data.plugins_map;
        let id = Id::of::<T>();

        if plugins_map.contains_key(&id) {
            let ref_plugin = plugins_map.get(&id).unwrap();
            let plugin = ref_plugin.downcast_ref::<T>().unwrap();
            Some(plugin.clone())
        } else {
            None
        }
    }
    pub fn for_each_plugin<F>(&mut self, func: F) where F: Fn(&mut Box<Plugin>) {
        for plugin in self.data.plugins.iter_mut() {
            func(plugin);
        }
    }
    fn sort_plugins(&mut self) {
        self.data.plugins.sort_by(|a, b| {
            a.get_order().cmp(&b.get_order())
        });
    }

    pub fn __remove_entity(&mut self, entity: &mut Entity) -> bool {
        let removed;
        {
            let ref mut entities = self.data.entities;

            match entities.iter().position(|e| *e == *entity) {
                Some(i) => {
                    entities.remove(&i);
                    removed = true;
                },
                None => {
                    removed = false
                },
            }
        }

        if removed {
            entity.__remove_scene_children(self);
        }

        removed
    }

    pub fn __add_component(&mut self, component: &mut Box<Component>) {
        let id = component.get_component_manager_id();
        let contains_key = self.data.component_managers_map.contains_key(&id);
        let mut component_manager_ref;

        if !contains_key {
            let component_manager = component.new_component_manager();

            component_manager_ref = Shared::new(component_manager);

            component_manager_ref.set_scene(Some(self.clone()));

            self.data.component_managers_map.insert(id, component_manager_ref.clone());
            self.data.component_managers.push(component_manager_ref.clone());

            if self.initted() {
                self.sort_component_managers();
            }
        } else {
            component_manager_ref = self.data.component_managers_map.get(&id).unwrap().clone();
        }

        component_manager_ref.add_component(component);

        if self.initted() {
            component_manager_ref.init();
        }
    }
    pub fn __remove_component(&mut self, component: &mut Box<Component>) {
        let id = component.get_component_manager_id();
        let is_empty;

        component.set_entity(None);

        {
            let ref mut component_managers_map = self.data.component_managers_map;
            let component_manager = component_managers_map.get_mut(&id).unwrap();
            is_empty = component_manager.is_empty();
            component_manager.remove_component(component);
        }

        if is_empty {
            {
                let ref mut component_managers = self.data.component_managers;
                match component_managers.iter().position(|c| c.get_id() == id) {
                    Some(i) => {
                        {
                            let ref mut component_manager = component_managers[i];
                            component_manager.set_scene(None);
                            component_manager.clear();
                        }
                        component_managers.remove(&i);
                    },
                    None => {},
                }
            }
            self.data.component_managers_map.remove(&id);
        }
    }
}

impl PartialEq<Scene> for Scene {
    fn eq(&self, other: &Scene) -> bool {
        (&*self.data as *const _) == (&*other.data as *const _)
    }
    fn ne(&self, other: &Scene) -> bool {
        !self.eq(other)
    }
}
<|endoftext|>