use super::{model::ModelInstance, GeneratedNode, Generator};
use crate::grid::{
coordinate_system::CoordinateSystem,
grid::{Grid, GridData},
};
#[cfg(feature = "bevy")]
use bevy::ecs::component::Component;
#[derive(Clone, Copy, Debug)]
pub enum GenerationUpdate {
Generated(GeneratedNode),
Reinitializing(u64),
Failed(usize),
}
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct QueuedStatefulObserver<T: CoordinateSystem, G: Grid<T>> {
grid_data: GridData<T, Option<ModelInstance>, G>,
receiver: crossbeam_channel::Receiver<GenerationUpdate>,
}
impl<T: CoordinateSystem, G: Grid<T>> QueuedStatefulObserver<T, G> {
pub fn new(generator: &mut Generator<T, G>) -> Self {
let receiver = generator.create_observer_queue();
QueuedStatefulObserver::create(receiver, generator.grid())
}
pub(crate) fn create(
receiver: crossbeam_channel::Receiver<GenerationUpdate>,
grid: &G,
) -> Self {
QueuedStatefulObserver {
grid_data: GridData::new(grid.clone(), vec![None; grid.total_size()]),
receiver,
}
}
pub fn grid_data(&self) -> &GridData<T, Option<ModelInstance>, G> {
&self.grid_data
}
pub fn dequeue_all(&mut self) {
while let Ok(update) = self.receiver.try_recv() {
match update {
GenerationUpdate::Generated(grid_node) => self
.grid_data
.set(grid_node.node_index, Some(grid_node.model_instance)),
GenerationUpdate::Reinitializing(_) => self.grid_data.reset(None),
GenerationUpdate::Failed(_) => self.grid_data.reset(None),
}
}
}
pub fn dequeue_one(&mut self) -> Option<GenerationUpdate> {
match self.receiver.try_recv() {
Ok(update) => {
match update {
GenerationUpdate::Generated(grid_node) => self
.grid_data
.set(grid_node.node_index, Some(grid_node.model_instance)),
GenerationUpdate::Reinitializing(_) => self.grid_data.reset(None),
GenerationUpdate::Failed(_) => self.grid_data.reset(None),
}
Some(update)
}
Err(_) => None,
}
}
}
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct QueuedObserver {
receiver: crossbeam_channel::Receiver<GenerationUpdate>,
}
impl QueuedObserver {
pub fn new<T: CoordinateSystem, G: Grid<T>>(generator: &mut Generator<T, G>) -> Self {
let receiver = generator.create_observer_queue();
QueuedObserver { receiver }
}
pub(crate) fn create(receiver: crossbeam_channel::Receiver<GenerationUpdate>) -> Self {
Self { receiver }
}
pub fn dequeue_all(&mut self) -> Vec<GenerationUpdate> {
let mut updates = Vec::new();
while let Ok(update) = self.receiver.try_recv() {
updates.push(update);
}
updates
}
pub fn dequeue_one(&mut self) -> Option<GenerationUpdate> {
match self.receiver.try_recv() {
Ok(update) => Some(update),
Err(_) => None,
}
}
}