<commit_before>extern crate std;
extern crate num;
extern crate uuid;

use std::str::SendStr;
use std::io::net::ip::IpAddr;
use self::uuid::Uuid;

pub enum OpcodeRequest {
    //requests
    OpcodeStartup = 0x01,
    OpcodeCredentials = 0x04,
    OpcodeOptions = 0x05,
    OpcodeQuery = 0x07,
    OpcodePrepare = 0x09,
    OpcodeExecute = 0x0A,
    OpcodeRegister = 0x0B,
}

#[deriving(Show)]
pub enum OpcodeResponse {
    //responces
    OpcodeError = 0x00,
    OpcodeReady = 0x02,
    OpcodeAuthenticate = 0x03,
    OpcodeSupported = 0x06,
    OpcodeResult = 0x08,
    OpcodeEvent = 0x0C,

    OpcodeUnknown
}

#[deriving(Show, FromPrimitive)]
pub enum KindResult {
    KindVoid = 0x0001,
    KindRows = 0x0002,
    KindSetKeyspace = 0x0003,
    KindPrepared = 0x0004,
    KindSchemaChange = 0x0005
}

pub fn opcode_response(val: u8) -> OpcodeResponse {
    match val {
        /* requests
        0x01 => OpcodeStartup,
        0x04 => OpcodeCredentials,
        0x05 => OpcodeOptions,
        0x07 => OpcodeQuery,
        0x09 => OpcodePrepare,
        0x0B => OpcodeRegister,
        */

        0x00 => OpcodeError,
        0x02 => OpcodeReady,
        0x03 => OpcodeAuthenticate,
        0x06 => OpcodeSupported,
        0x08 => OpcodeResult,
        // 0x0A => OpcodeExecute,
        0x0C => OpcodeEvent,

        _ => OpcodeUnknown
    }
}

pub mod Consistency {
    pub enum Consistency {
        Any = 0x0000,
        One = 0x0001,
        Two = 0x0002,
        Three = 0x0003,
        Quorum = 0x0004,
        All = 0x0005,
        LocalQuorum = 0x0006,
        EachQuorum = 0x0007,
        Unknown,
    }
}

#[deriving(Show)]
pub enum CqlValueType {
    ColumnCustom = 0x0000,
    ColumnASCII = 0x0001,
    ColumnBigInt = 0x0002,
    ColumnBlob = 0x0003,
    ColumnBoolean = 0x0004,
    ColumnCounter = 0x0005,
    ColumnDecimal = 0x0006,
    ColumnDouble = 0x0007,
    ColumnFloat = 0x0008,
    ColumnInt = 0x0009,
    ColumnText = 0x000A,
    ColumnTimestamp = 0x000B,
    ColumnUuid = 0x000C,
    ColumnVarChar = 0x000D,
    ColumnVarint = 0x000E,
    ColumnTimeUuid = 0x000F,
    ColumnInet = 0x0010,
    ColumnList = 0x0020,
    ColumnMap = 0x0021,
    ColumnSet = 0x0022,
    ColumnUnknown,
}

pub fn cql_column_type(val: u16) -> CqlValueType {
    match val {
        0x0000 => ColumnCustom,
        0x0001 => ColumnASCII,
        0x0002 => ColumnBigInt,
        0x0003 => ColumnBlob,
        0x0004 => ColumnBoolean,
        0x0005 => ColumnCounter,
        0x0006 => ColumnDecimal,
        0x0007 => ColumnDouble,
        0x0008 => ColumnFloat,
        0x0009 => ColumnInt,
        0x000A => ColumnText,
        0x000B => ColumnTimestamp,
        0x000C => ColumnUuid,
        0x000D => ColumnVarChar,
        0x000E => ColumnVarint,
        0x000F => ColumnTimeUuid,
        0x0010 => ColumnInet,
        0x0020 => ColumnList,
        0x0021 => ColumnMap,
        0x0022 => ColumnSet,
        _ => ColumnUnknown
    }
}

#[deriving(Show)]
pub enum RCErrorType {
    ReadError,
    WriteError,
    SerializeError,
    ConnectionError,
    NoDataError
}

#[deriving(Show)]
pub struct RCError {
    pub kind: RCErrorType,
    pub desc: SendStr,
}

impl RCError {
    pub fn new<T: IntoMaybeOwned<'static>>(msg: T, kind: RCErrorType) -> RCError {
        RCError {
            kind: kind,
            desc: msg.into_maybe_owned()
        }
    }
}

pub type RCResult<T> = Result<T, RCError>;

pub struct CqlStringMap {
    pub pairs: Vec<CqlPair>,
}

pub struct CqlPair {
    pub key: &'static str,
    pub value: &'static str,
}

pub enum CqlBytesSize {
   Cqli32,
   Cqli16
}

#[deriving(Show)]
pub struct CqlColMetadata {
    pub keyspace: SendStr,
    pub table: SendStr,
    pub col_name: SendStr,
    pub col_type: CqlValueType,
    pub col_type_aux1: CqlValueType,
    pub col_type_aux2: CqlValueType
}

#[deriving(Show)]
pub struct CqlMetadata {
    pub flags: u32,
    pub column_count: u32,
    pub keyspace: SendStr,
    pub table: SendStr,
    pub row_metadata: Vec<CqlColMetadata>,
}

#[deriving(Show)]
pub struct Pair<T, V> {
    pub key: T,
    pub value: V
}

pub type CQLList = Vec<CqlValue>;
pub type CQLMap = Vec<Pair<CqlValue, CqlValue>>;
pub type CQLSet = Vec<CqlValue>;

#[deriving(Show)]
pub enum CqlValue {
    CqlASCII(Option<SendStr>),
    CqlBigInt(Option<i64>),
    CqlBlob(Option<Vec<u8>>),
    CqlBoolean(Option<bool>),
    CqlCounter(Option<i64>),
    CqlDecimal(Option<num::BigInt>),
    CqlDouble(Option<f64>),
    CqlFloat(Option<f32>),
    CqlInet(Option<IpAddr>),
    CqlInt(Option<i32>),
    CqlList(Option<CQLList>),
    CqlMap(Option<CQLMap>),
    CqlSet(Option<CQLSet>),
    CqlText(Option<SendStr>),
    CqlTimestamp(Option<u64>),
    CqlUuid(Option<Uuid>),
    CqlTimeUuid(Option<Uuid>),
    CqlVarchar(Option<SendStr>),
    CqlVarint(Option<num::BigInt>),
    CqlUnknown,
}

#[deriving(Show)]
pub struct CqlRow {
    pub cols: Vec<CqlValue>,
}

/*
impl CqlRow {
    fn get_column(&self, col_name: &str) -> Option<CqlValue> {
        let mut i = 0;
        let len = self.metadata.row_metadata.len();
        while i < len {
            if self.metadata.row_metadata.get(i).col_name.as_slice() == col_name {
                return Some(*self.cols.get(i));
            }
            i += 1;
        }
        None
    }
}
*/

#[deriving(Show)]
pub struct CqlRows {
    pub metadata: Box<CqlMetadata>,
    pub rows: Vec<CqlRow>,
}

pub struct CqlRequest<'a> {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeRequest,
    pub body: CqlRequestBody<'a>,
}

pub enum CqlRequestBody<'a> {
    RequestStartup(CqlStringMap),
    RequestCred(&'a Vec<SendStr>),
    RequestQuery(SendStr, Consistency::Consistency, u8),
    RequestPrepare(SendStr),
    RequestExec(&'a CqlPreparedStat, Vec<CqlValue>, Consistency::Consistency, u8),
    RequestOptions,
}

#[deriving(Show)]
pub struct CqlResponse {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeResponse,
    pub body: CqlResponseBody,
}

#[deriving(Show)]
pub enum CqlResponseBody {
    ResponseError(u32, SendStr),
    ResponseReady,
    ResponseAuth(SendStr),

    ResultVoid,
    ResultRows(Box<CqlRows>),
    ResultKeyspace(SendStr),
    ResultPrepared(Box<CqlPreparedStat>),
    ResultSchemaChange(SendStr, SendStr, SendStr),
    ResultUnknown,

    ResponseEmpty,
}

#[deriving(Show)]
pub struct CqlPreparedStat {
    pub id: Vec<u8>,
    pub meta: Box<CqlMetadata>,
    pub meta_result: Option<Box<CqlMetadata>>
}

<commit_msg>Added new error type Moved some Vec and String to &[] and &str<commit_after>extern crate std;
extern crate num;
extern crate uuid;

use std::str::SendStr;
use std::io::net::ip::IpAddr;
use self::uuid::Uuid;

pub enum OpcodeRequest {
    //requests
    OpcodeStartup = 0x01,
    OpcodeCredentials = 0x04,
    OpcodeOptions = 0x05,
    OpcodeQuery = 0x07,
    OpcodePrepare = 0x09,
    OpcodeExecute = 0x0A,
    OpcodeRegister = 0x0B,
}

#[deriving(Show)]
pub enum OpcodeResponse {
    //responces
    OpcodeError = 0x00,
    OpcodeReady = 0x02,
    OpcodeAuthenticate = 0x03,
    OpcodeSupported = 0x06,
    OpcodeResult = 0x08,
    OpcodeEvent = 0x0C,

    OpcodeUnknown
}

#[deriving(Show, FromPrimitive)]
pub enum KindResult {
    KindVoid = 0x0001,
    KindRows = 0x0002,
    KindSetKeyspace = 0x0003,
    KindPrepared = 0x0004,
    KindSchemaChange = 0x0005
}

pub fn opcode_response(val: u8) -> OpcodeResponse {
    match val {
        /* requests
        0x01 => OpcodeStartup,
        0x04 => OpcodeCredentials,
        0x05 => OpcodeOptions,
        0x07 => OpcodeQuery,
        0x09 => OpcodePrepare,
        0x0B => OpcodeRegister,
        */

        0x00 => OpcodeError,
        0x02 => OpcodeReady,
        0x03 => OpcodeAuthenticate,
        0x06 => OpcodeSupported,
        0x08 => OpcodeResult,
        // 0x0A => OpcodeExecute,
        0x0C => OpcodeEvent,

        _ => OpcodeUnknown
    }
}

pub mod Consistency {
    pub enum Consistency {
        Any = 0x0000,
        One = 0x0001,
        Two = 0x0002,
        Three = 0x0003,
        Quorum = 0x0004,
        All = 0x0005,
        LocalQuorum = 0x0006,
        EachQuorum = 0x0007,
        Unknown,
    }
}

#[deriving(Show)]
pub enum CqlValueType {
    ColumnCustom = 0x0000,
    ColumnASCII = 0x0001,
    ColumnBigInt = 0x0002,
    ColumnBlob = 0x0003,
    ColumnBoolean = 0x0004,
    ColumnCounter = 0x0005,
    ColumnDecimal = 0x0006,
    ColumnDouble = 0x0007,
    ColumnFloat = 0x0008,
    ColumnInt = 0x0009,
    ColumnText = 0x000A,
    ColumnTimestamp = 0x000B,
    ColumnUuid = 0x000C,
    ColumnVarChar = 0x000D,
    ColumnVarint = 0x000E,
    ColumnTimeUuid = 0x000F,
    ColumnInet = 0x0010,
    ColumnList = 0x0020,
    ColumnMap = 0x0021,
    ColumnSet = 0x0022,
    ColumnUnknown,
}

pub fn cql_column_type(val: u16) -> CqlValueType {
    match val {
        0x0000 => ColumnCustom,
        0x0001 => ColumnASCII,
        0x0002 => ColumnBigInt,
        0x0003 => ColumnBlob,
        0x0004 => ColumnBoolean,
        0x0005 => ColumnCounter,
        0x0006 => ColumnDecimal,
        0x0007 => ColumnDouble,
        0x0008 => ColumnFloat,
        0x0009 => ColumnInt,
        0x000A => ColumnText,
        0x000B => ColumnTimestamp,
        0x000C => ColumnUuid,
        0x000D => ColumnVarChar,
        0x000E => ColumnVarint,
        0x000F => ColumnTimeUuid,
        0x0010 => ColumnInet,
        0x0020 => ColumnList,
        0x0021 => ColumnMap,
        0x0022 => ColumnSet,
        _ => ColumnUnknown
    }
}

#[deriving(Show)]
pub enum RCErrorType {
    ReadError,
    WriteError,
    SerializeError,
    ConnectionError,
    NoDataError,
    GenericError
}

#[deriving(Show)]
pub struct RCError {
    pub kind: RCErrorType,
    pub desc: SendStr,
}

impl RCError {
    pub fn new<T: IntoMaybeOwned<'static>>(msg: T, kind: RCErrorType) -> RCError {
        RCError {
            kind: kind,
            desc: msg.into_maybe_owned()
        }
    }
}

pub type RCResult<T> = Result<T, RCError>;

pub struct CqlStringMap {
    pub pairs: Vec<CqlPair>,
}

pub struct CqlPair {
    pub key: &'static str,
    pub value: &'static str,
}

pub enum CqlBytesSize {
   Cqli32,
   Cqli16
}

#[deriving(Show)]
pub struct CqlColMetadata {
    pub keyspace: SendStr,
    pub table: SendStr,
    pub col_name: SendStr,
    pub col_type: CqlValueType,
    pub col_type_aux1: CqlValueType,
    pub col_type_aux2: CqlValueType
}

#[deriving(Show)]
pub struct CqlMetadata {
    pub flags: u32,
    pub column_count: u32,
    pub keyspace: SendStr,
    pub table: SendStr,
    pub row_metadata: Vec<CqlColMetadata>,
}

#[deriving(Show)]
pub struct Pair<T, V> {
    pub key: T,
    pub value: V
}

pub type CQLList = Vec<CqlValue>;
pub type CQLMap = Vec<Pair<CqlValue, CqlValue>>;
pub type CQLSet = Vec<CqlValue>;

#[deriving(Show)]
pub enum CqlValue {
    CqlASCII(Option<SendStr>),
    CqlBigInt(Option<i64>),
    CqlBlob(Option<Vec<u8>>),
    CqlBoolean(Option<bool>),
    CqlCounter(Option<i64>),
    CqlDecimal(Option<num::BigInt>),
    CqlDouble(Option<f64>),
    CqlFloat(Option<f32>),
    CqlInet(Option<IpAddr>),
    CqlInt(Option<i32>),
    CqlList(Option<CQLList>),
    CqlMap(Option<CQLMap>),
    CqlSet(Option<CQLSet>),
    CqlText(Option<SendStr>),
    CqlTimestamp(Option<u64>),
    CqlUuid(Option<Uuid>),
    CqlTimeUuid(Option<Uuid>),
    CqlVarchar(Option<SendStr>),
    CqlVarint(Option<num::BigInt>),
    CqlUnknown,
}

#[deriving(Show)]
pub struct CqlRow {
    pub cols: Vec<CqlValue>,
}

/*
impl CqlRow {
    fn get_column(&self, col_name: &str) -> Option<CqlValue> {
        let mut i = 0;
        let len = self.metadata.row_metadata.len();
        while i < len {
            if self.metadata.row_metadata.get(i).col_name.as_slice() == col_name {
                return Some(*self.cols.get(i));
            }
            i += 1;
        }
        None
    }
}
*/

#[deriving(Show)]
pub struct CqlRows {
    pub metadata: Box<CqlMetadata>,
    pub rows: Vec<CqlRow>,
}

pub struct CqlRequest<'a> {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeRequest,
    pub body: CqlRequestBody<'a>,
}

pub enum CqlRequestBody<'a> {
    RequestStartup(CqlStringMap),
    RequestCred(&'a Vec<SendStr>),
    RequestQuery(SendStr, Consistency::Consistency, u8),
    RequestPrepare(&'a str),
    RequestExec(&'a CqlPreparedStat, &'a [CqlValue], Consistency::Consistency, u8),
    RequestOptions,
}

#[deriving(Show)]
pub struct CqlResponse {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeResponse,
    pub body: CqlResponseBody,
}

#[deriving(Show)]
pub enum CqlResponseBody {
    ResponseError(u32, SendStr),
    ResponseReady,
    ResponseAuth(SendStr),

    ResultVoid,
    ResultRows(Box<CqlRows>),
    ResultKeyspace(SendStr),
    ResultPrepared(Box<CqlPreparedStat>),
    ResultSchemaChange(SendStr, SendStr, SendStr),
    ResultUnknown,

    ResponseEmpty,
}

#[deriving(Show)]
pub struct CqlPreparedStat {
    pub id: Vec<u8>,
    pub meta: Box<CqlMetadata>,
    pub meta_result: Option<Box<CqlMetadata>>
}

<|endoftext|>


<commit_before>// External modules:
use darwin_rs::{Individual, SimulationBuilder, Population, PopulationBuilder};
use image;
// use image::{GenericImage, FilterType, DynamicImage, imageops};
use image::{GenericImage, DynamicImage, Rgba};
use rand::Rng;
use rand;
use walkdir::{WalkDir};

// use std::path::Path;
use std::f64::consts::PI;
use std::cmp;

// Internal modules:
use config::PanolutionConfig;

#[derive(Clone)]
pub struct ImageArrangement {
    pub file_name: String, // TODO: Share path between individuals
    // TODO: Add image and share it, so it doesn't have to be re-loaded every time
    pub samples: u32,
    pub x0: u32,
    pub y0: u32,
    pub x1: u32,
    pub y1: u32,
    pub angle: f64,
    // TODO: add more image operations
}

#[derive(Clone)]
pub struct Solution {
    pub arrangement: Vec<ImageArrangement>,
}

struct SamplePixel{
    x: u32,
    y: u32,
    pixels: Vec<(u8, u8, u8)>
}

fn valid_image_file(file_name: &str) -> bool {
    let extension = file_name.split(".").last().unwrap_or("").to_lowercase();

    let supported: Vec<String> = vec!["jpg", "jpeg", "gif", "png", "tif", "tiff"].iter().map(|s| s.to_string()).collect();

    supported.contains(&extension)
}

fn calc_canvas_size(arrangement: &Vec<ImageArrangement>) -> (u32, u32, u32, u32) {
    arrangement.iter().fold((u32::max_value(), u32::max_value(), 0, 0), |(cx0, cy0, cx1, cy1), im_ar| {
        (cmp::min(cx0, im_ar.x0), cmp::min(cy0, im_ar.y0), cmp::max(cx1, im_ar.x1), cmp::max(cy1, im_ar.y1))
    })
}

fn get_pixel(cx: f64, cy: f64, im_ar: &ImageArrangement, img: &DynamicImage) -> Option<(u8, u8, u8)> {
    // Center of image
    let mx = ((im_ar.x0 + im_ar.x1) / 2) as f64;
    let my = ((im_ar.y0 + im_ar.y1) / 2) as f64;

    // Move center of rotation to origin (0,0)
    let ox = cx - mx;
    let oy = cy - my;

    // Rotate canvas point in reverse of image orientation (clockwise)
    let cos_a = im_ar.angle.cos();
    let sin_a = im_ar.angle.sin();

    let rx = (ox * cos_a) + (oy * sin_a);
    let ry = (-ox * sin_a) + (oy * cos_a);

    // Move back to image coordinate system
    let imx = (rx + mx) as u32;
    let imy = (ry + my) as u32;

    // Check if point is inside the image:

    if (imx >= im_ar.x0) && (imx <= im_ar.x1) && (imy >= im_ar.y0) && (imy <= im_ar.y1) {
        let pixel = img.get_pixel(imx - im_ar.x0, imy - im_ar.y0) as Rgba<u8>;
        return Some((pixel.data[0], pixel.data[1], pixel.data[2]));
    }

    None
}

fn make_all_populations(num_of_individuals: u32, num_of_populations: u32, initial_solution: &Solution) -> Vec<Population<Solution>> {
    let mut result = Vec::new();

    let mut initial_population = Vec::new();

    for _ in 0..num_of_individuals {
        initial_population.push(initial_solution.clone());
    }

    for i in 0..num_of_populations {
        let pop = PopulationBuilder::<Solution>::new()
            .set_id(i + 1)
            .initial_population(&initial_population)
            .reset_limit_end(0)
            .increasing_mutation_rate()
            .finalize().unwrap();

        result.push(pop);
    }

    result
}

impl Individual for Solution {
    fn mutate(&mut self) {
        let mut rng = rand::thread_rng();
        let num_of_operations: u8 = 4;

        let index1: usize = rng.gen_range(0, self.arrangement.len());

        // Probably use this create and enums for operation:
        // https://github.com/andersk/enum_primitive-rs
        let operation: u8 = rng.gen_range(0, num_of_operations);

        match operation {
            0 => {
                // Change image order
                let mut index2: usize = rng.gen_range(0, self.arrangement.len());
                while index1 == index2 {
                    index2 = rng.gen_range(0, self.arrangement.len());
                }

                self.arrangement.swap(index1, index2);
            },
            1 => {
                // Move x
                let dx = rng.gen_range::<i32>(0, 500) - 250;
                let new_x = (self.arrangement[index1].x0 as i32) + dx;

                if new_x >= 0 {
                    self.arrangement[index1].x0 = new_x as u32;
                    self.arrangement[index1].x1 = ((self.arrangement[index1].x1 as i32) + dx) as u32;
                }
            },
            2 => {
                // Move y
                let dy = rng.gen_range::<i32>(0, 500) - 250;
                let new_y = (self.arrangement[index1].y0 as i32) + dy;

                if new_y >= 0 {
                    self.arrangement[index1].y0 = new_y as u32;
                    self.arrangement[index1].y1 = ((self.arrangement[index1].y1 as i32) + dy) as u32;
                }
            },
            3 => {
                // Rotate
                self.arrangement[index1].angle = self.arrangement[index1].angle + (rng.next_f64() * 0.1);
                if self.arrangement[index1].angle < 0.0 {
                    self.arrangement[index1].angle = 0.0;
                } else if self.arrangement[index1].angle > 2.0 * PI {
                    self.arrangement[index1].angle = 0.0;
                }
            },
            op => {
                warn!("mutate(): unknown operation: {}", op)
            }
        }
    }

    fn calculate_fitness(&mut self) -> f64 {
        let mut fitness = 0.0;

        let num_of_samples = self.arrangement[0].samples;

        let (cx0, cy0, cx1, cy1) = calc_canvas_size(&self.arrangement);

        // Create sample points on canvas:
        let mut rng = rand::thread_rng();
        let mut sample_pixels = Vec::new();

        for _ in 0..num_of_samples {
            sample_pixels.push(SamplePixel{
                x: rng.gen_range::<u32>(cx0, cx1),
                y: rng.gen_range::<u32>(cy0, cy1),
                pixels: Vec::new()
            });
        }

        for im_ar in &self.arrangement {
            if let Ok(img) = image::open(&im_ar.file_name) {
                for sp in &mut sample_pixels {
                    if let Some(pixel) = get_pixel(sp.x as f64, sp.y as f64, &im_ar, &img) {
                        sp.pixels.push(pixel);
                    }
                }
            }
        }

        fitness
    }

    fn reset(&mut self) {
        for arrangement in &mut self.arrangement {
            // Reset all image operation to original image
            arrangement.x1 = arrangement.x1 - arrangement.x0;
            arrangement.y1 = arrangement.y1 - arrangement.y0;
            arrangement.x0 = 0;
            arrangement.y0 = 0;
            arrangement.angle = 0.0;
        }
    }
}

fn run_darwin(solution: &Solution, config: &PanolutionConfig) -> Solution {
    let pano = SimulationBuilder::<Solution>::new()
        .iterations(config.max_iteration)
        .threads(config.num_of_threads)
        .add_multiple_populations(make_all_populations(10, 8, &solution))
        .finalize();

    match pano {
        Err(e) => {
            error!("An error occured");

            for e in e.iter().skip(1) {
                error!("Caused by '{}'", e)
            }

            solution.clone()
        },
        Ok(mut pano_simulation) => {
            pano_simulation.run();

            info!("Total run time: {} ms", pano_simulation.total_time_in_ms);
            info!("Improvement factor: {}", pano_simulation.simulation_result.improvement_factor);
            info!("Number of iterations: {}", pano_simulation.simulation_result.iteration_counter);

            pano_simulation.simulation_result.fittest[0].individual.clone()
        }
    }
}

pub fn optimize(solution: Option<&Solution>, config: &PanolutionConfig, sample_index: usize) -> Solution {
    match solution {
        None => {
            let mut arrangement = Vec::new();

            for entry in WalkDir::new(&config.input_path) {
                if let Ok(entry) = entry {
                    if entry.file_type().is_file() {
                        if let Some(file_name) = entry.file_name().to_str() {
                            if valid_image_file(file_name) {
                                if let Some(full_path) = entry.path().to_str() {

                                    if let Ok(img) = image::open(&full_path) {
                                        arrangement.push(ImageArrangement{
                                            file_name: full_path.to_string(),
                                            samples: config.num_of_samples[sample_index],
                                            x0: 0,
                                            y0: 0,
                                            x1: img.width(),
                                            y1: img.height(),
                                            angle: 0.0,
                                        });
                                    } else {
                                        error!("Could not open image: {}", full_path)
                                    }
                                } else {
                                    error!("Could not convert full path to str: {:?}", entry);
                                }
                            } else {
                                error!("Image format currently not supported: {}", file_name);
                            }
                        } else {
                            error!("Could not convert file name to str: {:?}", entry);
                        }
                    } else {
                        info!("Ignore non-file: {:?}", entry);
                    }
                } else {
                    error!("Error in WalkDir");
                }
            }

            let solution = Solution{arrangement: arrangement};

            if solution.arrangement.len() > 0 {
                run_darwin(&solution, &config)
            } else {
                // An error occured
                // TODO: return Result<Soultion> and use chain_err
                solution
            }
        },
        Some(solution) => {
            let mut updated_arrangement = solution.arrangement.clone();

            for im_ar in &mut updated_arrangement {
                im_ar.samples = config.num_of_samples[sample_index];
            }

            run_darwin(&Solution{arrangement: updated_arrangement}, &config)
        }
    }
}
<commit_msg>fix bounds check<commit_after>// External modules:
use darwin_rs::{Individual, SimulationBuilder, Population, PopulationBuilder};
use image;
// use image::{GenericImage, FilterType, DynamicImage, imageops};
use image::{GenericImage, DynamicImage, Rgba};
use rand::Rng;
use rand;
use walkdir::{WalkDir};

// use std::path::Path;
use std::f64::consts::PI;
use std::cmp;

// Internal modules:
use config::PanolutionConfig;

#[derive(Clone)]
pub struct ImageArrangement {
    pub file_name: String, // TODO: Share path between individuals
    // TODO: Add image and share it, so it doesn't have to be re-loaded every time
    pub samples: u32,
    pub x0: u32,
    pub y0: u32,
    pub x1: u32,
    pub y1: u32,
    pub angle: f64,
    // TODO: add more image operations
}

#[derive(Clone)]
pub struct Solution {
    pub arrangement: Vec<ImageArrangement>,
}

struct SamplePixel{
    x: u32,
    y: u32,
    pixels: Vec<(u8, u8, u8)>
}

fn valid_image_file(file_name: &str) -> bool {
    let extension = file_name.split(".").last().unwrap_or("").to_lowercase();

    let supported: Vec<String> = vec!["jpg", "jpeg", "gif", "png", "tif", "tiff"].iter().map(|s| s.to_string()).collect();

    supported.contains(&extension)
}

fn calc_canvas_size(arrangement: &Vec<ImageArrangement>) -> (u32, u32, u32, u32) {
    arrangement.iter().fold((u32::max_value(), u32::max_value(), 0, 0), |(cx0, cy0, cx1, cy1), im_ar| {
        (cmp::min(cx0, im_ar.x0), cmp::min(cy0, im_ar.y0), cmp::max(cx1, im_ar.x1), cmp::max(cy1, im_ar.y1))
    })
}

fn get_pixel(cx: f64, cy: f64, im_ar: &ImageArrangement, img: &DynamicImage) -> Option<(u8, u8, u8)> {
    // Center of image
    let mx = ((im_ar.x0 + im_ar.x1) / 2) as f64;
    let my = ((im_ar.y0 + im_ar.y1) / 2) as f64;

    // Move center of rotation to origin (0,0)
    let ox = cx - mx;
    let oy = cy - my;

    // Rotate canvas point in reverse of image orientation (clockwise)
    let cos_a = im_ar.angle.cos();
    let sin_a = im_ar.angle.sin();

    let rx = (ox * cos_a) + (oy * sin_a);
    let ry = (-ox * sin_a) + (oy * cos_a);

    // Move back to image coordinate system
    let imx = ((rx + mx) as u32) - im_ar.x0;
    let imy = ((ry + my) as u32) - im_ar.y0;

    // Check if point is inside the image:

    if (imx >= 0) && (imx < img.width()) && (imy >= 0) && (imy < img.height()) {
        let pixel = img.get_pixel(imx, imy) as Rgba<u8>;
        return Some((pixel.data[0], pixel.data[1], pixel.data[2]));
    }

    None
}

fn make_all_populations(num_of_individuals: u32, num_of_populations: u32, initial_solution: &Solution) -> Vec<Population<Solution>> {
    let mut result = Vec::new();

    let mut initial_population = Vec::new();

    for _ in 0..num_of_individuals {
        initial_population.push(initial_solution.clone());
    }

    for i in 0..num_of_populations {
        let pop = PopulationBuilder::<Solution>::new()
            .set_id(i + 1)
            .initial_population(&initial_population)
            .reset_limit_end(0)
            .increasing_mutation_rate()
            .finalize().unwrap();

        result.push(pop);
    }

    result
}

impl Individual for Solution {
    fn mutate(&mut self) {
        let mut rng = rand::thread_rng();
        let num_of_operations: u8 = 4;

        let index1: usize = rng.gen_range(0, self.arrangement.len());

        // Probably use this create and enums for operation:
        // https://github.com/andersk/enum_primitive-rs
        let operation: u8 = rng.gen_range(0, num_of_operations);

        match operation {
            0 => {
                // Change image order
                let mut index2: usize = rng.gen_range(0, self.arrangement.len());
                while index1 == index2 {
                    index2 = rng.gen_range(0, self.arrangement.len());
                }

                self.arrangement.swap(index1, index2);
            },
            1 => {
                // Move x
                let dx = rng.gen_range::<i32>(0, 500) - 250;
                let new_x = (self.arrangement[index1].x0 as i32) + dx;

                if new_x >= 0 {
                    self.arrangement[index1].x0 = new_x as u32;
                    self.arrangement[index1].x1 = ((self.arrangement[index1].x1 as i32) + dx) as u32;
                }
            },
            2 => {
                // Move y
                let dy = rng.gen_range::<i32>(0, 500) - 250;
                let new_y = (self.arrangement[index1].y0 as i32) + dy;

                if new_y >= 0 {
                    self.arrangement[index1].y0 = new_y as u32;
                    self.arrangement[index1].y1 = ((self.arrangement[index1].y1 as i32) + dy) as u32;
                }
            },
            3 => {
                // Rotate
                self.arrangement[index1].angle = self.arrangement[index1].angle + (rng.next_f64() * 0.1);
                if self.arrangement[index1].angle < 0.0 {
                    self.arrangement[index1].angle = 0.0;
                } else if self.arrangement[index1].angle > 2.0 * PI {
                    self.arrangement[index1].angle = 0.0;
                }
            },
            op => {
                warn!("mutate(): unknown operation: {}", op)
            }
        }
    }

    fn calculate_fitness(&mut self) -> f64 {
        let mut fitness = 0.0;

        let num_of_samples = self.arrangement[0].samples;

        let (cx0, cy0, cx1, cy1) = calc_canvas_size(&self.arrangement);

        // Create sample points on canvas:
        let mut rng = rand::thread_rng();
        let mut sample_pixels = Vec::new();

        for _ in 0..num_of_samples {
            sample_pixels.push(SamplePixel{
                x: rng.gen_range::<u32>(cx0, cx1),
                y: rng.gen_range::<u32>(cy0, cy1),
                pixels: Vec::new()
            });
        }

        for im_ar in &self.arrangement {
            if let Ok(img) = image::open(&im_ar.file_name) {
                for sp in &mut sample_pixels {
                    if let Some(pixel) = get_pixel(sp.x as f64, sp.y as f64, &im_ar, &img) {
                        sp.pixels.push(pixel);
                    }
                }
            }
        }

        fitness
    }

    fn reset(&mut self) {
        for arrangement in &mut self.arrangement {
            // Reset all image operation to original image
            arrangement.x1 = arrangement.x1 - arrangement.x0;
            arrangement.y1 = arrangement.y1 - arrangement.y0;
            arrangement.x0 = 0;
            arrangement.y0 = 0;
            arrangement.angle = 0.0;
        }
    }
}

fn run_darwin(solution: &Solution, config: &PanolutionConfig) -> Solution {
    let pano = SimulationBuilder::<Solution>::new()
        .iterations(config.max_iteration)
        .threads(config.num_of_threads)
        .add_multiple_populations(make_all_populations(10, 8, &solution))
        .finalize();

    match pano {
        Err(e) => {
            error!("An error occured");

            for e in e.iter().skip(1) {
                error!("Caused by '{}'", e)
            }

            solution.clone()
        },
        Ok(mut pano_simulation) => {
            pano_simulation.run();

            info!("Total run time: {} ms", pano_simulation.total_time_in_ms);
            info!("Improvement factor: {}", pano_simulation.simulation_result.improvement_factor);
            info!("Number of iterations: {}", pano_simulation.simulation_result.iteration_counter);

            pano_simulation.simulation_result.fittest[0].individual.clone()
        }
    }
}

pub fn optimize(solution: Option<&Solution>, config: &PanolutionConfig, sample_index: usize) -> Solution {
    match solution {
        None => {
            let mut arrangement = Vec::new();

            for entry in WalkDir::new(&config.input_path) {
                if let Ok(entry) = entry {
                    if entry.file_type().is_file() {
                        if let Some(file_name) = entry.file_name().to_str() {
                            if valid_image_file(file_name) {
                                if let Some(full_path) = entry.path().to_str() {

                                    if let Ok(img) = image::open(&full_path) {
                                        arrangement.push(ImageArrangement{
                                            file_name: full_path.to_string(),
                                            samples: config.num_of_samples[sample_index],
                                            x0: 0,
                                            y0: 0,
                                            x1: img.width(),
                                            y1: img.height(),
                                            angle: 0.0,
                                        });
                                    } else {
                                        error!("Could not open image: {}", full_path)
                                    }
                                } else {
                                    error!("Could not convert full path to str: {:?}", entry);
                                }
                            } else {
                                error!("Image format currently not supported: {}", file_name);
                            }
                        } else {
                            error!("Could not convert file name to str: {:?}", entry);
                        }
                    } else {
                        info!("Ignore non-file: {:?}", entry);
                    }
                } else {
                    error!("Error in WalkDir");
                }
            }

            let solution = Solution{arrangement: arrangement};

            if solution.arrangement.len() > 0 {
                run_darwin(&solution, &config)
            } else {
                // An error occured
                // TODO: return Result<Soultion> and use chain_err
                solution
            }
        },
        Some(solution) => {
            let mut updated_arrangement = solution.arrangement.clone();

            for im_ar in &mut updated_arrangement {
                im_ar.samples = config.num_of_samples[sample_index];
            }

            run_darwin(&Solution{arrangement: updated_arrangement}, &config)
        }
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io::{self, Write};
use std::net::Shutdown;
use std::rc::Rc;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready, Token};

use super::binary;
use super::close_listener::CloseListener;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::router::Router;
use super::selector::{EventHandler, Selector};
use super::stream_buffer::StreamBuffer;

const TAG: &'static str = "Client";

pub struct Client {
    id: u32,
    stream: TcpStream,
    token: Token,
    client_to_network: IPv4PacketBuffer,
    network_to_client: StreamBuffer,
    router: Router,
    close_listener: Box<CloseListener<Client>>,
    closed: bool,
    // number of remaining bytes of "id" to send to the client before relaying any data
    pending_id_bytes: usize,
}

impl Client {
    pub fn new(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: Box<CloseListener<Client>>) -> io::Result<Rc<RefCell<Self>>> {
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            stream: stream,
            token: Token(0), // default value, will be set afterwards
            client_to_network: IPv4PacketBuffer::new(),
            network_to_client: StreamBuffer::new(16 * MAX_PACKET_LENGTH),
            router: Router::new(),
            closed: false,
            close_listener: close_listener,
            pending_id_bytes: 4,
        }));

        {
            let mut self_ref = rc.borrow_mut();
            // set client as router owner
            self_ref.router.set_client(Rc::downgrade(&rc));

            // rc is an EventHandler, register() expects a Box<EventHandler>
            let handler = Box::new(rc.clone());
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn id(&self) -> u32 {
        return self.id;
    }

    pub fn router(&mut self) -> &mut Router {
        &mut self.router
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token).unwrap();
        // shutdown only (there is no close), the socket will be closed on drop
        if let Err(_) = self.stream.shutdown(Shutdown::Both) {
            warn!(target: TAG, "Cannot shutdown client socket");
        }
        self.router.clear(selector);
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if self.must_send_id() {
            match self.send_id() {
                Ok(_) => {
                    if self.pending_id_bytes == 0 {
                        debug!(target:TAG, "Client id #{} sent to client", self.id);
                    }
                }
                Err(_) => {
                    error!(target: TAG, "Cannot write client id #{}", self.id);
                    self.close(selector);
                }
            }
        } else {
            match self.write() {
                Ok(_) => self.process_pending(),
                Err(_) => {
                    error!(target: TAG, "Cannot write");
                    self.close(selector);
                }
            }
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(true) => self.push_to_network(selector),
            Ok(false) => {
                debug!(target: TAG, "EOF reached");
                self.close(selector);
            }
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    pub fn send_to_client(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) -> io::Result<()> {
        self.send_raw_to_client(selector, ipv4_packet.raw())
    }

    pub fn send_raw_to_client(&mut self, selector: &mut Selector, raw: &[u8]) -> io::Result<()> {
        if raw.len() as usize <= self.network_to_client.remaining() {
            self.network_to_client.read_from(raw)?;
            self.update_interests(selector);
            Ok(())
        } else {
            warn!(target: TAG, "Client buffer full");
            Err(io::Error::new(io::ErrorKind::WouldBlock, "Client buffer full"))
        }
    }

    fn send_id(&mut self) -> io::Result<()> {
        assert!(self.must_send_id());
        let raw_id = binary::to_byte_array(self.id);
        let w = self.stream.write(&raw_id[4 - self.pending_id_bytes..])?;
        self.pending_id_bytes -= w;
        Ok(())
    }

    fn update_interests(&mut self, selector: &mut Selector) {
        let ready = if self.network_to_client.is_empty() {
            Ready::readable()
        } else {
            Ready::readable() | Ready::writable()
        };
        selector.reregister(&self.stream, self.token, ready, PollOpt::level()).expect("Cannot register on poll");
    }

    fn read(&mut self) -> io::Result<(bool)> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn write(&mut self) -> io::Result<()> {
        self.network_to_client.write_to(&mut self.stream)?;
        Ok(())
    }

    fn push_to_network(&mut self, selector: &mut Selector) {
        while self.push_one_packet_to_network(selector) {
            self.client_to_network.next();
        }
    }

    fn push_one_packet_to_network(&mut self, selector: &mut Selector) -> bool {
        match self.client_to_network.as_ipv4_packet() {
            Some(ref packet) => {
                self.router.send_to_network(selector, packet);
                true
            }
            None => false
        }
    }

    fn process_pending(&mut self) {
        // TODO
    }

    pub fn clean_expired_connections(&mut self, selector: &mut Selector) {
        self.router.clean_expired_connections(selector);
    }

    fn must_send_id(&self) -> bool{
        self.pending_id_bytes > 0
    }
}

impl EventHandler for Client {
    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}
<commit_msg>Self-weak for Client<commit_after>use std::cell::RefCell;
use std::io::{self, Write};
use std::net::Shutdown;
use std::rc::{Rc, Weak};
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready, Token};

use super::binary;
use super::close_listener::CloseListener;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::router::Router;
use super::selector::{EventHandler, Selector};
use super::stream_buffer::StreamBuffer;

const TAG: &'static str = "Client";

pub struct Client {
    self_weak: Weak<RefCell<Client>>,
    id: u32,
    stream: TcpStream,
    token: Token,
    client_to_network: IPv4PacketBuffer,
    network_to_client: StreamBuffer,
    router: Router,
    close_listener: Box<CloseListener<Client>>,
    closed: bool,
    // number of remaining bytes of "id" to send to the client before relaying any data
    pending_id_bytes: usize,
}

impl Client {
    pub fn new(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: Box<CloseListener<Client>>) -> io::Result<Rc<RefCell<Self>>> {
        let rc = Rc::new(RefCell::new(Self {
            self_weak: Weak::new(),
            id: id,
            stream: stream,
            token: Token(0), // default value, will be set afterwards
            client_to_network: IPv4PacketBuffer::new(),
            network_to_client: StreamBuffer::new(16 * MAX_PACKET_LENGTH),
            router: Router::new(),
            closed: false,
            close_listener: close_listener,
            pending_id_bytes: 4,
        }));

        {
            let mut self_ref = rc.borrow_mut();
            // keep a shared reference to this client
            self_ref.self_weak = Rc::downgrade(&rc);
            // set client as router owner
            self_ref.router.set_client(Rc::downgrade(&rc));

            // rc is an EventHandler, register() expects a Box<EventHandler>
            let handler = Box::new(rc.clone());
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn id(&self) -> u32 {
        return self.id;
    }

    pub fn router(&mut self) -> &mut Router {
        &mut self.router
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token).unwrap();
        // shutdown only (there is no close), the socket will be closed on drop
        if let Err(_) = self.stream.shutdown(Shutdown::Both) {
            warn!(target: TAG, "Cannot shutdown client socket");
        }
        self.router.clear(selector);
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if self.must_send_id() {
            match self.send_id() {
                Ok(_) => {
                    if self.pending_id_bytes == 0 {
                        debug!(target:TAG, "Client id #{} sent to client", self.id);
                    }
                }
                Err(_) => {
                    error!(target: TAG, "Cannot write client id #{}", self.id);
                    self.close(selector);
                }
            }
        } else {
            match self.write() {
                Ok(_) => self.process_pending(),
                Err(_) => {
                    error!(target: TAG, "Cannot write");
                    self.close(selector);
                }
            }
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(true) => self.push_to_network(selector),
            Ok(false) => {
                debug!(target: TAG, "EOF reached");
                self.close(selector);
            }
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    pub fn send_to_client(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) -> io::Result<()> {
        self.send_raw_to_client(selector, ipv4_packet.raw())
    }

    pub fn send_raw_to_client(&mut self, selector: &mut Selector, raw: &[u8]) -> io::Result<()> {
        if raw.len() as usize <= self.network_to_client.remaining() {
            self.network_to_client.read_from(raw)?;
            self.update_interests(selector);
            Ok(())
        } else {
            warn!(target: TAG, "Client buffer full");
            Err(io::Error::new(io::ErrorKind::WouldBlock, "Client buffer full"))
        }
    }

    fn send_id(&mut self) -> io::Result<()> {
        assert!(self.must_send_id());
        let raw_id = binary::to_byte_array(self.id);
        let w = self.stream.write(&raw_id[4 - self.pending_id_bytes..])?;
        self.pending_id_bytes -= w;
        Ok(())
    }

    fn update_interests(&mut self, selector: &mut Selector) {
        let ready = if self.network_to_client.is_empty() {
            Ready::readable()
        } else {
            Ready::readable() | Ready::writable()
        };
        selector.reregister(&self.stream, self.token, ready, PollOpt::level()).expect("Cannot register on poll");
    }

    fn read(&mut self) -> io::Result<(bool)> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn write(&mut self) -> io::Result<()> {
        self.network_to_client.write_to(&mut self.stream)?;
        Ok(())
    }

    fn push_to_network(&mut self, selector: &mut Selector) {
        while self.push_one_packet_to_network(selector) {
            self.client_to_network.next();
        }
    }

    fn push_one_packet_to_network(&mut self, selector: &mut Selector) -> bool {
        match self.client_to_network.as_ipv4_packet() {
            Some(ref packet) => {
                self.router.send_to_network(selector, packet);
                true
            }
            None => false
        }
    }

    fn process_pending(&mut self) {
        // TODO
    }

    pub fn clean_expired_connections(&mut self, selector: &mut Selector) {
        self.router.clean_expired_connections(selector);
    }

    fn must_send_id(&self) -> bool{
        self.pending_id_bytes > 0
    }
}

impl EventHandler for Client {
    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}
<|endoftext|>


<commit_before>use game::{Game, View, ViewAction};
use game::data::Rectangle;
use game::gfx::{CopySprite, Sprite};
use views::background::Background;
use data::load_character;
use sdl2::pixels::Color;
use sdl2::mixer::{Chunk};
use conv::prelude::*;
use std::path::Path;

mod background;

const PLAYER_SPEED: f64 = 170.0;
const ZOOM_SPEED: f32 = 0.01;
const CHARACTER_W: f64 = 56.0;
const CHARACTER_H: f64 = 43.0;

const TERRAIN_W: f64 = 100.0;
const TERRAIN_H: f64 = 50.0;

const TILES_W: usize = 32;
const TILES_H: usize = 20;

const FIRE_SPRITE_START_INDEX: usize = 211;

#[derive(Clone, Copy)]
enum CharacterFrame {
  Right = 0,
  UpRight = 1,
  Up = 2,
  UpLeft = 3,
  Left = 4,
  DownLeft = 5,
  Down = 6,
  DownRight = 7,
}

#[derive(Clone, Copy)]
enum TerrainFrame {
  Sand = 0,
  Grass = 1,
}

struct Character {
  rect: Rectangle,
  sprites: Vec<Sprite>,
  current: CharacterFrame,
  heading: CharacterFrame,
  move_anim_index: u32,
  fire_anim_index: u32
}

struct TerrainTile {
  rect: Rectangle,
  terrain_sprites: Vec<Sprite>,
  current: TerrainFrame,
}

pub struct GameView {
  player: Character,
  tiles: Vec<TerrainTile>,
  background: Background,
  pistol: Chunk,
}

impl GameView {
  pub fn new(game: &mut Game) -> GameView {
    let spritesheet = Sprite::load(&mut game.renderer, "assets/character.png").unwrap();
    let terrain_spritesheet = Sprite::load(&mut game.renderer, "assets/terrain.png").unwrap();
    let pistol_audio = Chunk::from_file(Path::new("assets/audio/pistol.ogg")).unwrap();
    let character_datapoints = load_character();
    let mut sprites = Vec::with_capacity(512);
    let mut terrain_sprites = Vec::with_capacity(TILES_W);
    let mut tiles = Vec::with_capacity(TILES_W * TILES_H * 2);

    for x in 0..3 {
      terrain_sprites.push(terrain_spritesheet.region(Rectangle {
        w: TERRAIN_W,
        h: TERRAIN_H,
        x: TERRAIN_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..(FIRE_SPRITE_START_INDEX - 1) {
      sprites.push(spritesheet.region(character_datapoints[x]).unwrap());
    }

    for x in FIRE_SPRITE_START_INDEX..255 {
      sprites.push(spritesheet.region(character_datapoints[x]).unwrap());
    }

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let x2: f64 = 100.0 * 1.5 as f64;
        let y2: f64 = 50.0 * 1.5 as f64;
        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * x as f64,
            y: 50.0 * y as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Grass,
        });

        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * f64::value_from((x + 1)).unwrap() - x2 as f64,
            y: 50.0 * f64::value_from((y + 1)).unwrap() - y2 as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Sand,
        });
      }
    }

    GameView {
      player: Character {
        rect: Rectangle {
          x: 64.0,
          y: 64.0,
          w: CHARACTER_W,
          h: CHARACTER_H,
        },
        sprites: sprites.clone(),
        current: CharacterFrame::Down,
        heading: CharacterFrame::Down,
        move_anim_index: 0,
        fire_anim_index: 0
      },

      tiles: tiles,

      pistol: pistol_audio,

      background: Background {
        pos: 0.0,
        sprite: Sprite::load(&mut game.renderer, "assets/background.png").unwrap(),
      },
    }
  }
}

impl View for GameView {
  fn render(&mut self, game: &mut Game, elapsed: f64) -> ViewAction {
    if game.events.now.quit || game.events.now.key_escape == Some(true) {
      return ViewAction::Quit;
    }

    let diagonal = (game.events.key_up ^ game.events.key_down) && (game.events.key_left ^ game.events.key_right);
    let moved = if diagonal { 1.0 / 2.0f64.sqrt() } else { 1.0 } * PLAYER_SPEED * elapsed;
    let dx = match (game.events.key_left, game.events.key_right) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    let dy = match (game.events.key_up, game.events.key_down) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    self.player.rect.x += dx * 1.5;
    self.player.rect.y += dy * 0.75;

    let movable_region = Rectangle {
      x: 0.0,
      y: 0.0,
      w: game.output_size().0,
      h: game.output_size().1,
    };

    self.player.rect = self.player.rect.move_inside(movable_region).unwrap();
    self.player.current =
    if dx == 0.0 && dy < 0.0       { CharacterFrame::Up }
    else if dx > 0.0 && dy < 0.0   { CharacterFrame::UpRight }
    else if dx < 0.0 && dy < 0.0   { CharacterFrame::UpLeft }
    else if dx == 0.0 && dy == 0.0 { self.player.heading }
    else if dx > 0.0 && dy == 0.0  { CharacterFrame::Right }
    else if dx < 0.0 && dy == 0.0  { CharacterFrame::Left }
    else if dx == 0.0 && dy > 0.0  { CharacterFrame::Down }
    else if dx > 0.0 && dy > 0.0   { CharacterFrame::DownRight }
    else if dx < 0.0 && dy > 0.0   { CharacterFrame::DownLeft }
    else { unreachable!() };

    self.player.heading = self.player.current;

    game.renderer.set_draw_color(Color::RGBA(120, 120, 120, 0));
    self.background.render(&mut game.renderer);
    game.renderer.clear();

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let index = x * TILES_H + y;
        game.renderer.copy_sprite(&self.tiles[index].terrain_sprites[self.tiles[index].current as usize], self.tiles[index].rect);
      }
    }

    game.renderer.set_draw_color(Color::RGBA(119, 119, 119, 0));
    match game.events.mouse_click {
      Some(_) => {
        let index = 211 + self.player.current as usize * 5 + self.player.fire_anim_index as usize;
        game.renderer.copy_sprite(&self.player.sprites[index], self.player.rect);
        self.player.fire_anim_index =
          if dx == 0.0 && dy == 0.0 { 0u32 } else if self.player.fire_anim_index < 4u32 { self.player.fire_anim_index + 1u32 } else { 0u32 };
        if self.player.fire_anim_index == 0 {
          game.play_sound(&self.pistol);
        }
      },
      None => {
        let index = self.player.current as usize * 28 + self.player.move_anim_index as usize;
        game.renderer.copy_sprite(&self.player.sprites[index], self.player.rect);
        self.player.move_anim_index =
          if dx == 0.0 && dy == 0.0 { 0u32 } else if self.player.move_anim_index < 13u32 { self.player.move_anim_index + 1u32 } else { 0u32 };
      },
    };

    let scale = game.renderer.scale();
    if game.events.zoom_in == true && scale.0 <= 2.0 && scale.1 <= 2.0 {
      let _ = game.renderer.set_scale(scale.0 + ZOOM_SPEED, scale.1 + ZOOM_SPEED);
    } else if game.events.zoom_out == true && scale.0 > 0.85 && scale.1 > 0.85 {
      let _ = game.renderer.set_scale(scale.0 - ZOOM_SPEED, scale.1 - ZOOM_SPEED);
    }

    ViewAction::None
  }
}
<commit_msg>Remove background from gameview<commit_after>use game::{Game, View, ViewAction};
use game::data::Rectangle;
use game::gfx::{CopySprite, Sprite};
use views::background::Background;
use data::load_character;
use sdl2::pixels::Color;
use sdl2::mixer::{Chunk};
use conv::prelude::*;
use std::path::Path;

mod background;

const PLAYER_SPEED: f64 = 170.0;
const ZOOM_SPEED: f32 = 0.01;
const CHARACTER_W: f64 = 56.0;
const CHARACTER_H: f64 = 43.0;

const TERRAIN_W: f64 = 100.0;
const TERRAIN_H: f64 = 50.0;

const TILES_W: usize = 32;
const TILES_H: usize = 20;

const FIRE_SPRITE_START_INDEX: usize = 211;

#[derive(Clone, Copy)]
enum CharacterFrame {
  Right = 0,
  UpRight = 1,
  Up = 2,
  UpLeft = 3,
  Left = 4,
  DownLeft = 5,
  Down = 6,
  DownRight = 7,
}

#[derive(Clone, Copy)]
enum TerrainFrame {
  Sand = 0,
  Grass = 1,
}

struct Character {
  rect: Rectangle,
  sprites: Vec<Sprite>,
  current: CharacterFrame,
  heading: CharacterFrame,
  move_anim_index: u32,
  fire_anim_index: u32
}

struct TerrainTile {
  rect: Rectangle,
  terrain_sprites: Vec<Sprite>,
  current: TerrainFrame,
}

pub struct GameView {
  player: Character,
  tiles: Vec<TerrainTile>,
  pistol: Chunk,
}

impl GameView {
  pub fn new(game: &mut Game) -> GameView {
    let spritesheet = Sprite::load(&mut game.renderer, "assets/character.png").unwrap();
    let terrain_spritesheet = Sprite::load(&mut game.renderer, "assets/terrain.png").unwrap();
    let pistol_audio = Chunk::from_file(Path::new("assets/audio/pistol.ogg")).unwrap();
    let character_datapoints = load_character();
    let mut sprites = Vec::with_capacity(512);
    let mut terrain_sprites = Vec::with_capacity(TILES_W);
    let mut tiles = Vec::with_capacity(TILES_W * TILES_H * 2);

    for x in 0..3 {
      terrain_sprites.push(terrain_spritesheet.region(Rectangle {
        w: TERRAIN_W,
        h: TERRAIN_H,
        x: TERRAIN_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..(FIRE_SPRITE_START_INDEX - 1) {
      sprites.push(spritesheet.region(character_datapoints[x]).unwrap());
    }

    for x in FIRE_SPRITE_START_INDEX..255 {
      sprites.push(spritesheet.region(character_datapoints[x]).unwrap());
    }

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let x2: f64 = 100.0 * 1.5 as f64;
        let y2: f64 = 50.0 * 1.5 as f64;
        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * x as f64,
            y: 50.0 * y as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Grass,
        });

        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * f64::value_from((x + 1)).unwrap() - x2 as f64,
            y: 50.0 * f64::value_from((y + 1)).unwrap() - y2 as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Sand,
        });
      }
    }

    GameView {
      player: Character {
        rect: Rectangle {
          x: 64.0,
          y: 64.0,
          w: CHARACTER_W,
          h: CHARACTER_H,
        },
        sprites: sprites.clone(),
        current: CharacterFrame::Down,
        heading: CharacterFrame::Down,
        move_anim_index: 0,
        fire_anim_index: 0
      },

      tiles: tiles,

      pistol: pistol_audio
    }
  }
}

impl View for GameView {
  fn render(&mut self, game: &mut Game, elapsed: f64) -> ViewAction {
    if game.events.now.quit || game.events.now.key_escape == Some(true) {
      return ViewAction::Quit;
    }

    let diagonal = (game.events.key_up ^ game.events.key_down) && (game.events.key_left ^ game.events.key_right);
    let moved = if diagonal { 1.0 / 2.0f64.sqrt() } else { 1.0 } * PLAYER_SPEED * elapsed;
    let dx = match (game.events.key_left, game.events.key_right) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    let dy = match (game.events.key_up, game.events.key_down) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    self.player.rect.x += dx * 1.5;
    self.player.rect.y += dy * 0.75;

    let movable_region = Rectangle {
      x: 0.0,
      y: 0.0,
      w: game.output_size().0,
      h: game.output_size().1,
    };

    self.player.rect = self.player.rect.move_inside(movable_region).unwrap();
    self.player.current =
    if dx == 0.0 && dy < 0.0       { CharacterFrame::Up }
    else if dx > 0.0 && dy < 0.0   { CharacterFrame::UpRight }
    else if dx < 0.0 && dy < 0.0   { CharacterFrame::UpLeft }
    else if dx == 0.0 && dy == 0.0 { self.player.heading }
    else if dx > 0.0 && dy == 0.0  { CharacterFrame::Right }
    else if dx < 0.0 && dy == 0.0  { CharacterFrame::Left }
    else if dx == 0.0 && dy > 0.0  { CharacterFrame::Down }
    else if dx > 0.0 && dy > 0.0   { CharacterFrame::DownRight }
    else if dx < 0.0 && dy > 0.0   { CharacterFrame::DownLeft }
    else { unreachable!() };

    self.player.heading = self.player.current;

    game.renderer.set_draw_color(Color::RGBA(120, 120, 120, 0));
    game.renderer.clear();

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let index = x * TILES_H + y;
        game.renderer.copy_sprite(&self.tiles[index].terrain_sprites[self.tiles[index].current as usize], self.tiles[index].rect);
      }
    }

    game.renderer.set_draw_color(Color::RGBA(119, 119, 119, 0));
    match game.events.mouse_click {
      Some(_) => {
        let index = 211 + self.player.current as usize * 5 + self.player.fire_anim_index as usize;
        game.renderer.copy_sprite(&self.player.sprites[index], self.player.rect);
        self.player.fire_anim_index =
          if dx == 0.0 && dy == 0.0 { 0u32 } else if self.player.fire_anim_index < 4u32 { self.player.fire_anim_index + 1u32 } else { 0u32 };
        if self.player.fire_anim_index == 0 {
          game.play_sound(&self.pistol);
        }
      },
      None => {
        let index = self.player.current as usize * 28 + self.player.move_anim_index as usize;
        game.renderer.copy_sprite(&self.player.sprites[index], self.player.rect);
        self.player.move_anim_index =
          if dx == 0.0 && dy == 0.0 { 0u32 } else if self.player.move_anim_index < 13u32 { self.player.move_anim_index + 1u32 } else { 0u32 };
      },
    };

    let scale = game.renderer.scale();
    if game.events.zoom_in == true && scale.0 <= 2.0 && scale.1 <= 2.0 {
      let _ = game.renderer.set_scale(scale.0 + ZOOM_SPEED, scale.1 + ZOOM_SPEED);
    } else if game.events.zoom_out == true && scale.0 > 0.85 && scale.1 > 0.85 {
      let _ = game.renderer.set_scale(scale.0 - ZOOM_SPEED, scale.1 - ZOOM_SPEED);
    }

    ViewAction::None
  }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    fn run<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    fn create_entity<T>(&mut self, component: T) where T: Debug + Send + Sync + Clone + 'static {
        let e = self.next_entity();
        self.entities.push(e);

        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);

        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));
    }

    fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize);
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<commit_msg>Generalized run() to run2() though there's some inconvenient allocation involved.<commit_after>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    fn run1<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    fn run2<F, C1, C2>(&mut self, f: F)
        where F: Fn(&C1, &C2, &[E], &EventSender<E>) -> (C1, C2) + Sync,
              C1: Debug + Send + Sync + 'static,
              C2: Debug + Send + Sync + 'static
    {
        let current1 = self.current_components.get::<VecResource<C1>>().expect("Tried to run a system on an unknown component type");
        let current2 = self.current_components.get::<VecResource<C2>>().expect("Tried to run a system on an unknown component type");
        let c1: &[C1] = &current1.data;
        let c2: &[C2] = &current2.data;

        let next_events = &self.next_events;
        // BUGGO: Aieee, my perfect non-allocating system is now poisoned!
        let mut next_hax: Vec<(C1, C2)> = Vec::with_capacity(c1.len());
        c1.par_iter()
            .zip(c2)
            .zip(&self.current_events.channels)
            .map(|((comp1, comp2), e)| {
                let event_queue = e.read().expect("Aiee event queue is poisoned in World::run(); did a system crash?");
                f(comp1, comp2, &event_queue[..], next_events)
            })
            .collect_into(&mut next_hax);
        //.enumerate()
        // This doesn't seem to work 'cause it gets pesky about the closure altering self,
        // for some reason.  Hmm.
        //.for_each(|(i, (comp1, comp2))| {
            //    next1.data[i] = comp1;
            //});
        //.collect_into(v);
        let (r1, r2): (Vec<C1>, Vec<C2>) = next_hax.into_iter().unzip();
        {
            let next1 = self.next_components.get_mut::<VecResource<C1>>().expect("current_components exists but next_components does not, this should never happen!");
            let n1 = &mut next1.data;
            *n1 = r1;
        }
        {
            let next2 = self.next_components.get_mut::<VecResource<C2>>().expect("current_components exists but next_components does not, this should never happen!");
            let n2 = &mut next2.data;
            *n2 = r2;
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    fn create_entity<T>(&mut self, component: T) where T: Debug + Send + Sync + Clone + 'static {
        let e = self.next_entity();
        self.entities.push(e);

        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);

        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));
    }

    fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize);
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run1(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<|endoftext|>


<commit_before>use gemlab::geometry::is_point_inside_triangle;
use gemlab::util::GridSearchCell;
use gemlab::StrError;
use plotpy::{Canvas, Plot, PolyCode, Text};

fn main() -> Result<(), StrError> {
    // [num_triangle][nnode=3][ndim=2]
    #[rustfmt::skip]
    const TRIS: [[[f64; 2]; 3]; 8] = [
        [[0.0, 0.0],  [1.0, 0.0],  [0.5, 0.85]],
        [[1.0, 0.0],  [2.0, 0.0],  [1.5, 0.85]],
        [[0.5, 0.85], [1.0, 0.0],  [1.5, 0.85]],
        [[1.5, 0.85], [2.0, 0.0],  [2.5, 0.85]],
        [[0.5, 0.85], [1.5, 0.85], [1.0, 1.7]],
        [[1.5, 0.85], [2.5, 0.85], [2.0, 1.7]],
        [[1.0, 1.7],  [1.5, 0.85], [2.0, 1.7]],
        [[2.0, 1.7],  [2.5, 0.85], [3.0, 1.7]],
    ];

    // closure that returns the number of nodes of a cell `t`
    let get_nnode = |_t| Ok(3);

    // closure that returns the coordinates of point `m` of cell `t`
    let get_x = |t: usize, m: usize| Ok(&TRIS[t][m][..]);

    // allocate grid search tool
    let ndim = 2;
    let grid = GridSearchCell::new(ndim, TRIS.len(), get_nnode, get_x, None, None)?;

    // print information
    println!("{}", grid);

    // closure that tells whether the point is in the cell or not
    let is_in_cell = |t: usize, x: &[f64]| Ok(is_point_inside_triangle(&TRIS[t][0], &TRIS[t][1], &TRIS[t][2], x));

    // find triangle given coords
    let x = &[0.5, 0.5];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?}", id);

    // find with another point
    let x = &[0.4, 0.2];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?}", id);

    // draw triangles and grid
    let mut plot = Plot::new();
    grid.draw(&mut plot, false)?;
    draw_triangles(&mut plot, &TRIS);
    plot.set_equal_axes(true)
        .set_figure_size_points(600.0, 600.0)
        .grid_and_labels("x", "y")
        .save("/tmp/gemlab/example_grid_search_triangles.svg")?;
    Ok(())
}

fn draw_triangles(plot: &mut Plot, triangles: &[[[f64; 2]; 3]]) {
    let mut ids = Text::new();
    ids.set_color("#cd0000")
        .set_bbox(true)
        .set_bbox_style("circle,pad=0.3")
        .set_bbox_edgecolor("None")
        .set_bbox_facecolor("white")
        .set_bbox_alpha(0.8);
    let mut canvas = Canvas::new();
    let (mut xc, mut yc) = (0.0, 0.0);
    canvas.set_face_color("#fefddc").set_edge_color("#fcb827");
    for t in 0..triangles.len() {
        canvas.polycurve_begin();
        for m in 0..3 {
            let code = if m == 0 {
                xc = triangles[t][m][0];
                yc = triangles[t][m][1];
                PolyCode::MoveTo
            } else {
                xc += triangles[t][m][0];
                yc += triangles[t][m][1];
                PolyCode::LineTo
            };
            canvas.polycurve_add(&triangles[t][m][0], &triangles[t][m][1], code);
        }
        canvas.polycurve_end(true);
        xc /= 3.0;
        yc /= 3.0;
        ids.draw(xc, yc, format!("{}", t).as_str());
    }
    plot.add(&canvas).add(&ids);
}
<commit_msg>Improve example<commit_after>use gemlab::geometry::is_point_inside_triangle;
use gemlab::util::GridSearchCell;
use gemlab::StrError;
use plotpy::{Canvas, Plot, PolyCode, Text};

fn brute_force_search(triangles: &[[[f64; 2]; 3]], x: &[f64]) -> Option<usize> {
    for i in 0..triangles.len() {
        let t = &triangles[i];
        if is_point_inside_triangle(&t[0], &t[1], &t[2], x) {
            return Some(i);
        }
    }
    None
}

fn main() -> Result<(), StrError> {
    // [num_triangle][nnode=3][ndim=2]
    #[rustfmt::skip]
    const TRIS: [[[f64; 2]; 3]; 8] = [
        [[0.0, 0.0],  [1.0, 0.0],  [0.5, 0.85]],
        [[1.0, 0.0],  [2.0, 0.0],  [1.5, 0.85]],
        [[0.5, 0.85], [1.0, 0.0],  [1.5, 0.85]],
        [[1.5, 0.85], [2.0, 0.0],  [2.5, 0.85]],
        [[0.5, 0.85], [1.5, 0.85], [1.0, 1.7]],
        [[1.5, 0.85], [2.5, 0.85], [2.0, 1.7]],
        [[1.0, 1.7],  [1.5, 0.85], [2.0, 1.7]],
        [[2.0, 1.7],  [2.5, 0.85], [3.0, 1.7]],
    ];

    // closure that returns the number of nodes of a cell `t`
    let get_nnode = |_t| Ok(3);

    // closure that returns the coordinates of point `m` of cell `t`
    let get_x = |t: usize, m: usize| Ok(&TRIS[t][m][..]);

    // allocate grid search tool
    let ndim = 2;
    let grid = GridSearchCell::new(ndim, TRIS.len(), get_nnode, get_x, None, None)?;

    // print information
    println!("{}", grid);

    // closure that tells whether the point is in the cell or not
    let is_in_cell = |t: usize, x: &[f64]| Ok(is_point_inside_triangle(&TRIS[t][0], &TRIS[t][1], &TRIS[t][2], x));

    // find triangle given coords
    let x = &[1.0, 0.5];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&TRIS, x));
    assert_eq!(id, Some(2));

    // find with another triangle
    let x = &[2.9, 1.6];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&TRIS, x));
    assert_eq!(id, Some(7));

    // maybe find with another triangle
    let x = &[3.0, 1.0];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&TRIS, x));
    assert_eq!(id, None);

    // draw triangles and grid
    let mut plot = Plot::new();
    grid.draw(&mut plot, false)?;
    draw_triangles(&mut plot, &TRIS);
    plot.set_equal_axes(true)
        .set_figure_size_points(600.0, 600.0)
        .grid_and_labels("x", "y")
        .save("/tmp/gemlab/example_grid_search_triangles.svg")?;
    Ok(())
}

fn draw_triangles(plot: &mut Plot, triangles: &[[[f64; 2]; 3]]) {
    let mut ids = Text::new();
    ids.set_color("#cd0000")
        .set_bbox(true)
        .set_bbox_style("circle,pad=0.3")
        .set_bbox_edgecolor("None")
        .set_bbox_facecolor("white")
        .set_bbox_alpha(0.8);
    let mut canvas = Canvas::new();
    let (mut xc, mut yc) = (0.0, 0.0);
    canvas.set_face_color("#fefddc").set_edge_color("#fcb827");
    for t in 0..triangles.len() {
        canvas.polycurve_begin();
        for m in 0..3 {
            let code = if m == 0 {
                xc = triangles[t][m][0];
                yc = triangles[t][m][1];
                PolyCode::MoveTo
            } else {
                xc += triangles[t][m][0];
                yc += triangles[t][m][1];
                PolyCode::LineTo
            };
            canvas.polycurve_add(&triangles[t][m][0], &triangles[t][m][1], code);
        }
        canvas.polycurve_end(true);
        xc /= 3.0;
        yc /= 3.0;
        ids.draw(xc, yc, format!("{}", t).as_str());
    }
    plot.add(&canvas).add(&ids);
}
<|endoftext|>


<commit_before>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}

mpl From<Bar> for Foo {

+    fn from(child: Bar) -> Foo {

+        Foo(child.0)

+    }

+}

impl std::convert::TryFrom<Foo> for Bar {
    type Error = String;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Foo", "Bar"
            ))
        }
    }
}
impl IBar for Bar {}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}

impl std::convert::TryFrom<Bar> for Baz {
    type Error = String;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Bar", "Baz"
            ))
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = String;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Foo", "Baz"
            ))
        }
    }
}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<commit_msg>Fix spacing issue<commit_after>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}

impl From<Bar> for Foo {
    fn from(child: Bar) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Bar {
    type Error = String;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Foo", "Bar"
            ))
        }
    }
}
impl IBar for Bar {}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}

impl std::convert::TryFrom<Bar> for Baz {
    type Error = String;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Bar", "Baz"
            ))
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = String;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err(format!(
                "This {} is not an cannot be downcasted to {}",
                "Foo", "Baz"
            ))
        }
    }
}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<|endoftext|>