<commit_before>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// 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::path::Path;
use sdl2::rect::Rect;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::render::{Renderer, Texture};
use sdl2_image::{LoadTexture};

use super::game::{Level, Position, Direction};

/// The Drawer struct is responsible for drawing the game onto the screen.
pub struct Drawer<'a> {
    /// The underlying SDL renderer
    renderer: Renderer<'a>,
    /// The texture containing all the tiles
    texture: Texture,
    /// The size of the screen in pixels
    screen_size: (u32, u32),
}

impl<'a> Drawer<'a> {
    /// Creates a new Drawer instance.
    pub fn new(renderer: Renderer<'a>) -> Drawer {
        let path = Path::new("assets/image/tileset.png");
        let texture = renderer.load_texture(path).unwrap();
        let screen_size = renderer.window().unwrap().drawable_size();
        Drawer {
            renderer: renderer,
            texture: texture,
            screen_size: screen_size,
        }
    }

    /// Draws a level onto the screen.
    pub fn draw(&mut self, level: &Level) {
        // Draw a full-size image onto an off-screen buffer
        let fullsize = self.get_rendering_size(&level);
        let _ = self.renderer.render_target()
            .expect("Render targets are not supported")
            .create_and_set(PixelFormatEnum::RGBA8888, fullsize);

        self.draw_fullsize(level);

        // Copy onto the screen with appropriate scaling
        let final_rect = self.get_centered_image_rect(self.get_scaled_rendering_size(&level));
        let texture = self.renderer.render_target()
            .unwrap()
            .reset()
            .unwrap_or_else(|err| panic!("Could not reset to the default render target: {}", err))
            .unwrap_or_else(|| panic!("Could not get the offscreen texture"));

        self.renderer.clear();
        self.renderer.copy(&texture, Some(Rect::new_unwrap(0, 0, fullsize.0, fullsize.1)), final_rect);
        self.renderer.present();
    }

    /// Draws a full-size image of the given level onto the current render target.
    fn draw_fullsize(&mut self, level: &Level) {
        let (cols, rows) = level.extents();
        self.renderer.set_draw_color(Color::RGB(0, 0, 0));
        self.renderer.clear();

        for j in (0..rows) {
            for i in (0..cols) {
                let pos = Position::new(j, i);
                let (x, y) = Tile::get_coordinates(&pos);

                // First draw the floor tiles
                if level.is_square(&pos) {
                    self.draw_tile(Tile::Square, x, y);
                } else {
                    self.draw_tile(Tile::Floor, x, y);
                }

                // Add the shadows
                let flags = get_shadow_flags(&level, &pos);
                for f in &[N_EDGE, S_EDGE, E_EDGE, W_EDGE, NE_CORNER, NW_CORNER, SE_CORNER, SW_CORNER] {
                    if flags.contains(*f) {
                        self.draw_tile(Tile::Shadow(*f), x, y);
                    }
                }

                // Draw the other items
                let z = y - Tile::offset();
                if level.is_wall(&pos) {
                    self.draw_tile(Tile::Wall, x, z);
                }
                if level.is_box(&pos) {
                    self.draw_tile(Tile::Rock, x, z);
                }
                if level.is_player(&pos) {
                    self.draw_tile(Tile::Player, x, z);
                }
            }
        }
    }

    /// Draws a tile at the given coordinates.
    fn draw_tile(&mut self, tile: Tile, x: i32, y: i32) {
        let (col, row) = tile.location().unwrap_or_else(|| {
            panic!("No image for this tile: {:?}", tile);
        });
        let tile = self.get_tile_rect(col, row);
        self.renderer.copy(&self.texture, tile, Some(Rect::new_unwrap(x, y, Tile::width(), Tile::height())));
    }

    /// Returns the Rect of the tile located at the given row and column in the texture.
    fn get_tile_rect(&self, col: u32, row: u32) -> Option<Rect> {
        let x = (col * Tile::width()) as i32;
        let y = (row * Tile::height()) as i32;
        Some(Rect::new_unwrap(x, y, Tile::width(), Tile::height()))
    }

    /// Returns the full size needed to draw the given level.
    fn get_rendering_size(&self, level: &Level) -> (u32, u32) {
        let (w, h) = level.extents();
        let width = w as u32 * Tile::width();
        let height = if h > 0 {
            Tile::height() + (h - 1) as u32 * Tile::effective_height()
        } else {
            0
        };

        (width, height)
    }

    /// Returns the size of the drawing scaled to fit onto the screen.
    fn get_scaled_rendering_size(&self, level: &Level) -> (u32, u32) {
        let render_size = self.get_rendering_size(&level);
        let width_ratio = (self.screen_size.0 as f64) / (render_size.0 as f64);
        let height_ratio = (self.screen_size.1 as f64) / (render_size.1 as f64);
        let ratio = f64::min(1.0, f64::min(width_ratio, height_ratio));

        let scale = |sz: u32| {
            (ratio * (sz as f64)).floor() as u32
        };

        (scale(render_size.0), scale(render_size.1))
    }

    /// Returns the Rect of an image of given dimensions so that it's centered on the screen.
    fn get_centered_image_rect(&self, img_size: (u32, u32)) -> Option<Rect> {
        let x = (self.screen_size.0 - img_size.0) as i32 / 2;
        let y = (self.screen_size.1 - img_size.1) as i32 / 2;
        Some(Rect::new_unwrap(x, y, img_size.0, img_size.1))
    }
}

/// Represents a kind of tile.
#[derive(Debug)]
enum Tile {
    /// Standard floor tile
    Floor,
    /// Wall tile
    Wall,
    /// Rock tile
    Rock,
    /// Target square tile
    Square,
    /// Player tile
    Player,
    /// Shadow tile
    Shadow(ShadowFlags),
}

impl Tile {
    /// Returns the location of the tile in the tileset texture.
    pub fn location(&self) -> Option<(u32, u32)> {
        match *self {
           Tile::Floor => Some((0, 0)),
           Tile::Wall => Some((0, 2)),
           Tile::Rock => Some((2, 0)),
           Tile::Square => Some((1, 0)),
           Tile::Player => Some((3, 0)),
           Tile::Shadow(N_EDGE) => Some((4, 0)),
           Tile::Shadow(S_EDGE) => Some((5, 0)),
           Tile::Shadow(E_EDGE) => Some((0, 1)),
           Tile::Shadow(W_EDGE) => Some((1, 1)),
           Tile::Shadow(NE_CORNER) => Some((2, 1)),
           Tile::Shadow(NW_CORNER) => Some((3, 1)),
           Tile::Shadow(SE_CORNER) => Some((4, 1)),
           Tile::Shadow(SW_CORNER) => Some((5, 1)),
           Tile::Shadow(ShadowFlags { .. }) => None,
        }
    }

    /// Returns the width of a tile.
    pub fn width() -> u32 {
        101
    }

    /// Returns the height of a tile.
    pub fn height() -> u32 {
        171
    }

    /// Returns the effective height of a tile (used for stacking)
    pub fn effective_height() -> u32 {
        83
    }

    /// Returns the offset need to draw items on the floor.
    pub fn offset() -> i32 {
        40
    }

    /// Returns the top-left corner coordinates of the tile corresponding
    /// to the given position.
    fn get_coordinates(pos: &Position) -> (i32, i32) {
        let x = Self::width() as i32 * pos.column();
        let y = Self::effective_height() as i32 * pos.row();
        (x, y)
    }
}

bitflags!(
    /// Represents the different kind of shadows that can be cast
    /// onto a floor tile.
    flags ShadowFlags: i32 {
        /// North edge
        const N_EDGE = 0x1,
        /// South edge
        const S_EDGE = 0x2,
        /// East edge
        const E_EDGE = 0x4,
        /// West edge
        const W_EDGE = 0x8,
        /// North East corner
        const NE_CORNER = 0x10,
        /// North West corner
        const NW_CORNER = 0x20,
        /// South East corner
        const SE_CORNER = 0x40,
        /// South West corner
        const SW_CORNER = 0x80,
    }
);

/// Returns the shadow flags for a particular position in the given level.
fn get_shadow_flags(level: &Level, pos: &Position) -> ShadowFlags {
    let north = pos.neighbor(Direction::Up);
    let south = pos.neighbor(Direction::Down);
    let west = pos.neighbor(Direction::Left);
    let east = pos.neighbor(Direction::Right);

    let mut flags = ShadowFlags::empty();
    if level.is_wall(&north) {
        flags = flags | N_EDGE;
    }
    if level.is_wall(&south) {
        flags = flags | S_EDGE;
    }
    if level.is_wall(&west) {
        flags = flags | W_EDGE;
    }
    if level.is_wall(&east) {
        flags = flags | E_EDGE;
    }
    if level.is_wall(&north.neighbor(Direction::Right)) && !flags.intersects(N_EDGE | E_EDGE) {
        flags = flags | NE_CORNER;
    }
    if level.is_wall(&north.neighbor(Direction::Left)) && !flags.intersects(N_EDGE | W_EDGE) {
        flags = flags | NW_CORNER;
    }
    if level.is_wall(&south.neighbor(Direction::Right)) && !flags.intersects(S_EDGE | E_EDGE) {
        flags = flags | SE_CORNER;
    }
    if level.is_wall(&south.neighbor(Direction::Left)) && !flags.intersects(S_EDGE | W_EDGE) {
        flags = flags | SW_CORNER;
    }
    flags
}

<commit_msg>Prevent a name shadowing problem<commit_after>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// 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::path::Path;
use sdl2::rect::Rect;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::render::{Renderer, Texture};
use sdl2_image::{LoadTexture};

use super::game::{Level, Position, Direction};

/// The Drawer struct is responsible for drawing the game onto the screen.
pub struct Drawer<'a> {
    /// The underlying SDL renderer
    renderer: Renderer<'a>,
    /// The texture containing all the tiles
    texture: Texture,
    /// The size of the screen in pixels
    screen_size: (u32, u32),
}

impl<'a> Drawer<'a> {
    /// Creates a new Drawer instance.
    pub fn new(renderer: Renderer<'a>) -> Drawer {
        let path = Path::new("assets/image/tileset.png");
        let texture = renderer.load_texture(path).unwrap();
        let screen_size = renderer.window().unwrap().drawable_size();
        Drawer {
            renderer: renderer,
            texture: texture,
            screen_size: screen_size,
        }
    }

    /// Draws a level onto the screen.
    pub fn draw(&mut self, level: &Level) {
        // Draw a full-size image onto an off-screen buffer
        let fullsize = self.get_rendering_size(&level);
        let _ = self.renderer.render_target()
            .expect("Render targets are not supported")
            .create_and_set(PixelFormatEnum::RGBA8888, fullsize);

        self.draw_fullsize(level);

        // Copy onto the screen with appropriate scaling
        let final_rect = self.get_centered_image_rect(self.get_scaled_rendering_size(&level));
        let texture = self.renderer.render_target()
            .unwrap()
            .reset()
            .unwrap_or_else(|err| panic!("Could not reset to the default render target: {}", err))
            .unwrap_or_else(|| panic!("Could not get the offscreen texture"));

        self.renderer.clear();
        self.renderer.copy(&texture, Some(Rect::new_unwrap(0, 0, fullsize.0, fullsize.1)), final_rect);
        self.renderer.present();
    }

    /// Draws a full-size image of the given level onto the current render target.
    fn draw_fullsize(&mut self, level: &Level) {
        let (cols, rows) = level.extents();
        self.renderer.set_draw_color(Color::RGB(0, 0, 0));
        self.renderer.clear();

        for j in (0..rows) {
            for i in (0..cols) {
                let pos = Position::new(j, i);
                let (x, y) = Tile::get_coordinates(&pos);

                // First draw the floor tiles
                if level.is_square(&pos) {
                    self.draw_tile(Tile::Square, x, y);
                } else {
                    self.draw_tile(Tile::Floor, x, y);
                }

                // Add the shadows
                let flags = get_shadow_flags(&level, &pos);
                for f in &[N_EDGE, S_EDGE, E_EDGE, W_EDGE, NE_CORNER, NW_CORNER, SE_CORNER, SW_CORNER] {
                    if flags.contains(*f) {
                        self.draw_tile(Tile::Shadow(*f), x, y);
                    }
                }

                // Draw the other items
                let z = y - Tile::offset();
                if level.is_wall(&pos) {
                    self.draw_tile(Tile::Wall, x, z);
                }
                if level.is_box(&pos) {
                    self.draw_tile(Tile::Rock, x, z);
                }
                if level.is_player(&pos) {
                    self.draw_tile(Tile::Player, x, z);
                }
            }
        }
    }

    /// Draws a tile at the given coordinates.
    fn draw_tile(&mut self, tile: Tile, x: i32, y: i32) {
        let (col, row) = tile.location().unwrap_or_else(|| {
            panic!("No image for this tile: {:?}", tile);
        });
        let tile_rect = self.get_tile_rect(col, row);
        self.renderer.copy(&self.texture, tile_rect, Some(Rect::new_unwrap(x, y, Tile::width(), Tile::height())));
    }

    /// Returns the Rect of the tile located at the given row and column in the texture.
    fn get_tile_rect(&self, col: u32, row: u32) -> Option<Rect> {
        let x = (col * Tile::width()) as i32;
        let y = (row * Tile::height()) as i32;
        Some(Rect::new_unwrap(x, y, Tile::width(), Tile::height()))
    }

    /// Returns the full size needed to draw the given level.
    fn get_rendering_size(&self, level: &Level) -> (u32, u32) {
        let (w, h) = level.extents();
        let width = w as u32 * Tile::width();
        let height = if h > 0 {
            Tile::height() + (h - 1) as u32 * Tile::effective_height()
        } else {
            0
        };

        (width, height)
    }

    /// Returns the size of the drawing scaled to fit onto the screen.
    fn get_scaled_rendering_size(&self, level: &Level) -> (u32, u32) {
        let render_size = self.get_rendering_size(&level);
        let width_ratio = (self.screen_size.0 as f64) / (render_size.0 as f64);
        let height_ratio = (self.screen_size.1 as f64) / (render_size.1 as f64);
        let ratio = f64::min(1.0, f64::min(width_ratio, height_ratio));

        let scale = |sz: u32| {
            (ratio * (sz as f64)).floor() as u32
        };

        (scale(render_size.0), scale(render_size.1))
    }

    /// Returns the Rect of an image of given dimensions so that it's centered on the screen.
    fn get_centered_image_rect(&self, img_size: (u32, u32)) -> Option<Rect> {
        let x = (self.screen_size.0 - img_size.0) as i32 / 2;
        let y = (self.screen_size.1 - img_size.1) as i32 / 2;
        Some(Rect::new_unwrap(x, y, img_size.0, img_size.1))
    }
}

/// Represents a kind of tile.
#[derive(Debug)]
enum Tile {
    /// Standard floor tile
    Floor,
    /// Wall tile
    Wall,
    /// Rock tile
    Rock,
    /// Target square tile
    Square,
    /// Player tile
    Player,
    /// Shadow tile
    Shadow(ShadowFlags),
}

impl Tile {
    /// Returns the location of the tile in the tileset texture.
    pub fn location(&self) -> Option<(u32, u32)> {
        match *self {
           Tile::Floor => Some((0, 0)),
           Tile::Wall => Some((0, 2)),
           Tile::Rock => Some((2, 0)),
           Tile::Square => Some((1, 0)),
           Tile::Player => Some((3, 0)),
           Tile::Shadow(N_EDGE) => Some((4, 0)),
           Tile::Shadow(S_EDGE) => Some((5, 0)),
           Tile::Shadow(E_EDGE) => Some((0, 1)),
           Tile::Shadow(W_EDGE) => Some((1, 1)),
           Tile::Shadow(NE_CORNER) => Some((2, 1)),
           Tile::Shadow(NW_CORNER) => Some((3, 1)),
           Tile::Shadow(SE_CORNER) => Some((4, 1)),
           Tile::Shadow(SW_CORNER) => Some((5, 1)),
           Tile::Shadow(ShadowFlags { .. }) => None,
        }
    }

    /// Returns the width of a tile.
    pub fn width() -> u32 {
        101
    }

    /// Returns the height of a tile.
    pub fn height() -> u32 {
        171
    }

    /// Returns the effective height of a tile (used for stacking)
    pub fn effective_height() -> u32 {
        83
    }

    /// Returns the offset need to draw items on the floor.
    pub fn offset() -> i32 {
        40
    }

    /// Returns the top-left corner coordinates of the tile corresponding
    /// to the given position.
    fn get_coordinates(pos: &Position) -> (i32, i32) {
        let x = Self::width() as i32 * pos.column();
        let y = Self::effective_height() as i32 * pos.row();
        (x, y)
    }
}

bitflags!(
    /// Represents the different kind of shadows that can be cast
    /// onto a floor tile.
    flags ShadowFlags: i32 {
        /// North edge
        const N_EDGE = 0x1,
        /// South edge
        const S_EDGE = 0x2,
        /// East edge
        const E_EDGE = 0x4,
        /// West edge
        const W_EDGE = 0x8,
        /// North East corner
        const NE_CORNER = 0x10,
        /// North West corner
        const NW_CORNER = 0x20,
        /// South East corner
        const SE_CORNER = 0x40,
        /// South West corner
        const SW_CORNER = 0x80,
    }
);

/// Returns the shadow flags for a particular position in the given level.
fn get_shadow_flags(level: &Level, pos: &Position) -> ShadowFlags {
    let north = pos.neighbor(Direction::Up);
    let south = pos.neighbor(Direction::Down);
    let west = pos.neighbor(Direction::Left);
    let east = pos.neighbor(Direction::Right);

    let mut flags = ShadowFlags::empty();
    if level.is_wall(&north) {
        flags = flags | N_EDGE;
    }
    if level.is_wall(&south) {
        flags = flags | S_EDGE;
    }
    if level.is_wall(&west) {
        flags = flags | W_EDGE;
    }
    if level.is_wall(&east) {
        flags = flags | E_EDGE;
    }
    if level.is_wall(&north.neighbor(Direction::Right)) && !flags.intersects(N_EDGE | E_EDGE) {
        flags = flags | NE_CORNER;
    }
    if level.is_wall(&north.neighbor(Direction::Left)) && !flags.intersects(N_EDGE | W_EDGE) {
        flags = flags | NW_CORNER;
    }
    if level.is_wall(&south.neighbor(Direction::Right)) && !flags.intersects(S_EDGE | E_EDGE) {
        flags = flags | SE_CORNER;
    }
    if level.is_wall(&south.neighbor(Direction::Left)) && !flags.intersects(S_EDGE | W_EDGE) {
        flags = flags | SW_CORNER;
    }
    flags
}

<|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.

#![feature(collections)]
#![feature(core)]
#![feature(exit_status)]
#![feature(path)]
#![feature(rustc_private)]
#![feature(std_misc)]
#![feature(test)]

extern crate getopts;
extern crate test;

use test::{AutoColor, TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use test::ShouldPanic;
use getopts::{getopts, reqopt};
use std::{str, env};
use std::ffi::OsStr;
use std::fs::read_dir;
use std::process::{Command, Stdio};
use std::thunk::Thunk;

#[derive(Clone)]
struct Config {
    source_dir: String,
    filter: Option<String>
}

fn main() {
    let args = env::args();
    let config = parse_config(args.collect());
    let opts = test_options(config.clone());
    let tests = find_tests(config);
    match run_tests_console(&opts, tests) {
        Ok(false) => env::set_exit_status(1), // tests failed
        Err(_) => env::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

fn parse_config(args: Vec<String>) -> Config {
    let args = args.tail();
    let opts = vec!(reqopt("s", "source-dir", "source-dir", "source-dir"));
    let matches = match getopts(args, opts.as_slice()) {
      Ok(m) => m,
      Err(f) => panic!(f.to_string())
    };

    Config {
        source_dir: matches.opt_str("source-dir").unwrap(),
        filter: matches.free.first().map(|s| s.clone())
    }
}

fn test_options(config: Config) -> TestOpts {
    TestOpts {
        filter: config.filter,
        run_ignored: false,
        run_tests: true,
        run_benchmarks: false,
        logfile: None,
        nocapture: false,
        color: AutoColor,
    }
}

fn find_tests(config: Config) -> Vec<TestDescAndFn> {
    read_dir(&config.source_dir)
        .ok()
        .expect("Error reading directory.")
        .filter_map(Result::ok)
        .map(|e| e.path())
        .filter(|file| file.extension().map_or(false, |e| e == OsStr::from_str("html")))
        .map(|file| make_test(file.display().to_string()))
        .collect()
}

fn make_test(file: String) -> TestDescAndFn {
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(file.clone()),
            ignore: false,
            should_panic: ShouldPanic::No,
        },
        testfn: DynTestFn(Thunk::new(move || { run_test(file) }))
    }
}

fn run_test(file: String) {
    let path = env::current_dir().unwrap().join(&file);
    // FIXME (#1094): not the right way to transform a path
    let infile = format!("file://{}", path.display());
    let args = ["-z", "-f", infile.as_slice()];

    let mut prc_arg = env::current_exe().unwrap();
    let prc_arg = match prc_arg.pop() {
        true => prc_arg.join("servo"),
        _ => panic!("could not pop directory"),
    };
    let output = match Command::new(prc_arg.to_str().unwrap())
        .args(args.as_slice())
        .stdin(Stdio::null())
        .stderr(Stdio::inherit())
        .output()
    {
        Ok(p) => p,
        _ => panic!("Unable to spawn process."),
    };

    print!("{}", str::from_utf8(&output.stdout).unwrap());

    let out = str::from_utf8(&output.stderr);
    let lines: Vec<&str> = out.unwrap().split('\n').collect();
    for &line in lines.iter() {
        if line.contains("TEST-UNEXPECTED-FAIL") {
            panic!(line.to_string());
        }
    }

    if !output.status.success() {
        panic!("Servo exited with non-zero status {:?}", output.status);
    }
}
<commit_msg>Move away from as_slice() in contenttest.<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.

#![feature(collections)]
#![feature(exit_status)]
#![feature(path)]
#![feature(rustc_private)]
#![feature(std_misc)]
#![feature(test)]

extern crate getopts;
extern crate test;

use test::{AutoColor, TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use test::ShouldPanic;
use getopts::{getopts, reqopt};
use std::{str, env};
use std::ffi::OsStr;
use std::fs::read_dir;
use std::process::{Command, Stdio};
use std::thunk::Thunk;

#[derive(Clone)]
struct Config {
    source_dir: String,
    filter: Option<String>
}

fn main() {
    let args = env::args();
    let config = parse_config(args.collect());
    let opts = test_options(config.clone());
    let tests = find_tests(config);
    match run_tests_console(&opts, tests) {
        Ok(false) => env::set_exit_status(1), // tests failed
        Err(_) => env::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

fn parse_config(args: Vec<String>) -> Config {
    let args = args.tail();
    let opts = vec!(reqopt("s", "source-dir", "source-dir", "source-dir"));
    let matches = match getopts(args, &opts) {
      Ok(m) => m,
      Err(f) => panic!(f.to_string())
    };

    Config {
        source_dir: matches.opt_str("source-dir").unwrap(),
        filter: matches.free.first().map(|s| s.clone())
    }
}

fn test_options(config: Config) -> TestOpts {
    TestOpts {
        filter: config.filter,
        run_ignored: false,
        run_tests: true,
        run_benchmarks: false,
        logfile: None,
        nocapture: false,
        color: AutoColor,
    }
}

fn find_tests(config: Config) -> Vec<TestDescAndFn> {
    read_dir(&config.source_dir)
        .ok()
        .expect("Error reading directory.")
        .filter_map(Result::ok)
        .map(|e| e.path())
        .filter(|file| file.extension().map_or(false, |e| e == OsStr::from_str("html")))
        .map(|file| make_test(file.display().to_string()))
        .collect()
}

fn make_test(file: String) -> TestDescAndFn {
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(file.clone()),
            ignore: false,
            should_panic: ShouldPanic::No,
        },
        testfn: DynTestFn(Thunk::new(move || { run_test(file) }))
    }
}

fn run_test(file: String) {
    let path = env::current_dir().unwrap().join(&file);
    // FIXME (#1094): not the right way to transform a path
    let infile = format!("file://{}", path.display());
    let args = ["-z", "-f", &*infile];

    let mut prc_arg = env::current_exe().unwrap();
    let prc_arg = match prc_arg.pop() {
        true => prc_arg.join("servo"),
        _ => panic!("could not pop directory"),
    };
    let output = match Command::new(prc_arg.to_str().unwrap())
        .args(&args)
        .stdin(Stdio::null())
        .stderr(Stdio::inherit())
        .output()
    {
        Ok(p) => p,
        _ => panic!("Unable to spawn process."),
    };

    print!("{}", str::from_utf8(&output.stdout).unwrap());

    let out = str::from_utf8(&output.stderr);
    let lines: Vec<&str> = out.unwrap().split('\n').collect();
    for &line in lines.iter() {
        if line.contains("TEST-UNEXPECTED-FAIL") {
            panic!(line.to_string());
        }
    }

    if !output.status.success() {
        panic!("Servo exited with non-zero status {:?}", output.status);
    }
}
<|endoftext|>


<commit_before>//! The `render` module takes a tree of layout boxes and paints the screen.

// TODO move this file into it's own module
// TODO seperate drawing logic from command building logic

use gfx;
use gfx_window_glutin;
use glutin;

use gfx::traits::FactoryExt;
use gfx::Device;

pub type DepthFormat = gfx::format::DepthStencil;
pub type ColorFormat = gfx::format::Rgba8;

gfx_defines!{
    vertex Vertex {
        pos: [f32; 2] = "a_Pos",
        color: [f32; 3] = "a_Color",
    }

    pipeline pipe {
        vbuf: gfx::VertexBuffer<Vertex> = (),
        out: gfx::RenderTarget<ColorFormat> = "Target0",
    }
}

const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];

pub fn render_loop() {
    let builder = glutin::WindowBuilder::new()
        .with_title(String::from("SQUARE"))
        .with_dimensions(1024, 768)
        .with_vsync();

    let (window, mut device, mut factory, main_color, _main_depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder);

    let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();

    let pso = factory.create_pipeline_simple(
        include_bytes!("shaders/triangle.glslv"),
        include_bytes!("shaders/triangle.glslf"),
        pipe::new()
    ).unwrap();

    let (vertices, index_data) = render_commands(vec![DisplayCommand::SolidRect(String::new(), Rect {x:1.0, y:1.0, height:1.0, width:1.0})]);

    let (vertex_buffer, slice) = factory.create_vertex_buffer_with_slice(&vertices, &index_data[..]);

    let data = pipe::Data {
        vbuf: vertex_buffer,
        out: main_color,
    };

    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
                glutin::Event::Closed => break 'main,
                _ => {},
            }
        }

        encoder.clear(&data.out, CLEAR_COLOR);
        encoder.draw(&slice, &pso, &data);
        encoder.flush(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
    }
}

fn render_commands(command_list: DisplayList) -> (Vec<Vertex>, Vec<u16>) {
    let mut vertices = Vec::new();
    let mut index_data = Vec::new();

    for command in command_list {
        match command {
            DisplayCommand::SolidRect(color, rect) => {
                let (mut v, mut i) = render_rect(color, rect);
                vertices.append(&mut v);
                index_data.append(&mut i);
            },
        }
    }
    return (vertices, index_data);
}

fn render_rect(color: String, rect: Rect) -> (Vec<Vertex>, Vec<u16>) {
    let vertices = vec![
        Vertex { pos: [0.5, -0.5], color: [0.5, 0.0, 0.0] },
        Vertex { pos: [-0.5, -0.5], color: [0.5, 0.0, 0.0] },
        Vertex { pos: [-0.5, 0.5], color: [0.5, 0.0, 0.0] },
        Vertex { pos: [0.5, 0.5], color: [0.5, 0.0, 0.0] },
    ];
    let index_data = vec![
        0, 1, 2, 2, 3, 0,
    ];

    return (vertices, index_data);
}

use layout::{LayoutBox, Rect};

pub type DisplayList = Vec<DisplayCommand>;

pub enum DisplayCommand {
    SolidRect(String, Rect),
}

pub fn build_display_commands(root: &LayoutBox) -> DisplayList {
    let mut commands = Vec::new();
    render_layout_box(&mut commands, root);
    commands
}

fn render_layout_box(commands: &mut DisplayList, layout_box: &LayoutBox) {
    render_background(commands, layout_box);
    render_borders(commands, layout_box);
    //TODO: Render text

    for child in &layout_box.children {
        render_layout_box(commands, child);
    }
}

fn render_background(commands: &mut DisplayList, layout_box: &LayoutBox) {
    get_color(layout_box, "background").map(|color|
        commands.push(DisplayCommand::SolidRect(color, layout_box.dimensions.border_box())));
}

fn get_color(layout_box: &LayoutBox, name: &str) -> Option<String> {
    return None;
}

fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
    let color = match get_color(layout_box, "border-color") {
        Some(color) => color,
        _ => return,
    };

    let d = &layout_box.dimensions;
    let border_box = d.border_box();

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y,
        width: d.border.left,
        height: border_box.height,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x + border_box.width - d.border.right,
        y: border_box.y,
        width: d.border.right,
        height: border_box.height,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y,
        width: border_box.width,
        height: d.border.top,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y + border_box.height - d.border.bottom,
        width: border_box.width,
        height: d.border.bottom,
    }));
}
<commit_msg>rendering transformed boxes<commit_after>//! The `render` module takes a tree of layout boxes and paints the screen.

// TODO move this file into it's own module
// TODO seperate drawing logic from command building logic

use gfx;
use gfx_window_glutin;
use glutin;

use gfx::traits::FactoryExt;
use gfx::Device;

pub type DepthFormat = gfx::format::DepthStencil;
pub type ColorFormat = gfx::format::Rgba8;

// TODO integrate with layout module for screen resizing
const SCREEN_WIDTH: usize = 1024;
const SCREEN_HEIGHT: usize = 768;

gfx_defines!{
    vertex Vertex {
        pos: [f32; 2] = "a_Pos",
        color: [f32; 3] = "a_Color",
    }

    pipeline pipe {
        vbuf: gfx::VertexBuffer<Vertex> = (),
        out: gfx::RenderTarget<ColorFormat> = "Target0",
    }
}

const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];

pub fn render_loop() {
    let builder = glutin::WindowBuilder::new()
        .with_title(String::from("feOxy"))
        .with_dimensions(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
        .with_vsync();

    let (window, mut device, mut factory, main_color, _main_depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder);

    let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();

    let pso = factory.create_pipeline_simple(
        include_bytes!("shaders/triangle.glslv"),
        include_bytes!("shaders/triangle.glslf"),
        pipe::new()
    ).unwrap();

    let (vertices, index_data) = render_commands(vec![
        DisplayCommand::SolidRect(String::from("red"), Rect {x: 100.0, y: 100.0, height: 100.0, width: 100.0 }),
        DisplayCommand::SolidRect(String::from("green"), Rect {x: 0.0, y: 100.0, height: 100.0, width: 100.0 }),
        DisplayCommand::SolidRect(String::from("blue"), Rect {x: 100.0, y: 0.0, height: 100.0, width: 100.0 })
    ]);

    let (vertex_buffer, slice) = factory.create_vertex_buffer_with_slice(&vertices, &index_data[..]);

    let data = pipe::Data {
        vbuf: vertex_buffer,
        out: main_color,
    };

    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
                glutin::Event::Closed => break 'main,
                _ => {},
            }
        }

        encoder.clear(&data.out, CLEAR_COLOR);
        encoder.draw(&slice, &pso, &data);
        encoder.flush(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
    }
}

fn render_commands(command_list: DisplayList) -> (Vec<Vertex>, Vec<u16>) {
    let mut vertices = Vec::new();
    let mut index_data = Vec::new();

    for command in command_list {
        match command {
            DisplayCommand::SolidRect(color, rect) => {
                let c;
                if color == "red" {
                    c = [0.5, 0.0, 0.0];
                } else if color == "green" {
                    c = [0.0, 0.5, 0.0];
                } else {
                    c = [0.0, 0.0, 0.5];
                };
                let (mut v, mut i) = render_rect(&c, rect);
                vertices.append(&mut v);
                index_data.append(&mut i);
            },
        }
    }
    return (vertices, index_data);
}

fn render_rect(c: &[f32; 3], rect: Rect) -> (Vec<Vertex>, Vec<u16>) {
    println!("{:?}", rect);
    let (x, y, h, w) = transform_rect(rect);
    let vertices = vec![
        Vertex { pos: [x + w, y], color: *c },
        Vertex { pos: [x, y], color: *c },
        Vertex { pos: [x, y + h], color: *c },
        Vertex { pos: [x + w, y + h], color: *c },
    ];
    let index_data = vec![
        0, 1, 2, 2, 3, 0,
        4, 5, 6, 6, 7, 4,
        8, 9, 10, 10, 11, 8,
    ];

    return (vertices, index_data);
}

/// Transforms a rect into gfx coordinates based on screen size.
///
/// layout_box coord system:    gfx obj coord system:  gfx screen coord system:
///  (x, y)    (x+w, y)           (x, y+h) (x+w, y+h)     (-1, 1)    (1,1)
///     +-------+                     +-------+             +-------+
///     |       |                     |       |             |       |
///     |       |                     |       |             |       |
///     +-------+                     +-------+             +-------+
///  (x, y+h) (x+w, y+h)           (x, y)  (x+w, y)     (-1, -1)  (1, -1)
fn transform_rect(rect: Rect) -> (f32, f32, f32, f32) {
    let w = rect.width / SCREEN_WIDTH as f32 * 2.0;
    let h = rect.height / SCREEN_HEIGHT as f32 * 2.0;
    let x = rect.x / SCREEN_WIDTH as f32 * 2.0 - 1.0;
    let y = -(rect.y / SCREEN_HEIGHT as f32 * 2.0 - 1.0 + h);

    println!("x: {}, y: {}, w: {}, h: {}", x, y, w, h);

    (x, y, h, w)
}

use layout::{LayoutBox, Rect};

pub type DisplayList = Vec<DisplayCommand>;

pub enum DisplayCommand {
    SolidRect(String, Rect),
}

pub fn build_display_commands(root: &LayoutBox) -> DisplayList {
    let mut commands = Vec::new();
    render_layout_box(&mut commands, root);
    commands
}

fn render_layout_box(commands: &mut DisplayList, layout_box: &LayoutBox) {
    render_background(commands, layout_box);
    render_borders(commands, layout_box);
    //TODO: Render text

    for child in &layout_box.children {
        render_layout_box(commands, child);
    }
}

fn render_background(commands: &mut DisplayList, layout_box: &LayoutBox) {
    get_color(layout_box, "background").map(|color|
        commands.push(DisplayCommand::SolidRect(color, layout_box.dimensions.border_box())));
}

fn get_color(layout_box: &LayoutBox, name: &str) -> Option<String> {
    return None;
}

fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
    let color = match get_color(layout_box, "border-color") {
        Some(color) => color,
        _ => return,
    };

    let d = &layout_box.dimensions;
    let border_box = d.border_box();

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y,
        width: d.border.left,
        height: border_box.height,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x + border_box.width - d.border.right,
        y: border_box.y,
        width: d.border.right,
        height: border_box.height,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y,
        width: border_box.width,
        height: d.border.top,
    }));

    commands.push(DisplayCommand::SolidRect(color.clone(), Rect {
        x: border_box.x,
        y: border_box.y + border_box.height - d.border.bottom,
        width: border_box.width,
        height: d.border.bottom,
    }));
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::sync::{Arc, Mutex, RwLock, Weak};

use actors::{Actor, ActorRef, ActorSystem, CanReceive, Message, Props};

/// Special messages issued by the actor system.
#[derive(Clone)]
pub enum SystemMessage {
    /// Restarts the actor by repa=lacing it with a new version created with its Props.
    Restart,

    /// Makes the actor launch its initialisation.
    Start,

    /// Tells an actor that its child failed.
    Failure(Arc<CanReceive>),
}

enum Ref<T> {
    StrongRef(Arc<T>),
    WeakRef(Weak<T>),
}

/// Main interface for accessing the main Actor information (system, mailbox, sender, props...).
pub struct ActorCell<Args: Message, M: Message, A: Actor<M> + 'static> {
    // We have an inner structure in order to be able to generate new ActorCell easily.
    inner_cell: Ref<InnerActorCell<Args, M, A>>,
}

impl<Args: Message, M: Message, A: Actor<M>> Clone for ActorCell<Args, M, A> {
    fn clone(&self) -> ActorCell<Args, M, A> {
        ActorCell {
            inner_cell: Ref::WeakRef(match self.inner_cell {
                Ref::StrongRef(inner) => Arc::downgrade(&inner),
                Ref::WeakRef(inner) => inner.clone(),
            })
        }
    }
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> ActorCell<Args, M, A> {
    /// Creates a new ActorCell.
    pub fn new(actor: A, props: Props<Args, M, A>, system: ActorSystem, father: Arc<CanReceive>) -> ActorCell<Args, M, A> {
        ActorCell {
            inner_cell: Ref::StrongRef(Arc::new(InnerActorCell::new(actor, props, system, father))),
        }
    }

    /// Puts a message with its sender in the Actor's mailbox and schedules the Actor.
    pub fn receive_message(&self, message: M, sender: Arc<CanReceive >) {
        let inner = match self.inner_cell {
            Ref::StrongRef(inner) => inner,
            Ref::WeakRef(inner) => match inner.upgrade() {
                Some(inner) => inner,
                None => {
                    println!("A message was send to a ref to a stopped actor");
                    return;
                },
            }
        };
        inner.receive_message(message, sender);
        inner.system.enqueue_actor(self.actor_ref());
    }

    /// Puts a system message with its sender in the Actor's system mailbox and schedules the Actor.
    pub fn receive_system_message(&self, system_message: SystemMessage) {
        self.inner_cell.receive_system_message(system_message);
        self.inner_cell.system.enqueue_actor(self.actor_ref());
    }

    /// Makes the Actor handle an envelope in its mailbaox.
    pub fn handle_envelope(&self) {
        self.inner_cell.handle_envelope(self.clone());
    }
}

/// This is the API that Actors are supposed to see of their context while handling a message.
pub trait ActorContext<Args: Message, M: Message, A: Actor<M> + 'static> {
    /// Returns an ActorRef of the Actor.
    fn actor_ref(&self) -> ActorRef<Args, M, A>;

    /// Spawns an actor.
    ///
    /// Note that the supervision is not yet implemented so it does the same as creating an actor
    /// through the actor system.
    fn actor_of<ArgBis: Message, MBis: Message, ABis: Actor<MBis> + 'static>(&self, props: Props<ArgBis, MBis, ABis>) -> ActorRef<ArgBis, MBis, ABis>;

    /// Sends a Message to the targeted CanReceive<M>.
    fn tell<MessageTo: Message, T: CanReceive>(&self, to: T, message: MessageTo);

    /// Returns an Arc to the sender of the message being handled.
    fn sender(&self) -> Arc<CanReceive >;

    /// Children of the actor.
    fn children(&self) -> Vec<Arc<CanReceive>>;

    /// Lifecycle monitoring, list of monitored actors.
    fn monitoring(&self) -> Vec<Arc<CanReceive>>;
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> ActorContext<Args, M, A> for ActorCell<Args, M, A> {
    fn actor_ref(&self) -> ActorRef<Args, M, A> {
        ActorRef::with_cell(self.clone())
    }

    fn actor_of<ArgBis: Message, MBis: Message, ABis: Actor<MBis> + 'static>(&self, props: Props<ArgBis, MBis, ABis>) -> ActorRef<ArgBis, MBis, ABis> {
        let actor = props.create();
        let actor_cell = ActorCell {
            inner_cell: Ref::StrongRef(Arc::new(InnerActorCell::new(actor, props, self.inner_cell.system.clone(),
                                                     Arc::new(self.actor_ref())))),
        };
        let child = ActorRef::with_cell(actor_cell);
        {self.inner_cell.children.lock().unwrap().push(Arc::new(child.clone()));}
        {self.inner_cell.monitoring.lock().unwrap().push(Arc::new(child.clone()));}
        child.receive_system_message(SystemMessage::Start);
        child
    }

    fn tell<MessageTo: Message, T: CanReceive>(&self, to: T, message: MessageTo) {
        to.receive(Box::new(message), Arc::new(self.actor_ref()));
    }

    fn sender(&self) -> Arc<CanReceive > {
        self.inner_cell.current_sender.lock().unwrap().as_ref().unwrap().clone()
    }

    fn children(&self) -> Vec<Arc<CanReceive>> {
        self.inner_cell.children.lock().unwrap().clone()
    }

    fn monitoring(&self) -> Vec<Arc<CanReceive>> {
        self.inner_cell.monitoring.lock().unwrap().clone()
    }
}

struct Failsafe {
    father: Arc<CanReceive>,
    child: Arc<CanReceive>,
    active: bool,
}

impl Failsafe {
    fn new(father: Arc<CanReceive>, child: Arc<CanReceive>) -> Failsafe {
        Failsafe {
            father: father,
            child: child,
            active: true,
        }
    }

    fn cancel(mut self) {
        self.active = false;
    }
}

impl Drop for Failsafe {
    fn drop(&mut self) {
        if self.active {
            self.father.receive_system_message(SystemMessage::Failure(self.child.clone()));
        }
    }
}

struct InnerActorCell<Args: Message, M: Message, A: Actor<M> + 'static> {
    actor: RwLock<A>,
    mailbox: Mutex<VecDeque<Envelope<M>>>,
    system_mailbox: Mutex<VecDeque<SystemMessage>>,
    props: Props<Args, M, A>,
    system: ActorSystem,
    current_sender: Mutex<Option<Arc<CanReceive>>>,
    busy: Mutex<()>,
    father: Arc<CanReceive>,
    children: Mutex<Vec<Arc<CanReceive>>>,
    monitoring: Mutex<Vec<Arc<CanReceive>>>,
    _monitored: Mutex<Vec<Arc<CanReceive>>>,
}

struct Envelope<M> {
    message: M,
    sender: Arc<CanReceive>,
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> InnerActorCell<Args, M, A> {
    fn new(actor: A, props: Props<Args, M, A>, system: ActorSystem, father: Arc<CanReceive>) -> InnerActorCell<Args, M, A> {
        InnerActorCell {
            actor: RwLock::new(actor),
            mailbox: Mutex::new(VecDeque::new()),
            system_mailbox: Mutex::new(VecDeque::new()),
            props: props,
            system: system,
            current_sender: Mutex::new(None),
            busy: Mutex::new(()),
            father: father.clone(),
            children: Mutex::new(Vec::new()),
            monitoring: Mutex::new(Vec::new()),
            _monitored: Mutex::new(vec![father.clone()]),
        }
    }

    fn receive_envelope(&self, envelope: Envelope<M>) {
        self.mailbox.lock().unwrap().push_back(envelope);
    }

    fn receive_message(&self, message: M, sender: Arc<CanReceive>) {
        self.receive_envelope(Envelope{message: message, sender: sender});
    }

    fn receive_system_message(&self, system_message: SystemMessage) {
        self.system_mailbox.lock().unwrap().push_back(system_message);
    }

    fn handle_envelope(&self, context: ActorCell<Args, M, A>) {
        // Now we do not want users to be able to touch current_sender while the actor is busy.
        let _lock = self.busy.lock();
        let failsafe = Failsafe::new(self.father.clone(), Arc::new(context.actor_ref()));
        // System messages are handled first, so that we can restart an actor if he failed without
        // loosing the messages in the mailbox.
        // NOTE: This does not break the fact that messages sent by the same actor are treated in
        // the order they are sent (if all to the same target actor), as system messages must not
        // be sent by other actors by the user.
        if let Some(message) = self.system_mailbox.lock().unwrap().pop_front() {
            match message {
                SystemMessage::Restart => self.restart(),
                SystemMessage::Start => self.start(),
                SystemMessage::Failure(actor) => actor.receive_system_message(SystemMessage::Restart),
            }
            failsafe.cancel();
            return;
        }
        let envelope = match self.mailbox.lock().unwrap().pop_front() {
            Some(envelope) => envelope,
            None => {
                failsafe.cancel();
                return;
            }
        };
        {
            let mut current_sender = self.current_sender.lock().unwrap();
            *current_sender = Some(envelope.sender.clone());
        };
        {
            let actor = self.actor.read().unwrap();
            actor.receive(envelope.message, context);
        }
        failsafe.cancel();
    }

    fn start(&self) {
        self.actor.write().unwrap().pre_start();
    }

    fn restart(&self) {
        let mut actor = self.actor.write().unwrap();
        actor.pre_restart();
        *actor = self.props.create();
        actor.post_restart();
    }
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> Drop for InnerActorCell<Args, M, A> {
    fn drop(&mut self) {
        println!("dropped an actor cell");
    }
}

<commit_msg>WIP - borrowing issues<commit_after>use std::collections::VecDeque;
use std::sync::{Arc, Mutex, RwLock, Weak};

use actors::{Actor, ActorRef, ActorSystem, CanReceive, Message, Props};

/// Special messages issued by the actor system.
#[derive(Clone)]
pub enum SystemMessage {
    /// Restarts the actor by repa=lacing it with a new version created with its Props.
    Restart,

    /// Makes the actor launch its initialisation.
    Start,

    /// Tells an actor that its child failed.
    Failure(Arc<CanReceive>),
}

enum Ref<T> {
    StrongRef(Arc<T>),
    WeakRef(Weak<T>),
}

/// Main interface for accessing the main Actor information (system, mailbox, sender, props...).
pub struct ActorCell<Args: Message, M: Message, A: Actor<M> + 'static> {
    // We have an inner structure in order to be able to generate new ActorCell easily.
    inner_cell: Ref<InnerActorCell<Args, M, A>>,
}

impl<Args: Message, M: Message, A: Actor<M>> Clone for ActorCell<Args, M, A> {
    fn clone(&self) -> ActorCell<Args, M, A> {
        ActorCell {
            inner_cell: Ref::WeakRef(match self.inner_cell {
                Ref::StrongRef(ref inner) => Arc::downgrade(&inner),
                Ref::WeakRef(ref inner) => inner.clone(),
            })
        }
    }
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> ActorCell<Args, M, A> {
    /// Creates a new ActorCell.
    pub fn new(actor: A, props: Props<Args, M, A>, system: ActorSystem, father: Arc<CanReceive>) -> ActorCell<Args, M, A> {
        ActorCell {
            inner_cell: Ref::StrongRef(Arc::new(InnerActorCell::new(actor, props, system, father))),
        }
    }

    /// Puts a message with its sender in the Actor's mailbox and schedules the Actor.
    pub fn receive_message(&self, message: M, sender: Arc<CanReceive >) {
        // TODO(gamazeps) make  a macro for this.
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner.clone(),
                None => {
                    println!("A message was send to a ref to a stopped actor");
                    return;
                },
            }
        };
        inner.receive_message(message, sender);
        inner.system.enqueue_actor(self.actor_ref());
    }

    /// Puts a system message with its sender in the Actor's system mailbox and schedules the Actor.
    pub fn receive_system_message(&self, system_message: SystemMessage) {
        // TODO(gamazeps) make  a macro for this.
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner,
                None => {
                    println!("A message was send to a ref to a stopped actor");
                    return;
                },
            }
        };
        inner.receive_system_message(system_message);
        inner.system.enqueue_actor(self.actor_ref());
    }

    /// Makes the Actor handle an envelope in its mailbaox.
    pub fn handle_envelope(&self) {
        // TODO(gamazeps) make  a macro for this.
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner,
                None => {
                    println!("A message was send to a ref to a stopped actor");
                    return;
                },
            }
        };
        inner.handle_envelope(self.clone());
    }
}

/// This is the API that Actors are supposed to see of their context while handling a message.
pub trait ActorContext<Args: Message, M: Message, A: Actor<M> + 'static> {
    /// Returns an ActorRef of the Actor.
    fn actor_ref(&self) -> ActorRef<Args, M, A>;

    /// Spawns an actor.
    ///
    /// Note that the supervision is not yet implemented so it does the same as creating an actor
    /// through the actor system.
    fn actor_of<ArgBis: Message, MBis: Message, ABis: Actor<MBis> + 'static>(&self, props: Props<ArgBis, MBis, ABis>) -> ActorRef<ArgBis, MBis, ABis>;

    /// Sends a Message to the targeted CanReceive<M>.
    fn tell<MessageTo: Message, T: CanReceive>(&self, to: T, message: MessageTo);

    /// Returns an Arc to the sender of the message being handled.
    fn sender(&self) -> Arc<CanReceive >;

    /// Children of the actor.
    fn children(&self) -> Vec<Arc<CanReceive>>;

    /// Lifecycle monitoring, list of monitored actors.
    fn monitoring(&self) -> Vec<Arc<CanReceive>>;
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> ActorContext<Args, M, A> for ActorCell<Args, M, A> {
    fn actor_ref(&self) -> ActorRef<Args, M, A> {
        ActorRef::with_cell(self.clone())
    }

    fn actor_of<ArgBis: Message, MBis: Message, ABis: Actor<MBis> + 'static>(&self, props: Props<ArgBis, MBis, ABis>) -> ActorRef<ArgBis, MBis, ABis> {
        let actor = props.create();
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner.clone(),
                None => {
                    panic!("Tried to create an actor from the context of a no longer existing actor");
                },
            }
        };
        let inner_cell = InnerActorCell::new(actor, props, inner.system.clone(),
                                             Arc::new(self.actor_ref()));
        let actor_cell = ActorCell {
            inner_cell: Ref::StrongRef(Arc::new(inner_cell)),
        };
        let child = ActorRef::with_cell(actor_cell);
        {inner.children.lock().unwrap().push(Arc::new(child.clone()));}
        {inner.monitoring.lock().unwrap().push(Arc::new(child.clone()));}
        child.receive_system_message(SystemMessage::Start);
        child
    }

    fn tell<MessageTo: Message, T: CanReceive>(&self, to: T, message: MessageTo) {
        to.receive(Box::new(message), Arc::new(self.actor_ref()));
    }

    fn sender(&self) -> Arc<CanReceive > {
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner.clone(),
                None => {
                    panic!("Tried to get a sender from the context of a no longer existing actor");
                },
            }
        };
        inner.current_sender.lock().unwrap().as_ref().unwrap().clone()
    }

    fn children(&self) -> Vec<Arc<CanReceive>> {
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner.clone(),
                None => {
                    panic!("Tried to get the children from the context of a no longer existing actor");
                },
            }
        };
        inner.children.lock().unwrap().clone()
    }

    fn monitoring(&self) -> Vec<Arc<CanReceive>> {
        let inner = match self.inner_cell {
            Ref::StrongRef(ref inner) => inner.clone(),
            Ref::WeakRef(ref inner) => match inner.upgrade() {
                Some(inner) => inner.clone(),
                None => {
                    panic!("Tried to get the monitored actors from the context of a no longer existing actor");
                },
            }
        };
        inner.monitoring.lock().unwrap().clone()
    }
}

struct Failsafe {
    father: Arc<CanReceive>,
    child: Arc<CanReceive>,
    active: bool,
}

impl Failsafe {
    fn new(father: Arc<CanReceive>, child: Arc<CanReceive>) -> Failsafe {
        Failsafe {
            father: father,
            child: child,
            active: true,
        }
    }

    fn cancel(mut self) {
        self.active = false;
    }
}

impl Drop for Failsafe {
    fn drop(&mut self) {
        if self.active {
            self.father.receive_system_message(SystemMessage::Failure(self.child.clone()));
        }
    }
}

struct InnerActorCell<Args: Message, M: Message, A: Actor<M> + 'static> {
    actor: RwLock<A>,
    mailbox: Mutex<VecDeque<Envelope<M>>>,
    system_mailbox: Mutex<VecDeque<SystemMessage>>,
    props: Props<Args, M, A>,
    system: ActorSystem,
    current_sender: Mutex<Option<Arc<CanReceive>>>,
    busy: Mutex<()>,
    father: Arc<CanReceive>,
    children: Mutex<Vec<Arc<CanReceive>>>,
    monitoring: Mutex<Vec<Arc<CanReceive>>>,
    _monitored: Mutex<Vec<Arc<CanReceive>>>,
}

struct Envelope<M> {
    message: M,
    sender: Arc<CanReceive>,
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> InnerActorCell<Args, M, A> {
    fn new(actor: A, props: Props<Args, M, A>, system: ActorSystem, father: Arc<CanReceive>) -> InnerActorCell<Args, M, A> {
        InnerActorCell {
            actor: RwLock::new(actor),
            mailbox: Mutex::new(VecDeque::new()),
            system_mailbox: Mutex::new(VecDeque::new()),
            props: props,
            system: system,
            current_sender: Mutex::new(None),
            busy: Mutex::new(()),
            father: father.clone(),
            children: Mutex::new(Vec::new()),
            monitoring: Mutex::new(Vec::new()),
            _monitored: Mutex::new(vec![father.clone()]),
        }
    }

    fn receive_envelope(&self, envelope: Envelope<M>) {
        self.mailbox.lock().unwrap().push_back(envelope);
    }

    fn receive_message(&self, message: M, sender: Arc<CanReceive>) {
        self.receive_envelope(Envelope{message: message, sender: sender});
    }

    fn receive_system_message(&self, system_message: SystemMessage) {
        self.system_mailbox.lock().unwrap().push_back(system_message);
    }

    fn handle_envelope(&self, context: ActorCell<Args, M, A>) {
        // Now we do not want users to be able to touch current_sender while the actor is busy.
        let _lock = self.busy.lock();
        let failsafe = Failsafe::new(self.father.clone(), Arc::new(context.actor_ref()));
        // System messages are handled first, so that we can restart an actor if he failed without
        // loosing the messages in the mailbox.
        // NOTE: This does not break the fact that messages sent by the same actor are treated in
        // the order they are sent (if all to the same target actor), as system messages must not
        // be sent by other actors by the user.
        if let Some(message) = self.system_mailbox.lock().unwrap().pop_front() {
            match message {
                SystemMessage::Restart => self.restart(),
                SystemMessage::Start => self.start(),
                SystemMessage::Failure(actor) => actor.receive_system_message(SystemMessage::Restart),
            }
            failsafe.cancel();
            return;
        }
        let envelope = match self.mailbox.lock().unwrap().pop_front() {
            Some(envelope) => envelope,
            None => {
                failsafe.cancel();
                return;
            }
        };
        {
            let mut current_sender = self.current_sender.lock().unwrap();
            *current_sender = Some(envelope.sender.clone());
        };
        {
            let actor = self.actor.read().unwrap();
            actor.receive(envelope.message, context);
        }
        failsafe.cancel();
    }

    fn start(&self) {
        self.actor.write().unwrap().pre_start();
    }

    fn restart(&self) {
        let mut actor = self.actor.write().unwrap();
        actor.pre_restart();
        *actor = self.props.create();
        actor.post_restart();
    }
}

impl<Args: Message, M: Message, A: Actor<M> + 'static> Drop for InnerActorCell<Args, M, A> {
    fn drop(&mut self) {
        println!("dropped an actor cell");
    }
}

<|endoftext|>


<commit_before>// Copyright 2015 Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the protein alphabet.
//!
//! # Example
//!
//! ```
//! use bio::alphabets;
//! let alphabet = alphabets::protein::alphabet();
//! assert!(alphabet.is_word(b"DEQsga"));
//! assert!(!alphabet.is_word(b"BzJ"));
//! ```

use crate::alphabets::Alphabet;

/// Returns the standard protein alphabet, containing the 20 common amino acids.
pub fn alphabet() -> Alphabet {
    Alphabet::new(&b"ARNDCEQGHILKMFPSTWYVarndceqghilkmfpstwyv"[..])
}

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

    #[test]
    fn is_word() {
        assert!(alphabet().is_word(b"PRSkl"));
    }

    #[test]
    fn is_no_word() {
        assert!(!alphabet().is_word(b"Bb"));
    }

    #[test]
    fn symbol_is_no_word() {
        assert!(!alphabet().is_word(b"#"));
    }

    #[test]
    fn number_is_no_word() {
        assert!(!alphabet().is_word(b"42"));
    }
}
<commit_msg>feat: adds iupac amino acid alpha (#444)<commit_after>// Copyright 2015 Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the protein alphabet.
//!
//! # Example
//!
//! ```
//! use bio::alphabets;
//! let alphabet = alphabets::protein::alphabet();
//! assert!(alphabet.is_word(b"DEQsga"));
//! assert!(!alphabet.is_word(b"BzJ"));
//! ```

use crate::alphabets::Alphabet;

/// Returns the standard protein alphabet, containing the 20 common amino acids.
pub fn alphabet() -> Alphabet {
    Alphabet::new(&b"ARNDCEQGHILKMFPSTWYVarndceqghilkmfpstwyv"[..])
}

/// Returns the IUPAC amino acid alphabet.
pub fn iupac_alphabet() -> Alphabet {
    Alphabet::new(b"ABCDEFGHIKLMNPQRSTVWXYZabcdefghiklmnpqrstvwxyz")
}

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

    #[test]
    fn is_word() {
        assert!(alphabet().is_word(b"PRSkl"));
    }

    #[test]
    fn is_no_word() {
        assert!(!alphabet().is_word(b"Bb"));
    }

    #[test]
    fn symbol_is_no_word() {
        assert!(!alphabet().is_word(b"#"));
    }

    #[test]
    fn number_is_no_word() {
        assert!(!alphabet().is_word(b"42"));
    }

    #[test]
    fn iupac_contains_iupac_chars() {
        assert!(iupac_alphabet().is_word(b"XMN"));
    }
}
<|endoftext|>


<commit_before>//! 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);
    }
}
<commit_msg>Removed `mut` on calls to `GameTime::tick()` in `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(&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(
            &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>/// This macro provides a more user-friendly wrapper around the `Select` struct.
///
/// It is similar in syntax to a `match` expression: It takes a list of cases,
/// each of the form `operation(arguments) => expression`. Note that
/// `expression` may be a block as well. The individual cases may optionally be
/// separated by commas. As with `match`, the whole macro invocation is treated
/// as an expression, so values can be returned from the individual cases.
///
/// A simple example to illustrate:
///
/// ```ignore
/// select_loop! {
///     send(tx0, value) => println!("Sent value to tx0!"),
///     send(tx1, value) => { println!("Sent value to tx1!") }
/// }
/// ```
///
/// Please keep in mind the standard rules of the `Select`:
///
/// 1. No two cases may use the same end of the same channel. In the example
///    above this means that even if `tx0` and `tx1` are different `Sender`
///    instances, they must not belong to the same channel.
///
/// The following operations are supported by the macro:
///
/// * **`send($tx:expr, $variable:ident) => ...`:** Attempt to `send` the value of
///   `$variable` with `$tx`. If sending fails, the value of `$variable` is
///   automatically recovered. For convenience, `$variable` is automatically
///   made mutable by the macro.
/// * **`send($tx:expr, mut $field:expr) => ...`:** Attempt to `send` the value of
///   `$variable` with `$tx`. If sending fails, the value of `$variable` is
///   automatically recovered. Different from the previous version, this version
///   assumes that `$field` is mutable. And while the macro accepts any
///   expression for `$field`, it only really makes sense to specify plain
///   variables or direct field references (e.g. `some_struct.some_field`).
/// * **`send($tx:expr, eval $expr:expr) => ...`:** Attempt to `send` the result of
///   evaluating `$expr` with `$tx`. *Warning:* $expr is evaluated once in every
///   loop iteration. In some iterations, its result may simply be discarded
///   with no actual attempt at sending it.
/// * **`recv($rx:expr, $variable:ident) => ...`:** Attempt to receive a value from
///   `$rx`. If successful, the received value will be available in `$variable`
///    for the expression of this case.
/// * **`recv($rx:expr, mut $variable:ident) => ...`:** Attempt to receive a value
///   from `$rx`. If successful, the received value will be available in the
///   mutable `$variable` for the expression of this case.
/// * **`recv($rx:expr, _) => ...`:** Attempt to receive a value
///   from `$rx`. If successful, the received value is discarded.
/// * **`disconnected() => ...`:** This case is triggered when all channels in the
///   loop have disconnected.
/// * **`would_block() => ...`:** This case is triggered when all channels in the
///   loop would block.
/// * **`timed_out($duration:expr) => ...`:** Enables a timeout for the select loop.
///   If the timeout is reached without any of the other cases triggering, this
///   case is triggered. If there are multiple `timed_out` cases, only the
///   duration from the last case is registered.
///
#[macro_export]
macro_rules! select_loop {
    // The main entrypoint
    {$($method:ident($($args:tt)*) => $body:expr$(,)*)*} => {
        #[allow(unused_mut, unused_variables)]
        {
            let mut state = $crate::Select::new();

            // Build the prelude.
            //
            // This currently performs two tasks:
            //
            // 1) Make all variables used in send(_, $ident) mutable (the
            //    variable will move into the loop anyway, so we can move it
            //    here as well).
            // 2) If a timeout was specified, overwrite the above state with one
            //    which has the timeout set.
            $(select_loop!(@prelude(state) $method($($args)*));)*

            // The actual select loop which a user would write manually
            #[allow(unreachable_code)]
            loop {
                #[allow(bad_style)]
                struct _DONT_USE_AN_UNLABELED_CONTINUE_OR_BREAK_IN_SELECT_LOOP;

                $(
                    // Build the actual method invocations.
                    select_loop! {
                        @impl(state)
                        $method($($args)*) => {
                            // This double-loop construct is used to guard against the user
                            // using unlabeled breaks and continues in their code.
                            //
                            // It works by abusing  ust's control flow analysis. If the user
                            // code (`$body`) contains an unlabeled break or continue, the
                            // inner loop will be broken with a result whose type doesn't match
                            // `_DONT_USE_AN_UNLABELED_CONTINUE_OR_BREAK_IN_SELECT_LOOP`, and
                            // that will show up in error messages.
                            let res;
                            let _: _DONT_USE_AN_UNLABELED_CONTINUE_OR_BREAK_IN_SELECT_LOOP = loop {
                                res = $body;
                                break _DONT_USE_AN_UNLABELED_CONTINUE_OR_BREAK_IN_SELECT_LOOP;
                            };
                            break res;
                        }
                    }
                )*
            }
        }
    };

    //The individual method invocations
    {@impl($state:ident) send($tx:expr, $val:ident) => $body:expr} => {
        match $state.send(&*&$tx, $val) {
            Ok(()) => {
                $body
            }
            Err($crate::SelectSendError(val)) => {
                $val = val;
            }
        }
    };
    {@impl($state:ident) send($tx:expr, mut $val:expr) => $body:expr} => {
        match $state.send(&*&$tx, $val) {
            Ok(()) => {
                $body
            }
            Err($crate::SelectSendError(val)) => {
                $val = val;
            }
        }
    };
    {@impl($state:ident) send($tx:expr, eval $val:expr) => $body:expr} => {
        if let Ok(()) = $state.send(&*&$tx, $val) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, _) => $body:expr} => {
        if let Ok(_) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, $val:ident) => $body:expr} => {
        if let Ok($val) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, mut $val:ident) => $body:expr} => {
        if let Ok(mut $val) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) disconnected() => $body:expr} => {
        if $state.disconnected() {
            $body
        }
    };
    {@impl($state:ident) would_block() => $body:expr} => {
        if $state.would_block() {
            $body
        }
    };
    {@impl($state:ident) timed_out($_timeout:expr) => $body:expr} => {
        if $state.timed_out() {
            $body
        }
    };

    // The prelude helpers
    {@prelude($state:ident) send($tx:expr, $val:ident)} => {
        let mut $val = $val;
    };
    {@prelude($state:ident) timed_out($timeout:expr)} => {
        let mut $state = $crate::Select::with_timeout($timeout);
    };
    {@prelude($state:ident) $($tail:tt)*} => {};
}
<commit_msg>Also forbid unlabeled continue<commit_after>/// This macro provides a more user-friendly wrapper around the `Select` struct.
///
/// It is similar in syntax to a `match` expression: It takes a list of cases,
/// each of the form `operation(arguments) => expression`. Note that
/// `expression` may be a block as well. The individual cases may optionally be
/// separated by commas. As with `match`, the whole macro invocation is treated
/// as an expression, so values can be returned from the individual cases.
///
/// A simple example to illustrate:
///
/// ```ignore
/// select_loop! {
///     send(tx0, value) => println!("Sent value to tx0!"),
///     send(tx1, value) => { println!("Sent value to tx1!") }
/// }
/// ```
///
/// Please keep in mind the standard rules of the `Select`:
///
/// 1. No two cases may use the same end of the same channel. In the example
///    above this means that even if `tx0` and `tx1` are different `Sender`
///    instances, they must not belong to the same channel.
///
/// The following operations are supported by the macro:
///
/// * **`send($tx:expr, $variable:ident) => ...`:** Attempt to `send` the value of
///   `$variable` with `$tx`. If sending fails, the value of `$variable` is
///   automatically recovered. For convenience, `$variable` is automatically
///   made mutable by the macro.
/// * **`send($tx:expr, mut $field:expr) => ...`:** Attempt to `send` the value of
///   `$variable` with `$tx`. If sending fails, the value of `$variable` is
///   automatically recovered. Different from the previous version, this version
///   assumes that `$field` is mutable. And while the macro accepts any
///   expression for `$field`, it only really makes sense to specify plain
///   variables or direct field references (e.g. `some_struct.some_field`).
/// * **`send($tx:expr, eval $expr:expr) => ...`:** Attempt to `send` the result of
///   evaluating `$expr` with `$tx`. *Warning:* $expr is evaluated once in every
///   loop iteration. In some iterations, its result may simply be discarded
///   with no actual attempt at sending it.
/// * **`recv($rx:expr, $variable:ident) => ...`:** Attempt to receive a value from
///   `$rx`. If successful, the received value will be available in `$variable`
///    for the expression of this case.
/// * **`recv($rx:expr, mut $variable:ident) => ...`:** Attempt to receive a value
///   from `$rx`. If successful, the received value will be available in the
///   mutable `$variable` for the expression of this case.
/// * **`recv($rx:expr, _) => ...`:** Attempt to receive a value
///   from `$rx`. If successful, the received value is discarded.
/// * **`disconnected() => ...`:** This case is triggered when all channels in the
///   loop have disconnected.
/// * **`would_block() => ...`:** This case is triggered when all channels in the
///   loop would block.
/// * **`timed_out($duration:expr) => ...`:** Enables a timeout for the select loop.
///   If the timeout is reached without any of the other cases triggering, this
///   case is triggered. If there are multiple `timed_out` cases, only the
///   duration from the last case is registered.
///
#[macro_export]
macro_rules! select_loop {
    // The main entrypoint
    {$($method:ident($($args:tt)*) => $body:expr$(,)*)*} => {
        #[allow(unused_mut, unused_variables)]
        {
            let mut state = $crate::Select::new();

            // Build the prelude.
            //
            // This currently performs two tasks:
            //
            // 1) Make all variables used in send(_, $ident) mutable (the
            //    variable will move into the loop anyway, so we can move it
            //    here as well).
            // 2) If a timeout was specified, overwrite the above state with one
            //    which has the timeout set.
            $(select_loop!(@prelude(state) $method($($args)*));)*

            // The actual select loop which a user would write manually
            #[allow(unreachable_code)]
            loop {
                #[allow(bad_style)]
                struct _DONT_USE_AN_UNLABELED_BREAK_IN_SELECT_LOOP;

                $(
                    // Build the actual method invocations.
                    select_loop! {
                        @impl(state)
                        $method($($args)*) => {
                            // This double-loop construct is used to guard against the user
                            // using unlabeled breaks and continues in their code.
                            // It works by abusing Rust's control flow analysis.
                            //
                            // If the user code (`$body`) contains an unlabeled break, the
                            // inner loop will be broken with a result whose type doesn't match
                            // `_DONT_USE_AN_UNLABELED_BREAK_IN_SELECT_LOOP`, and that
                            // will show up in error messages.
                            //
                            // Similarly, if the user code contains an unlabeled continue,
                            // the inner loop will try to assign a value to variable
                            // `_DONT_USE_AN_UNLABELED_CONTINUE_IN_SELECT_LOOP` twice, which
                            // will again show up in error messages.
                            #[allow(bad_style)]
                            let _DONT_USE_AN_UNLABELED_CONTINUE_IN_SELECT_LOOP;

                            let res;
                            let _: _DONT_USE_AN_UNLABELED_BREAK_IN_SELECT_LOOP = loop {
                                _DONT_USE_AN_UNLABELED_CONTINUE_IN_SELECT_LOOP = ();
                                res = $body;
                                break _DONT_USE_AN_UNLABELED_BREAK_IN_SELECT_LOOP;
                            };
                            break res;
                        }
                    }
                )*
            }
        }
    };

    //The individual method invocations
    {@impl($state:ident) send($tx:expr, $val:ident) => $body:expr} => {
        match $state.send(&*&$tx, $val) {
            Ok(()) => {
                $body
            }
            Err($crate::SelectSendError(val)) => {
                $val = val;
            }
        }
    };
    {@impl($state:ident) send($tx:expr, mut $val:expr) => $body:expr} => {
        match $state.send(&*&$tx, $val) {
            Ok(()) => {
                $body
            }
            Err($crate::SelectSendError(val)) => {
                $val = val;
            }
        }
    };
    {@impl($state:ident) send($tx:expr, eval $val:expr) => $body:expr} => {
        if let Ok(()) = $state.send(&*&$tx, $val) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, _) => $body:expr} => {
        if let Ok(_) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, $val:ident) => $body:expr} => {
        if let Ok($val) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) recv($rx:expr, mut $val:ident) => $body:expr} => {
        if let Ok(mut $val) = $state.recv(&*&$rx) {
            $body
        }
    };
    {@impl($state:ident) disconnected() => $body:expr} => {
        if $state.disconnected() {
            $body
        }
    };
    {@impl($state:ident) would_block() => $body:expr} => {
        if $state.would_block() {
            $body
        }
    };
    {@impl($state:ident) timed_out($_timeout:expr) => $body:expr} => {
        if $state.timed_out() {
            $body
        }
    };

    // The prelude helpers
    {@prelude($state:ident) send($tx:expr, $val:ident)} => {
        let mut $val = $val;
    };
    {@prelude($state:ident) timed_out($timeout:expr)} => {
        let mut $state = $crate::Select::with_timeout($timeout);
    };
    {@prelude($state:ident) $($tail:tt)*} => {};
}
<|endoftext|>


<commit_before>use std::ffi::CString;

use rustc::lib::llvm;
use rustc::lib::llvm::{ ContextRef
                      , ModuleRef
                      , ValueRef
                      , BuilderRef
                  };
use seax::compiler_tools::ForkTable;

use position::Positional;

pub type IRResult = Result<ValueRef, Positional<String>>;
pub type SymbolTable<'a> = ForkTable<'a, &'a str, ValueRef>;

/// Trait for an object that can be compiled to LLVM IR
pub trait ToIR {
    fn to_ir(&self) -> IRResult;
}

/// LLVM compilation context.
///
/// This is based rather loosely on MIT License code from
/// the [iron-kaleidoscope](https://github.com/jauhien/iron-kaleidoscope)
/// tutorial, and from [`librustc_trans`](https://github.com/rust-lang/rust/blob/master/src/librustc_trans/trans/mod.rs)
/// from the Rust compiler.
pub struct LLVMContext<'a> {
    pub llctx: ContextRef,
    pub llmod: ModuleRef,
    pub llbuilder: BuilderRef,
    pub names: SymbolTable<'a>
}

// because we are in the Raw Pointer Sadness Zone (read: unsafe),
// it is necessary that we assert that everything exists.
macro_rules! not_null {
    ($target:expr) => ({
        let e = $target;
        if e.is_null() {
            panic!("assertion failed: {} returned null!", stringify!($target));
        } else { e }
    })
}

impl<'a> LLVMContext<'a> {
    pub fn new(module_name: &str) -> Self {
        let name = CString::new(module_name).unwrap();
        unsafe {
            let ctx = not_null!(llvm::LLVMContextCreate());
            LLVMContext {
                llctx: ctx
              , llmod: not_null!(llvm::LLVMModuleCreateWithNameInContext(name.into_raw(), ctx))
              , llbuilder: not_null!(llvm::LLVMCreateBuilderInContext(ctx))
              , names: SymbolTable::new()
            }
        }
    }
}

impl<'a> Drop for LLVMContext<'a> {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMDisposeModule(self.llmod);
            llvm::LLVMDisposeBuilder(self.llbuilder);
            llvm::LLVMContextDispose(self.llctx);
        }
    }
}
<commit_msg>ToIR now takes a Context (oops)<commit_after>use std::ffi::CString;

use rustc::lib::llvm;
use rustc::lib::llvm::{ ContextRef
                      , ModuleRef
                      , ValueRef
                      , BuilderRef
                  };
use seax::compiler_tools::ForkTable;

use position::Positional;

pub type IRResult = Result<ValueRef, Positional<String>>;
pub type SymbolTable<'a> = ForkTable<'a, &'a str, ValueRef>;

/// Trait for an object that can be compiled to LLVM IR
pub trait ToIR {
    fn to_ir(&self, context: LLVMContext) -> IRResult;
}

/// LLVM compilation context.
///
/// This is based rather loosely on MIT License code from
/// the [iron-kaleidoscope](https://github.com/jauhien/iron-kaleidoscope)
/// tutorial, and from [`librustc_trans`](https://github.com/rust-lang/rust/blob/master/src/librustc_trans/trans/mod.rs)
/// from the Rust compiler.
pub struct LLVMContext<'a> {
    pub llctx: ContextRef,
    pub llmod: ModuleRef,
    pub llbuilder: BuilderRef,
    pub names: SymbolTable<'a>
}

// because we are in the Raw Pointer Sadness Zone (read: unsafe),
// it is necessary that we assert that everything exists.
macro_rules! not_null {
    ($target:expr) => ({
        let e = $target;
        if e.is_null() {
            panic!("assertion failed: {} returned null!", stringify!($target));
        } else { e }
    })
}

impl<'a> LLVMContext<'a> {

    pub fn new(module_name: &str) -> Self {
        let name = CString::new(module_name).unwrap();
        unsafe {
            let ctx = not_null!(llvm::LLVMContextCreate());
            LLVMContext {
                llctx: ctx
              , llmod: not_null!(llvm::LLVMModuleCreateWithNameInContext(name.into_raw(), ctx))
              , llbuilder: not_null!(llvm::LLVMCreateBuilderInContext(ctx))
              , names: SymbolTable::new()
            }
        }
    }

    /// Dump the module's contents to stderr for debugging
    ///
    /// Apparently this is the only reasonable way to get a textual
    /// representation of a `ModuleRef` in `librustc_llvm`...
    pub fn dump(&self) {
        unsafe { llvm::LLVMDumpModule(self.llmod); }
    }
}

impl<'a> Drop for LLVMContext<'a> {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMDisposeModule(self.llmod);
            llvm::LLVMDisposeBuilder(self.llbuilder);
            llvm::LLVMContextDispose(self.llctx);
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLFieldSetElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFieldSetElementDerived, NodeCast};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFieldSetElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlformelement::HTMLFormElement;
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::validitystate::ValidityState;
use servo_util::str::{DOMString, StaticStringVec};

#[deriving(Encodable)]
pub struct HTMLFieldSetElement {
    pub htmlelement: HTMLElement
}

impl HTMLFieldSetElementDerived for EventTarget {
    fn is_htmlfieldsetelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLFieldSetElementTypeId))
    }
}

impl HTMLFieldSetElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFieldSetElement {
        HTMLFieldSetElement {
            htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFieldSetElement> {
        let element = HTMLFieldSetElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLFieldSetElementBinding::Wrap)
    }
}

pub trait HTMLFieldSetElementMethods {
    fn Disabled(&self) -> bool;
    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Name(&self) -> DOMString;
    fn SetName(&mut self, _name: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn Elements(&self) -> Temporary<HTMLCollection>;
    fn WillValidate(&self) -> bool;
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&mut self, _error: DOMString);
}

impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> {
    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&mut self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    // http://www.whatwg.org/html/#dom-fieldset-elements
    fn Elements(&self) -> Temporary<HTMLCollection> {
        struct ElementsFilter;
        impl CollectionFilter for ElementsFilter {
            fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool {
                static tag_names: StaticStringVec = &["button", "fieldset", "input",
                    "keygen", "object", "output", "select", "textarea"];
                let root: &JSRef<Element> = ElementCast::to_ref(root).unwrap();
                elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.deref().local_name)
            }
        }
        let node: &JSRef<Node> = NodeCast::from_ref(self);
        let filter = box ElementsFilter;
        let window = window_from_node(node).root();
        HTMLCollection::create(&*window, node, filter)
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&mut self, _error: DOMString) {
    }
}
<commit_msg>Remove needless '&mut self' from HTMLFieldSetElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLFieldSetElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFieldSetElementDerived, NodeCast};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFieldSetElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlformelement::HTMLFormElement;
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::validitystate::ValidityState;
use servo_util::str::{DOMString, StaticStringVec};

#[deriving(Encodable)]
pub struct HTMLFieldSetElement {
    pub htmlelement: HTMLElement
}

impl HTMLFieldSetElementDerived for EventTarget {
    fn is_htmlfieldsetelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLFieldSetElementTypeId))
    }
}

impl HTMLFieldSetElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFieldSetElement {
        HTMLFieldSetElement {
            htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFieldSetElement> {
        let element = HTMLFieldSetElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLFieldSetElementBinding::Wrap)
    }
}

pub trait HTMLFieldSetElementMethods {
    fn Disabled(&self) -> bool;
    fn SetDisabled(&self, _disabled: bool) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Name(&self) -> DOMString;
    fn SetName(&self, _name: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn Elements(&self) -> Temporary<HTMLCollection>;
    fn WillValidate(&self) -> bool;
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&self, _error: DOMString);
}

impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> {
    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    // http://www.whatwg.org/html/#dom-fieldset-elements
    fn Elements(&self) -> Temporary<HTMLCollection> {
        struct ElementsFilter;
        impl CollectionFilter for ElementsFilter {
            fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool {
                static tag_names: StaticStringVec = &["button", "fieldset", "input",
                    "keygen", "object", "output", "select", "textarea"];
                let root: &JSRef<Element> = ElementCast::to_ref(root).unwrap();
                elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.deref().local_name)
            }
        }
        let node: &JSRef<Node> = NodeCast::from_ref(self);
        let filter = box ElementsFilter;
        let window = window_from_node(node).root();
        HTMLCollection::create(&*window, node, filter)
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&self, _error: DOMString) {
    }
}
<|endoftext|>