<commit_before>//! NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
//! See "Kohonen neural networks for optimal colour quantization"
//! in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
//! for a discussion of the algorithm.
//! See also  http://www.acm.org/~dekker/NEUQUANT.HTML

/* NeuQuant Neural-Net Quantization Algorithm
 * ------------------------------------------
 *
 * Copyright (c) 1994 Anthony Dekker
 *
 * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
 * See "Kohonen neural networks for optimal colour quantization"
 * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
 * for a discussion of the algorithm.
 * See also  http://www.acm.org/~dekker/NEUQUANT.HTML
 *
 * Any party obtaining a copy of these files from the author, directly or
 * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
 * world-wide, paid up, royalty-free, nonexclusive right and license to deal
 * in this software and documentation files (the "Software"), including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons who receive
 * copies from any such party to do so, with the only requirement being
 * that this copyright notice remain intact.
 *
 *
 * Incorporated bugfixes and alpha channel handling from pngnq
 * http://pngnq.sourceforge.net
 *
 */

use std::num::Float;
use std::cmp::{
    max,
    min
};
use super::utils::clamp;

const CHANNELS: usize = 4;

const RADIUS_DEC: i32 = 30; // factor of 1/30 each cycle

const ALPHA_BIASSHIFT: i32 = 10;            // alpha starts at 1
const INIT_ALPHA: i32 = 1 << ALPHA_BIASSHIFT; // biased by 10 bits

const GAMMA: f64 = 1024.0;
const BETA: f64 = 1.0 / GAMMA;
const BETAGAMMA: f64 = BETA * GAMMA;

// four primes near 500 - assume no image has a length so large
// that it is divisible by all four primes
const PRIMES: [usize; 4] = [499, 491, 478, 503];

#[derive(Copy)]
struct Quad<T> {
    r: T,
    g: T,
    b: T,
    a: T,
}

type Neuron = Quad<f64>;
type Color = Quad<i32>;

/// Neural network color quantizer
pub struct NeuQuant {
    network: Vec<Neuron>,
    colormap: Vec<Color>,
    netindex: Vec<usize>,
    bias: Vec<f64>, // bias and freq arrays for learning
    freq: Vec<f64>,
    samplefac: i32,
    netsize: usize,
}

impl NeuQuant {
    /// Creates a new neuronal network and trains it with the supplied data
    pub fn new(samplefac: i32, colors: usize, pixels: &[u8]) -> Self {
        let netsize = colors;
        let mut this = NeuQuant {
            network: Vec::with_capacity(netsize),
            colormap: Vec::with_capacity(netsize),
            netindex: vec![0; 256],
            bias: Vec::with_capacity(netsize),
            freq: Vec::with_capacity(netsize),
            samplefac: samplefac,
            netsize: colors
        };
        this.init(pixels);
        this
    }

    /// Initializes the neuronal network and trains it with the supplied data
    pub fn init(&mut self, pixels: &[u8]) {
        self.network.clear();
        self.colormap.clear();
        self.bias.clear();
        self.freq.clear();
        let freq = (self.netsize as f64).recip();
        for i in 0..self.netsize {
            let tmp = (i as f64) * 256.0 / (self.netsize as f64);
            // Sets alpha values at 0 for dark pixels.
            let a = if i < 16 { i as f64 * 16.0 } else { 255.0 };
            self.network.push(Neuron { r: tmp, g: tmp, b: tmp, a: a});
            self.colormap.push(Color { r: 0, g: 0, b: 0, a: 255 });
            self.freq.push(freq);
            self.bias.push(0.0);
        }
        self.learn(pixels);
        self.build_colormap();
        self.inxbuild();
    }

    /// Maps the pixel in-place to the best-matching color in the color map
    #[inline(always)]
    pub fn map_pixel(&self, pixel: &mut [u8]) {
        match pixel {
            [r, g, b, a] => {
                let i = self.inxsearch(b, g, r, a);
                pixel[0] = self.colormap[i].r as u8;
                pixel[1] = self.colormap[i].g as u8;
                pixel[2] = self.colormap[i].b as u8;
                pixel[3] = self.colormap[i].a as u8;
            }
            _ => panic!()
        }
    }

    /// Finds the best-matching index in the color map for `pixel`
    #[inline(always)]
    pub fn index_of(&self, pixel: &[u8]) -> usize {
        match pixel {
            [r, g, b, a] => {
                self.inxsearch(b, g, r, a)
            }
            _ => panic!()
        }
    }

    /// Move neuron i towards biased (a,b,g,r) by factor alpha
    fn altersingle(&mut self, alpha: f64, i: i32, quad: Quad<f64>) {
        let n = &mut self.network[i as usize];
        n.b -= alpha * (n.b - quad.b);
        n.g -= alpha * (n.g - quad.g);
        n.r -= alpha * (n.r - quad.r);
        n.a -= alpha * (n.a - quad.a);
    }

    /// Move neuron adjacent neurons towards biased (a,b,g,r) by factor alpha
    fn alterneigh(&mut self, alpha: f64, rad: i32, i: i32, quad: Quad<f64>) {
        let lo = max(i - rad, 0);
        let hi = min(i + rad, self.netsize as i32);
        let mut j = i + 1;
        let mut k = i - 1;
        let mut q = 0;

        while (j < hi) || (k > lo) {
            let rad_sq = rad as f64 * rad as f64;
            let alpha = (alpha * (rad_sq - q as f64 * q as f64)) / rad_sq;
            q += 1;
            if j < hi {
                let p = &mut self.network[j as usize];
                p.b -= alpha * (p.b - quad.b);
                p.g -= alpha * (p.g - quad.g);
                p.r -= alpha * (p.r - quad.r);
                p.a -= alpha * (p.a - quad.a);
                j += 1;
            }
            if k > lo {
                let p = &mut self.network[k as usize];
                p.b -= alpha * (p.b - quad.b);
                p.g -= alpha * (p.g - quad.g);
                p.r -= alpha * (p.r - quad.r);
                p.a -= alpha * (p.a - quad.a);
                k -= 1;
            }
        }
    }

    /// Search for biased BGR values
    /// finds closest neuron (min dist) and updates freq
    /// finds best neuron (min dist-bias) and returns position
    /// for frequently chosen neurons, freq[i] is high and bias[i] is negative
    /// bias[i] = gamma*((1/self.netsize)-freq[i])
    fn contest (&mut self, b: f64, g: f64, r: f64, a: f64) -> i32 {
        let mut bestd = Float::max_value();
        let mut bestbiasd: f64 = bestd;
        let mut bestpos = -1;
        let mut bestbiaspos: i32 = bestpos;

        for i in 0..self.netsize {
            let bestbiasd_biased = bestbiasd + self.bias[i];
            let mut dist;
            let n = &self.network[i];
            dist  = (n.b - b).abs();
            dist += (n.r - r).abs();
            if dist < bestd || dist < bestbiasd_biased {
                dist += (n.g - g).abs();
                dist += (n.a - a).abs();
                if dist < bestd {bestd=dist; bestpos=i as i32;}
                let biasdist = dist - self.bias [i];
                if biasdist < bestbiasd {bestbiasd=biasdist; bestbiaspos=i as i32;}
            }
            self.freq[i] -= BETA * self.freq[i];
            self.bias[i] += BETAGAMMA * self.freq[i];
        }
        self.freq[bestpos as usize] += BETA;
        self.bias[bestpos as usize] -= BETAGAMMA;
        return bestbiaspos;
    }

    /// Main learning loop
    /// Note: the number of learning cycles is crucial and the parameters are not
    /// optimized for net sizes < 26 or > 256. 1064 colors seems to work fine
    fn learn(&mut self, pixels: &[u8]) {
        let initrad: i32 = self.netsize as i32/8;   // for 256 cols, radius starts at 32
        let radiusbiasshift: i32 = 6;
        let radiusbias: i32 = 1 << radiusbiasshift;
        let init_bias_radius: i32 = initrad*radiusbias;
        let mut bias_radius = init_bias_radius;
        let alphadec = 30 + ((self.samplefac-1)/3);
        let lengthcount = pixels.len() / CHANNELS;
        let samplepixels = lengthcount / self.samplefac as usize;
        // learning cycles
        let n_cycles = match self.netsize >> 1 { n if n <= 100 => 100, n => n};
        let delta = match samplepixels / n_cycles { 0 => 1, n => n };
        let mut alpha = INIT_ALPHA;

        let mut rad = bias_radius >> radiusbiasshift;
        if rad <= 1 {rad = 0};

        let mut pos = 0;
        let step = *PRIMES.iter()
            .find(|&&prime| lengthcount % prime != 0)
            .unwrap_or(&PRIMES[3]);

        let mut i = 0;
        while i < samplepixels {
            let (r, g, b, a) = {
                let p = &pixels[CHANNELS * pos..][..CHANNELS];
                (p[0] as f64, p[1] as f64, p[2] as f64, p[3] as f64)
            };

            let j =  self.contest (b, g, r, a);

            let alpha_ = (1.0 * alpha as f64) / INIT_ALPHA as f64;
            self.altersingle(alpha_, j, Quad { b: b, g: g, r: r, a: a });
            if rad > 0 {
                self.alterneigh(alpha_, rad, j, Quad { b: b, g: g, r: r, a: a })
            };

            pos += step;
            while pos >= lengthcount { pos -= lengthcount };

            i += 1;
            if i%delta == 0 {
                alpha -= alpha / alphadec;
                bias_radius -= bias_radius / RADIUS_DEC;
                rad = bias_radius >> radiusbiasshift;
                if rad <= 1 {rad = 0};
            }
        }
    }

    /// initializes the color map
    fn build_colormap(&mut self) {
        for i in 0usize..self.netsize {
            self.colormap[i].b = clamp((0.5 + self.network[i].b) as i32, 0, 255);
            self.colormap[i].g = clamp((0.5 + self.network[i].g) as i32, 0, 255);
            self.colormap[i].r = clamp((0.5 + self.network[i].r) as i32, 0, 255);
            self.colormap[i].a = clamp((0.5 + self.network[i].a) as i32, 0, 255);
        }
    }

    /// Insertion sort of network and building of netindex[0..255]
    fn inxbuild(&mut self) {
        let mut previouscol = 0;
        let mut startpos = 0;

        for i in 0..self.netsize {
            let mut p = self.colormap[i];
            let mut q;
            let mut smallpos = i;
            let mut smallval = p.g as usize;            // index on g
            // find smallest in i..netsize-1
            for j in (i + 1)..self.netsize {
                q = self.colormap[j];
                if (q.g as usize) < smallval {      // index on g
                    smallpos = j;
                    smallval = q.g as usize;    // index on g
                }
            }
            q = self.colormap[smallpos];
            // swap p (i) and q (smallpos) entries
            if i != smallpos {
                let mut j;
                j = q;   q = p;   p = j;
                self.colormap[i] = p;
                self.colormap[smallpos] = q;
            }
            // smallval entry is now in position i
            if smallval != previouscol {
                self.netindex[previouscol] = (startpos + i)>>1;
                for j in (previouscol + 1)..smallval {
                    self.netindex[j] = i
                }
                previouscol = smallval;
                startpos = i;
            }
        }
        let max_netpos = self.netsize - 1;
        self.netindex[previouscol] = (startpos + max_netpos)>>1;
        for j in (previouscol + 1)..256 { self.netindex[j] = max_netpos }; // really 256
    }

    /// Search for best matching color
    fn inxsearch(&self, b: u8, g: u8, r: u8, a: u8) -> usize {
        let mut bestd = 1 << 30; // ~ 1_000_000
        let mut best = 0;
        // start at netindex[g] and work outwards
        let mut i = self.netindex[g as usize];
        let mut j = if i > 0 { i - 1 } else { 0 };

        while (i < self.netsize) || (j >  0) {
            if i < self.netsize {
                let p = self.colormap[i];
                let mut e = p.g - g as i32;
                let mut dist = e*e; // inx key
                if dist >= bestd { break }
                else {
                    e = p.b - b as i32;
                    dist += e*e;
                    if dist < bestd {
                        e = p.r - r as i32;
                        dist += e*e;
                        if dist < bestd {
                            e = p.a - a as i32;
                            dist += e*e;
                            if dist < bestd { bestd = dist; best = i;}
                        }
                    }
                    i += 1;
                }
            }
            if j > 0 {
                let p = self.colormap[j];
                let mut e = p.g - g as i32;
                let mut dist = e*e; // inx key
                if dist >= bestd { break }
                else {
                    e = p.b - b as i32;
                    dist += e*e;
                    if dist < bestd {
                        e = p.r - r as i32;
                        dist += e*e;
                        if dist < bestd {
                            e = p.a - a as i32;
                            dist += e*e;
                            if dist < bestd { bestd = dist; best = j; }
                        }
                    }
                    j -= 1;
                }
            }
        }
        best
    }
}
<commit_msg>Use Float::round instead strange casting<commit_after>//! NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
//! See "Kohonen neural networks for optimal colour quantization"
//! in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
//! for a discussion of the algorithm.
//! See also  http://www.acm.org/~dekker/NEUQUANT.HTML

/* NeuQuant Neural-Net Quantization Algorithm
 * ------------------------------------------
 *
 * Copyright (c) 1994 Anthony Dekker
 *
 * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
 * See "Kohonen neural networks for optimal colour quantization"
 * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
 * for a discussion of the algorithm.
 * See also  http://www.acm.org/~dekker/NEUQUANT.HTML
 *
 * Any party obtaining a copy of these files from the author, directly or
 * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
 * world-wide, paid up, royalty-free, nonexclusive right and license to deal
 * in this software and documentation files (the "Software"), including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons who receive
 * copies from any such party to do so, with the only requirement being
 * that this copyright notice remain intact.
 *
 *
 * Incorporated bugfixes and alpha channel handling from pngnq
 * http://pngnq.sourceforge.net
 *
 */

use std::num::Float;
use std::cmp::{
    max,
    min
};
use super::utils::clamp;

const CHANNELS: usize = 4;

const RADIUS_DEC: i32 = 30; // factor of 1/30 each cycle

const ALPHA_BIASSHIFT: i32 = 10;            // alpha starts at 1
const INIT_ALPHA: i32 = 1 << ALPHA_BIASSHIFT; // biased by 10 bits

const GAMMA: f64 = 1024.0;
const BETA: f64 = 1.0 / GAMMA;
const BETAGAMMA: f64 = BETA * GAMMA;

// four primes near 500 - assume no image has a length so large
// that it is divisible by all four primes
const PRIMES: [usize; 4] = [499, 491, 478, 503];

#[derive(Copy)]
struct Quad<T> {
    r: T,
    g: T,
    b: T,
    a: T,
}

type Neuron = Quad<f64>;
type Color = Quad<i32>;

/// Neural network color quantizer
pub struct NeuQuant {
    network: Vec<Neuron>,
    colormap: Vec<Color>,
    netindex: Vec<usize>,
    bias: Vec<f64>, // bias and freq arrays for learning
    freq: Vec<f64>,
    samplefac: i32,
    netsize: usize,
}

impl NeuQuant {
    /// Creates a new neuronal network and trains it with the supplied data
    pub fn new(samplefac: i32, colors: usize, pixels: &[u8]) -> Self {
        let netsize = colors;
        let mut this = NeuQuant {
            network: Vec::with_capacity(netsize),
            colormap: Vec::with_capacity(netsize),
            netindex: vec![0; 256],
            bias: Vec::with_capacity(netsize),
            freq: Vec::with_capacity(netsize),
            samplefac: samplefac,
            netsize: colors
        };
        this.init(pixels);
        this
    }

    /// Initializes the neuronal network and trains it with the supplied data
    pub fn init(&mut self, pixels: &[u8]) {
        self.network.clear();
        self.colormap.clear();
        self.bias.clear();
        self.freq.clear();
        let freq = (self.netsize as f64).recip();
        for i in 0..self.netsize {
            let tmp = (i as f64) * 256.0 / (self.netsize as f64);
            // Sets alpha values at 0 for dark pixels.
            let a = if i < 16 { i as f64 * 16.0 } else { 255.0 };
            self.network.push(Neuron { r: tmp, g: tmp, b: tmp, a: a});
            self.colormap.push(Color { r: 0, g: 0, b: 0, a: 255 });
            self.freq.push(freq);
            self.bias.push(0.0);
        }
        self.learn(pixels);
        self.build_colormap();
        self.inxbuild();
    }

    /// Maps the pixel in-place to the best-matching color in the color map
    #[inline(always)]
    pub fn map_pixel(&self, pixel: &mut [u8]) {
        match pixel {
            [r, g, b, a] => {
                let i = self.inxsearch(b, g, r, a);
                pixel[0] = self.colormap[i].r as u8;
                pixel[1] = self.colormap[i].g as u8;
                pixel[2] = self.colormap[i].b as u8;
                pixel[3] = self.colormap[i].a as u8;
            }
            _ => panic!()
        }
    }

    /// Finds the best-matching index in the color map for `pixel`
    #[inline(always)]
    pub fn index_of(&self, pixel: &[u8]) -> usize {
        match pixel {
            [r, g, b, a] => {
                self.inxsearch(b, g, r, a)
            }
            _ => panic!()
        }
    }

    /// Move neuron i towards biased (a,b,g,r) by factor alpha
    fn altersingle(&mut self, alpha: f64, i: i32, quad: Quad<f64>) {
        let n = &mut self.network[i as usize];
        n.b -= alpha * (n.b - quad.b);
        n.g -= alpha * (n.g - quad.g);
        n.r -= alpha * (n.r - quad.r);
        n.a -= alpha * (n.a - quad.a);
    }

    /// Move neuron adjacent neurons towards biased (a,b,g,r) by factor alpha
    fn alterneigh(&mut self, alpha: f64, rad: i32, i: i32, quad: Quad<f64>) {
        let lo = max(i - rad, 0);
        let hi = min(i + rad, self.netsize as i32);
        let mut j = i + 1;
        let mut k = i - 1;
        let mut q = 0;

        while (j < hi) || (k > lo) {
            let rad_sq = rad as f64 * rad as f64;
            let alpha = (alpha * (rad_sq - q as f64 * q as f64)) / rad_sq;
            q += 1;
            if j < hi {
                let p = &mut self.network[j as usize];
                p.b -= alpha * (p.b - quad.b);
                p.g -= alpha * (p.g - quad.g);
                p.r -= alpha * (p.r - quad.r);
                p.a -= alpha * (p.a - quad.a);
                j += 1;
            }
            if k > lo {
                let p = &mut self.network[k as usize];
                p.b -= alpha * (p.b - quad.b);
                p.g -= alpha * (p.g - quad.g);
                p.r -= alpha * (p.r - quad.r);
                p.a -= alpha * (p.a - quad.a);
                k -= 1;
            }
        }
    }

    /// Search for biased BGR values
    /// finds closest neuron (min dist) and updates freq
    /// finds best neuron (min dist-bias) and returns position
    /// for frequently chosen neurons, freq[i] is high and bias[i] is negative
    /// bias[i] = gamma*((1/self.netsize)-freq[i])
    fn contest (&mut self, b: f64, g: f64, r: f64, a: f64) -> i32 {
        let mut bestd = Float::max_value();
        let mut bestbiasd: f64 = bestd;
        let mut bestpos = -1;
        let mut bestbiaspos: i32 = bestpos;

        for i in 0..self.netsize {
            let bestbiasd_biased = bestbiasd + self.bias[i];
            let mut dist;
            let n = &self.network[i];
            dist  = (n.b - b).abs();
            dist += (n.r - r).abs();
            if dist < bestd || dist < bestbiasd_biased {
                dist += (n.g - g).abs();
                dist += (n.a - a).abs();
                if dist < bestd {bestd=dist; bestpos=i as i32;}
                let biasdist = dist - self.bias [i];
                if biasdist < bestbiasd {bestbiasd=biasdist; bestbiaspos=i as i32;}
            }
            self.freq[i] -= BETA * self.freq[i];
            self.bias[i] += BETAGAMMA * self.freq[i];
        }
        self.freq[bestpos as usize] += BETA;
        self.bias[bestpos as usize] -= BETAGAMMA;
        return bestbiaspos;
    }

    /// Main learning loop
    /// Note: the number of learning cycles is crucial and the parameters are not
    /// optimized for net sizes < 26 or > 256. 1064 colors seems to work fine
    fn learn(&mut self, pixels: &[u8]) {
        let initrad: i32 = self.netsize as i32/8;   // for 256 cols, radius starts at 32
        let radiusbiasshift: i32 = 6;
        let radiusbias: i32 = 1 << radiusbiasshift;
        let init_bias_radius: i32 = initrad*radiusbias;
        let mut bias_radius = init_bias_radius;
        let alphadec = 30 + ((self.samplefac-1)/3);
        let lengthcount = pixels.len() / CHANNELS;
        let samplepixels = lengthcount / self.samplefac as usize;
        // learning cycles
        let n_cycles = match self.netsize >> 1 { n if n <= 100 => 100, n => n};
        let delta = match samplepixels / n_cycles { 0 => 1, n => n };
        let mut alpha = INIT_ALPHA;

        let mut rad = bias_radius >> radiusbiasshift;
        if rad <= 1 {rad = 0};

        let mut pos = 0;
        let step = *PRIMES.iter()
            .find(|&&prime| lengthcount % prime != 0)
            .unwrap_or(&PRIMES[3]);

        let mut i = 0;
        while i < samplepixels {
            let (r, g, b, a) = {
                let p = &pixels[CHANNELS * pos..][..CHANNELS];
                (p[0] as f64, p[1] as f64, p[2] as f64, p[3] as f64)
            };

            let j =  self.contest (b, g, r, a);

            let alpha_ = (1.0 * alpha as f64) / INIT_ALPHA as f64;
            self.altersingle(alpha_, j, Quad { b: b, g: g, r: r, a: a });
            if rad > 0 {
                self.alterneigh(alpha_, rad, j, Quad { b: b, g: g, r: r, a: a })
            };

            pos += step;
            while pos >= lengthcount { pos -= lengthcount };

            i += 1;
            if i%delta == 0 {
                alpha -= alpha / alphadec;
                bias_radius -= bias_radius / RADIUS_DEC;
                rad = bias_radius >> radiusbiasshift;
                if rad <= 1 {rad = 0};
            }
        }
    }

    /// initializes the color map
    fn build_colormap(&mut self) {
        for i in 0usize..self.netsize {
            self.colormap[i].b = clamp(self.network[i].b.round() as i32, 0, 255);
            self.colormap[i].g = clamp(self.network[i].g.round() as i32, 0, 255);
            self.colormap[i].r = clamp(self.network[i].r.round() as i32, 0, 255);
            self.colormap[i].a = clamp(self.network[i].a.round() as i32, 0, 255);
        }
    }

    /// Insertion sort of network and building of netindex[0..255]
    fn inxbuild(&mut self) {
        let mut previouscol = 0;
        let mut startpos = 0;

        for i in 0..self.netsize {
            let mut p = self.colormap[i];
            let mut q;
            let mut smallpos = i;
            let mut smallval = p.g as usize;            // index on g
            // find smallest in i..netsize-1
            for j in (i + 1)..self.netsize {
                q = self.colormap[j];
                if (q.g as usize) < smallval {      // index on g
                    smallpos = j;
                    smallval = q.g as usize;    // index on g
                }
            }
            q = self.colormap[smallpos];
            // swap p (i) and q (smallpos) entries
            if i != smallpos {
                let mut j;
                j = q;   q = p;   p = j;
                self.colormap[i] = p;
                self.colormap[smallpos] = q;
            }
            // smallval entry is now in position i
            if smallval != previouscol {
                self.netindex[previouscol] = (startpos + i)>>1;
                for j in (previouscol + 1)..smallval {
                    self.netindex[j] = i
                }
                previouscol = smallval;
                startpos = i;
            }
        }
        let max_netpos = self.netsize - 1;
        self.netindex[previouscol] = (startpos + max_netpos)>>1;
        for j in (previouscol + 1)..256 { self.netindex[j] = max_netpos }; // really 256
    }

    /// Search for best matching color
    fn inxsearch(&self, b: u8, g: u8, r: u8, a: u8) -> usize {
        let mut bestd = 1 << 30; // ~ 1_000_000
        let mut best = 0;
        // start at netindex[g] and work outwards
        let mut i = self.netindex[g as usize];
        let mut j = if i > 0 { i - 1 } else { 0 };

        while (i < self.netsize) || (j >  0) {
            if i < self.netsize {
                let p = self.colormap[i];
                let mut e = p.g - g as i32;
                let mut dist = e*e; // inx key
                if dist >= bestd { break }
                else {
                    e = p.b - b as i32;
                    dist += e*e;
                    if dist < bestd {
                        e = p.r - r as i32;
                        dist += e*e;
                        if dist < bestd {
                            e = p.a - a as i32;
                            dist += e*e;
                            if dist < bestd { bestd = dist; best = i;}
                        }
                    }
                    i += 1;
                }
            }
            if j > 0 {
                let p = self.colormap[j];
                let mut e = p.g - g as i32;
                let mut dist = e*e; // inx key
                if dist >= bestd { break }
                else {
                    e = p.b - b as i32;
                    dist += e*e;
                    if dist < bestd {
                        e = p.r - r as i32;
                        dist += e*e;
                        if dist < bestd {
                            e = p.a - a as i32;
                            dist += e*e;
                            if dist < bestd { bestd = dist; best = j; }
                        }
                    }
                    j -= 1;
                }
            }
        }
        best
    }
}
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>empty message<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc;
use cell::UnsafeCell;

pub struct RWLock {
    inner: UnsafeCell<libc::pthread_rwlock_t>,
    write_locked: UnsafeCell<bool>,
}

unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}

impl RWLock {
    pub const fn new() -> RWLock {
        RWLock {
            inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER),
            write_locked: UnsafeCell::new(false),
        }
    }
    #[inline]
    pub unsafe fn read(&self) {
        let r = libc::pthread_rwlock_rdlock(self.inner.get());

        // According to the pthread_rwlock_rdlock spec, this function **may**
        // fail with EDEADLK if a deadlock is detected. On the other hand
        // pthread mutexes will *never* return EDEADLK if they are initialized
        // as the "fast" kind (which ours always are). As a result, a deadlock
        // situation may actually return from the call to pthread_rwlock_rdlock
        // instead of blocking forever (as mutexes and Windows rwlocks do). Note
        // that not all unix implementations, however, will return EDEADLK for
        // their rwlocks.
        //
        // We roughly maintain the deadlocking behavior by panicking to ensure
        // that this lock acquisition does not succeed.
        //
        // We also check whether there this lock is already write locked. This
        // is only possible if it was write locked by the current thread and
        // the implementation allows recursive locking. The POSIX standard
        // doesn't require recursivly locking a rwlock to deadlock, but we can't
        // allow that because it could lead to aliasing issues.
        if r == libc::EDEADLK || *self.write_locked.get() {
            if r == 0 {
                self.raw_unlock();
            }
            panic!("rwlock read lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
        }
    }
    #[inline]
    pub unsafe fn try_read(&self) -> bool {
        let r = libc::pthread_rwlock_tryrdlock(self.inner.get());
        if r == 0 && *self.write_locked.get() {
            self.raw_unlock();
            false
        } else {
            r == 0
        }
    }
    #[inline]
    pub unsafe fn write(&self) {
        let r = libc::pthread_rwlock_wrlock(self.inner.get());
        // see comments above for why we check for EDEADLK and write_locked
        if r == libc::EDEADLK || *self.write_locked.get() {
            if r == 0 {
                self.raw_unlock();
            }
            panic!("rwlock write lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
        }
        *self.write_locked.get() = true;
    }
    #[inline]
    pub unsafe fn try_write(&self) -> bool {
        let r = libc::pthread_rwlock_trywrlock(self.inner.get());
        if r == 0 && *self.write_locked.get() {
            self.raw_unlock();
            false
        } else if r == 0 {
            *self.write_locked.get() = true;
            true
        } else {
            false
        }
    }
    #[inline]
    unsafe fn raw_unlock(&self) {
        let r = libc::pthread_rwlock_unlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn read_unlock(&self) {
        debug_assert!(!*self.write_locked.get());
        self.raw_unlock();
    }
    #[inline]
    pub unsafe fn write_unlock(&self) {
        debug_assert!(*self.write_locked.get());
        *self.write_locked.get() = false;
        self.raw_unlock();
    }
    #[inline]
    pub unsafe fn destroy(&self) {
        let r = libc::pthread_rwlock_destroy(self.inner.get());
        // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
        // rwlock that was just initialized with
        // libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
        // or pthread_rwlock_init() is called, this behaviour no longer occurs.
        if cfg!(target_os = "dragonfly") {
            debug_assert!(r == 0 || r == libc::EINVAL);
        } else {
            debug_assert_eq!(r, 0);
        }
    }
}
<commit_msg>Fix rwlock successfully acquiring a write lock after a read lock<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc;
use cell::UnsafeCell;
use sync::atomic::{AtomicUsize, Ordering};

pub struct RWLock {
    inner: UnsafeCell<libc::pthread_rwlock_t>,
    write_locked: UnsafeCell<bool>,
    num_readers: AtomicUsize,
}

unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}

impl RWLock {
    pub const fn new() -> RWLock {
        RWLock {
            inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER),
            write_locked: UnsafeCell::new(false),
            num_readers: AtomicUsize::new(0),
        }
    }
    #[inline]
    pub unsafe fn read(&self) {
        let r = libc::pthread_rwlock_rdlock(self.inner.get());

        // According to the pthread_rwlock_rdlock spec, this function **may**
        // fail with EDEADLK if a deadlock is detected. On the other hand
        // pthread mutexes will *never* return EDEADLK if they are initialized
        // as the "fast" kind (which ours always are). As a result, a deadlock
        // situation may actually return from the call to pthread_rwlock_rdlock
        // instead of blocking forever (as mutexes and Windows rwlocks do). Note
        // that not all unix implementations, however, will return EDEADLK for
        // their rwlocks.
        //
        // We roughly maintain the deadlocking behavior by panicking to ensure
        // that this lock acquisition does not succeed.
        //
        // We also check whether there this lock is already write locked. This
        // is only possible if it was write locked by the current thread and
        // the implementation allows recursive locking. The POSIX standard
        // doesn't require recursivly locking a rwlock to deadlock, but we can't
        // allow that because it could lead to aliasing issues.
        if r == libc::EDEADLK || *self.write_locked.get() {
            if r == 0 {
                self.raw_unlock();
            }
            panic!("rwlock read lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
            self.num_readers.fetch_add(1, Ordering::Relaxed);
        }
    }
    #[inline]
    pub unsafe fn try_read(&self) -> bool {
        let r = libc::pthread_rwlock_tryrdlock(self.inner.get());
        if r == 0 {
            if *self.write_locked.get() {
                self.raw_unlock();
                false
            } else {
                self.num_readers.fetch_add(1, Ordering::Relaxed);
                true
            }
        } else {
            false
        }
    }
    #[inline]
    pub unsafe fn write(&self) {
        let r = libc::pthread_rwlock_wrlock(self.inner.get());
        // See comments above for why we check for EDEADLK and write_locked. We
        // also need to check that num_readers is 0.
        if r == libc::EDEADLK || *self.write_locked.get() ||
           self.num_readers.load(Ordering::Relaxed) != 0 {
            if r == 0 {
                self.raw_unlock();
            }
            panic!("rwlock write lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
        }
        *self.write_locked.get() = true;
    }
    #[inline]
    pub unsafe fn try_write(&self) -> bool {
        let r = libc::pthread_rwlock_trywrlock(self.inner.get());
        if r == 0 {
            if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 {
                self.raw_unlock();
                false
            } else {
                *self.write_locked.get() = true;
                true
            }
        } else {
            false
        }
    }
    #[inline]
    unsafe fn raw_unlock(&self) {
        let r = libc::pthread_rwlock_unlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn read_unlock(&self) {
        debug_assert!(!*self.write_locked.get());
        self.num_readers.fetch_sub(1, Ordering::Relaxed);
        self.raw_unlock();
    }
    #[inline]
    pub unsafe fn write_unlock(&self) {
        debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0);
        debug_assert!(*self.write_locked.get());
        *self.write_locked.get() = false;
        self.raw_unlock();
    }
    #[inline]
    pub unsafe fn destroy(&self) {
        let r = libc::pthread_rwlock_destroy(self.inner.get());
        // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
        // rwlock that was just initialized with
        // libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
        // or pthread_rwlock_init() is called, this behaviour no longer occurs.
        if cfg!(target_os = "dragonfly") {
            debug_assert!(r == 0 || r == libc::EINVAL);
        } else {
            debug_assert_eq!(r, 0);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Rename Cursor struct member variables<commit_after><|endoftext|>


<commit_before><commit_msg>Invalid source code formatin, rustfmt errors Fixed<commit_after><|endoftext|>


<commit_before>/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of Dmitry Vyukov.
 */

//! A mostly lock-free multi-producer, single consumer queue.
//!
//! This module contains an implementation of a concurrent MPSC queue. This
//! queue can be used to share data between tasks, and is also used as the
//! building block of channels in rust.
//!
//! Note that the current implementation of this queue has a caveat of the `pop`
//! method, and see the method for more information about it. Due to this
//! caveat, this queue may not be appropriate for all use-cases.

// http://www.1024cores.net/home/lock-free-algorithms
//                         /queues/non-intrusive-mpsc-node-based-queue

use kinds::Send;
use mem;
use ops::Drop;
use option::{Option, None, Some};
use owned::Box;
use ptr::RawPtr;
use sync::atomics::{AtomicPtr, Release, Acquire, AcqRel, Relaxed};

/// A result of the `pop` function.
pub enum PopResult<T> {
    /// Some data has been popped
    Data(T),
    /// The queue is empty
    Empty,
    /// The queue is in an inconsistent state. Popping data should succeed, but
    /// some pushers have yet to make enough progress in order allow a pop to
    /// succeed. It is recommended that a pop() occur "in the near future" in
    /// order to see if the sender has made progress or not
    Inconsistent,
}

struct Node<T> {
    next: AtomicPtr<Node<T>>,
    value: Option<T>,
}

/// The multi-producer single-consumer structure. This is not cloneable, but it
/// may be safely shared so long as it is guaranteed that there is only one
/// popper at a time (many pushers are allowed).
pub struct Queue<T> {
    head: AtomicPtr<Node<T>>,
    tail: *mut Node<T>,
}

impl<T> Node<T> {
    unsafe fn new(v: Option<T>) -> *mut Node<T> {
        mem::transmute(box Node {
            next: AtomicPtr::new(0 as *mut Node<T>),
            value: v,
        })
    }
}

impl<T: Send> Queue<T> {
    /// Creates a new queue that is safe to share among multiple producers and
    /// one consumer.
    pub fn new() -> Queue<T> {
        let stub = unsafe { Node::new(None) };
        Queue {
            head: AtomicPtr::new(stub),
            tail: stub,
        }
    }

    /// Pushes a new value onto this queue.
    pub fn push(&mut self, t: T) {
        unsafe {
            let n = Node::new(Some(t));
            let prev = self.head.swap(n, AcqRel);
            (*prev).next.store(n, Release);
        }
    }

    /// Pops some data from this queue.
    ///
    /// Note that the current implementation means that this function cannot
    /// return `Option<T>`. It is possible for this queue to be in an
    /// inconsistent state where many pushes have succeeded and completely
    /// finished, but pops cannot return `Some(t)`. This inconsistent state
    /// happens when a pusher is pre-empted at an inopportune moment.
    ///
    /// This inconsistent state means that this queue does indeed have data, but
    /// it does not currently have access to it at this time.
    pub fn pop(&mut self) -> PopResult<T> {
        unsafe {
            let tail = self.tail;
            let next = (*tail).next.load(Acquire);

            if !next.is_null() {
                self.tail = next;
                assert!((*tail).value.is_none());
                assert!((*next).value.is_some());
                let ret = (*next).value.take_unwrap();
                let _: Box<Node<T>> = mem::transmute(tail);
                return Data(ret);
            }

            if self.head.load(Acquire) == tail {Empty} else {Inconsistent}
        }
    }

    /// Attempts to pop data from this queue, but doesn't attempt too hard. This
    /// will canonicalize inconsistent states to a `None` value.
    pub fn casual_pop(&mut self) -> Option<T> {
        match self.pop() {
            Data(t) => Some(t),
            Empty | Inconsistent => None,
        }
    }
}

#[unsafe_destructor]
impl<T: Send> Drop for Queue<T> {
    fn drop(&mut self) {
        unsafe {
            let mut cur = self.tail;
            while !cur.is_null() {
                let next = (*cur).next.load(Relaxed);
                let _: Box<Node<T>> = mem::transmute(cur);
                cur = next;
            }
        }
    }
}

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

    use native;
    use super::{Queue, Data, Empty, Inconsistent};
    use sync::arc::UnsafeArc;

    #[test]
    fn test_full() {
        let mut q = Queue::new();
        q.push(box 1);
        q.push(box 2);
    }

    #[test]
    fn test() {
        let nthreads = 8u;
        let nmsgs = 1000u;
        let mut q = Queue::new();
        match q.pop() {
            Empty => {}
            Inconsistent | Data(..) => fail!()
        }
        let (tx, rx) = channel();
        let q = UnsafeArc::new(q);

        for _ in range(0, nthreads) {
            let tx = tx.clone();
            let q = q.clone();
            native::task::spawn(proc() {
                for i in range(0, nmsgs) {
                    unsafe { (*q.get()).push(i); }
                }
                tx.send(());
            });
        }

        let mut i = 0u;
        while i < nthreads * nmsgs {
            match unsafe { (*q.get()).pop() } {
                Empty | Inconsistent => {},
                Data(_) => { i += 1 }
            }
        }
        drop(tx);
        for _ in range(0, nthreads) {
            rx.recv();
        }
    }
}
<commit_msg>std: Rebuild mpsc queue with Unsafe/&self<commit_after>/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of Dmitry Vyukov.
 */

//! A mostly lock-free multi-producer, single consumer queue.
//!
//! This module contains an implementation of a concurrent MPSC queue. This
//! queue can be used to share data between tasks, and is also used as the
//! building block of channels in rust.
//!
//! Note that the current implementation of this queue has a caveat of the `pop`
//! method, and see the method for more information about it. Due to this
//! caveat, this queue may not be appropriate for all use-cases.

// http://www.1024cores.net/home/lock-free-algorithms
//                         /queues/non-intrusive-mpsc-node-based-queue

use kinds::Send;
use mem;
use ops::Drop;
use option::{Option, None, Some};
use owned::Box;
use ptr::RawPtr;
use sync::atomics::{AtomicPtr, Release, Acquire, AcqRel, Relaxed};
use ty::Unsafe;

/// A result of the `pop` function.
pub enum PopResult<T> {
    /// Some data has been popped
    Data(T),
    /// The queue is empty
    Empty,
    /// The queue is in an inconsistent state. Popping data should succeed, but
    /// some pushers have yet to make enough progress in order allow a pop to
    /// succeed. It is recommended that a pop() occur "in the near future" in
    /// order to see if the sender has made progress or not
    Inconsistent,
}

struct Node<T> {
    next: AtomicPtr<Node<T>>,
    value: Option<T>,
}

/// The multi-producer single-consumer structure. This is not cloneable, but it
/// may be safely shared so long as it is guaranteed that there is only one
/// popper at a time (many pushers are allowed).
pub struct Queue<T> {
    head: AtomicPtr<Node<T>>,
    tail: Unsafe<*mut Node<T>>,
}

impl<T> Node<T> {
    unsafe fn new(v: Option<T>) -> *mut Node<T> {
        mem::transmute(box Node {
            next: AtomicPtr::new(0 as *mut Node<T>),
            value: v,
        })
    }
}

impl<T: Send> Queue<T> {
    /// Creates a new queue that is safe to share among multiple producers and
    /// one consumer.
    pub fn new() -> Queue<T> {
        let stub = unsafe { Node::new(None) };
        Queue {
            head: AtomicPtr::new(stub),
            tail: Unsafe::new(stub),
        }
    }

    /// Pushes a new value onto this queue.
    pub fn push(&self, t: T) {
        unsafe {
            let n = Node::new(Some(t));
            let prev = self.head.swap(n, AcqRel);
            (*prev).next.store(n, Release);
        }
    }

    /// Pops some data from this queue.
    ///
    /// Note that the current implementation means that this function cannot
    /// return `Option<T>`. It is possible for this queue to be in an
    /// inconsistent state where many pushes have succeeded and completely
    /// finished, but pops cannot return `Some(t)`. This inconsistent state
    /// happens when a pusher is pre-empted at an inopportune moment.
    ///
    /// This inconsistent state means that this queue does indeed have data, but
    /// it does not currently have access to it at this time.
    pub fn pop(&self) -> PopResult<T> {
        unsafe {
            let tail = *self.tail.get();
            let next = (*tail).next.load(Acquire);

            if !next.is_null() {
                *self.tail.get() = next;
                assert!((*tail).value.is_none());
                assert!((*next).value.is_some());
                let ret = (*next).value.take_unwrap();
                let _: Box<Node<T>> = mem::transmute(tail);
                return Data(ret);
            }

            if self.head.load(Acquire) == tail {Empty} else {Inconsistent}
        }
    }

    /// Attempts to pop data from this queue, but doesn't attempt too hard. This
    /// will canonicalize inconsistent states to a `None` value.
    pub fn casual_pop(&self) -> Option<T> {
        match self.pop() {
            Data(t) => Some(t),
            Empty | Inconsistent => None,
        }
    }
}

#[unsafe_destructor]
impl<T: Send> Drop for Queue<T> {
    fn drop(&mut self) {
        unsafe {
            let mut cur = *self.tail.get();
            while !cur.is_null() {
                let next = (*cur).next.load(Relaxed);
                let _: Box<Node<T>> = mem::transmute(cur);
                cur = next;
            }
        }
    }
}

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

    use native;
    use super::{Queue, Data, Empty, Inconsistent};
    use sync::arc::UnsafeArc;

    #[test]
    fn test_full() {
        let mut q = Queue::new();
        q.push(box 1);
        q.push(box 2);
    }

    #[test]
    fn test() {
        let nthreads = 8u;
        let nmsgs = 1000u;
        let mut q = Queue::new();
        match q.pop() {
            Empty => {}
            Inconsistent | Data(..) => fail!()
        }
        let (tx, rx) = channel();
        let q = UnsafeArc::new(q);

        for _ in range(0, nthreads) {
            let tx = tx.clone();
            let q = q.clone();
            native::task::spawn(proc() {
                for i in range(0, nmsgs) {
                    unsafe { (*q.get()).push(i); }
                }
                tx.send(());
            });
        }

        let mut i = 0u;
        while i < nthreads * nmsgs {
            match unsafe { (*q.get()).pop() } {
                Empty | Inconsistent => {},
                Data(_) => { i += 1 }
            }
        }
        drop(tx);
        for _ in range(0, nthreads) {
            rx.recv();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Only derive negation on primitive types that support it.<commit_after><|endoftext|>


<commit_before><commit_msg>impl Add for &NonSmallInt<commit_after><|endoftext|>


<commit_before><commit_msg> change to make all tests run<commit_after><|endoftext|>


<commit_before><commit_msg>Create lib.rs<commit_after>
<|endoftext|>


<commit_before><commit_msg>version work<commit_after><|endoftext|>


<commit_before><commit_msg>Trying out a new header structure and splitting.<commit_after><|endoftext|>


<commit_before><commit_msg>Made events queue instead of handling recursively<commit_after><|endoftext|>


<commit_before><commit_msg>Renaming BMPVersion to Version<commit_after><|endoftext|>


<commit_before><commit_msg>IdVec::clear<commit_after><|endoftext|>


<commit_before><commit_msg>keytype: add missing source file<commit_after>// Copyright (c) 2015, Ben Boeckel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//       this list of conditions and the following disclaimer in the documentation
//       and/or other materials provided with the distribution.
//     * Neither the name of this project nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::borrow::Cow;

/// A trait for representing a type of key in the Linux keyring subsystem.
pub trait KeyType {
    /// The type for describing the key.
    type Description: KeyDescription + ?Sized;
    /// The type for representing a payload for the key.
    type Payload: KeyPayload + ?Sized;

    /// The name of the keytype.
    fn name() -> &'static str;
}

/// A description for a key.
pub trait KeyDescription {
    /// The description of the key.
    fn description(&self) -> Cow<str>;
}

impl KeyDescription for str {
    fn description(&self) -> Cow<str> {
        Cow::Borrowed(&self)
    }
}

impl KeyDescription for String {
    fn description(&self) -> Cow<str> {
        Cow::Borrowed(&self)
    }
}

/// A payload for a key.
pub trait KeyPayload {
    /// The payload for the key.
    fn payload(&self) -> Cow<[u8]>;
}

impl KeyPayload for () {
    fn payload(&self) -> Cow<[u8]> {
        Cow::Borrowed(&[])
    }
}

impl KeyPayload for str {
    fn payload(&self) -> Cow<[u8]> {
        Cow::Borrowed(self.as_bytes())
    }
}

impl KeyPayload for String {
    fn payload(&self) -> Cow<[u8]> {
        Cow::Borrowed(self.as_bytes())
    }
}

impl KeyPayload for [u8] {
    fn payload(&self) -> Cow<[u8]> {
        Cow::Borrowed(self)
    }
}

impl KeyPayload for Vec<u8> {
    fn payload(&self) -> Cow<[u8]> {
        Cow::Borrowed(&self)
    }
}
<|endoftext|>


<commit_before><commit_msg>Set default Vulkan debug mask to hide debug and info messages, and reorder option fields for clarity<commit_after><|endoftext|>


<commit_before><commit_msg>Add deque sanitization test<commit_after><|endoftext|>


<commit_before><commit_msg>Updated rust basic bot<commit_after>#![allow(non_snake_case)]
#![allow(warnings)]

extern crate rand;
#[macro_use] extern crate text_io;

//Notice: due to Rust's extreme dislike of (even private!) global mutables, we do not reset the production values of each tile during get_frame.
//If you change them, you may not be able to recover the actual production values of the map, so we recommend not editing them.
//However, if your code calls for it, you're welcome to edit the production values of the sites of the map - just do so at your own risk.

mod hlt;
use hlt::{ networking, types };
use std::collections::HashMap;
use rand::Rng;

fn main() {
	let (my_id, mut game_map) = networking::get_init();
	let mut rng = rand::thread_rng();
	networking::send_init(format!("{}{}", "RustBot".to_string(), my_id.to_string()));
	loop {
		networking::get_frame(&mut game_map);
		let mut moves = HashMap::new();
		for a in 0..game_map.height {
			for b in 0..game_map.width {
				let l = hlt::types::Location { x: b, y: a };
				if game_map.get_site(l, types::STILL).owner == my_id {
					let mut dir: u8 = types::STILL;
					if { game_map.get_site(l, types::STILL).strength } >= 5 * game_map.get_site(l, types::STILL).production {
						dir = (rng.gen::<u32>() % 5) as u8;
						for d in types::CARDINALS.iter() {
							if game_map.get_site(l, *d).owner != my_id {
								dir = *d;
							}
						}
					}
					moves.insert(l, dir);
				}
			}
		}
		networking::send_frame(moves);
	}
}<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::MaybeTyped::*;

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::hir::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::hir::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
use rustc_metadata::creader::read_local_crates;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;
use html::render::RenderInfo;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(TyCtxt<'a, 'tcx, 'tcx>),
    NotTyped(&'a session::Session)
}

pub type Externs = HashMap<String, Vec<String>>;
pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
    // Note that external items for which `doc(hidden)` applies to are shown as
    // non-reachable while local items aren't. This is because we're reusing
    // the access levels from crateanalysis.
    /// Later on moved into `clean::Crate`
    pub access_levels: RefCell<AccessLevels<DefId>>,
    /// Later on moved into `html::render::CACHE_KEY`
    pub renderinfo: RefCell<RenderInfo>,
    /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
    pub external_traits: RefCell<HashMap<DefId, clean::Trait>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub trait DocAccessLevels {
    fn is_doc_reachable(&self, DefId) -> bool;
}

impl DocAccessLevels for AccessLevels<DefId> {
    fn is_doc_reachable(&self, did: DefId) -> bool {
        self.is_public(did)
    }
}

pub fn run_core(search_paths: SearchPaths,
                cfgs: Vec<String>,
                externs: Externs,
                input: Input,
                triple: Option<String>) -> (clean::Crate, RenderInfo)
{
    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
    let sess = session::build_session_(sessopts, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);
    let dep_graph = DepGraph::new(false);

    let mut defs = hir_map::collect_definitions(&krate);
    read_local_crates(&sess, &cstore, &defs, &krate, &name, &dep_graph);

    // Lower ast -> hir and resolve.
    let (analysis, resolutions, mut hir_forest) = {
        driver::lower_and_resolve(&sess, &name, &mut defs, &krate, dep_graph,
                                  resolve::MakeGlobMap::No)
    };

    let arenas = ty::CtxtArenas::new();
    let hir_map = hir_map::map_crate(&mut hir_forest, defs);

    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     hir_map,
                                                     analysis,
                                                     resolutions,
                                                     &arenas,
                                                     &name,
                                                     |tcx, _, analysis, result| {
        // Return if the driver hit an err (in `result`)
        if let Err(_) = result {
            return None
        }

        let _ignore = tcx.dep_graph.in_ignore();
        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
            access_levels: RefCell::new(access_levels),
            external_traits: RefCell::new(HashMap::new()),
            renderinfo: RefCell::new(Default::default()),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt);
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        Some((krate, ctxt.renderinfo.into_inner()))
    }), &sess).unwrap()
}
<commit_msg>Resolved rustdoc crash (#33678) by aborting instead of unwrapping. Removed Option use and comment to match.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::MaybeTyped::*;

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::hir::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::hir::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
use rustc_metadata::creader::read_local_crates;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;
use html::render::RenderInfo;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(TyCtxt<'a, 'tcx, 'tcx>),
    NotTyped(&'a session::Session)
}

pub type Externs = HashMap<String, Vec<String>>;
pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
    // Note that external items for which `doc(hidden)` applies to are shown as
    // non-reachable while local items aren't. This is because we're reusing
    // the access levels from crateanalysis.
    /// Later on moved into `clean::Crate`
    pub access_levels: RefCell<AccessLevels<DefId>>,
    /// Later on moved into `html::render::CACHE_KEY`
    pub renderinfo: RefCell<RenderInfo>,
    /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
    pub external_traits: RefCell<HashMap<DefId, clean::Trait>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub trait DocAccessLevels {
    fn is_doc_reachable(&self, DefId) -> bool;
}

impl DocAccessLevels for AccessLevels<DefId> {
    fn is_doc_reachable(&self, did: DefId) -> bool {
        self.is_public(did)
    }
}

pub fn run_core(search_paths: SearchPaths,
                cfgs: Vec<String>,
                externs: Externs,
                input: Input,
                triple: Option<String>) -> (clean::Crate, RenderInfo)
{
    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
    let sess = session::build_session_(sessopts, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);
    let dep_graph = DepGraph::new(false);

    let mut defs = hir_map::collect_definitions(&krate);
    read_local_crates(&sess, &cstore, &defs, &krate, &name, &dep_graph);

    // Lower ast -> hir and resolve.
    let (analysis, resolutions, mut hir_forest) = {
        driver::lower_and_resolve(&sess, &name, &mut defs, &krate, dep_graph,
                                  resolve::MakeGlobMap::No)
    };

    let arenas = ty::CtxtArenas::new();
    let hir_map = hir_map::map_crate(&mut hir_forest, defs);

    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     hir_map,
                                                     analysis,
                                                     resolutions,
                                                     &arenas,
                                                     &name,
                                                     |tcx, _, analysis, result| {
        if let Err(_) = result {
            sess.fatal("Compilation failed, aborting rustdoc");
        }

        let _ignore = tcx.dep_graph.in_ignore();
        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
            access_levels: RefCell::new(access_levels),
            external_traits: RefCell::new(HashMap::new()),
            renderinfo: RefCell::new(Default::default()),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt);
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        (krate, ctxt.renderinfo.into_inner())
    }), &sess)
}
<|endoftext|>


<commit_before><commit_msg>Add RMS example to the examples directory<commit_after>// Hound -- A wav encoding and decoding library in Rust
// Copyright (C) 2017 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.
// 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.

// This example computes the root mean square (rms) of an audio file with
// integer or float samples, of at most 32 bits per sample. It is a slightly
// more elaborate version of the example found in the readme, mostly useful for
// checking whether Hound can read a specific file.

extern crate hound;

use std::env;
use std::io;

/// Compute the RMS of either integers or float samples.
fn compute_rms<S, R>(reader: &mut hound::WavReader<R>) -> f64
where
    f64: From<S>,
    S: hound::Sample,
    R: io::Read,
{
    let sqr_sum = reader.samples::<S>().fold(0.0, |sqr_sum, s| {
        let sample = f64::from(s.unwrap());
        sqr_sum + sample * sample
    });
    (sqr_sum / reader.len() as f64).sqrt()
}

fn main() {
    // Compute the RMS for all files given on the command line.
    for fname in env::args().skip(1) {
        let mut reader = hound::WavReader::open(&fname).unwrap();
        let rms = match reader.spec().sample_format {
            hound::SampleFormat::Float => compute_rms::<f32, _>(&mut reader),
            hound::SampleFormat::Int => compute_rms::<i32, _>(&mut reader),
        };
        println!("{}: {:0.1}", fname, rms);
    }
}
<|endoftext|>


<commit_before><commit_msg>Added example for rectangle texture bug<commit_after>
// Allow dead code since this is an example app.
#![allow(dead_code)]
#![feature(globs)]

extern crate piston;
extern crate graphics;
extern crate sdl2_game_window;
extern crate opengl_graphics;

use opengl_graphics::{Gl, Texture};
use Window = sdl2_game_window::GameWindowSDL2;
use graphics::*;
use piston::{
    AssetStore,
    GameIterator,
    GameIteratorSettings,
    GameWindowSettings,
    Render,
};

#[start]
fn start(argc: int, argv: **u8) -> int {
    // Run on the main thread.
    native::start(argc, argv, main)
}

fn main() {
    let mut window = Window::new(
        GameWindowSettings {
            title: "Rust-Graphics-Lab: Texture App".to_string(),
            size: [600, 300],
            fullscreen: false,
            exit_on_esc: true,
        }
    );

    let asset_store = AssetStore::from_folder("assets");

    let image = asset_store.path("dices.png").unwrap();
    let image = Texture::from_path(&image).unwrap();

    let game_iter_settings = GameIteratorSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };
    let mut game_iter = GameIterator::new(&mut window, &game_iter_settings);
    let ref mut gl = Gl::new();
    loop {
        match game_iter.next() {
            None => break,
            Some(mut e) => match e {
                Render(ref mut args) => {
                    gl.viewport(0, 0, args.width as i32, args.height as i32);
                    let c = Context::abs(
                            args.width as f64,
                            args.height as f64
                        );
                    c.rgb(1.0, 1.0, 1.0).draw(gl);
                    c.rect(0.0, 0.0, 50.0, 50.0).rgb(1.0, 0.0, 0.0).draw(gl);
                    let offset = 150.0;
                    // c.trans(0.0, offset).image(&image).draw(gl);
                },
                _ => {},
            }
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Manually impl Ord, PartialOrd<commit_after><|endoftext|>


<commit_before><commit_msg>add test for logger naming<commit_after><|endoftext|>


<commit_before><commit_msg>Ignore test of the FTPS example in lib docs<commit_after><|endoftext|>


<commit_before><commit_msg>Fix mod<commit_after><|endoftext|>


<commit_before>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]

extern crate time;
extern crate current;

use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Current, Get, Modifier, Set };
use std::cmp;
use std::cell::RefCell;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose) {
        self.set_mut(val);
    }
}

impl<T: Set<ShouldClose>> SetShouldClose for T {}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Set<Size>`.
/// Used to support generic constraints.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size) {
        self.set_mut(val);
    }
}

impl<T: Set<Size>> SetSize for T {}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<W: SwapBuffers> SwapBuffers for Current<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.deref_mut().swap_buffers();
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<W: PollEvent<I>, I> PollEvent<I> for Current<W> {
    fn poll_event(&mut self) -> Option<I> {
        self.deref_mut().poll_event()
    }
}

impl<'a, W: 'a + PollEvent<I>, I> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Render arguments
#[deriving(Clone, PartialEq, Show)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[deriving(Clone, PartialEq, Show)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
}

#[deriving(Show)]
enum EventsState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Ups>`
pub trait SetUps: Set<Ups> {
    /// Sets updates per second.
    fn set_ups(&mut self, val: Ups) {
        self.set_mut(val);
    }
}

impl<T: Set<Ups>> SetUps for T {}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Fps>`
pub trait SetMaxFps: Set<MaxFps> {
    /// Sets frames per second.
    fn set_max_fps(&mut self, val: MaxFps) {
        self.set_mut(val);
    }
}

impl<T: Set<MaxFps>> SetMaxFps for T {}

/// Blanket impl for object that fulfill requirements.
pub trait EventWindow<I>:
    PollEvent<I>
  + GetShouldClose
  + GetSize
  + SwapBuffers {}

impl<T: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers, I>
EventWindow<I> for T {}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: EventsState::RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I, E: EventMap<I>>
Iterator<E>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                EventsState::RenderState => {
                    let ShouldClose(should_close) = self.window.get_should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = EventsState::SwapBuffersState;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    EventsState::UpdateLoopState
                }
                EventsState::SwapBuffersState => {
                    self.window.swap_buffers();
                    EventsState::UpdateLoopState
                }
                EventsState::UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        EventsState::UpdateLoopState
                    } else if next_event == next_frame {
                        EventsState::RenderState
                    } else {
                        EventsState::HandleEventsState
                    }
                }
                EventsState::HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => EventsState::UpdateState,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                EventsState::UpdateState => {
                    self.state = EventsState::UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<commit_msg>Removed `State` from `EventsState` enum variants<commit_after>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]

extern crate time;
extern crate current;

use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Current, Get, Modifier, Set };
use std::cmp;
use std::cell::RefCell;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose) {
        self.set_mut(val);
    }
}

impl<T: Set<ShouldClose>> SetShouldClose for T {}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Set<Size>`.
/// Used to support generic constraints.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size) {
        self.set_mut(val);
    }
}

impl<T: Set<Size>> SetSize for T {}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<W: SwapBuffers> SwapBuffers for Current<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.deref_mut().swap_buffers();
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<W: PollEvent<I>, I> PollEvent<I> for Current<W> {
    fn poll_event(&mut self) -> Option<I> {
        self.deref_mut().poll_event()
    }
}

impl<'a, W: 'a + PollEvent<I>, I> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Render arguments
#[deriving(Clone, PartialEq, Show)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[deriving(Clone, PartialEq, Show)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
}

#[deriving(Show)]
enum EventsState {
    Render,
    SwapBuffers,
    UpdateLoop,
    HandleEvents,
    Update,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Ups>`
pub trait SetUps: Set<Ups> {
    /// Sets updates per second.
    fn set_ups(&mut self, val: Ups) {
        self.set_mut(val);
    }
}

impl<T: Set<Ups>> SetUps for T {}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Fps>`
pub trait SetMaxFps: Set<MaxFps> {
    /// Sets frames per second.
    fn set_max_fps(&mut self, val: MaxFps) {
        self.set_mut(val);
    }
}

impl<T: Set<MaxFps>> SetMaxFps for T {}

/// Blanket impl for object that fulfill requirements.
pub trait EventWindow<I>:
    PollEvent<I>
  + GetShouldClose
  + GetSize
  + SwapBuffers {}

impl<T: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers, I>
EventWindow<I> for T {}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: EventsState::Render,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I, E: EventMap<I>>
Iterator<E>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                EventsState::Render => {
                    let ShouldClose(should_close) = self.window.get_should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = EventsState::SwapBuffers;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    EventsState::UpdateLoop
                }
                EventsState::SwapBuffers => {
                    self.window.swap_buffers();
                    EventsState::UpdateLoop
                }
                EventsState::UpdateLoop => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        EventsState::UpdateLoop
                    } else if next_event == next_frame {
                        EventsState::Render
                    } else {
                        EventsState::HandleEvents
                    }
                }
                EventsState::HandleEvents => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => EventsState::Update,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                EventsState::Update => {
                    self.state = EventsState::UpdateLoop;
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>fixed tests to account for deps<commit_after><|endoftext|>


<commit_before><commit_msg>Snake_cased struct names<commit_after><|endoftext|>


<commit_before><commit_msg>fix npc in_proximity method<commit_after><|endoftext|>


<commit_before><commit_msg>hello-world example added.<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;

extern crate actix_http;
extern crate actix_net;
extern crate futures;
extern crate http;

use actix_http::{h1, Response};
use actix_net::server::Server;
use actix_net::service::NewServiceExt;
use futures::future;
use http::header::{HeaderValue};
use std::env;

fn main() {
    env::set_var("RUST_LOG", "hello_world=info");
    env_logger::init();

    Server::new().bind("hello-world", "127.0.0.1:8080", || {
        h1::H1Service::build()
            .client_timeout(1000)
            .client_disconnect(1000)
            .server_hostname("localhost")
            .finish(|_req| {
                info!("{:?}", _req);
                let mut res = Response::Ok();
                res.header("x-head", HeaderValue::from_static("dummy value!"));
                future::ok::<_, ()>(res.body("Hello world!"))
            })
            .map(|_| ())
    }).unwrap().run();
}

<|endoftext|>


<commit_before><commit_msg>Return individual results as iterator<commit_after><|endoftext|>