<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) => Err(format!("{}", err)),
            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!("{}", 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 assert_run_writes_correct_output(prog: Vec<Instruction>,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let mut output = Vec::new();
        {
            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).unwrap();
        }

        assert_eq!(output, expected_output);
    }

    #[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_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]
        );
    }
}
<commit_msg>Add more meaningful error messages to read_value() and write_value().<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 => {
                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) => Err(
                format!("reading of a value failed (reason: {})", err)
            ),
            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 assert_run_writes_correct_output(prog: Vec<Instruction>,
                                        input: &[u8],
                                        expected_output: &[u8]) {
        let mut output = Vec::new();
        {
            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).unwrap();
        }

        assert_eq!(output, expected_output);
    }

    #[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_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]
        );
    }
}
<|endoftext|>


<commit_before>//! Implements the [`FrameRunner`](./runner/struct.FrameRunner.html) struct for managing frame simulations.
use clock::{GameTime, GameClock};

use framerate::counter::FrameCount;
use step::TimeStep;

/// A helper type for running frame simulations with a frame counter.
///
/// `FrameRunner` combines a [`GameClock`](../clock/struct.GameTime.html)
/// and a [`FrameCount`](../framerate/counter/struct.FrameCounter.html) object,
/// tracking each frame as well as a framerate. `FrameRunner` provides
/// a `tick` method like `GameClock`, and updates both the `GameClock` and
/// `FrameCount` objects contained.
#[derive(Debug)]
pub struct FrameRunner<C: FrameCount, T: TimeStep> {
    clock: GameClock,
    counter: C,
    time_progress: T,
}

impl<C, T> FrameRunner<C, T>
where
    C: FrameCount,
    T: TimeStep,
{
    /// Construct a new `FrameRunner` from a `GameClock` and a `FrameCount`.
    pub fn new(clock: GameClock, counter: C, time_progress: T) -> FrameRunner<C, T> {
        FrameRunner {
            clock,
            counter,
            time_progress,
        }
    }

    /// Get a reference to the contained `GameClock`.
    pub fn clock(&self) -> &GameClock {
        &self.clock
    }
    /// Get a mutable reference to the contained `GameClock`.
    pub fn clock_mut(&mut self) -> &mut GameClock {
        &mut self.clock
    }
    /// Get a reference to the contained `FrameCount`.
    pub fn counter(&self) -> &C {
        &self.counter
    }
    /// Get a mutable reference to the contained `FrameCount`.
    pub fn counter_mut(&mut self) -> &mut C {
        &mut self.counter
    }
    /// Mark the start of a new frame, updating time and frame rate statistics.
    ///
    /// The `GameTime` for the new frame is returned, with the same properties as that
    /// returned from [`GameClock::tick`](../clock/struct.GameClock.html#method.tick).
    pub fn tick(&mut self) -> GameTime {
        let time = self.clock.tick(&mut self.time_progress);
        time
    }

    /// Perform one frame of the simulation using `frame_fn`.
    ///
    /// The closure is passed the `GameTime` for the frame by calling `tick`
    /// and will call
    /// [`GameClock::sleep_remaining`](../clock/struct.GameClock.html#method.sleep_remaining)
    /// after the closure has ended.
    pub fn do_frame<F>(&mut self, frame_fn: F)
    where
        F: FnOnce(GameTime),
    {
        let time = self.tick();
        frame_fn(time);
        self.clock.sleep_remaining(&self.counter);
    }
}
<commit_msg>Added `tick_with_wall_time` to FrameRunner.<commit_after>//! Implements the [`FrameRunner`](./runner/struct.FrameRunner.html) struct for managing frame simulations.
use chrono;

use clock::{GameTime, GameClock};
use framerate::counter::FrameCount;
use step::TimeStep;

/// A helper type for running frame simulations with a frame counter.
///
/// `FrameRunner` combines a [`GameClock`](../clock/struct.GameTime.html)
/// and a [`FrameCount`](../framerate/counter/struct.FrameCounter.html) object,
/// tracking each frame as well as a framerate. `FrameRunner` provides
/// a `tick` method like `GameClock`, and updates both the `GameClock` and
/// `FrameCount` objects contained.
#[derive(Debug)]
pub struct FrameRunner<C: FrameCount, T: TimeStep> {
    clock: GameClock,
    counter: C,
    time_progress: T,
}

impl<C, T> FrameRunner<C, T>
where
    C: FrameCount,
    T: TimeStep,
{
    /// Construct a new `FrameRunner` from a `GameClock` and a `FrameCount`.
    pub fn new(clock: GameClock, counter: C, time_progress: T) -> FrameRunner<C, T> {
        FrameRunner {
            clock,
            counter,
            time_progress,
        }
    }

    /// Get a reference to the contained `GameClock`.
    pub fn clock(&self) -> &GameClock {
        &self.clock
    }
    /// Get a mutable reference to the contained `GameClock`.
    pub fn clock_mut(&mut self) -> &mut GameClock {
        &mut self.clock
    }
    /// Get a reference to the contained `FrameCount`.
    pub fn counter(&self) -> &C {
        &self.counter
    }
    /// Get a mutable reference to the contained `FrameCount`.
    pub fn counter_mut(&mut self) -> &mut C {
        &mut self.counter
    }
    /// Mark the start of a new frame, updating time and frame rate statistics.
    ///
    /// The `GameTime` for the new frame is returned, with the same properties as that
    /// returned from [`GameClock::tick`](../clock/struct.GameClock.html#method.tick).
    pub fn tick(&mut self) -> GameTime {
        let time = self.clock.tick(&mut self.time_progress);
        time
    }

    /// Mark the start of a new frame with a specified wall time, updating time statistics.
    ///
    /// This function is like `tick` but allows for the start time for the
    /// frame to be specified.
    pub fn tick_with_wall_time(
        &mut self,
        frame_start: chrono::DateTime<chrono::Local>,
    ) -> GameTime {
        self.clock.tick_with_wall_time(
            &mut self.time_progress,
            frame_start,
        )
    }

    /// Perform one frame of the simulation using `frame_fn`.
    ///
    /// The closure is passed the `GameTime` for the frame by calling `tick`
    /// and will call
    /// [`GameClock::sleep_remaining`](../clock/struct.GameClock.html#method.sleep_remaining)
    /// after the closure has ended.
    pub fn do_frame<F>(&mut self, frame_fn: F)
    where
        F: FnOnce(GameTime),
    {
        let time = self.tick();
        frame_fn(time);
        self.clock.sleep_remaining(&self.counter);
    }
}
<|endoftext|>


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

use std::io::Error;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
use std::sync::Arc;

use slog::{info, o, Logger};

use crate::config::{Config, ConnectionConfig};

/// Server is the UDP server main implementation
pub struct Server {
    log: Logger,
}

impl Server {
    pub fn new(base: Logger) -> Self {
        let log = base.new(o!("source" => "server::Server"));
        return Server { log };
    }

    /// start the async processing of UDP packets
    pub async fn run(self, config: Arc<Config>) -> Result<(), Error> {
        let Server { log } = self;
        info!(log, "Starting on port {}", config.local.port);

        let _socket = bind(&config).await?;

        match &config.connections {
            ConnectionConfig::Sender { address, .. } => {
                info!(log, "Sender configuration"; "address" => address)
            }
            ConnectionConfig::Receiver { endpoints } => {
                info!(log, "Receiver configuration"; "endpoints" => endpoints.len())
            }
        };

        return Ok(());
    }
}

/// bind binds to the local socket provided in config.local.port
async fn bind(config: &Config) -> Result<UdpSocket, Error> {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), config.local.port);
    return UdpSocket::bind(addr);
}
<commit_msg>Think I bound a socket<commit_after>/*
 * Copyright 2020 Google LLC All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;

use slog::{info, o, Logger};
use tokio::io::Result;
use tokio::net::UdpSocket;

use crate::config::{Config, ConnectionConfig};

/// Server is the UDP server main implementation
pub struct Server {
    log: Logger,
}

impl Server {
    pub fn new(base: Logger) -> Self {
        let log = base.new(o!("source" => "server::Server"));
        return Server { log };
    }

    /// start the async processing of UDP packets
    pub async fn run(self, config: Arc<Config>) -> Result<()> {
        let Server { log } = self;
        info!(log, "Starting on port {}", config.local.port);

        let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), config.local.port);
        UdpSocket::bind(addr).await?;

        match &config.connections {
            ConnectionConfig::Sender { address, .. } => {
                info!(log, "Sender configuration"; "address" => address)
            }
            ConnectionConfig::Receiver { endpoints } => {
                info!(log, "Receiver configuration"; "endpoints" => endpoints.len())
            }
        };

        return Ok(());
    }
}
<|endoftext|>


<commit_before><commit_msg>Make indentation consistent.<commit_after><|endoftext|>


<commit_before>use luminance::{FragmentShader, GeometryShader, StageError, ShaderTypeable,
                TessellationControlShader, TessellationEvaluationShader, VertexShader};
use luminance_gl::gl33::{ProgramProxy, Stage};
use std::fs;
use std::io::Read;
use std::path::Path;

pub use luminance::{ProgramError, Uniformable, UniformUpdate};
pub use luminance::shader::program::UniformWarning;
pub use luminance_gl::gl33::{self, Uniform};
pub use luminance_gl::gl33::token::*;

#[derive(Debug)]
pub enum ShaderError {
  StageError(StageError),
  ProgramError(ProgramError)
}

fn compile_stages(tess_src: Option<(&str, &str)>, vs_src: &str, gs_src: Option<&str>, fs_src: &str) -> Result<(Option<(Stage<TessellationControlShader>, Stage<TessellationEvaluationShader>)>, Stage<VertexShader>, Option<Stage<GeometryShader>>, Stage<FragmentShader>), StageError> {
  let tess = match tess_src {
    None => None,
    Some((tcs_src, tes_src)) => {
      let tcs = try!(Stage::new(tcs_src));
      let tes = try!(Stage::new(tes_src));
      Some((tcs, tes))
    }
  };
  let vs = try!(Stage::new(vs_src));
  let gs = match gs_src {
    None => None,
    Some(gs_src) => {
      let gs = try!(Stage::new(gs_src));
      Some(gs)
    }
  };
  let fs = try!(Stage::new(fs_src));

  Ok((tess, vs, gs, fs))
}

pub fn new_program<GetUni, T>(tess_src: Option<(&str, &str)>, vs_src: &str, gs_src: Option<&str>, fs_src: &str, get_uni: &GetUni) -> Result<gl33::Program<T>, ProgramError> where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> {
  let stages = compile_stages(tess_src, vs_src, gs_src, fs_src);

  match stages {
    Ok((tess, vs, gs, fs)) => {
      if let Some((tcs, tes)) = tess {
        if let Some(gs) = gs {
          gl33::Program::new(Some((&tcs, &tes)), &vs, Some(&gs), &fs, get_uni)
        } else {
          gl33::Program::new(Some((&tcs, &tes)), &vs, None, &fs, get_uni)
        }
      } else if let Some(gs) = gs {
        gl33::Program::new(None, &vs, Some(&gs), &fs, get_uni)
      } else {
        gl33::Program::new(None, &vs, None, &fs, get_uni)
      }
    },
    Err(stage_error) => {
      Err(ProgramError::LinkFailed(format!("{:?}", stage_error)))
    }
  }
}

pub fn new_program_from_disk<P, GetUni, T>(tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: &GetUni) -> Result<gl33::Program<T>, ProgramError>
      where P: AsRef<Path>,
            GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> {
  // load vertex and fragment shaders first
  let vs = try!(read_stage(vs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
  let fs = try!(read_stage(fs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));

  match (tess_path, gs_path) {
    (None, None) => { // no tessellation nor geometry
      gl33::Program::new(None, &vs, None, &fs, get_uni)
    },
    (Some((tcs_path, tes_path)), None) => { // tessellation without geometry
      let tcs = try!(read_stage(tcs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let tes = try!(read_stage(tes_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(Some((&tcs, &tes)), &vs, None, &fs, get_uni)
    },
    (None, Some(gs_path)) => { // geometry without tessellation
      let gs = try!(read_stage(gs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(None, &vs, Some(&gs), &fs, get_uni)
    },
    (Some((tcs_path, tes_path)), Some(gs_path)) => { // tessellation and geometry
      let tcs = try!(read_stage(tcs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let tes = try!(read_stage(tes_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let gs = try!(read_stage(gs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(Some((&tcs, &tes)), &vs, Some(&gs), &fs, get_uni)
    }
  }
}

pub fn read_stage<P, T>(path: P) -> Result<Stage<T>, StageError> where P: AsRef<Path>, T: ShaderTypeable {
  let path = path.as_ref();

  info!("loading {:?} stage: \x1b[35m{:?}", T::shader_type(), path);

  let fh = fs::File::open(path);

  match fh {
    Err(e) => {
      Err(StageError::CompilationFailed(T::shader_type(), format!("{:?}", e)))
    },
    Ok(mut fh) => {
      let mut stage_src = String::new();
      let _ = fh.read_to_string(&mut stage_src);

      Stage::new(stage_src.chars().as_str())
    }
  }
}

#[cfg(feature = "hot-resource")]
mod hot {
  use super::*;

  use luminance_gl::gl33::ProgramProxy;
  use resource::ResourceManager;
  use std::ops::Deref;
  use std::path::{Path, PathBuf};
  use std::sync::mpsc;

  pub struct Program<T> {
    rx: mpsc::Receiver<()>,
    program: gl33::Program<T>,
    get_uni: Box<Fn(ProgramProxy) -> Result<T, ProgramError>>,
    vs_path: PathBuf,
    fs_path: PathBuf,
    tess_path: Option<(PathBuf, PathBuf)>,
    gs_path: Option<PathBuf>
  }

  impl<T> Program<T> {
    pub fn load<GetUni, P>(manager: &mut ResourceManager, tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: GetUni) -> Result<Self, ProgramError>
        where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> + 'static,
              P: AsRef<Path> {
      let vs_path = vs_path.as_ref();
      let fs_path = fs_path.as_ref();
      let tess_path = tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_ref(), tes.as_ref()));
      let gs_path = gs_path.as_ref().map(|gs| gs.as_ref());

      let program = try!(new_program_from_disk(tess_path, vs_path, gs_path, fs_path, &get_uni));

      let (sx, rx) = mpsc::channel();
      manager.monitor(vs_path, sx.clone());
      manager.monitor(fs_path, sx.clone());

      if let Some((tcs, tes)) = tess_path {
        manager.monitor(tcs, sx.clone());
        manager.monitor(tes, sx.clone());
      }

      if let Some(gs) = gs_path {
        manager.monitor(gs, sx.clone());
      }

      Ok(Program {
        rx: rx,
        program: program,
        get_uni: Box::new(get_uni),
        vs_path: vs_path.to_path_buf(),
        fs_path: fs_path.to_path_buf(),
        tess_path: tess_path.map(|(tcs, tes)| (tcs.to_path_buf(), tes.to_path_buf())),
        gs_path: gs_path.map(|gs| gs.to_path_buf()),
      })
    }

    fn reload(&mut self) {
      let vs = self.vs_path.as_path();
      let fs = self.fs_path.as_path();
      let tess = self.tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_path(), tes.as_path()));
      let gs = self.gs_path.as_ref().map(|gs| gs.as_path());

      let program = new_program_from_disk(tess, vs, gs, fs, &self.get_uni.as_ref());

      match program {
        Ok(program) => {
          self.program = program;
          info!("reloaded shader program");
        },
        Err(e) => {
          err!("reloading program has failed: {:?}", e);
        }
      }
    }

    pub fn sync(&mut self) {
      if self.rx.try_recv().is_ok() {
        self.reload();
      }
    }
  }

  impl<'a, T> Deref for Program<T> {
    type Target = gl33::Program<T>;

    fn deref(&self) -> &Self::Target {
      &self.program
    }
  }
}

#[cfg(not(feature = "hot-resource"))]
mod cold {
  use super::*;

  use luminance_gl::gl33::ProgramProxy;
  use resource::ResourceManager;
  use std::ops::Deref;
  use std::path::Path;

  pub struct Program<T>(gl33::Program<T>);

  impl<T> Program<T> {
    pub fn load<GetUni, P>(_: &mut ResourceManager, tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: GetUni) -> Result<Program<T>, ProgramError>
        where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> + 'static,
              P: AsRef<Path> {
      let vs_path = vs_path.as_ref();
      let fs_path = fs_path.as_ref();
      let tess_path = tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_ref(), tes.as_ref()));
      let gs_path = gs_path.as_ref().map(|gs| gs.as_ref());

      let program = try!(new_program_from_disk(tess_path, vs_path, gs_path, fs_path, &get_uni));

      Ok(Program(program))
    }

    pub fn sync(&mut self) {}
  }

  impl<'a, T> Deref for Program<T> {
    type Target = gl33::Program<T>;

    fn deref(&self) -> &Self::Target {
      &self.0
    }
  }
}

#[cfg(feature = "hot-resource")]
pub use self::hot::*;
#[cfg(not(feature = "hot-resource"))]
pub use self::cold::*;

/// A helper function used to make uniforms optionable. If there’s a warning, it’s printed out.
pub fn opt_uni<T>(uni: (Uniform<T>, Option<UniformWarning>)) -> Uniform<T> where T: Uniformable<GL33> {
  if let Some(warning) = uni.1 {
    warn!("{:?}", warning);
  }

  uni.0
}
<commit_msg>Fixed shader hot reloading sync.<commit_after>use luminance::{FragmentShader, GeometryShader, StageError, ShaderTypeable,
                TessellationControlShader, TessellationEvaluationShader, VertexShader};
use luminance_gl::gl33::{ProgramProxy, Stage};
use std::fs;
use std::io::Read;
use std::path::Path;

pub use luminance::{ProgramError, Uniformable, UniformUpdate};
pub use luminance::shader::program::UniformWarning;
pub use luminance_gl::gl33::{self, Uniform};
pub use luminance_gl::gl33::token::*;

#[derive(Debug)]
pub enum ShaderError {
  StageError(StageError),
  ProgramError(ProgramError)
}

fn compile_stages(tess_src: Option<(&str, &str)>, vs_src: &str, gs_src: Option<&str>, fs_src: &str) -> Result<(Option<(Stage<TessellationControlShader>, Stage<TessellationEvaluationShader>)>, Stage<VertexShader>, Option<Stage<GeometryShader>>, Stage<FragmentShader>), StageError> {
  let tess = match tess_src {
    None => None,
    Some((tcs_src, tes_src)) => {
      let tcs = try!(Stage::new(tcs_src));
      let tes = try!(Stage::new(tes_src));
      Some((tcs, tes))
    }
  };
  let vs = try!(Stage::new(vs_src));
  let gs = match gs_src {
    None => None,
    Some(gs_src) => {
      let gs = try!(Stage::new(gs_src));
      Some(gs)
    }
  };
  let fs = try!(Stage::new(fs_src));

  Ok((tess, vs, gs, fs))
}

pub fn new_program<GetUni, T>(tess_src: Option<(&str, &str)>, vs_src: &str, gs_src: Option<&str>, fs_src: &str, get_uni: &GetUni) -> Result<gl33::Program<T>, ProgramError> where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> {
  let stages = compile_stages(tess_src, vs_src, gs_src, fs_src);

  match stages {
    Ok((tess, vs, gs, fs)) => {
      if let Some((tcs, tes)) = tess {
        if let Some(gs) = gs {
          gl33::Program::new(Some((&tcs, &tes)), &vs, Some(&gs), &fs, get_uni)
        } else {
          gl33::Program::new(Some((&tcs, &tes)), &vs, None, &fs, get_uni)
        }
      } else if let Some(gs) = gs {
        gl33::Program::new(None, &vs, Some(&gs), &fs, get_uni)
      } else {
        gl33::Program::new(None, &vs, None, &fs, get_uni)
      }
    },
    Err(stage_error) => {
      Err(ProgramError::LinkFailed(format!("{:?}", stage_error)))
    }
  }
}

pub fn new_program_from_disk<P, GetUni, T>(tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: &GetUni) -> Result<gl33::Program<T>, ProgramError>
      where P: AsRef<Path>,
            GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> {
  // load vertex and fragment shaders first
  let vs = try!(read_stage(vs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
  let fs = try!(read_stage(fs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));

  match (tess_path, gs_path) {
    (None, None) => { // no tessellation nor geometry
      gl33::Program::new(None, &vs, None, &fs, get_uni)
    },
    (Some((tcs_path, tes_path)), None) => { // tessellation without geometry
      let tcs = try!(read_stage(tcs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let tes = try!(read_stage(tes_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(Some((&tcs, &tes)), &vs, None, &fs, get_uni)
    },
    (None, Some(gs_path)) => { // geometry without tessellation
      let gs = try!(read_stage(gs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(None, &vs, Some(&gs), &fs, get_uni)
    },
    (Some((tcs_path, tes_path)), Some(gs_path)) => { // tessellation and geometry
      let tcs = try!(read_stage(tcs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let tes = try!(read_stage(tes_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      let gs = try!(read_stage(gs_path).map_err(|e| ProgramError::LinkFailed(format!("{:?}", e))));
      gl33::Program::new(Some((&tcs, &tes)), &vs, Some(&gs), &fs, get_uni)
    }
  }
}

pub fn read_stage<P, T>(path: P) -> Result<Stage<T>, StageError> where P: AsRef<Path>, T: ShaderTypeable {
  let path = path.as_ref();

  info!("loading {:?} stage: \x1b[35m{:?}", T::shader_type(), path);

  let fh = fs::File::open(path);

  match fh {
    Err(e) => {
      Err(StageError::CompilationFailed(T::shader_type(), format!("{:?}", e)))
    },
    Ok(mut fh) => {
      let mut stage_src = String::new();
      let _ = fh.read_to_string(&mut stage_src);

      Stage::new(stage_src.chars().as_str())
    }
  }
}

#[cfg(feature = "hot-resource")]
mod hot {
  use super::*;

  use luminance_gl::gl33::ProgramProxy;
  use resource::ResourceManager;
  use std::ops::Deref;
  use std::path::{Path, PathBuf};
  use std::sync::mpsc;

  pub struct Program<T> {
    rx: mpsc::Receiver<()>,
    last_update_time: Option<f64>,
    program: gl33::Program<T>,
    get_uni: Box<Fn(ProgramProxy) -> Result<T, ProgramError>>,
    vs_path: PathBuf,
    fs_path: PathBuf,
    tess_path: Option<(PathBuf, PathBuf)>,
    gs_path: Option<PathBuf>
  }

  impl<T> Program<T> {
    pub fn load<GetUni, P>(manager: &mut ResourceManager, tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: GetUni) -> Result<Self, ProgramError>
        where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> + 'static,
              P: AsRef<Path> {
      let vs_path = vs_path.as_ref();
      let fs_path = fs_path.as_ref();
      let tess_path = tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_ref(), tes.as_ref()));
      let gs_path = gs_path.as_ref().map(|gs| gs.as_ref());

      let program = try!(new_program_from_disk(tess_path, vs_path, gs_path, fs_path, &get_uni));

      let (sx, rx) = mpsc::channel();
      manager.monitor(vs_path, sx.clone());
      manager.monitor(fs_path, sx.clone());

      if let Some((tcs, tes)) = tess_path {
        manager.monitor(tcs, sx.clone());
        manager.monitor(tes, sx.clone());
      }

      if let Some(gs) = gs_path {
        manager.monitor(gs, sx.clone());
      }

      Ok(Program {
        rx: rx,
        last_update_time: None,
        program: program,
        get_uni: Box::new(get_uni),
        vs_path: vs_path.to_path_buf(),
        fs_path: fs_path.to_path_buf(),
        tess_path: tess_path.map(|(tcs, tes)| (tcs.to_path_buf(), tes.to_path_buf())),
        gs_path: gs_path.map(|gs| gs.to_path_buf()),
      })
    }

    fn reload(&mut self) {
      let vs = self.vs_path.as_path();
      let fs = self.fs_path.as_path();
      let tess = self.tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_path(), tes.as_path()));
      let gs = self.gs_path.as_ref().map(|gs| gs.as_path());

      let program = new_program_from_disk(tess, vs, gs, fs, &self.get_uni.as_ref());

      match program {
        Ok(program) => {
          self.program = program;
          info!("reloaded shader program");
        },
        Err(e) => {
          err!("reloading program has failed: {:?}", e);
        }
      }
    }

    decl_sync_hot!();
  }

  impl<'a, T> Deref for Program<T> {
    type Target = gl33::Program<T>;

    fn deref(&self) -> &Self::Target {
      &self.program
    }
  }
}

#[cfg(not(feature = "hot-resource"))]
mod cold {
  use super::*;

  use luminance_gl::gl33::ProgramProxy;
  use resource::ResourceManager;
  use std::ops::Deref;
  use std::path::Path;

  pub struct Program<T>(gl33::Program<T>);

  impl<T> Program<T> {
    pub fn load<GetUni, P>(_: &mut ResourceManager, tess_path: Option<(P, P)>, vs_path: P, gs_path: Option<P>, fs_path: P, get_uni: GetUni) -> Result<Program<T>, ProgramError>
        where GetUni: Fn(ProgramProxy) -> Result<T, ProgramError> + 'static,
              P: AsRef<Path> {
      let vs_path = vs_path.as_ref();
      let fs_path = fs_path.as_ref();
      let tess_path = tess_path.as_ref().map(|&(ref tcs, ref tes)| (tcs.as_ref(), tes.as_ref()));
      let gs_path = gs_path.as_ref().map(|gs| gs.as_ref());

      let program = try!(new_program_from_disk(tess_path, vs_path, gs_path, fs_path, &get_uni));

      Ok(Program(program))
    }

    pub fn sync(&mut self) {}
  }

  impl<'a, T> Deref for Program<T> {
    type Target = gl33::Program<T>;

    fn deref(&self) -> &Self::Target {
      &self.0
    }
  }
}

#[cfg(feature = "hot-resource")]
pub use self::hot::*;
#[cfg(not(feature = "hot-resource"))]
pub use self::cold::*;

/// A helper function used to make uniforms optionable. If there’s a warning, it’s printed out.
pub fn opt_uni<T>(uni: (Uniform<T>, Option<UniformWarning>)) -> Uniform<T> where T: Uniformable<GL33> {
  if let Some(warning) = uni.1 {
    warn!("{:?}", warning);
  }

  uni.0
}
<|endoftext|>


<commit_before>use consumer::*;
use count::*;
use filter::*;
use flat_map::*;
use fold::*;
use group_by::*;
use inspect::*;
use map::*;
use max_by_key::*;
use max::*;
use min_by_key::*;
use min::*;
use skip_last::*;
use skip::*;
use subscription::*;
use sum::*;
use take_last::*;
use take::*;

pub trait Stream<T> {
    fn consume<C: Consumer<T>>(self, consumer: C);

    /// Count the number ofthe item received.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .count()
    ///     .into_vec();
    /// assert!(vec == [10], "vec = {:?}", vec);
    /// ```
    fn count(self) -> Count<Self, T>
        where Self: Sized
    {
        Count::new(self)
    }

    /// Creates a stream which uses a closure to determine if an element should be emitted.
    /// The closure must return true or false. `filter()` creates a stream which calls this closure on each element. If the closure returns true,
    /// then the element is returned. If the closure returns false, it will try again, and call the closure on the next element, seeing if it passes the test.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut vec = Vec::new();
    ///
    /// (0..5)
    ///     .to_stream()
    ///     .filter(|v| *v > 2)
    ///     .inspect(|v| vec.push(*v))
    ///     .subscribe();
    ///
    /// assert!(vec == &[3, 4], "vec = {:?}", vec);
    /// ```
    fn filter<F>(self, predicate: F) -> Filter<Self, F>
        where Self: Sized,
              F: FnMut(&mut T) -> bool
    {
        Filter::new(self, predicate)
    }

    /// Creates an stream that works like map, but flattens nested structure.
    /// The `map()` adapter is very useful, but only when the closure argument produces values.
    /// If it produces a stream instead, there's an extra layer of indirection. flat_map() will remove this extra layer on its own.    /// If it produces a stream instead, there's an extra layer of indirection. flat_map() will remove this extra layer on its own.
    ///
    /// Another way of thinking about flat_map(): map()'s closure returns one item for each element, and flat_map()'s closure returns a stream for each element.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..4i32)
    ///     .to_stream()
    ///     .flat_map(|v| Value::new(v + 10))
    ///     .into_vec();
    ///
    /// assert!(vec == [10, 11, 12, 13], "vec = {:?}", vec);
    /// ```
    fn flat_map<F, SO, O>(self, func: F) -> Flatmap<Self, F, T, SO, O>
        where Self: Sized,
              F: FnMut(T) -> SO,
              SO: Stream<O>
    {
        Flatmap::new(self, func)
    }

    /// A stream adaptor that applies a function, producing a single, final value.
    ///`fold()` takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element.
    /// It returns the value that the accumulator should have for the next iteration.
    ///
    /// The initial value is the value the accumulator will have on the first call.
    /// After applying this closure to every element of the iterator, `fold()` returns the accumulator.
    ///
    /// This operation is sometimes called 'reduce' or 'inject'.

    /// Folding is useful whenever you have a collection of something, and want to produce a single value from it.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut v = 0;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .fold(0, |o, i| o + i)
    ///     .inspect(|x| v = *x)
    ///     .subscribe();
    ///
    /// assert!(v == 45, "v = {}", v);
    /// ```
    fn fold<O, F>(self, initial: O, func: F) -> Fold<Self, T, F, O>
        where Self: Sized,
              F: FnMut(O, T) -> O
    {
        Fold::new(self, initial, func)
    }

    /// Group incoming values using a `key_selector`.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut vec = Vec::new();
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .group_by(|v| v % 2)
    ///     .inspect(|g| vec.push(g.get_key()))
    ///     .subscribe();
    ///
    /// // This gives 2 groups
    /// assert!(vec == vec!(0, 1), "vec = {:?}", vec);
    /// ```
    fn group_by<F: FnMut(&V) -> K, K, V>(self, key_selector: F) -> GroupBy<F, K, Self, V>
        where Self: Sized
    {
        GroupBy::new(self, key_selector)
    }

    /// Do something with each element of a stream, passing the value on.
    /// This is usefull to debug an item.
    fn inspect<F>(self, func: F) -> Inspect<Self, F>
        where F: FnMut(&mut T),
              Self: Sized
    {
        Inspect::new(self, func)
    }

    /// Takes a closure and creates a stream which calls that closure on each element.
    /// `map()` transforms one stream into another, by means of its argument: something that implements FnMut. It produces a new stream which calls this closure
    /// on each element of the original stream.
    ///
    /// If you are good at thinking in types, you can think of map() like this: If you have a stream that gives you elements of some type A, and you want a stream
    /// of some other type B, you can use `map()`, passing a closure that takes an A and returns a B.
    /// `map()` is conceptually similar to a for loop. However, as `map()` is lazy, it is best used when you're already working with other streams. If you're doing
    /// some sort of looping for a side effect, it's considered more idiomatic to use for than `map()`.`
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut value = 0;
    ///
    /// let vec = (0..4)
    ///     .to_stream()
    ///     .map(|v| v + 10)
    ///     .into_vec();
    /// assert!(vec == [10, 11, 12, 13], "vec = {:?}", vec);
    /// ```
    fn map<O, F>(self, func: F) -> Map<Self, F, T, O>
        where Self: Sized,
              F: FnMut(T) -> O
    {
        Map::new(self, func)
    }

    /// Returns the maximum element of a stream.
    /// Returns the lastest element if the comparison determines two elements to be equally maximum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 0;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .max()
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 9, "value = {:?}", value);
    /// ```
    fn max(self) -> Max<Self>
        where Self: Sized
    {
        Max::new(self)
    }

    /// Returns the element that gives the maximum value from the specified function.
    /// Returns the lastest element if the comparison determines two elements to be equally maximum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .max_by_key(|v| 10 - *v)
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 0, "value = {:?}", value);
    /// ```
    fn max_by_key<F: FnMut(&T) -> K, K>(self, f: F) -> MaxByKey<Self, F, K>
        where Self: Sized
    {
        MaxByKey::new(self, f)
    }

    /// Returns the minimum element of a stream.
    /// Returns the lastest element if the comparison determines two elements to be equally minimum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .min()
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 0, "value = {:?}", value);
    /// ```
    fn min(self) -> Min<Self>
        where Self: Sized
    {
        Min::new(self)
    }

    /// Returns the element that gives the minimum value from the specified function.
    /// Returns the lastest element if the comparison determines two elements to be equally minimum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .min_by_key(|v| 10 - *v)
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 9, "value = {:?}", value);
    /// ```
    fn min_by_key<F: FnMut(&T) -> K, K>(self, f: F) -> MinByKey<Self, F, K>
        where Self: Sized
    {
        MinByKey::new(self, f)
    }

    /// Ignore the first X values from the stream
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .skip(3)
    ///     .into_vec();
    /// assert!(vec == [3, 4, 5, 6, 7, 8, 9], "vec = {:?}", vec);
    /// ```
    fn skip(self, count: u64) -> Skip<Self>
        where Self: Sized
    {
        Skip::new(self, count)
    }

    /// Ignores the last X values of the stream
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .skip_last(3)
    ///     .into_vec();
    /// assert!(vec == [0, 1, 2, 3, 4, 5, 6], "vec = {:?}", vec);
    /// ```
    fn skip_last(self, count: usize) -> SkipLast<Self>
        where Self: Sized
    {
        SkipLast::new(self, count)
    }

    fn subscribe(self)
        where Self: Sized
    {
        self.consume(Subscription::new());
    }

    /// Calculate the sum of the item received.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .sum()
    ///     .into_vec();
    /// assert!(vec == [45], "vec = {:?}", vec);
    /// ```
    fn sum(self) -> Sum<Self>
        where Self: Sized
    {
        Sum::new(self)
    }

    /// Take only the first X values of the stream and close the stream after
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .take(3)
    ///     .into_vec();
    /// assert!(vec == [0, 1, 2], "vec = {:?}", vec);
    /// ```
    fn take(self, count: u64) -> Take<Self>
        where Self: Sized
    {
        Take::new(self, count)
    }

    /// Take the only the last X values of the stream and close the stream after
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .take_last(3)
    ///     .into_vec();
    /// assert!(vec == [7, 8, 9], "vec = {:?}", vec);
    /// ```
    fn take_last(self, count: usize) -> TakeLast<Self>
        where Self: Sized
    {
        TakeLast::new(self, count)
    }
}<commit_msg>fix documentation of flat_map<commit_after>use consumer::*;
use count::*;
use filter::*;
use flat_map::*;
use fold::*;
use group_by::*;
use inspect::*;
use map::*;
use max_by_key::*;
use max::*;
use min_by_key::*;
use min::*;
use skip_last::*;
use skip::*;
use subscription::*;
use sum::*;
use take_last::*;
use take::*;

pub trait Stream<T> {
    fn consume<C: Consumer<T>>(self, consumer: C);

    /// Count the number ofthe item received.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .count()
    ///     .into_vec();
    /// assert!(vec == [10], "vec = {:?}", vec);
    /// ```
    fn count(self) -> Count<Self, T>
        where Self: Sized
    {
        Count::new(self)
    }

    /// Creates a stream which uses a closure to determine if an element should be emitted.
    /// The closure must return true or false. `filter()` creates a stream which calls this closure on each element. If the closure returns true,
    /// then the element is returned. If the closure returns false, it will try again, and call the closure on the next element, seeing if it passes the test.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut vec = Vec::new();
    ///
    /// (0..5)
    ///     .to_stream()
    ///     .filter(|v| *v > 2)
    ///     .inspect(|v| vec.push(*v))
    ///     .subscribe();
    ///
    /// assert!(vec == &[3, 4], "vec = {:?}", vec);
    /// ```
    fn filter<F>(self, predicate: F) -> Filter<Self, F>
        where Self: Sized,
              F: FnMut(&mut T) -> bool
    {
        Filter::new(self, predicate)
    }

    /// Creates an stream that works like map, but flattens nested structure.
    /// The `map()` adapter is very useful, but only when the closure argument produces values.
    /// If it produces a stream instead, there's an extra layer of indirection. flat_map() will remove this extra layer on its own.
    ///
    /// Another way of thinking about flat_map(): map()'s closure returns one item for each element, and flat_map()'s closure returns a stream for each element.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..4i32)
    ///     .to_stream()
    ///     .flat_map(|v| Value::new(v + 10))
    ///     .into_vec();
    ///
    /// assert!(vec == [10, 11, 12, 13], "vec = {:?}", vec);
    /// ```
    fn flat_map<F, SO, O>(self, func: F) -> Flatmap<Self, F, T, SO, O>
        where Self: Sized,
              F: FnMut(T) -> SO,
              SO: Stream<O>
    {
        Flatmap::new(self, func)
    }

    /// A stream adaptor that applies a function, producing a single, final value.
    ///`fold()` takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element.
    /// It returns the value that the accumulator should have for the next iteration.
    ///
    /// The initial value is the value the accumulator will have on the first call.
    /// After applying this closure to every element of the iterator, `fold()` returns the accumulator.
    ///
    /// This operation is sometimes called 'reduce' or 'inject'.

    /// Folding is useful whenever you have a collection of something, and want to produce a single value from it.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut v = 0;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .fold(0, |o, i| o + i)
    ///     .inspect(|x| v = *x)
    ///     .subscribe();
    ///
    /// assert!(v == 45, "v = {}", v);
    /// ```
    fn fold<O, F>(self, initial: O, func: F) -> Fold<Self, T, F, O>
        where Self: Sized,
              F: FnMut(O, T) -> O
    {
        Fold::new(self, initial, func)
    }

    /// Group incoming values using a `key_selector`.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut vec = Vec::new();
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .group_by(|v| v % 2)
    ///     .inspect(|g| vec.push(g.get_key()))
    ///     .subscribe();
    ///
    /// // This gives 2 groups
    /// assert!(vec == vec!(0, 1), "vec = {:?}", vec);
    /// ```
    fn group_by<F: FnMut(&V) -> K, K, V>(self, key_selector: F) -> GroupBy<F, K, Self, V>
        where Self: Sized
    {
        GroupBy::new(self, key_selector)
    }

    /// Do something with each element of a stream, passing the value on.
    /// This is usefull to debug an item.
    fn inspect<F>(self, func: F) -> Inspect<Self, F>
        where F: FnMut(&mut T),
              Self: Sized
    {
        Inspect::new(self, func)
    }

    /// Takes a closure and creates a stream which calls that closure on each element.
    /// `map()` transforms one stream into another, by means of its argument: something that implements FnMut. It produces a new stream which calls this closure
    /// on each element of the original stream.
    ///
    /// If you are good at thinking in types, you can think of map() like this: If you have a stream that gives you elements of some type A, and you want a stream
    /// of some other type B, you can use `map()`, passing a closure that takes an A and returns a B.
    /// `map()` is conceptually similar to a for loop. However, as `map()` is lazy, it is best used when you're already working with other streams. If you're doing
    /// some sort of looping for a side effect, it's considered more idiomatic to use for than `map()`.`
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let mut value = 0;
    ///
    /// let vec = (0..4)
    ///     .to_stream()
    ///     .map(|v| v + 10)
    ///     .into_vec();
    /// assert!(vec == [10, 11, 12, 13], "vec = {:?}", vec);
    /// ```
    fn map<O, F>(self, func: F) -> Map<Self, F, T, O>
        where Self: Sized,
              F: FnMut(T) -> O
    {
        Map::new(self, func)
    }

    /// Returns the maximum element of a stream.
    /// Returns the lastest element if the comparison determines two elements to be equally maximum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 0;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .max()
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 9, "value = {:?}", value);
    /// ```
    fn max(self) -> Max<Self>
        where Self: Sized
    {
        Max::new(self)
    }

    /// Returns the element that gives the maximum value from the specified function.
    /// Returns the lastest element if the comparison determines two elements to be equally maximum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .max_by_key(|v| 10 - *v)
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 0, "value = {:?}", value);
    /// ```
    fn max_by_key<F: FnMut(&T) -> K, K>(self, f: F) -> MaxByKey<Self, F, K>
        where Self: Sized
    {
        MaxByKey::new(self, f)
    }

    /// Returns the minimum element of a stream.
    /// Returns the lastest element if the comparison determines two elements to be equally minimum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .min()
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 0, "value = {:?}", value);
    /// ```
    fn min(self) -> Min<Self>
        where Self: Sized
    {
        Min::new(self)
    }

    /// Returns the element that gives the minimum value from the specified function.
    /// Returns the lastest element if the comparison determines two elements to be equally minimum.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let mut value = 100;
    ///
    /// (0..10)
    ///     .to_stream()
    ///     .min_by_key(|v| 10 - *v)
    ///     .inspect(|v| value = *v)
    ///     .subscribe();
    /// assert!(value == 9, "value = {:?}", value);
    /// ```
    fn min_by_key<F: FnMut(&T) -> K, K>(self, f: F) -> MinByKey<Self, F, K>
        where Self: Sized
    {
        MinByKey::new(self, f)
    }

    /// Ignore the first X values from the stream
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .skip(3)
    ///     .into_vec();
    /// assert!(vec == [3, 4, 5, 6, 7, 8, 9], "vec = {:?}", vec);
    /// ```
    fn skip(self, count: u64) -> Skip<Self>
        where Self: Sized
    {
        Skip::new(self, count)
    }

    /// Ignores the last X values of the stream
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .skip_last(3)
    ///     .into_vec();
    /// assert!(vec == [0, 1, 2, 3, 4, 5, 6], "vec = {:?}", vec);
    /// ```
    fn skip_last(self, count: usize) -> SkipLast<Self>
        where Self: Sized
    {
        SkipLast::new(self, count)
    }

    fn subscribe(self)
        where Self: Sized
    {
        self.consume(Subscription::new());
    }

    /// Calculate the sum of the item received.
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .sum()
    ///     .into_vec();
    /// assert!(vec == [45], "vec = {:?}", vec);
    /// ```
    fn sum(self) -> Sum<Self>
        where Self: Sized
    {
        Sum::new(self)
    }

    /// Take only the first X values of the stream and close the stream after
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .take(3)
    ///     .into_vec();
    /// assert!(vec == [0, 1, 2], "vec = {:?}", vec);
    /// ```
    fn take(self, count: u64) -> Take<Self>
        where Self: Sized
    {
        Take::new(self, count)
    }

    /// Take the only the last X values of the stream and close the stream after
    ///
    /// # Examples
    ///
    /// ```
    /// use asyncplify::*;
    ///
    /// let vec = (0..10)
    ///     .to_stream()
    ///     .take_last(3)
    ///     .into_vec();
    /// assert!(vec == [7, 8, 9], "vec = {:?}", vec);
    /// ```
    fn take_last(self, count: usize) -> TakeLast<Self>
        where Self: Sized
    {
        TakeLast::new(self, count)
    }
}<|endoftext|>


<commit_before>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
  output: Vec<i32>,
}

pub type StreamReader<R>  = Stream<ReadStream<R>>;
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> io::Result<Stream<ReadStream<R>>> {
    let producer  = ReadStream::new(reader);
    let error_str = "parser: couldn't parse the reader";

    Stream::from_stream_producer(producer, error_str)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::NotFound` is returned when the given filename isn't found.
  /// * `ErrorKind::InvalidData` is returned when the data within the file
  ///   isn't valid FLAC data.
  #[inline]
  pub fn from_file(filename: &str) -> io::Result<Stream<ReadStream<File>>> {
    File::open(filename).and_then(|file| {
      let producer  = ReadStream::new(file);
      let error_str = format!("parser: couldn't parse the given file {}",
                              filename);

      Stream::from_stream_producer(producer, &error_str)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::InvalidData` is returned when the data within the buffer
  ///   isn't valid FLAC data.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> io::Result<Stream<ByteStream>> {
    let producer  = ByteStream::new(buffer);
    let error_str = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(producer, error_str)
  }

  fn from_stream_producer(mut producer: P, error_str: &str)
                          -> io::Result<Self> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    let is_error = many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    });

    if !is_error {
      Ok(Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
        output: Vec::new(),
      })
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;

    if self.output.is_empty() {
      let channels    = self.info.channels as usize;
      let block_size  = self.info.max_block_size as usize;
      let output_size = block_size * channels;

      self.output.reserve_exact(output_size);

      unsafe { self.output.set_len(output_size) }
    }

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame<'a>(&'a mut self) -> Option<usize> {
    let stream_info = self.info();

    loop {
      match self.producer.parse(|i| frame_parser(i, &stream_info)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut self.output[start..end];

            subframe::decode(&subframe, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, &mut self.output);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P> where P: 'a + StreamProducer {
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a, P> Iterator for Iter<'a, P> where P: StreamProducer {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      if let Some(block_size) = self.stream.next_frame() {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a, P> IntoIterator for &'a mut Stream

 where P: StreamProducer {
  type Item     = i32;
  type IntoIter = Iter<'a, P>;

  #[inline]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<commit_msg>Use alias in initialization functions for `Stream`<commit_after>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
  output: Vec<i32>,
}

pub type StreamReader<R>  = Stream<ReadStream<R>>;
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> io::Result<StreamReader<R>> {
    let producer  = ReadStream::new(reader);
    let error_str = "parser: couldn't parse the reader";

    Stream::from_stream_producer(producer, error_str)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::NotFound` is returned when the given filename isn't found.
  /// * `ErrorKind::InvalidData` is returned when the data within the file
  ///   isn't valid FLAC data.
  #[inline]
  pub fn from_file(filename: &str) -> io::Result<StreamReader<File>> {
    File::open(filename).and_then(|file| {
      let producer  = ReadStream::new(file);
      let error_str = format!("parser: couldn't parse the given file {}",
                              filename);

      Stream::from_stream_producer(producer, &error_str)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::InvalidData` is returned when the data within the buffer
  ///   isn't valid FLAC data.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> io::Result<StreamBuffer> {
    let producer  = ByteStream::new(buffer);
    let error_str = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(producer, error_str)
  }

  fn from_stream_producer(mut producer: P, error_str: &str)
                          -> io::Result<Self> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    let is_error = many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    });

    if !is_error {
      Ok(Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
        output: Vec::new(),
      })
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;

    if self.output.is_empty() {
      let channels    = self.info.channels as usize;
      let block_size  = self.info.max_block_size as usize;
      let output_size = block_size * channels;

      self.output.reserve_exact(output_size);

      unsafe { self.output.set_len(output_size) }
    }

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame<'a>(&'a mut self) -> Option<usize> {
    let stream_info = self.info();

    loop {
      match self.producer.parse(|i| frame_parser(i, &stream_info)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut self.output[start..end];

            subframe::decode(&subframe, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, &mut self.output);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P> where P: 'a + StreamProducer {
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a, P> Iterator for Iter<'a, P> where P: StreamProducer {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      if let Some(block_size) = self.stream.next_frame() {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a, P> IntoIterator for &'a mut Stream

 where P: StreamProducer {
  type Item     = i32;
  type IntoIter = Iter<'a, P>;

  #[inline]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<|endoftext|>


<commit_before>use std::os::raw::{c_int, c_double, c_void};
use std::ptr;

use ffi;
use base::*;

extern "C" fn write_wrapper<W>(raw_out: *mut ffi::SoundIoOutStream, min: c_int, max: c_int)
    where W: Fn(OutStream, i32, i32)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.write.as_ref().map(|ref f| f(out, min as i32, max as i32));
}

extern "C" fn underflow_wrapper<U>(raw_out: *mut ffi::SoundIoOutStream)
    where U: Fn(OutStream)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.underflow.as_ref().map(|ref f| f(out));
}

extern "C" fn error_wrapper<E>(raw_out: *mut ffi::SoundIoOutStream, error: ffi::SioError)
    where E: Fn(OutStream, ffi::SioError)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.error.as_ref().map(|ref f| f(out, error));
}

struct OutStreamCallbacks<'a> {
    write: Option<Box<Fn(OutStream, i32, i32) + 'a>>,
    underflow: Option<Box<Fn(OutStream) + 'a>>,
    error: Option<Box<Fn(OutStream, ffi::SioError) + 'a>>,
}
impl<'a> Default for OutStreamCallbacks<'a> {
    fn default() -> Self {
        OutStreamCallbacks {
            write: None,
            underflow: None,
            error: None,
        }
    }
}
impl<'a> Drop for OutStreamCallbacks<'a> {
    fn drop(&mut self) {}
}

pub struct OutStream<'a> {
    stream: *mut ffi::SoundIoOutStream,
    callbacks: Box<OutStreamCallbacks<'a>>,
}
impl<'a> OutStream<'a> {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        let callbacks = Box::new(OutStreamCallbacks::default());
        OutStream {
            stream: raw_stream,
            callbacks: callbacks,
        }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<W>(&mut self, callback: Box<W>)
        where W: Fn(OutStream, i32, i32) + 'a
    {
        // stored box reference to callback closure
        self.callbacks.write = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).write_callback = Some(write_wrapper::<W>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_underflow_callback<U>(&mut self, callback: Box<U>)
        where U: Fn(OutStream) + 'a
    {
        self.callbacks.underflow = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).underflow_callback = Some(underflow_wrapper::<U>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_error_callback<E>(&mut self, callback: Box<E>)
        where E: Fn(OutStream, ffi::SioError) + 'a
    {
        self.callbacks.error = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).error_callback = Some(error_wrapper::<E>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn write_stream(&self,
                        min_frame_count: i32,
                        buffers: &Vec<Vec<f32>>)
                        -> Result<i32, ffi::SioError> {
        let channel_count = self.get_layout().channel_count();
        // check if buffer contains frames for all channels
        if buffers.len() < channel_count as usize {
            return Err(ffi::SioError::Invalid);
        }
        // check if there are at least min_frame_count frames for all channels
        if !buffers.iter().map(|c| c.len()).all(|l| l >= min_frame_count as usize) {
            return Err(ffi::SioError::Invalid);
        }

        // assuming that every channel buffer has the same length
        let mut frame_count = buffers[0].len() as c_int;
        let mut raw_areas: *mut ffi::SoundIoChannelArea = ptr::null_mut();
        let actual_frame_count = try!(self.begin_write(&mut raw_areas, &frame_count));
        let areas = unsafe { ::std::slice::from_raw_parts_mut(raw_areas, channel_count as usize) };
        for idx in 0..actual_frame_count as usize {
            for channel in 0..channel_count as usize {
                let area = areas[channel];
                let addr = (area.ptr as usize + area.step as usize * idx) as *mut f32;
                unsafe { *addr = buffers[channel][idx] }
            }
        }
        self.end_write().map_or(Ok(actual_frame_count), |err| Err(err))
    }

    pub fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: &i32)
                       -> Result<i32, ffi::SioError> {
        let mut actual_frame_count = *frame_count as c_int;
        match unsafe {
            ffi::soundio_outstream_begin_write(self.stream,
                                               areas,
                                               &mut actual_frame_count as *mut c_int)
        } {
            ffi::SioError::None => Ok(actual_frame_count),
            err @ _ => Err(err),
        }
    }

    pub fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl<'a> Drop for OutStream<'a> {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<commit_msg>Make `{begin,end}_write` private<commit_after>use std::os::raw::{c_int, c_double, c_void};
use std::ptr;

use ffi;
use base::*;

extern "C" fn write_wrapper<W>(raw_out: *mut ffi::SoundIoOutStream, min: c_int, max: c_int)
    where W: Fn(OutStream, i32, i32)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.write.as_ref().map(|ref f| f(out, min as i32, max as i32));
}

extern "C" fn underflow_wrapper<U>(raw_out: *mut ffi::SoundIoOutStream)
    where U: Fn(OutStream)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.underflow.as_ref().map(|ref f| f(out));
}

extern "C" fn error_wrapper<E>(raw_out: *mut ffi::SoundIoOutStream, error: ffi::SioError)
    where E: Fn(OutStream, ffi::SioError)
{
    let out = OutStream::new(raw_out);
    let callbacks_ptr = unsafe { (*out.stream).userdata as *const Box<OutStreamCallbacks> };
    let callbacks: &Box<OutStreamCallbacks> = unsafe { &*callbacks_ptr };
    callbacks.error.as_ref().map(|ref f| f(out, error));
}

struct OutStreamCallbacks<'a> {
    write: Option<Box<Fn(OutStream, i32, i32) + 'a>>,
    underflow: Option<Box<Fn(OutStream) + 'a>>,
    error: Option<Box<Fn(OutStream, ffi::SioError) + 'a>>,
}
impl<'a> Default for OutStreamCallbacks<'a> {
    fn default() -> Self {
        OutStreamCallbacks {
            write: None,
            underflow: None,
            error: None,
        }
    }
}
impl<'a> Drop for OutStreamCallbacks<'a> {
    fn drop(&mut self) {}
}

pub struct OutStream<'a> {
    stream: *mut ffi::SoundIoOutStream,
    callbacks: Box<OutStreamCallbacks<'a>>,
}
impl<'a> OutStream<'a> {
    pub fn new(raw_stream: *mut ffi::SoundIoOutStream) -> Self {
        let callbacks = Box::new(OutStreamCallbacks::default());
        OutStream {
            stream: raw_stream,
            callbacks: callbacks,
        }
    }

    pub fn open(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_open(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn start(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_start(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn register_write_callback<W>(&mut self, callback: Box<W>)
        where W: Fn(OutStream, i32, i32) + 'a
    {
        // stored box reference to callback closure
        self.callbacks.write = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).write_callback = Some(write_wrapper::<W>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_underflow_callback<U>(&mut self, callback: Box<U>)
        where U: Fn(OutStream) + 'a
    {
        self.callbacks.underflow = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).underflow_callback = Some(underflow_wrapper::<U>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn register_error_callback<E>(&mut self, callback: Box<E>)
        where E: Fn(OutStream, ffi::SioError) + 'a
    {
        self.callbacks.error = Some(callback);
        unsafe {
            // register wrapper for write_callback
            (*self.stream).error_callback = Some(error_wrapper::<E>);
            // store reference to callbacks struct in userdata pointer
            (*self.stream).userdata =
                &self.callbacks as *const Box<OutStreamCallbacks> as *mut c_void
        }
    }

    pub fn write_stream(&self,
                        min_frame_count: i32,
                        buffers: &Vec<Vec<f32>>)
                        -> Result<i32, ffi::SioError> {
        let channel_count = self.get_layout().channel_count();
        // check if buffer contains frames for all channels
        if buffers.len() < channel_count as usize {
            return Err(ffi::SioError::Invalid);
        }
        // check if there are at least min_frame_count frames for all channels
        if !buffers.iter().map(|c| c.len()).all(|l| l >= min_frame_count as usize) {
            return Err(ffi::SioError::Invalid);
        }

        // assuming that every channel buffer has the same length
        let mut frame_count = buffers[0].len() as c_int;
        let mut raw_areas: *mut ffi::SoundIoChannelArea = ptr::null_mut();
        let actual_frame_count = try!(self.begin_write(&mut raw_areas, &frame_count));
        let areas = unsafe { ::std::slice::from_raw_parts_mut(raw_areas, channel_count as usize) };
        for idx in 0..actual_frame_count as usize {
            for channel in 0..channel_count as usize {
                let area = areas[channel];
                let addr = (area.ptr as usize + area.step as usize * idx) as *mut f32;
                unsafe { *addr = buffers[channel][idx] }
            }
        }
        self.end_write().map_or(Ok(actual_frame_count), |err| Err(err))
    }

    fn begin_write(&self,
                       areas: *mut *mut ffi::SoundIoChannelArea,
                       frame_count: &i32)
                       -> Result<i32, ffi::SioError> {
        let mut actual_frame_count = *frame_count as c_int;
        match unsafe {
            ffi::soundio_outstream_begin_write(self.stream,
                                               areas,
                                               &mut actual_frame_count as *mut c_int)
        } {
            ffi::SioError::None => Ok(actual_frame_count),
            err @ _ => Err(err),
        }
    }

    fn end_write(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_end_write(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn clear_buffer(&self) -> Option<ffi::SioError> {
        match unsafe { ffi::soundio_outstream_clear_buffer(self.stream) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn pause(&self, pause: bool) -> Option<ffi::SioError> {
        let pause_c_bool = match pause {
            true => 1u8,
            false => 0u8,
        };
        match unsafe { ffi::soundio_outstream_pause(self.stream, pause_c_bool) } {
            ffi::SioError::None => None,
            err @ _ => Some(err),
        }
    }

    pub fn get_latency(&self) -> Result<f64, ffi::SioError> {
        let mut latency = 0.0f64;
        match unsafe {
            ffi::soundio_outstream_get_latency(self.stream, &mut latency as *mut c_double)
        } {
            ffi::SioError::None => Ok(latency),
            err @ _ => Err(err),
        }

    }

    pub fn current_format(&self) -> Result<ffi::SioFormat, ffi::SioError> {
        match unsafe { (*self.stream).format } {
            ffi::SioFormat::Invalid => Err(ffi::SioError::Invalid),
            fmt @ _ => Ok(fmt),
        }
    }

    pub fn get_layout(&self) -> ChannelLayout {
        ChannelLayout::new(unsafe { &(*self.stream).layout })
    }

    pub fn get_sample_rate(&self) -> i32 {
        unsafe { (*self.stream).sample_rate as i32 }
    }

    pub fn get_device(&self) -> Device {
        let dev = Device::new(unsafe { (*self.stream).device });
        dev.inc_ref();
        dev
    }

    pub fn destroy(&self) {
        unsafe { ffi::soundio_outstream_destroy(self.stream) }
    }
}
impl<'a> Drop for OutStream<'a> {
    fn drop(&mut self) {
        // TODO: call destroy manually.
        // OutStream will get dropped each time a new
        // struct is created from the same *mut pointer.
    }
}
<|endoftext|>