Skip to content

Commit

Permalink
voxel: Add explicit connections to code
Browse files Browse the repository at this point in the history
  • Loading branch information
Ondraceq committed Nov 2, 2023
1 parent f1b0a7a commit a0e8a54
Show file tree
Hide file tree
Showing 13 changed files with 589 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub enum Heuristic {
}

impl Heuristic {
pub fn get_fn<'a, TWorld>(self, goal: &TWorld) -> Box<dyn FnMut(&TWorld) -> usize + 'a>
pub fn get_fn<'a, TWorld>(self, goal: &TWorld) -> Box<dyn 'a + FnMut(&TWorld) -> usize>
where
TWorld: 'a + NormVoxelWorld + Eq + std::hash::Hash,
TWorld::IndexType: num::Integer + std::hash::Hash,
Expand Down
8 changes: 3 additions & 5 deletions softwareComponents/voxelReconfig/src/voxel_world/centered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,9 @@ where
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(
self.world()
.all_voxels()
.map(|(orig_pos, voxel)| (self.get_new_pos(orig_pos), voxel)),
)
self.world()
.all_voxels()
.map(|(orig_pos, voxel)| (self.get_new_pos(orig_pos), voxel))
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl<TIndex: MapVoxelWorldIndex> VoxelWorld for MapVoxelWorld<TIndex> {
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(self.data.iter().map(|(&OrdPos(pos), &voxel)| (pos, voxel)))
self.data.iter().map(|(&OrdPos(pos), &voxel)| (pos, voxel))
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,18 @@ impl<TIndex: MatrixVoxelWorldIndex> VoxelWorld for MatrixVoxelWorld<TIndex> {
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(
self.data
.get_data()
.zip(0..)
.flat_map(|(plain, x)| {
plain.zip(0..).flat_map(move |(row, y)| {
row.iter()
.copied()
.zip(0..)
.map(move |(voxel, z)| (Self::to_position([x, y, z]).unwrap(), voxel))
})
self.data
.get_data()
.zip(0..)
.flat_map(|(plain, x)| {
plain.zip(0..).flat_map(move |(row, y)| {
row.iter()
.copied()
.zip(0..)
.map(move |(voxel, z)| (Self::to_position([x, y, z]).unwrap(), voxel))
})
.filter_map(|(pos, voxel)| Some((pos, voxel.get_voxel()?))),
)
})
.filter_map(|(pos, voxel)| Some((pos, voxel.get_voxel()?)))
}

fn get_voxel(&self, position: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl<TIndex: SortvecVoxelWorldIndex> VoxelWorld for SortvecVoxelWorld<TIndex> {
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(self.data.iter().map(|(&OrdPos(pos), &voxel)| (pos, voxel)))
self.data.iter().map(|(&OrdPos(pos), &voxel)| (pos, voxel))
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
1 change: 1 addition & 0 deletions softwareComponents/voxelReconfig/src/voxel_world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod world_rotation;

pub mod impls;
pub mod traits;
pub mod with_connections;

pub use centered::CenteredVoxelWorld;
pub use rotated::{rotate_voxel, RotatedVoxelWorld};
Expand Down
4 changes: 2 additions & 2 deletions softwareComponents/voxelReconfig/src/voxel_world/rotated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ where
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(self.world().all_voxels().map(|(orig_pos, voxel)| {
self.world().all_voxels().map(|(orig_pos, voxel)| {
let rot_voxel = rotate_voxel(voxel, self.rotation);
let rot_pos = self.get_new_pos(orig_pos);
(rot_pos, rot_voxel)
}))
})
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
16 changes: 6 additions & 10 deletions softwareComponents/voxelReconfig/src/voxel_world/subworld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,9 @@ impl<'a, TWorld: VoxelWorld> VoxelWorld for VoxelSubworld<'a, TWorld> {
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(
self.included
.iter()
.map(|&OrdPos(pos)| (pos, self.world.get_voxel(pos).unwrap())),
)
self.included
.iter()
.map(|&OrdPos(pos)| (pos, self.world.get_voxel(pos).unwrap()))
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down Expand Up @@ -207,11 +205,9 @@ pub mod complement {
}

fn all_voxels(&self) -> Self::PosVoxelIter<'_> {
Box::new(
self.underlying_world()
.all_voxels()
.filter(|&(pos, _)| self.contains(pos)),
)
self.underlying_world()
.all_voxels()
.filter(|&(pos, _)| self.contains(pos))
}

fn get_voxel(&self, pos: Pos<Self::IndexType>) -> Option<Voxel> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use super::super::Connections;
use crate::atoms::Axis;
use crate::pos::ord::OrdPos;
use crate::pos::Pos;
use std::collections::{btree_map, BTreeMap};

pub trait MapConnectionsIndex:
num::Signed + Ord + Copy + std::hash::Hash + std::fmt::Debug
{
}
impl<T> MapConnectionsIndex for T where
Self: num::Signed + Ord + Copy + std::hash::Hash + std::fmt::Debug
{
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MapConnections<IndexType: MapConnectionsIndex> {
connections: BTreeMap<OrdPos<IndexType>, [bool; 3]>,
}

impl<IndexType: MapConnectionsIndex> Default for MapConnections<IndexType> {
fn default() -> Self {
Self {
connections: Default::default(),
}
}
}

fn axes_from_inner_value(axes_connected: [bool; 3]) -> smallvec::SmallVec<[Axis; 3]> {
axes_connected
.into_iter()
.zip(enum_iterator::all())
.filter(|&(axis_connected, _)| axis_connected)
.map(|(_, axis)| axis)
.collect()
}

impl<TIndex: MapConnectionsIndex> Connections for MapConnections<TIndex> {
type IndexType = TIndex;
type ConnectionIter<'a> = impl 'a + Iterator<Item = (Pos<Self::IndexType>, Axis)>
where
Self: 'a;

fn connect(&mut self, pos_from: Pos<Self::IndexType>, connected_to: Axis) {
self.connections.entry(OrdPos(pos_from)).or_default()[connected_to.as_index()] = true;
}

fn disconnect(&mut self, pos_from: Pos<Self::IndexType>, connected_to: Axis) {
if let btree_map::Entry::Occupied(mut entry) = self.connections.entry(OrdPos(pos_from)) {
entry.get_mut()[connected_to.as_index()] = false;
if entry.get().iter().all(|&value| !value) {
// Respect default equality
entry.remove();
}
}
}

fn is_connected(&self, pos_from: Pos<Self::IndexType>, connected_to: Axis) -> bool {
if let Some(connections) = self.connections.get(&OrdPos(pos_from)) {
connections[connected_to.as_index()]
} else {
false
}
}

fn connections_from(&self, pos_from: Pos<Self::IndexType>) -> smallvec::SmallVec<[Axis; 3]> {
self.connections
.get(&OrdPos(pos_from))
.copied()
.map_or_else(Default::default, axes_from_inner_value)
}

fn all_connections(&self) -> Self::ConnectionIter<'_> {
self.connections.iter().flat_map(|(&OrdPos(pos), &axes)| {
axes_from_inner_value(axes)
.into_iter()
.map(move |axis| (pos, axis))
})
}

fn from_connections(
connections_iter: impl IntoIterator<Item = (Pos<Self::IndexType>, Axis)>,
) -> Self {
let mut result = Self::default();
for (pos, axis) in connections_iter {
result.connect(pos, axis);
}
result
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod map_connections;
pub mod set_connections;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use super::super::Connections;
use crate::atoms::Axis;
use crate::pos::ord::OrdPos;
use crate::pos::Pos;
use enum_iterator::Sequence;
use std::collections::BTreeSet;

pub trait SetConnectionsIndex:
num::Signed + Ord + Copy + std::hash::Hash + std::fmt::Debug
{
}
impl<T> SetConnectionsIndex for T where
Self: num::Signed + Ord + Copy + std::hash::Hash + std::fmt::Debug
{
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SetConnections<IndexType: SetConnectionsIndex> {
connections: BTreeSet<(OrdPos<IndexType>, Axis)>,
}

impl<TIndex: SetConnectionsIndex> Default for SetConnections<TIndex> {
fn default() -> Self {
Self {
connections: Default::default(),
}
}
}

fn iter_adaptor<TIndex: num::Num + Copy>(value: &(OrdPos<TIndex>, Axis)) -> (Pos<TIndex>, Axis) {
let &(OrdPos(pos), axis) = value;
(pos, axis)
}

impl<TIndex: SetConnectionsIndex> Connections for SetConnections<TIndex> {
type IndexType = TIndex;
type ConnectionIter<'a> = impl 'a + Iterator<Item = (Pos<Self::IndexType>, Axis)>
where
Self: 'a;

fn connect(&mut self, pos_from: Pos<Self::IndexType>, connected_to: Axis) {
self.connections.insert((OrdPos(pos_from), connected_to));
}

fn disconnect(&mut self, pos_from: Pos<Self::IndexType>, connected_to: Axis) {
self.connections.remove(&(OrdPos(pos_from), connected_to));
}

fn is_connected(&self, pos_from: Pos<Self::IndexType>, connected_to: Axis) -> bool {
self.connections.contains(&(OrdPos(pos_from), connected_to))
}

fn connections_from(&self, pos_from: Pos<Self::IndexType>) -> smallvec::SmallVec<[Axis; 3]> {
let first_axis = Axis::first().unwrap();
let last_axis = Axis::last().unwrap();
self.connections
.range((OrdPos(pos_from), first_axis)..=(OrdPos(pos_from), last_axis))
.map(|&(_, axis)| axis)
.collect()
}

fn all_connections(&self) -> Self::ConnectionIter<'_> {
self.connections.iter().map(iter_adaptor)
}

fn from_connections(
connections_iter: impl IntoIterator<Item = (Pos<Self::IndexType>, Axis)>,
) -> Self {
Self {
connections: connections_iter
.into_iter()
.map(|(pos, axis)| (OrdPos(pos), axis))
.collect(),
}
}
}
Loading

0 comments on commit a0e8a54

Please sign in to comment.