<commit_before>use features::*;

use rand::{Rng};
use std::rc::{Rc};
use std::sync::{Arc};

#[derive(Clone)]
pub struct ReplayEntry<F, Action, Res> {
  pub prev:     BeliefState<F>,
  pub action:   Action,
  pub res:      Option<Res>,
  pub next:     BeliefState<F>,
  pub terminal: bool,
  pub idx:      usize,
}

#[derive(Clone)]
pub struct ReplayFrame<F, Action, Res> {
  pub action:   Action,
  pub res:      Option<Res>,
  pub next_obs: Rc<F>,
  pub terminal: bool,
}

pub struct LinearReplayCache<F, Action, Res> {
  history_len:  usize,
  //frame_dim:    (usize, usize, usize),
  capacity:     usize,
  head:         usize,
  frames:       Vec<ReplayFrame<F, Action, Res>>,
}

impl<F, Action, Res> LinearReplayCache<F, Action, Res> where Action: Copy, Res: Copy {
  pub fn new(history_len: usize, /*frame_dim: (usize, usize, usize),*/ capacity: usize) -> Self {
    LinearReplayCache{
      history_len:  history_len,
      //frame_dim:    frame_dim,
      capacity:     capacity,
      head:         0,
      frames:       Vec::with_capacity(capacity),
    }
  }

  pub fn len(&self) -> usize {
    self.frames.len()
  }

  pub fn insert(&mut self, action: Action, res: Option<Res>, next_obs: Rc<F>, terminal: bool) {
    self.push(action, res, next_obs, terminal);
  }

  pub fn push(&mut self, action: Action, res: Option<Res>, next_obs: Rc<F>, terminal: bool) {
    let new_frame = ReplayFrame{
      action:   action,
      res:      res,
      next_obs: next_obs,
      terminal: terminal,
    };
    assert!(self.head < self.capacity);
    if self.head >= self.frames.len() {
      self.frames.push(new_frame);
    } else {
      self.frames[self.head] = new_frame;
    }
    assert!(self.frames.len() <= self.capacity);
    self.head = (self.head + 1) % self.capacity;
  }

  fn build_state(&self, idx: usize) -> BeliefState<F> {
    let mut state = BeliefState::new(Some(self.history_len), /*self.frame_dim*/);
    /*if idx >= self.history_len - 1 {
      for offset in 0 .. self.history_len {
        state.push(self.frames[idx - (self.history_len - 1) + offset].next_obs.clone());
      }
    } else {*/
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      state.push(self.frames[offset_idx].next_obs.clone());
    }
    //}
    state
  }

  pub fn sample<R>(&self, rng: &mut R) -> ReplayEntry<F, Action, Res> where R: Rng {
    assert!(self.frames.len() >= self.history_len + 1);
    assert!(self.frames.len() <= self.capacity);
    let mut idx = 0;
    'outer_loop : loop {
      idx = rng.gen_range(0, self.frames.len());
      let last_idx = (self.frames.len() + self.head - 1) % self.frames.len();
      let first_valid_idx = (self.frames.len() + last_idx - (self.frames.len() - 1) + self.history_len) % self.frames.len();
      if (first_valid_idx < last_idx && idx >= first_valid_idx && idx <= last_idx) ||
          (last_idx < first_valid_idx && (idx >= first_valid_idx || idx <= last_idx)) {
        for offset in 0 .. self.history_len {
          let offset_idx = (self.frames.len() + idx - self.history_len + offset) % self.frames.len();
          if self.frames[offset_idx].terminal {
            continue 'outer_loop;
          }
        }
        break 'outer_loop;
      }
      /*// FIXME(20161029): this index is biased when the replay memory is full,
      // but ignore it for now because the effect should be tiny.
      idx = rng.gen_range(self.history_len, self.frames.len());
      if idx >= self.head && idx < self.head + self.history_len {
        continue;
      }
      for offset in 0 .. self.history_len {
        if self.frames[idx - self.history_len + offset].terminal {
          continue 'outer_loop;
        }
      }
      break;*/
    }
    let prev_state = self.build_state(idx - 1);
    let next_state = self.build_state(idx);
    ReplayEntry{
      prev:     prev_state,
      action:   self.frames[idx].action,
      res:      self.frames[idx].res,
      next:     next_state,
      terminal: self.frames[idx].terminal,
      idx:      idx,
    }
  }
}

#[derive(Clone)]
pub struct SharedReplayEntry<State, Action, Res> {
  pub prev:     State,
  pub action:   Action,
  pub res:      Option<Res>,
  pub next:     State,
  pub terminal: bool,
  pub idx:      usize,
}

#[derive(Clone)]
pub struct SharedReplayFrame<Obs, Action, Res> {
  pub action:   Action,
  pub res:      Option<Res>,
  pub next_obs: Arc<Obs>,
  pub terminal: bool,
}

pub struct SharedLinearReplayCache<Obs, Action, Res> {
  history_len:  usize,
  //frame_dim:    (usize, usize, usize),
  capacity:     usize,
  head:         usize,
  frames:       Vec<SharedReplayFrame<Obs, Action, Res>>,
}

impl<F, Action, Res> SharedLinearReplayCache<F, Action, Res> where F: MultiObs, Action: Copy, Res: Copy {
  pub fn new(history_len: usize, /*frame_dim: (usize, usize, usize),*/ capacity: usize) -> Self {
    SharedLinearReplayCache{
      history_len:  history_len,
      //frame_dim:    frame_dim,
      capacity:     capacity,
      head:         0,
      frames:       Vec::with_capacity(capacity),
    }
  }

  pub fn len(&self) -> usize {
    self.frames.len()
  }

  pub fn insert(&mut self, action: Action, res: Option<Res>, next_obs: Arc<F>, terminal: bool) {
    self.push(action, res, next_obs, terminal);
  }

  pub fn push(&mut self, action: Action, res: Option<Res>, next_obs: Arc<F>, terminal: bool) {
    let new_frame = SharedReplayFrame{
      action:   action,
      res:      res,
      next_obs: next_obs,
      terminal: terminal,
    };
    assert!(self.head < self.capacity);
    if self.head >= self.frames.len() {
      self.frames.push(new_frame);
    } else {
      self.frames[self.head] = new_frame;
    }
    assert!(self.frames.len() <= self.capacity);
    self.head = (self.head + 1) % self.capacity;
  }

  fn build_state<State>(&self, idx: usize) -> State where State: SharedMultiBeliefState<F> {
    //let mut state = BeliefState::new(Some(self.history_len), /*self.frame_dim*/);
    let mut state = State::_build(Some(self.history_len));
    /*if idx >= self.history_len - 1 {
      for offset in 0 .. self.history_len {
        state.push(self.frames[idx - (self.history_len - 1) + offset].next_obs.clone());
      }
    } else {*/
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      state.append(self.frames[offset_idx].next_obs.clone());
    }
    //}
    state
  }

  pub fn sample<R, State>(&self, rng: &mut R) -> SharedReplayEntry<State, Action, Res> where R: Rng, State: SharedMultiBeliefState<F> {
    assert!(self.frames.len() >= self.history_len + 1);
    assert!(self.frames.len() <= self.capacity);
    let mut idx = 0;
    'outer_loop : loop {
      idx = rng.gen_range(0, self.frames.len());
      let last_idx = (self.frames.len() + self.head - 1) % self.frames.len();
      let first_valid_idx = (self.frames.len() + last_idx - (self.frames.len() - 1) + self.history_len) % self.frames.len();
      if (first_valid_idx < last_idx && idx >= first_valid_idx && idx <= last_idx) ||
          (last_idx < first_valid_idx && (idx >= first_valid_idx || idx <= last_idx)) {
        for offset in 0 .. self.history_len {
          let offset_idx = (self.frames.len() + idx - self.history_len + offset) % self.frames.len();
          if self.frames[offset_idx].terminal {
            continue 'outer_loop;
          }
        }
        break 'outer_loop;
      }
      /*// FIXME(20161029): this index is biased when the replay memory is full,
      // but ignore it for now because the effect should be tiny.
      idx = rng.gen_range(self.history_len, self.frames.len());
      if idx >= self.head && idx < self.head + self.history_len {
        continue;
      }
      for offset in 0 .. self.history_len {
        if self.frames[idx - self.history_len + offset].terminal {
          continue 'outer_loop;
        }
      }
      break;*/
    }
    let prev_state = self.build_state(idx - 1);
    let next_state = self.build_state(idx);
    SharedReplayEntry{
      prev:     prev_state,
      action:   self.frames[idx].action,
      res:      self.frames[idx].res,
      next:     next_state,
      terminal: self.frames[idx].terminal,
      idx:      idx,
    }
  }
}
<commit_msg>Replay memory supports action history.<commit_after>use features::*;

use rand::{Rng};
use std::rc::{Rc};
use std::sync::{Arc};

#[derive(Clone)]
pub struct ReplayEntry<F, Action, Res> {
  pub prev:     BeliefState<F>,
  pub action:   Action,
  pub res:      Option<Res>,
  pub next:     BeliefState<F>,
  pub terminal: bool,
  pub idx:      usize,
}

#[derive(Clone)]
pub struct ReplayFrame<F, Action, Res> {
  pub action:   Action,
  pub res:      Option<Res>,
  pub next_obs: Rc<F>,
  pub terminal: bool,
}

pub struct LinearReplayCache<F, Action, Res> {
  history_len:  usize,
  //frame_dim:    (usize, usize, usize),
  capacity:     usize,
  head:         usize,
  frames:       Vec<ReplayFrame<F, Action, Res>>,
}

impl<F, Action, Res> LinearReplayCache<F, Action, Res> where Action: Copy, Res: Copy {
  pub fn new(history_len: usize, /*frame_dim: (usize, usize, usize),*/ capacity: usize) -> Self {
    LinearReplayCache{
      history_len:  history_len,
      //frame_dim:    frame_dim,
      capacity:     capacity,
      head:         0,
      frames:       Vec::with_capacity(capacity),
    }
  }

  pub fn len(&self) -> usize {
    self.frames.len()
  }

  pub fn insert(&mut self, action: Action, res: Option<Res>, next_obs: Rc<F>, terminal: bool) {
    self.push(action, res, next_obs, terminal);
  }

  pub fn push(&mut self, action: Action, res: Option<Res>, next_obs: Rc<F>, terminal: bool) {
    let new_frame = ReplayFrame{
      action:   action,
      res:      res,
      next_obs: next_obs,
      terminal: terminal,
    };
    assert!(self.head < self.capacity);
    if self.head >= self.frames.len() {
      self.frames.push(new_frame);
    } else {
      self.frames[self.head] = new_frame;
    }
    assert!(self.frames.len() <= self.capacity);
    self.head = (self.head + 1) % self.capacity;
  }

  fn build_state(&self, idx: usize) -> BeliefState<F> {
    let mut state = BeliefState::new(Some(self.history_len), /*self.frame_dim*/);
    /*if idx >= self.history_len - 1 {
      for offset in 0 .. self.history_len {
        state.push(self.frames[idx - (self.history_len - 1) + offset].next_obs.clone());
      }
    } else {*/
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      state.push(self.frames[offset_idx].next_obs.clone());
    }
    //}
    state
  }

  pub fn sample<R>(&self, rng: &mut R) -> ReplayEntry<F, Action, Res> where R: Rng {
    assert!(self.frames.len() >= self.history_len + 1);
    assert!(self.frames.len() <= self.capacity);
    let mut idx = 0;
    'outer_loop : loop {
      idx = rng.gen_range(0, self.frames.len());
      let last_idx = (self.frames.len() + self.head - 1) % self.frames.len();
      let first_valid_idx = (self.frames.len() + last_idx - (self.frames.len() - 1) + self.history_len) % self.frames.len();
      if (first_valid_idx < last_idx && idx >= first_valid_idx && idx <= last_idx) ||
          (last_idx < first_valid_idx && (idx >= first_valid_idx || idx <= last_idx)) {
        for offset in 0 .. self.history_len {
          let offset_idx = (self.frames.len() + idx - self.history_len + offset) % self.frames.len();
          if self.frames[offset_idx].terminal {
            continue 'outer_loop;
          }
        }
        break 'outer_loop;
      }
      /*// FIXME(20161029): this index is biased when the replay memory is full,
      // but ignore it for now because the effect should be tiny.
      idx = rng.gen_range(self.history_len, self.frames.len());
      if idx >= self.head && idx < self.head + self.history_len {
        continue;
      }
      for offset in 0 .. self.history_len {
        if self.frames[idx - self.history_len + offset].terminal {
          continue 'outer_loop;
        }
      }
      break;*/
    }
    let prev_state = self.build_state(idx - 1);
    let next_state = self.build_state(idx);
    ReplayEntry{
      prev:     prev_state,
      action:   self.frames[idx].action,
      res:      self.frames[idx].res,
      next:     next_state,
      terminal: self.frames[idx].terminal,
      idx:      idx,
    }
  }
}

#[derive(Clone)]
pub struct SharedReplayEntry<State, Action, Res> {
  pub prev:     State,
  pub action:   Action,
  pub res:      Option<Res>,
  pub next:     State,
  pub terminal: bool,
  pub idx:      usize,
}

#[derive(Clone)]
pub struct SharedReplayFrame<Obs, Action, Res> {
  pub action:   Action,
  pub res:      Option<Res>,
  pub next_obs: Arc<Obs>,
  pub terminal: bool,
}

pub struct SharedLinearReplayCache<Obs, Action, Res> {
  history_len:  usize,
  //frame_dim:    (usize, usize, usize),
  capacity:     usize,
  head:         usize,
  frames:       Vec<SharedReplayFrame<Obs, Action, Res>>,
}

impl<F, Action, Res> SharedLinearReplayCache<F, Action, Res> where F: MultiObs, Action: Copy, Res: Copy {
  pub fn new(history_len: usize, /*frame_dim: (usize, usize, usize),*/ capacity: usize) -> Self {
    SharedLinearReplayCache{
      history_len:  history_len,
      //frame_dim:    frame_dim,
      capacity:     capacity,
      head:         0,
      frames:       Vec::with_capacity(capacity),
    }
  }

  pub fn len(&self) -> usize {
    self.frames.len()
  }

  pub fn insert(&mut self, action: Action, res: Option<Res>, next_obs: Arc<F>, terminal: bool) {
    self.push(action, res, next_obs, terminal);
  }

  pub fn push(&mut self, action: Action, res: Option<Res>, next_obs: Arc<F>, terminal: bool) {
    let new_frame = SharedReplayFrame{
      action:   action,
      res:      res,
      next_obs: next_obs,
      terminal: terminal,
    };
    assert!(self.head < self.capacity);
    if self.head >= self.frames.len() {
      self.frames.push(new_frame);
    } else {
      self.frames[self.head] = new_frame;
    }
    assert!(self.frames.len() <= self.capacity);
    self.head = (self.head + 1) % self.capacity;
  }

  fn build_state<State>(&self, idx: usize) -> State where State: SharedMultiBeliefState<F> {
    //let mut state = BeliefState::new(Some(self.history_len), /*self.frame_dim*/);
    let mut state = State::_build(Some(self.history_len));
    /*if idx >= self.history_len - 1 {
      for offset in 0 .. self.history_len {
        state.push(self.frames[idx - (self.history_len - 1) + offset].next_obs.clone());
      }
    } else {*/
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      state.append(self.frames[offset_idx].next_obs.clone());
    }
    //}
    state
  }

  pub fn sample<R, State>(&self, rng: &mut R) -> SharedReplayEntry<State, Action, Res> where R: Rng, State: SharedMultiBeliefState<F> {
    assert!(self.frames.len() >= self.history_len + 1);
    assert!(self.frames.len() <= self.capacity);
    let mut idx = 0;
    'outer_loop : loop {
      idx = rng.gen_range(0, self.frames.len());
      let last_idx = (self.frames.len() + self.head - 1) % self.frames.len();
      let first_valid_idx = (self.frames.len() + last_idx - (self.frames.len() - 1) + self.history_len) % self.frames.len();
      if (first_valid_idx < last_idx && idx >= first_valid_idx && idx <= last_idx) ||
          (last_idx < first_valid_idx && (idx >= first_valid_idx || idx <= last_idx)) {
        for offset in 0 .. self.history_len {
          let offset_idx = (self.frames.len() + idx - self.history_len + offset) % self.frames.len();
          if self.frames[offset_idx].terminal {
            continue 'outer_loop;
          }
        }
        break 'outer_loop;
      }
      /*// FIXME(20161029): this index is biased when the replay memory is full,
      // but ignore it for now because the effect should be tiny.
      idx = rng.gen_range(self.history_len, self.frames.len());
      if idx >= self.head && idx < self.head + self.history_len {
        continue;
      }
      for offset in 0 .. self.history_len {
        if self.frames[idx - self.history_len + offset].terminal {
          continue 'outer_loop;
        }
      }
      break;*/
    }
    let prev_state = self.build_state(idx - 1);
    let next_state = self.build_state(idx);
    SharedReplayEntry{
      prev:     prev_state,
      action:   self.frames[idx].action,
      res:      self.frames[idx].res,
      next:     next_state,
      terminal: self.frames[idx].terminal,
      idx:      idx,
    }
  }
}

#[derive(Clone)]
pub struct SharedMultiReplayEntry<State, ActH, Action, Res> {
  pub prev_states:  Vec<State>,
  pub prev_act_h:   ActH,
  pub action:   Vec<Option<Action>>,
  pub act_idx:  Vec<Option<u32>>,
  pub res:      Vec<Option<Res>>,
  pub next_states:  Vec<State>,
  pub next_act_h:   ActH,
  pub terminal: bool,
  pub idx:      usize,
}

#[derive(Clone)]
pub struct SharedMultiReplayFrame<Obs, Action, Res> {
  pub action:   Vec<Option<Action>>,
  pub act_idx:  Vec<Option<u32>>,
  pub res:      Vec<Option<Res>>,
  pub next_obs: Vec<Arc<Obs>>,
  pub terminal: bool,
}

pub struct SharedLinearMultiReplayCache<Obs, Action, Res> {
  num_players:  usize,
  action_dim:   usize,
  history_len:  usize,
  capacity:     usize,
  head:         usize,
  frames:       Vec<SharedMultiReplayFrame<Obs, Action, Res>>,
}

impl<F, Action, Res> SharedLinearMultiReplayCache<F, Action, Res> where F: MultiObs, Action: Copy, Res: Copy {
  pub fn new(num_players: usize, action_dim: usize, history_len: usize, capacity: usize) -> Self {
    SharedLinearMultiReplayCache{
      num_players:  num_players,
      action_dim:   action_dim,
      history_len:  history_len,
      capacity:     capacity,
      head:         0,
      frames:       Vec::with_capacity(capacity),
    }
  }

  pub fn len(&self) -> usize {
    self.frames.len()
  }

  pub fn push(&mut self, action: Vec<Option<Action>>, act_idx: Vec<Option<u32>>, res: Vec<Option<Res>>, next_obs: Vec<Arc<F>>, terminal: bool) {
    let new_frame = SharedMultiReplayFrame{
      action:   action,
      act_idx:  act_idx,
      res:      res,
      next_obs: next_obs,
      terminal: terminal,
    };
    assert!(self.head < self.capacity);
    if self.head >= self.frames.len() {
      self.frames.push(new_frame);
    } else {
      self.frames[self.head] = new_frame;
    }
    assert!(self.frames.len() <= self.capacity);
    self.head = (self.head + 1) % self.capacity;
  }

  fn build_state<State>(&self, player_rank: usize, idx: usize) -> State where State: SharedMultiBeliefState<F> {
    let mut state = State::_build(Some(self.history_len));
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      state.append(self.frames[offset_idx].next_obs[player_rank].clone());
    }
    state
  }

  fn build_action_history<ActH>(&self, idx: usize) -> ActH where ActH: SharedMultiActionHistory {
    let mut action_hist = ActH::_build(self.num_players, self.action_dim, Some(self.history_len));
    for offset in 0 .. self.history_len {
      let offset_idx = (self.frames.len() + idx - (self.history_len - 1) + offset) % self.frames.len();
      action_hist.append(self.frames[offset_idx].act_idx.clone());
    }
    action_hist
  }

  pub fn sample<R, State, ActH>(&self, rng: &mut R) -> SharedMultiReplayEntry<State, ActH, Action, Res> where R: Rng, State: SharedMultiBeliefState<F>, ActH: SharedMultiActionHistory {
    assert!(self.frames.len() >= self.history_len + 1);
    assert!(self.frames.len() <= self.capacity);
    let mut idx = 0;
    'outer_loop : loop {
      idx = rng.gen_range(0, self.frames.len());
      let last_idx = (self.frames.len() + self.head - 1) % self.frames.len();
      let first_valid_idx = (self.frames.len() + last_idx - (self.frames.len() - 1) + self.history_len) % self.frames.len();
      if (first_valid_idx < last_idx && idx >= first_valid_idx && idx <= last_idx) ||
          (last_idx < first_valid_idx && (idx >= first_valid_idx || idx <= last_idx)) {
        for offset in 0 .. self.history_len {
          let offset_idx = (self.frames.len() + idx - self.history_len + offset) % self.frames.len();
          if self.frames[offset_idx].terminal {
            continue 'outer_loop;
          }
        }
        break 'outer_loop;
      }
    }
    let mut prev_states = vec![];
    let mut next_states = vec![];
    for r in 0 .. self.num_players {
      let prev_state = self.build_state(r, idx - 1);
      prev_states.push(prev_state);
      let next_state = self.build_state(r, idx);
      next_states.push(next_state);
    }
    let prev_act_h = self.build_action_history(idx - 1);
    let next_act_h = self.build_action_history(idx);
    SharedMultiReplayEntry{
      prev_states:  prev_states,
      prev_act_h:   prev_act_h,
      action:   self.frames[idx].action.clone(),
      act_idx:  self.frames[idx].act_idx.clone(),
      res:      self.frames[idx].res.clone(),
      next_states:  next_states,
      next_act_h:   next_act_h,
      terminal: self.frames[idx].terminal,
      idx:      idx,
    }
  }
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate log;

use std::sync::{Once, ONCE_INIT};

pub struct LoggerUtils {}

struct SimpleLogger;

use self::log::{LogMetadata, LogRecord, LogLevelFilter};

impl log::Log for SimpleLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        true
    }
    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("{:>5}|{:<27}|{:>30}:{:<4}| {}", record.level(), record.target(), record.location().file(), record.location().line(), record.args());
        }
    }
}

impl LoggerUtils {
    pub fn init() {
        lazy_static! {
            static ref LOGGER_INIT: Once = ONCE_INIT;
        }

        LOGGER_INIT.call_once(|| {
            log::set_logger(|max_log_level| {
                max_log_level.set(LogLevelFilter::Info);
                Box::new(SimpleLogger)
            }).unwrap();
        });
    }
}

#[macro_export]
macro_rules! try_log {
    ($expr:expr) => (match $expr {
        Ok(val) => val,
        Err(err) => {
            error!("try_log! | {}", err);
            return Err(From::from(err))
        }
    })
}
<commit_msg>Update trace format<commit_after>extern crate env_logger;
extern crate log;

use std::sync::{Once, ONCE_INIT};

pub struct LoggerUtils {}

struct SimpleLogger;

use self::log::{LogMetadata, LogRecord, LogLevelFilter};

impl log::Log for SimpleLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        true
    }
    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("{:>5}|{:<30}|{:>35}:{:<4}| {}", record.level(), record.target(), record.location().file(), record.location().line(), record.args());
        }
    }
}

impl LoggerUtils {
    pub fn init() {
        lazy_static! {
            static ref LOGGER_INIT: Once = ONCE_INIT;
        }

        LOGGER_INIT.call_once(|| {
            log::set_logger(|max_log_level| {
                max_log_level.set(LogLevelFilter::Info);
                Box::new(SimpleLogger)
            }).unwrap();
        });
    }
}

#[macro_export]
macro_rules! try_log {
    ($expr:expr) => (match $expr {
        Ok(val) => val,
        Err(err) => {
            error!("try_log! | {}", err);
            return Err(From::from(err))
        }
    })
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

#[crate_id = "github.com/mozilla-servo/rust-layers#layers:0.1"];

#[feature(managed_boxes)];

extern crate extra;
extern crate geom;
extern crate opengles;
extern crate std;
extern crate serialize;

#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate io_surface;
#[cfg(target_os="macos")]
extern crate collections;

#[cfg(target_os="linux")]
extern crate xlib;

#[cfg(target_os="android")]
extern crate egl;

pub mod layers;
pub mod color;
pub mod rendergl;
pub mod scene;
pub mod texturegl;
pub mod util;

pub mod platform {
    #[cfg(target_os="linux")]
    pub mod linux {
        pub mod surface;
    }
    #[cfg(target_os="macos")]
    pub mod macos {
        pub mod surface;
    }
    #[cfg(target_os="android")]
    pub mod android {
        pub mod surface;
    }
    pub mod surface;
}

<commit_msg>Update to current rust: don't use libextra.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

#[crate_id = "github.com/mozilla-servo/rust-layers#layers:0.1"];

#[feature(managed_boxes)];

extern crate geom;
extern crate opengles;
extern crate std;
extern crate serialize;

#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate io_surface;
#[cfg(target_os="macos")]
extern crate collections;

#[cfg(target_os="linux")]
extern crate xlib;

#[cfg(target_os="android")]
extern crate egl;

pub mod layers;
pub mod color;
pub mod rendergl;
pub mod scene;
pub mod texturegl;
pub mod util;

pub mod platform {
    #[cfg(target_os="linux")]
    pub mod linux {
        pub mod surface;
    }
    #[cfg(target_os="macos")]
    pub mod macos {
        pub mod surface;
    }
    #[cfg(target_os="android")]
    pub mod android {
        pub mod surface;
    }
    pub mod surface;
}

<|endoftext|>


<commit_before>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(convert)]

//extern crate libc;
//use libc::geteuid;

use std::fs;

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

fn is_digit(d: char) -> bool {
    d >= '0' && d <= '9'
}

fn get_pids() -> Vec<i32> {
    let mut pids: Vec<i32> = vec!();

    match fs::read_dir(PROC_PATH) {
	Err(err) => println!("read_dir({}): {}", PROC_PATH, err),
	Ok(result) => for entry in result {
	    match entry {
		Err(_) => (), // ignore
		Ok(dent) => {
		    if !is_digit(dent.file_name().to_str().unwrap().char_at(0)) {
			continue;
		    }
		    match fs::metadata(dent.path()) {
			Err(_) => (), // ignore
			Ok(md) => {
			    if md.is_dir() {
				pids.push(i32::from_str_radix(dent.file_name().to_str().unwrap(), 10).unwrap());
			    }
			}
		    }
		},
	    }
	},
    };

    return pids;
}

fn cmdinfos_for(pids: Vec<i32>) -> Vec<CmdInfo> {
    let mut infos: Vec<CmdInfo> = Vec::with_capacity(pids.len());

    for pid in pids {
	println!("pid: {}", pid);
    }

    return infos;
}

fn main() {

    // command line flag parsing

    // check euid
    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let pids = get_pids();

    // get details of all pids (possibly in parallel)
    let infos = cmdinfos_for(pids);

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<commit_msg>rusty get_pid<commit_after>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(convert,str_char)]

//extern crate libc;
//use libc::geteuid;

use std::fs;
use std::io::{Error, ErrorKind};

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

fn is_digit(d: char) -> bool {
    d >= '0' && d <= '9'
}

fn not_dir<T>() -> Result<T, Error> {
    Err(Error::new(ErrorKind::NotFound, "not a directory"))
}

fn get_pids<'a>() -> Result<Vec<i32>, String> {
    let mut dir = fs::read_dir(PROC_PATH);
    if dir.is_err() {
	return Err(format!("read_dir({}): {}", PROC_PATH, dir.err().unwrap()));
    }

    // TODO: look at filter_map
    let pids: Vec<i32> = dir.unwrap()
	.filter(|e| e.is_ok()) // ignore bad dirent results
	.map(|e| e.unwrap())   // make this a list of dirents
	.filter(|e| is_digit(e.file_name().to_str().unwrap().char_at(0)))
	.filter(|e| fs::metadata(e.path()).and_then(|md| if md.is_dir() { Ok("") } else { not_dir() }).is_ok())
	.map(|e| i32::from_str_radix(e.file_name().to_str().unwrap(), 10).unwrap())
	.collect();

    Ok(pids)
}
/*
    {
	Err(err) => println!("read_dir({}): {}", PROC_PATH, err),
	Ok(result) => {
	    // result.filter()
	}
	    for entry in result {
	    match entry {
		Err(_) => (), // ignore
		Ok(dent) => {
		    if !is_digit(dent.file_name().to_str().unwrap().char_at(0)) {
			continue;
		    }
		    match fs::metadata(dent.path()) {
			Err(_) => (), // ignore
			Ok(md) => {
			    if md.is_dir() {
				pids.push(i32::from_str_radix(dent.file_name().to_str().unwrap(), 10).unwrap());
			    }
			}
		    }
		},
	    }
	},
    };

    return pids;
}
*/

fn cmdinfos_for(pids: Vec<i32>) -> Vec<CmdInfo> {
    let mut infos: Vec<CmdInfo> = Vec::with_capacity(pids.len());

    for pid in pids {
	println!("pid: {}", pid);
    }

    return infos;
}

fn main() {

    // command line flag parsing

    // check euid
    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let pids_r = get_pids();
    if pids_r.is_err() {
	println!("get_pids: {}", pids_r.err().unwrap());
	return;
    }

    let pids = pids_r.unwrap();
    // get details of all pids (possibly in parallel)
    let infos = cmdinfos_for(pids);

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::*;
use std::mem;
use std::slice;
use std::thread;
use std::to_num::ToNum;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Box<[Color]>,
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Ok(mut font_file) = File::open("file:/ui/unifont.font") {
            let _ = font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Ok(file) => {
                Some(box Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    file: file,
                    font: font,
                    data: vec![Color::rgb(0, 0, 0); (w * h * 4) as usize].into_boxed_slice(),
                })
            }
            Err(_) => None,
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Ok(path) = self.file.path() {
            // orbital://x/y/w/h/t
            if let Some(path_str) = path.to_str() {
                let parts: Vec<&str> = path_str.split('/').collect();
                if let Some(x) = parts.get(3) {
                    self.x = x.to_num_signed();
                }
                if let Some(y) = parts.get(4) {
                    self.y = y.to_num_signed();
                }
                if let Some(w) = parts.get(5) {
                    self.w = w.to_num();
                }
                if let Some(h) = parts.get(6) {
                    self.h = h.to_num();
                }
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get width
    pub fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    pub fn height(&self) -> u32 {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, _: &str) {
        // TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: i32, y: i32, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as i32 && y < self.h as i32 {
            let new = color.data;

            let alpha = (new >> 24) & 0xFF;
            if alpha > 0 {
                let old = &mut self.data[y as usize * self.w as usize + x as usize].data;
                if alpha >= 255 {
                    *old = new;
                } else {
                    let n_r = (((new >> 16) & 0xFF) * alpha) >> 8;
                    let n_g = (((new >> 8) & 0xFF) * alpha) >> 8;
                    let n_b = ((new & 0xFF) * alpha) >> 8;

                    let n_alpha = 255 - alpha;
                    let o_a = (((*old >> 24) & 0xFF) * n_alpha) >> 8;
                    let o_r = (((*old >> 16) & 0xFF) * n_alpha) >> 8;
                    let o_g = (((*old >> 8) & 0xFF) * n_alpha) >> 8;
                    let o_b = ((*old & 0xFF) * n_alpha) >> 8;

                    *old = ((o_a << 24) | (o_r << 16) | (o_g << 8) | o_b) + ((alpha << 24) | (n_r << 16) | (n_g << 8) | n_b);
                }
            }
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as i32, y + row as i32, color);
                }
            }
            offset += 1;
        }
    }

    // TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        for mut d in self.data.iter_mut() {
            *d = color;
        }
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, color: Color) {
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    // TODO: Improve speed
    pub fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Return a iterator over events
    pub fn events(&mut self) -> EventIter {
        EventIter::new(self)
    }

    /// Poll for an event
    // TODO: Replace with events()
    #[deprecated]
    pub fn poll(&mut self) -> Option<Event> {
        loop {
            let mut event = Event::new();
            match self.file.read(&mut event) {
                Ok(0) => thread::yield_now(),
                Ok(_) => return Some(event),
                Err(_) => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.write(unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * mem::size_of::<Color>())
        }).is_ok()
    }
}

/// Event iterator
pub struct EventIter {
    events: [Event; 128],
    i: usize,
    count: usize,
}

impl EventIter {
    pub fn new(window: &mut Window) -> EventIter {
        let mut iter = EventIter {
            events: [Event::new(); 128],
            i: 0,
            count: 0,
        };

        'blocking: loop {
            //Should it be cleared? iter.events = [Event::new(); 128];
            match window.file.read(unsafe {
                slice::from_raw_parts_mut(iter.events.as_mut_ptr() as *mut u8, iter.events.len() * mem::size_of::<Event>())
            }){
                Ok(0) => thread::yield_now(),
                Ok(count) => {
                    iter.count = count/mem::size_of::<Event>();
                    break 'blocking;
                },
                Err(_) => break 'blocking,
            }
        }

        iter
    }
}

impl Iterator for EventIter {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        if self.i < self.count {
            if let Some(event) = self.events.get(self.i) {
                self.i += 1;
                Some(*event)
            } else {
                None
            }
        } else {
            None
        }
    }
}
<commit_msg>Convert most things to using .events()<commit_after>use std::fs::File;
use std::io::*;
use std::mem;
use std::slice;
use std::thread;
use std::to_num::ToNum;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Box<[Color]>,
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Ok(mut font_file) = File::open("file:/ui/unifont.font") {
            let _ = font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Ok(file) => {
                Some(box Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    file: file,
                    font: font,
                    data: vec![Color::rgb(0, 0, 0); (w * h * 4) as usize].into_boxed_slice(),
                })
            }
            Err(_) => None,
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Ok(path) = self.file.path() {
            // orbital://x/y/w/h/t
            if let Some(path_str) = path.to_str() {
                let parts: Vec<&str> = path_str.split('/').collect();
                if let Some(x) = parts.get(3) {
                    self.x = x.to_num_signed();
                }
                if let Some(y) = parts.get(4) {
                    self.y = y.to_num_signed();
                }
                if let Some(w) = parts.get(5) {
                    self.w = w.to_num();
                }
                if let Some(h) = parts.get(6) {
                    self.h = h.to_num();
                }
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get width
    pub fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    pub fn height(&self) -> u32 {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, _: &str) {
        // TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: i32, y: i32, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as i32 && y < self.h as i32 {
            let new = color.data;

            let alpha = (new >> 24) & 0xFF;
            if alpha > 0 {
                let old = &mut self.data[y as usize * self.w as usize + x as usize].data;
                if alpha >= 255 {
                    *old = new;
                } else {
                    let n_r = (((new >> 16) & 0xFF) * alpha) >> 8;
                    let n_g = (((new >> 8) & 0xFF) * alpha) >> 8;
                    let n_b = ((new & 0xFF) * alpha) >> 8;

                    let n_alpha = 255 - alpha;
                    let o_a = (((*old >> 24) & 0xFF) * n_alpha) >> 8;
                    let o_r = (((*old >> 16) & 0xFF) * n_alpha) >> 8;
                    let o_g = (((*old >> 8) & 0xFF) * n_alpha) >> 8;
                    let o_b = ((*old & 0xFF) * n_alpha) >> 8;

                    *old = ((o_a << 24) | (o_r << 16) | (o_g << 8) | o_b) + ((alpha << 24) | (n_r << 16) | (n_g << 8) | n_b);
                }
            }
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as i32, y + row as i32, color);
                }
            }
            offset += 1;
        }
    }

    // TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        for mut d in self.data.iter_mut() {
            *d = color;
        }
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, color: Color) {
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    // TODO: Improve speed
    pub fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Return a iterator over events
    pub fn events(&mut self) -> EventIter {
        let mut iter = EventIter {
            events: [Event::new(); 128],
            i: 0,
            count: 0,
        };

        'blocking: loop {
            //Should it be cleared? iter.events = [Event::new(); 128];
            match self.file.read(unsafe {
                slice::from_raw_parts_mut(iter.events.as_mut_ptr() as *mut u8, iter.events.len() * mem::size_of::<Event>())
            }){
                Ok(0) => thread::yield_now(),
                Ok(count) => {
                    iter.count = count/mem::size_of::<Event>();
                    break 'blocking;
                },
                Err(_) => break 'blocking,
            }
        }

        iter
    }

    /// Poll for an event
    // TODO: Replace with events()
    #[deprecated]
    pub fn poll(&mut self) -> Option<Event> {
        loop {
            let mut event = Event::new();
            match self.file.read(&mut event) {
                Ok(0) => thread::yield_now(),
                Ok(_) => return Some(event),
                Err(_) => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.write(unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * mem::size_of::<Color>())
        }).is_ok()
    }
}

/// Event iterator
pub struct EventIter {
    events: [Event; 128],
    i: usize,
    count: usize,
}

impl Iterator for EventIter {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        if self.i < self.count {
            if let Some(event) = self.events.get(self.i) {
                self.i += 1;
                Some(*event)
            } else {
                None
            }
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>//! Basic hello world example.

extern crate ggez;
use ggez::conf;
use ggez::event;
use ggez::{Context, GameResult};
use ggez::graphics;
use std::env;
use std::path;

// First we make a structure to contain the game's state
struct MainState {
    text: graphics::Text,
    frames: usize,
}

// Then we implement the `ggez:event::EventHandler` trait on it, which
// requires callbacks for updating and drawing the game state each frame.
//
// The `EventHandler` trait also contains callbacks for event handling
// that you can override if you wish, but the defaults are fine.
impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let font = graphics::Font::new(ctx, "/DejaVuSerif.ttf", 48)?;
        let text = graphics::Text::new(ctx, "Hello world!", &font)?;

        let s = MainState {
            text: text,
            frames: 0,
        };
        Ok(s)
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        // Drawables are drawn from their center.
        let dest_point = graphics::Point2::new(self.text.width() as f32 / 2.0 + 10.0,
                                               self.text.height() as f32 / 2.0 + 10.0);
        graphics::draw(ctx, &self.text, dest_point, 0.0)?;
        graphics::present(ctx);
        self.frames += 1;
        if (self.frames % 100) == 0 {
            println!("FPS: {}", ggez::timer::get_fps(ctx));
        }
        Ok(())
    }
}

// Now our main function, which does three things:
//
// * First, create a new `ggez::conf::Conf`
// object which contains configuration info on things such
// as screen resolution and window title,
// * Second, create a `ggez::game::Game` object which will
// do the work of creating our MainState and running our game,
// * then just call `game.run()` which runs the `Game` mainloop.
pub fn main() {
    let c = conf::Conf::new();
    let ctx = &mut Context::load_from_conf("helloworld", "ggez", c).unwrap();

    // We add the CARGO_MANIFEST_DIR/resources do the filesystems paths so
    // we we look in the cargo project for files.
    if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let mut path = path::PathBuf::from(manifest_dir);
        path.push("resources");
        ctx.filesystem.mount(&path, true);
    }

    let state = &mut MainState::new(ctx).unwrap();
    if let Err(e) = event::run(ctx, state) {
        println!("Error encountered: {}", e);
    } else {
        println!("Game exited cleanly.");
    }
}
<commit_msg>Fixed mistaken comment in hello_world example<commit_after>//! Basic hello world example.

extern crate ggez;
use ggez::conf;
use ggez::event;
use ggez::{Context, GameResult};
use ggez::graphics;
use std::env;
use std::path;

// First we make a structure to contain the game's state
struct MainState {
    text: graphics::Text,
    frames: usize,
}

// Then we implement the `ggez:event::EventHandler` trait on it, which
// requires callbacks for updating and drawing the game state each frame.
//
// The `EventHandler` trait also contains callbacks for event handling
// that you can override if you wish, but the defaults are fine.
impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let font = graphics::Font::new(ctx, "/DejaVuSerif.ttf", 48)?;
        let text = graphics::Text::new(ctx, "Hello world!", &font)?;

        let s = MainState {
            text: text,
            frames: 0,
        };
        Ok(s)
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        // Drawables are drawn from their top-left corner
        let dest_point = graphics::Point2::new(10.0,
                                               10.0);
        graphics::draw(ctx, &self.text, dest_point, 0.0)?;
        graphics::present(ctx);
        self.frames += 1;
        if (self.frames % 100) == 0 {
            println!("FPS: {}", ggez::timer::get_fps(ctx));
        }
        Ok(())
    }
}

// Now our main function, which does three things:
//
// * First, create a new `ggez::conf::Conf`
// object which contains configuration info on things such
// as screen resolution and window title,
// * Second, create a `ggez::game::Game` object which will
// do the work of creating our MainState and running our game,
// * then just call `game.run()` which runs the `Game` mainloop.
pub fn main() {
    let c = conf::Conf::new();
    let ctx = &mut Context::load_from_conf("helloworld", "ggez", c).unwrap();

    // We add the CARGO_MANIFEST_DIR/resources do the filesystems paths so
    // we we look in the cargo project for files.
    if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let mut path = path::PathBuf::from(manifest_dir);
        path.push("resources");
        ctx.filesystem.mount(&path, true);
    }

    let state = &mut MainState::new(ctx).unwrap();
    if let Err(e) = event::run(ctx, state) {
        println!("Error encountered: {}", e);
    } else {
        println!("Game exited cleanly.");
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::error::Error;
use std::fmt::{self, Debug};
use iron::{Request, Response, Handler, IronResult, IronError};
use iron::{status, method};
use iron::typemap;
use recognizer::Router as Recognizer;
use recognizer::{Match, Params};

/// `Router` provides an interface for creating complex routes as middleware
/// for the Iron framework.
pub struct Router {
    // The routers, specialized by method.
    routers: HashMap<method::Method, Recognizer<Box<Handler + Send + Sync>>>,
    error: Option<Box<Handler + Send + Sync>>
}

#[derive(Debug)]
/// The error thrown by router if there is no matching route.
pub struct NoRoute;

impl fmt::Display for NoRoute {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

impl Error for NoRoute {
    fn description(&self) -> &str { "No Route" }
}

impl Router {
    /// `new` constructs a new, blank `Router`.
    pub fn new() -> Router { Router { routers: HashMap::new(), error: None } }
    /// Add a new route to a `Router`, matching both a method and glob pattern.
    ///
    /// `route` supports glob patterns: `*` for a single wildcard segment and
    /// `:param` for matching storing that segment of the request url in the `Params`
    /// object, which is stored in the request `extensions`.
    ///
    /// For instance, to route `Get` requests on any route matching
    /// `/users/:userid/:friend` and store `userid` and `friend` in
    /// the exposed Params object:
    ///
    /// ```ignore
    /// router.route(iron::method::Method::Get, "/users/:userid/:friendid", controller);
    /// ```
    ///
    /// The controller provided to route can be any `Handler`, which allows
    /// extreme flexibility when handling routes. For instance, you could provide
    /// a `Chain`, a `Handler`, which contains an authorization middleware and
    /// a controller function, so that you can confirm that the request is
    /// authorized for this route before handling it.
    pub fn route<H: Handler, S: Str>(&mut self, method: method::Method, glob: S, handler: H) -> &mut Router {
        match self.routers.entry(method) {
            Vacant(entry)   => entry.insert(Recognizer::new()),
            Occupied(entry) => entry.into_mut()
        }.add(glob.as_slice(), Box::new(handler) as Box<Handler + Send + Sync>);
        self
    }

    /// Like route, but specialized to the `Get` method.
    pub fn get<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Get, glob, handler)
    }

    /// Like route, but specialized to the `Post` method.
    pub fn post<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Post, glob, handler)
    }

    /// Like route, but specialized to the `Put` method.
    pub fn put<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Put, glob, handler)
    }

    /// Like route, but specialized to the `Delete` method.
    pub fn delete<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Delete, glob, handler)
    }

    /// Like route, but specialized to the `Head` method.
    pub fn head<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Head, glob, handler)
    }

    /// Like route, but specialized to the `Patch` method.
    pub fn patch<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Patch, glob, handler)
    }

    /// Like route, but specialized to the `Options` method.
    pub fn options<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Options, glob, handler)
    }

    /// Add a Handler to be used for this Router's `catch` method.
    pub fn error<H: Handler>(&mut self, handler: H) -> &mut Router {
        self.error = Some(Box::new(handler) as Box<Handler + Send + Sync>);
        self
    }

    fn recognize<'a>(&'a self, method: &method::Method, path: &str)
                     -> Option<Match<&'a Box<Handler + Send + Sync>>> {
        self.routers.get(method).and_then(|router| router.recognize(path).ok())
    }
}

impl typemap::Key for Router { type Value = Params; }

impl Handler for Router {
    fn call(&self, req: &mut Request) -> IronResult<Response> {
        let matched = match self.recognize(&req.method, req.url.path.connect("/").as_slice()) {
            Some(matched) => matched,
            // No match.
            None => return Err(Box::new(NoRoute) as IronError)
        };

        req.extensions.insert::<Router>(matched.params);
        matched.handler.call(req)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> (Response, IronResult<()>) {
        match self.error {
            Some(ref error_handler) => error_handler.catch(req, err),
            // Error that is not caught by anything!
            None => (Response::with(status::InternalServerError), Err(err))
        }
    }
}
<commit_msg>(feat) Fix the build and handle Options requests.<commit_after>use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::error::Error;
use std::fmt;

use iron::{Request, Response, Handler, IronResult, IronError};
use iron::{status, method, headers};
use iron::typemap::Key;

use recognizer::Router as Recognizer;
use recognizer::{Match, Params};

static METHODS: &'static [method::Method] =
    &[method::Get, method::Post, method::Post,
      method::Put, method::Delete, method::Head,
      method::Patch];

/// `Router` provides an interface for creating complex routes as middleware
/// for the Iron framework.
pub struct Router {
    // The routers, specialized by method.
    routers: HashMap<method::Method, Recognizer<Box<Handler>>>
}

#[derive(Debug)]
/// The error thrown by router if there is no matching route.
pub struct NoRoute;

impl fmt::Display for NoRoute {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("No matching route found.")
    }
}

impl Error for NoRoute {
    fn description(&self) -> &str { "No Route" }
}

impl Router {
    /// `new` constructs a new, blank `Router`.
    pub fn new() -> Router { Router { routers: HashMap::new() } }
    /// Add a new route to a `Router`, matching both a method and glob pattern.
    ///
    /// `route` supports glob patterns: `*` for a single wildcard segment and
    /// `:param` for matching storing that segment of the request url in the `Params`
    /// object, which is stored in the request `extensions`.
    ///
    /// For instance, to route `Get` requests on any route matching
    /// `/users/:userid/:friend` and store `userid` and `friend` in
    /// the exposed Params object:
    ///
    /// ```ignore
    /// # use iron::method;
    /// router.route(method::Get, "/users/:userid/:friendid", controller);
    /// ```
    ///
    /// The controller provided to route can be any `Handler`, which allows
    /// extreme flexibility when handling routes. For instance, you could provide
    /// a `Chain`, a `Handler`, which contains an authorization middleware and
    /// a controller function, so that you can confirm that the request is
    /// authorized for this route before handling it.
    pub fn route<H, S>(&mut self, method: method::Method,
                       glob: S, handler: H) -> &mut Router
    where H: Handler, S: Str {
        match self.routers.entry(method) {
            Vacant(entry)   => entry.insert(Recognizer::new()),
            Occupied(entry) => entry.into_mut()
        }.add(glob.as_slice(), Box::new(handler) as Box<Handler>);
        self
    }

    /// Like route, but specialized to the `Get` method.
    pub fn get<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Get, glob, handler)
    }

    /// Like route, but specialized to the `Post` method.
    pub fn post<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Post, glob, handler)
    }

    /// Like route, but specialized to the `Put` method.
    pub fn put<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Put, glob, handler)
    }

    /// Like route, but specialized to the `Delete` method.
    pub fn delete<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Delete, glob, handler)
    }

    /// Like route, but specialized to the `Head` method.
    pub fn head<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Head, glob, handler)
    }

    /// Like route, but specialized to the `Patch` method.
    pub fn patch<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Patch, glob, handler)
    }

    /// Like route, but specialized to the `Options` method.
    pub fn options<H: Handler, S: Str>(&mut self, glob: S, handler: H) -> &mut Router {
        self.route(method::Options, glob, handler)
    }

    fn recognize<'a>(&'a self, method: &method::Method, path: &str)
                     -> Option<Match<&'a Box<Handler>>> {
        self.routers.get(method).and_then(|router| router.recognize(path).ok())
    }

    fn handle_options(&self, req: &mut Request, path: &str) -> IronResult<Response> {
        // If there is an override, use it.
        if let Some(matched) = self.recognize(&method::Options, path) {
            req.extensions.insert::<Router>(matched.params);
            return matched.handler.handle(req);
        }

        // Else, get all the available methods and return them.
        let mut options = vec![];

        for method in METHODS.iter() {
            self.routers.get(method).map(|router| {
                if let Some(_) = router.recognize(path).ok() {
                    options.push(method.clone());
                }
            });
        }

        let mut res = Response::with(status::Ok);
        res.headers.set(headers::Allow(options));
        Ok(res)
    }
}

impl Key for Router { type Value = Params; }

impl Handler for Router {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let path = req.url.path.connect("/");

        if let method::Options = req.method {
            return self.handle_options(req, &path[]);
        }

        let matched = match self.recognize(&req.method, &path[]) {
            Some(matched) => matched,
            // No match.
            None => return Err(IronError {
                error: Box::new(NoRoute),
                response: Response::with(status::NotFound)
            })
        };

        req.extensions.insert::<Router>(matched.params);
        matched.handler.handle(req)
    }
}

<|endoftext|>


<commit_before><commit_msg>[move] Do not include vector native implementations (#4621)<commit_after><|endoftext|>


<commit_before>use card::Card;

#[derive(Debug, PartialEq)]
pub struct CardPoints {
    card: Card,
    points: i32
}

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

	use card::*;

    #[test]
    fn equality() {
    	let card = Card { suit: Suit::Heart, rank: Rank::Ace };
    	assert_eq!(CardPoints { card: card, points: 1 }, CardPoints { card: card, points: 1 });
    }
}
<commit_msg>Update card_points.rs<commit_after>use card::Card;

#[derive(Debug, PartialEq)]
pub struct CardPoints {
    card: Card,
    points: i32
}

impl CardPoints {
	pub fn new(card: Card, points: i32) -> CardPoints {
		CardPoints { card: card, points: points }
	}
}

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

	use card::*;

    #[test]
    fn equality() {
    	let card = Card::new(Suit::Heart, Rank::Ace);
    	assert_eq!(CardPoints::new(card, 1), CardPoints::new(card, 1));
    }
}
<|endoftext|>


<commit_before>//! Running of programs.

use parser::Instruction;
use std;

///
/// A runner of programs.
///
#[derive(Default)]
pub struct Runner {
    /// Program to be run.
    prog: Vec<Instruction>,
    /// A potentially infinite number of data cells.
    data: Vec<u8>,
    /// Instruction pointer (index).
    ip: usize,
    /// Data-cell pointer (index).
    dp: usize,
}

impl Runner {
    ///
    /// Constructs a new runner.
    ///
    pub fn new() -> Self {
        Runner::default()
    }

    ///
    /// Runs the given program.
    ///
    /// # Arguments
    ///
    /// * `prog` - Program to be run.
    /// * `input` - Input for the program.
    /// * `output` - Output for the program.
    ///
    pub fn run(&mut self,
               prog: Vec<Instruction>,
               mut input: &mut std::io::Read,
               mut output: &mut std::io::Write)
               -> Result<(), String> {
        self.prog = prog;
        self.data.clear();
        self.ip = 0;
        self.dp = 0;

        while !self.is_prog_end() {
            try!(self.run_instruction(&mut input, &mut output));
        }

        Ok(())
    }

    fn is_prog_end(&self) -> bool {
        self.ip >= self.prog.len()
    }

    fn run_instruction(&mut self,
                       mut input: &mut std::io::Read,
                       mut output: &mut std::io::Write)
                       -> Result<(), String> {
        match self.prog[self.ip] {
            Instruction::Next => {
                self.dp += 1;
            }
            Instruction::Prev => {
                self.dp -= 1;
            }
            Instruction::Inc => {
                let value = self.load_value();
                self.store_value(value.wrapping_add(1));
            }
            Instruction::Dec => {
                let value = self.load_value();
                self.store_value(value.wrapping_sub(1));
            }
            Instruction::Read => {
                let value = try!(self.read_value(&mut input));
                self.store_value(value);
            }
            Instruction::Write => {
                let value = self.load_value();
                try!(self.write_value(&mut output, value));
            }
            Instruction::LoopStart(loop_end_ip) => {
                if self.is_current_cell_zero() {
                    self.ip = loop_end_ip;
                }
            }
            Instruction::LoopEnd(loop_start_ip) => {
                if !self.is_current_cell_zero() {
                    self.ip = loop_start_ip;
                }
            }
        }
        self.ip += 1;
        Ok(())
    }

    fn load_value(&mut self) -> u8 {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp]
    }

    fn store_value(&mut self, value: u8) {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp] = value;
    }

    fn read_value(&self, mut input: &mut std::io::Read) -> Result<u8, String> {
        let mut buf = [0u8];
        match input.read_exact(&mut buf) {
            Err(err) => match err.kind() {
                // There are multiple ways of dealing with EOF. We have chosen
                // to return 0.
                std::io::ErrorKind::UnexpectedEof => Ok(0),
                _ => Err(format!("reading of a value failed (reason: {:?})", err.kind())),
            },
            Ok(_) => Ok(buf[0]),
        }
    }

    fn write_value(&self, mut output: &mut std::io::Write, value: u8) -> Result<(), String> {
        match output.write(&[value]) {
            Err(err) => Err(
                format!("writing of a value failed (reason: {})", err)
            ),
            Ok(_) => Ok(()),
        }
    }

    fn is_current_cell_zero(&mut self) -> bool {
        self.load_value() == 0
    }

    fn ensure_current_cell_is_accessible(&mut self) {
        let cell_count = self.data.len();
        if self.dp >= cell_count {
            for _ in 0..(self.dp - cell_count + 1) {
                self.data.push(0);
            }
        }
    }
}

///
/// Runs the given program.
///
/// # Arguments
///
/// * `prog` - Program to be run.
/// * `input` - Input for the program.
/// * `output` - Output for the program.
///
pub fn run(prog: Vec<Instruction>,
           mut input: &mut std::io::Read,
           mut output: &mut std::io::Write)
           -> Result<(), String> {
    let mut runner = Runner::new();
    runner.run(prog, &mut input, &mut output)
}

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

    fn run_and_get_output(prog: Vec<Instruction>,
                          input: &[u8])
                          -> Result<Vec<u8>, String> {
        let mut output = Vec::new();
        match {
            let mut input_reader = std::io::BufReader::new(input.as_ref());
            let mut output_writer = std::io::BufWriter::new(&mut output);
            run(prog, &mut input_reader, &mut output_writer)
        } {
            Ok(_) => Ok(output),
            Err(err) => Err(err),
        }
    }

    fn assert_run_writes_correct_output(prog: Vec<Instruction>,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let output = run_and_get_output(prog, input).unwrap();
        assert_eq!(output, expected_output);
    }

    fn assert_run_returns_error(prog: Vec<Instruction>,
                         input: &[u8]) {
        let result = run_and_get_output(prog, input);
        assert!(result.is_err());
    }

    #[test]
    fn test_run_does_nothing_when_program_has_no_instructions() {
        assert_run_writes_correct_output(
            vec![],
            &[],
            &[]
        );
    }

    #[test]
    fn test_run_can_read_from_input_and_write_to_output() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[1],
            &[1]
        );
    }

    #[test]
    fn test_read_stores_zero_when_at_end_of_file() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[],
            &[0]
        );
    }

    #[test]
    fn test_run_can_increment_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Inc,
                Instruction::Write,
            ],
            &[1],
            &[2]
        );
    }

    #[test]
    fn test_run_can_decrement_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Dec,
                Instruction::Write,
            ],
            &[1],
            &[0]
        );
    }

    #[test]
    fn test_run_can_move_between_cells() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Next,
                Instruction::Read,
                Instruction::Next,
                Instruction::Prev,
                Instruction::Write,
                Instruction::Prev,
                Instruction::Write,
            ],
            &[1, 2],
            &[2, 1]
        );
    }

    #[test]
    fn test_run_can_loop() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::LoopStart(6),
                Instruction::Dec,
                Instruction::Next,
                Instruction::Inc,
                Instruction::Prev,
                Instruction::LoopEnd(1),
                Instruction::Write,
                Instruction::Next,
                Instruction::Write
            ],
            &[2],
            &[0, 2]
        );
    }

    #[test]
    fn test_copies_input_to_output() {
        assert_run_writes_correct_output(
            vec![
                // Read the whole input:
                Instruction::Next,
                Instruction::Inc,
                Instruction::LoopStart(5),
                Instruction::Next,
                Instruction::Read,
                Instruction::LoopEnd(2),
                // Rewind to the beginning:
                Instruction::Prev,
                Instruction::LoopStart(9),
                Instruction::Prev,
                Instruction::LoopEnd(7),
                // Write the whole input:
                Instruction::Next,
                Instruction::Next,
                Instruction::LoopStart(15),
                Instruction::Write,
                Instruction::Next,
                Instruction::LoopEnd(12)
            ],
            &[4, 3, 1, 5],
            &[4, 3, 1, 5]
        );
    }
}
<commit_msg>Ensure that the data pointer can be decremented before decrementing it.<commit_after>//! Running of programs.

use parser::Instruction;
use std;

///
/// A runner of programs.
///
#[derive(Default)]
pub struct Runner {
    /// Program to be run.
    prog: Vec<Instruction>,
    /// A potentially infinite number of data cells.
    data: Vec<u8>,
    /// Instruction pointer (index).
    ip: usize,
    /// Data-cell pointer (index).
    dp: usize,
}

impl Runner {
    ///
    /// Constructs a new runner.
    ///
    pub fn new() -> Self {
        Runner::default()
    }

    ///
    /// Runs the given program.
    ///
    /// # Arguments
    ///
    /// * `prog` - Program to be run.
    /// * `input` - Input for the program.
    /// * `output` - Output for the program.
    ///
    pub fn run(&mut self,
               prog: Vec<Instruction>,
               mut input: &mut std::io::Read,
               mut output: &mut std::io::Write)
               -> Result<(), String> {
        self.prog = prog;
        self.data.clear();
        self.ip = 0;
        self.dp = 0;

        while !self.is_prog_end() {
            try!(self.run_instruction(&mut input, &mut output));
        }

        Ok(())
    }

    fn is_prog_end(&self) -> bool {
        self.ip >= self.prog.len()
    }

    fn run_instruction(&mut self,
                       mut input: &mut std::io::Read,
                       mut output: &mut std::io::Write)
                       -> Result<(), String> {
        match self.prog[self.ip] {
            Instruction::Next => {
                self.dp += 1;
            }
            Instruction::Prev => {
                try!(self.ensure_can_decrement_dp_by_one());
                self.dp -= 1;
            }
            Instruction::Inc => {
                let value = self.load_value();
                self.store_value(value.wrapping_add(1));
            }
            Instruction::Dec => {
                let value = self.load_value();
                self.store_value(value.wrapping_sub(1));
            }
            Instruction::Read => {
                let value = try!(self.read_value(&mut input));
                self.store_value(value);
            }
            Instruction::Write => {
                let value = self.load_value();
                try!(self.write_value(&mut output, value));
            }
            Instruction::LoopStart(loop_end_ip) => {
                if self.is_current_cell_zero() {
                    self.ip = loop_end_ip;
                }
            }
            Instruction::LoopEnd(loop_start_ip) => {
                if !self.is_current_cell_zero() {
                    self.ip = loop_start_ip;
                }
            }
        }
        self.ip += 1;
        Ok(())
    }

    fn load_value(&mut self) -> u8 {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp]
    }

    fn store_value(&mut self, value: u8) {
        self.ensure_current_cell_is_accessible();
        self.data[self.dp] = value;
    }

    fn read_value(&self, mut input: &mut std::io::Read) -> Result<u8, String> {
        let mut buf = [0u8];
        match input.read_exact(&mut buf) {
            Err(err) => match err.kind() {
                // There are multiple ways of dealing with EOF. We have chosen
                // to return 0.
                std::io::ErrorKind::UnexpectedEof => Ok(0),
                _ => Err(format!("reading of a value failed (reason: {:?})", err.kind())),
            },
            Ok(_) => Ok(buf[0]),
        }
    }

    fn write_value(&self, mut output: &mut std::io::Write, value: u8) -> Result<(), String> {
        match output.write(&[value]) {
            Err(err) => Err(
                format!("writing of a value failed (reason: {})", err)
            ),
            Ok(_) => Ok(()),
        }
    }

    fn is_current_cell_zero(&mut self) -> bool {
        self.load_value() == 0
    }

    fn ensure_current_cell_is_accessible(&mut self) {
        let cell_count = self.data.len();
        if self.dp >= cell_count {
            for _ in 0..(self.dp - cell_count + 1) {
                self.data.push(0);
            }
        }
    }

    fn ensure_can_decrement_dp_by_one(&self) -> Result<(), String> {
        match self.dp {
            0 => Err("cannot decrement the data pointer because it is 0".to_string()),
            _ => Ok(()),
        }
    }
}

///
/// Runs the given program.
///
/// # Arguments
///
/// * `prog` - Program to be run.
/// * `input` - Input for the program.
/// * `output` - Output for the program.
///
pub fn run(prog: Vec<Instruction>,
           mut input: &mut std::io::Read,
           mut output: &mut std::io::Write)
           -> Result<(), String> {
    let mut runner = Runner::new();
    runner.run(prog, &mut input, &mut output)
}

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

    fn run_and_get_output(prog: Vec<Instruction>,
                          input: &[u8])
                          -> Result<Vec<u8>, String> {
        let mut output = Vec::new();
        match {
            let mut input_reader = std::io::BufReader::new(input.as_ref());
            let mut output_writer = std::io::BufWriter::new(&mut output);
            run(prog, &mut input_reader, &mut output_writer)
        } {
            Ok(_) => Ok(output),
            Err(err) => Err(err),
        }
    }

    fn assert_run_writes_correct_output(prog: Vec<Instruction>,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let output = run_and_get_output(prog, input).unwrap();
        assert_eq!(output, expected_output);
    }

    fn assert_run_returns_error(prog: Vec<Instruction>,
                         input: &[u8]) {
        let result = run_and_get_output(prog, input);
        assert!(result.is_err());
    }

    #[test]
    fn test_run_does_nothing_when_program_has_no_instructions() {
        assert_run_writes_correct_output(
            vec![],
            &[],
            &[]
        );
    }

    #[test]
    fn test_run_can_read_from_input_and_write_to_output() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[1],
            &[1]
        );
    }

    #[test]
    fn test_read_stores_zero_when_at_end_of_file() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Write
            ],
            &[],
            &[0]
        );
    }

    #[test]
    fn test_run_can_increment_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Inc,
                Instruction::Write,
            ],
            &[1],
            &[2]
        );
    }

    #[test]
    fn test_run_can_decrement_cell() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Dec,
                Instruction::Write,
            ],
            &[1],
            &[0]
        );
    }

    #[test]
    fn test_run_can_move_between_cells() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::Next,
                Instruction::Read,
                Instruction::Next,
                Instruction::Prev,
                Instruction::Write,
                Instruction::Prev,
                Instruction::Write,
            ],
            &[1, 2],
            &[2, 1]
        );
    }

    #[test]
    fn test_run_can_loop() {
        assert_run_writes_correct_output(
            vec![
                Instruction::Read,
                Instruction::LoopStart(6),
                Instruction::Dec,
                Instruction::Next,
                Instruction::Inc,
                Instruction::Prev,
                Instruction::LoopEnd(1),
                Instruction::Write,
                Instruction::Next,
                Instruction::Write
            ],
            &[2],
            &[0, 2]
        );
    }

    #[test]
    fn test_copies_input_to_output() {
        assert_run_writes_correct_output(
            vec![
                // Read the whole input:
                Instruction::Next,
                Instruction::Inc,
                Instruction::LoopStart(5),
                Instruction::Next,
                Instruction::Read,
                Instruction::LoopEnd(2),
                // Rewind to the beginning:
                Instruction::Prev,
                Instruction::LoopStart(9),
                Instruction::Prev,
                Instruction::LoopEnd(7),
                // Write the whole input:
                Instruction::Next,
                Instruction::Next,
                Instruction::LoopStart(15),
                Instruction::Write,
                Instruction::Next,
                Instruction::LoopEnd(12)
            ],
            &[4, 3, 1, 5],
            &[4, 3, 1, 5]
        );
    }

    #[test]
    fn test_returns_error_when_underflowing_data_pointer() {
        assert_run_returns_error(vec![Instruction::Prev], &[]);
    }
}
<|endoftext|>


<commit_before>extern crate num;
extern crate bit_vec;

use std::env;
use std::fmt;
use std::io::prelude::*;
use std::fs::File;
use std::default::Default;
use std::rc::Rc;
use std::collections::HashMap;
use bit_vec::BitVec;
use num::bigint::BigUint;
use num::traits::{One, ToPrimitive};

#[derive(Clone, Debug)]
pub enum Noun {
    Cell(Rc<Noun>, Rc<Noun>),
    Atom(BigUint),
}

use Noun::*;

impl fmt::Display for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Atom(ref n) => return dot_separators(f, &n),
            &Cell(ref a, ref b) => {
                try!(write!(f, "[{} ", a));
                // List pretty-printer.
                let mut cur = b;
                loop {
                    match **cur {
                        Cell(ref a, ref b) => {
                            try!(write!(f, "{} ", a));
                            cur = &b;
                        }
                        Atom(ref n) => {
                            try!(dot_separators(f, &n));
                            return write!(f, "]");
                        }
                    }
                }
            }
        }

        fn dot_separators<T: fmt::Display>(f: &mut fmt::Formatter, item: &T) -> fmt::Result {
            let s = format!("{}", item);
            let phase = s.len() % 3;
            for (i, c) in s.chars().enumerate() {
                if i > 0 && i % 3 == phase {
                    try!(write!(f, "."));
                }
                try!(write!(f, "{}", c));
            }
            Ok(())
        }
    }
}

fn rub(bits: &BitVec, pos: usize) -> (usize, BigUint) {
    // Length of the prefix in bits is the count of initial zeroes before
    // the separator 1.

    let mut p = 0;

    // Assume the first bit is zero even if it isn't.
    let mut k = 1;
    p += 1;

    while !bits[pos + p] {
        k += 1;
        p += 1;
    }
    p += 1;

    // Read the prefix.
    let mut b = 0;
    if k > 1 {
        for i in 0..(k - 2) {
            if bits[pos + p] {
                b += 1 << i;
            }
            p += 1;
        }
        // Add the implicit top 1 to the prefix.
        b += 1 << (k - 2);
    }

    let mut q: BigUint = Default::default();
    for i in 0..b {
        if bits[pos + p] {
            q = q + (BigUint::one() << i);
        }
        p += 1;
    }
    (p, q)
}

pub fn cue(bits: &BitVec) -> Rc<Noun> {
    return parse(0, bits, &mut HashMap::new()).1;

    fn parse(mut pos: usize, bits: &BitVec, dict: &mut HashMap<usize, Rc<Noun>>) -> (usize, Rc<Noun>) {
        let key = pos;
        if bits[pos] {
            pos += 1;
            if !bits[pos] {
                // 10: encode a pair.
                pos += 1;
                let (p, left) = parse(pos, bits, dict);
                pos = p;
                let (p, right) = parse(pos, bits, dict);
                pos = p;

                let ret = Rc::new(Noun::Cell(left, right));
                dict.insert(key, ret.clone());
                (pos, ret)
            } else {
                // 11: Repeat element
                // Read the index in bitstream where the value was first
                // encountered.
                let (p, q) = rub(&bits, pos);
                pos += p;
                let key = q.to_usize().unwrap();
                (pos, dict.get(&key).unwrap().clone())
            }
        } else {
            // Atom.
            let (p, q) = rub(&bits, pos);
            pos += p;
            let ret = Rc::new(Noun::Atom(q));
            dict.insert(key, ret.clone());
            (pos, ret)
        }
    }
}

fn main() {
    let mut file = File::open(env::args().nth(1).expect("Usage scan [urbit.pill]")).unwrap();

    let mut buf = Vec::new();
    file.read_to_end(&mut buf).unwrap();

    // Guarantee that the buffer is made of 32-bit chunks.
    while buf.len() % 4 != 0 {
        buf.push(0);
    }

    // Reverse bits of each byte to be little-endian all the way.
    for i in 0..buf.len() {
        let b = &mut buf[i];
        *b = (*b & 0xF0) >> 4 | (*b & 0x0F) << 4;
        *b = (*b & 0xCC) >> 2 | (*b & 0x33) << 2;
        *b = (*b & 0xAA) >> 1 | (*b & 0x55) << 1;
    }

    let bits = BitVec::from_bytes(&buf);

    let cell = cue(&bits);

    println!("{}", cell);
}
<commit_msg>Pill unpacker counts atoms<commit_after>extern crate num;
extern crate bit_vec;

use std::env;
use std::fmt;
use std::io::prelude::*;
use std::fs::File;
use std::default::Default;
use std::rc::Rc;
use std::collections::HashMap;
use bit_vec::BitVec;
use num::bigint::BigUint;
use num::traits::{One, ToPrimitive};

#[derive(Clone, Debug)]
pub enum Noun {
    Cell(Rc<Noun>, Rc<Noun>),
    Atom(BigUint),
}

use Noun::*;

impl fmt::Display for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Atom(ref n) => return dot_separators(f, &n),
            &Cell(ref a, ref b) => {
                try!(write!(f, "[{} ", a));
                // List pretty-printer.
                let mut cur = b;
                loop {
                    match **cur {
                        Cell(ref a, ref b) => {
                            try!(write!(f, "{} ", a));
                            cur = &b;
                        }
                        Atom(ref n) => {
                            try!(dot_separators(f, &n));
                            return write!(f, "]");
                        }
                    }
                }
            }
        }

        fn dot_separators<T: fmt::Display>(f: &mut fmt::Formatter, item: &T) -> fmt::Result {
            let s = format!("{}", item);
            let phase = s.len() % 3;
            for (i, c) in s.chars().enumerate() {
                if i > 0 && i % 3 == phase {
                    try!(write!(f, "."));
                }
                try!(write!(f, "{}", c));
            }
            Ok(())
        }
    }
}

fn rub(bits: &BitVec, pos: usize) -> (usize, BigUint) {
    // Length of the prefix in bits is the count of initial zeroes before
    // the separator 1.

    let mut p = 0;

    // Assume the first bit is zero even if it isn't.
    let mut k = 1;
    p += 1;

    while !bits[pos + p] {
        k += 1;
        p += 1;
    }
    p += 1;

    // Read the prefix.
    let mut b = 0;
    if k > 1 {
        for i in 0..(k - 2) {
            if bits[pos + p] {
                b += 1 << i;
            }
            p += 1;
        }
        // Add the implicit top 1 to the prefix.
        b += 1 << (k - 2);
    }

    let mut q: BigUint = Default::default();
    for i in 0..b {
        if bits[pos + p] {
            q = q + (BigUint::one() << i);
        }
        p += 1;
    }
    (p, q)
}

pub fn cue(bits: &BitVec) -> (Rc<Noun>, u64) {
    let (_, noun, size) = parse(0, bits, &mut HashMap::new());
    return (noun, size);

    fn parse(mut pos: usize, bits: &BitVec, dict: &mut HashMap<usize, (Rc<Noun>, u64)>) -> (usize, Rc<Noun>, u64) {
        let key = pos;
        if bits[pos] {
            pos += 1;
            if !bits[pos] {
                // 10: encode a pair.
                pos += 1;
                let (p, left, s1) = parse(pos, bits, dict);
                pos = p;
                let (p, right, s2) = parse(pos, bits, dict);
                pos = p;

                let ret = Rc::new(Noun::Cell(left, right));
                let size = s1 + s2;
                dict.insert(key, (ret.clone(), size));
                (pos, ret, size)
            } else {
                // 11: Repeat element
                // Read the index in bitstream where the value was first
                // encountered.
                let (p, q) = rub(&bits, pos);
                pos += p;
                let key = q.to_usize().unwrap();
                let (noun, size) = dict.get(&key).unwrap().clone();
                (pos, noun, size)
            }
        } else {
            // Atom.
            let (p, q) = rub(&bits, pos);
            pos += p;
            let ret = Rc::new(Noun::Atom(q));
            dict.insert(key, (ret.clone(), 1));
            (pos, ret, 1)
        }
    }
}

fn main() {
    let mut file = File::open(env::args().nth(1).expect("Usage scan [urbit.pill]")).unwrap();

    let mut buf = Vec::new();
    file.read_to_end(&mut buf).unwrap();

    // Guarantee that the buffer is made of 32-bit chunks.
    while buf.len() % 4 != 0 {
        buf.push(0);
    }

    // Reverse bits of each byte to be little-endian all the way.
    for i in 0..buf.len() {
        let b = &mut buf[i];
        *b = (*b & 0xF0) >> 4 | (*b & 0x0F) << 4;
        *b = (*b & 0xCC) >> 2 | (*b & 0x33) << 2;
        *b = (*b & 0xAA) >> 1 | (*b & 0x55) << 1;
    }

    let bits = BitVec::from_bytes(&buf);

    let (_cell, size) = cue(&bits);

    println!("Pillfile {} consists of {} atoms", env::args().nth(1).unwrap(), size);
}
<|endoftext|>