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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
extern crate core;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
use crate::data::Game;
use crate::lazy_static::__Deref;
use std::collections::HashSet;
use std::sync::{Mutex, MutexGuard};
use stdweb::js;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
pub mod data;
pub mod logging;
lazy_static! {
static ref GAME: Mutex<Game> = Mutex::new(Game::new());
}
pub fn game<'a>() -> MutexGuard<'a, Game> {
GAME.lock().unwrap()
}
pub fn init_screeps_connection(game_loop: &'static dyn Fn(&Game)) {
std::panic::set_hook(Box::new(|info| {
let msg = &info.to_string();
let panic_message = msg.to_owned();
js! { @(no_return)
console.error( @{msg} );
}
panic!(panic_message);
}));
logging::setup_logging(logging::Info);
info!(
"Global Reset! Compile took: {}",
screeps::game::cpu::get_used()
);
let _game_loop = move || {
debug!("loop starting! CPU: {}", screeps::game::cpu::get_used());
game().refresh_state();
game_loop(game().deref());
let time = screeps::game::time();
if time % 128 == 3 {
info!("running memory cleanup");
cleanup_memory().expect("expected Memory.creeps format to be a regular memory object");
}
debug!("done! cpu: {}", screeps::game::cpu::get_used())
};
js! {
Error.stackTraceLimit = 25;
var game_loop = @{_game_loop};
module.exports.loop = function() {
if(Game.cpu.bucket < 500){
console.log("we are running out of time!" + JSON.stringify(Game.cpu));
return;
}
try {
game_loop();
} catch (error) {
console_error("caught exception:", error);
if (error.stack) {
console_error("stack trace:", error.stack);
}
console_error("resetting VM next tick.");
module.exports.loop = wasm_initialize;
}
}
}
}
fn cleanup_memory() -> Result<(), Box<dyn (::std::error::Error)>> {
let alive_creeps: HashSet<String> = screeps::game::creeps::keys().into_iter().collect();
let screeps_memory = match screeps::memory::root().dict("creeps")? {
Some(v) => v,
None => {
warn!("not cleaning game creep memory: no Memory.creeps dict");
return Ok(());
}
};
for mem_name in screeps_memory.keys() {
if !alive_creeps.contains(&mem_name) {
debug!("cleaning up creep memory of dead creep {}", mem_name);
screeps_memory.del(&mem_name);
}
}
Ok(())
}