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
use linked_hash_set::LinkedHashSet;
use rayon::slice::ParallelSliceMut;
use specs::{Component, VecStorage};
use crate::Vec2;
#[derive(Default, Component)]
#[storage(VecStorage)]
pub struct ChunkRequestsComp {
pub pending: LinkedHashSet<Vec2<i32>>,
pub loaded: LinkedHashSet<Vec2<i32>>,
}
impl ChunkRequestsComp {
pub fn new() -> Self {
Self::default()
}
pub fn add(&mut self, coords: &Vec2<i32>) {
self.pending.insert(coords.to_owned());
}
pub fn mark_finish(&mut self, coords: &Vec2<i32>) {
self.pending.remove(coords);
self.loaded.insert(coords.to_owned());
}
pub fn unload(&mut self, coords: &Vec2<i32>) {
self.pending.remove(coords);
self.loaded.remove(coords);
}
pub fn sort_pending(&mut self, center: &Vec2<i32>) {
let Vec2(cx, cz) = center;
let mut pendings: Vec<Vec2<i32>> = self.pending.clone().into_iter().collect();
pendings.par_sort_by(|c1, c2| {
let dist1 = (c1.0 - cx).pow(2) + (c1.1 - cz).pow(2);
let dist2 = (c2.0 - cx).pow(2) + (c2.1 - cz).pow(2);
dist1.cmp(&dist2)
});
let list = LinkedHashSet::from_iter(pendings.into_iter());
self.pending = list;
}
pub fn is_interested(&self, coords: &Vec2<i32>) -> bool {
self.loaded.contains(coords)
}
pub fn has(&self, coords: &Vec2<i32>) -> bool {
self.pending.contains(coords) || self.loaded.contains(coords)
}
}