<commit_before>use std::{ io, fs, cmp };
use std::ops::Range;
use futures::{ Stream, Poll, Async };
use tokio_io::io::Window;
use hyper;
use ::error;

#[cfg(feature = "sendfile")] use tokio::net::TcpStream;
#[cfg(feature = "sendfile")] use std::sync::Arc;
#[cfg(feature = "sendfile")] use futures::sync::BiLock;
#[cfg(feature = "sendfile")] use ::sendfile::SendFileFut;

pub struct File {
    fd: fs::File,
    chunk_length: usize,
    pub length: u64
}

impl File {
    #[inline]
    pub fn new(fd: fs::File, chunk_length: usize, length: u64) -> io::Result<Self> {
        Ok(File { fd, chunk_length, length })
    }

    #[inline]
    pub fn try_clone(&self) -> io::Result<Self> {
        Ok(File {
            fd: self.fd.try_clone()?,
            chunk_length: self.chunk_length,
            length: self.length
        })
    }

    pub fn read(self, range: Range<u64>) -> io::Result<ReadChunkFut> {
        let buf = vec![0; cmp::min(self.chunk_length, self.length as _)];
        Ok(ReadChunkFut { fd: self.fd, range, buf })
    }

    #[cfg(feature = "sendfile")]
    #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
    pub fn sendfile(self, range: Range<u64>, socket: Arc<BiLock<TcpStream>>) -> io::Result<SendFileFut> {
        Ok(SendFileFut {
            socket,
            fd: self.fd,
            offset: range.start as _,
            end: range.end as _
        })
    }
}

pub struct ReadChunkFut {
    fd: fs::File,
    range: Range<u64>,
    buf: Vec<u8>
}

impl Stream for ReadChunkFut {
    type Item = hyper::Result<hyper::Chunk>;
    type Error = error::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        #[cfg(unix)] use std::os::unix::fs::FileExt;
        #[cfg(windows)] use std::os::windows::fs::FileExt;

        let want_len = cmp::min((self.range.end - self.range.start) as _, self.buf.len());

        if want_len > 0 {
            let mut window = Window::new(&mut self.buf[..]);
            window.set_end(want_len);

            #[cfg(unix)]
            let read_len = self.fd.read_at(window.as_mut(), self.range.start)?;

            #[cfg(windows)]
            let read_len = self.fd.seek_read(window.as_mut(), self.range.start)?;

            self.range.start += read_len as u64;
            window.set_end(read_len);
            let chunk = Vec::from(window.as_ref());
            let chunk = hyper::Chunk::from(chunk);
            Ok(Async::Ready(Some(Ok(chunk))))
        } else {
            Ok(Async::Ready(None))
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;

    use std::fs;
    use std::io::Write;
    use futures::Stream;
    use self::tempdir::TempDir;
    use super::*;

    #[test]
    fn test_file() {
        let tmp = TempDir::new("webdir_test_file").unwrap();

        {
            fs::File::create(tmp.path().join("test")).unwrap()
                .write_all(&[42; 1024]).unwrap();
        }

        let fd = fs::File::open(tmp.path().join("test")).unwrap();
        let len = fd.metadata().unwrap().len();

        let fd = File::new(fd, len as _, 1 << 16).unwrap();
        let fut = fd.read(32..1021).unwrap()
            .map(|chunk| chunk.unwrap().to_vec())
            .concat2();

        let output = fut.wait().unwrap();

        assert_eq!(output, &[42; 989][..]);
    }
}
<commit_msg>[Fixed] fix test<commit_after>use std::{ io, fs, cmp };
use std::ops::Range;
use futures::{ Stream, Poll, Async };
use tokio_io::io::Window;
use hyper;
use ::error;

#[cfg(feature = "sendfile")] use tokio::net::TcpStream;
#[cfg(feature = "sendfile")] use std::sync::Arc;
#[cfg(feature = "sendfile")] use futures::sync::BiLock;
#[cfg(feature = "sendfile")] use ::sendfile::SendFileFut;

pub struct File {
    fd: fs::File,
    chunk_length: usize,
    pub length: u64
}

impl File {
    #[inline]
    pub fn new(fd: fs::File, chunk_length: usize, length: u64) -> io::Result<Self> {
        Ok(File { fd, chunk_length, length })
    }

    #[inline]
    pub fn try_clone(&self) -> io::Result<Self> {
        Ok(File {
            fd: self.fd.try_clone()?,
            chunk_length: self.chunk_length,
            length: self.length
        })
    }

    pub fn read(self, range: Range<u64>) -> io::Result<ReadChunkFut> {
        let buf = vec![0; cmp::min(self.chunk_length, self.length as _)];
        Ok(ReadChunkFut { fd: self.fd, range, buf })
    }

    #[cfg(feature = "sendfile")]
    #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
    pub fn sendfile(self, range: Range<u64>, socket: Arc<BiLock<TcpStream>>) -> io::Result<SendFileFut> {
        Ok(SendFileFut {
            socket,
            fd: self.fd,
            offset: range.start as _,
            end: range.end as _
        })
    }
}

pub struct ReadChunkFut {
    fd: fs::File,
    range: Range<u64>,
    buf: Vec<u8>
}

impl Stream for ReadChunkFut {
    type Item = hyper::Result<hyper::Chunk>;
    type Error = error::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        #[cfg(unix)] use std::os::unix::fs::FileExt;
        #[cfg(windows)] use std::os::windows::fs::FileExt;

        let want_len = cmp::min((self.range.end - self.range.start) as _, self.buf.len());

        if want_len > 0 {
            let mut window = Window::new(&mut self.buf[..]);
            window.set_end(want_len);

            #[cfg(unix)]
            let read_len = self.fd.read_at(window.as_mut(), self.range.start)?;

            #[cfg(windows)]
            let read_len = self.fd.seek_read(window.as_mut(), self.range.start)?;

            self.range.start += read_len as u64;
            window.set_end(read_len);
            let chunk = Vec::from(window.as_ref());
            let chunk = hyper::Chunk::from(chunk);
            Ok(Async::Ready(Some(Ok(chunk))))
        } else {
            Ok(Async::Ready(None))
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;

    use std::fs;
    use std::io::Write;
    use futures::{ Future, Stream };
    use self::tempdir::TempDir;
    use super::*;

    #[test]
    fn test_file() {
        let tmp = TempDir::new("webdir_test_file").unwrap();

        {
            fs::File::create(tmp.path().join("test")).unwrap()
                .write_all(&[42; 1024]).unwrap();
        }

        let fd = fs::File::open(tmp.path().join("test")).unwrap();
        let len = fd.metadata().unwrap().len();

        let fd = File::new(fd, len as _, 1 << 16).unwrap();
        let fut = fd.read(32..1021).unwrap()
            .map(|chunk| chunk.unwrap().to_vec())
            .concat2();

        let output = fut.wait().unwrap();

        assert_eq!(output, &[42; 989][..]);
    }
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate orbclient;
extern crate orbfont;

use std::cmp::max;

use std::env;

use orbclient::{Color, Renderer, Window, EventOption, K_ESC};
use orbfont::Font;

fn event_loop(window: &mut Window){
    loop {
        for event in window.events() {
            if let EventOption::Key(key_event) = event.to_option() {
                if key_event.pressed && key_event.scancode == K_ESC {
                    return;
                }
            }
            if let EventOption::Quit(_) = event.to_option() {
                return;
            }
        }
    }
}

fn error_msg(window: &mut Window, msg: &str) {
    let mut x = 0;
    for c in msg.chars() {
        window.char(x, 0, c, Color::rgb(255, 255, 255));
        x += 8;
    }
}

fn main() {
    let (title, font_res) = match env::args().nth(1) {
        Some(arg) => (arg.clone(), Font::from_path(&arg)),
        None => ("Default Font".to_string(), Font::find(None, None, None)),
    };

    match font_res {
        Ok(font) => {
            let lines = [
                font.render("ABCDEFGHIJK", 64.0),
                font.render("LMNOPQRSTUV", 64.0),
                font.render("WXYZabcdefg", 64.0),
                font.render("hijklmnopqr", 64.0),
                font.render("stuvwxyz.?!", 64.0),
                font.render("0123456789 ", 64.0)
            ];
            let mut width = 0;
            let mut height = 0;
            for line in lines.iter() {
                width = max(width, line.width());
                height += line.height();
            }
            let mut window = Window::new(-1,
                                         -1,
                                         max(320, width),
                                         max(32, height),
                                         &("Character Map (".to_string() + &title + ")"))
                                 .unwrap();
            window.set(Color::rgb(255, 255, 255));
            let mut y = 0;
            for line in lines.iter() {
                line.draw(&mut window, 0, y, Color::rgb(0, 0, 0));
                y += line.height() as i32;
            }
            window.sync();
            event_loop(&mut window);
        },
        Err(err) => {
            let mut window = Window::new(-1,
                                         -1,
                                         320,
                                         32,
                                         &("Character Map (".to_string() + &title + ")"))
                                 .unwrap();
            window.set(Color::rgb(0, 0, 0));
            error_msg(&mut window, &format!("{}", err));
            window.sync();
            event_loop(&mut window);
        }
    }
}
<commit_msg>Resizable character map<commit_after>#![deny(warnings)]

extern crate orbclient;
extern crate orbfont;

use std::cmp::max;

use std::env;

use orbclient::{Color, Renderer, Window, WindowFlag, EventOption};
use orbfont::Font;

fn main() {
    let (title, font_res) = match env::args().nth(1) {
        Some(arg) => (arg.clone(), Font::from_path(&arg)),
        None => ("Default Font".to_string(), Font::find(None, None, None)),
    };

    match font_res {
        Ok(font) => {
            let lines = [
                font.render("ABCDEFGHIJK", 64.0),
                font.render("LMNOPQRSTUV", 64.0),
                font.render("WXYZabcdefg", 64.0),
                font.render("hijklmnopqr", 64.0),
                font.render("stuvwxyz.?!", 64.0),
                font.render("0123456789 ", 64.0)
            ];

            let mut width = 0;
            let mut height = 0;
            for line in lines.iter() {
                width = max(width, line.width());
                height += line.height();
            }

            let redraw = move |window: &mut Window| {
                window.set(Color::rgb(255, 255, 255));
                let mut y = 0;
                for line in lines.iter() {
                    line.draw(window, 0, y, Color::rgb(0, 0, 0));
                    y += line.height() as i32;
                }
                window.sync();
            };

            let mut window = Window::new_flags(-1, -1, max(320, width), max(32, height),
                                        &format!("{} - Character Map", title),
                                        &[WindowFlag::Resizable])
                                    .unwrap();

            redraw(&mut window);

            loop {
                for event in window.events() {
                    match event.to_option() {
                        EventOption::Resize(_) => redraw(&mut window),
                        EventOption::Quit(_) => return,
                        _ => ()
                    }
                }
            }
        },
        Err(err) => {
            let mut window = Window::new(-1, -1, 320, 32, &format!("{} - Character Map", title))
                                    .unwrap();
            window.set(Color::rgb(0, 0, 0));
            let mut x = 0;
            for c in format!("{}", err).chars() {
                window.char(x, 0, c, Color::rgb(255, 255, 255));
                x += 8;
            }
            window.sync();
            loop {
                for event in window.events() {
                    match event.to_option() {
                        EventOption::Quit(_) => return,
                        _ => ()
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate polydraw;

use std::cmp::{Ordering, min, max};
use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Section {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
   pub edge: usize,
   pub poly: usize,
}

impl Section {
   fn set_bottom(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p2 = *point;
      } else {
         self.p1 = *point;
      }
   }

   fn set_top(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p1 = *point;
      } else {
         self.p2 = *point;
      }
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   sections: Vec<Section>,
   sections_end: usize,

   sections_min_y: Vec<i64>,
   sections_max_y: Vec<i64>,
   sections_order: Vec<usize>,

   active: Vec<Section>,
   active_source: Vec<usize>,
   active_end: usize,
}

impl ClipRenderer {
   fn new() -> Self {
      let div_per_pixel = 1000;

      let mut edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      for edge in edges.iter_mut() {
         edge.p1.x *= div_per_pixel;
         edge.p1.y *= div_per_pixel;
         edge.p2.x *= div_per_pixel;
         edge.p2.y *= div_per_pixel;
      }

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let sections = create_default_vec(65536);

      let sections_min_y = create_default_vec(65536);
      let sections_max_y = create_default_vec(65536);
      let sections_order = create_default_vec(65536);

      let active = create_default_vec(65536);
      let active_source = create_default_vec(65536);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: div_per_pixel,

         edges: edges,
         polys: polys,

         sections: sections,
         sections_end: 0,

         sections_min_y: sections_min_y,
         sections_max_y: sections_max_y,
         sections_order: sections_order,

         active: active,
         active_source: active_source,
         active_end: 0,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn eval_sections_min_max_y(&mut self) {
      for section_index in 0..self.sections_end {
         let ref section = self.sections[section_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (section_min_y, section_max_y) = if section.edge_type.reversed() {
            (section.p2.y, section.p1.y)
         } else {
            (section.p1.y, section.p2.y)
         };

         if section_min_y < min_y  {
            min_y = section_min_y;
         }

         if section_max_y > max_y {
            max_y = section_max_y;
         }

         self.sections_min_y[section_index] = min_y;
         self.sections_max_y[section_index] = max_y;
         self.sections_order[section_index] = section_index;
      }

      self.sort_sections_order();

      self.iterate_sections();
   }

   fn sort_sections_order(&mut self) {
      let sections_order = &mut self.sections_order[..self.sections_end];
      let sections_min_y = &self.sections_min_y;
      let sections_max_y = &self.sections_max_y;

      sections_order.sort_by(|a, b| {
         match sections_min_y[*a].cmp(&sections_min_y[*b]) {
            Ordering::Less => Ordering::Less,
            Ordering::Greater => Ordering::Greater,
            Ordering::Equal => sections_max_y[*a].cmp(&sections_max_y[*b])
         }
      });
   }

   fn iterate_sections(&self) {
      let mut prev_y = i64::MIN;
      for order_index in 0..self.sections_end {
         let section_index = self.sections_order[order_index];
         let min_y = self.sections_min_y[section_index];

         if min_y != prev_y {
            prev_y = min_y;
         }
      }
   }

   fn transfer_sections(&mut self) {
      self.sections_end = 0;

      for poly_index in 0..self.polys.len() {
         let ref poly = self.polys[poly_index];

         for edge_index in poly.start..poly.end {
            let ref edge = self.edges[edge_index];

            self.sections[self.sections_end] = Section {
               edge_type: edge.edge_type,
               p1: edge.p1,
               p2: edge.p2,
               edge: edge_index,
               poly: poly_index,
            };

            self.sections_end += 1;
         }
      }
   }

   fn clip_sections(&mut self) {
      let sections_target = self.sections_order[0];
      let sections_clipper = self.sections_order[1];

      let active_target = self.copy_to_active(sections_target);
      let active_clipper = self.copy_to_active(sections_clipper);

      let intersection = self.intersect_sections(
         &self.active[active_target],
         &self.active[active_clipper]
      );

      match intersection {
         Some(pt) => {
            self.sections[sections_clipper].set_bottom(&pt);
            self.change_section_order(1, pt.y);

            self.sections[sections_target].set_bottom(&pt);
            self.change_section_order(0, pt.y);

            self.active[active_target].set_top(&pt);
            self.active[active_clipper].set_top(&pt);
         },
         None => {}
      }
   }

   fn copy_to_active(&mut self, sections_index: usize) -> usize {
      let active_index = self.active_end;

      self.active_source[active_index] = sections_index;
      self.active[active_index] = self.sections[sections_index];

      self.active_end += 1;

      active_index
   }

   fn change_section_order(&mut self, order_index: usize, new_min_y: i64) {
      let sections_index = self.sections_order[order_index];
      self.sections_min_y[sections_index] = new_min_y;

      let mut current_order_index = order_index;
      let mut next_order_index = order_index + 1;

      while next_order_index < self.sections_end {
         let next_index = self.sections_order[next_order_index];

         if new_min_y > self.sections_min_y[next_index] {
            self.sections_order[current_order_index] = next_index;
         } else {
            break;
         }

         current_order_index = next_order_index;
         next_order_index += 1;
      }

      if current_order_index != order_index {
         self.sections_order[current_order_index] = sections_index;
      }
   }

   fn intersect_sections(&self, s1: &Section, s2: &Section) -> Option<Point> {
      let s1_a = (s1.p2.y - s1.p1.y) as f64;
      let s1_b = (s1.p1.x - s1.p2.x) as f64;
      let s1_c = (s1.p2.x * s1.p1.y - s1.p1.x * s1.p2.y) as f64;

      let s2_a = (s2.p2.y - s2.p1.y) as f64;
      let s2_b = (s2.p1.x - s2.p2.x) as f64;
      let s2_c = (s2.p2.x * s2.p1.y - s2.p1.x * s2.p2.y) as f64;

      let denominator = s1_a * s2_b - s2_a * s1_b;

      if denominator == 0. {
         return None;
      }

      let x = (s2_c * s1_b - s1_c * s2_b) / denominator;
      let y = (s2_a * s1_c - s1_a * s2_c) / denominator;

      let x = x.round() as i64;
      let y = y.round() as i64;

      let x1 = max(min(s1.p1.x, s1.p2.x), min(s2.p1.x, s2.p2.x));
      let x2 = min(max(s1.p1.x, s1.p2.x), max(s2.p1.x, s2.p2.x));
      let y1 = max(min(s1.p1.y, s1.p2.y), min(s2.p1.y, s2.p2.y));
      let y2 = min(max(s1.p1.y, s1.p2.y), max(s2.p1.y, s2.p2.y));

      if x < x1 || x > x2 || y < y1 || y > y2 {
         return None;
      }

      return Some(Point::new(x, y));
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.transfer_sections();

      self.eval_sections_min_max_y();

      self.clip_sections();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);

      panic!("END");
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<commit_msg>Checking for correct sections order.<commit_after>extern crate polydraw;

use std::cmp::{Ordering, min, max};
use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Section {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
   pub edge: usize,
   pub poly: usize,
}

impl Section {
   fn set_bottom(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p2 = *point;
      } else {
         self.p1 = *point;
      }
   }

   fn set_top(&mut self, point: &Point) {
      if self.edge_type.reversed() {
         self.p1 = *point;
      } else {
         self.p2 = *point;
      }
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   sections: Vec<Section>,
   sections_end: usize,

   sections_min_y: Vec<i64>,
   sections_max_y: Vec<i64>,
   sections_order: Vec<usize>,

   active: Vec<Section>,
   active_source: Vec<usize>,
   active_end: usize,
}

impl ClipRenderer {
   fn new() -> Self {
      let div_per_pixel = 1000;

      let mut edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      for edge in edges.iter_mut() {
         edge.p1.x *= div_per_pixel;
         edge.p1.y *= div_per_pixel;
         edge.p2.x *= div_per_pixel;
         edge.p2.y *= div_per_pixel;
      }

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let sections = create_default_vec(65536);

      let sections_min_y = create_default_vec(65536);
      let sections_max_y = create_default_vec(65536);
      let sections_order = create_default_vec(65536);

      let active = create_default_vec(65536);
      let active_source = create_default_vec(65536);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: div_per_pixel,

         edges: edges,
         polys: polys,

         sections: sections,
         sections_end: 0,

         sections_min_y: sections_min_y,
         sections_max_y: sections_max_y,
         sections_order: sections_order,

         active: active,
         active_source: active_source,
         active_end: 0,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn eval_sections_min_max_y(&mut self) {
      for section_index in 0..self.sections_end {
         let ref section = self.sections[section_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (section_min_y, section_max_y) = if section.edge_type.reversed() {
            (section.p2.y, section.p1.y)
         } else {
            (section.p1.y, section.p2.y)
         };

         if section_min_y < min_y  {
            min_y = section_min_y;
         }

         if section_max_y > max_y {
            max_y = section_max_y;
         }

         self.sections_min_y[section_index] = min_y;
         self.sections_max_y[section_index] = max_y;
         self.sections_order[section_index] = section_index;
      }

      self.sort_sections_order();

      self.iterate_sections();
   }

   fn sort_sections_order(&mut self) {
      let sections_order = &mut self.sections_order[..self.sections_end];
      let sections_min_y = &self.sections_min_y;
      let sections_max_y = &self.sections_max_y;

      sections_order.sort_by(|a, b| {
         match sections_min_y[*a].cmp(&sections_min_y[*b]) {
            Ordering::Less => Ordering::Less,
            Ordering::Greater => Ordering::Greater,
            Ordering::Equal => sections_max_y[*a].cmp(&sections_max_y[*b])
         }
      });
   }

   fn iterate_sections(&self) {
      let mut prev_y = i64::MIN;
      for order_index in 0..self.sections_end {
         let section_index = self.sections_order[order_index];
         let min_y = self.sections_min_y[section_index];

         if min_y != prev_y {
            prev_y = min_y;
         }
      }
   }

   fn transfer_sections(&mut self) {
      self.sections_end = 0;

      for poly_index in 0..self.polys.len() {
         let ref poly = self.polys[poly_index];

         for edge_index in poly.start..poly.end {
            let ref edge = self.edges[edge_index];

            self.sections[self.sections_end] = Section {
               edge_type: edge.edge_type,
               p1: edge.p1,
               p2: edge.p2,
               edge: edge_index,
               poly: poly_index,
            };

            self.sections_end += 1;
         }
      }
   }

   fn clip_sections(&mut self) {
      let sections_target = self.sections_order[0];
      let sections_clipper = self.sections_order[1];

      let active_target = self.copy_to_active(sections_target);
      let active_clipper = self.copy_to_active(sections_clipper);

      let intersection = self.intersect_sections(
         &self.active[active_target],
         &self.active[active_clipper]
      );

      match intersection {
         Some(pt) => {
            self.sections[sections_clipper].set_bottom(&pt);
            self.change_section_order(1, pt.y);

            self.check_sections_order();

            self.sections[sections_target].set_bottom(&pt);
            self.change_section_order(0, pt.y);

            self.check_sections_order();

            self.active[active_target].set_top(&pt);
            self.active[active_clipper].set_top(&pt);
         },
         None => {}
      }
   }

   fn copy_to_active(&mut self, sections_index: usize) -> usize {
      let active_index = self.active_end;

      self.active_source[active_index] = sections_index;
      self.active[active_index] = self.sections[sections_index];

      self.active_end += 1;

      active_index
   }

   fn change_section_order(&mut self, order_index: usize, new_min_y: i64) {
      let sections_index = self.sections_order[order_index];
      self.sections_min_y[sections_index] = new_min_y;

      let mut current_order_index = order_index;
      let mut next_order_index = order_index + 1;

      while next_order_index < self.sections_end {
         let next_index = self.sections_order[next_order_index];

         if new_min_y > self.sections_min_y[next_index] {
            self.sections_order[current_order_index] = next_index;
         } else {
            break;
         }

         current_order_index = next_order_index;
         next_order_index += 1;
      }

      if current_order_index != order_index {
         self.sections_order[current_order_index] = sections_index;
      }
   }

   fn intersect_sections(&self, s1: &Section, s2: &Section) -> Option<Point> {
      let s1_a = (s1.p2.y - s1.p1.y) as f64;
      let s1_b = (s1.p1.x - s1.p2.x) as f64;
      let s1_c = (s1.p2.x * s1.p1.y - s1.p1.x * s1.p2.y) as f64;

      let s2_a = (s2.p2.y - s2.p1.y) as f64;
      let s2_b = (s2.p1.x - s2.p2.x) as f64;
      let s2_c = (s2.p2.x * s2.p1.y - s2.p1.x * s2.p2.y) as f64;

      let denominator = s1_a * s2_b - s2_a * s1_b;

      if denominator == 0. {
         return None;
      }

      let x = (s2_c * s1_b - s1_c * s2_b) / denominator;
      let y = (s2_a * s1_c - s1_a * s2_c) / denominator;

      let x = x.round() as i64;
      let y = y.round() as i64;

      let x1 = max(min(s1.p1.x, s1.p2.x), min(s2.p1.x, s2.p2.x));
      let x2 = min(max(s1.p1.x, s1.p2.x), max(s2.p1.x, s2.p2.x));
      let y1 = max(min(s1.p1.y, s1.p2.y), min(s2.p1.y, s2.p2.y));
      let y2 = min(max(s1.p1.y, s1.p2.y), max(s2.p1.y, s2.p2.y));

      if x < x1 || x > x2 || y < y1 || y > y2 {
         return None;
      }

      return Some(Point::new(x, y));
   }

   fn check_sections_order(&self) {
      let mut prev_y = i64::MIN;

      for order_index in 0..self.sections_end {
         let section_index = self.sections_order[order_index];
         let min_y = self.sections_min_y[section_index];

         if min_y < prev_y {
            panic!("Wrong sections order");
         }

         prev_y = min_y;
      }
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.transfer_sections();

      self.eval_sections_min_max_y();

      self.clip_sections();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);

      panic!("END");
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<|endoftext|>


<commit_before>//! Interfaces and implementations for directed graphs.
//!
//! This module provides a set of interfaces and implementations of software
//! components for graph representations.  Ergonomics and composability are the
//! main goals here.
//!
//! We would like a graph representation that gives us both fast traversal and
//! fast analysis, and whose API allows for efficient *and* ergonomic use.
//! Naturally there is no best fit, but we can achieve a good fit using
//! a variant of the adjacency-list pattern.
//!
//! Our implementation is based on that of the `petgraph` crate.  Here,
//! however, each node contains space-optimized vectors of outgoing and
//! incoming edges.
//!
//!

mod common;
pub mod iter;
pub mod interface;
pub mod visit;

pub use self::common::{EdgeIndex,NodeIndex,AdjacencyList};
pub use self::weighted::{Edge as WeightedEdge, Node as WeightedNode};
pub use self::interface::{Id,Edge,Node,Graph};

/// Simple data-bearing directed graph.  `N` determines the type of data
/// attached to nodes, `E` the type attached to edges, and `Ix` the integer
/// type used to identify nodes and edges.
pub type WeightedGraph<N, E, Ix = common::DefaultIndexType> = AdjacencyList<WeightedNode<N, EdgeIndex<Ix>>, WeightedEdge<E, NodeIndex<Ix>>>;

/// Unweighted directed graph.  `Ix` determines the integer type used to
/// identify nodes and edges.
pub type BasicGraph<Ix = common::DefaultIndexType> = AdjacencyList<basic::Node<EdgeIndex<Ix>>, basic::Edge<NodeIndex<Ix>>>;

/// Produce `impl` items on some trait for several structurally-identical types.
macro_rules! impl_basic_edge {
    ($I: ident) => {
        type NodeId = $I;
        #[inline(always)]
        fn source(&self) -> I { self.source }
        #[inline(always)]
        fn target(&self) -> I { self.target }
    }
}

macro_rules! impl_basic_node {
    ($I: ident) => {
        type EdgeId = $I;
        #[inline(always)]
        fn incoming_edges(&self) -> std::slice::Iter<$I> {
            self.incoming_edges.iter()
        }

        fn incoming_edge_count(&self) -> usize {
            self.incoming_edges.len()
        }

        #[inline(always)]
        fn outgoing_edges(&self) -> std::slice::Iter<$I> {
            self.outgoing_edges.iter()
        }

        fn outgoing_edge_count(&self) -> usize {
            self.outgoing_edges.len()
        }

        #[inline(always)]
        fn add_incoming_edge(&mut self, e: $I) {
            self.incoming_edges.push(e);
        }

        #[inline(always)]
        fn add_outgoing_edge(&mut self, e: $I) {
            self.outgoing_edges.push(e);
        }
    }
}

pub mod weighted;
pub mod basic;
<commit_msg>util/graph/mod.rs: fix/add doc comments on internal macros<commit_after>//! Interfaces and implementations for directed graphs.
//!
//! This module provides a set of interfaces and implementations of software
//! components for graph representations.  Ergonomics and composability are the
//! main goals here.
//!
//! We would like a graph representation that gives us both fast traversal and
//! fast analysis, and whose API allows for efficient *and* ergonomic use.
//! Naturally there is no best fit, but we can achieve a good fit using
//! a variant of the adjacency-list pattern.
//!
//! Our implementation is based on that of the `petgraph` crate.  Here,
//! however, each node contains space-optimized vectors of outgoing and
//! incoming edges.
//!
//!

mod common;
pub mod iter;
pub mod interface;
pub mod visit;

pub use self::common::{EdgeIndex,NodeIndex,AdjacencyList};
pub use self::weighted::{Edge as WeightedEdge, Node as WeightedNode};
pub use self::interface::{Id,Edge,Node,Graph};

/// Simple data-bearing directed graph.  `N` determines the type of data
/// attached to nodes, `E` the type attached to edges, and `Ix` the integer
/// type used to identify nodes and edges.
pub type WeightedGraph<N, E, Ix = common::DefaultIndexType> = AdjacencyList<WeightedNode<N, EdgeIndex<Ix>>, WeightedEdge<E, NodeIndex<Ix>>>;

/// Unweighted directed graph.  `Ix` determines the integer type used to
/// identify nodes and edges.
pub type BasicGraph<Ix = common::DefaultIndexType> = AdjacencyList<basic::Node<EdgeIndex<Ix>>, basic::Edge<NodeIndex<Ix>>>;

/// Implement `interface::Edge` for a type with members
/// `source: $I` and `target: $I`.
macro_rules! impl_basic_edge {
    ($I: ident) => {
        type NodeId = $I;
        #[inline(always)]
        fn source(&self) -> I { self.source }
        #[inline(always)]
        fn target(&self) -> I { self.target }
    }
}

/// Implement `interface::Node` for a type with members `incoming_edges` and
/// `outgoing_edges` of types compatible with `Vec<$I>`.
macro_rules! impl_basic_node {
    ($I: ident) => {
        type EdgeId = $I;
        #[inline(always)]
        fn incoming_edges(&self) -> std::slice::Iter<$I> {
            self.incoming_edges.iter()
        }

        fn incoming_edge_count(&self) -> usize {
            self.incoming_edges.len()
        }

        #[inline(always)]
        fn outgoing_edges(&self) -> std::slice::Iter<$I> {
            self.outgoing_edges.iter()
        }

        fn outgoing_edge_count(&self) -> usize {
            self.outgoing_edges.len()
        }

        #[inline(always)]
        fn add_incoming_edge(&mut self, e: $I) {
            self.incoming_edges.push(e);
        }

        #[inline(always)]
        fn add_outgoing_edge(&mut self, e: $I) {
            self.outgoing_edges.push(e);
        }
    }
}

pub mod weighted;
pub mod basic;
<|endoftext|>


<commit_before>use std::fmt;

// Following code is modified from
// https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/escape.rs
//
// Escape type and impl fmt::Display is:
//
// Copyright 2013 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 struct Escape<'a>(pub &'a str);

impl<'a> fmt::Display for Escape<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Escape(s) = *self;
        let pile_o_bits = s;
        let mut last = 0;
        for (i, ch) in s.bytes().enumerate() {
            match ch as char {
                // TODO: Verify escaping (\") is neccesary?
                /// It should escape aginst special characters (\n, \\)
                /// for creating command line style command.
                '\n' | '\\'  => {
                    try!(fmt.write_str(&pile_o_bits[last.. i]));
                    let s = match ch as char {
                        '\n' => "\\n",
                        '\\' => "\\\\",
                        _ => unreachable!()
                    };
                    try!(fmt.write_str(s));
                    last = i + 1;
                }
                _ => {}
            }
        }

        if last < s.len() {
            try!(fmt.write_str(&pile_o_bits[last..]));
        }
        Ok(())
    }
}

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

    #[test]
    fn test_fmt() {
        assert_eq!("\\n", format!("{}", Escape("\n")));
        assert_eq!("\\\\", format!("{}", Escape("\\")));
    }
}
<commit_msg>rustfmt<commit_after>use std::fmt;

// Following code is modified from
// https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/escape.rs
//
// Escape type and impl fmt::Display is:
//
// Copyright 2013 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 struct Escape<'a>(pub &'a str);

impl<'a> fmt::Display for Escape<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Escape(s) = *self;
        let pile_o_bits = s;
        let mut last = 0;
        for (i, ch) in s.bytes().enumerate() {
            match ch as char {
                // TODO: Verify escaping (\") is neccesary?
                /// It should escape aginst special characters (\n, \\)
                /// for creating command line style command.
                '\n' | '\\' => {
                    try!(fmt.write_str(&pile_o_bits[last..i]));
                    let s = match ch as char {
                        '\n' => "\\n",
                        '\\' => "\\\\",
                        _ => unreachable!(),
                    };
                    try!(fmt.write_str(s));
                    last = i + 1;
                }
                _ => {}
            }
        }

        if last < s.len() {
            try!(fmt.write_str(&pile_o_bits[last..]));
        }
        Ok(())
    }
}

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

    #[test]
    fn test_fmt() {
        assert_eq!("\\n", format!("{}", Escape("\n")));
        assert_eq!("\\\\", format!("{}", Escape("\\")));
    }
}
<|endoftext|>


<commit_before>#![ cfg_attr( not( feature = "use_std" ), no_std ) ]
#![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ]
#![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ]
#![ doc( html_root_url = "https://docs.rs/derive_tools/latest/derive_tools/" ) ]
#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( trait_alias ) ]
// #![ feature( type_name_of_val ) ]

//!
//! Collection of derives which extend STD.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/// Internal namespace.
pub( crate ) mod private
{
}

/// Dependencies.
pub mod dependencies
{
  pub use ::derive_more;
  pub use ::parse_display;
  pub use ::clone_dyn;
}

/// Protected namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::orphan::*;
}

#[ doc( inline ) ]
pub use protected::*;

/// Orphan namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use ::derive_more::*;

  #[ cfg( feature = "derive_display" ) ]
  pub use ::parse_display::Display;

  #[ cfg( feature = "derive_from_str" ) ]
  pub use ::parse_display::FromStr;

  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::exposed::*;

}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{

  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::prelude::*;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::clone_dyn;

}
<commit_msg>Fix module `derive_tools`, reexport optional modules under features<commit_after>#![ cfg_attr( not( feature = "use_std" ), no_std ) ]
#![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ]
#![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ]
#![ doc( html_root_url = "https://docs.rs/derive_tools/latest/derive_tools/" ) ]
#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( trait_alias ) ]
// #![ feature( type_name_of_val ) ]

//!
//! Collection of derives which extend STD.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/// Internal namespace.
pub( crate ) mod private
{
}

/// Dependencies.
pub mod dependencies
{
  pub use ::derive_more;
  #[ cfg( feature = "parse_display" ) ]
  pub use ::parse_display;
  #[ cfg( feature = "clone_dyn" ) ]
  pub use ::clone_dyn;
}

/// Protected namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::orphan::*;
}

#[ doc( inline ) ]
pub use protected::*;

/// Orphan namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use ::derive_more::*;

  #[ cfg( feature = "derive_display" ) ]
  pub use ::parse_display::Display;

  #[ cfg( feature = "derive_from_str" ) ]
  pub use ::parse_display::FromStr;

  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::exposed::*;

}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{

  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::prelude::*;
  #[ cfg( feature = "derive_clone_dyn" ) ]
  pub use ::clone_dyn::clone_dyn;

}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::net::{Ipv4Addr, SocketAddr};
use std::io;
use std::rc::{Rc, Weak};
use mio::{Event, PollOpt, Ready};
use mio::tcp::TcpListener;

use super::binary;
use super::client::Client;
use super::selector::{EventHandler, Selector};

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

pub struct TunnelServer {
    self_weak: Weak<RefCell<TunnelServer>>,
    clients: Vec<Rc<RefCell<Client>>>,
    tcp_listener: TcpListener,
    next_client_id: u32,
}

impl TunnelServer {
    pub fn new(port: u16, selector: &mut Selector) -> io::Result<Rc<RefCell<Self>>> {
        let tcp_listener = TunnelServer::start_socket(port)?;
        let rc = Rc::new(RefCell::new(Self {
            self_weak: Weak::new(),
            clients: Vec::new(),
            tcp_listener: tcp_listener,
            next_client_id: 0,
        }));

        // keep a shared reference to this
        rc.borrow_mut().self_weak = Rc::downgrade(&rc);

        // rc is an EventHandler, register() expects a Box<EventHandler>
        let handler = Box::new(rc.clone());
        selector.register(
            &rc.borrow().tcp_listener,
            handler,
            Ready::readable(),
            PollOpt::edge(),
        )?;
        Ok(rc)
    }

    fn start_socket(port: u16) -> io::Result<TcpListener> {
        let localhost = Ipv4Addr::new(127, 0, 0, 1).into();
        let addr = SocketAddr::new(localhost, port);
        let server = TcpListener::bind(&addr)?;
        Ok(server)
    }

    fn accept_client(&mut self, selector: &mut Selector) -> io::Result<()> {
        let (stream, _) = self.tcp_listener.accept()?;
        let client_id = self.next_client_id;
        self.next_client_id += 1;
        let weak = self.self_weak.clone();
        let on_client_closed = Box::new(move |client: &Client| if let Some(rc) = weak.upgrade() {
            let mut tunnel_server = rc.borrow_mut();
            tunnel_server.remove_client(client);
        } else {
            warn!(
                target: TAG,
                "on_client_closed called but no client available"
            );
        });
        let client = Client::new(client_id, selector, stream, on_client_closed)?;
        self.clients.push(client);
        info!(target: TAG, "Client #{} connected", client_id);
        Ok(())
    }

    fn remove_client(&mut self, client: &Client) {
        info!(target: TAG, "Client #{} disconnected", client.id());
        let index = self.clients
            .iter()
            .position(|item| {
                // compare pointers to find the client to remove
                binary::ptr_eq(client, item.as_ptr())
            })
            .expect("Trying to remove an unknown client");
        self.clients.swap_remove(index);
    }

    pub fn clean_up(&mut self, selector: &mut Selector) {
        for client in &self.clients {
            client.borrow_mut().clean_expired_connections(selector);
        }
    }
}

impl EventHandler for TunnelServer {
    fn on_ready(&mut self, selector: &mut Selector, _: Event) {
        if let Err(err) = self.accept_client(selector) {
            error!(target: TAG, "Cannot accept client: {}", err);
        }
    }
}
<commit_msg>Use Self to call static methods<commit_after>use std::cell::RefCell;
use std::net::{Ipv4Addr, SocketAddr};
use std::io;
use std::rc::{Rc, Weak};
use mio::{Event, PollOpt, Ready};
use mio::tcp::TcpListener;

use super::binary;
use super::client::Client;
use super::selector::{EventHandler, Selector};

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

pub struct TunnelServer {
    self_weak: Weak<RefCell<TunnelServer>>,
    clients: Vec<Rc<RefCell<Client>>>,
    tcp_listener: TcpListener,
    next_client_id: u32,
}

impl TunnelServer {
    pub fn new(port: u16, selector: &mut Selector) -> io::Result<Rc<RefCell<Self>>> {
        let tcp_listener = Self::start_socket(port)?;
        let rc = Rc::new(RefCell::new(Self {
            self_weak: Weak::new(),
            clients: Vec::new(),
            tcp_listener: tcp_listener,
            next_client_id: 0,
        }));

        // keep a shared reference to this
        rc.borrow_mut().self_weak = Rc::downgrade(&rc);

        // rc is an EventHandler, register() expects a Box<EventHandler>
        let handler = Box::new(rc.clone());
        selector.register(
            &rc.borrow().tcp_listener,
            handler,
            Ready::readable(),
            PollOpt::edge(),
        )?;
        Ok(rc)
    }

    fn start_socket(port: u16) -> io::Result<TcpListener> {
        let localhost = Ipv4Addr::new(127, 0, 0, 1).into();
        let addr = SocketAddr::new(localhost, port);
        let server = TcpListener::bind(&addr)?;
        Ok(server)
    }

    fn accept_client(&mut self, selector: &mut Selector) -> io::Result<()> {
        let (stream, _) = self.tcp_listener.accept()?;
        let client_id = self.next_client_id;
        self.next_client_id += 1;
        let weak = self.self_weak.clone();
        let on_client_closed = Box::new(move |client: &Client| if let Some(rc) = weak.upgrade() {
            let mut tunnel_server = rc.borrow_mut();
            tunnel_server.remove_client(client);
        } else {
            warn!(
                target: TAG,
                "on_client_closed called but no client available"
            );
        });
        let client = Client::new(client_id, selector, stream, on_client_closed)?;
        self.clients.push(client);
        info!(target: TAG, "Client #{} connected", client_id);
        Ok(())
    }

    fn remove_client(&mut self, client: &Client) {
        info!(target: TAG, "Client #{} disconnected", client.id());
        let index = self.clients
            .iter()
            .position(|item| {
                // compare pointers to find the client to remove
                binary::ptr_eq(client, item.as_ptr())
            })
            .expect("Trying to remove an unknown client");
        self.clients.swap_remove(index);
    }

    pub fn clean_up(&mut self, selector: &mut Selector) {
        for client in &self.clients {
            client.borrow_mut().clean_expired_connections(selector);
        }
    }
}

impl EventHandler for TunnelServer {
    fn on_ready(&mut self, selector: &mut Selector, _: Event) {
        if let Err(err) = self.accept_client(selector) {
            error!(target: TAG, "Cannot accept client: {}", err);
        }
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
use std::marker::PhantomData;
use std::collections::VecDeque;

use progress::Timestamp;
use communication::Data;
use communication::{Communicator, Pullable, Pushable, Observer};
use communication::observer::ExchangeObserver;

use abomonation::Abomonation;

// A ParallelizationContract transforms the output of a Communicator, a (Vec<Pushable>, Pullable),
// to an (Observer, Pullable).
pub trait ParallelizationContract<T: Timestamp, D: Data> {
    type Observer: Observer<Time=T, Data=D>+'static;
    type Pullable: Pullable<(T, Vec<D>)>+'static;
    fn connect<C: Communicator>(self, communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>);
}

// direct connection
pub struct Pipeline;
impl<T: Timestamp, D: Data> ParallelizationContract<T, D> for Pipeline {
    type Observer = PactObserver<T, D, Rc<RefCell<VecDeque<(T, Vec<D>)>>>>;
    type Pullable = Rc<RefCell<VecDeque<(T, Vec<D>)>>>;
    fn connect<C: Communicator>(self,_communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>) {
        let shared1 = Rc::new(RefCell::new(VecDeque::new()));
        let shared2 = Rc::new(RefCell::new(Vec::new()));
        return (PactObserver::new(shared1.clone(), shared2.clone()), PactPullable::new(shared1, shared2));
    }
}

// exchanges between multiple observers
pub struct Exchange<D, F: Fn(&D)->u64> { hash_func: F, phantom: PhantomData<D>, }
impl<D, F: Fn(&D)->u64> Exchange<D, F> {
    pub fn new(func: F) -> Exchange<D, F> {
        Exchange {
            hash_func:  func,
            phantom:    PhantomData,
        }
    }
}

// Exchange uses a Box<Pushable> because it cannot know what type of pushable will return from the communicator.
// The PactObserver will do some buffering for Exchange, cutting down on the virtual calls, but we still
// would like to get the vectors it sends back, so that they can be re-used if possible.
impl<T: Timestamp, D: Data+Abomonation, F: Fn(&D)->u64+'static> ParallelizationContract<T, D> for Exchange<D, F> {
    type Observer = ExchangeObserver<PactObserver<T, D, Box<Pushable<(T, Vec<D>)>>>, F>;
    type Pullable = Box<Pullable<(T, Vec<D>)>>;
    fn connect<C: Communicator>(self, communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>) {
        let (senders, receiver) = communicator.new_channel();
        let shared = Rc::new(RefCell::new(Vec::new()));
        let exchange_sender = ExchangeObserver::new(senders.into_iter().map(|x| PactObserver::new(x, shared.clone())).collect(), self.hash_func);
        return (exchange_sender, PactPullable::new(receiver, shared));
    }
}

pub struct PactPullable<T:Send, D:Send+Clone, P: Pullable<(T, Vec<D>)>> {
    pullable: P,
    buffer:   Vec<D>,
    shared:   Rc<RefCell<Vec<Vec<D>>>>,
    phantom:  PhantomData<T>,
}

impl<T:Send, D: Send+Clone, P: Pullable<(T, Vec<D>)>> PactPullable<T, D, P> {
    // this method is repeatedly called by worker logic.
    // we want to clean up prior data in any way needed,
    // for example recycling any remaining elements and
    // pushing the buffer into self.shared.
    pub fn pull(&mut self) -> Option<(T, &mut Vec<D>)> {
        assert!(self.buffer.len() == 0);                // TODO : this is pretty hard core ...
        if let Some((time, mut data)) = self.pullable.pull() {
            if data.len() > 0 {
                mem::swap(&mut data, &mut self.buffer); // install buffer
                assert!(data.capacity() == 256);
                self.shared.borrow_mut().push(data);    // TODO : determine sane buffering strategy
                Some((time, &mut self.buffer))
            } else { None }
        } else { None }
    }
    fn new(pullable: P, shared: Rc<RefCell<Vec<Vec<D>>>>) -> PactPullable<T, D, P> {
        PactPullable {
            pullable: pullable,
            buffer:   Vec::with_capacity(256),
            shared:   shared,
            phantom:  PhantomData,
        }
    }
}

pub struct PactObserver<T:Send, D:Send+Clone, P: Pushable<(T, Vec<D>)>> {
    pub pushable:   P,
    shared:         Rc<RefCell<Vec<Vec<D>>>>,
    current_time:   Option<T>,
}

impl<T:Send, D:Send+Clone, P: Pushable<(T, Vec<D>)>> PactObserver<T, D, P> {
    pub fn new(pushable: P, shared: Rc<RefCell<Vec<Vec<D>>>>) -> PactObserver<T, D, P> {
        PactObserver {
            pushable: pushable,
            shared: shared,
            current_time: None,
        }
    }
}

impl<T:Send+Clone, D:Send+Clone, P: Pushable<(T, Vec<D>)>> Observer for PactObserver<T,D,P> {
    type Time = T;
    type Data = D;
    #[inline] fn open(&mut self, time: &T) {
        assert!(self.current_time.is_none());
        self.current_time = Some(time.clone());
    }
    #[inline] fn shut(&mut self,_time: &T) {
        assert!(self.current_time.is_some());
        self.current_time = None;

        // we've just been shut; if there are spare shared buffers, we might return some of them
        if self.shared.borrow().len() > 0 {
            let len = self.shared.borrow().len();
            self.shared.borrow_mut().truncate(len / 2);
        }
    }
    #[inline] fn give(&mut self, data: &mut Vec<D>) {
        if let Some(time) = self.current_time.clone() {
            let empty = self.shared.borrow_mut().pop().unwrap_or_else(|| Vec::with_capacity(256));
            assert!(empty.len() == 0);
            assert!(empty.capacity() == 256);
            self.pushable.push((time, mem::replace(data, empty)));
        }
        else {
            panic!("PactObserver: self.give() with unset self.current_time");
        }
    }
}

// broadcasts to all observers
// TODO : This needs support from the progress tracking protocol;
// TODO : we don't know/report how many messages are actually created.
// pub struct Broadcast;
// impl<T: Timestamp, D: Data+Columnar> ParallelizationContract<T, D> for Broadcast {
//     type Observer = BroadcastObserver<PushableObserver<T,D,Box<Pushable<(T,Vec<D>)>>>>;
//     type Pullable = Box<Pullable<(T, Vec<D>)>>;
//     fn connect<C: Communicator>(self, communicator: &mut C) -> (<Broadcast as ParallelizationContract<T, D>>::Observer,
//                                                                 <Broadcast as ParallelizationContract<T, D>>::Pullable) {
//         let (senders, receiver) = communicator.new_channel();
//
//         let exchange_sender = BroadcastObserver {
//             observers:  senders.into_iter().map(|x| PushableObserver { data: Vec::new(), pushable: x, phantom: PhantomData }).collect()
//         };
//
//         panic!("Broadcast won't work until progress counting becomes aware of how many records are sent");
//
//         return (exchange_sender, receiver);
//     }
// }
<commit_msg>too aggressive capacity demands (failed w/deserialization)<commit_after>use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
use std::marker::PhantomData;
use std::collections::VecDeque;

use progress::Timestamp;
use communication::Data;
use communication::{Communicator, Pullable, Pushable, Observer};
use communication::observer::ExchangeObserver;

use abomonation::Abomonation;

// A ParallelizationContract transforms the output of a Communicator, a (Vec<Pushable>, Pullable),
// to an (Observer, Pullable).
pub trait ParallelizationContract<T: Timestamp, D: Data> {
    type Observer: Observer<Time=T, Data=D>+'static;
    type Pullable: Pullable<(T, Vec<D>)>+'static;
    fn connect<C: Communicator>(self, communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>);
}

// direct connection
pub struct Pipeline;
impl<T: Timestamp, D: Data> ParallelizationContract<T, D> for Pipeline {
    type Observer = PactObserver<T, D, Rc<RefCell<VecDeque<(T, Vec<D>)>>>>;
    type Pullable = Rc<RefCell<VecDeque<(T, Vec<D>)>>>;
    fn connect<C: Communicator>(self,_communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>) {
        let shared1 = Rc::new(RefCell::new(VecDeque::new()));
        let shared2 = Rc::new(RefCell::new(Vec::new()));
        return (PactObserver::new(shared1.clone(), shared2.clone()), PactPullable::new(shared1, shared2));
    }
}

// exchanges between multiple observers
pub struct Exchange<D, F: Fn(&D)->u64> { hash_func: F, phantom: PhantomData<D>, }
impl<D, F: Fn(&D)->u64> Exchange<D, F> {
    pub fn new(func: F) -> Exchange<D, F> {
        Exchange {
            hash_func:  func,
            phantom:    PhantomData,
        }
    }
}

// Exchange uses a Box<Pushable> because it cannot know what type of pushable will return from the communicator.
// The PactObserver will do some buffering for Exchange, cutting down on the virtual calls, but we still
// would like to get the vectors it sends back, so that they can be re-used if possible.
impl<T: Timestamp, D: Data+Abomonation, F: Fn(&D)->u64+'static> ParallelizationContract<T, D> for Exchange<D, F> {
    type Observer = ExchangeObserver<PactObserver<T, D, Box<Pushable<(T, Vec<D>)>>>, F>;
    type Pullable = Box<Pullable<(T, Vec<D>)>>;
    fn connect<C: Communicator>(self, communicator: &mut C) -> (Self::Observer, PactPullable<T, D, Self::Pullable>) {
        let (senders, receiver) = communicator.new_channel();
        let shared = Rc::new(RefCell::new(Vec::new()));
        let exchange_sender = ExchangeObserver::new(senders.into_iter().map(|x| PactObserver::new(x, shared.clone())).collect(), self.hash_func);
        return (exchange_sender, PactPullable::new(receiver, shared));
    }
}

pub struct PactPullable<T:Send, D:Send+Clone, P: Pullable<(T, Vec<D>)>> {
    pullable: P,
    buffer:   Vec<D>,
    shared:   Rc<RefCell<Vec<Vec<D>>>>,
    phantom:  PhantomData<T>,
}

impl<T:Send, D: Send+Clone, P: Pullable<(T, Vec<D>)>> PactPullable<T, D, P> {
    // this method is repeatedly called by worker logic.
    // we want to clean up prior data in any way needed,
    // for example recycling any remaining elements and
    // pushing the buffer into self.shared.
    pub fn pull(&mut self) -> Option<(T, &mut Vec<D>)> {
        assert!(self.buffer.len() == 0);                // TODO : this is pretty hard core ...
        if let Some((time, mut data)) = self.pullable.pull() {
            if data.len() > 0 {
                mem::swap(&mut data, &mut self.buffer); // install buffer
                self.shared.borrow_mut().push(data);    // TODO : determine sane buffering strategy
                Some((time, &mut self.buffer))
            } else { None }
        } else { None }
    }
    fn new(pullable: P, shared: Rc<RefCell<Vec<Vec<D>>>>) -> PactPullable<T, D, P> {
        PactPullable {
            pullable: pullable,
            buffer:   Vec::with_capacity(256),
            shared:   shared,
            phantom:  PhantomData,
        }
    }
}

pub struct PactObserver<T:Send, D:Send+Clone, P: Pushable<(T, Vec<D>)>> {
    pub pushable:   P,
    shared:         Rc<RefCell<Vec<Vec<D>>>>,
    current_time:   Option<T>,
}

impl<T:Send, D:Send+Clone, P: Pushable<(T, Vec<D>)>> PactObserver<T, D, P> {
    pub fn new(pushable: P, shared: Rc<RefCell<Vec<Vec<D>>>>) -> PactObserver<T, D, P> {
        PactObserver {
            pushable: pushable,
            shared: shared,
            current_time: None,
        }
    }
}

impl<T:Send+Clone, D:Send+Clone, P: Pushable<(T, Vec<D>)>> Observer for PactObserver<T,D,P> {
    type Time = T;
    type Data = D;
    #[inline] fn open(&mut self, time: &T) {
        assert!(self.current_time.is_none());
        self.current_time = Some(time.clone());
    }
    #[inline] fn shut(&mut self,_time: &T) {
        assert!(self.current_time.is_some());
        self.current_time = None;

        // we've just been shut; if there are spare shared buffers, we might return some of them
        if self.shared.borrow().len() > 0 {
            let len = self.shared.borrow().len();
            self.shared.borrow_mut().truncate(len / 2);
        }
    }
    #[inline] fn give(&mut self, data: &mut Vec<D>) {
        if let Some(time) = self.current_time.clone() {
            let empty = self.shared.borrow_mut().pop().unwrap_or_else(|| Vec::with_capacity(256));
            assert!(empty.len() == 0);
            // assert!(empty.capacity() == 256);
            self.pushable.push((time, mem::replace(data, empty)));
        }
        else {
            panic!("PactObserver: self.give() with unset self.current_time");
        }
    }
}

// broadcasts to all observers
// TODO : This needs support from the progress tracking protocol;
// TODO : we don't know/report how many messages are actually created.
// pub struct Broadcast;
// impl<T: Timestamp, D: Data+Columnar> ParallelizationContract<T, D> for Broadcast {
//     type Observer = BroadcastObserver<PushableObserver<T,D,Box<Pushable<(T,Vec<D>)>>>>;
//     type Pullable = Box<Pullable<(T, Vec<D>)>>;
//     fn connect<C: Communicator>(self, communicator: &mut C) -> (<Broadcast as ParallelizationContract<T, D>>::Observer,
//                                                                 <Broadcast as ParallelizationContract<T, D>>::Pullable) {
//         let (senders, receiver) = communicator.new_channel();
//
//         let exchange_sender = BroadcastObserver {
//             observers:  senders.into_iter().map(|x| PushableObserver { data: Vec::new(), pushable: x, phantom: PhantomData }).collect()
//         };
//
//         panic!("Broadcast won't work until progress counting becomes aware of how many records are sent");
//
//         return (exchange_sender, receiver);
//     }
// }
<|endoftext|>


<commit_before>extern crate std;
extern crate hmacsha1;

use std::fs::File;

pub struct Game {
    file: std::fs::File,
}

impl Game {
    pub fn new () -> Game {
        std::fs::create_dir("game");
        let mut f = File::create("game/game.log");
        if !f.is_ok() { panic!("cannot create game log") }

        Game { file: f.unwrap() }
    }

}
<commit_msg>squelch warnings<commit_after>#![allow(dead_code)]
#![allow(unused_must_use)]

extern crate std;
extern crate hmacsha1;

use std::fs::File;

pub struct Game {
    file: std::fs::File,
}

impl Game {
    pub fn new () -> Game {
        std::fs::create_dir("game");
        let f = File::create("game/game.log");
        if !f.is_ok() { panic!("cannot create game log") }

        Game { file: f.unwrap() }
    }

}
<|endoftext|>


<commit_before>use crate::{
    core::worley::*,
    math::vectors::*,
    noise_fns::{NoiseFn, Seedable},
    permutationtable::PermutationTable,
};
use alloc::boxed::Box;

/// Noise function that outputs Worley noise.
pub struct Worley {
    /// Specifies the distance function to use when calculating the boundaries of
    /// the cell.
    pub distance_function: Box<DistanceFunction>,

    /// Signifies whether the distance from the borders of the cell should be returned, or the
    /// value for the cell.
    pub return_type: ReturnType,

    /// Frequency of the seed points.
    pub frequency: f64,

    seed: u32,
    perm_table: PermutationTable,
}

type DistanceFunction = dyn Fn(&[f64], &[f64]) -> f64;

impl Worley {
    pub const DEFAULT_SEED: u32 = 0;
    pub const DEFAULT_FREQUENCY: f64 = 1.0;

    pub fn new(seed: u32) -> Self {
        Self {
            perm_table: PermutationTable::new(seed),
            seed,
            distance_function: Box::new(distance_functions::euclidean),
            return_type: ReturnType::Value,
            frequency: Self::DEFAULT_FREQUENCY,
        }
    }

    /// Sets the distance function used by the Worley cells.
    pub fn set_distance_function<F>(self, function: F) -> Self
    where
        F: Fn(&[f64], &[f64]) -> f64 + 'static,
    {
        Self {
            distance_function: Box::new(function),
            ..self
        }
    }

    /// Enables or disables applying the distance from the nearest seed point
    /// to the output value.
    pub fn set_return_type(self, return_type: ReturnType) -> Self {
        Self {
            return_type,
            ..self
        }
    }

    /// Sets the frequency of the seed points.
    pub fn set_frequency(self, frequency: f64) -> Self {
        Self { frequency, ..self }
    }
}

impl Default for Worley {
    fn default() -> Self {
        Self::new(0)
    }
}

impl Seedable for Worley {
    /// Sets the seed value used by the Worley cells.
    fn set_seed(self, seed: u32) -> Self {
        // If the new seed is the same as the current seed, just return self.
        if self.seed == seed {
            return self;
        }

        // Otherwise, regenerate the permutation table based on the new seed.
        Self {
            perm_table: PermutationTable::new(seed),
            seed,
            ..self
        }
    }

    fn seed(&self) -> u32 {
        self.seed
    }
}

impl NoiseFn<f64, 2> for Worley {
    fn get(&self, point: [f64; 2]) -> f64 {
        worley_2d(
            &self.perm_table,
            &self.distance_function,
            self.return_type,
            (Vector2::from(point) * self.frequency).into_array(),
        )
    }
}

impl NoiseFn<f64, 3> for Worley {
    fn get(&self, point: [f64; 3]) -> f64 {
        worley_3d(
            &self.perm_table,
            &self.distance_function,
            self.return_type,
            (Vector3::from(point) * self.frequency).into_array(),
        )
    }
}

#[allow(clippy::cognitive_complexity)]
impl NoiseFn<f64, 4> for Worley {
    fn get(&self, point: [f64; 4]) -> f64 {
        worley_4d(
            &self.perm_table,
            &self.distance_function,
            self.return_type,
            (Vector4::from(point) * self.frequency).into_array(),
        )
    }
}
<commit_msg>Allow Worley noise to be cloned<commit_after>use crate::{
    core::worley::*,
    math::vectors::*,
    noise_fns::{NoiseFn, Seedable},
    permutationtable::PermutationTable,
};
use alloc::rc::Rc;

/// Noise function that outputs Worley noise.
#[derive(Clone)]
pub struct Worley {
    /// Specifies the distance function to use when calculating the boundaries of
    /// the cell.
    pub distance_function: Rc<DistanceFunction>,

    /// Signifies whether the distance from the borders of the cell should be returned, or the
    /// value for the cell.
    pub return_type: ReturnType,

    /// Frequency of the seed points.
    pub frequency: f64,

    seed: u32,
    perm_table: PermutationTable,
}

type DistanceFunction = dyn Fn(&[f64], &[f64]) -> f64;

impl Worley {
    pub const DEFAULT_SEED: u32 = 0;
    pub const DEFAULT_FREQUENCY: f64 = 1.0;

    pub fn new(seed: u32) -> Self {
        Self {
            perm_table: PermutationTable::new(seed),
            seed,
            distance_function: Rc::new(distance_functions::euclidean),
            return_type: ReturnType::Value,
            frequency: Self::DEFAULT_FREQUENCY,
        }
    }

    /// Sets the distance function used by the Worley cells.
    pub fn set_distance_function<F>(self, function: F) -> Self
    where
        F: Fn(&[f64], &[f64]) -> f64 + 'static,
    {
        Self {
            distance_function: Rc::new(function),
            ..self
        }
    }

    /// Enables or disables applying the distance from the nearest seed point
    /// to the output value.
    pub fn set_return_type(self, return_type: ReturnType) -> Self {
        Self {
            return_type,
            ..self
        }
    }

    /// Sets the frequency of the seed points.
    pub fn set_frequency(self, frequency: f64) -> Self {
        Self { frequency, ..self }
    }
}

impl Default for Worley {
    fn default() -> Self {
        Self::new(0)
    }
}

impl Seedable for Worley {
    /// Sets the seed value used by the Worley cells.
    fn set_seed(self, seed: u32) -> Self {
        // If the new seed is the same as the current seed, just return self.
        if self.seed == seed {
            return self;
        }

        // Otherwise, regenerate the permutation table based on the new seed.
        Self {
            perm_table: PermutationTable::new(seed),
            seed,
            ..self
        }
    }

    fn seed(&self) -> u32 {
        self.seed
    }
}

impl NoiseFn<f64, 2> for Worley {
    fn get(&self, point: [f64; 2]) -> f64 {
        worley_2d(
            &self.perm_table,
            &*self.distance_function,
            self.return_type,
            (Vector2::from(point) * self.frequency).into_array(),
        )
    }
}

impl NoiseFn<f64, 3> for Worley {
    fn get(&self, point: [f64; 3]) -> f64 {
        worley_3d(
            &self.perm_table,
            &*self.distance_function,
            self.return_type,
            (Vector3::from(point) * self.frequency).into_array(),
        )
    }
}

#[allow(clippy::cognitive_complexity)]
impl NoiseFn<f64, 4> for Worley {
    fn get(&self, point: [f64; 4]) -> f64 {
        worley_4d(
            &self.perm_table,
            &*self.distance_function,
            self.return_type,
            (Vector4::from(point) * self.frequency).into_array(),
        )
    }
}
<|endoftext|>


<commit_before>use std::ops::Add;
use ndarray;
use rand;
use rand::Rng;

type TileArray = ndarray::Array2<Tile>;
// Index into a TileArray; arrays are indexed in (row (y), column (x)) order
type TileIndex = (usize, usize);

impl Add<Direction> for TileIndex {
    type Output = TileIndex;

    fn add(self, direction: Direction) -> TileIndex {
        let (y, x) = self;
        match direction {
            Direction::Up => (y - 1, x),
            Direction::Down => (y + 1, x),
            Direction::Left => (y, x - 1),
            Direction::Right => (y, x + 1),
        }
    }
}

#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    fn reverse(&self) -> Direction {
        match *self {
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
            Direction::Left => Direction::Right,
            Direction::Right => Direction::Left,
        }
    }
}

#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub enum Tile {
    Floor,
    Wall,
    Food,
    // Snake contains the optional directions towards the previous and next snake segments.  The
    // tail has only a next direction (so a Snake(None, Some(_))) while the head has only a
    // previous direction (so a Snake(Some(_), None)); all other segments have both defined.
    Snake(Option<Direction>, Option<Direction>),
}

#[derive(Serialize, Deserialize)]
pub struct GameState {
    level_width: usize,
    level_height: usize,
    tiles: TileArray,
    snake_head_idx: TileIndex,
    snake_tail_idx: TileIndex,
    snake_dir: Direction,
    snake_alive: bool,
    score: u32,
    highscore: u32,
}

impl GameState {
    pub fn new(level_width: usize, level_height: usize, highscore: u32) -> Self {
        let mut tiles = ndarray::Array::from_elem((level_height, level_width), Tile::Floor);

        // Build level wall
        for x in 0..level_width {
            tiles[(0, x)] = Tile::Wall;
            tiles[(level_height - 1, x)] = Tile::Wall;
        }
        for y in 0..level_height {
            tiles[(y, 0)] = Tile::Wall;
            tiles[(y, level_width - 1)] = Tile::Wall;
        }

        // Place snake
        tiles[(3, 3)] = Tile::Snake(None, Some(Direction::Right));
        tiles[(3, 4)] = Tile::Snake(Some(Direction::Left), Some(Direction::Right));
        tiles[(3, 5)] = Tile::Snake(Some(Direction::Left), None);
        let snake_head_idx = (3, 5);
        let snake_tail_idx = (3, 3);
        let snake_dir = Direction::Right;
        let snake_alive = true;
        let score = 0;

        let mut game_state = GameState {
            level_width: level_width,
            level_height: level_height,
            tiles: tiles,
            snake_head_idx: snake_head_idx,
            snake_tail_idx: snake_tail_idx,
            snake_dir: snake_dir,
            snake_alive: snake_alive,
            score: score,
            highscore: highscore,
        };
        game_state.spawn_food();

        game_state
    }

    pub fn reset(&mut self) {
        *self = GameState::new(self.level_width, self.level_height, self.highscore);
    }

    pub fn level_size(&self) -> (usize, usize) {
        (self.level_width, self.level_height)
    }

    pub fn snake_alive(&self) -> bool {
        self.snake_alive
    }

    fn spawn_food(&mut self) {
        let mut rng = rand::thread_rng();
        let mut index;
        // FIXME This will hang if the snake fills the entire playing field
        loop {
            index = (rng.gen_range(1, self.level_height - 1),
                     rng.gen_range(1, self.level_width - 1));
            if self.tiles[index] == Tile::Floor {
                break;
            };
        }
        self.tiles[index] = Tile::Food;
    }

    pub fn tiles(&self) -> &TileArray {
        &self.tiles
    }

    fn get_snake_prev(&self, index: TileIndex) -> Result<Direction, String> {
        if let Tile::Snake(Some(prev), _) = self.tiles[index] {
            Ok(prev)
        } else {
            Err(format!("Expected Snake(Some(_), _) on tile at {:?}, but found {:?}",
                        index,
                        self.tiles[index]))
        }
    }

    fn get_snake_next(&self, index: TileIndex) -> Result<Direction, String> {
        if let Tile::Snake(_, Some(next)) = self.tiles[index] {
            Ok(next)
        } else {
            Err(format!("Expected Snake(_, Some(_)) on tile at {:?}, but found {:?}",
                        index,
                        self.tiles[index]))
        }
    }

    pub fn update(&mut self, input: Option<Direction>) -> Result<(), String> {
        // Don't do anything if the snake is dead
        if !self.snake_alive {
            return Ok(());
        }

        // Handle input
        if let Some(new_snake_dir) = input {
            self.snake_dir = new_snake_dir;
        }

        // Move snake
        let new_snake_head_idx = self.snake_head_idx + self.snake_dir;
        let new_snake_tail_idx = self.snake_tail_idx + self.get_snake_next(self.snake_tail_idx)?;
        let mut eat_food = false;
        // Check for collision
        match self.tiles[new_snake_head_idx] {
            Tile::Wall | Tile::Snake(..) => {
                // New head collides with wall or snake, so game over
                self.snake_alive = false;
                println!("Game over!");
                println!("Your score: {}", self.score);
                if self.score > self.highscore {
                    println!("*** New highscore! ***");
                    self.highscore = self.score;
                } else {
                    println!("Highscore: {}", self.highscore);
                }
                return Ok(());
            }
            Tile::Food => {
                // New head collides with food, so eat the food
                eat_food = true;
            }
            Tile::Floor => {} // No collision
        }
        // Move snake head
        self.tiles[self.snake_head_idx] =
            Tile::Snake(Some(self.get_snake_prev(self.snake_head_idx)?),
                        Some(self.snake_dir));
        self.tiles[new_snake_head_idx] = Tile::Snake(Some(self.snake_dir.reverse()), None);
        self.snake_head_idx = new_snake_head_idx;
        // Spawn new food or move snake tail
        if eat_food {
            self.score += 10;
            self.spawn_food();
        } else {
            self.tiles[self.snake_tail_idx] = Tile::Floor;
            self.tiles[new_snake_tail_idx] =
                Tile::Snake(None, Some(self.get_snake_next(new_snake_tail_idx)?));
            self.snake_tail_idx = new_snake_tail_idx;
        }

        Ok(())
    }
}

impl Default for GameState {
    fn default() -> Self {
        Self::new(40, 30, 0)
    }
}
<commit_msg>Disallow snake reverse direction input<commit_after>use std::ops::Add;
use ndarray;
use rand;
use rand::Rng;

type TileArray = ndarray::Array2<Tile>;
// Index into a TileArray; arrays are indexed in (row (y), column (x)) order
type TileIndex = (usize, usize);

impl Add<Direction> for TileIndex {
    type Output = TileIndex;

    fn add(self, direction: Direction) -> TileIndex {
        let (y, x) = self;
        match direction {
            Direction::Up => (y - 1, x),
            Direction::Down => (y + 1, x),
            Direction::Left => (y, x - 1),
            Direction::Right => (y, x + 1),
        }
    }
}

#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    fn reverse(&self) -> Direction {
        match *self {
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
            Direction::Left => Direction::Right,
            Direction::Right => Direction::Left,
        }
    }
}

#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub enum Tile {
    Floor,
    Wall,
    Food,
    // Snake contains the optional directions towards the previous and next snake segments.  The
    // tail has only a next direction (so a Snake(None, Some(_))) while the head has only a
    // previous direction (so a Snake(Some(_), None)); all other segments have both defined.
    Snake(Option<Direction>, Option<Direction>),
}

#[derive(Serialize, Deserialize)]
pub struct GameState {
    level_width: usize,
    level_height: usize,
    tiles: TileArray,
    snake_head_idx: TileIndex,
    snake_tail_idx: TileIndex,
    snake_dir: Direction,
    snake_alive: bool,
    score: u32,
    highscore: u32,
}

impl GameState {
    pub fn new(level_width: usize, level_height: usize, highscore: u32) -> Self {
        let mut tiles = ndarray::Array::from_elem((level_height, level_width), Tile::Floor);

        // Build level wall
        for x in 0..level_width {
            tiles[(0, x)] = Tile::Wall;
            tiles[(level_height - 1, x)] = Tile::Wall;
        }
        for y in 0..level_height {
            tiles[(y, 0)] = Tile::Wall;
            tiles[(y, level_width - 1)] = Tile::Wall;
        }

        // Place snake
        tiles[(3, 3)] = Tile::Snake(None, Some(Direction::Right));
        tiles[(3, 4)] = Tile::Snake(Some(Direction::Left), Some(Direction::Right));
        tiles[(3, 5)] = Tile::Snake(Some(Direction::Left), None);
        let snake_head_idx = (3, 5);
        let snake_tail_idx = (3, 3);
        let snake_dir = Direction::Right;
        let snake_alive = true;
        let score = 0;

        let mut game_state = GameState {
            level_width: level_width,
            level_height: level_height,
            tiles: tiles,
            snake_head_idx: snake_head_idx,
            snake_tail_idx: snake_tail_idx,
            snake_dir: snake_dir,
            snake_alive: snake_alive,
            score: score,
            highscore: highscore,
        };
        game_state.spawn_food();

        game_state
    }

    pub fn reset(&mut self) {
        *self = GameState::new(self.level_width, self.level_height, self.highscore);
    }

    pub fn level_size(&self) -> (usize, usize) {
        (self.level_width, self.level_height)
    }

    pub fn snake_alive(&self) -> bool {
        self.snake_alive
    }

    fn spawn_food(&mut self) {
        let mut rng = rand::thread_rng();
        let mut index;
        // FIXME This will hang if the snake fills the entire playing field
        loop {
            index = (rng.gen_range(1, self.level_height - 1),
                     rng.gen_range(1, self.level_width - 1));
            if self.tiles[index] == Tile::Floor {
                break;
            };
        }
        self.tiles[index] = Tile::Food;
    }

    pub fn tiles(&self) -> &TileArray {
        &self.tiles
    }

    fn get_snake_prev(&self, index: TileIndex) -> Result<Direction, String> {
        if let Tile::Snake(Some(prev), _) = self.tiles[index] {
            Ok(prev)
        } else {
            Err(format!("Expected Snake(Some(_), _) on tile at {:?}, but found {:?}",
                        index,
                        self.tiles[index]))
        }
    }

    fn get_snake_next(&self, index: TileIndex) -> Result<Direction, String> {
        if let Tile::Snake(_, Some(next)) = self.tiles[index] {
            Ok(next)
        } else {
            Err(format!("Expected Snake(_, Some(_)) on tile at {:?}, but found {:?}",
                        index,
                        self.tiles[index]))
        }
    }

    pub fn update(&mut self, input: Option<Direction>) -> Result<(), String> {
        // Don't do anything if the snake is dead
        if !self.snake_alive {
            return Ok(());
        }

        // Handle input
        if let Some(new_snake_dir) = input {
            // Reversing direction would instantly crash the snake into itself, so don't allow it
            if new_snake_dir != self.snake_dir.reverse() {
                self.snake_dir = new_snake_dir;
            }
        }

        // Move snake
        let new_snake_head_idx = self.snake_head_idx + self.snake_dir;
        let new_snake_tail_idx = self.snake_tail_idx + self.get_snake_next(self.snake_tail_idx)?;
        let mut eat_food = false;
        // Check for collision
        match self.tiles[new_snake_head_idx] {
            Tile::Wall | Tile::Snake(..) => {
                // New head collides with wall or snake, so game over
                self.snake_alive = false;
                println!("Game over!");
                println!("Your score: {}", self.score);
                if self.score > self.highscore {
                    println!("*** New highscore! ***");
                    self.highscore = self.score;
                } else {
                    println!("Highscore: {}", self.highscore);
                }
                return Ok(());
            }
            Tile::Food => {
                // New head collides with food, so eat the food
                eat_food = true;
            }
            Tile::Floor => {} // No collision
        }
        // Move snake head
        self.tiles[self.snake_head_idx] =
            Tile::Snake(Some(self.get_snake_prev(self.snake_head_idx)?),
                        Some(self.snake_dir));
        self.tiles[new_snake_head_idx] = Tile::Snake(Some(self.snake_dir.reverse()), None);
        self.snake_head_idx = new_snake_head_idx;
        // Spawn new food or move snake tail
        if eat_food {
            self.score += 10;
            self.spawn_food();
        } else {
            self.tiles[self.snake_tail_idx] = Tile::Floor;
            self.tiles[new_snake_tail_idx] =
                Tile::Snake(None, Some(self.get_snake_next(new_snake_tail_idx)?));
            self.snake_tail_idx = new_snake_tail_idx;
        }

        Ok(())
    }
}

impl Default for GameState {
    fn default() -> Self {
        Self::new(40, 30, 0)
    }
}
<|endoftext|>