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

use value::Value;
use relation::{Relation, IndexSelect, ViewSelect};
use primitive::{Primitive, resolve_as_scalar};
use std::cmp::{min, max};

#[derive(Clone, Debug)]
pub struct Table {
    pub insert: Option<IndexSelect>,
    pub remove: Option<IndexSelect>,
}

#[derive(Clone, Debug)]
pub struct Union {
    pub selects: Vec<IndexSelect>,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConstraintOp {
    EQ,
    NEQ,
    LT,
    GT,
    LTE,
    GTE,
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub left: usize,
    pub op: ConstraintOp,
    pub right: usize,
}

impl Constraint {
    fn is_satisfied_by(&self, state: &[&Value]) -> bool {
        match self.op {
            ConstraintOp::EQ => state[self.left] == state[self.right],
            ConstraintOp::NEQ => state[self.left] != state[self.right],
            ConstraintOp::LT => state[self.left] < state[self.right],
            ConstraintOp::GT => state[self.left] > state[self.right],
            ConstraintOp::LTE => state[self.left] <= state[self.right],
            ConstraintOp::GTE => state[self.left] >= state[self.right],
        }
    }
}

#[derive(Clone, Debug)]
pub enum JoinSource {
    Relation{
        input: usize
    },
    Primitive{
        primitive: Primitive,
        arguments: Vec<usize>,
    },
}

#[derive(Clone, Debug)]
pub struct Join {
    pub constants: Vec<Value>,
    pub sources: Vec<JoinSource>,
    pub constraints: Vec<Vec<Constraint>>,
    pub select: ViewSelect,
}

#[derive(Clone, Debug)]
pub struct Reducer {
    pub primitive: Primitive,
    pub arguments: Vec<usize>,
}

#[derive(Clone, Debug)]
pub struct Aggregate {
    pub constants: Vec<Value>,
    pub outer: IndexSelect,
    pub inner: IndexSelect,
    pub limit_from: Option<usize>,
    pub limit_to: Option<usize>,
    pub reducers: Vec<Reducer>,
    pub selects_inner: bool,
    pub select: ViewSelect,
}

#[derive(Clone, Debug)]
pub enum View {
    Table(Table),
    Union(Union),
    Join(Join),
    Aggregate(Aggregate),
}

fn push_all<'a>(state: &mut Vec<&'a Value>, input: &'a Vec<Value>) {
    for value in input.iter() {
        state.push(value);
    }
}

fn pop_all<'a>(state: &mut Vec<&'a Value>, input: &'a Vec<Value>) {
    for _ in input.iter() {
        state.pop();
    }
}

fn join_step<'a>(join: &'a Join, ix: usize, inputs: &[&'a Relation], state: &mut Vec<&'a Value>, index: &mut BTreeSet<Vec<Value>>) {
    if ix == join.sources.len() {
        index.insert(join.select.select(&state[..]));
    } else {
        match join.sources[ix] {
            JoinSource::Relation{input} => {
                for values in inputs[input].index.iter() {
                    push_all(state, values);
                    if join.constraints[ix].iter().all(|constraint| constraint.is_satisfied_by(&state[..])) {
                        join_step(join, ix+1, inputs, state, index)
                    }
                    pop_all(state, values);
                }
            }
            JoinSource::Primitive{ref primitive, ref arguments, ..} => {
                for values in primitive.eval_from_join(&arguments[..], &state[..]).into_iter() {
                    // promise the borrow checker that we will pop values before we exit this scope
                    let values = unsafe { ::std::mem::transmute::<&Vec<Value>, &'a Vec<Value>>(&values) };
                    push_all(state, values);
                    if join.constraints[ix].iter().all(|constraint| constraint.is_satisfied_by(&state[..])) {
                        join_step(join, ix+1, inputs, state, index)
                    }
                    pop_all(state, values);
                }
            }
        }
    }
}

fn aggregate_step<'a>(aggregate: &Aggregate, input_sets: &'a [&[Vec<Value>]], state: &mut Vec<&'a Value>, index: &mut BTreeSet<Vec<Value>>) {
    if input_sets.len() == 0 {
        index.insert(aggregate.select.select(&state[..]));
    } else {
        for values in input_sets[0].iter() {
            push_all(state, values);
            aggregate_step(aggregate, &input_sets[1..], state, index);
            pop_all(state, values);
        }
    }
}

impl View {
    pub fn run(&self, old_output: &Relation, inputs: &[&Relation]) -> Option<Relation> {
        match *self {
            View::Table(_) => None,
            View::Union(ref union) => {
                assert_eq!(union.selects.len(), inputs.len());
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                for select in union.selects.iter() {
                    for values in select.select(&inputs[..]) {
                        output.index.insert(values);
                    }
                }
                Some(output)
            }
            View::Join(ref join) => {
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                let mut tuples = Vec::with_capacity(join.sources.len());
                join_step(join, 0, inputs, &mut tuples, &mut output.index);
                Some(output)
            }
            View::Aggregate(ref aggregate) => {
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                let mut outer = aggregate.outer.select(&inputs[..]);
                let mut inner = aggregate.inner.select(&inputs[..]);
                outer.sort();
                outer.dedup();
                inner.sort();
                let constants = &aggregate.constants[..];
                let mut group_start = 0;
                for outer_values in outer.into_iter() {
                    let mut group_end = group_start;
                    while (group_end < inner.len())
                    && (inner[group_end][0..outer_values.len()] == outer_values[..]) {
                        group_end += 1;
                    }
                    let (group, output_values) = {
                        let limit_from = match aggregate.limit_from {
                            None => group_start,
                            Some(ix) => group_start
                                + resolve_as_scalar(ix, constants, &outer_values[..]).as_usize(),
                        };
                        let limit_to = match aggregate.limit_to {
                            None => group_end,
                            Some(ix) => group_start
                                + resolve_as_scalar(ix, constants, &outer_values[..]).as_usize(),
                        };
                        let limit_from = min(max(limit_from, group_start), group_end);
                        let limit_to = min(max(limit_to, limit_from), group_end);
                        let group = &inner[limit_from..limit_to];
                        let output_values = aggregate.reducers.iter().map(|reducer| {
                            reducer.primitive.eval_from_aggregate(&reducer.arguments[..], constants, &outer_values[..], group)
                        }).collect::<Vec<_>>();
                        (group, output_values)
                    };
                    let mut output_sets = vec![];
                    let null = Value::Null;
                    if aggregate.selects_inner {
                        output_sets.push(group);
                    } else {
                        // nasty hack - fill null values for inner so that the ixes work out right
                        for _ in aggregate.inner.mapping.iter() {
                            state.push(&null);
                        }
                    }
                    for output in output_values.iter() {
                        output_sets.push(output);
                    }
                    let mut state = constants.iter().chain(outer_values.iter()).collect::<Vec<_>>();
                    aggregate_step(aggregate, &output_sets[..], &mut state, &mut output.index);
                    group_start = group_end;
                }
                Some(output)
            }
        }
    }
}<commit_msg>Typo?<commit_after>use std::collections::BTreeSet;

use value::Value;
use relation::{Relation, IndexSelect, ViewSelect};
use primitive::{Primitive, resolve_as_scalar};
use std::cmp::{min, max};

#[derive(Clone, Debug)]
pub struct Table {
    pub insert: Option<IndexSelect>,
    pub remove: Option<IndexSelect>,
}

#[derive(Clone, Debug)]
pub struct Union {
    pub selects: Vec<IndexSelect>,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConstraintOp {
    EQ,
    NEQ,
    LT,
    GT,
    LTE,
    GTE,
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub left: usize,
    pub op: ConstraintOp,
    pub right: usize,
}

impl Constraint {
    fn is_satisfied_by(&self, state: &[&Value]) -> bool {
        match self.op {
            ConstraintOp::EQ => state[self.left] == state[self.right],
            ConstraintOp::NEQ => state[self.left] != state[self.right],
            ConstraintOp::LT => state[self.left] < state[self.right],
            ConstraintOp::GT => state[self.left] > state[self.right],
            ConstraintOp::LTE => state[self.left] <= state[self.right],
            ConstraintOp::GTE => state[self.left] >= state[self.right],
        }
    }
}

#[derive(Clone, Debug)]
pub enum JoinSource {
    Relation{
        input: usize
    },
    Primitive{
        primitive: Primitive,
        arguments: Vec<usize>,
    },
}

#[derive(Clone, Debug)]
pub struct Join {
    pub constants: Vec<Value>,
    pub sources: Vec<JoinSource>,
    pub constraints: Vec<Vec<Constraint>>,
    pub select: ViewSelect,
}

#[derive(Clone, Debug)]
pub struct Reducer {
    pub primitive: Primitive,
    pub arguments: Vec<usize>,
}

#[derive(Clone, Debug)]
pub struct Aggregate {
    pub constants: Vec<Value>,
    pub outer: IndexSelect,
    pub inner: IndexSelect,
    pub limit_from: Option<usize>,
    pub limit_to: Option<usize>,
    pub reducers: Vec<Reducer>,
    pub selects_inner: bool,
    pub select: ViewSelect,
}

#[derive(Clone, Debug)]
pub enum View {
    Table(Table),
    Union(Union),
    Join(Join),
    Aggregate(Aggregate),
}

fn push_all<'a>(state: &mut Vec<&'a Value>, input: &'a Vec<Value>) {
    for value in input.iter() {
        state.push(value);
    }
}

fn pop_all<'a>(state: &mut Vec<&'a Value>, input: &'a Vec<Value>) {
    for _ in input.iter() {
        state.pop();
    }
}

fn join_step<'a>(join: &'a Join, ix: usize, inputs: &[&'a Relation], state: &mut Vec<&'a Value>, index: &mut BTreeSet<Vec<Value>>) {
    if ix == join.sources.len() {
        index.insert(join.select.select(&state[..]));
    } else {
        match join.sources[ix] {
            JoinSource::Relation{input} => {
                for values in inputs[input].index.iter() {
                    push_all(state, values);
                    if join.constraints[ix].iter().all(|constraint| constraint.is_satisfied_by(&state[..])) {
                        join_step(join, ix+1, inputs, state, index)
                    }
                    pop_all(state, values);
                }
            }
            JoinSource::Primitive{ref primitive, ref arguments, ..} => {
                for values in primitive.eval_from_join(&arguments[..], &state[..]).into_iter() {
                    // promise the borrow checker that we will pop values before we exit this scope
                    let values = unsafe { ::std::mem::transmute::<&Vec<Value>, &'a Vec<Value>>(&values) };
                    push_all(state, values);
                    if join.constraints[ix].iter().all(|constraint| constraint.is_satisfied_by(&state[..])) {
                        join_step(join, ix+1, inputs, state, index)
                    }
                    pop_all(state, values);
                }
            }
        }
    }
}

fn aggregate_step<'a>(aggregate: &Aggregate, input_sets: &'a [&[Vec<Value>]], state: &mut Vec<&'a Value>, index: &mut BTreeSet<Vec<Value>>) {
    if input_sets.len() == 0 {
        index.insert(aggregate.select.select(&state[..]));
    } else {
        for values in input_sets[0].iter() {
            push_all(state, values);
            aggregate_step(aggregate, &input_sets[1..], state, index);
            pop_all(state, values);
        }
    }
}

impl View {
    pub fn run(&self, old_output: &Relation, inputs: &[&Relation]) -> Option<Relation> {
        match *self {
            View::Table(_) => None,
            View::Union(ref union) => {
                assert_eq!(union.selects.len(), inputs.len());
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                for select in union.selects.iter() {
                    for values in select.select(&inputs[..]) {
                        output.index.insert(values);
                    }
                }
                Some(output)
            }
            View::Join(ref join) => {
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                let mut tuples = Vec::with_capacity(join.sources.len());
                join_step(join, 0, inputs, &mut tuples, &mut output.index);
                Some(output)
            }
            View::Aggregate(ref aggregate) => {
                let mut output = Relation::new(
                    old_output.view.clone(),
                    old_output.fields.clone(),
                    old_output.names.clone()
                    );
                let mut outer = aggregate.outer.select(&inputs[..]);
                let mut inner = aggregate.inner.select(&inputs[..]);
                outer.sort();
                outer.dedup();
                inner.sort();
                let constants = &aggregate.constants[..];
                let mut group_start = 0;
                for outer_values in outer.into_iter() {
                    let mut group_end = group_start;
                    while (group_end < inner.len())
                    && (inner[group_end][0..outer_values.len()] == outer_values[..]) {
                        group_end += 1;
                    }
                    let (group, output_values) = {
                        let limit_from = match aggregate.limit_from {
                            None => group_start,
                            Some(ix) => group_start
                                + resolve_as_scalar(ix, constants, &outer_values[..]).as_usize(),
                        };
                        let limit_to = match aggregate.limit_to {
                            None => group_end,
                            Some(ix) => group_start
                                + resolve_as_scalar(ix, constants, &outer_values[..]).as_usize(),
                        };
                        let limit_from = min(max(limit_from, group_start), group_end);
                        let limit_to = min(max(limit_to, limit_from), group_end);
                        let group = &inner[limit_from..limit_to];
                        let output_values = aggregate.reducers.iter().map(|reducer| {
                            reducer.primitive.eval_from_aggregate(&reducer.arguments[..], constants, &outer_values[..], group)
                        }).collect::<Vec<_>>();
                        (group, output_values)
                    };
                    let mut output_sets = vec![];
                    let null = Value::Null;
                    let mut state = constants.iter().chain(outer_values.iter()).collect::<Vec<_>>();
                    if aggregate.selects_inner {
                        output_sets.push(group);
                    } else {
                        // nasty hack - fill null values for inner so that the ixes work out right
                        for _ in aggregate.inner.mapping.iter() {
                            state.push(&null);
                        }
                    }
                    for output in output_values.iter() {
                        output_sets.push(output);
                    }
                    aggregate_step(aggregate, &output_sets[..], &mut state, &mut output.index);
                    group_start = group_end;
                }
                Some(output)
            }
        }
    }
}<|endoftext|>


<commit_before>use std::any::Any;
use std::error::Error;
use std::fmt;
use std::fmt::Debug;
use std::result;
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver, TryRecvError, RecvError, SendError};
use std::thread;

use time::{Duration, SteadyTime};

pub type InitResult<E> = result::Result<Option<u64>, E>;
pub type ActorResult<T> = result::Result<T, ActorError>;
pub type StartResult<T, E> = result::Result<Actor<T>, E>;

pub struct Actor<T> where T: Any + Send {
    pub sender: Sender<Message<T>>,
    pub receiver: Receiver<Message<T>>,
    pub handle: thread::JoinHandle<ActorResult<()>>,
    pub name: Option<String>,
}

impl<T> Actor<T> where T: Any + Send {
    /// Create a new actor handler struct.
    pub fn new(sender: Sender<Message<T>>, receiver: Receiver<Message<T>>,
        handle: thread::JoinHandle<ActorResult<()>>, name: Option<String>) -> Self {
        Actor {
            sender: sender,
            receiver: receiver,
            handle: handle,
            name: name,
        }
    }

    pub fn cast(&self, message: T) -> Result<(), ActorError> {
        self::cast(&self.sender, message)
    }

    pub fn call(&self, message: T) -> Result<T, ActorError> {
        self::call(&self.sender, &self.receiver, message)
    }
}

pub fn cast<T: Any + Send>(tx: &Sender<Message<T>>, message: T) -> Result<(), ActorError> {
    match tx.send(Message::Cast(message)) {
        Ok(()) => Ok(()),
        Err(err) => Err(ActorError::from(err)),
    }
}

pub fn call<T: Any + Send>(tx: &Sender<Message<T>>, rx: &Receiver<Message<T>>, message: T) -> Result<T, ActorError> {
    match tx.send(Message::Call(message)) {
        Ok(()) => {
            match rx.recv() {
                Ok(Message::Reply(msg)) => Ok(msg),
                Ok(_) => panic!("must reply from a call!"),
                Err(err) => Err(ActorError::from(err)),
            }
        },
        Err(err) => Err(ActorError::from(err)),
    }
}

pub struct Builder<T: GenServer> {
    name: Option<String>,
    spec: T,
}

impl<A: GenServer> Builder<A> {
    pub fn new(spec: A) -> Self {
        Builder {
            name: None,
            spec: spec,
        }
    }

    pub fn name(mut self, name: String) -> Builder<A> {
        self.name = Some(name);
        self
    }

    /// Start an actor on a new thread and return an Actor.
    pub fn start(self, mut state: A::S) -> StartResult<A::T, A::E> {
        let (otx, orx) = mpsc::channel::<Message<A::T>>();
        let (itx, irx) = mpsc::channel::<Message<A::T>>();
        let initial_wait_ms = match self.spec.init(&itx, &mut state) {
            Ok(result) => result,
            Err(err) => return Err(err),
        };
        let itx2 = itx.clone(); // clone 'self' sender for actor struct
        let name = self.name.clone();
        let thread_name = name.clone().unwrap_or("GenServer".to_string());
        let handle = thread::Builder::new().name(thread_name.clone()).spawn(move || {
            let mut timeout: Option<SteadyTime> = None;
            if let Some(ms) = initial_wait_ms {
                set_timeout(ms, &mut timeout);
            }
            loop {
                if let Some(go_time) = timeout {
                    if go_time >= SteadyTime::now() {
                        match self.spec.handle_timeout(&itx, &mut state) {
                            HandleResult::Stop(reason, None) => return shutdown(reason, None, &otx),
                            HandleResult::NoReply(Some(0)) => {
                                set_timeout(0, &mut timeout);
                                continue;
                            },
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_timeout: {:?}", hr),
                        }
                    }
                }
                match irx.try_recv() {
                    Ok(Message::Call(msg)) => {
                        match self.spec.handle_call(msg, &itx, &otx, &mut state) {
                            HandleResult::Reply(msg, new_timeout) => {
                                try!(otx.send(Message::Reply(msg)));
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                        }
                    },
                    Ok(Message::Cast(msg)) => {
                        match self.spec.handle_cast(msg, &itx, &mut state) {
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_cast: {:?}", hr),
                        }
                    },
                    Ok(Message::Info(msg)) => {
                        match self.spec.handle_info(msg, &itx, &mut state) {
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_info: {:?}", hr),
                        }
                    },
                    Ok(hr) => panic!("received unexpected message type: {:?}", hr),
                    Err(TryRecvError::Disconnected) => { break; },
                    Err(TryRecvError::Empty) => { },
                }
            }
            Ok(())
        }).unwrap();
        Ok(Actor::new(itx2, orx, handle, name))
    }
}

#[derive(Debug)]
pub enum ActorError {
    InitFailure(String),
    AbnormalShutdown(String),
    SendError,
    RecvError,
}

impl<T: Any + Send> From<mpsc::SendError<Message<T>>> for ActorError {
    fn from(_err: mpsc::SendError<Message<T>>) -> Self {
        ActorError::SendError
    }
}

impl From<mpsc::RecvError> for ActorError {
    fn from(_err: mpsc::RecvError) -> Self {
        ActorError::RecvError
    }
}

#[derive(Debug)]
pub enum StopReason {
    Normal,
    Fatal(String),
}

#[derive(Debug)]
pub enum HandleResult<T> where T: Any + Send {
    Reply(T, Option<u64>),
    NoReply(Option<u64>),
    Stop(StopReason, Option<T>),
}

pub enum Message<T> where T: Any + Send {
    Call(T),
    Cast(T),
    Info(T),
    Reply(T),
}

impl<T> Debug for Message<T> where T: Any + Send + Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Message::Call(ref msg) => write!(f, "CALL: {:?}", msg),
            &Message::Cast(ref msg) => write!(f, "CAST: {:?}", msg),
            &Message::Info(ref msg) => write!(f, "INFO: {:?}", msg),
            &Message::Reply(ref msg) => write!(f, "REPLY: {:?}", msg)
        }
    }
}

pub trait GenServer : Send + 'static {
    type T: Send + Any + Debug;
    type S: Send + Any;
    type E: Error + 'static;

    fn init(&self, _tx: &Sender<Message<Self::T>>, state: &mut Self::S) -> InitResult<Self::E>;

    fn handle_call(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _caller: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        panic!("handle_call callback not implemented");
    }
    fn handle_cast(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        panic!("handle_cast callback not implemented");
    }
    fn handle_info(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        HandleResult::NoReply(None)
    }
    fn handle_timeout(&self, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        HandleResult::NoReply(None)
    }
}

fn set_timeout(wait_ms: u64, current_timeout: &mut Option<SteadyTime>) {
    *current_timeout = Some(SteadyTime::now() + Duration::milliseconds(wait_ms as i64));
}

fn shutdown<T: Any + Send>(reason: StopReason, reply: Option<T>, sender: &Sender<Message<T>>) -> Result<(), ActorError> {
    if let Some(msg) = reply {
        let _result = sender.send(Message::Reply(msg));
    }
    match reason {
        StopReason::Normal => Ok(()),
        StopReason::Fatal(e) => Err(ActorError::AbnormalShutdown(e)),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fmt;
    use std::error::Error;
    use std::sync::mpsc::Sender;

    struct Worker;

    struct MyState {
        pub initialized: bool,
    }

    impl MyState {
        pub fn new() -> Self {
            MyState {
                initialized: false,
            }
        }
    }

    #[derive(Debug)]
    enum MyError {
        DirtyState,
    }

    #[derive(Debug)]
    enum MyMessage {
        Ok,
        Stop,
        State(bool),
        GetState,
        SetState(bool),
    }

    impl GenServer for Worker {
        type T = MyMessage;
        type S = MyState;
        type E = MyError;

        fn init(&self, _tx: &Sender<Message<Self::T>>, state: &mut Self::S) -> InitResult<Self::E> {
            if state.initialized {
                Err(MyError::DirtyState)
            } else {
                state.initialized = true;
                Ok(None)
            }
        }

        fn handle_call(&self, msg: Self::T, _: &Sender<Message<Self::T>>, _: &Sender<Message<Self::T>>, state: &mut Self::S) -> HandleResult<Self::T> {
            match msg {
                MyMessage::Stop => HandleResult::Stop(StopReason::Normal, Some(MyMessage::Ok)),
                MyMessage::GetState => HandleResult::Reply(MyMessage::State(state.initialized), None),
                MyMessage::SetState(value) => {
                    state.initialized = value;
                    HandleResult::Reply(MyMessage::Ok, None)
                }
                _ => HandleResult::Stop(StopReason::Fatal(String::from("Nope")), None),
            }
        }

        fn handle_cast(&self, msg: Self::T, _: &Sender<Message<Self::T>>, state: &mut Self::S) -> HandleResult<Self::T> {
            match msg {
                MyMessage::SetState(value) => {
                    state.initialized = value;
                    HandleResult::NoReply(None)
                },
                _ => HandleResult::NoReply(None)
            }
        }
    }

    impl fmt::Display for MyError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match *self {
                MyError::DirtyState => write!(f, "state already initialized"),
            }
        }
    }

    impl Error for MyError {
        fn description(&self) -> &str {
            match *self {
                MyError::DirtyState => "state already initialized"
            }
        }
    }

    #[test]
    fn error_on_init() {
        let mut state = MyState::new();
        state.initialized = true;
        match Builder::new(Worker).start(state) {
            Err(MyError::DirtyState) => assert!(true),
            Ok(_) => assert!(false),
        }
    }

    #[test]
    fn call_set_get_state() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(true)) => assert!(true),
            _ => assert!(false),
        }
        assert!(actor.call(MyMessage::SetState(false)).is_ok());
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(false)) => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn multiple_cast_and_call_ordered() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        assert!(actor.cast(MyMessage::SetState(false)).is_ok());
        assert!(actor.cast(MyMessage::SetState(true)).is_ok());
        assert!(actor.cast(MyMessage::SetState(false)).is_ok());
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(result)) => assert_eq!(result, false),
            _ => assert!(false),
        }
    }

    #[test]
    fn stopping_an_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        match actor.call(MyMessage::Stop) {
            Ok(MyMessage::Ok) => assert!(true),
            _ => assert!(false),
        }
        match actor.handle.join() {
            Ok(_) => assert!(true),
            Err(_) => assert!(false),
        }
    }

    #[test]
    fn explicitly_naming_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).name("batman".to_string()).start(state).unwrap();
        assert!(actor.name.is_some());
        assert_eq!(actor.name.unwrap(), "batman".to_string());
    }

    #[test]
    fn default_named_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        assert!(actor.name.is_none());
    }
}
<commit_msg>pass inner recv loop sender instead of outer sender<commit_after>use std::any::Any;
use std::error::Error;
use std::fmt;
use std::fmt::Debug;
use std::result;
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver, TryRecvError, RecvError, SendError};
use std::thread;

use time::{Duration, SteadyTime};

pub type InitResult<E> = result::Result<Option<u64>, E>;
pub type ActorResult<T> = result::Result<T, ActorError>;
pub type StartResult<T, E> = result::Result<Actor<T>, E>;

pub struct Actor<T> where T: Any + Send {
    pub sender: Sender<Message<T>>,
    pub receiver: Receiver<Message<T>>,
    pub handle: thread::JoinHandle<ActorResult<()>>,
    pub name: Option<String>,
}

impl<T> Actor<T> where T: Any + Send {
    /// Create a new actor handler struct.
    pub fn new(sender: Sender<Message<T>>, receiver: Receiver<Message<T>>,
        handle: thread::JoinHandle<ActorResult<()>>, name: Option<String>) -> Self {
        Actor {
            sender: sender,
            receiver: receiver,
            handle: handle,
            name: name,
        }
    }

    pub fn cast(&self, message: T) -> Result<(), ActorError> {
        self::cast(&self.sender, message)
    }

    pub fn call(&self, message: T) -> Result<T, ActorError> {
        self::call(&self.sender, &self.receiver, message)
    }
}

pub fn cast<T: Any + Send>(tx: &Sender<Message<T>>, message: T) -> Result<(), ActorError> {
    match tx.send(Message::Cast(message)) {
        Ok(()) => Ok(()),
        Err(err) => Err(ActorError::from(err)),
    }
}

pub fn call<T: Any + Send>(tx: &Sender<Message<T>>, rx: &Receiver<Message<T>>, message: T) -> Result<T, ActorError> {
    match tx.send(Message::Call(message)) {
        Ok(()) => {
            match rx.recv() {
                Ok(Message::Reply(msg)) => Ok(msg),
                Ok(_) => panic!("must reply from a call!"),
                Err(err) => Err(ActorError::from(err)),
            }
        },
        Err(err) => Err(ActorError::from(err)),
    }
}

pub struct Builder<T: GenServer> {
    name: Option<String>,
    spec: T,
}

impl<A: GenServer> Builder<A> {
    pub fn new(spec: A) -> Self {
        Builder {
            name: None,
            spec: spec,
        }
    }

    pub fn name(mut self, name: String) -> Builder<A> {
        self.name = Some(name);
        self
    }

    /// Start an actor on a new thread and return an Actor.
    pub fn start(self, mut state: A::S) -> StartResult<A::T, A::E> {
        let (otx, orx) = mpsc::channel::<Message<A::T>>();
        let (itx, irx) = mpsc::channel::<Message<A::T>>();
        let initial_wait_ms = match self.spec.init(&itx, &mut state) {
            Ok(result) => result,
            Err(err) => return Err(err),
        };
        let itx2 = itx.clone(); // clone inner receive loop's sender for actor struct
        let name = self.name.clone();
        let thread_name = name.clone().unwrap_or("GenServer".to_string());
        let handle = thread::Builder::new().name(thread_name.clone()).spawn(move || {
            let mut timeout: Option<SteadyTime> = None;
            if let Some(ms) = initial_wait_ms {
                set_timeout(ms, &mut timeout);
            }
            loop {
                if let Some(go_time) = timeout {
                    if go_time >= SteadyTime::now() {
                        match self.spec.handle_timeout(&otx, &mut state) {
                            HandleResult::Stop(reason, None) => return shutdown(reason, None, &otx),
                            HandleResult::NoReply(Some(0)) => {
                                set_timeout(0, &mut timeout);
                                continue;
                            },
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_timeout: {:?}", hr),
                        }
                    }
                }
                match irx.try_recv() {
                    Ok(Message::Call(msg)) => {
                        match self.spec.handle_call(msg, &otx, &itx, &mut state) {
                            HandleResult::Reply(msg, new_timeout) => {
                                try!(otx.send(Message::Reply(msg)));
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                        }
                    },
                    Ok(Message::Cast(msg)) => {
                        match self.spec.handle_cast(msg, &otx, &mut state) {
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_cast: {:?}", hr),
                        }
                    },
                    Ok(Message::Info(msg)) => {
                        match self.spec.handle_info(msg, &otx, &mut state) {
                            HandleResult::Stop(reason, reply) => return shutdown(reason, reply, &otx),
                            HandleResult::NoReply(new_timeout) => {
                                if let Some(ms) = new_timeout {
                                    set_timeout(ms, &mut timeout);
                                }
                            },
                            hr => panic!("unexpected `HandleResult` returned from handle_info: {:?}", hr),
                        }
                    },
                    Ok(hr) => panic!("received unexpected message type: {:?}", hr),
                    Err(TryRecvError::Disconnected) => { break; },
                    Err(TryRecvError::Empty) => { },
                }
            }
            Ok(())
        }).unwrap();
        Ok(Actor::new(itx2, orx, handle, name))
    }
}

#[derive(Debug)]
pub enum ActorError {
    InitFailure(String),
    AbnormalShutdown(String),
    SendError,
    RecvError,
}

impl<T: Any + Send> From<mpsc::SendError<Message<T>>> for ActorError {
    fn from(_err: mpsc::SendError<Message<T>>) -> Self {
        ActorError::SendError
    }
}

impl From<mpsc::RecvError> for ActorError {
    fn from(_err: mpsc::RecvError) -> Self {
        ActorError::RecvError
    }
}

#[derive(Debug)]
pub enum StopReason {
    Normal,
    Fatal(String),
}

#[derive(Debug)]
pub enum HandleResult<T> where T: Any + Send {
    Reply(T, Option<u64>),
    NoReply(Option<u64>),
    Stop(StopReason, Option<T>),
}

pub enum Message<T> where T: Any + Send {
    Call(T),
    Cast(T),
    Info(T),
    Reply(T),
}

impl<T> Debug for Message<T> where T: Any + Send + Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Message::Call(ref msg) => write!(f, "CALL: {:?}", msg),
            &Message::Cast(ref msg) => write!(f, "CAST: {:?}", msg),
            &Message::Info(ref msg) => write!(f, "INFO: {:?}", msg),
            &Message::Reply(ref msg) => write!(f, "REPLY: {:?}", msg)
        }
    }
}

pub trait GenServer : Send + 'static {
    type T: Send + Any + Debug;
    type S: Send + Any;
    type E: Error + 'static;

    fn init(&self, _tx: &Sender<Message<Self::T>>, state: &mut Self::S) -> InitResult<Self::E>;

    fn handle_call(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _caller: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        panic!("handle_call callback not implemented");
    }
    fn handle_cast(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        panic!("handle_cast callback not implemented");
    }
    fn handle_info(&self, _message: Self::T, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        HandleResult::NoReply(None)
    }
    fn handle_timeout(&self, _tx: &Sender<Message<Self::T>>, _state: &mut Self::S) -> HandleResult<Self::T> {
        HandleResult::NoReply(None)
    }
}

fn set_timeout(wait_ms: u64, current_timeout: &mut Option<SteadyTime>) {
    *current_timeout = Some(SteadyTime::now() + Duration::milliseconds(wait_ms as i64));
}

fn shutdown<T: Any + Send>(reason: StopReason, reply: Option<T>, sender: &Sender<Message<T>>) -> Result<(), ActorError> {
    if let Some(msg) = reply {
        let _result = sender.send(Message::Reply(msg));
    }
    match reason {
        StopReason::Normal => Ok(()),
        StopReason::Fatal(e) => Err(ActorError::AbnormalShutdown(e)),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fmt;
    use std::error::Error;
    use std::sync::mpsc::Sender;

    struct Worker;

    struct MyState {
        pub initialized: bool,
    }

    impl MyState {
        pub fn new() -> Self {
            MyState {
                initialized: false,
            }
        }
    }

    #[derive(Debug)]
    enum MyError {
        DirtyState,
    }

    #[derive(Debug)]
    enum MyMessage {
        Ok,
        Stop,
        State(bool),
        GetState,
        SetState(bool),
    }

    impl GenServer for Worker {
        type T = MyMessage;
        type S = MyState;
        type E = MyError;

        fn init(&self, _tx: &Sender<Message<Self::T>>, state: &mut Self::S) -> InitResult<Self::E> {
            if state.initialized {
                Err(MyError::DirtyState)
            } else {
                state.initialized = true;
                Ok(None)
            }
        }

        fn handle_call(&self, msg: Self::T, _: &Sender<Message<Self::T>>, _: &Sender<Message<Self::T>>, state: &mut Self::S) -> HandleResult<Self::T> {
            match msg {
                MyMessage::Stop => HandleResult::Stop(StopReason::Normal, Some(MyMessage::Ok)),
                MyMessage::GetState => HandleResult::Reply(MyMessage::State(state.initialized), None),
                MyMessage::SetState(value) => {
                    state.initialized = value;
                    HandleResult::Reply(MyMessage::Ok, None)
                }
                _ => HandleResult::Stop(StopReason::Fatal(String::from("Nope")), None),
            }
        }

        fn handle_cast(&self, msg: Self::T, _: &Sender<Message<Self::T>>, state: &mut Self::S) -> HandleResult<Self::T> {
            match msg {
                MyMessage::SetState(value) => {
                    state.initialized = value;
                    HandleResult::NoReply(None)
                },
                _ => HandleResult::NoReply(None)
            }
        }
    }

    impl fmt::Display for MyError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match *self {
                MyError::DirtyState => write!(f, "state already initialized"),
            }
        }
    }

    impl Error for MyError {
        fn description(&self) -> &str {
            match *self {
                MyError::DirtyState => "state already initialized"
            }
        }
    }

    #[test]
    fn error_on_init() {
        let mut state = MyState::new();
        state.initialized = true;
        match Builder::new(Worker).start(state) {
            Err(MyError::DirtyState) => assert!(true),
            Ok(_) => assert!(false),
        }
    }

    #[test]
    fn call_set_get_state() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(true)) => assert!(true),
            _ => assert!(false),
        }
        assert!(actor.call(MyMessage::SetState(false)).is_ok());
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(false)) => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn multiple_cast_and_call_ordered() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        assert!(actor.cast(MyMessage::SetState(false)).is_ok());
        assert!(actor.cast(MyMessage::SetState(true)).is_ok());
        assert!(actor.cast(MyMessage::SetState(false)).is_ok());
        match actor.call(MyMessage::GetState) {
            Ok(MyMessage::State(result)) => assert_eq!(result, false),
            _ => assert!(false),
        }
    }

    #[test]
    fn stopping_an_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        match actor.call(MyMessage::Stop) {
            Ok(MyMessage::Ok) => assert!(true),
            _ => assert!(false),
        }
        match actor.handle.join() {
            Ok(_) => assert!(true),
            Err(_) => assert!(false),
        }
    }

    #[test]
    fn explicitly_naming_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).name("batman".to_string()).start(state).unwrap();
        assert!(actor.name.is_some());
        assert_eq!(actor.name.unwrap(), "batman".to_string());
    }

    #[test]
    fn default_named_actor() {
        let state = MyState::new();
        let actor = Builder::new(Worker).start(state).unwrap();
        assert!(actor.name.is_none());
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn f<'r>(p: &'r mut fn(p: &mut ())) {
    p(()) //~ ERROR expected function, found `&'r mut fn(&mut ())`
}

fn main() {}
<commit_msg>Test where the old infrastructure failed to detect the (applicable) impl of `FnMut` for some reason.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(overloaded_calls)]

fn f<'r>(p: &'r mut fn(p: &mut ())) {
    p(()) //~ ERROR mismatched types: expected `&mut ()`, found `()`
}

fn main() {}
<|endoftext|>


<commit_before>use std::result;

use piston::input::*;

use rand::Rng;

use super::block::Tetromino;
use super::block::TETROMINOS;

pub type Result<T> = result::Result<T, String>;

use super::BOARD_WIDTH;
use super::BOARD_HEIGHT;

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum GameState {
    Playing,
    Paused,
    Over // donezo. player lost or quit
}

pub struct Board {
    pub cells: [[u8; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize],
    pub current_piece: Tetromino, // current active Tetromino
    pub state: GameState,

    // line_counts[i] = # of filled blocks in row i
    line_counts: [i64; BOARD_HEIGHT as usize] ,
    // for "random bag" generation of the next tetromino
    tetrominos_bag: Vec<Tetromino>
}

impl Board {
    pub fn init_board() -> Board {
        let mut bag = TETROMINOS.to_vec();
        ::rand::thread_rng().shuffle(&mut bag);

        Board {
            cells: [[0; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize],
            current_piece: bag.remove(0),
            state: GameState::Playing,

            line_counts: [0; BOARD_HEIGHT as usize],
            tetrominos_bag: bag
        }
    }

    pub fn handle_key_press(&mut self, inp: Input) {
        match inp {
            Input::Press(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.current_piece.rotate_right();

                        // undo rotation if it was invalid...lol
                        if self.current_piece_out_of_bounds() {
                            self.current_piece.rotate_left();
                        }
                    }
                    Button::Keyboard(Key::Left) => {
                        if self.can_move_current_piece_left() {
                            self.current_piece.move_left();
                        }
                    }
                    Button::Keyboard(Key::Right) => {
                        if self.can_move_current_piece_right() {
                            self.current_piece.move_right();
                        }
                    }
                    Button::Keyboard(Key::Down) => {
                        if self.can_move_current_piece_down() {
                            self.current_piece.move_down();
                        }
                    }
                    Button::Keyboard(Key::Space) => {
                        // pressing spacebar drops piece to bottom
                        while self.can_move_current_piece_down() {
                            self.current_piece.move_down();
                        }
                    }
                    // P = pause button
                    Button::Keyboard(Key::P) => {
                        if self.state == GameState::Playing {
                            self.state = GameState::Paused;
                        } else if self.state == GameState::Paused {
                            self.state = GameState::Playing;
                        }
                    }
                    // R = restart button
                    // TODO: disabled for multiplayer
                    Button::Keyboard(Key::R) => {
                        // reset all game variables
                        let mut bag = TETROMINOS.to_vec();
                        ::rand::thread_rng().shuffle(&mut bag);

                        self.cells = [[0; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize];
                        self.current_piece = bag.remove(0);
                        self.state = GameState::Playing;
                        self.line_counts = [0; BOARD_HEIGHT as usize];
                        self.tetrominos_bag = bag;
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }

    // iterate thru board and clear the specified row
    fn clear_row(&mut self, row: usize) {
        for col in 0..BOARD_WIDTH {
            self.cells[row][col as usize] = 0;
        }
        self.line_counts[row] = 0;

        // move all cells above (and including) the cleared row down by one
        for r in (1..(row+1)).rev() {
            for col in 0..BOARD_WIDTH {
                self.cells[r as usize][col as usize] = self.cells[(r-1) as usize][col as usize];
            }
            self.line_counts[r as usize] = self.line_counts[(r-1) as usize];
        }
    }

    pub fn clear_line_if_needed(&mut self) {
        // iterate through rows affected by current piece
        let mut rows_affected = Vec::new();
        let current_y = self.current_piece.y_offset;

        for r in 0..self.current_piece.blocks.len() {
            for c in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[r][c] == 1 {
                    let board_y: usize = ((r as f64) + current_y) as usize;
                    rows_affected.push(board_y);
                }
            }
        }

        for row in rows_affected.iter() {
            if self.line_counts[*row] == BOARD_WIDTH {
                self.clear_row(*row);
            }
        }
    }

    pub fn advance_board(&mut self) {
        if self.state != GameState::Playing {
            return
        }
        // check if game is over or not
        // check top row of board and see if any of them are filled?
        for col in 0..self.cells[0].len() {
            if self.cells[0][col] == 1{
                self.state = GameState::Over;
                return
            }
        }

        // make the existing piece fall
        if self.can_move_current_piece_down() {
            self.current_piece.move_down();
        } else {
            // add piece to board cells
            self.set_piece_on_board();

            // clear line if necessary
            self.clear_line_if_needed();

            // get new piece
            self.current_piece = self.get_next_piece();
        }
    }

    fn can_move_current_piece_down(&self) -> bool {
        if self.current_piece.bottommost() + 1.0 >= BOARD_HEIGHT as f64 {
            return false
        }
        // check if piece will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64);
                    let board_y: i64 = (row as i64) + (current_y as i64) + 1;
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn can_move_current_piece_left(&self) -> bool {
        if self.current_piece.leftmost() - 1.0 < 0.0 {
            return false;
        }
        // check if will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64) - 1;
                    let board_y: i64 = (row as i64) + (current_y as i64);
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn can_move_current_piece_right(&self) -> bool {
        if self.current_piece.rightmost() + 1.0 >= BOARD_WIDTH as f64  {
            return false;
        }
        // check if will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64) + 1;
                    let board_y: i64 = (row as i64) + (current_y as i64);
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn current_piece_out_of_bounds(&self) -> bool {
        if self.current_piece.leftmost() < 0.0 || self.current_piece.rightmost() >= BOARD_WIDTH as f64 || self.current_piece.bottommost() >= BOARD_HEIGHT as f64 {
            return true
        }
        false
    }

    pub fn set_piece_on_board(&mut self) {
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;

        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let x: i64 = (col as i64) + (current_x as i64);
                    let y: i64 = (row as i64) + (current_y as i64);
                    self.cells[y as usize][x as usize] = 1;
                    self.line_counts[y as usize] += 1;
                }
            }
        }
    }

    pub fn get_next_piece(&mut self) -> Tetromino {
        if self.tetrominos_bag.len() == 0 {
            self.tetrominos_bag = TETROMINOS.to_vec();
            ::rand::thread_rng().shuffle(&mut self.tetrominos_bag);
        }
        self.tetrominos_bag.remove(0)
    }
}<commit_msg>add score to board<commit_after>use piston::input::*;

use rand::Rng;

use super::BOARD_WIDTH;
use super::BOARD_HEIGHT;
use super::block::Tetromino;
use super::block::TETROMINOS;

// 1st entry is # of points for clearing 1 line, etc.
const SCORES_PER_LINE: [u64; 4] = [80, 200, 600, 2400];

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum GameState {
    Playing,
    Paused,
    Over // donezo. player lost or quit
}

pub struct Board {
    pub cells: [[u8; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize],
    pub current_piece: Tetromino, // current active Tetromino
    pub state: GameState,
    pub score: u64,

    // line_counts[i] = # of filled blocks in row i
    line_counts: [i64; BOARD_HEIGHT as usize],
    // for "random bag" generation of the next tetromino
    tetrominos_bag: Vec<Tetromino>
}

impl Board {
    pub fn init_board() -> Board {
        let mut bag = TETROMINOS.to_vec();
        ::rand::thread_rng().shuffle(&mut bag);

        Board {
            cells: [[0; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize],
            current_piece: bag.remove(0),
            state: GameState::Playing,
            score: 0,

            line_counts: [0; BOARD_HEIGHT as usize],
            tetrominos_bag: bag
        }
    }

    pub fn handle_key_press(&mut self, inp: Input) {
        match inp {
            Input::Press(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.current_piece.rotate_right();

                        // undo rotation if it was invalid...lol
                        if self.current_piece_out_of_bounds() {
                            self.current_piece.rotate_left();
                        }
                    }
                    Button::Keyboard(Key::Left) => {
                        if self.can_move_current_piece_left() {
                            self.current_piece.move_left();
                        }
                    }
                    Button::Keyboard(Key::Right) => {
                        if self.can_move_current_piece_right() {
                            self.current_piece.move_right();
                        }
                    }
                    Button::Keyboard(Key::Down) => {
                        if self.can_move_current_piece_down() {
                            self.current_piece.move_down();
                        }
                    }
                    Button::Keyboard(Key::Space) => {
                        // pressing spacebar drops piece to bottom
                        while self.can_move_current_piece_down() {
                            self.current_piece.move_down();
                        }
                    }
                    // P = pause button
                    Button::Keyboard(Key::P) => {
                        if self.state == GameState::Playing {
                            self.state = GameState::Paused;
                        } else if self.state == GameState::Paused {
                            self.state = GameState::Playing;
                        }
                    }
                    // R = restart button
                    // TODO: disabled for multiplayer
                    Button::Keyboard(Key::R) => {
                        // reset all game variables
                        let mut bag = TETROMINOS.to_vec();
                        ::rand::thread_rng().shuffle(&mut bag);

                        self.cells = [[0; BOARD_WIDTH as usize]; BOARD_HEIGHT as usize];
                        self.current_piece = bag.remove(0);
                        self.state = GameState::Playing;
                        self.line_counts = [0; BOARD_HEIGHT as usize];
                        self.tetrominos_bag = bag;
                        self.score = 0;
                        println!("===== GAME RESTARTED =====");
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }

    // iterate thru board and clear the specified row
    fn clear_row(&mut self, row: usize) {
        for col in 0..BOARD_WIDTH {
            self.cells[row][col as usize] = 0;
        }
        self.line_counts[row] = 0;

        // move all cells above (and including) the cleared row down by one
        for r in (1..(row+1)).rev() {
            for col in 0..BOARD_WIDTH {
                self.cells[r as usize][col as usize] = self.cells[(r-1) as usize][col as usize];
            }
            self.line_counts[r as usize] = self.line_counts[(r-1) as usize];
        }
    }

    pub fn clear_line_if_needed(&mut self) {
        // iterate through rows affected by current piece
        let mut rows_affected = Vec::new();
        let current_y = self.current_piece.y_offset;

        for r in 0..self.current_piece.blocks.len() {
            for c in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[r][c] == 1 {
                    let board_y: usize = ((r as f64) + current_y) as usize;
                    rows_affected.push(board_y);
                }
            }
        }

        let mut rows_cleared = 0;
        for row in rows_affected.iter() {
            if self.line_counts[*row] == BOARD_WIDTH {
                self.clear_row(*row);
                rows_cleared += 1;
            }
        }
        if rows_cleared > 0 {
            self.score += SCORES_PER_LINE[rows_cleared - 1];
        }
    }

    pub fn advance_board(&mut self) {
        // println!("=== SCORE: {:?} ===", self.score);

        if self.state != GameState::Playing {
            return
        }
        // check if game is over or not
        // check top row of board and see if any of them are filled?
        for col in 0..self.cells[0].len() {
            if self.cells[0][col] == 1{
                self.state = GameState::Over;
                return
            }
        }

        // make the existing piece fall
        if self.can_move_current_piece_down() {
            self.current_piece.move_down();
        } else {
            // add piece to board cells
            self.set_piece_on_board();

            // clear line if necessary
            self.clear_line_if_needed();

            // get new piece
            self.current_piece = self.get_next_piece();
        }
    }

    fn can_move_current_piece_down(&self) -> bool {
        if self.current_piece.bottommost() + 1.0 >= BOARD_HEIGHT as f64 {
            return false
        }
        // check if piece will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64);
                    let board_y: i64 = (row as i64) + (current_y as i64) + 1;
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn can_move_current_piece_left(&self) -> bool {
        if self.current_piece.leftmost() - 1.0 < 0.0 {
            return false;
        }
        // check if will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64) - 1;
                    let board_y: i64 = (row as i64) + (current_y as i64);
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn can_move_current_piece_right(&self) -> bool {
        if self.current_piece.rightmost() + 1.0 >= BOARD_WIDTH as f64  {
            return false;
        }
        // check if will intersect with a piece already on the board
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let board_x: i64 = (col as i64) + (current_x as i64) + 1;
                    let board_y: i64 = (row as i64) + (current_y as i64);
                    if self.cells[board_y as usize][board_x as usize] == 1 {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn current_piece_out_of_bounds(&self) -> bool {
        if self.current_piece.leftmost() < 0.0 || self.current_piece.rightmost() >= BOARD_WIDTH as f64 || self.current_piece.bottommost() >= BOARD_HEIGHT as f64 {
            return true
        }
        false
    }

    pub fn set_piece_on_board(&mut self) {
        let current_x = self.current_piece.x_offset;
        let current_y = self.current_piece.y_offset;
        for row in 0..self.current_piece.blocks.len() {
            for col in 0..self.current_piece.blocks[0].len() {
                if self.current_piece.blocks[row][col] == 1 {
                    let x: i64 = (col as i64) + (current_x as i64);
                    let y: i64 = (row as i64) + (current_y as i64);
                    self.cells[y as usize][x as usize] = 1;
                    self.line_counts[y as usize] += 1;
                }
            }
        }
    }

    pub fn get_next_piece(&mut self) -> Tetromino {
        if self.tetrominos_bag.len() == 0 {
            self.tetrominos_bag = TETROMINOS.to_vec();
            ::rand::thread_rng().shuffle(&mut self.tetrominos_bag);
        }
        self.tetrominos_bag.remove(0)
    }
}<|endoftext|>


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

use glib_sys;
use std::borrow::Borrow;
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::slice;
use translate::*;

glib_wrapper! {
    /// A shared immutable byte slice (the equivalent of `Rc<[u8]>`).
    ///
    /// `From` implementations that take references (e.g. `&[u8]`) copy the
    /// data. The `from_static` constructor avoids copying static data.
    ///
    /// ```
    /// use glib::Bytes;
    ///
    /// let v = vec![1, 2, 3];
    /// let b = Bytes::from(&v);
    /// assert_eq!(v, b);
    ///
    /// let s = b"xyz";
    /// let b = Bytes::from_static(s);
    /// assert_eq!(&s[..], b);
    /// ```
    pub struct Bytes(Shared<glib_sys::GBytes>);

    match fn {
        ref => |ptr| glib_sys::g_bytes_ref(ptr),
        unref => |ptr| glib_sys::g_bytes_unref(ptr),
        get_type => || glib_sys::g_bytes_get_type(),
    }
}

impl Bytes {
    /// Copies `data` into a new shared slice.
    fn new<T: AsRef<[u8]>>(data: T) -> Bytes {
        let data = data.as_ref();
        unsafe { from_glib_full(glib_sys::g_bytes_new(data.as_ptr() as *const _, data.len())) }
    }

    /// Creates a view into static `data` without copying.
    pub fn from_static(data: &'static [u8]) -> Bytes {
        unsafe {
            from_glib_full(glib_sys::g_bytes_new_static(data.as_ptr() as *const _, data.len()))
        }
    }

    /// Takes ownership of `data` and creates a new `Bytes` without copying.
    pub fn from_owned<T: AsRef<[u8]> + Send + 'static>(data: T) -> Bytes {
        let data: Box<T> = Box::new(data);
        let (size, data_ptr) = {
            let data = (*data).as_ref();
            (data.len(), data.as_ptr())
        };

        unsafe extern "C" fn drop_box<T: AsRef<[u8]> + Send + 'static>(b: glib_sys::gpointer) {
            let _: Box<T> = Box::from_raw(b as *mut _);
        }

        unsafe {
            from_glib_full(glib_sys::g_bytes_new_with_free_func(data_ptr as *const _, size, Some(drop_box::<T>), Box::into_raw(data) as *mut _))
        }
    }
}

unsafe impl Send for Bytes { }
unsafe impl Sync for Bytes { }

impl<'a, T: ?Sized + Borrow<[u8]> + 'a> From<&'a T> for Bytes {
    fn from(value: &'a T) -> Bytes {
        Bytes::new(value.borrow())
    }
}

impl fmt::Debug for Bytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Bytes")
            .field("ptr", &self.to_glib_none().0)
            .field("data", &&self[..])
            .finish()
    }
}

impl Deref for Bytes {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        unsafe {
            let mut len = 0;
            let ptr = glib_sys::g_bytes_get_data(self.to_glib_none().0, &mut len);
            debug_assert!(!ptr.is_null() || len == 0);
            slice::from_raw_parts(ptr as *const u8, len)
        }
    }
}

impl PartialEq for Bytes {
    fn eq(&self, other: &Self) -> bool {
        unsafe {
            from_glib(
                glib_sys::g_bytes_equal(self.to_glib_none().0 as *const _,
                    other.to_glib_none().0 as *const _))
        }
    }
}

impl Eq for Bytes { }

impl PartialOrd for Bytes {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        unsafe {
            let ret = glib_sys::g_bytes_compare(self.to_glib_none().0 as *const _,
                other.to_glib_none().0 as *const _);
            ret.partial_cmp(&0)
        }
    }
}

impl Ord for Bytes {
    fn cmp(&self, other: &Self) -> Ordering {
        unsafe {
            let ret = glib_sys::g_bytes_compare(self.to_glib_none().0 as *const _,
                other.to_glib_none().0 as *const _);
            ret.cmp(&0)
        }
    }
}

macro_rules! impl_cmp {
    ($lhs:ty, $rhs: ty) => {
        impl<'a, 'b> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool {
                self[..].eq(&other[..])
            }
        }

        impl<'a, 'b> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool {
                self[..].eq(&other[..])
            }
        }

        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
            #[inline]
            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }

        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
            #[inline]
            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }
    }
}

impl_cmp!(Bytes, [u8]);
impl_cmp!(Bytes, &'a [u8]);
impl_cmp!(&'a Bytes, [u8]);
impl_cmp!(Bytes, Vec<u8>);
impl_cmp!(&'a Bytes, Vec<u8>);

impl Hash for Bytes {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.len().hash(state);
        Hash::hash_slice(self, state)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;
    use super::*;

    #[test]
    fn eq() {
        let abc: &[u8] = b"abc";
        let def: &[u8] = b"def";
        let a1 = Bytes::from(abc);
        let a2 = Bytes::from(abc);
        let d = Bytes::from(def);
        assert_eq!(a1, a2);
        assert_eq!(def, d);
        assert!(a1 != d);
        assert!(a1 != def);
    }

    #[test]
    fn ord() {
        let abc: &[u8] = b"abc";
        let def: &[u8] = b"def";
        let a = Bytes::from(abc);
        let d = Bytes::from(def);
        assert!(a < d);
        assert!(a < def);
        assert!(abc < d);
        assert!(d > a);
        assert!(d > abc);
        assert!(def > a);
    }

    #[test]
    fn hash() {
        let b1 = Bytes::from(b"this is a test");
        let b2 = Bytes::from(b"this is a test");
        let b3 = Bytes::from(b"test");
        let mut set = HashSet::new();
        set.insert(b1);
        assert!(set.contains(&b2));
        assert!(!set.contains(&b3));
    }

    #[test]
    fn from_static() {
        let b1 = Bytes::from_static(b"this is a test");
        let b2 = Bytes::from(b"this is a test");
        assert_eq!(b1, b2);
    }

    #[test]
    fn from_owned() {
        let b = Bytes::from_owned(vec![1, 2, 3]);
        assert_eq!(b, [1u8, 2u8, 3u8].as_ref());
    }
}
<commit_msg>gbytes: Impl AsRef<[u8]><commit_after>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use glib_sys;
use std::borrow::Borrow;
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::slice;
use translate::*;

glib_wrapper! {
    /// A shared immutable byte slice (the equivalent of `Rc<[u8]>`).
    ///
    /// `From` implementations that take references (e.g. `&[u8]`) copy the
    /// data. The `from_static` constructor avoids copying static data.
    ///
    /// ```
    /// use glib::Bytes;
    ///
    /// let v = vec![1, 2, 3];
    /// let b = Bytes::from(&v);
    /// assert_eq!(v, b);
    ///
    /// let s = b"xyz";
    /// let b = Bytes::from_static(s);
    /// assert_eq!(&s[..], b);
    /// ```
    pub struct Bytes(Shared<glib_sys::GBytes>);

    match fn {
        ref => |ptr| glib_sys::g_bytes_ref(ptr),
        unref => |ptr| glib_sys::g_bytes_unref(ptr),
        get_type => || glib_sys::g_bytes_get_type(),
    }
}

impl Bytes {
    /// Copies `data` into a new shared slice.
    fn new<T: AsRef<[u8]>>(data: T) -> Bytes {
        let data = data.as_ref();
        unsafe { from_glib_full(glib_sys::g_bytes_new(data.as_ptr() as *const _, data.len())) }
    }

    /// Creates a view into static `data` without copying.
    pub fn from_static(data: &'static [u8]) -> Bytes {
        unsafe {
            from_glib_full(glib_sys::g_bytes_new_static(data.as_ptr() as *const _, data.len()))
        }
    }

    /// Takes ownership of `data` and creates a new `Bytes` without copying.
    pub fn from_owned<T: AsRef<[u8]> + Send + 'static>(data: T) -> Bytes {
        let data: Box<T> = Box::new(data);
        let (size, data_ptr) = {
            let data = (*data).as_ref();
            (data.len(), data.as_ptr())
        };

        unsafe extern "C" fn drop_box<T: AsRef<[u8]> + Send + 'static>(b: glib_sys::gpointer) {
            let _: Box<T> = Box::from_raw(b as *mut _);
        }

        unsafe {
            from_glib_full(glib_sys::g_bytes_new_with_free_func(data_ptr as *const _, size, Some(drop_box::<T>), Box::into_raw(data) as *mut _))
        }
    }
}

unsafe impl Send for Bytes { }
unsafe impl Sync for Bytes { }

impl<'a, T: ?Sized + Borrow<[u8]> + 'a> From<&'a T> for Bytes {
    fn from(value: &'a T) -> Bytes {
        Bytes::new(value.borrow())
    }
}

impl fmt::Debug for Bytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Bytes")
            .field("ptr", &self.to_glib_none().0)
            .field("data", &&self[..])
            .finish()
    }
}

impl AsRef<[u8]> for Bytes {
    fn as_ref(&self) -> &[u8] {
        &*self
    }
}

impl Deref for Bytes {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        unsafe {
            let mut len = 0;
            let ptr = glib_sys::g_bytes_get_data(self.to_glib_none().0, &mut len);
            debug_assert!(!ptr.is_null() || len == 0);
            slice::from_raw_parts(ptr as *const u8, len)
        }
    }
}

impl PartialEq for Bytes {
    fn eq(&self, other: &Self) -> bool {
        unsafe {
            from_glib(
                glib_sys::g_bytes_equal(self.to_glib_none().0 as *const _,
                    other.to_glib_none().0 as *const _))
        }
    }
}

impl Eq for Bytes { }

impl PartialOrd for Bytes {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        unsafe {
            let ret = glib_sys::g_bytes_compare(self.to_glib_none().0 as *const _,
                other.to_glib_none().0 as *const _);
            ret.partial_cmp(&0)
        }
    }
}

impl Ord for Bytes {
    fn cmp(&self, other: &Self) -> Ordering {
        unsafe {
            let ret = glib_sys::g_bytes_compare(self.to_glib_none().0 as *const _,
                other.to_glib_none().0 as *const _);
            ret.cmp(&0)
        }
    }
}

macro_rules! impl_cmp {
    ($lhs:ty, $rhs: ty) => {
        impl<'a, 'b> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool {
                self[..].eq(&other[..])
            }
        }

        impl<'a, 'b> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool {
                self[..].eq(&other[..])
            }
        }

        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
            #[inline]
            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }

        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
            #[inline]
            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }
    }
}

impl_cmp!(Bytes, [u8]);
impl_cmp!(Bytes, &'a [u8]);
impl_cmp!(&'a Bytes, [u8]);
impl_cmp!(Bytes, Vec<u8>);
impl_cmp!(&'a Bytes, Vec<u8>);

impl Hash for Bytes {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.len().hash(state);
        Hash::hash_slice(self, state)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;
    use super::*;

    #[test]
    fn eq() {
        let abc: &[u8] = b"abc";
        let def: &[u8] = b"def";
        let a1 = Bytes::from(abc);
        let a2 = Bytes::from(abc);
        let d = Bytes::from(def);
        assert_eq!(a1, a2);
        assert_eq!(def, d);
        assert!(a1 != d);
        assert!(a1 != def);
    }

    #[test]
    fn ord() {
        let abc: &[u8] = b"abc";
        let def: &[u8] = b"def";
        let a = Bytes::from(abc);
        let d = Bytes::from(def);
        assert!(a < d);
        assert!(a < def);
        assert!(abc < d);
        assert!(d > a);
        assert!(d > abc);
        assert!(def > a);
    }

    #[test]
    fn hash() {
        let b1 = Bytes::from(b"this is a test");
        let b2 = Bytes::from(b"this is a test");
        let b3 = Bytes::from(b"test");
        let mut set = HashSet::new();
        set.insert(b1);
        assert!(set.contains(&b2));
        assert!(!set.contains(&b3));
    }

    #[test]
    fn from_static() {
        let b1 = Bytes::from_static(b"this is a test");
        let b2 = Bytes::from(b"this is a test");
        assert_eq!(b1, b2);
    }

    #[test]
    fn from_owned() {
        let b = Bytes::from_owned(vec![1, 2, 3]);
        assert_eq!(b, [1u8, 2u8, 3u8].as_ref());
    }
}
<|endoftext|>


<commit_before>// -*- rust -*-
// error-pattern:1 == 2
// xfail-test Been deadlocking on mac
use std;
import std::task;
import std::comm::chan;
import std::comm::port;
import std::comm::recv;

fn child() { assert (1 == 2); }

fn parent() {
    let p = port::<int>();
    let f = child;
    task::spawn(f);
    let x = recv(p);
}

// This task is not linked to the failure chain, but since the other
// tasks are going to fail the kernel, this one will fail too
fn sleeper() {
    let p = port::<int>();
    let x = recv(p);
}

fn main() {
    let g = sleeper;
    task::spawn(g);
    let f = parent;
    task::spawn(f);
}<commit_msg>Rehabilitate run-fail/linked-failure4.rs<commit_after>// -*- rust -*-
// error-pattern:1 == 2
use std;
import std::task;
import std::comm::chan;
import std::comm::port;
import std::comm::recv;

fn child(&&_args: ()) { assert (1 == 2); }

fn parent(&&_args: ()) {
    let p = port::<int>();
    task::spawn((), child);
    let x = recv(p);
}

// This task is not linked to the failure chain, but since the other
// tasks are going to fail the kernel, this one will fail too
fn sleeper(&&_args: ()) {
    let p = port::<int>();
    let x = recv(p);
}

fn main() {
    task::spawn((), sleeper);
    task::spawn((), parent);
}<|endoftext|>


<commit_before>use std::num::Float;
use std::default::Default;
use std::fmt::{Show, Formatter, Error};
use std::rand::random;
use std::ascii::OwnedAsciiExt;
use serialize::hex::ToHex;
use serialize::{
    Decodable, Encodable,
    Decoder, Encoder,
    DecoderHelpers, EncoderHelpers
};
use utils::clampf32;

/// A basic color struct for general color use
/// made of red, green, blue and alpha elements.
#[deriving(Copy)]
pub struct Color(pub [f32, ..4]);

impl Color {

    /// Basic constructor for a Color struct.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color([r, g, b, a])
    }

    /// Returns the red component of the color.
    #[inline(always)]
    pub fn r(&self) -> f32 {
        let &Color(c) = self;
        c[0]
    }

    /// Returns the green component of the color.
    #[inline(always)]
    pub fn g(&self) -> f32 {
        let &Color(c) = self;
        c[1]
    }

    /// Returns the blue component of the color.
    #[inline(always)]
    pub fn b(&self) -> f32 {
        let &Color(c) = self;
        c[2]
    }

    /// Sets the red component of the color.
    #[inline(always)]
    pub fn set_r(&mut self, r: f32) {
        let &Color(ref mut c) = self;
        c[0] = r;
    }

    /// Sets the green component of the color.
    #[inline(always)]
    pub fn set_g(&mut self, g: f32) {
        let &Color(ref mut c) = self;
        c[1] = g;
    }

    /// Sets the blue component of the color.
    #[inline(always)]
    pub fn set_b(&mut self, b: f32) {
        let &Color(ref mut c) = self;
        c[2] = b;
    }

    /// Sets the alpha component of the color.
    #[inline(always)]
    pub fn set_a(&mut self, a: f32) {
        let &Color(ref mut c) = self;
        c[3] = a;
    }

    /// Returns the alpha component of the color.
    #[inline(always)]
    pub fn a(&self) -> f32 {
        let &Color(c) = self;
        c[3]
    }

    /// Basic constructor for a Black Color struct.
    pub fn black() -> Color {
        Color([0f32, 0f32, 0f32, 1f32])
    }

    /// Basic constructor for a White Color struct.
    pub fn white() -> Color {
        Color([1f32, 1f32, 1f32, 1f32])
    }

    /// Return color as a vector.
    pub fn as_vec(&self) -> Vec<f32> {
        vec![self.r(), self.g(), self.b(), self.a()]
    }

    /// Clamp the Color's values between 0f32 and 1f32.
    fn clamp(c: Color) -> Color {
        Color([
            clampf32(c.r()),
            clampf32(c.g()),
            clampf32(c.b()),
            clampf32(c.a())
        ])
    }

    /// Return a highlighted version of the current Color.
    pub fn highlighted(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r() - 0.2,
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.2,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.5f32 * self.r() + self.r()),
                 clampf32((1f32 - self.g()) * 0.1f32 * self.g() + self.g()),
                 clampf32((1f32 - self.b()) * 0.1f32 * self.b() + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.5f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a clicked version of the current Color.
    pub fn clicked(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r(),
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.4,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.75f32 + self.r()),
                 clampf32((1f32 - self.g()) * 0.25f32 + self.g()),
                 clampf32((1f32 - self.b()) * 0.25f32 + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.75f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a random color.
    pub fn random() -> Color {
        let r = random::<f32>();
        let g = random::<f32>();
        let b = random::<f32>();
        let a = 1f32;
        Color::new(r, g, b, a)
    }

    /// Return an inverted version of the color.
    pub fn invert(&self) -> Color {
        let r = (1f32 - self.r()).abs();
        let g = (1f32 - self.g()).abs();
        let b = (1f32 - self.b()).abs();
        Color::new(r, g, b, self.a())
    }

    /// Return either black or white, depending which contrasts
    /// the Color the most. This will be useful for determining
    /// a readable color for text on any given background Color.
    pub fn plain_contrast(&self) -> Color {
        if self.luminance() > 0.5f32 { Color::black() }
        else { Color::white() }
    }

    /// Return the luminance of the color.
    pub fn luminance(&self) -> f32 {
        (self.r() + self.g() + self.b()) / 3f32
    }

    /// Return an array of the channels in this color
    /// clamped to [0..255]
    pub fn to_32_bit(&self) -> [u8, ..4] {
        [
            to_8_bit(self.r()),
            to_8_bit(self.g()),
            to_8_bit(self.b()),
            to_8_bit(self.a()),
        ]
    }

    /// Return the hex representation of this color
    /// in the format #RRGGBBAA
    /// e.g. `Color(1.0, 0.0, 5.0, 1.0) == "#FF0080FF"`
    pub fn to_hex(&self) -> String {
        let vals = self.to_32_bit();
        // Hex colors are always uppercased
        let hex = vals.as_slice().to_hex().into_ascii_upper();
        format!("#{}", hex.as_slice())
    }
}

fn to_8_bit(chan: f32) -> u8 {
    let chan = clampf32(chan);
    (chan * 255.0) as u8
}

impl Clone for Color {
    fn clone(&self) -> Color {
        *self
    }
}

impl Default for Color {
    /// Default constructor for a Color struct.
    fn default() -> Color {
        Color([0.5, 0.8, 0.6, 1.0])
    }
}

impl Add<Color, Color> for Color {
    fn add(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() + rhs.r(),
                self.g() + rhs.g(),
                self.b() + rhs.b(),
                self.a()
            ])
        )
    }
}

impl Sub<Color, Color> for Color {
    fn sub(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() - rhs.r(),
                self.g() - rhs.g(),
                self.b() - rhs.b(),
                self.a()
            ])
        )
    }
}

impl Div<Color, Color> for Color {
    fn div(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() / rhs.r(),
                self.g() / rhs.g(),
                self.b() / rhs.b(),
                self.a() / rhs.a(),
            ])
        )
    }
}

impl Mul<Color, Color> for Color {
    fn mul(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() * rhs.r(),
                self.g() * rhs.g(),
                self.b() * rhs.b(),
                self.a() * rhs.a(),
            ])
        )
    }
}

impl Show for Color {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        let hex = self.to_hex();
        fmt.pad(hex.as_slice())
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Color {
    fn decode(dec: &mut D) -> Result<Color, E> {
        let vec = try!(dec.read_to_vec(|le_dec| le_dec.read_f32()));

        if vec.len() != 4 {
            return Err(dec.error(format!(
                "Expected a 4 element vector when decoding Color.
                Found a vector of length {}.", vec.len()).as_slice()));
        }

        Ok(Color([vec[0], vec[1], vec[2], vec[3]]))
    }
}

impl<E, S: Encoder<E>> Encodable<S, E> for Color {
    fn encode(&self, enc: &mut S) -> Result<(), E> {
        let Color(ref vec) = *self;

        enc.emit_from_vec(vec, |le_enc, elt| le_enc.emit_f32(*elt))
    }
}

/// A trait used for "colorable" widget context types.
pub trait Colorable {
    fn color(self, color: Color) -> Self;
    /// A method used for passing color as rgba.
    fn rgba(self, r: f32, g: f32, b: f32, a: f32) -> Self;
}
<commit_msg>Fix type for trait<commit_after>use std::num::Float;
use std::default::Default;
use std::fmt::{Show, Formatter, Error};
use std::rand::random;
use std::ascii::OwnedAsciiExt;
use serialize::hex::ToHex;
use serialize::{
    Decodable, Encodable,
    Decoder, Encoder,
    DecoderHelpers, EncoderHelpers
};
use utils::clampf32;

/// A basic color struct for general color use
/// made of red, green, blue and alpha elements.
#[deriving(Copy)]
pub struct Color(pub [f32, ..4]);

impl Color {

    /// Basic constructor for a Color struct.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color([r, g, b, a])
    }

    /// Returns the red component of the color.
    #[inline(always)]
    pub fn r(&self) -> f32 {
        let &Color(c) = self;
        c[0]
    }

    /// Returns the green component of the color.
    #[inline(always)]
    pub fn g(&self) -> f32 {
        let &Color(c) = self;
        c[1]
    }

    /// Returns the blue component of the color.
    #[inline(always)]
    pub fn b(&self) -> f32 {
        let &Color(c) = self;
        c[2]
    }

    /// Sets the red component of the color.
    #[inline(always)]
    pub fn set_r(&mut self, r: f32) {
        let &Color(ref mut c) = self;
        c[0] = r;
    }

    /// Sets the green component of the color.
    #[inline(always)]
    pub fn set_g(&mut self, g: f32) {
        let &Color(ref mut c) = self;
        c[1] = g;
    }

    /// Sets the blue component of the color.
    #[inline(always)]
    pub fn set_b(&mut self, b: f32) {
        let &Color(ref mut c) = self;
        c[2] = b;
    }

    /// Sets the alpha component of the color.
    #[inline(always)]
    pub fn set_a(&mut self, a: f32) {
        let &Color(ref mut c) = self;
        c[3] = a;
    }

    /// Returns the alpha component of the color.
    #[inline(always)]
    pub fn a(&self) -> f32 {
        let &Color(c) = self;
        c[3]
    }

    /// Basic constructor for a Black Color struct.
    pub fn black() -> Color {
        Color([0f32, 0f32, 0f32, 1f32])
    }

    /// Basic constructor for a White Color struct.
    pub fn white() -> Color {
        Color([1f32, 1f32, 1f32, 1f32])
    }

    /// Return color as a vector.
    pub fn as_vec(&self) -> Vec<f32> {
        vec![self.r(), self.g(), self.b(), self.a()]
    }

    /// Clamp the Color's values between 0f32 and 1f32.
    fn clamp(c: Color) -> Color {
        Color([
            clampf32(c.r()),
            clampf32(c.g()),
            clampf32(c.b()),
            clampf32(c.a())
        ])
    }

    /// Return a highlighted version of the current Color.
    pub fn highlighted(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r() - 0.2,
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.2,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.5f32 * self.r() + self.r()),
                 clampf32((1f32 - self.g()) * 0.1f32 * self.g() + self.g()),
                 clampf32((1f32 - self.b()) * 0.1f32 * self.b() + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.5f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a clicked version of the current Color.
    pub fn clicked(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r(),
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.4,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.75f32 + self.r()),
                 clampf32((1f32 - self.g()) * 0.25f32 + self.g()),
                 clampf32((1f32 - self.b()) * 0.25f32 + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.75f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a random color.
    pub fn random() -> Color {
        let r = random::<f32>();
        let g = random::<f32>();
        let b = random::<f32>();
        let a = 1f32;
        Color::new(r, g, b, a)
    }

    /// Return an inverted version of the color.
    pub fn invert(&self) -> Color {
        let r = (1f32 - self.r()).abs();
        let g = (1f32 - self.g()).abs();
        let b = (1f32 - self.b()).abs();
        Color::new(r, g, b, self.a())
    }

    /// Return either black or white, depending which contrasts
    /// the Color the most. This will be useful for determining
    /// a readable color for text on any given background Color.
    pub fn plain_contrast(&self) -> Color {
        if self.luminance() > 0.5f32 { Color::black() }
        else { Color::white() }
    }

    /// Return the luminance of the color.
    pub fn luminance(&self) -> f32 {
        (self.r() + self.g() + self.b()) / 3f32
    }

    /// Return an array of the channels in this color
    /// clamped to [0..255]
    pub fn to_32_bit(&self) -> [u8, ..4] {
        [
            to_8_bit(self.r()),
            to_8_bit(self.g()),
            to_8_bit(self.b()),
            to_8_bit(self.a()),
        ]
    }

    /// Return the hex representation of this color
    /// in the format #RRGGBBAA
    /// e.g. `Color(1.0, 0.0, 5.0, 1.0) == "#FF0080FF"`
    pub fn to_hex(&self) -> String {
        let vals = self.to_32_bit();
        // Hex colors are always uppercased
        let hex = vals.as_slice().to_hex().into_ascii_upper();
        format!("#{}", hex.as_slice())
    }
}

fn to_8_bit(chan: f32) -> u8 {
    let chan = clampf32(chan);
    (chan * 255.0) as u8
}

impl Clone for Color {
    fn clone(&self) -> Color {
        *self
    }
}

impl Default for Color {
    /// Default constructor for a Color struct.
    fn default() -> Color {
        Color([0.5, 0.8, 0.6, 1.0])
    }
}

impl Add<Color, Color> for Color {
    fn add(self, rhs: Color) -> Color {
        Color::clamp(
            Color([
                self.r() + rhs.r(),
                self.g() + rhs.g(),
                self.b() + rhs.b(),
                self.a()
            ])
        )
    }
}

impl Sub<Color, Color> for Color {
    fn sub(self, rhs: Color) -> Color {
        Color::clamp(
            Color([
                self.r() - rhs.r(),
                self.g() - rhs.g(),
                self.b() - rhs.b(),
                self.a()
            ])
        )
    }
}

impl Div<Color, Color> for Color {
    fn div(self, rhs: Color) -> Color {
        Color::clamp(
            Color([
                self.r() / rhs.r(),
                self.g() / rhs.g(),
                self.b() / rhs.b(),
                self.a() / rhs.a(),
            ])
        )
    }
}

impl Mul<Color, Color> for Color {
    fn mul(self, rhs: Color) -> Color {
        Color::clamp(
            Color([
                self.r() * rhs.r(),
                self.g() * rhs.g(),
                self.b() * rhs.b(),
                self.a() * rhs.a(),
            ])
        )
    }
}

impl Show for Color {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        let hex = self.to_hex();
        fmt.pad(hex.as_slice())
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Color {
    fn decode(dec: &mut D) -> Result<Color, E> {
        let vec = try!(dec.read_to_vec(|le_dec| le_dec.read_f32()));

        if vec.len() != 4 {
            return Err(dec.error(format!(
                "Expected a 4 element vector when decoding Color.
                Found a vector of length {}.", vec.len()).as_slice()));
        }

        Ok(Color([vec[0], vec[1], vec[2], vec[3]]))
    }
}

impl<E, S: Encoder<E>> Encodable<S, E> for Color {
    fn encode(&self, enc: &mut S) -> Result<(), E> {
        let Color(ref vec) = *self;

        enc.emit_from_vec(vec, |le_enc, elt| le_enc.emit_f32(*elt))
    }
}

/// A trait used for "colorable" widget context types.
pub trait Colorable {
    fn color(self, color: Color) -> Self;
    /// A method used for passing color as rgba.
    fn rgba(self, r: f32, g: f32, b: f32, a: f32) -> Self;
}
<|endoftext|>