screeps/local/
cost_matrix.rs1use std::ops::{Index, IndexMut};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 constants::ROOM_AREA,
7 objects::CostMatrix,
8 traits::{CostMatrixGet, CostMatrixSet},
9};
10
11use super::{linear_index_to_xy, Position, RoomXY, XMajor};
12
13#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(transparent)]
19pub struct LocalCostMatrix {
20 #[serde(with = "serde_impls")]
21 bits: [u8; ROOM_AREA],
22}
23
24impl Default for LocalCostMatrix {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl LocalCostMatrix {
31 #[inline]
43 pub const fn new() -> Self {
44 LocalCostMatrix::new_with_value(0)
45 }
46
47 #[inline]
59 pub const fn new_with_value(value: u8) -> Self {
60 LocalCostMatrix {
61 bits: [value; ROOM_AREA],
62 }
63 }
64
65 #[inline]
69 pub fn set(&mut self, xy: RoomXY, val: u8) {
70 self[xy] = val;
71 }
72
73 #[inline]
77 pub fn get(&self, xy: RoomXY) -> u8 {
78 self[xy]
79 }
80
81 pub const fn get_bits(&self) -> &[u8; ROOM_AREA] {
82 &self.bits
83 }
84
85 pub fn iter(&self) -> impl Iterator<Item = (RoomXY, u8)> + '_ {
86 self.bits
87 .iter()
88 .enumerate()
89 .map(|(idx, &val)| (linear_index_to_xy(idx), val))
90 }
91
92 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RoomXY, &mut u8)> {
93 self.bits
94 .iter_mut()
95 .enumerate()
96 .map(|(idx, val)| (linear_index_to_xy(idx), val))
97 }
98}
99
100impl From<LocalCostMatrix> for Vec<u8> {
101 #[inline]
104 fn from(lcm: LocalCostMatrix) -> Vec<u8> {
105 lcm.bits.into()
106 }
107}
108
109impl From<&LocalCostMatrix> for Vec<u8> {
110 fn from(lcm: &LocalCostMatrix) -> Vec<u8> {
111 lcm.bits.into()
112 }
113}
114
115impl From<&CostMatrix> for LocalCostMatrix {
116 fn from(js_matrix: &CostMatrix) -> Self {
117 let mut bits = [0; ROOM_AREA];
118 js_matrix.get_bits().copy_to(&mut bits);
119
120 LocalCostMatrix { bits }
121 }
122}
123
124impl AsRef<XMajor<u8>> for LocalCostMatrix {
125 fn as_ref(&self) -> &XMajor<u8> {
126 XMajor::from_flat_ref(&self.bits)
127 }
128}
129
130impl AsMut<XMajor<u8>> for LocalCostMatrix {
131 fn as_mut(&mut self) -> &mut XMajor<u8> {
132 XMajor::from_flat_mut(&mut self.bits)
133 }
134}
135
136impl Index<RoomXY> for LocalCostMatrix {
137 type Output = u8;
138
139 fn index(&self, xy: RoomXY) -> &Self::Output {
140 &self.bits[xy.x][xy.y]
141 }
142}
143
144impl IndexMut<RoomXY> for LocalCostMatrix {
145 fn index_mut(&mut self, xy: RoomXY) -> &mut Self::Output {
146 &mut self.bits[xy.x][xy.y]
147 }
148}
149
150impl Index<Position> for LocalCostMatrix {
151 type Output = u8;
152
153 fn index(&self, idx: Position) -> &Self::Output {
154 &self[RoomXY::from(idx)]
155 }
156}
157
158impl IndexMut<Position> for LocalCostMatrix {
159 fn index_mut(&mut self, idx: Position) -> &mut Self::Output {
160 &mut self[RoomXY::from(idx)]
161 }
162}
163
164impl CostMatrixSet for LocalCostMatrix {
165 fn set_xy(&mut self, xy: RoomXY, cost: u8) {
166 LocalCostMatrix::set(self, xy, cost);
167 }
168}
169
170impl CostMatrixGet for LocalCostMatrix {
171 fn get_xy(&mut self, xy: RoomXY) -> u8 {
172 LocalCostMatrix::get(self, xy)
173 }
174}
175
176mod serde_impls {
179 use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
180
181 use super::ROOM_AREA;
182
183 pub(super) fn serialize<S>(bits: &[u8; ROOM_AREA], serializer: S) -> Result<S::Ok, S::Error>
184 where
185 S: Serializer,
186 {
187 bits[..].serialize(serializer)
188 }
189
190 pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<[u8; ROOM_AREA], D::Error>
191 where
192 D: Deserializer<'de>,
193 {
194 let bits_slice: &[u8] = <&[u8]>::deserialize(deserializer)?;
195
196 if bits_slice.len() != ROOM_AREA {
197 return Err(D::Error::invalid_length(
198 bits_slice.len(),
199 &format!("a vec of length {ROOM_AREA}").as_str(),
200 ));
201 }
202
203 Ok(bits_slice.try_into().unwrap())
205 }
206}