screeps_pathfinding/utils/cache/
terrain_cache_struct.rs

1use std::collections::HashMap;
2
3use screeps::{LocalRoomTerrain, RoomName};
4
5/// A simple passthrough cache that preferentially returns cached
6/// terrain data, dynamically pulling terrain data as-needed
7/// from game state and caching it before returning it.
8#[derive(Debug, Clone)]
9pub struct TerrainCache {
10    cache: HashMap<RoomName, LocalRoomTerrain>,
11}
12
13impl Default for TerrainCache {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl TerrainCache {
20    /// Initializes a new, empty terrain cache.
21    pub fn new() -> Self {
22        Self {
23            cache: HashMap::new(),
24        }
25    }
26
27    /// Returns the cached room terrain, if it exists.
28    ///
29    /// Returns None if the room terrain isn't cached.
30    pub fn get_cached_terrain(&self, room_name: &RoomName) -> Option<&LocalRoomTerrain> {
31        self.cache.get(room_name)
32    }
33
34    /// Returns whether the terrain is cached for a particular room.
35    pub fn is_terrain_cached(&self, room_name: &RoomName) -> bool {
36        self.cache.contains_key(room_name)
37    }
38
39    /// Returns the room terrain, pulling and caching it from the game state if it's not already cached.
40    ///
41    /// Returns None only if [screeps::objects::RoomTerrain::new] returns None.
42    ///
43    /// Note: This method can, but might not, pull from the game state, which requires crossing the WASM boundary.
44    pub fn get_terrain(&mut self, room_name: &RoomName) -> Option<&LocalRoomTerrain> {
45        if !self.is_terrain_cached(room_name) {
46            // We don't have a cached copy of the terrain, pull it and cache it
47            let js_terrain_opt = screeps::objects::RoomTerrain::new(*room_name);
48            if let Some(js_terrain) = js_terrain_opt {
49                let local_terrain = screeps::local::LocalRoomTerrain::from(js_terrain);
50                let _ = self.cache.insert(*room_name, local_terrain);
51            }
52        }
53
54        self.get_cached_terrain(room_name)
55    }
56
57    /// Updates the terrain cache for a specific room.
58    ///
59    /// This allows for pre-loading the cache with any existing
60    /// room terrain you might already have available.
61    pub fn update_cached_terrain(&mut self, room_name: RoomName, local_terrain: LocalRoomTerrain) {
62        let _ = self.cache.insert(room_name, local_terrain);
63    }
64
65    /// Removes the terrain cached for a specific room.
66    pub fn remove_cached_terrain(&mut self, room_name: &RoomName) {
67        self.cache.remove(room_name);
68    }
69}