瀏覽代碼

Allow setting frames per second

Johannes Hofmann 8 年之前
父節點
當前提交
7b21669c01
共有 2 個檔案被更改,包括 35 行新增3 行删除
  1. 15
    0
      src/config.rs
  2. 20
    3
      src/main.rs

+ 15
- 0
src/config.rs 查看文件

13
 pub struct Config {
13
 pub struct Config {
14
     tile_cache_dir: PathBuf,
14
     tile_cache_dir: PathBuf,
15
     sources: Vec<(String, TileSource)>,
15
     sources: Vec<(String, TileSource)>,
16
+    fps: f64,
16
 }
17
 }
17
 
18
 
18
 impl Config {
19
 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
                 let sources_table = table.get("tile_sources")
80
                 let sources_table = table.get("tile_sources")
71
                     .ok_or_else(|| "missing \"tile_sources\" table".to_string())?
81
                     .ok_or_else(|| "missing \"tile_sources\" table".to_string())?
72
                     .as_table()
82
                     .as_table()
120
                     Config {
130
                     Config {
121
                         tile_cache_dir: tile_cache_dir,
131
                         tile_cache_dir: tile_cache_dir,
122
                         sources: sources_vec,
132
                         sources: sources_vec,
133
+                        fps: fps,
123
                     }
134
                     }
124
                 )
135
                 )
125
             },
136
             },
140
     pub fn tile_sources(&self) -> &[(String, TileSource)] {
151
     pub fn tile_sources(&self) -> &[(String, TileSource)] {
141
         &self.sources
152
         &self.sources
142
     }
153
     }
154
+
155
+    pub fn fps(&self) -> f64 {
156
+        self.fps
157
+    }
143
 }
158
 }
144
 
159
 
145
 #[cfg(test)]
160
 #[cfg(test)]

+ 20
- 3
src/main.rs 查看文件

30
 use coord::ScreenCoord;
30
 use coord::ScreenCoord;
31
 use glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode};
31
 use glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode};
32
 use map_view_gl::MapViewGl;
32
 use map_view_gl::MapViewGl;
33
+use std::error::Error;
33
 use std::time::{Duration, Instant};
34
 use std::time::{Duration, Instant};
34
 use tile_source::TileSource;
35
 use tile_source::TileSource;
35
 
36
 
170
             .value_name("FILE")
171
             .value_name("FILE")
171
             .help("Set a custom config file")
172
             .help("Set a custom config file")
172
             .takes_value(true))
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
         .arg(Arg::with_name("offline")
185
         .arg(Arg::with_name("offline")
174
             .long("offline")
186
             .long("offline")
175
             .help("Do not use the network"))
187
             .help("Do not use the network"))
209
         mouse_pressed: false,
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
     let mut draw_dur = Duration::from_millis(8);
230
     let mut draw_dur = Duration::from_millis(8);
214
     let mut last_draw = Instant::now();
231
     let mut last_draw = Instant::now();
215
 
232
 
238
 
255
 
239
         {
256
         {
240
             let diff = last_draw.elapsed();
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
                     std::thread::sleep(dur);
260
                     std::thread::sleep(dur);
244
 
261
 
245
                     for event in window.poll_events() {
262
                     for event in window.poll_events() {