Skip to content

Commit

Permalink
Move to local placer
Browse files Browse the repository at this point in the history
  • Loading branch information
rollrat committed Nov 17, 2024
1 parent 1374e21 commit a7240c2
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 103 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
derive_more = "1.0.0"
derive_more = { version = "1.0.0", features = ["deref"] }
disjoint-set = "0.0.2"
eyre = "0.6.8"
fastnbt = "2"
Expand Down
13 changes: 11 additions & 2 deletions src/graph/logic/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
use std::ops::Deref;
use crate::transform::logic::LogicGraphTransformer;

use super::Graph;

pub mod builder;

#[derive(Debug, Clone, Deref)]
#[derive(Debug, Clone, derive_more::Deref)]
pub struct LogicGraph {
#[deref]
pub graph: Graph,
}

impl LogicGraph {
pub fn prepare_place(self) -> eyre::Result<Self> {
let mut transform = LogicGraphTransformer::new(self);
transform.decompose_and()?;
transform.remove_double_neg_expression();
Ok(transform.finish())
}
}
21 changes: 20 additions & 1 deletion src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ impl GraphNodeKind {
_ => unreachable!(),
}
}

pub fn is_input(&self) -> bool {
matches!(self, GraphNodeKind::Input(_))
}

pub fn is_output(&self) -> bool {
matches!(self, GraphNodeKind::Output(_))
}

pub fn is_logic(&self) -> bool {
matches!(self, GraphNodeKind::Logic(_))
}

pub fn as_logic(&self) -> Option<&Logic> {
match self {
GraphNodeKind::Logic(inner) => Some(inner),
_ => None,
}
}
}

#[derive(Default, Debug, Clone)]
Expand Down Expand Up @@ -182,7 +201,7 @@ impl Graph {
.collect();

for (from, to) in replace_targets {
let mut node = other.nodes.iter_mut().find(|node| node.id == from).unwrap();
let node = other.nodes.iter_mut().find(|node| node.id == from).unwrap();

self.find_node_by_id_mut(to)
.unwrap()
Expand Down
11 changes: 10 additions & 1 deletion src/logic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,18 @@ impl LogicType {
LogicType::Xor => "Xor".to_owned(),
}
}

pub fn is_not(&self) -> bool {
matches!(self, LogicType::Not)
}

pub fn is_or(&self) -> bool {
matches!(self, LogicType::Or)
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, derive_more::Deref)]
pub struct Logic {
#[deref]
pub logic_type: LogicType,
}
57 changes: 0 additions & 57 deletions src/transform/component/mod.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod component;
pub mod logic;
pub mod placer;
pub mod router;
Expand Down
107 changes: 67 additions & 40 deletions src/transform/placer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::{collections::HashSet, iter::repeat_with};

use petgraph::stable_graph::NodeIndex;
use eyre::ensure;

use crate::{
graph::{
logic::LogicGraph,
world::{
builder::{PlaceBound, PropagateType},
WorldGraph,
},
GraphNodeId, GraphNodeKind, SubGraphWithGraph,
},
world::{block::Block, position::Position, world::World3D},
};
Expand All @@ -35,61 +35,56 @@ impl PlacedNode {
.into_iter()
.collect()
}

pub fn has_conflict_with(&self, other: &Self) -> bool {
todo!()
}

// pub fn
}

pub struct LocalPlacer<'a> {
graph: SubGraphWithGraph<'a>,
try_count: usize,
max_width_size: usize,
max_height_size: usize,
pub struct LocalPlacer {
graph: LogicGraph,
}

pub const K_MAX_LOCAL_PLACE_NODE_COUNT: usize = 25;

impl<'a> LocalPlacer<'a> {
// you should not pass side effected sub-graph
pub fn new(
graph: SubGraphWithGraph<'a>,
try_count: usize,
max_width_size: Option<usize>,
max_height_size: Option<usize>,
) -> eyre::Result<Self> {
assert!(try_count > 0);

Self::verify(&graph);

Ok(Self {
graph,
try_count,
max_width_size: max_width_size.unwrap_or(usize::MAX),
max_height_size: max_height_size.unwrap_or(usize::MAX),
})
impl LocalPlacer {
pub fn new(graph: LogicGraph) -> eyre::Result<Self> {
let result = Self { graph };
result.verify()?;
Ok(result)
}

pub fn verify(graph: &SubGraphWithGraph<'a>) {
assert!(graph.nodes.len() > 0);
assert!(graph.nodes.len() <= K_MAX_LOCAL_PLACE_NODE_COUNT);

for node_id in &graph.nodes {
assert!(matches!(
graph.graph.find_node_by_id(*node_id).unwrap().kind,
GraphNodeKind::Logic { .. }
));
fn verify(&self) -> eyre::Result<()> {
ensure!(self.graph.nodes.len() > 0, "");
ensure!(
self.graph.nodes.len() <= K_MAX_LOCAL_PLACE_NODE_COUNT,
"too large graph"
);

for node_id in &self.graph.nodes {
let kind = &self.graph.find_node_by_id(node_id.id).unwrap().kind;
ensure!(
kind.is_input() || kind.is_output() || kind.is_logic(),
"cannot place"
);
if let Some(logic) = kind.as_logic() {
ensure!(logic.is_not() || logic.is_or(), "cannot place");
}
}
}

pub fn generate(&mut self) -> WorldGraph {
let try_count = self.try_count;
Ok(())
}

// TODO: make parallel
pub fn generate(&mut self) -> World3D {
repeat_with(|| self.next_place())
.take(try_count)
.min_by_key(|(_, c)| *c)
.unwrap()
.0
}

fn next_place(&mut self) -> (WorldGraph, usize) {
fn next_place(&mut self) -> (World3D, usize) {
todo!()
}
}
Expand All @@ -109,3 +104,35 @@ impl<'a> LocalPlacerCostEstimator<'a> {
todo!()
}
}

#[cfg(test)]
mod tests {

use crate::{
graph::{
graphviz::ToGraphvizGraph,
logic::{builder::LogicGraphBuilder, LogicGraph},
},
nbt::{NBTRoot, ToNBT},
transform::placer::LocalPlacer,
};

fn build_graph_from_stmt(stmt: &str, output: &str) -> eyre::Result<LogicGraph> {
LogicGraphBuilder::new(stmt.to_string()).build(output.to_string())
}

#[test]
fn test_generate_component_and() -> eyre::Result<()> {
let logic_graph = build_graph_from_stmt("a&b", "c")?.prepare_place()?;
dbg!(&logic_graph);
println!("{}", logic_graph.to_graphviz());

let mut placer = LocalPlacer::new(logic_graph)?;
let world3d = placer.generate();

let nbt: NBTRoot = world3d.to_nbt();
nbt.save("test/and-gate-new.nbt");

Ok(())
}
}

0 comments on commit a7240c2

Please sign in to comment.