use crate::params::{ParamDescriptor, ParamValue};
use crate::view::GridView;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Extent {
pub w: f32,
pub h: f32,
}
impl Extent {
pub fn cells(self) -> (u32, u32) {
(self.w.max(1.0) as u32, self.h.max(1.0) as u32)
}
}
pub trait FieldLayer: Send + 'static {
const HAS_GRID: bool = true;
const KIND: &'static str;
type Params: Send + Sync;
type Read<'a>
where
Self: 'a;
type DepositLanes: Send + 'static;
fn param_descriptors() -> Vec<ParamDescriptor>;
fn from_params(params: &[ParamValue]) -> Self::Params;
fn new(extent: Extent, params: &[ParamValue]) -> Self;
fn read(&self) -> Self::Read<'_>;
fn alloc_deposits(&self, n: usize) -> Self::DepositLanes;
fn update(&mut self, deposits: &Self::DepositLanes, p: &Self::Params, tick: u64);
fn prepare_view(&mut self) {}
fn grid_view(&self) -> Option<GridView<'_>>;
fn cell_count(&self) -> usize;
fn heap_bytes(&self) -> usize;
}
#[derive(Debug)]
pub struct NoField;
impl FieldLayer for NoField {
const HAS_GRID: bool = false;
const KIND: &'static str = "None";
type Params = ();
type Read<'a> = ();
type DepositLanes = ();
fn param_descriptors() -> Vec<ParamDescriptor> {
Vec::new()
}
fn from_params(_params: &[ParamValue]) {}
fn new(_extent: Extent, _params: &[ParamValue]) -> Self {
Self
}
fn read(&self) {}
fn alloc_deposits(&self, _n: usize) {}
fn update(&mut self, _deposits: &(), _p: &(), _tick: u64) {}
fn grid_view(&self) -> Option<GridView<'_>> {
None
}
fn cell_count(&self) -> usize {
0
}
fn heap_bytes(&self) -> usize {
0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extent_rounds_down_to_whole_cells() {
assert_eq!(Extent { w: 200.0, h: 200.0 }.cells(), (200, 200));
assert_eq!(Extent { w: 10.9, h: 4.2 }.cells(), (10, 4));
}
#[test]
fn extent_never_collapses_below_one_cell() {
assert_eq!(Extent { w: 0.0, h: 0.0 }.cells(), (1, 1));
assert_eq!(Extent { w: -5.0, h: 0.4 }.cells(), (1, 1));
}
}