1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#![warn(dead_code)]
#![deny(missing_docs)]
pub mod context;
pub mod log;
pub mod timing;
use context::{Context, Story, Request};
use log::{Log, event::{Receiver}};
use std::sync::{Arc, RwLock};
use std::thread::{sleep, spawn};
use timing::{RevLimiter};
macro_rules! inner_loop {
($method: ident, $state: ident, $cycles_per_second: ident) => {
let mut rev_limiter = RevLimiter::new_from_frequency(false, false, $cycles_per_second, 1.0);
loop {
let delta = rev_limiter.begin();
match $state.story.$method(delta, &$state.log) {
Request::Continue => (),
Request::Stop => {
match $state.stop_request.write() {
Ok (mut stop) => *stop = true,
Err (_) => ()
}
break;
}
}
match $state.stop_request.read() {
Ok (stop) => if *stop { break; },
Err (_) => ()
}
let wait = rev_limiter.next();
sleep(wait);
}
};
}
struct GameState {
pub log: Log,
pub story: Story,
pub stop_request: RwLock<bool>
}
pub struct Game {
state: Arc<GameState>
}
impl Game {
pub fn new () -> Self {
return Self {
state: Arc::new(GameState {
log: Log::new(),
story: Story::new(),
stop_request: RwLock::new(false)
})
};
}
pub fn push_story_context (&mut self, context: Box<Context + Send + Sync>) {
self.state.story.push_context(context);
}
pub fn add_log_receiver (&mut self, receiver: Box<Receiver + Send + Sync>) {
self.state.log.add_receiver(receiver);
}
pub fn run (&mut self, frames_per_second: u32, ticks_per_second: u32) {
match self.state.stop_request.write() {
Ok (mut stop) => *stop = false,
Err (_) => ()
}
let update_loop_state = self.state.clone();
let update_loop = spawn(move || {
inner_loop!(update, update_loop_state, ticks_per_second);
});
let render_loop_state = self.state.clone();
inner_loop!(render, render_loop_state, frames_per_second);
let _ = update_loop.join();
}
}