<commit_before>//! The master module provides the Master struct which instructs Workers which
//! portions of the image they should render and collects their results to combine
//! into the final image.

use std::path::PathBuf;
use std::io::prelude::*;
use std::collections::HashMap;
use std::net::ToSocketAddrs;
use std::iter;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use image;
use mio::tcp::{TcpStream, Shutdown};
use mio::*;

use film::Image;
use exec::Config;
use exec::distrib::{worker, Instructions};
use sampler::BlockQueue;

#[derive(Debug)]
enum DistributedFrame {
    InProgress {
        frame: usize,
        // The number of workers who have reported results for this
        // frame so far
        num_reporting: usize,
        render: Image,
    },
    Completed,
}

#[derive(Clone, Debug)]
struct WorkerBuffer {
    pub buf: Vec<u8>,
    pub expected_size: usize,
    pub currently_read: usize,
}

impl WorkerBuffer {
    pub fn new() -> WorkerBuffer {
        WorkerBuffer { buf: Vec::new(), expected_size: 8, currently_read: 0 }
    }
}

pub struct Master {
    // Hostnames of the workers to send work too
    workers: Vec<String>,
    connections: Vec<TcpStream>,
    // Temporary buffers to store worker results in as they're
    // read in over TCP
    worker_buffers: Vec<WorkerBuffer>,
    config: Config,
    frames: HashMap<usize, DistributedFrame>,
    img_dim: (usize, usize),
    blocks_per_worker: usize,
    blocks_remainder: usize,
}

impl Master {
    /// Create a new master that will contact the worker nodes passed and
    /// send instructions on what parts of the scene to start rendering
    pub fn start_workers(workers: Vec<String>, config: Config, img_dim: (usize, usize))
                         -> (Master, EventLoop<Master>) {
        // Figure out how many blocks we have for this image and assign them to our workers
        let queue = BlockQueue::new((img_dim.0 as u32, img_dim.1 as u32), (8, 8), (0, 0));
        let blocks_per_worker = queue.len() / workers.len();
        let blocks_remainder = queue.len() % workers.len();
        println!("Have {} workers, each worker does {} blocks w/ {} remainder",
                 workers.len(), blocks_per_worker, blocks_remainder);

        let mut event_loop = EventLoop::<Master>::new().unwrap();
        let mut connections = Vec::new();

        // Connect to each worker and send instructions on what to render
        // I guess this should also be queue'd up and the writes actually performed asynchronously?
        // Otherwise we need to loop on write_all while waiting for the connection to open
        for (i, host) in workers.iter().enumerate() {
            let addr = (&host[..], worker::PORT).to_socket_addrs().unwrap().next().unwrap();
            println!("Connecting too {:?}", addr);
            match TcpStream::connect(&addr) {
                Ok(stream) => {
                    println!("Connected and writing");
                    println!("Adding stream to event loop");
                    // Each worker is identified in the event loop by their index in the vec
                    match event_loop.register(&stream, Token(i), EventSet::all(), PollOpt::level()){
                        Err(e) => println!("Error registering stream from {}: {}", host, e),
                        Ok(_) => {},
                    }
                    connections.push(stream);
                },
                Err(e) => println!("Failed to contact worker {}: {:?}", host, e),
            }
        }
        let worker_buffers: Vec<_> = iter::repeat(WorkerBuffer::new()).take(workers.len()).collect();
        let master = Master { workers: workers, connections: connections,
                              worker_buffers: worker_buffers, config: config,
                              frames: HashMap::new(),
                              img_dim: img_dim,
                              blocks_per_worker: blocks_per_worker,
                              blocks_remainder: blocks_remainder };
        (master, event_loop)
    }
    /// Read a result frame from a worker and save it into the list of frames we're collecting from
    /// all workers. Will save out the final render if all workers have reported results for this
    /// frame.
    fn save_results(&mut self, frame: worker::Frame) {
        // Find the frame this worker is referring to and add its results
        let frame_num = frame.frame as usize;
        println!("Worker reporting frame {}", frame_num);
        if let Some(df) = self.frames.get_mut(&frame_num) {
            match df {
                &mut DistributedFrame::InProgress { frame: _, ref mut num_reporting, ref mut render } => {
                    render.add_blocks(frame.block_size, &frame.blocks, &frame.pixels);
                    *num_reporting += 1;
                    println!("We have parts of this frame already");
                },
                &mut DistributedFrame::Completed => println!("Worker reporting on completed frame!?"),
            }
        }
        // TODO: Better way here? We get stuck because self.frames is counted as borrowed
        // from the if above, making this really awkward.
        if self.frames.get_mut(&frame_num).is_none() {
            // TODO: I need to seperate the render target from the actual image as the
            // filter here isn't used in this path and it doesn't make sense to have one
            let mut render = Image::new(self.img_dim);
            render.add_blocks(frame.block_size, &frame.blocks, &frame.pixels);
            let df = DistributedFrame::InProgress { frame: frame_num, num_reporting: 1, render: render};
            self.frames.insert(frame_num, df);
            println!("This is a new frame");
        }
        if let Some(df) = self.frames.get_mut(&frame_num) {
            let mut finished = false;
            match df {
                &mut DistributedFrame::InProgress { frame, num_reporting, ref render } => {
                    if num_reporting == self.workers.len() {
                        println!("We have completed frame {}", frame_num);
                        let out_file = match self.config.out_path.extension() {
                            Some(_) => self.config.out_path.clone(),
                            None => self.config.out_path.join(
                                PathBuf::from(format!("frame{:05}.png", frame))),
                        };
                        println!("Frame {}: rendered to '{}'\n--------------------",
                                 frame_num, out_file.display());
                        let img = render.get_srgb8();
                        let dim = render.dimensions();
                        match image::save_buffer(&out_file.as_path(), &img[..], dim.0 as u32,
                                                 dim.1 as u32, image::RGB(8)) {
                            Ok(_) => {},
                            Err(e) => println!("Error saving image, {}", e),
                        };
                        finished = true;
                    }
                },
                &mut DistributedFrame::Completed => println!("Can not save out already completed frame"),
            }
            // This is also a bit awkward, since we borrow the df in the match
            // we can't mark it finished in there. TODO: Better design?
            if finished {
                *df = DistributedFrame::Completed;
            }
        }
    }
    fn read_worker_buffer(&mut self, worker: usize) -> bool {
        let mut buf = &mut self.worker_buffers[worker];
        // If we haven't read the size of data being sent, read that now
        if buf.currently_read < 8 {
            // First 8 bytes are a u64 specifying the number of bytes being sent
            buf.buf.extend(iter::repeat(0u8).take(8));
            println!("Reading size header...");
            match self.connections[worker].read(&mut buf.buf[buf.currently_read..]) {
                Ok(n) => buf.currently_read += n,
                Err(e) => println!("Error reading results from worker {}: {}", self.workers[worker], e),
            }
            println!("Read {} bytes so far, must read {} in total", buf.currently_read, buf.expected_size);
            if buf.currently_read == buf.expected_size {
                println!("Got size header");
                // How many bytes we expect to get from the worker for a frame
                buf.expected_size = decode(&buf.buf[..]).unwrap();
                println!("Expecting {} bytes", buf.expected_size);
                // Extend the Vec so we've got enough room for the remaning bytes, minus the 8 for the
                // encoded size header
                buf.buf.extend(iter::repeat(0u8).take(buf.expected_size - 8));
            }
        }
        // If we've finished reading the size header we can now start reading the frame data
        if buf.currently_read >= 8 {
            println!("Reading from worker");
            match self.connections[worker].read(&mut buf.buf[buf.currently_read..]) {
                Ok(n) => buf.currently_read += n,
                Err(e) => println!("Error reading results from worker {}: {}", self.workers[worker], e),
            }
            println!("Read {} bytes so far, must read {} in total", buf.currently_read, buf.expected_size);
        }
        buf.currently_read == buf.expected_size
    }
}

impl Handler for Master {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Master>, token: Token, event: EventSet) {
        let worker = token.as_usize();
        println!("Event from {}: {:?}", worker, event);
        if event.is_error() {
            println!("Error connecting too {}", self.workers[worker]);
            match self.connections[worker].shutdown(Shutdown::Both) {
                Err(e) => println!("Error shutting down worker {}: {}", worker, e),
                Ok(_) => {},
            }
            // Remove the connection from the event loop
            match event_loop.deregister(&self.connections[worker]) {
                Err(e) => println!("Error deregistering worker {}: {}", worker, e),
                Ok(_) => {},
            }
        }
        // A worker is ready to receive instructions from us
        if event.is_writable() {
            let b_start = worker * self.blocks_per_worker;
            let b_count =
                if worker == self.workers.len() - 1 {
                    self.blocks_per_worker + self.blocks_remainder
                } else {
                    self.blocks_per_worker
                };
            let instr = Instructions::new(&self.config.scene_file,
                                          (self.config.frame_info.start, self.config.frame_info.end),
                                          b_start, b_count);
            println!("Sending instructions {:?} to {}", instr, self.workers[worker]);
            let bytes = encode(&instr, SizeLimit::Infinite).unwrap();
            println!("Encoded instructions size: {}", instr.encoded_size);
            // Loop until we successfully write the byes
            match self.connections[worker].write_all(&bytes[..]) {
                Err(e) => println!("Failed to send instructions to {}: {:?}", self.workers[worker], e),
                Ok(_) => println!("Instructions sent"),
            }
            // Register that we no longer care about writable events on this connection
            event_loop.reregister(&self.connections[worker], token,
                                  EventSet::readable() | EventSet::error() | EventSet::hup(),
                                  PollOpt::level()).expect("Re-registering failed");
        }
        // Some results are available from a worker
        if event.is_readable() {
            println!("Readable event from worker {}", worker);
            if self.read_worker_buffer(worker) {
                println!("Got all frame data, now parsing");
                let frame: worker::Frame = decode(&self.worker_buffers[worker].buf[..]).unwrap();
                println!("Saving frame results");
                self.save_results(frame);
                // Clean up our read buffer
                self.worker_buffers[worker].buf.clear();
                self.worker_buffers[worker].expected_size = 8;
                self.worker_buffers[worker].currently_read = 0;
            }
        }
        // If the worker has terminated, shutdown the read end of the connection
        if event.is_hup() {
            println!("Worker {} has hung up", worker);
            match self.connections[worker].shutdown(Shutdown::Read) {
                Err(e) => println!("Error shutting down worker {}: {}", worker, e),
                Ok(_) => {},
            }
            // Remove the connection from the event loop
            match event_loop.deregister(&self.connections[worker]) {
                Err(e) => println!("Error deregistering worker {}: {}", worker, e),
                Ok(_) => {},
            }
        }
        // After getting results from the worker we check if we've completed all our frames
        // and exit if so
        let all_complete = self.frames.values().fold(true,
                                |all, v| {
                                    match v {
                                        &DistributedFrame::Completed => true && all,
                                        _ => false,
                                    }
                                });
        // The frame start/end range is inclusive, so we must add 1 here
        let num_frames = self.config.frame_info.end - self.config.frame_info.start + 1;
        println!("Rendering {} frames have {}, all_complete? {}",
                 num_frames, self.frames.len(), all_complete);
        // TODO: We can't use frame_info.frames as this is not the `subset` of frames
        // we're rendering
        if self.frames.len() == num_frames && all_complete {
            println!("All frames have been rendered, master exiting");
            event_loop.shutdown();
        }
    }
}

<commit_msg>Use the hashmap entry API to clean up ugly lookup/insertion code<commit_after>//! The master module provides the Master struct which instructs Workers which
//! portions of the image they should render and collects their results to combine
//! into the final image.

use std::path::PathBuf;
use std::io::prelude::*;
use std::collections::HashMap;
use std::net::ToSocketAddrs;
use std::iter;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use image;
use mio::tcp::{TcpStream, Shutdown};
use mio::*;

use film::Image;
use exec::Config;
use exec::distrib::{worker, Instructions};
use sampler::BlockQueue;

#[derive(Debug)]
enum DistributedFrame {
    InProgress {
        frame: usize,
        // The number of workers who have reported results for this
        // frame so far
        num_reporting: usize,
        render: Image,
    },
    Completed,
}

impl DistributedFrame {
    pub fn start(frame_num: usize, img_dim: (usize, usize)) -> DistributedFrame {
        DistributedFrame::InProgress { frame: frame_num, num_reporting: 0, render: Image::new(img_dim) }
    }
}

#[derive(Clone, Debug)]
struct WorkerBuffer {
    pub buf: Vec<u8>,
    pub expected_size: usize,
    pub currently_read: usize,
}

impl WorkerBuffer {
    pub fn new() -> WorkerBuffer {
        WorkerBuffer { buf: Vec::new(), expected_size: 8, currently_read: 0 }
    }
}

pub struct Master {
    // Hostnames of the workers to send work too
    workers: Vec<String>,
    connections: Vec<TcpStream>,
    // Temporary buffers to store worker results in as they're
    // read in over TCP
    worker_buffers: Vec<WorkerBuffer>,
    config: Config,
    frames: HashMap<usize, DistributedFrame>,
    img_dim: (usize, usize),
    blocks_per_worker: usize,
    blocks_remainder: usize,
}

impl Master {
    /// Create a new master that will contact the worker nodes passed and
    /// send instructions on what parts of the scene to start rendering
    pub fn start_workers(workers: Vec<String>, config: Config, img_dim: (usize, usize))
                         -> (Master, EventLoop<Master>) {
        // Figure out how many blocks we have for this image and assign them to our workers
        let queue = BlockQueue::new((img_dim.0 as u32, img_dim.1 as u32), (8, 8), (0, 0));
        let blocks_per_worker = queue.len() / workers.len();
        let blocks_remainder = queue.len() % workers.len();
        println!("Have {} workers, each worker does {} blocks w/ {} remainder",
                 workers.len(), blocks_per_worker, blocks_remainder);

        let mut event_loop = EventLoop::<Master>::new().unwrap();
        let mut connections = Vec::new();

        // Connect to each worker and send instructions on what to render
        // I guess this should also be queue'd up and the writes actually performed asynchronously?
        // Otherwise we need to loop on write_all while waiting for the connection to open
        for (i, host) in workers.iter().enumerate() {
            let addr = (&host[..], worker::PORT).to_socket_addrs().unwrap().next().unwrap();
            println!("Connecting too {:?}", addr);
            match TcpStream::connect(&addr) {
                Ok(stream) => {
                    println!("Connected and writing");
                    println!("Adding stream to event loop");
                    // Each worker is identified in the event loop by their index in the vec
                    match event_loop.register(&stream, Token(i), EventSet::all(), PollOpt::level()){
                        Err(e) => println!("Error registering stream from {}: {}", host, e),
                        Ok(_) => {},
                    }
                    connections.push(stream);
                },
                Err(e) => println!("Failed to contact worker {}: {:?}", host, e),
            }
        }
        let worker_buffers: Vec<_> = iter::repeat(WorkerBuffer::new()).take(workers.len()).collect();
        let master = Master { workers: workers, connections: connections,
                              worker_buffers: worker_buffers, config: config,
                              frames: HashMap::new(),
                              img_dim: img_dim,
                              blocks_per_worker: blocks_per_worker,
                              blocks_remainder: blocks_remainder };
        (master, event_loop)
    }
    /// Read a result frame from a worker and save it into the list of frames we're collecting from
    /// all workers. Will save out the final render if all workers have reported results for this
    /// frame.
    fn save_results(&mut self, frame: worker::Frame) {
        // Find the frame this worker is referring to and add its results
        let frame_num = frame.frame as usize;
        let img_dim = self.img_dim;
        println!("Worker reporting frame {}", frame_num);
        let mut df = self.frames.entry(frame_num).or_insert_with(|| {
                println!("This is a new frame");
                DistributedFrame::start(frame_num, img_dim)
            });
        let mut finished = false;
        match df {
            &mut DistributedFrame::InProgress { frame: _, ref mut num_reporting, ref mut render } => {
                render.add_blocks(frame.block_size, &frame.blocks, &frame.pixels);
                *num_reporting += 1;
                println!("We have parts of this frame already");
                if *num_reporting == self.workers.len() {
                    println!("We have completed frame {}", frame_num);
                    let out_file = match self.config.out_path.extension() {
                        Some(_) => self.config.out_path.clone(),
                        None => self.config.out_path.join(
                            PathBuf::from(format!("frame{:05}.png", frame_num))),
                    };
                    println!("Frame {}: rendered to '{}'\n--------------------",
                             frame_num, out_file.display());
                    let img = render.get_srgb8();
                    let dim = render.dimensions();
                    match image::save_buffer(&out_file.as_path(), &img[..], dim.0 as u32,
                    dim.1 as u32, image::RGB(8)) {
                        Ok(_) => {},
                        Err(e) => println!("Error saving image, {}", e),
                    };
                    finished = true;
                }
            },
            &mut DistributedFrame::Completed => println!("Worker reporting on completed frame!?"),
        }
        // This is also a bit awkward, since we borrow the df in the match
        // we can't mark it finished in there
        if finished {
            *df = DistributedFrame::Completed;
        }
    }
    fn read_worker_buffer(&mut self, worker: usize) -> bool {
        let mut buf = &mut self.worker_buffers[worker];
        // If we haven't read the size of data being sent, read that now
        if buf.currently_read < 8 {
            // First 8 bytes are a u64 specifying the number of bytes being sent
            buf.buf.extend(iter::repeat(0u8).take(8));
            println!("Reading size header...");
            match self.connections[worker].read(&mut buf.buf[buf.currently_read..]) {
                Ok(n) => buf.currently_read += n,
                Err(e) => println!("Error reading results from worker {}: {}", self.workers[worker], e),
            }
            println!("Read {} bytes so far, must read {} in total", buf.currently_read, buf.expected_size);
            if buf.currently_read == buf.expected_size {
                println!("Got size header");
                // How many bytes we expect to get from the worker for a frame
                buf.expected_size = decode(&buf.buf[..]).unwrap();
                println!("Expecting {} bytes", buf.expected_size);
                // Extend the Vec so we've got enough room for the remaning bytes, minus the 8 for the
                // encoded size header
                buf.buf.extend(iter::repeat(0u8).take(buf.expected_size - 8));
            }
        }
        // If we've finished reading the size header we can now start reading the frame data
        if buf.currently_read >= 8 {
            println!("Reading from worker");
            match self.connections[worker].read(&mut buf.buf[buf.currently_read..]) {
                Ok(n) => buf.currently_read += n,
                Err(e) => println!("Error reading results from worker {}: {}", self.workers[worker], e),
            }
            println!("Read {} bytes so far, must read {} in total", buf.currently_read, buf.expected_size);
        }
        buf.currently_read == buf.expected_size
    }
}

impl Handler for Master {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Master>, token: Token, event: EventSet) {
        let worker = token.as_usize();
        println!("Event from {}: {:?}", worker, event);
        if event.is_error() {
            println!("Error connecting too {}", self.workers[worker]);
            match self.connections[worker].shutdown(Shutdown::Both) {
                Err(e) => println!("Error shutting down worker {}: {}", worker, e),
                Ok(_) => {},
            }
            // Remove the connection from the event loop
            match event_loop.deregister(&self.connections[worker]) {
                Err(e) => println!("Error deregistering worker {}: {}", worker, e),
                Ok(_) => {},
            }
        }
        // A worker is ready to receive instructions from us
        if event.is_writable() {
            let b_start = worker * self.blocks_per_worker;
            let b_count =
                if worker == self.workers.len() - 1 {
                    self.blocks_per_worker + self.blocks_remainder
                } else {
                    self.blocks_per_worker
                };
            let instr = Instructions::new(&self.config.scene_file,
                                          (self.config.frame_info.start, self.config.frame_info.end),
                                          b_start, b_count);
            println!("Sending instructions {:?} to {}", instr, self.workers[worker]);
            let bytes = encode(&instr, SizeLimit::Infinite).unwrap();
            println!("Encoded instructions size: {}", instr.encoded_size);
            // Loop until we successfully write the byes
            match self.connections[worker].write_all(&bytes[..]) {
                Err(e) => println!("Failed to send instructions to {}: {:?}", self.workers[worker], e),
                Ok(_) => println!("Instructions sent"),
            }
            // Register that we no longer care about writable events on this connection
            event_loop.reregister(&self.connections[worker], token,
                                  EventSet::readable() | EventSet::error() | EventSet::hup(),
                                  PollOpt::level()).expect("Re-registering failed");
        }
        // Some results are available from a worker
        if event.is_readable() {
            println!("Readable event from worker {}", worker);
            if self.read_worker_buffer(worker) {
                println!("Got all frame data, now parsing");
                let frame: worker::Frame = decode(&self.worker_buffers[worker].buf[..]).unwrap();
                println!("Saving frame results");
                self.save_results(frame);
                // Clean up our read buffer
                self.worker_buffers[worker].buf.clear();
                self.worker_buffers[worker].expected_size = 8;
                self.worker_buffers[worker].currently_read = 0;
            }
        }
        // If the worker has terminated, shutdown the read end of the connection
        if event.is_hup() {
            println!("Worker {} has hung up", worker);
            match self.connections[worker].shutdown(Shutdown::Read) {
                Err(e) => println!("Error shutting down worker {}: {}", worker, e),
                Ok(_) => {},
            }
            // Remove the connection from the event loop
            match event_loop.deregister(&self.connections[worker]) {
                Err(e) => println!("Error deregistering worker {}: {}", worker, e),
                Ok(_) => {},
            }
        }
        // After getting results from the worker we check if we've completed all our frames
        // and exit if so
        let all_complete = self.frames.values().fold(true,
                                |all, v| {
                                    match v {
                                        &DistributedFrame::Completed => true && all,
                                        _ => false,
                                    }
                                });
        // The frame start/end range is inclusive, so we must add 1 here
        let num_frames = self.config.frame_info.end - self.config.frame_info.start + 1;
        println!("Rendering {} frames have {}, all_complete? {}",
                 num_frames, self.frames.len(), all_complete);
        // TODO: We can't use frame_info.frames as this is not the `subset` of frames
        // we're rendering
        if self.frames.len() == num_frames && all_complete {
            println!("All frames have been rendered, master exiting");
            event_loop.shutdown();
        }
    }
}

<|endoftext|>


<commit_before>extern crate crypto;

use std::fs;
use std::io;
use std::io::prelude::*;
use std::path::PathBuf;

use self::crypto::md5::Md5;
use self::crypto::digest::Digest;

pub trait FileComparable<T> {
    fn get_key(&mut self, file: &PathBuf) -> Option<T> where T : Ord;
    //fn compose(&mut self, &mut U) -> V where U : FileComparable<T, U, V>, V : FileComparable<T, U, V>;
}

// We should move this out to a submodule, maybe? But I can't figure out Rust's module system :()

pub struct Md5Comparator {

}

impl Md5Comparator {
    pub fn new() -> Md5Comparator {
        Md5Comparator {}
    }
}

impl FileComparable<String> for Md5Comparator {
    fn get_key(&mut self, file_path: &PathBuf) -> Option<String> {
        // Yuck! There must be some monadic simplification here!
        match fs::File::open(&file_path) {
            Ok(file) => {

                let mut buf_reader = io::BufReader::new(file);
                let mut contents = String::new();

                match buf_reader.read_to_string(&mut contents) {
                    Ok(_) => {
                        let mut sh = Md5::new();
                        sh.input_str(&contents);
                        Some(sh.result_str())
                    },
                    Err(msg) => {println!("Cannot read file {} to calculate hash: {}", file_path.display(), msg); None }
                }
            },
            Err(msg) => { println!("Cannot open file {} to calculate hash: {}", file_path.display(), msg); None }
        }
    }
}<commit_msg>trying out polymorphism<commit_after>extern crate crypto;

use std::fs;
use std::io;
use std::io::prelude::*;
use std::path::PathBuf;

use self::crypto::md5::Md5;
use self::crypto::digest::Digest;

pub trait FileComparable<T> {
    fn get_key(&mut self, file: &PathBuf) -> Option<T> where T : Ord;
    //fn compose(&mut self, &mut U) -> V where U : FileComparable<T, U, V>, V : FileComparable<T, U, V>;
}

// We should move this out to a submodule, maybe? But I can't figure out Rust's module system :()

pub struct Md5Comparator {

}

impl Md5Comparator {
    pub fn new() -> Md5Comparator {
        Md5Comparator {}
    }
}

impl FileComparable<String> for Md5Comparator {
    fn get_key(&mut self, file_path: &PathBuf) -> Option<String> {
        // Yuck! There must be some monadic simplification here!
        match fs::File::open(&file_path) {
            Ok(file) => {

                let mut buf_reader = io::BufReader::new(file);
                let mut contents = String::new();

                match buf_reader.read_to_string(&mut contents) {
                    Ok(_) => {
                        let mut sh = Md5::new();
                        sh.input_str(&contents);
                        Some(sh.result_str())
                    },
                    Err(msg) => {println!("Cannot read file {} to calculate hash: {}", file_path.display(), msg); None }
                }
            },
            Err(msg) => { println!("Cannot open file {} to calculate hash: {}", file_path.display(), msg); None }
        }
    }
}

// To see if our Trait-based strategy pattern will work

pub struct TrivialComparator {

}

impl TrivialComparator {
    pub fn new() -> TrivialComparator {
        TrivialComparator {}
    }
}

impl FileComparable<u32> for TrivialComparator {
    fn get_key(&mut self, file_path: &PathBuf) -> Option<u32> {
        Some(1)
    }
}<|endoftext|>


<commit_before>//! Traits

use std::ops::{Add, Div, Mul, Sub};

/// Any type that can be SIMD accelerated
pub trait Simd: Add<Output=Self> + Copy + Div<Output=Self> + Mul<Output=Self> + Sub<Output=Self> {
    type Vector: Vector<Elem=Self>;
}

/// SIMD vector
pub trait Vector:
    Add<Output=Self> +
    Copy +
    Div<Output=Self> +
    Mul<Output=Self> +
    Sub<Output=Self>
{
    type Elem: Simd<Vector=Self>;

    /// Casts e.g. `&[f32]` into an *aligned* `&[f32x4]`, the elements that don't fit in the
    /// aligned slice will be returned as a `&[f32]` slices.
    ///
    /// # Examples
    ///
    /// ```
    /// use simd::f32x4;
    /// use simd::traits::Vector;
    ///
    /// let v: Vec<_> = (0..10).map(|x| x as f32).collect();
    /// let (head, body, tail) = <f32x4 as Vector>::cast(&v);
    ///
    /// assert_eq!(format!("{:?}", head), "[]");
    /// assert_eq!(format!("{:?}", body), "[f32x4(0, 1, 2, 3), f32x4(4, 5, 6, 7)]");
    /// assert_eq!(format!("{:?}", tail), "[8, 9]");
    ///
    /// let slice = &v[1..5];
    /// let (head, body, tail) = <f32x4 as Vector>::cast(slice);
    ///
    /// assert_eq!(format!("{:?}", head), "[1, 2, 3, 4]");
    /// assert_eq!(format!("{:?}", body), "[]");
    /// assert_eq!(format!("{:?}", tail), "[]");
    ///
    /// let slice = &v[2..];
    /// let (head, body, tail) = <f32x4 as Vector>::cast(slice);
    ///
    /// assert_eq!(format!("{:?}", head), "[2, 3]");
    /// assert_eq!(format!("{:?}", body), "[f32x4(4, 5, 6, 7)]");
    /// assert_eq!(format!("{:?}", tail), "[8, 9]");
    /// ```
    fn cast<'a>(&'a [Self::Elem]) -> (&'a [Self::Elem], &'a [Self], &'a [Self::Elem]);

    /// Creates an SIMD vector that contains several copies of `elem`
    fn from_elem(Self::Elem) -> Self;

    /// Creates an SIMD vector with all its elements set to zero
    fn zeroed() -> Self;

    /// Maps each element of the SIMD vector
    ///
    /// NOTE: Slow! This maps `f` on each element *serially*.
    fn map<F>(&self, f: F) -> Self where F: FnMut(Self::Elem) -> Self::Elem;

    /// Returns the sum of all its elements
    fn sum(&self) -> Self::Elem;
}

<commit_msg>docs: document associated types<commit_after>//! Traits

use std::ops::{Add, Div, Mul, Sub};

/// Any type that can be SIMD accelerated
pub trait Simd: Add<Output=Self> + Copy + Div<Output=Self> + Mul<Output=Self> + Sub<Output=Self> {
    /// The SIMD vector associated to this type
    type Vector: Vector<Elem=Self>;
}

/// SIMD vector
pub trait Vector:
    Add<Output=Self> +
    Copy +
    Div<Output=Self> +
    Mul<Output=Self> +
    Sub<Output=Self>
{
    /// Each element of the SIMD vector
    type Elem: Simd<Vector=Self>;

    /// Casts e.g. `&[f32]` into an *aligned* `&[f32x4]`, the elements that don't fit in the
    /// aligned slice will be returned as a `&[f32]` slices.
    ///
    /// # Examples
    ///
    /// ```
    /// use simd::f32x4;
    /// use simd::traits::Vector;
    ///
    /// let v: Vec<_> = (0..10).map(|x| x as f32).collect();
    /// let (head, body, tail) = <f32x4 as Vector>::cast(&v);
    ///
    /// assert_eq!(format!("{:?}", head), "[]");
    /// assert_eq!(format!("{:?}", body), "[f32x4(0, 1, 2, 3), f32x4(4, 5, 6, 7)]");
    /// assert_eq!(format!("{:?}", tail), "[8, 9]");
    ///
    /// let slice = &v[1..5];
    /// let (head, body, tail) = <f32x4 as Vector>::cast(slice);
    ///
    /// assert_eq!(format!("{:?}", head), "[1, 2, 3, 4]");
    /// assert_eq!(format!("{:?}", body), "[]");
    /// assert_eq!(format!("{:?}", tail), "[]");
    ///
    /// let slice = &v[2..];
    /// let (head, body, tail) = <f32x4 as Vector>::cast(slice);
    ///
    /// assert_eq!(format!("{:?}", head), "[2, 3]");
    /// assert_eq!(format!("{:?}", body), "[f32x4(4, 5, 6, 7)]");
    /// assert_eq!(format!("{:?}", tail), "[8, 9]");
    /// ```
    fn cast<'a>(&'a [Self::Elem]) -> (&'a [Self::Elem], &'a [Self], &'a [Self::Elem]);

    /// Creates an SIMD vector that contains several copies of `elem`
    fn from_elem(Self::Elem) -> Self;

    /// Creates an SIMD vector with all its elements set to zero
    fn zeroed() -> Self;

    /// Maps each element of the SIMD vector
    ///
    /// NOTE: Slow! This maps `f` on each element *serially*.
    fn map<F>(&self, f: F) -> Self where F: FnMut(Self::Elem) -> Self::Elem;

    /// Returns the sum of all its elements
    fn sum(&self) -> Self::Elem;
}

<|endoftext|>


<commit_before>// Copyright 2015 Nicholas Bishop
//
// 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::ops::{Add, Div, Mul, Sub};

/// Vector with two f32 components
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec2f {
    pub x: f32,
    pub y: f32
}

impl Vec2f {
    /// Create a Vec2f from two components
    pub fn new(x: f32, y: f32) -> Vec2f {
        Vec2f { x: x,
                y: y }
    }

    pub fn cross(&self, other: Vec2f) -> f32 {
        self.x * other.y - self.y * other.x
    }
}

/// Vector with three f32 components
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec3f {
    pub x: f32,
    pub y: f32,
    pub z: f32
}

impl Vec3f {
    /// Create a Vec3f from three components
    pub fn new(x: f32, y: f32, z: f32) -> Vec3f {
        Vec3f { x: x,
                y: y,
                z: z }
    }

    /// Create a Vec3f with all components set to the same scalar
    pub fn from_scalar<T: CastF32>(s: T) -> Vec3f {
        let f = s.as_f32();
        Vec3f {
            x: f,
            y: f,
            z: f
        }
    }

    /// Squared length of the vector
    pub fn magnitude_squared(&self) -> f32 {
        dot3(*self, *self)
    }

    /// Length of the vector
    pub fn magnitude(&self) -> f32 {
        self.magnitude_squared().sqrt()
    }

    /// Create a normalized copy, or None if the magnitude is zero
    pub fn normalized(&self) -> Option<Vec3f> {
        let m = self.magnitude();
        if m == 0.0 {
            None
        }
        else {
            let f = 1.0 / m;
            Some((*self) * f)
        }
    }

    /// Projection of `self` into `v`, or None if the magnitude of
    /// `b` is zero.
    pub fn project_onto(&self, v: Vec3f) -> Option<Vec3f> {
        if v == ZERO_3F {
            None
        }
        else {
            Some(v * (dot3(*self, v) / dot3(v, v)))
        }
    }
}

/// Vec3f(0.0, 0.0, 0.0)
pub const ZERO_3F: Vec3f = Vec3f { x: 0.0, y: 0.0, z: 0.0 };

/// Convert a numeric type to an f32
pub trait CastF32 { fn as_f32(&self) -> f32; }

impl CastF32 for f32 { fn as_f32(&self) -> f32 { *self } }
impl CastF32 for f64 { fn as_f32(&self) -> f32 { *self as f32 } }

impl CastF32 for i8  { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i16 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i32 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i64 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for isize { fn as_f32(&self) -> f32 { *self as f32 } }

impl CastF32 for u8  { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u16 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u32 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u64 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for usize { fn as_f32(&self) -> f32 { *self as f32 } }

/// Create a Vec3f from x, y, and z inputs
///
/// This is a convenience function that provides a little more
/// flexibility than Vec3f::new in that it will happily take numbers
/// that aren't f32 (including a mix of different types for each
/// component). Vec3f is such a common type that it seems reasonable
/// to provide a little extra ease of use.
pub fn vec3f<X: CastF32, Y: CastF32, Z: CastF32>(x: X, y: Y, z: Z) -> Vec3f {
    Vec3f { x: x.as_f32(), y: y.as_f32(), z: z.as_f32() }
}

/// Inner product of two Vec3f inputs
pub fn dot3(a: Vec3f, b: Vec3f) -> f32 {
    let v = a * b;
    v.x + v.y + v.z
}

/// Cross product of two Vec3f inputs
pub fn cross(a: Vec3f, b: Vec3f) -> Vec3f {
    Vec3f::new(a.y * b.z - a.z * b.y,
               a.z * b.x - a.x * b.z,
               a.x * b.y - a.y * b.x)
}

/// Distance between two points
pub fn distance3(a: Vec3f, b: Vec3f) -> f32 {
    (a - b).magnitude()
}

/// Linearly interpolate between two points by the factor `t`. When
/// `t` is zero the result is `p0`, and when `t` is one the result is
/// `p1`. The range of `t` is not clamped.
pub fn lerp3(p0: &Vec3f, p1: &Vec3f, t: f32) -> Vec3f {
    let n = 1.0 - t;
    Vec3f::new(p0.x * n + p1.x * t,
               p0.y * n + p1.y * t,
               p0.z * n + p1.z * t)
}

impl Add for Vec3f {
    type Output = Vec3f;
    fn add(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x + v.x, self.y + v.y, self.z + v.z)
    }
}

impl Add<f32> for Vec3f {
    type Output = Vec3f;
    fn add(self, s: f32) -> Vec3f {
        Vec3f::new(self.x + s, self.y + s, self.z + s)
    }
}

impl Div for Vec3f {
    type Output = Vec3f;
    fn div(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x / v.x, self.y / v.y, self.z / v.z)
    }
}

impl Mul<Vec3f> for Vec3f {
    type Output = Vec3f;
    fn mul(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x * v.x, self.y * v.y, self.z * v.z)
    }
}

impl Mul<f32> for Vec3f {
    type Output = Vec3f;
    fn mul(self, f: f32) -> Vec3f {
        Vec3f::new(self.x * f, self.y * f, self.z * f)
    }
}

impl Sub for Vec3f {
    type Output = Vec3f;
    fn sub(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x - v.x, self.y - v.y, self.z - v.z)
    }
}

impl Sub<f32> for Vec3f {
    type Output = Vec3f;
    fn sub(self, s: f32) -> Vec3f {
        Vec3f::new(self.x - s, self.y - s, self.z - s)
    }
}

#[test]
fn test_vec3f_create() {
    vec3f(1.0f32, 2, 3i32);
    assert!(Vec3f::from_scalar(1) == vec3f(1, 1, 1));
}

#[test]
fn test_vec3f_magnitude() {
    let v = vec3f(-4, 0, 0);
    assert!(v.magnitude_squared() == 16.0);
    assert!(v.magnitude() == 4.0);
}

#[test]
fn test_vec3f_distance() {
    assert!(distance3(vec3f(0, -4, 0), vec3f(0, 4, 0)) == 8.0);
}

#[test]
fn test_vec3f_normalized() {
    assert_eq!(vec3f(0, 0, 0).normalized(), None);
    assert_eq!(vec3f(0.5, 0, 0).normalized(), Some(vec3f(1, 0, 0)));
}

#[test]
fn test_vec3f_project_onto() {
    let z = vec3f(0, 0, 0);
    let a = vec3f(1, 0, 0);
    let b = vec3f(1, 1, 0);
    assert_eq!(a.project_onto(z), None);
    assert_eq!(a.project_onto(b).unwrap(), vec3f(0.5, 0.5, 0));
}

#[test]
fn test_vec3f_arithmetic() {
    let a = vec3f(1, 2, 3);
    let b = vec3f(4, 5, 6);
    assert!(a + b == vec3f(5, 7, 9));
    assert!(a - b == vec3f(-3, -3, -3));
    assert!(a * b == vec3f(4, 10, 18));
    assert!(a / b == vec3f(0.25, 2.0 / 5.0, 0.5));
}

#[test]
fn test_vec3f_dot() {
    assert!(dot3(vec3f(1, 2, 3), vec3f(4, 5, 6)) == 32.0);
}

#[test]
fn test_vec3f_cross() {
    assert!(cross(vec3f(1, 0, 0), vec3f(0, 1, 0)) == vec3f(0, 0, 1));
}

#[test]
fn test_vec3f_lerp() {
    let p0 = vec3f(1.0, 2.0, 3.0);
    let p1 = vec3f(-1.0, -2.0, -3.0);
    assert!(lerp3(&p0, &p1, 0.0) == p0);
    assert!(lerp3(&p0, &p1, 0.25) == vec3f(0.5, 1.0, 1.5));
    assert!(lerp3(&p0, &p1, 0.5) == vec3f(0.0, 0.0, 0.0));
    assert!(lerp3(&p0, &p1, 1.0) == p1);
}
<commit_msg>Add more 2D types<commit_after>// Copyright 2015 Nicholas Bishop
//
// 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::ops::{Add, Div, Mul, Sub};

/// Vector with two f32 components
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec2f {
    pub x: f32,
    pub y: f32
}

impl Vec2f {
    /// Create a Vec2f from two components
    pub fn new(x: f32, y: f32) -> Vec2f {
        Vec2f { x: x,
                y: y }
    }

    pub fn cross(&self, other: Vec2f) -> f32 {
        self.x * other.y - self.y * other.x
    }
}

impl Sub for Vec2f {
    type Output = Vec2f;
    fn sub(self, v: Vec2f) -> Vec2f {
        Vec2f::new(self.x - v.x, self.y - v.y)
    }
}

pub struct Quad2f {
    pub points: (Vec2f, Vec2f, Vec2f, Vec2f)
}

impl Quad2f {
    pub fn new(points: (Vec2f, Vec2f, Vec2f, Vec2f)) -> Quad2f {
        Quad2f {
            points: points
        }
    }

    // Adapted from stackoverflow.com/questions/808441
    pub fn iblerp(&self, point: Vec2f) {
        let a = (self.points.0 - point).cross(self.points.0 - self.points.2);
        let b = ( (self.points.0 - point).cross(self.points.1 - self.points.3) + (self.points.1 - point).cross(self.points.0 - self.points.2) ) / 2;
        let c = (self.points.1 - point).cross(self.points.1 - self.points.3);
    }
}

/// Vector with three f32 components
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec3f {
    pub x: f32,
    pub y: f32,
    pub z: f32
}

impl Vec3f {
    /// Create a Vec3f from three components
    pub fn new(x: f32, y: f32, z: f32) -> Vec3f {
        Vec3f { x: x,
                y: y,
                z: z }
    }

    /// Create a Vec3f with all components set to the same scalar
    pub fn from_scalar<T: CastF32>(s: T) -> Vec3f {
        let f = s.as_f32();
        Vec3f {
            x: f,
            y: f,
            z: f
        }
    }

    /// Squared length of the vector
    pub fn magnitude_squared(&self) -> f32 {
        dot3(*self, *self)
    }

    /// Length of the vector
    pub fn magnitude(&self) -> f32 {
        self.magnitude_squared().sqrt()
    }

    /// Create a normalized copy, or None if the magnitude is zero
    pub fn normalized(&self) -> Option<Vec3f> {
        let m = self.magnitude();
        if m == 0.0 {
            None
        }
        else {
            let f = 1.0 / m;
            Some((*self) * f)
        }
    }

    /// Projection of `self` into `v`, or None if the magnitude of
    /// `b` is zero.
    pub fn project_onto(&self, v: Vec3f) -> Option<Vec3f> {
        if v == ZERO_3F {
            None
        }
        else {
            Some(v * (dot3(*self, v) / dot3(v, v)))
        }
    }
}

/// Vec3f(0.0, 0.0, 0.0)
pub const ZERO_3F: Vec3f = Vec3f { x: 0.0, y: 0.0, z: 0.0 };

/// Convert a numeric type to an f32
pub trait CastF32 { fn as_f32(&self) -> f32; }

impl CastF32 for f32 { fn as_f32(&self) -> f32 { *self } }
impl CastF32 for f64 { fn as_f32(&self) -> f32 { *self as f32 } }

impl CastF32 for i8  { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i16 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i32 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for i64 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for isize { fn as_f32(&self) -> f32 { *self as f32 } }

impl CastF32 for u8  { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u16 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u32 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for u64 { fn as_f32(&self) -> f32 { *self as f32 } }
impl CastF32 for usize { fn as_f32(&self) -> f32 { *self as f32 } }

/// Create a Vec3f from x, y, and z inputs
///
/// This is a convenience function that provides a little more
/// flexibility than Vec3f::new in that it will happily take numbers
/// that aren't f32 (including a mix of different types for each
/// component). Vec3f is such a common type that it seems reasonable
/// to provide a little extra ease of use.
pub fn vec3f<X: CastF32, Y: CastF32, Z: CastF32>(x: X, y: Y, z: Z) -> Vec3f {
    Vec3f { x: x.as_f32(), y: y.as_f32(), z: z.as_f32() }
}

/// Inner product of two Vec3f inputs
pub fn dot3(a: Vec3f, b: Vec3f) -> f32 {
    let v = a * b;
    v.x + v.y + v.z
}

/// Cross product of two Vec3f inputs
pub fn cross(a: Vec3f, b: Vec3f) -> Vec3f {
    Vec3f::new(a.y * b.z - a.z * b.y,
               a.z * b.x - a.x * b.z,
               a.x * b.y - a.y * b.x)
}

/// Distance between two points
pub fn distance3(a: Vec3f, b: Vec3f) -> f32 {
    (a - b).magnitude()
}

/// Linearly interpolate between two points by the factor `t`. When
/// `t` is zero the result is `p0`, and when `t` is one the result is
/// `p1`. The range of `t` is not clamped.
pub fn lerp3(p0: &Vec3f, p1: &Vec3f, t: f32) -> Vec3f {
    let n = 1.0 - t;
    Vec3f::new(p0.x * n + p1.x * t,
               p0.y * n + p1.y * t,
               p0.z * n + p1.z * t)
}

impl Add for Vec3f {
    type Output = Vec3f;
    fn add(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x + v.x, self.y + v.y, self.z + v.z)
    }
}

impl Add<f32> for Vec3f {
    type Output = Vec3f;
    fn add(self, s: f32) -> Vec3f {
        Vec3f::new(self.x + s, self.y + s, self.z + s)
    }
}

impl Div for Vec3f {
    type Output = Vec3f;
    fn div(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x / v.x, self.y / v.y, self.z / v.z)
    }
}

impl Mul<Vec3f> for Vec3f {
    type Output = Vec3f;
    fn mul(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x * v.x, self.y * v.y, self.z * v.z)
    }
}

impl Mul<f32> for Vec3f {
    type Output = Vec3f;
    fn mul(self, f: f32) -> Vec3f {
        Vec3f::new(self.x * f, self.y * f, self.z * f)
    }
}

impl Sub for Vec3f {
    type Output = Vec3f;
    fn sub(self, v: Vec3f) -> Vec3f {
        Vec3f::new(self.x - v.x, self.y - v.y, self.z - v.z)
    }
}

impl Sub<f32> for Vec3f {
    type Output = Vec3f;
    fn sub(self, s: f32) -> Vec3f {
        Vec3f::new(self.x - s, self.y - s, self.z - s)
    }
}

#[test]
fn test_vec3f_create() {
    vec3f(1.0f32, 2, 3i32);
    assert!(Vec3f::from_scalar(1) == vec3f(1, 1, 1));
}

#[test]
fn test_vec3f_magnitude() {
    let v = vec3f(-4, 0, 0);
    assert!(v.magnitude_squared() == 16.0);
    assert!(v.magnitude() == 4.0);
}

#[test]
fn test_vec3f_distance() {
    assert!(distance3(vec3f(0, -4, 0), vec3f(0, 4, 0)) == 8.0);
}

#[test]
fn test_vec3f_normalized() {
    assert_eq!(vec3f(0, 0, 0).normalized(), None);
    assert_eq!(vec3f(0.5, 0, 0).normalized(), Some(vec3f(1, 0, 0)));
}

#[test]
fn test_vec3f_project_onto() {
    let z = vec3f(0, 0, 0);
    let a = vec3f(1, 0, 0);
    let b = vec3f(1, 1, 0);
    assert_eq!(a.project_onto(z), None);
    assert_eq!(a.project_onto(b).unwrap(), vec3f(0.5, 0.5, 0));
}

#[test]
fn test_vec3f_arithmetic() {
    let a = vec3f(1, 2, 3);
    let b = vec3f(4, 5, 6);
    assert!(a + b == vec3f(5, 7, 9));
    assert!(a - b == vec3f(-3, -3, -3));
    assert!(a * b == vec3f(4, 10, 18));
    assert!(a / b == vec3f(0.25, 2.0 / 5.0, 0.5));
}

#[test]
fn test_vec3f_dot() {
    assert!(dot3(vec3f(1, 2, 3), vec3f(4, 5, 6)) == 32.0);
}

#[test]
fn test_vec3f_cross() {
    assert!(cross(vec3f(1, 0, 0), vec3f(0, 1, 0)) == vec3f(0, 0, 1));
}

#[test]
fn test_vec3f_lerp() {
    let p0 = vec3f(1.0, 2.0, 3.0);
    let p1 = vec3f(-1.0, -2.0, -3.0);
    assert!(lerp3(&p0, &p1, 0.0) == p0);
    assert!(lerp3(&p0, &p1, 0.25) == vec3f(0.5, 1.0, 1.5));
    assert!(lerp3(&p0, &p1, 0.5) == vec3f(0.0, 0.0, 0.0));
    assert!(lerp3(&p0, &p1, 1.0) == p1);
}
<|endoftext|>


<commit_before>//! Displays an image in a window created by sdl2.

use image::{
    imageops::{resize, FilterType},
    ConvertBuffer, GenericImageView, RgbaImage,
};
use sdl2::{
    event::{Event, WindowEvent},
    keyboard::Keycode,
    pixels::{Color, PixelFormatEnum},
    rect::Rect,
    render::{Canvas, TextureCreator, WindowCanvas},
    surface::Surface,
    video::{Window, WindowContext},
};

/// Displays the provided RGBA image in a new window.
///
/// The minimum window width or height is 150 pixels - input values less than this
/// will be rounded up to the minimum.
pub fn display_image<I>(title: &str, image: &I, window_width: u32, window_height: u32)
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    display_multiple_images(title, &vec![image], window_width, window_height);
}

/// Displays the provided RGBA images in new windows.
///
/// The minimum window width or height is 150 pixels - input values less than this
/// will be rounded up to the minimum.
pub fn display_multiple_images<I>(title: &str, images: &[&I], window_width: u32, window_height: u32)
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    if images.len() == 0 {
        return;
    }

    // Enforce minimum window size
    const MIN_WINDOW_DIMENSION: u32 = 150;
    let window_width = window_width.max(MIN_WINDOW_DIMENSION);
    let window_height = window_height.max(MIN_WINDOW_DIMENSION);

    // Initialise sdl2 window
    let sdl = sdl2::init().expect("couldn't create sdl2 context");
    let video_subsystem = sdl.video().expect("couldn't create video subsystem");

    let mut windows: Vec<Window> = Vec::with_capacity(images.len());
    let mut window_visibility: Vec<bool> = Vec::with_capacity(images.len());
    for _ in 0..images.len() {
        let mut window = video_subsystem
            .window(title, window_width, window_height)
            .resizable()
            .allow_highdpi()
            .build()
            .expect("couldn't create window");

        window
            .set_minimum_size(MIN_WINDOW_DIMENSION, MIN_WINDOW_DIMENSION)
            .expect("invalid minimum size for window");

        windows.push(window);
        window_visibility.push(true);
    }

    {
        use sdl2::video::WindowPos::Positioned;

        let (base_position_x, base_position_y) = windows[0].position();
        for (i, window) in windows.iter_mut().enumerate() {
            let multiplier = 1.0 + i as f32 / 20.0;
            window.set_position(
                Positioned((base_position_x as f32 * multiplier) as i32),
                Positioned(base_position_y),
            );

            let (window_pos_x, _window_pos_y) = window.position();
            let display_bounds = video_subsystem
                .display_bounds(0)
                .expect("No bounds found for that display.");
            let screen_width = display_bounds.w;
            if window_pos_x + window_width as i32 > screen_width {
                window.set_position(
                    Positioned(screen_width - window_width as i32),
                    Positioned(base_position_y),
                );
            }
        }
    }

    let mut canvases: Vec<WindowCanvas> = Vec::with_capacity(images.len());
    for window in windows.into_iter() {
        let canvas = window
            .into_canvas()
            .software()
            .build()
            .expect("couldn't create canvas");
        canvases.push(canvas);
    }

    let mut texture_creators: Vec<TextureCreator<WindowContext>> = Vec::with_capacity(images.len());
    for canvas in canvases.iter() {
        let texture_creator = canvas.texture_creator();
        texture_creators.push(texture_creator);
    }

    // Shrinks input image to fit if required and renders to the sdl canvas

    for (i, (canvas, texture_creator)) in
        canvases.iter_mut().zip(texture_creators.iter()).enumerate()
    {
        render_image_to_canvas(
            images[i],
            window_width,
            window_height,
            canvas,
            texture_creator,
        );
    }

    let mut hidden_count = 0;

    // Create and start event loop to keep window open until Esc
    let mut event_pump = sdl.event_pump().unwrap();
    event_pump.enable_event(sdl2::event::EventType::Window);
    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit { .. }
                | Event::KeyDown {
                    keycode: Some(Keycode::Escape),
                    ..
                } => break 'running,
                Event::KeyDown {
                    keycode: Some(Keycode::Q),
                    window_id,
                    ..
                } => {
                    for (i, canvas) in canvases.iter_mut().enumerate() {
                        if window_id == canvas.window().id() {
                            canvas.window_mut().hide();
                            window_visibility[i] = false;
                            hidden_count += 1;
                        }
                        if hidden_count == images.len() {
                            break 'running;
                        }
                    }
                }
                Event::Window {
                    win_event: WindowEvent::Close,
                    window_id,
                    ..
                } => {
                    for (i, canvas) in canvases.iter_mut().enumerate() {
                        if window_id == canvas.window().id() {
                            canvas.window_mut().hide();
                            window_visibility[i] = false;
                            hidden_count += 1;
                        }
                        if hidden_count == images.len() {
                            break 'running;
                        }
                    }
                }
                Event::Window {
                    win_event: WindowEvent::Resized(w, h),
                    window_id,
                    ..
                } => {
                    for (i, (canvas, texture_creator)) in
                        canvases.iter_mut().zip(texture_creators.iter()).enumerate()
                    {
                        if window_id == canvas.window().id() {
                            render_image_to_canvas(
                                images[i],
                                w as u32,
                                h as u32,
                                canvas,
                                texture_creator,
                            );
                        }
                    }
                }
                _ => {}
            }
        }
    }
}

// Scale input image down if required so that it fits within a window of the given dimensions
fn resize_to_fit<I>(image: &I, window_width: u32, window_height: u32) -> RgbaImage
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    let image = image.convert();
    if image.height() < window_height && image.width() < window_width {
        return image;
    }

    let scale = {
        let width_scale = window_width as f32 / image.width() as f32;
        let height_scale = window_height as f32 / image.height() as f32;
        width_scale.min(height_scale)
    };

    let height = (scale * image.height() as f32) as u32;
    let width = (scale * image.width() as f32) as u32;

    resize(&image, width, height, FilterType::Triangle)
}

fn render_image_to_canvas<I>(
    image: &I,
    window_width: u32,
    window_height: u32,
    canvas: &mut Canvas<Window>,
    texture_creator: &TextureCreator<WindowContext>,
) where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    let scaled_image = resize_to_fit(image, window_width, window_height);

    let (image_width, image_height) = scaled_image.dimensions();
    let mut buffer = scaled_image.into_raw();
    const CHANNEL_COUNT: u32 = 4;
    let surface = Surface::from_data(
        &mut buffer,
        image_width,
        image_height,
        image_width * CHANNEL_COUNT,
        PixelFormatEnum::ABGR8888, // sdl2 expects bits from highest to lowest
    )
    .expect("couldn't create surface");

    let texture = texture_creator
        .create_texture_from_surface(surface)
        .expect("couldn't create texture from surface");

    canvas.set_draw_color(Color::RGB(255, 255, 255));
    canvas.clear();

    let left = ((window_width - image_width) as f32 / 2f32) as i32;
    let top = ((window_height - image_height) as f32 / 2f32) as i32;
    canvas
        .copy(
            &texture,
            None,
            Rect::new(left, top, image_width, image_height),
        )
        .unwrap();
    canvas.present();
}
<commit_msg>Fix display-window feature due to upstream refactoring of buffers (#414)<commit_after>//! Displays an image in a window created by sdl2.

use image::{
    buffer::ConvertBuffer,
    imageops::{resize, FilterType},
    GenericImageView, RgbaImage,
};
use sdl2::{
    event::{Event, WindowEvent},
    keyboard::Keycode,
    pixels::{Color, PixelFormatEnum},
    rect::Rect,
    render::{Canvas, TextureCreator, WindowCanvas},
    surface::Surface,
    video::{Window, WindowContext},
};

/// Displays the provided RGBA image in a new window.
///
/// The minimum window width or height is 150 pixels - input values less than this
/// will be rounded up to the minimum.
pub fn display_image<I>(title: &str, image: &I, window_width: u32, window_height: u32)
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    display_multiple_images(title, &vec![image], window_width, window_height);
}

/// Displays the provided RGBA images in new windows.
///
/// The minimum window width or height is 150 pixels - input values less than this
/// will be rounded up to the minimum.
pub fn display_multiple_images<I>(title: &str, images: &[&I], window_width: u32, window_height: u32)
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    if images.len() == 0 {
        return;
    }

    // Enforce minimum window size
    const MIN_WINDOW_DIMENSION: u32 = 150;
    let window_width = window_width.max(MIN_WINDOW_DIMENSION);
    let window_height = window_height.max(MIN_WINDOW_DIMENSION);

    // Initialise sdl2 window
    let sdl = sdl2::init().expect("couldn't create sdl2 context");
    let video_subsystem = sdl.video().expect("couldn't create video subsystem");

    let mut windows: Vec<Window> = Vec::with_capacity(images.len());
    let mut window_visibility: Vec<bool> = Vec::with_capacity(images.len());
    for _ in 0..images.len() {
        let mut window = video_subsystem
            .window(title, window_width, window_height)
            .resizable()
            .allow_highdpi()
            .build()
            .expect("couldn't create window");

        window
            .set_minimum_size(MIN_WINDOW_DIMENSION, MIN_WINDOW_DIMENSION)
            .expect("invalid minimum size for window");

        windows.push(window);
        window_visibility.push(true);
    }

    {
        use sdl2::video::WindowPos::Positioned;

        let (base_position_x, base_position_y) = windows[0].position();
        for (i, window) in windows.iter_mut().enumerate() {
            let multiplier = 1.0 + i as f32 / 20.0;
            window.set_position(
                Positioned((base_position_x as f32 * multiplier) as i32),
                Positioned(base_position_y),
            );

            let (window_pos_x, _window_pos_y) = window.position();
            let display_bounds = video_subsystem
                .display_bounds(0)
                .expect("No bounds found for that display.");
            let screen_width = display_bounds.w;
            if window_pos_x + window_width as i32 > screen_width {
                window.set_position(
                    Positioned(screen_width - window_width as i32),
                    Positioned(base_position_y),
                );
            }
        }
    }

    let mut canvases: Vec<WindowCanvas> = Vec::with_capacity(images.len());
    for window in windows.into_iter() {
        let canvas = window
            .into_canvas()
            .software()
            .build()
            .expect("couldn't create canvas");
        canvases.push(canvas);
    }

    let mut texture_creators: Vec<TextureCreator<WindowContext>> = Vec::with_capacity(images.len());
    for canvas in canvases.iter() {
        let texture_creator = canvas.texture_creator();
        texture_creators.push(texture_creator);
    }

    // Shrinks input image to fit if required and renders to the sdl canvas

    for (i, (canvas, texture_creator)) in
        canvases.iter_mut().zip(texture_creators.iter()).enumerate()
    {
        render_image_to_canvas(
            images[i],
            window_width,
            window_height,
            canvas,
            texture_creator,
        );
    }

    let mut hidden_count = 0;

    // Create and start event loop to keep window open until Esc
    let mut event_pump = sdl.event_pump().unwrap();
    event_pump.enable_event(sdl2::event::EventType::Window);
    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit { .. }
                | Event::KeyDown {
                    keycode: Some(Keycode::Escape),
                    ..
                } => break 'running,
                Event::KeyDown {
                    keycode: Some(Keycode::Q),
                    window_id,
                    ..
                } => {
                    for (i, canvas) in canvases.iter_mut().enumerate() {
                        if window_id == canvas.window().id() {
                            canvas.window_mut().hide();
                            window_visibility[i] = false;
                            hidden_count += 1;
                        }
                        if hidden_count == images.len() {
                            break 'running;
                        }
                    }
                }
                Event::Window {
                    win_event: WindowEvent::Close,
                    window_id,
                    ..
                } => {
                    for (i, canvas) in canvases.iter_mut().enumerate() {
                        if window_id == canvas.window().id() {
                            canvas.window_mut().hide();
                            window_visibility[i] = false;
                            hidden_count += 1;
                        }
                        if hidden_count == images.len() {
                            break 'running;
                        }
                    }
                }
                Event::Window {
                    win_event: WindowEvent::Resized(w, h),
                    window_id,
                    ..
                } => {
                    for (i, (canvas, texture_creator)) in
                        canvases.iter_mut().zip(texture_creators.iter()).enumerate()
                    {
                        if window_id == canvas.window().id() {
                            render_image_to_canvas(
                                images[i],
                                w as u32,
                                h as u32,
                                canvas,
                                texture_creator,
                            );
                        }
                    }
                }
                _ => {}
            }
        }
    }
}

// Scale input image down if required so that it fits within a window of the given dimensions
fn resize_to_fit<I>(image: &I, window_width: u32, window_height: u32) -> RgbaImage
where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    let image = image.convert();
    if image.height() < window_height && image.width() < window_width {
        return image;
    }

    let scale = {
        let width_scale = window_width as f32 / image.width() as f32;
        let height_scale = window_height as f32 / image.height() as f32;
        width_scale.min(height_scale)
    };

    let height = (scale * image.height() as f32) as u32;
    let width = (scale * image.width() as f32) as u32;

    resize(&image, width, height, FilterType::Triangle)
}

fn render_image_to_canvas<I>(
    image: &I,
    window_width: u32,
    window_height: u32,
    canvas: &mut Canvas<Window>,
    texture_creator: &TextureCreator<WindowContext>,
) where
    I: GenericImageView + ConvertBuffer<RgbaImage>,
{
    let scaled_image = resize_to_fit(image, window_width, window_height);

    let (image_width, image_height) = scaled_image.dimensions();
    let mut buffer = scaled_image.into_raw();
    const CHANNEL_COUNT: u32 = 4;
    let surface = Surface::from_data(
        &mut buffer,
        image_width,
        image_height,
        image_width * CHANNEL_COUNT,
        PixelFormatEnum::ABGR8888, // sdl2 expects bits from highest to lowest
    )
    .expect("couldn't create surface");

    let texture = texture_creator
        .create_texture_from_surface(surface)
        .expect("couldn't create texture from surface");

    canvas.set_draw_color(Color::RGB(255, 255, 255));
    canvas.clear();

    let left = ((window_width - image_width) as f32 / 2f32) as i32;
    let top = ((window_height - image_height) as f32 / 2f32) as i32;
    canvas
        .copy(
            &texture,
            None,
            Rect::new(left, top, image_width, image_height),
        )
        .unwrap();
    canvas.present();
}
<|endoftext|>


<commit_before>use sfml::window::{ContextSettings, VideoMode, Close};
use sfml::window::event::Event;
use sfml::graphics::{RenderWindow, RenderTarget, Color, View};
use sfml::system::vector2::{Vector2f, ToVec};
use sfml::window::keyboard::Key as SfmlKey;

use key::{Key, SpecialKey};

use std::mem;
use std::thread;

/// The event state
///
/// Used for storing information of the events.
/// Is exposed through methods of `Window`.
pub struct EventState {
    pub right: bool,
    pub left: bool,
    pub chars: String,
    pub keys: Vec<SpecialKey>,
}

impl EventState {
    /// Create new default event state
    pub fn new() -> Self {
        EventState {
            right: false,
            left: false,
            chars: String::new(),
            keys: Vec::new(),
        }
    }
}

/// Window
pub struct Window {
    window: RenderWindow,
    /// The event state
    pub event: EventState,
}

impl Window {
    /// Create new window
    pub fn new(title: &str) -> Window {
        Window {
            window: RenderWindow::new(VideoMode::new_init(800, 600, 32),
                                      title,
                                      Close,
                                      &ContextSettings::default())
                        .expect("Could not construct window"),
            event: EventState::new(),
        }

    }

    /// Set width of the window
    pub fn width(&mut self, width: u32) -> &mut Window {
        let mut s = self.window.get_size();
        s.x = width;

        self.window.set_size(&s);
        self.goto(0.0, 0.0);

        self

    }

    /// Set the height of the window
    pub fn height(&mut self, height: u32) -> &mut Window {
        let mut s = self.window.get_size();
        s.y = height;

        self.window.set_size(&s);
        self.goto(0.0, 0.0);

        self

    }

    /// Get the mouse position
    pub fn mouse(&self) -> (f32, f32) {
        let pos = self.window.get_mouse_position().to_vector2f();

        (pos.x, pos.y)
    }

    /// Get the x coordinate of the mouse
    pub fn mx(&self) -> f32 {
        self.mouse().0
    }

    /// Get the y coordinate of the mouse
    pub fn my(&self) -> f32 {
        self.mouse().1
    }

    /// Check if the window is open
    pub fn is_open(&self) -> bool {
        self.window.is_open()
    }

    /// Is the left mouse button clicked?
    pub fn left_click(&self) -> bool {
        self.event.left
    }

    /// Is the right mouse button clicked?
    pub fn right_click(&self) -> bool {
        self.event.right
    }

    /// Is `k` (char or special key) pressed?
    pub fn key<T: Key>(&self, k: T) -> bool {
        k.is_pressed(self)
    }

    /// Poll the pressed chars
    pub fn poll_char(&mut self) -> String {
        mem::replace(&mut self.event.chars, String::new())
    }

    /// Clear the window
    pub fn clear(&mut self, r: u8, g: u8, b: u8) {
        self.window.clear(&Color::new_rgb(r, g, b));

        self.event.chars.clear();
        self.event.left = false;
        self.event.right = false;
    }

    /// Listen for events
    pub fn listen(&mut self) {

        for e in self.window.events() {
            match e {
                Event::TextEntered {
                    code: c
                } => self.event.chars.push(c),
                Event::MouseLeft => self.event.left = true,
                Event::MouseEntered => self.event.right = true,
                Event::Closed => self.window.close(),
                Event::Resized {
                    width,
                    height,
                } => {
                    self.width(width);
                    self.height(height);
                }
                Event::KeyPressed {
                    code: c,
                    ..
                } => {
                    match c {
                        SfmlKey::Escape => self.event.keys.push(SpecialKey::Escape),
                        SfmlKey::LControl | SfmlKey::RControl =>
                            self.event.keys.push(SpecialKey::Control),
                        SfmlKey::LShift | SfmlKey::RShift =>
                            self.event.keys.push(SpecialKey::Shift),
                        SfmlKey::LAlt | SfmlKey::RAlt => self.event.keys.push(SpecialKey::Alt),
                        SfmlKey::Return => self.event.keys.push(SpecialKey::Return),
                        SfmlKey::BackSpace => self.event.keys.push(SpecialKey::Backspace),
                        SfmlKey::Left => self.event.keys.push(SpecialKey::Left),
                        SfmlKey::Right => self.event.keys.push(SpecialKey::Right),
                        SfmlKey::Up => self.event.keys.push(SpecialKey::Up),
                        SfmlKey::Down => self.event.keys.push(SpecialKey::Down),
                        _ => {}
                    }
                }
                _ => {}
            }
        }
    }

    /// Update the window
    pub fn update(&mut self) -> bool {
        thread::sleep_ms(50);

        self.window.display();

        self.is_open()

    }

    /// Change view (camera) of the window
    pub fn goto(&mut self, x: f32, y: f32) {
        let size = self.window.get_size().to_vector2f();
        self.window.set_view(&View::new_init(&(Vector2f::new(x, y) + size / 2.0), &size).unwrap());
    }

    /// Convert to SFML (backend) window
    pub fn to_sfml_window(&mut self) -> &mut RenderWindow {
        &mut self.window
    }
}
<commit_msg>Fix bug in special key trigger<commit_after>use sfml::window::{ContextSettings, VideoMode, Close};
use sfml::window::event::Event;
use sfml::graphics::{RenderWindow, RenderTarget, Color, View};
use sfml::system::vector2::{Vector2f, ToVec};
use sfml::window::keyboard::Key as SfmlKey;

use key::{Key, SpecialKey};

use std::mem;
use std::thread;

/// The event state
///
/// Used for storing information of the events.
/// Is exposed through methods of `Window`.
pub struct EventState {
    pub right: bool,
    pub left: bool,
    pub chars: String,
    pub keys: Vec<SpecialKey>,
}

impl EventState {
    /// Create new default event state
    pub fn new() -> Self {
        EventState {
            right: false,
            left: false,
            chars: String::new(),
            keys: Vec::new(),
        }
    }
}

/// Window
pub struct Window {
    window: RenderWindow,
    /// The event state
    pub event: EventState,
}

impl Window {
    /// Create new window
    pub fn new(title: &str) -> Window {
        Window {
            window: RenderWindow::new(VideoMode::new_init(800, 600, 32),
                                      title,
                                      Close,
                                      &ContextSettings::default())
                        .expect("Could not construct window"),
            event: EventState::new(),
        }

    }

    /// Set width of the window
    pub fn width(&mut self, width: u32) -> &mut Window {
        let mut s = self.window.get_size();
        s.x = width;

        self.window.set_size(&s);
        self.goto(0.0, 0.0);

        self

    }

    /// Set the height of the window
    pub fn height(&mut self, height: u32) -> &mut Window {
        let mut s = self.window.get_size();
        s.y = height;

        self.window.set_size(&s);
        self.goto(0.0, 0.0);

        self

    }

    /// Get the mouse position
    pub fn mouse(&self) -> (f32, f32) {
        let pos = self.window.get_mouse_position().to_vector2f();

        (pos.x, pos.y)
    }

    /// Get the x coordinate of the mouse
    pub fn mx(&self) -> f32 {
        self.mouse().0
    }

    /// Get the y coordinate of the mouse
    pub fn my(&self) -> f32 {
        self.mouse().1
    }

    /// Check if the window is open
    pub fn is_open(&self) -> bool {
        self.window.is_open()
    }

    /// Is the left mouse button clicked?
    pub fn left_click(&self) -> bool {
        self.event.left
    }

    /// Is the right mouse button clicked?
    pub fn right_click(&self) -> bool {
        self.event.right
    }

    /// Is `k` (char or special key) pressed?
    pub fn key<T: Key>(&self, k: T) -> bool {
        k.is_pressed(self)
    }

    /// Poll the pressed chars
    pub fn poll_char(&mut self) -> String {
        mem::replace(&mut self.event.chars, String::new())
    }

    /// Clear the window
    pub fn clear(&mut self, r: u8, g: u8, b: u8) {
        self.window.clear(&Color::new_rgb(r, g, b));

        self.event.chars.clear();
        self.keys.clear();
        self.event.left = false;
        self.event.right = false;
    }

    /// Listen for events
    pub fn listen(&mut self) {

        for e in self.window.events() {
            match e {
                Event::TextEntered {
                    code: c
                } => self.event.chars.push(c),
                Event::MouseLeft => self.event.left = true,
                Event::MouseEntered => self.event.right = true,
                Event::Closed => self.window.close(),
                Event::Resized {
                    width,
                    height,
                } => {
                    self.width(width);
                    self.height(height);
                }
                Event::KeyPressed {
                    code: c,
                    ..
                } => {
                    match c {
                        SfmlKey::Escape => self.event.keys.push(SpecialKey::Escape),
                        SfmlKey::LControl | SfmlKey::RControl =>
                            self.event.keys.push(SpecialKey::Control),
                        SfmlKey::LShift | SfmlKey::RShift =>
                            self.event.keys.push(SpecialKey::Shift),
                        SfmlKey::LAlt | SfmlKey::RAlt => self.event.keys.push(SpecialKey::Alt),
                        SfmlKey::Return => self.event.keys.push(SpecialKey::Return),
                        SfmlKey::BackSpace => self.event.keys.push(SpecialKey::Backspace),
                        SfmlKey::Left => self.event.keys.push(SpecialKey::Left),
                        SfmlKey::Right => self.event.keys.push(SpecialKey::Right),
                        SfmlKey::Up => self.event.keys.push(SpecialKey::Up),
                        SfmlKey::Down => self.event.keys.push(SpecialKey::Down),
                        _ => {}
                    }
                }
                _ => {}
            }
        }
    }

    /// Update the window
    pub fn update(&mut self) -> bool {
        thread::sleep_ms(50);

        self.window.display();

        self.is_open()

    }

    /// Change view (camera) of the window
    pub fn goto(&mut self, x: f32, y: f32) {
        let size = self.window.get_size().to_vector2f();
        self.window.set_view(&View::new_init(&(Vector2f::new(x, y) + size / 2.0), &size).unwrap());
    }

    /// Convert to SFML (backend) window
    pub fn to_sfml_window(&mut self) -> &mut RenderWindow {
        &mut self.window
    }
}
<|endoftext|>