<commit_before>use geom::point::Point;
use renderer::Renderer;
use frame::Frame;
use draw::RGB;

use super::Scene;

pub struct DevelRenderer {
   scene: Scene,
   aliased: Vec<RGB>,
   rendered: Vec<RGB>,
}

const SUBDIVISIONS: i64 = 3;

impl DevelRenderer {
   #[inline]
   pub fn new(scene: Scene) -> Self {
      DevelRenderer {
         scene: scene,

         aliased: vec!(),
         rendered: vec!(),
      }
   }

   fn check_resize(&mut self, width: u32, height: u32) {
      if self.rendered.len() == (width * height) as usize {
         return;
      }

      self.aliased.resize((width * height) as usize * (SUBDIVISIONS * SUBDIVISIONS) as usize, RGB::new(0, 0, 0));
      self.rendered.resize((width * height) as usize, RGB::new(0, 0, 0));
   }

   #[inline]
   fn clear(&mut self) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for i in 0..aliased.len() {
         aliased[i] = RGB::default();
      }
   }

   #[inline]
   fn render_aliased(&mut self, frame: &mut Frame) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for poly in &self.scene.polys {
         let points = &poly.points;

         let (left, right) = get_left_right_edges(points);

         let mut left_i = 0;
         let mut right_i = 0;

         let mut left_edge = left[left_i];
         let mut right_edge = right[right_i];

         let mut left_x = left_edge.p1.x;
         let mut right_x = right_edge.p1.x;

         let left_last_i = left.len() - 1;
         let right_last_i = right.len() - 1;

         let mut left_advancer = YAxisAdvancer::new(&left_edge);
         let mut right_advancer = YAxisAdvancer::new(&right_edge);

         let min_y = left_edge.p1.y;
         let max_y = left[left_last_i].p2.y;

         for y in min_y..max_y + 1 {
            if left_edge.p2.y == y && left_i != left_last_i {
               left_i += 1;
               left_edge = left[left_i];
               left_advancer = YAxisAdvancer::new(&left_edge);
            }

            if right_edge.p2.y == y && right_i != right_last_i  {
               right_i += 1;
               right_edge = right[right_i];
               right_advancer = YAxisAdvancer::new(&right_edge);
            }

            for x in left_x..right_x {
               aliased[y as usize * frame.width as usize * SUBDIVISIONS as usize + x as usize] = poly.color;
            }

            left_x = left_advancer.advance();
            right_x = right_advancer.advance();
         }
      }
   }

   #[inline]
   fn downsample(&mut self, frame: &mut Frame) {
      let aliased: &mut Vec<RGB> = self.aliased.as_mut();

      let rendered: &mut Vec<RGB> = self.rendered.as_mut();

      let divisor = (SUBDIVISIONS * SUBDIVISIONS) as u16;

      for y in 0..frame.height as usize {
         for x in 0..frame.width as usize {
            let mut r: u16 = 0;
            let mut g: u16 = 0;
            let mut b: u16 = 0;
            for box_y in 0..SUBDIVISIONS as usize {
               for box_x in 0..SUBDIVISIONS as usize {
                  let pos = (box_y + y * SUBDIVISIONS as usize * frame.width as usize * SUBDIVISIONS as usize) + box_x + x * SUBDIVISIONS as usize;
                  let color = &aliased[pos];
                  r += color.r as u16;
                  g += color.g as u16;
                  b += color.b as u16;
               }
            }

            r /= divisor;
            g /= divisor;
            b /= divisor;

            let color = RGB::new(r as u8, g as u8, b as u8);

            frame.put_pixel(x as i32, y as i32, &color);

            rendered[y * frame.width as usize + x] = color;
         }
      }
   }
}

impl Renderer for DevelRenderer {
   #[inline]
   fn init(&mut self, width: u32, height: u32) {
      self.check_resize(width, height);
   }

   fn render(&mut self, frame: &mut Frame) {
      self.check_resize(frame.width, frame.height);

      self.clear();

      self.render_aliased(frame);

      self.downsample(frame);
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   p1: Point,
   p2: Point,
}

impl Edge {
   #[inline]
   fn new(p1: Point, p2: Point) -> Self {
      Edge {
         p1: p1,
         p2: p2,
      }
   }
}

struct YAxisAdvancer {
   delta: f64,
   f64x: f64,
}

impl YAxisAdvancer {
   fn new(edge: &Edge) -> Self {
      let dx = edge.p2.x - edge.p1.x;
      let dy = edge.p2.y - edge.p1.y;

      let delta = dx as f64 / dy as f64;
      let f64x = edge.p1.x as f64;

      YAxisAdvancer {
         delta: delta,
         f64x: f64x,
      }
   }

   fn advance(&mut self) -> i64 {
      self.f64x += self.delta;
      self.f64x.round() as i64
   }
}

fn get_left_right_edges(points: &Vec<Point>) -> (Vec<Edge>, Vec<Edge>){
   let (min_i, max_i) = find_min_max_y_index(points);

   let left = get_left_edges(points, min_i, max_i);
   let right = get_right_edges(points, min_i, max_i);

   (left, right)
}

fn get_left_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      curr_i += 1;

      if curr_i == points.len() {
         curr_i = 0;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

fn get_right_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      if curr_i == 0 {
         curr_i = points.len() - 1;
      } else {
         curr_i -= 1;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

fn find_min_max_y_index(points: &Vec<Point>) -> (usize, usize) {
   let (first, rest) = points.split_first().unwrap();

   let mut min_y = first.y;
   let mut max_y = min_y;
   let mut min_i = 0;
   let mut max_i = 0;

   for (i, point) in rest.iter().enumerate() {
      if point.y < min_y {
         min_i = i + 1;
         min_y = point.y;
      } else if point.y > max_y {
         max_i = i + 1;
         max_y = point.y;
      }
   }

   (min_i, max_i)
}

<commit_msg>Development renderer antialiasing fix<commit_after>use geom::point::Point;
use renderer::Renderer;
use frame::Frame;
use draw::RGB;

use super::Scene;

pub struct DevelRenderer {
   scene: Scene,
   aliased: Vec<RGB>,
//   rendered: Vec<RGB>,
}

const SUBDIVISIONS: usize = 3;

impl DevelRenderer {
   #[inline]
   pub fn new(scene: Scene) -> Self {
      DevelRenderer {
         scene: scene,

         aliased: vec!(),
//         rendered: vec!(),
      }
   }

   fn check_resize(&mut self, width: u32, height: u32) {
      if self.aliased.len() == (width * height) as usize * SUBDIVISIONS * SUBDIVISIONS {
         return;
      }

      self.aliased.resize((width * height) as usize * SUBDIVISIONS * SUBDIVISIONS, RGB::new(0, 0, 0));
//      self.rendered.resize((width * height) as usize, RGB::new(0, 0, 0));
   }

   #[inline]
   fn clear(&mut self) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for i in 0..aliased.len() {
         aliased[i] = RGB::default();
      }
   }

   #[inline]
   fn render_aliased(&mut self, frame: &mut Frame) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for poly in &self.scene.polys {
         let points = &poly.points;

         let (left, right) = get_left_right_edges(points);

         let mut left_i = 0;
         let mut right_i = 0;

         let mut left_edge = left[left_i];
         let mut right_edge = right[right_i];

         let mut left_x = left_edge.p1.x;
         let mut right_x = right_edge.p1.x;

         let left_last_i = left.len() - 1;
         let right_last_i = right.len() - 1;

         let mut left_advancer = YAxisAdvancer::new(&left_edge);
         let mut right_advancer = YAxisAdvancer::new(&right_edge);

         let min_y = left_edge.p1.y;
         let max_y = left[left_last_i].p2.y;

         for y in min_y..max_y + 1 {
            if left_edge.p2.y == y && left_i != left_last_i {
               left_i += 1;
               left_edge = left[left_i];
               left_advancer = YAxisAdvancer::new(&left_edge);
            }

            if right_edge.p2.y == y && right_i != right_last_i  {
               right_i += 1;
               right_edge = right[right_i];
               right_advancer = YAxisAdvancer::new(&right_edge);
            }

            for x in left_x..right_x {
               aliased[y as usize * frame.width as usize * SUBDIVISIONS + x as usize] = poly.color;
            }

            left_x = left_advancer.advance();
            right_x = right_advancer.advance();
         }
      }
   }

   #[inline]
   fn downsample(&mut self, frame: &mut Frame) {
      let aliased: &mut Vec<RGB> = self.aliased.as_mut();

//      let rendered: &mut Vec<RGB> = self.rendered.as_mut();

      let (width, height) = (frame.width as usize, frame.height as usize);

      for y in 0..height {
         for x in 0..width {
            let color = calc_pixel_color(aliased, width, x, y);

            frame.put_pixel(x as i32, y as i32, &color);

//            rendered[y * width + x] = color;
         }
      }
   }
}

impl Renderer for DevelRenderer {
   #[inline]
   fn init(&mut self, width: u32, height: u32) {
      self.check_resize(width, height);
   }

   #[inline]
   fn render(&mut self, frame: &mut Frame) {
      self.check_resize(frame.width, frame.height);

      self.clear();

      self.render_aliased(frame);

      self.downsample(frame);
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   p1: Point,
   p2: Point,
}

impl Edge {
   #[inline]
   fn new(p1: Point, p2: Point) -> Self {
      Edge {
         p1: p1,
         p2: p2,
      }
   }
}

struct YAxisAdvancer {
   delta: f64,
   f64x: f64,
}

impl YAxisAdvancer {
   #[inline]
   fn new(edge: &Edge) -> Self {
      let dx = edge.p2.x - edge.p1.x;
      let dy = edge.p2.y - edge.p1.y;

      let delta = dx as f64 / dy as f64;
      let f64x = edge.p1.x as f64;

      YAxisAdvancer {
         delta: delta,
         f64x: f64x,
      }
   }

   #[inline]
   fn advance(&mut self) -> i64 {
      self.f64x += self.delta;
      self.f64x.round() as i64
   }
}

#[inline]
fn get_left_right_edges(points: &Vec<Point>) -> (Vec<Edge>, Vec<Edge>){
   let (min_i, max_i) = find_min_max_y_index(points);

   let left = get_left_edges(points, min_i, max_i);
   let right = get_right_edges(points, min_i, max_i);

   (left, right)
}

#[inline]
fn get_left_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      curr_i += 1;

      if curr_i == points.len() {
         curr_i = 0;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn get_right_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      if curr_i == 0 {
         curr_i = points.len() - 1;
      } else {
         curr_i -= 1;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn find_min_max_y_index(points: &Vec<Point>) -> (usize, usize) {
   let (first, rest) = points.split_first().unwrap();

   let mut min_y = first.y;
   let mut max_y = min_y;
   let mut min_i = 0;
   let mut max_i = 0;

   for (i, point) in rest.iter().enumerate() {
      if point.y < min_y {
         min_i = i + 1;
         min_y = point.y;
      } else if point.y > max_y {
         max_i = i + 1;
         max_y = point.y;
      }
   }

   (min_i, max_i)
}

#[inline]
fn calc_pixel_color(aliased: &mut Vec<RGB>, width: usize, x: usize, y: usize) -> RGB {
   let mut r: u16 = 0;
   let mut g: u16 = 0;
   let mut b: u16 = 0;
   for box_y in 0..SUBDIVISIONS {
      for box_x in 0..SUBDIVISIONS {
         let pos = (box_y + y * SUBDIVISIONS) * width * SUBDIVISIONS + box_x + x * SUBDIVISIONS;
         let color = &aliased[pos];
         r += color.r as u16;
         g += color.g as u16;
         b += color.b as u16;
      }
   }

   let divisor = (SUBDIVISIONS * SUBDIVISIONS) as u16;

   r /= divisor;
   g /= divisor;
   b /= divisor;

   RGB::new(r as u8, g as u8, b as u8)
}
<|endoftext|>


<commit_before>extern crate tokio;

use tokio::io;
use tokio::net::TcpListener;
use tokio::prelude::*;

fn main() {
    let addr = "127.0.0.1:6142".parse().unwrap();
    let listener = TcpListener::bind(&addr).unwrap();

    let server = listener.incoming().for_each(|socket| {
        println!("accepted socket; addr={:?}", socket.peer_addr().unwrap());

        let connection = io::write_all(socket, "hello world\n").then(|res| {
            println!("wrote message; success={:?}", res.is_ok());
        });

        // spawn new task to process the socket
        tokio::spawn(connection);

        Ok(())
    }).map_err(|err| {
        // All tasks must have an `Error` type of `()`
        // This forces error handling and helps avoid silent failures.
        // In our example, we are only going to log the error to STDOUT.
        println!("accept error = {:?}", err)
    });

    println!("server running on localhost:6142");
    tokio::run(server);
}

// A task that polls a single widget and writes it to STDOUT
pub struct MyTask;

impl Future for MyTask {
    // The value this future will have when ready
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Result<Async<()>, ()> {
        match poll_widget() {
            Async::Ready(widget) => {
                println!("widget={:?}", widget);
                Ok(Async::Ready(()))
            }
            Async::NotReady => {
                Ok(Async::NotReady)
            }
        }
    }
}

pub struct SpinExecutor {
    // the tasks an executor is responsible for in a double queue
    tasks: VecDeque<Box<Future<Item=(), Error=()>>>,
}

impl SpinExecutor {
    pub fn spawn<T>(&mut self, task: T)
        where T: Future<Item=(), Error=()> + 'static
    {
        self.tasks.push_back(Box::new(task))
    }

    pub fn run(&mut self) {
        // Of course, this would not be very efficient.
        // The executor spins in a busy loop and tries to poll all tasks even if the task will just return NotReady again.
        while let Some(mut task) = self.tasks.pop_front() {
            match task.poll().unwrap() {
                Async::Ready(_) => {}
                Async::NotReady => {
                    self.tasks.push_back(task);
                }
            }
        }
    }
}
<commit_msg>last vision of executor<commit_after>extern crate tokio;

use tokio::io;
use tokio::net::TcpListener;
use tokio::prelude::*;

fn main() {
    let addr = "127.0.0.1:6142".parse().unwrap();
    let listener = TcpListener::bind(&addr).unwrap();

    let server = listener.incoming().for_each(|socket| {
        println!("accepted socket; addr={:?}", socket.peer_addr().unwrap());

        let connection = io::write_all(socket, "hello world\n").then(|res| {
            println!("wrote message; success={:?}", res.is_ok());
        });

        // spawn new task to process the socket
        tokio::spawn(connection);

        Ok(())
    }).map_err(|err| {
        // All tasks must have an `Error` type of `()`
        // This forces error handling and helps avoid silent failures.
        // In our example, we are only going to log the error to STDOUT.
        println!("accept error = {:?}", err)
    });

    println!("server running on localhost:6142");
    tokio::run(server);
}

// A task that polls a single widget and writes it to STDOUT
pub struct MyTask;

impl Future for MyTask {
    // The value this future will have when ready
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Result<Async<()>, ()> {
        match poll_widget() {
            Async::Ready(widget) => {
                println!("widget={:?}", widget);
                Ok(Async::Ready(()))
            }
            Async::NotReady => {
                Ok(Async::NotReady)
            }
        }
    }
}

pub struct SpinExecutor {
    // the tasks an executor is responsible for in a double queue
    tasks: VecDeque<Box<Future<Item=(), Error=()>>>,
}

impl SpinExecutor {
    pub fn spawn<T>(&mut self, task: T)
        where T: Future<Item=(), Error=()> + 'static
    {
        self.tasks.push_back(Box::new(task))
    }

    pub fn run(&mut self) {
        // Of course, this would not be very efficient.
        // The executor spins in a busy loop and tries to poll all tasks even if the task will just return NotReady again.

        // We won't use this naive approach and will implement something more advanced.
        //
        // while let Some(mut task) = self.tasks.pop_front() {
        //     match task.poll().unwrap() {
        //         Async::Ready(_) => {}
        //         Async::NotReady => {
        //             self.tasks.push_back(task);
        //         }
        //     }
        // }

        // So, to avoid busy loop here and waiting your CPU time
        // you just iterate over tasks one time and then go to sleep.
        // Someone will wake you up later.
        loop {
            while let Some(mut task) = self.ready_tasks.pop_front() {
                match task.poll().unwrap() {
                    Async::Ready(_) => {}
                    Async::NotReady => {
                        self.not_ready_tasks.push_back(task);
                    }
                }
            }

            if self.not_ready_tasks.is_empty() {
                return;
            }

            self.sleep_until_tasks_are_ready();
        }
    }
}
<|endoftext|>


<commit_before>//pub const TILE_SIZE: f32 = 46.0;

pub const TILES_PCS_W: usize = 128;
pub const TILES_PCS_H: usize = 128;

pub const TILE_SIZE: f32 = 48.0;

pub const Y_OFFSET: f32 = TILES_PCS_W as f32 / 4.0 * TILE_SIZE;

pub const CHARACTER_BUF_LENGTH: usize = 224;

pub const RESOLUTION_X: u32 = 1600;
pub const RESOLUTION_Y: u32 = 900;

pub const ASPECT_RATIO: f32 = (RESOLUTION_X / RESOLUTION_Y) as f32;

pub const VIEW_DISTANCE: f32 = 300.0;

pub const CHARACTER_SHEET_TOTAL_WIDTH: f32 = 16_128f32;
pub const SPRITE_OFFSET: f32 = 2.0;

pub const ZOMBIE_SHEET_TOTAL_WIDTH: f32 = 9_184f32;

pub const BULLET_SPEED: f32 = 15.0;
pub const CHARACTER_X_SPEED: f32 = 3.0;
pub const CHARACTER_Y_SPEED: f32 = 3.0;

pub const GAME_TITLE: &str = "Hinterland";

//Assets
pub const ZOMBIE_JSON_PATH: &str = "assets/zombie.json";
pub const CHARACTER_JSON_PATH: &str = "assets/character.json";
pub const PISTOL_AUDIO_PATH: &str = "assets/audio/pistol.ogg";
pub const MAP_FILE_PATH: &str = "assets/maps/tilemap.tmx";

pub const RUN_SPRITE_OFFSET: usize = 64;
pub const ZOMBIE_STILL_SPRITE_OFFSET: usize = 32;
pub const NORMAL_DEATH_SPRITE_OFFSET: usize = 64;

pub const AMMO_POSITIONS: [[f32; 2]; 4] = [[-640.0, -560.0], [-700.0, 400.0], [750.0, -450.0], [-50.0, 550.0]];
pub const HOUSE_POSITIONS: [[f32; 2]; 2] = [[-36.0, 644.0], [506.0, 230.0]];
pub const TREE_POSITIONS: [[f32; 2]; 5] = [[-506.0, -230.0], [368.0, -368.0], [-690.0, -506.0], [-874.0, -92.0], [-690.0, 138.0]];

pub const TERRAIN_OBJECTS: [[i32; 2]; 34] = [[48, 50],
  [48, 51],
  [48, 52],
  [49, 50],
  [49, 51],
  [49, 52],
  [50, 50],
  [50, 51],
  [50, 52],
  [51, 50],
  [51, 51],
  [51, 52],
  [69, 47],
  [69, 48],
  [69, 49],
  [70, 47],
  [70, 48],
  [70, 49],
  [71, 47],
  [71, 48],
  [71, 49],
  [72, 47],
  [72, 48],
  [72, 49],
  [61, 81],
  [60, 82],
  [81, 65],
  [82, 66],
  [61, 91],
  [62, 92],
  [48, 86],
  [49, 87],
  [47, 77],
  [48, 78]];

pub const GAME_VERSION: &str = "v0.3.12";

pub const HUD_TEXTS: [&str; 15] = [GAME_VERSION, "Ammo 0", "Ammo 1", "Ammo 2", "Ammo 3",
  "Ammo 4", "Ammo 5", "Ammo 6",
  "Ammo 7", "Ammo 8", "Ammo 9", "Ammo 10",
  "Magazines 0/2", "Magazines 1/2", "Magazines 2/2"];

pub const CURRENT_AMMO_TEXT: &str = "Ammo 10";
pub const CURRENT_MAGAZINE_TEXT: &str = "Magazines 2/2";
<commit_msg>Remove commented code and adjust ammo position<commit_after>pub const TILES_PCS_W: usize = 128;
pub const TILES_PCS_H: usize = 128;

pub const TILE_SIZE: f32 = 48.0;

pub const Y_OFFSET: f32 = TILES_PCS_W as f32 / 4.0 * TILE_SIZE;

pub const CHARACTER_BUF_LENGTH: usize = 224;

pub const RESOLUTION_X: u32 = 1600;
pub const RESOLUTION_Y: u32 = 900;

pub const ASPECT_RATIO: f32 = (RESOLUTION_X / RESOLUTION_Y) as f32;

pub const VIEW_DISTANCE: f32 = 300.0;

pub const CHARACTER_SHEET_TOTAL_WIDTH: f32 = 16_128f32;
pub const SPRITE_OFFSET: f32 = 2.0;

pub const ZOMBIE_SHEET_TOTAL_WIDTH: f32 = 9_184f32;

pub const BULLET_SPEED: f32 = 15.0;
pub const CHARACTER_X_SPEED: f32 = 3.0;
pub const CHARACTER_Y_SPEED: f32 = 3.0;

pub const GAME_TITLE: &str = "Hinterland";

//Assets
pub const ZOMBIE_JSON_PATH: &str = "assets/zombie.json";
pub const CHARACTER_JSON_PATH: &str = "assets/character.json";
pub const PISTOL_AUDIO_PATH: &str = "assets/audio/pistol.ogg";
pub const MAP_FILE_PATH: &str = "assets/maps/tilemap.tmx";

pub const RUN_SPRITE_OFFSET: usize = 64;
pub const ZOMBIE_STILL_SPRITE_OFFSET: usize = 32;
pub const NORMAL_DEATH_SPRITE_OFFSET: usize = 64;

// Object positions
pub const AMMO_POSITIONS: [[f32; 2]; 4] = [[-640.0, -560.0], [-700.0, 400.0], [750.0, -400.0], [-50.0, 550.0]];
pub const HOUSE_POSITIONS: [[f32; 2]; 2] = [[-36.0, 644.0], [506.0, 230.0]];
pub const TREE_POSITIONS: [[f32; 2]; 5] = [[-506.0, -230.0], [368.0, -368.0], [-690.0, -506.0], [-874.0, -92.0], [-690.0, 138.0]];

pub const TERRAIN_OBJECTS: [[i32; 2]; 34] = [[48, 50],
  [48, 51],
  [48, 52],
  [49, 50],
  [49, 51],
  [49, 52],
  [50, 50],
  [50, 51],
  [50, 52],
  [51, 50],
  [51, 51],
  [51, 52],
  [69, 47],
  [69, 48],
  [69, 49],
  [70, 47],
  [70, 48],
  [70, 49],
  [71, 47],
  [71, 48],
  [71, 49],
  [72, 47],
  [72, 48],
  [72, 49],
  [61, 81],
  [60, 82],
  [81, 65],
  [82, 66],
  [61, 91],
  [62, 92],
  [48, 86],
  [49, 87],
  [47, 77],
  [48, 78]];

pub const GAME_VERSION: &str = "v0.3.12";

pub const HUD_TEXTS: [&str; 15] = [GAME_VERSION, "Ammo 0", "Ammo 1", "Ammo 2", "Ammo 3",
  "Ammo 4", "Ammo 5", "Ammo 6",
  "Ammo 7", "Ammo 8", "Ammo 9", "Ammo 10",
  "Magazines 0/2", "Magazines 1/2", "Magazines 2/2"];

pub const CURRENT_AMMO_TEXT: &str = "Ammo 10";
pub const CURRENT_MAGAZINE_TEXT: &str = "Magazines 2/2";
<|endoftext|>


<commit_before>// Implement data structures for a Huffman encoding tree:
//   http://rosettacode.org/wiki/Huffman_coding

extern crate core;
use std::collections::HashMap;
use std::collections::priority_queue::PriorityQueue;

// Each HNode has a weight, representing the sum of the frequencies for all its
// children. It is either a leaf (containing a character), or a HTree
// (containing two children)
struct HNode {
    weight: int,
    item: HTreeOrHLeaf,
}

enum HTreeOrHLeaf {
    HTree(HTreeData),
    HLeaf(char),
}

struct HTreeData {
    left: Box<HNode>,
    right: Box<HNode>,
}

// Implementing comparison traits (Ord and all its dependencies) such that
// the HNode with the greatest weight is the smallest in a comparison. Basically
// reversing all the comparison operators.
impl Ord for HNode {
    fn cmp(&self, other: &HNode) -> Ordering {
        match self.weight.cmp(&other.weight) {
            Less    => Greater,
            Equal   => Equal,
            Greater => Less,
        }
    }
}

impl PartialOrd for HNode {
    fn partial_cmp(&self, other: &HNode) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Eq for HNode {}
impl PartialEq for HNode {
    fn eq(&self, other: &HNode) -> bool {
        self.weight == other.weight
    }
}

// Takes a non-empty string (function will fail if string is empty) and computes
// the Huffman encoding tree for that string.
fn huffman_tree(input: &str) -> HNode {
    // 1. Loop through all the characters in that string, adding them to a HashMap
    //    of character to frequency.
    let mut freq = HashMap::new();
    for ch in input.chars() {
        freq.insert_or_update_with(ch, 1, |_k, v: &mut int| {*v += 1;});
    }

    // 2. For each (character, frequency) pair in the HashMap, add a Leaf to a
    //    PriorityQueue
    let mut queue = PriorityQueue::<HNode>::new();
    for (ch, freq) in freq.iter() {
        let new_node = HNode{
            weight: *freq,
            item: HLeaf(*ch),
        };
        queue.push(new_node);
    }

    // 3. Pop two items with the least weight from the queue, combine them into
    //    a tree as children. The parent node's weight is the sum of the
    //    children's weight. Continue until one item is left on the queue, and
    //    return that item.
    while queue.len() > 1 {
        let item1 = queue.pop().unwrap();
        let item2 = queue.pop().unwrap();
        let new_node = HNode {
            weight: item1.weight + item2.weight,
            item: HTree(HTreeData{
                left: box item1,
                right: box item2,
            }),
        };
        queue.push(new_node);
    }
    queue.pop().unwrap()
}

// Takes a Huffman Tree, traverse it and build a table with each character and
// its encoding string.
fn build_encoding_table(tree: &HNode,
                      table: &mut HashMap<char,String>,
                      startStr: &str) {
    match tree.item {
        HTree(ref data) => {
            build_encoding_table(&*data.left, table,
                               String::from_str(startStr).append("0").as_slice());
            build_encoding_table(&*data.right, table,
                               String::from_str(startStr).append("1").as_slice());
        },
        HLeaf(ch)   => {table.insert(ch, String::from_str(startStr));}
    };
}

// Attempts to construct a tree, and test that the construction is successful
//    7
//   ----
//  /    \
// 4:'4'  3
//      -----
//     /     \
//    2:'2'  1:'1'
#[test]
fn test_tree_construction() {
    let to_encode = "4444221";
    let tree = huffman_tree(to_encode);
    assert!(tree.weight == 7);
    let children = match tree.item {
        HTree(data) => data,
        HLeaf(_)    => fail!("Tree Missing Children!"),
    };
    let left  = &children.left;
    let right = &children.right;
    assert!(right.weight == 4);
    assert!(left.weight == 3);
    let right_char = match right.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    assert!(right_char == '4');
    let children = match left.item {
        HTree(ref data) => data,
        HLeaf(_)    => fail!("Tree Missing Children!"),
    };
    let left  = &children.left;
    let right = &children.right;
    let left_char = match left.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    let right_char = match right.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    match (left.weight, right.weight) {
        (1, 2) => {
            assert!(left_char == '1');
            assert!(right_char == '2');
        },
        (2, 1) => {
            assert!(left_char == '2');
            assert!(right_char == '1');
        },
        (_, _) => {
            fail!("Incorrect Leaf Nodes");
        }
    };
}

#[test]
// Constructs a table:
//  '4': 1
//  '2': 01 OR 00
//  '1': 00    01
// And tests that the table was correctly constructed
fn test_table_construction() {
    let to_encode = "4444221";
    let tree = huffman_tree(to_encode);
    let mut table = HashMap::<char,String>::new();
    build_encoding_table(&tree, &mut table, "");
    let one  = table['1'].as_slice();
    let two  = table['2'].as_slice();
    let four = table['4'].as_slice();
    assert!(four == "1");
    assert!((one == "01" && two == "00") ||
            (one == "00" && two == "01"));
}

#[cfg(not(test))]
fn main() {
    let to_encode = "this is an example for huffman encoding";
    let tree = huffman_tree(to_encode);
    let mut table = HashMap::<char,String>::new();
    build_encoding_table(&tree, &mut table, "");

    for (ch, encoding) in table.iter() {
        println!("{}: {}", *ch, encoding);
    }
}
<commit_msg>non snake case argument<commit_after>// Implement data structures for a Huffman encoding tree:
//   http://rosettacode.org/wiki/Huffman_coding

extern crate core;
use std::collections::HashMap;
use std::collections::priority_queue::PriorityQueue;

// Each HNode has a weight, representing the sum of the frequencies for all its
// children. It is either a leaf (containing a character), or a HTree
// (containing two children)
struct HNode {
    weight: int,
    item: HTreeOrHLeaf,
}

enum HTreeOrHLeaf {
    HTree(HTreeData),
    HLeaf(char),
}

struct HTreeData {
    left: Box<HNode>,
    right: Box<HNode>,
}

// Implementing comparison traits (Ord and all its dependencies) such that
// the HNode with the greatest weight is the smallest in a comparison. Basically
// reversing all the comparison operators.
impl Ord for HNode {
    fn cmp(&self, other: &HNode) -> Ordering {
        match self.weight.cmp(&other.weight) {
            Less    => Greater,
            Equal   => Equal,
            Greater => Less,
        }
    }
}

impl PartialOrd for HNode {
    fn partial_cmp(&self, other: &HNode) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Eq for HNode {}
impl PartialEq for HNode {
    fn eq(&self, other: &HNode) -> bool {
        self.weight == other.weight
    }
}

// Takes a non-empty string (function will fail if string is empty) and computes
// the Huffman encoding tree for that string.
fn huffman_tree(input: &str) -> HNode {
    // 1. Loop through all the characters in that string, adding them to a HashMap
    //    of character to frequency.
    let mut freq = HashMap::new();
    for ch in input.chars() {
        freq.insert_or_update_with(ch, 1, |_k, v: &mut int| {*v += 1;});
    }

    // 2. For each (character, frequency) pair in the HashMap, add a Leaf to a
    //    PriorityQueue
    let mut queue = PriorityQueue::<HNode>::new();
    for (ch, freq) in freq.iter() {
        let new_node = HNode{
            weight: *freq,
            item: HLeaf(*ch),
        };
        queue.push(new_node);
    }

    // 3. Pop two items with the least weight from the queue, combine them into
    //    a tree as children. The parent node's weight is the sum of the
    //    children's weight. Continue until one item is left on the queue, and
    //    return that item.
    while queue.len() > 1 {
        let item1 = queue.pop().unwrap();
        let item2 = queue.pop().unwrap();
        let new_node = HNode {
            weight: item1.weight + item2.weight,
            item: HTree(HTreeData{
                left: box item1,
                right: box item2,
            }),
        };
        queue.push(new_node);
    }
    queue.pop().unwrap()
}

// Takes a Huffman Tree, traverse it and build a table with each character and
// its encoding string.
fn build_encoding_table(tree: &HNode,
                      table: &mut HashMap<char,String>,
                      start_str: &str) {
    match tree.item {
        HTree(ref data) => {
            build_encoding_table(&*data.left, table,
                               String::from_str(start_str).append("0").as_slice());
            build_encoding_table(&*data.right, table,
                               String::from_str(start_str).append("1").as_slice());
        },
        HLeaf(ch)   => {table.insert(ch, String::from_str(start_str));}
    };
}

// Attempts to construct a tree, and test that the construction is successful
//    7
//   ----
//  /    \
// 4:'4'  3
//      -----
//     /     \
//    2:'2'  1:'1'
#[test]
fn test_tree_construction() {
    let to_encode = "4444221";
    let tree = huffman_tree(to_encode);
    assert!(tree.weight == 7);
    let children = match tree.item {
        HTree(data) => data,
        HLeaf(_)    => fail!("Tree Missing Children!"),
    };
    let left  = &children.left;
    let right = &children.right;
    assert!(right.weight == 4);
    assert!(left.weight == 3);
    let right_char = match right.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    assert!(right_char == '4');
    let children = match left.item {
        HTree(ref data) => data,
        HLeaf(_)    => fail!("Tree Missing Children!"),
    };
    let left  = &children.left;
    let right = &children.right;
    let left_char = match left.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    let right_char = match right.item {
        HTree(_)  => fail!("Node is not Leaf Node!"),
        HLeaf(ch) => ch,
    };
    match (left.weight, right.weight) {
        (1, 2) => {
            assert!(left_char == '1');
            assert!(right_char == '2');
        },
        (2, 1) => {
            assert!(left_char == '2');
            assert!(right_char == '1');
        },
        (_, _) => {
            fail!("Incorrect Leaf Nodes");
        }
    };
}

#[test]
// Constructs a table:
//  '4': 1
//  '2': 01 OR 00
//  '1': 00    01
// And tests that the table was correctly constructed
fn test_table_construction() {
    let to_encode = "4444221";
    let tree = huffman_tree(to_encode);
    let mut table = HashMap::<char,String>::new();
    build_encoding_table(&tree, &mut table, "");
    let one  = table['1'].as_slice();
    let two  = table['2'].as_slice();
    let four = table['4'].as_slice();
    assert!(four == "1");
    assert!((one == "01" && two == "00") ||
            (one == "00" && two == "01"));
}

#[cfg(not(test))]
fn main() {
    let to_encode = "this is an example for huffman encoding";
    let tree = huffman_tree(to_encode);
    let mut table = HashMap::<char,String>::new();
    build_encoding_table(&tree, &mut table, "");

    for (ch, encoding) in table.iter() {
        println!("{}: {}", *ch, encoding);
    }
}
<|endoftext|>


<commit_before>//! Keyboard utility functions; allow querying state of keyboard keys and modifiers.
//!
//! Example:
//!
//! ```rust, no-run
//! use ggez::event::{EventHandler, KeyCode, KeyMods};
//! use ggez::{graphics, nalgebra as na, timer};
//! use ggez::input::keyboard;
//! use ggez::{Context, GameResult};
//!
//! struct MainState {
//!     position_x: f32,
//! }
//!
//! impl EventHandler for MainState {
//!     fn update(&mut self, ctx: &mut Context) -> GameResult {
//!         // Increase or decrease `position_x` by 0.5, or by 5.0 if Shift is held.
//!         if keyboard::is_key_pressed(ctx, KeyCode::Right) {
//!             if keyboard::is_mod_active(ctx, KeyMods::SHIFT) {
//!                 self.position_x += 4.5;
//!             }
//!             self.position_x += 0.5;
//!         } else if keyboard::is_key_pressed(ctx, KeyCode::Left) {
//!             if keyboard::is_mod_active(ctx, KeyMods::SHIFT) {
//!                 self.position_x -= 4.5;
//!             }
//!             self.position_x -= 0.5;
//!         }
//!         Ok(())
//!     }
//!
//!     fn draw(&mut self, ctx: &mut Context) -> GameResult {
//!         graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());
//!         // Draw a circle at `position_x`.
//!         graphics::circle(
//!             ctx,
//!             graphics::WHITE,
//!             graphics::DrawMode::Fill,
//!             na::Point2::new(self.position_x, 380.0),
//!             100.0,
//!             2.0,
//!         )?;
//!         graphics::present(ctx)?;
//!         timer::yield_now();
//!         Ok(())
//!     }
//!
//!     fn key_down_event(&mut self, ctx: &mut Context, key: KeyCode, mods: KeyMods, _: bool) {
//!         match key {
//!             // Quit if Shift+Ctrl+Q is pressed.
//!             KeyCode::Q => {
//!                 if mods.contains(KeyMods::SHIFT | KeyMods::CTRL) {
//!                     println!("Terminating!");
//!                     ctx.quit();
//!                 } else if mods.contains(KeyMods::SHIFT) || mods.contains(KeyMods::CTRL) {
//!                     println!("You need to hold both Shift and Control to quit.");
//!                 } else {
//!                     println!("Now you're not even trying!");
//!                 }
//!             }
//!             _ => (),
//!         }
//!     }
//! }
//! ```

use context::Context;

use winit::ModifiersState;
/// A key code.
pub use winit::VirtualKeyCode as KeyCode;

bitflags! {
    /// Bitflags describing state of keyboard modifiers, such as Control or Shift.
    #[derive(Default)]
    pub struct KeyMods: u8 {
        /// No modifiers; equivalent to `KeyMods::default()` and `KeyMods::empty()`.
        const NONE  = 0b00000000;
        /// Left or right Shift key.
        const SHIFT = 0b00000001;
        /// Left or right Control key.
        const CTRL  = 0b00000010;
        /// Left or right Alt key.
        const ALT   = 0b00000100;
        /// Left or right Win/Cmd/equivalent key.
        const LOGO  = 0b00001000;
    }
}

impl From<ModifiersState> for KeyMods {
    fn from(state: ModifiersState) -> Self {
        let mut keymod = KeyMods::empty();
        if state.shift {
            keymod |= Self::SHIFT;
        }
        if state.ctrl {
            keymod |= Self::CTRL;
        }
        if state.alt {
            keymod |= Self::ALT;
        }
        if state.logo {
            keymod |= Self::LOGO;
        }
        keymod
    }
}

/// Tracks held down keyboard keys, active keyboard modifiers,
/// and figures out if the system is sending repeat keystrokes.
#[derive(Clone, Debug)]
pub struct KeyboardContext {
    active_modifiers: KeyMods,
    /// A simple mapping of which key code has been pressed.
    /// KeyCode's are a c-like enum, and so can be converted to/from
    /// simple integers.
    /// As of winit 0.16 this is Big Enough For Anyone; assertions
    /// will check if that assumption gets violated.
    // Maybe we can just use a HashSet instead?  Eh.
    pressed_keys: Vec<bool>,

    // These two are necessary for tracking key-repeat.
    last_pressed: Option<KeyCode>,
    current_pressed: Option<KeyCode>,
}

impl KeyboardContext {
    pub(crate) fn new() -> Self {
        // We reserve a fixed-size vec because we never want to have
        // to bother resizing it, but it is not easy to ask
        // Rust what an enum's max member is and a Sufficiently Big
        // fixed-size array `[bool; MAX_KEY_IDX]` doesn't implement
        // nice things like Debug.  :|
        // We have an assert everywhere pressed_keys is accessed so
        // we know if this assumption is broken.
        const MAX_KEY_IDX: usize = 256;
        let mut key_vec = Vec::with_capacity(MAX_KEY_IDX);
        key_vec.resize(MAX_KEY_IDX, false);
        Self {
            active_modifiers: KeyMods::empty(),
            pressed_keys: key_vec,
            last_pressed: None,
            current_pressed: None,
        }
    }

    // TODO: Set modifiers correctly
    // and in general cmake sure this is hooked up correctly
    // from Context::process_event().
    // Looks like it is, but, not 100% sure.
    pub(crate) fn set_key(&mut self, key: KeyCode, pressed: bool) {
        let key_idx = key as usize;
        assert!(
            key_idx < self.pressed_keys.len(),
            "Impossible KeyCode detected!"
        );
        self.pressed_keys[key_idx] = pressed;
        if pressed {
            self.last_pressed = self.current_pressed;
            self.current_pressed = Some(key);
        } else {
            self.current_pressed = None;
            // Double check that this edge handling is necessary;
            // winit sounds like it should do this for us,
            // see https://docs.rs/winit/0.16.1/winit/struct.KeyboardInput.html#structfield.modifiers
            match key {
                KeyCode::LShift | KeyCode::RShift => self.active_modifiers -= KeyMods::SHIFT,
                KeyCode::LControl | KeyCode::RControl => self.active_modifiers -= KeyMods::CTRL,
                KeyCode::LAlt | KeyCode::RAlt => self.active_modifiers -= KeyMods::ALT,
                KeyCode::LWin | KeyCode::RWin => self.active_modifiers -= KeyMods::LOGO,
                _ => (),
            }
        }
    }

    // TODO: Merge into set_key?
    pub(crate) fn set_modifiers(&mut self, keymods: KeyMods) {
        self.active_modifiers = keymods;
    }

    pub(crate) fn is_key_pressed(&self, key: KeyCode) -> bool {
        let key_idx = key as usize;
        assert!(
            key_idx < self.pressed_keys.len(),
            "Impossible KeyCode detected!"
        );
        self.pressed_keys[key_idx]
    }

    pub(crate) fn is_key_repeated(&self) -> bool {
        if let Some(_) = self.last_pressed {
            self.last_pressed == self.current_pressed
        } else {
            false
        }
    }

    pub(crate) fn get_pressed_keys(&self) -> Vec<KeyCode> {
        self.pressed_keys
            .iter()
            .enumerate()
            .filter_map(|(key_idx, b)| {
                if *b {
                    // Sigh
                    // Horrible unsafe pointer cast to turn a number
                    // into the matching KeyCode, because Rust's support
                    // for C-like numeric enums is UTTER GARBAGE.
                    // Can we protect this with an assertion somehow?
                    // I don't even see a way to get the max element of an
                    // enum.
                    let keycode: &KeyCode =
                        unsafe { &*(&key_idx as *const usize as *const KeyCode) };
                    Some(*keycode)
                } else {
                    None
                }
            })
            .collect()
    }

    pub(crate) fn get_active_mods(&self) -> KeyMods {
        self.active_modifiers
    }
}

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

/// Checks if a key is currently pressed down.
pub fn is_key_pressed(ctx: &Context, key: KeyCode) -> bool {
    ctx.keyboard_context.is_key_pressed(key)
}

/// Checks if the last keystroke sent by the system is repeated,
/// like when a key is held down for a period of time.
pub fn is_key_repeated(ctx: &Context) -> bool {
    ctx.keyboard_context.is_key_repeated()
}

/// Returns a Vec with currently pressed keys.
pub fn get_pressed_keys(ctx: &Context) -> Vec<KeyCode> {
    ctx.keyboard_context.get_pressed_keys()
}

/// Checks if keyboard modifier (or several) is active.
pub fn is_mod_active(ctx: &Context, keymods: KeyMods) -> bool {
    ctx.keyboard_context.get_active_mods().contains(keymods)
}

/// Returns currently active keyboard modifiers.
pub fn get_active_mods(ctx: &Context) -> KeyMods {
    ctx.keyboard_context.get_active_mods()
}

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

    #[test]
    fn key_mod_conversions() {
        assert_eq!(
            KeyMods::empty(),
            KeyMods::from(ModifiersState {
                shift: false,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT | KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: true,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT | KeyMods::ALT | KeyMods::CTRL,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: true,
                alt: true,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT - KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            (KeyMods::SHIFT | KeyMods::ALT) - KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT - (KeyMods::ALT | KeyMods::SHIFT),
            KeyMods::from(ModifiersState {
                shift: false,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
    }

    #[test]
    fn pressed_keys_tracking() {
        let mut keyboard = KeyboardContext::new();
        assert_eq!(keyboard.get_pressed_keys(), &[]);
        assert!(!keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::A]);
        assert!(keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.get_pressed_keys(), &[]);
        assert!(!keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::A]);
        assert!(keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::A]);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::A, KeyCode::B]);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::A, KeyCode::B]);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::B]);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.get_pressed_keys(), &[KeyCode::B]);
        keyboard.set_key(KeyCode::B, false);
        assert_eq!(keyboard.get_pressed_keys(), &[]);
    }

    #[test]
    fn repeated_keys_tracking() {
        let mut keyboard = KeyboardContext::new();
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), true);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), true);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), true);
    }
}
<commit_msg>Change crate usage of getters in keyboard handling<commit_after>//! Keyboard utility functions; allow querying state of keyboard keys and modifiers.
//!
//! Example:
//!
//! ```rust, no-run
//! use ggez::event::{EventHandler, KeyCode, KeyMods};
//! use ggez::{graphics, nalgebra as na, timer};
//! use ggez::input::keyboard;
//! use ggez::{Context, GameResult};
//!
//! struct MainState {
//!     position_x: f32,
//! }
//!
//! impl EventHandler for MainState {
//!     fn update(&mut self, ctx: &mut Context) -> GameResult {
//!         // Increase or decrease `position_x` by 0.5, or by 5.0 if Shift is held.
//!         if keyboard::is_key_pressed(ctx, KeyCode::Right) {
//!             if keyboard::is_mod_active(ctx, KeyMods::SHIFT) {
//!                 self.position_x += 4.5;
//!             }
//!             self.position_x += 0.5;
//!         } else if keyboard::is_key_pressed(ctx, KeyCode::Left) {
//!             if keyboard::is_mod_active(ctx, KeyMods::SHIFT) {
//!                 self.position_x -= 4.5;
//!             }
//!             self.position_x -= 0.5;
//!         }
//!         Ok(())
//!     }
//!
//!     fn draw(&mut self, ctx: &mut Context) -> GameResult {
//!         graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());
//!         // Draw a circle at `position_x`.
//!         graphics::circle(
//!             ctx,
//!             graphics::WHITE,
//!             graphics::DrawMode::Fill,
//!             na::Point2::new(self.position_x, 380.0),
//!             100.0,
//!             2.0,
//!         )?;
//!         graphics::present(ctx)?;
//!         timer::yield_now();
//!         Ok(())
//!     }
//!
//!     fn key_down_event(&mut self, ctx: &mut Context, key: KeyCode, mods: KeyMods, _: bool) {
//!         match key {
//!             // Quit if Shift+Ctrl+Q is pressed.
//!             KeyCode::Q => {
//!                 if mods.contains(KeyMods::SHIFT | KeyMods::CTRL) {
//!                     println!("Terminating!");
//!                     ctx.quit();
//!                 } else if mods.contains(KeyMods::SHIFT) || mods.contains(KeyMods::CTRL) {
//!                     println!("You need to hold both Shift and Control to quit.");
//!                 } else {
//!                     println!("Now you're not even trying!");
//!                 }
//!             }
//!             _ => (),
//!         }
//!     }
//! }
//! ```

use context::Context;

use winit::ModifiersState;
/// A key code.
pub use winit::VirtualKeyCode as KeyCode;

bitflags! {
    /// Bitflags describing state of keyboard modifiers, such as Control or Shift.
    #[derive(Default)]
    pub struct KeyMods: u8 {
        /// No modifiers; equivalent to `KeyMods::default()` and `KeyMods::empty()`.
        const NONE  = 0b00000000;
        /// Left or right Shift key.
        const SHIFT = 0b00000001;
        /// Left or right Control key.
        const CTRL  = 0b00000010;
        /// Left or right Alt key.
        const ALT   = 0b00000100;
        /// Left or right Win/Cmd/equivalent key.
        const LOGO  = 0b00001000;
    }
}

impl From<ModifiersState> for KeyMods {
    fn from(state: ModifiersState) -> Self {
        let mut keymod = KeyMods::empty();
        if state.shift {
            keymod |= Self::SHIFT;
        }
        if state.ctrl {
            keymod |= Self::CTRL;
        }
        if state.alt {
            keymod |= Self::ALT;
        }
        if state.logo {
            keymod |= Self::LOGO;
        }
        keymod
    }
}

/// Tracks held down keyboard keys, active keyboard modifiers,
/// and figures out if the system is sending repeat keystrokes.
#[derive(Clone, Debug)]
pub struct KeyboardContext {
    active_modifiers: KeyMods,
    /// A simple mapping of which key code has been pressed.
    /// KeyCode's are a c-like enum, and so can be converted to/from
    /// simple integers.
    /// As of winit 0.16 this is Big Enough For Anyone; assertions
    /// will check if that assumption gets violated.
    // Maybe we can just use a HashSet instead?  Eh.
    pressed_keys: Vec<bool>,

    // These two are necessary for tracking key-repeat.
    last_pressed: Option<KeyCode>,
    current_pressed: Option<KeyCode>,
}

impl KeyboardContext {
    pub(crate) fn new() -> Self {
        // We reserve a fixed-size vec because we never want to have
        // to bother resizing it, but it is not easy to ask
        // Rust what an enum's max member is and a Sufficiently Big
        // fixed-size array `[bool; MAX_KEY_IDX]` doesn't implement
        // nice things like Debug.  :|
        // We have an assert everywhere pressed_keys is accessed so
        // we know if this assumption is broken.
        const MAX_KEY_IDX: usize = 256;
        let mut key_vec = Vec::with_capacity(MAX_KEY_IDX);
        key_vec.resize(MAX_KEY_IDX, false);
        Self {
            active_modifiers: KeyMods::empty(),
            pressed_keys: key_vec,
            last_pressed: None,
            current_pressed: None,
        }
    }

    // TODO: Set modifiers correctly
    // and in general cmake sure this is hooked up correctly
    // from Context::process_event().
    // Looks like it is, but, not 100% sure.
    pub(crate) fn set_key(&mut self, key: KeyCode, pressed: bool) {
        let key_idx = key as usize;
        assert!(
            key_idx < self.pressed_keys.len(),
            "Impossible KeyCode detected!"
        );
        self.pressed_keys[key_idx] = pressed;
        if pressed {
            self.last_pressed = self.current_pressed;
            self.current_pressed = Some(key);
        } else {
            self.current_pressed = None;
            // Double check that this edge handling is necessary;
            // winit sounds like it should do this for us,
            // see https://docs.rs/winit/0.16.1/winit/struct.KeyboardInput.html#structfield.modifiers
            match key {
                KeyCode::LShift | KeyCode::RShift => self.active_modifiers -= KeyMods::SHIFT,
                KeyCode::LControl | KeyCode::RControl => self.active_modifiers -= KeyMods::CTRL,
                KeyCode::LAlt | KeyCode::RAlt => self.active_modifiers -= KeyMods::ALT,
                KeyCode::LWin | KeyCode::RWin => self.active_modifiers -= KeyMods::LOGO,
                _ => (),
            }
        }
    }

    // TODO: Merge into set_key?
    pub(crate) fn set_modifiers(&mut self, keymods: KeyMods) {
        self.active_modifiers = keymods;
    }

    pub(crate) fn is_key_pressed(&self, key: KeyCode) -> bool {
        let key_idx = key as usize;
        assert!(
            key_idx < self.pressed_keys.len(),
            "Impossible KeyCode detected!"
        );
        self.pressed_keys[key_idx]
    }

    pub(crate) fn is_key_repeated(&self) -> bool {
        if self.last_pressed.is_some() {
            self.last_pressed == self.current_pressed
        } else {
            false
        }
    }

    pub(crate) fn pressed_keys(&self) -> Vec<KeyCode> {
        self.pressed_keys
            .iter()
            .enumerate()
            .filter_map(|(key_idx, b)| {
                if *b {
                    // Sigh
                    // Horrible unsafe pointer cast to turn a number
                    // into the matching KeyCode, because Rust's support
                    // for C-like numeric enums is UTTER GARBAGE.
                    // Can we protect this with an assertion somehow?
                    // I don't even see a way to get the max element of an
                    // enum.
                    let keycode: &KeyCode =
                        unsafe { &*(&key_idx as *const usize as *const KeyCode) };
                    Some(*keycode)
                } else {
                    None
                }
            })
            .collect()
    }

    pub(crate) fn active_mods(&self) -> KeyMods {
        self.active_modifiers
    }
}

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

/// Checks if a key is currently pressed down.
pub fn is_key_pressed(ctx: &Context, key: KeyCode) -> bool {
    ctx.keyboard_context.is_key_pressed(key)
}

/// Checks if the last keystroke sent by the system is repeated,
/// like when a key is held down for a period of time.
pub fn is_key_repeated(ctx: &Context) -> bool {
    ctx.keyboard_context.is_key_repeated()
}

/// Returns a Vec with currently pressed keys.
pub fn get_pressed_keys(ctx: &Context) -> Vec<KeyCode> {
    ctx.keyboard_context.pressed_keys()
}

/// Checks if keyboard modifier (or several) is active.
pub fn is_mod_active(ctx: &Context, keymods: KeyMods) -> bool {
    ctx.keyboard_context.active_mods().contains(keymods)
}

/// Returns currently active keyboard modifiers.
pub fn get_active_mods(ctx: &Context) -> KeyMods {
    ctx.keyboard_context.active_mods()
}

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

    #[test]
    fn key_mod_conversions() {
        assert_eq!(
            KeyMods::empty(),
            KeyMods::from(ModifiersState {
                shift: false,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT | KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: true,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT | KeyMods::ALT | KeyMods::CTRL,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: true,
                alt: true,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT - KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            (KeyMods::SHIFT | KeyMods::ALT) - KeyMods::ALT,
            KeyMods::from(ModifiersState {
                shift: true,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
        assert_eq!(
            KeyMods::SHIFT - (KeyMods::ALT | KeyMods::SHIFT),
            KeyMods::from(ModifiersState {
                shift: false,
                ctrl: false,
                alt: false,
                logo: false,
            })
        );
    }

    #[test]
    fn pressed_keys_tracking() {
        let mut keyboard = KeyboardContext::new();
        assert_eq!(keyboard.pressed_keys(), &[]);
        assert!(!keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::A]);
        assert!(keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.pressed_keys(), &[]);
        assert!(!keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::A]);
        assert!(keyboard.is_key_pressed(KeyCode::A));
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::A]);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::A, KeyCode::B]);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::A, KeyCode::B]);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::B]);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.pressed_keys(), &[KeyCode::B]);
        keyboard.set_key(KeyCode::B, false);
        assert_eq!(keyboard.pressed_keys(), &[]);
    }

    #[test]
    fn keyboard_modifiers() {
        let mut keyboard = KeyboardContext::new();

        // this test is mostly useless and is primarily for code coverage
        assert_eq!(keyboard.active_mods(), KeyMods::default());
        keyboard.set_modifiers(KeyMods::from(ModifiersState {
            shift: true,
            ctrl: true,
            alt: true,
            logo: true,
        }));

        // these test the workaround for https://github.com/tomaka/winit/issues/600
        assert_eq!(keyboard.active_mods(), KeyMods::SHIFT | KeyMods::CTRL | KeyMods::ALT | KeyMods::LOGO);
        keyboard.set_key(KeyCode::LControl, false);
        assert_eq!(keyboard.active_mods(), KeyMods::SHIFT | KeyMods::ALT | KeyMods::LOGO);
        keyboard.set_key(KeyCode::RAlt, false);
        assert_eq!(keyboard.active_mods(), KeyMods::SHIFT | KeyMods::LOGO);
        keyboard.set_key(KeyCode::LWin, false);
        assert_eq!(keyboard.active_mods(), KeyMods::SHIFT);
    }

    #[test]
    fn repeated_keys_tracking() {
        let mut keyboard = KeyboardContext::new();
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), true);
        keyboard.set_key(KeyCode::A, false);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::A, true);
        assert_eq!(keyboard.is_key_repeated(), true);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), false);
        keyboard.set_key(KeyCode::B, true);
        assert_eq!(keyboard.is_key_repeated(), true);
    }
}
<|endoftext|>


<commit_before>
extern crate sysfs_gpio;
extern crate sysfs_pwm;

use self::sysfs_gpio::{Direction, Pin};
use self::sysfs_pwm::{Pwm};
use ::std::error::Error;

use super::{PinProxyContract,PwmProxyContract,DirectionProxied,ProxyError,ProxyResult};

pub struct PinProxy {
	pin : Pin,
}

impl PinProxyContract for PinProxy
{
	fn new(pin_num: u64) -> PinProxy {
		PinProxy{ pin: Pin::new(pin_num) }
	}

	fn export(&self) ->  ProxyResult<()>{
		match self.pin.export()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn unexport(&self) ->  ProxyResult<()> {
		match self.pin.unexport()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_value(&self, value: u8) ->  ProxyResult<()> {
		match self.pin.set_value(value)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>{
		let dirmapped =  match dir {
										DirectionProxied::In =>  Direction::In,
										DirectionProxied::Out => Direction::Out,
										DirectionProxied::High => Direction::High,
										DirectionProxied::Low => Direction::Low,
									};
		match self.pin.set_direction(dirmapped)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}
}

pub struct PwmProxy {
	pwm : Pwm,
}

impl PwmProxyContract for PwmProxy
{
	fn new(chip: u32, number: u32) -> ProxyResult<PwmProxy>{

		match Pwm::new(chip, number) {
			Ok(pwm) => Ok(PwmProxy{ pwm: pwm}),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn export(&self) ->  ProxyResult<()>{
		match self.pwm.export()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn unexport(&self) ->  ProxyResult<()> {
		match self.pwm.unexport()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn enable(&self, enable: bool) -> ProxyResult<()>
	{
		match self.pwm.enable(enable)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{} caused by {}",result.description(),result.cause().unwrap());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_duty_cycle_ns(&self, duty_cycle_ns: u32) -> ProxyResult<()>
	{
		match self.pwm.set_duty_cycle_ns(duty_cycle_ns)
		{
			Ok(()) => {println!("setting dutycycle {}",duty_cycle_ns); Ok(())},
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_period_ns(&self, period_ns: u32) -> ProxyResult<()>
	{
		match self.pwm.set_period_ns(period_ns)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn get_period_ns(&self) -> ProxyResult<u32>
	{
		match self.pwm.get_period_ns()
		{
			Ok(result) => Ok(result),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}

	}

	fn increase_to_max(&self, duration_ms: u32, update_period_ms: u32)
	{
			let step: f32 = (duration_ms as f32 / update_period_ms as f32) / 1000.0;
			println!("step {}",step);
			let mut duty_cycle = 0.0;
			match self.pwm.get_period_ns()
			{
				Ok(period_ns) => {
				println!("period {}",period_ns);
					while duty_cycle < 1.0 {
						println!("duty cycle {}",duty_cycle);
						println!("set duty cycle ns{}",(duty_cycle * period_ns as f32) as u32);
						self.pwm.set_duty_cycle_ns((duty_cycle * period_ns as f32) as u32).unwrap();
						duty_cycle += step;
					}
					self.pwm.set_duty_cycle_ns(period_ns).unwrap()
				}
				Err(result) => {println!("{}",result.description())}
			}
	}

	fn decrease_to_minimum(&self, duration_ms: u32, update_period_ms: u32)
	{
		let step: f32 = (duration_ms as f32 / update_period_ms as f32) / 1000.0;
		println!("step {}",step);
		let mut duty_cycle = 1.0;
		match self.pwm.get_period_ns()
		{
			Ok(period_ns) => {
			println!("period {}",period_ns);
				while duty_cycle > 0.0 {
					println!("duty cycle {}",duty_cycle);
					println!("set duty cycle ns{}",(duty_cycle * period_ns as f32) as u32);
						self.pwm.set_duty_cycle_ns((duty_cycle * period_ns as f32) as u32).unwrap();
						duty_cycle -= step;
				}
				self.pwm.set_duty_cycle_ns(0).unwrap()
			}
			Err(result) => {println!("{}",result.description())}
		}
	}
}<commit_msg>delay<commit_after>
extern crate sysfs_gpio;
extern crate sysfs_pwm;

use self::sysfs_gpio::{Direction, Pin};
use self::sysfs_pwm::{Pwm};
use ::std::error::Error;
use std::thread;
use std::time;

use super::{PinProxyContract,PwmProxyContract,DirectionProxied,ProxyError,ProxyResult};

pub struct PinProxy {
	pin : Pin,
}

impl PinProxyContract for PinProxy
{
	fn new(pin_num: u64) -> PinProxy {
		PinProxy{ pin: Pin::new(pin_num) }
	}

	fn export(&self) ->  ProxyResult<()>{
		match self.pin.export()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn unexport(&self) ->  ProxyResult<()> {
		match self.pin.unexport()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_value(&self, value: u8) ->  ProxyResult<()> {
		match self.pin.set_value(value)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>{
		let dirmapped =  match dir {
										DirectionProxied::In =>  Direction::In,
										DirectionProxied::Out => Direction::Out,
										DirectionProxied::High => Direction::High,
										DirectionProxied::Low => Direction::Low,
									};
		match self.pin.set_direction(dirmapped)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}
}

pub struct PwmProxy {
	pwm : Pwm,
}

impl PwmProxyContract for PwmProxy
{
	fn new(chip: u32, number: u32) -> ProxyResult<PwmProxy>{

		match Pwm::new(chip, number) {
			Ok(pwm) => Ok(PwmProxy{ pwm: pwm}),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn export(&self) ->  ProxyResult<()>{
		match self.pwm.export()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn unexport(&self) ->  ProxyResult<()> {
		match self.pwm.unexport()
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn enable(&self, enable: bool) -> ProxyResult<()>
	{
		match self.pwm.enable(enable)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{} caused by {}",result.description(),result.cause().unwrap());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_duty_cycle_ns(&self, duty_cycle_ns: u32) -> ProxyResult<()>
	{
		match self.pwm.set_duty_cycle_ns(duty_cycle_ns)
		{
			Ok(()) => {println!("setting dutycycle {}",duty_cycle_ns); Ok(())},
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn set_period_ns(&self, period_ns: u32) -> ProxyResult<()>
	{
		match self.pwm.set_period_ns(period_ns)
		{
			Ok(()) => Ok(()),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}
	}

	fn get_period_ns(&self) -> ProxyResult<u32>
	{
		match self.pwm.get_period_ns()
		{
			Ok(result) => Ok(result),
			Err(result) => {println!("{}",result.description());
				Err(ProxyError::MonErreur)},
		}

	}

	fn increase_to_max(&self, duration_ms: u32, update_period_ms: u32)
	{
		let step: f32 = (duration_ms as f32 / update_period_ms as f32) / 1000.0;
		println!("step {}",step);
		let mut duty_cycle = 0.0;
		match self.pwm.get_period_ns()
		{
			Ok(period_ns) => {
			println!("period {}",period_ns);
				while duty_cycle < 1.0 {
					println!("duty cycle {}",duty_cycle);
					println!("set duty cycle ns{}",(duty_cycle * period_ns as f32) as u32);
					self.pwm.set_duty_cycle_ns((duty_cycle * period_ns as f32) as u32).unwrap();
					duty_cycle += step;
					thread::sleep(time::Duration::from_millis(20));
				}
				self.pwm.set_duty_cycle_ns(period_ns).unwrap()
			}
			Err(result) => {println!("{}",result.description())}
		}
	}

	fn decrease_to_minimum(&self, duration_ms: u32, update_period_ms: u32)
	{
		let step: f32 = (duration_ms as f32 / update_period_ms as f32) / 1000.0;
		println!("step {}",step);
		let mut duty_cycle = 1.0;
		match self.pwm.get_period_ns()
		{
			Ok(period_ns) => {
			println!("period {}",period_ns);
				while duty_cycle > 0.0 {
					println!("duty cycle {}",duty_cycle);
					println!("set duty cycle ns{}",(duty_cycle * period_ns as f32) as u32);
					self.pwm.set_duty_cycle_ns((duty_cycle * period_ns as f32) as u32).unwrap();
					duty_cycle -= step;
					thread::sleep(time::Duration::from_millis(20));
				}
				self.pwm.set_duty_cycle_ns(0).unwrap()
			}
			Err(result) => {println!("{}",result.description())}
		}
	}
}<|endoftext|>