use bevy::reflect::Reflect;
use crate::flowfields::{
fields::{Field, FieldCell},
utilities::FIELD_RESOLUTION,
};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone, Reflect, Debug)]
pub struct CostField {
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
field: [u8; FIELD_RESOLUTION * FIELD_RESOLUTION],
}
impl Default for CostField {
fn default() -> Self {
CostField {
field: [1_u8; FIELD_RESOLUTION * FIELD_RESOLUTION],
}
}
}
impl Field<u8> for CostField {
fn get(&self) -> &[u8; FIELD_RESOLUTION * FIELD_RESOLUTION] {
&self.field
}
fn get_field_cell_value(&self, field_cell: FieldCell) -> u8 {
let index = field_cell.as_1d_index();
self.field[index]
}
fn set_field_cell_value(&mut self, value: u8, field_cell: FieldCell) {
let index = field_cell.as_1d_index();
self.field[index] = value;
}
}
impl CostField {
pub fn new_with_cost(cost: u8) -> Self {
CostField {
field: [cost; FIELD_RESOLUTION * FIELD_RESOLUTION],
}
}
#[cfg(feature = "ron")]
pub fn from_ron(path: String) -> Self {
let file = std::fs::File::open(path).expect("Failed opening CostField file");
let field: CostField = match ron::de::from_reader(file) {
Ok(field) => field,
Err(e) => panic!("Failed deserializing CostField: {}", e),
};
field
}
}
#[rustfmt::skip]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn update() {
let mut field = CostField::new_with_cost(5);
let cell = FieldCell::new(3, 6);
field.set_field_cell_value(128, cell);
let actual = 128;
let result = field.get_field_cell_value(cell);
assert_eq!(actual, result);
}
#[test]
fn custom_cost() {
let costfield = CostField::new_with_cost(7);
let value = costfield.get_field_cell_value(FieldCell::from_index(4));
assert!(value == 7);
}
#[test]
fn ron() {
let path = env!("CARGO_MANIFEST_DIR").to_string() + "/assets/costfield_impassable.ron";
let costfield = CostField::from_ron(path);
let value = costfield.get_field_cell_value(FieldCell::new(5, 1));
assert!(value == 255);
}
}