Ver código fonte

Allow setting frames per second

Johannes Hofmann 8 anos atrás
pai
commit
7b21669c01
2 arquivos alterados com 35 adições e 3 exclusões
  1. 15
    0
      src/config.rs
  2. 20
    3
      src/main.rs

+ 15
- 0
src/config.rs Ver arquivo

@@ -13,6 +13,7 @@ static DEFAULT_CONFIG: &'static str = include_str!("../default_config.toml");
13 13
 pub struct Config {
14 14
     tile_cache_dir: PathBuf,
15 15
     sources: Vec<(String, TileSource)>,
16
+    fps: f64,
16 17
 }
17 18
 
18 19
 impl Config {
@@ -67,6 +68,15 @@ impl Config {
67 68
                     }
68 69
                 };
69 70
 
71
+                let fps = {
72
+                    match table.get("fps") {
73
+                        Some(&Value::Float(fps)) => fps,
74
+                        Some(&Value::Integer(fps)) => fps as f64,
75
+                        Some(_) => return Err("fps has to be an integer or a float.".to_string()),
76
+                        None => 60.0,
77
+                    }
78
+                };
79
+
70 80
                 let sources_table = table.get("tile_sources")
71 81
                     .ok_or_else(|| "missing \"tile_sources\" table".to_string())?
72 82
                     .as_table()
@@ -120,6 +130,7 @@ impl Config {
120 130
                     Config {
121 131
                         tile_cache_dir: tile_cache_dir,
122 132
                         sources: sources_vec,
133
+                        fps: fps,
123 134
                     }
124 135
                 )
125 136
             },
@@ -140,6 +151,10 @@ impl Config {
140 151
     pub fn tile_sources(&self) -> &[(String, TileSource)] {
141 152
         &self.sources
142 153
     }
154
+
155
+    pub fn fps(&self) -> f64 {
156
+        self.fps
157
+    }
143 158
 }
144 159
 
145 160
 #[cfg(test)]

+ 20
- 3
src/main.rs Ver arquivo

@@ -30,6 +30,7 @@ use clap::Arg;
30 30
 use coord::ScreenCoord;
31 31
 use glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode};
32 32
 use map_view_gl::MapViewGl;
33
+use std::error::Error;
33 34
 use std::time::{Duration, Instant};
34 35
 use tile_source::TileSource;
35 36
 
@@ -170,6 +171,17 @@ fn main() {
170 171
             .value_name("FILE")
171 172
             .help("Set a custom config file")
172 173
             .takes_value(true))
174
+        .arg(Arg::with_name("fps")
175
+            .long("fps")
176
+            .value_name("FPS")
177
+            .validator(|s| {
178
+                s.parse::<f64>()
179
+                    .map(|_| ())
180
+                    .map_err(|e| e.description().to_string())
181
+            })
182
+            .help("Set target frames per second (default is 60). \
183
+                  This should equal the refresh rate of the display.")
184
+            .takes_value(true))
173 185
         .arg(Arg::with_name("offline")
174 186
             .long("offline")
175 187
             .help("Do not use the network"))
@@ -209,7 +221,12 @@ fn main() {
209 221
         mouse_pressed: false,
210 222
     };
211 223
 
212
-    let milli16 = Duration::from_millis(16);
224
+    let fps: f64 = matches.value_of("fps").map(|s| s.parse().unwrap()).unwrap_or(config.fps());
225
+    let duration_per_frame = Duration::from_millis((1000.0 / fps - 0.5).max(0.0).floor() as u64);
226
+    info!("milliseconds per frame: {}",
227
+          duration_per_frame.as_secs() as f64 * 1000.0
228
+          + duration_per_frame.subsec_nanos() as f64 * 1e-6);
229
+
213 230
     let mut draw_dur = Duration::from_millis(8);
214 231
     let mut last_draw = Instant::now();
215 232
 
@@ -238,8 +255,8 @@ fn main() {
238 255
 
239 256
         {
240 257
             let diff = last_draw.elapsed();
241
-            if diff + draw_dur * 2 < milli16 {
242
-                if let Some(dur) = milli16.checked_sub(draw_dur * 2) {
258
+            if diff + draw_dur * 2 < duration_per_frame {
259
+                if let Some(dur) = duration_per_frame.checked_sub(draw_dur * 2) {
243 260
                     std::thread::sleep(dur);
244 261
 
245 262
                     for event in window.poll_events() {