use crate::action::ActionDescriptor;
use crate::authoring::model::agent_model::AgentLanes;
use crate::authoring::model::field::Extent;
use crate::network::Network;
use crate::params::{ParamDescriptor, ParamValue};
use crate::view::{StatDescriptor, StatValue};
#[derive(Clone, Copy, Debug)]
pub struct SpringParams {
pub spring: f32,
pub length: f32,
pub repulsion: f32,
pub cutoff: f32,
pub saturation: f32,
}
impl SpringParams {
pub const DEFAULT: Self = Self {
spring: 0.3,
length: 1.0,
repulsion: 0.05,
cutoff: 2.5,
saturation: 1.0,
};
}
pub struct Nodes<'a, N: NetworkModel + ?Sized> {
pub lanes: &'a mut N::Lanes,
pub graph: &'a mut Network,
pub aux: &'a mut N::Aux,
}
impl<N: NetworkModel + ?Sized> std::fmt::Debug for Nodes<'_, N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Nodes")
.field("graph", &self.graph)
.finish_non_exhaustive()
}
}
impl<N: NetworkModel + ?Sized> Nodes<'_, N> {
pub fn spawn(&mut self) -> u32 {
let i = self.graph.spawn();
self.lanes.grow(self.graph.slot_count());
i
}
pub fn retire(&mut self, i: u32) {
self.graph.retire(i);
let (pos_x, pos_y) = self.lanes.positions_mut();
if let (Some(x), Some(y)) = (pos_x.get_mut(i as usize), pos_y.get_mut(i as usize)) {
*x = f32::NAN;
*y = f32::NAN;
}
}
}
pub struct NodeCtx<'a, N: NetworkModel + ?Sized> {
pub graph: &'a Network,
pub params: &'a N::Params,
pub extent: Extent,
}
impl<N: NetworkModel + ?Sized> std::fmt::Debug for NodeCtx<'_, N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NodeCtx")
.field("graph", &self.graph)
.field("extent", &self.extent)
.finish_non_exhaustive()
}
}
pub trait NetworkModel: Send + Sync + 'static {
const NAME: &'static str;
const ID: &'static str;
const DESCRIPTION: &'static str;
const PALETTE: &'static [[u8; 4]];
const EDGE_PALETTE: &'static [[u8; 4]];
const STATS: &'static [StatDescriptor];
const ACTIONS: &'static [ActionDescriptor] = &[];
const CHUNK: usize = 512;
const DEFAULT_NODES: u32;
const MAX_NODES: u32 = 10_000_000;
const DEFAULT_EXTENT: Extent;
const LAYOUT: SpringParams = SpringParams::DEFAULT;
type Lanes: AgentLanes;
type Params: Send + Sync;
type Aux: Default + Send + 'static;
fn param_descriptors() -> Vec<ParamDescriptor>;
fn from_params(params: &[ParamValue], extent: Extent) -> Self::Params;
fn directed(_params: &Self::Params) -> bool {
false
}
fn init(nodes: &mut Nodes<'_, Self>, extent: Extent, params: &[ParamValue], rng: &mut u64);
fn run_global_pass(
_nodes: &mut Nodes<'_, Self>,
_params: &Self::Params,
_extent: Extent,
_rng: &mut u64,
_tick: u64,
) {
}
fn run_node_pass(_lanes: &mut Self::Lanes, _ctx: &NodeCtx<'_, Self>, _seed: u64, _tick: u64) {}
fn act(_action: usize, _nodes: &mut Nodes<'_, Self>, _extent: Extent, _params: &[ParamValue], _rng: &mut u64) {}
fn prepare_view(_nodes: &mut Nodes<'_, Self>, _tick: u64) {}
fn stats(lanes: &Self::Lanes, graph: &Network, aux: &Self::Aux) -> Vec<StatValue>;
fn aux_heap_bytes(_aux: &Self::Aux) -> usize {
0
}
}