aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/protocol/src/book.rs12
-rw-r--r--server/tools/src/diagram_dot.rs24
-rw-r--r--server/tools/src/diagram_svg.rs16
-rw-r--r--server/tools/src/recipe_diagram.rs28
4 files changed, 60 insertions, 20 deletions
diff --git a/server/protocol/src/book.rs b/server/protocol/src/book.rs
index 7c529f22..1654e014 100644
--- a/server/protocol/src/book.rs
+++ b/server/protocol/src/book.rs
@@ -69,8 +69,20 @@ pub struct DiagramEdge {
pub src: usize,
pub dst: usize,
pub label: Option<Message>,
+ pub style: EdgeStyle,
}
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub enum EdgeStyle {
+ Regular,
+ ProcessPassive,
+}
+
+impl EdgeStyle {
+ pub fn is_regular(&self) -> bool {
+ matches!(self, Self::Regular)
+ }
+}
impl NodeStyle {
pub fn is_procuct(&self) -> bool {
matches!(
diff --git a/server/tools/src/diagram_dot.rs b/server/tools/src/diagram_dot.rs
index b3e54881..f86a2d4e 100644
--- a/server/tools/src/diagram_dot.rs
+++ b/server/tools/src/diagram_dot.rs
@@ -19,7 +19,7 @@
use anyhow::{Result, bail};
use hurrycurry_protocol::{
Gamedata, Message,
- book::{Diagram, NodeStyle},
+ book::{Diagram, DiagramNode, NodeStyle},
};
use std::{
fmt::Write,
@@ -27,6 +27,8 @@ use std::{
process::{Command, Stdio},
};
+use crate::diagram_svg::{edge_color, node_color};
+
pub fn diagram_dot_svg(data: &Gamedata, diagram: &Diagram) -> Result<String> {
let mut child = Command::new("dot")
.arg("-Tsvg")
@@ -52,7 +54,7 @@ pub fn diagram_dot(data: &Gamedata, diagram: &Diagram, use_position: bool) -> Re
if use_position {
attrs.push(format!("pos=\"{},{}!\"", n.position.x, n.position.y));
}
- node_style(&mut attrs, &n.style);
+ node_style(&mut attrs, &n);
match &n.label {
Message::Text(text) => {
attrs.push(format!("label=\"{text}\""));
@@ -84,20 +86,22 @@ pub fn diagram_dot(data: &Gamedata, diagram: &Diagram, use_position: bool) -> Re
writeln!(out, "k{i} [{}]", attrs.join(" "))?;
}
for edge in &diagram.edges {
- writeln!(out, "k{} -> k{}", edge.src, edge.dst)?;
+ let color = edge_color(edge);
+ writeln!(out, "k{} -> k{} [color=\"{color}\"]", edge.src, edge.dst)?;
}
writeln!(out, "}}")?;
Ok(out)
}
-fn node_style(attrs: &mut Vec<String>, style: &NodeStyle) {
- let (shape, color) = match style {
- NodeStyle::FinalProduct => ("circle", "#555"),
- NodeStyle::IntermediateProduct => ("circle", "#333"),
- NodeStyle::ProcessActive => ("box", "#47c42b"),
- NodeStyle::ProcessPassive => ("box", "#c4a32b"),
- NodeStyle::ProcessInstant => ("box", "#5452d8"),
+fn node_style(attrs: &mut Vec<String>, node: &DiagramNode) {
+ let shape = match node.style {
+ NodeStyle::FinalProduct => "circle",
+ NodeStyle::IntermediateProduct => "circle",
+ NodeStyle::ProcessActive => "box",
+ NodeStyle::ProcessPassive => "box",
+ NodeStyle::ProcessInstant => "box",
};
+ let color = node_color(node);
attrs.push(format!("shape={shape}"));
attrs.push("style=filled".to_owned());
attrs.push(format!("fillcolor=\"{color}\""));
diff --git a/server/tools/src/diagram_svg.rs b/server/tools/src/diagram_svg.rs
index 0fc75668..fe3d9de4 100644
--- a/server/tools/src/diagram_svg.rs
+++ b/server/tools/src/diagram_svg.rs
@@ -19,7 +19,7 @@
use anyhow::Result;
use hurrycurry_protocol::{
Gamedata, Message,
- book::{Diagram, DiagramNode, NodeStyle},
+ book::{Diagram, DiagramEdge, DiagramNode, EdgeStyle, NodeStyle},
glam::Vec2,
};
use std::fmt::Write;
@@ -80,16 +80,18 @@ pub fn diagram_svg(data: &Gamedata, diagram: &Diagram) -> Result<String> {
let tip2 = dst + (dir + dir.perp() * -0.5) * 10.;
dst += dir * 5.; // prevent miter line cap from peeking out
+ let color = edge_color(edge);
+
// line path
writeln!(
out,
- r#"<path fill="none" stroke="black" stroke-width="2" d="M{} {} L{} {}" />"#,
+ r#"<path fill="none" stroke="{color}" stroke-width="2" d="M{} {} L{} {}" />"#,
src.x, src.y, dst.x, dst.y,
)?;
// tip path
writeln!(
out,
- r#"<path fill="black" stroke="none" d="M{} {} L{} {} L{} {} Z" />"#,
+ r#"<path fill="{color}" stroke="none" d="M{} {} L{} {} L{} {} Z" />"#,
tip0.x, tip0.y, tip1.x, tip1.y, tip2.x, tip2.y
)?;
}
@@ -110,7 +112,7 @@ fn node_edge_connect_pos(src: &DiagramNode, dst: &DiagramNode) -> Vec2 {
}
}
-fn node_color(node: &DiagramNode) -> &'static str {
+pub(crate) fn node_color(node: &DiagramNode) -> &'static str {
match node.style {
NodeStyle::FinalProduct => "#555",
NodeStyle::IntermediateProduct => "#333",
@@ -119,6 +121,12 @@ fn node_color(node: &DiagramNode) -> &'static str {
NodeStyle::ProcessInstant => "#5452d8",
}
}
+pub(crate) fn edge_color(edge: &DiagramEdge) -> &'static str {
+ match edge.style {
+ EdgeStyle::Regular => "#000000",
+ EdgeStyle::ProcessPassive => "#c4a32b",
+ }
+}
fn image_node(out: &mut String, node: &DiagramNode, path: String) -> Result<()> {
if matches!(
diff --git a/server/tools/src/recipe_diagram.rs b/server/tools/src/recipe_diagram.rs
index ec7656b9..903b869a 100644
--- a/server/tools/src/recipe_diagram.rs
+++ b/server/tools/src/recipe_diagram.rs
@@ -19,7 +19,7 @@
use anyhow::Result;
use hurrycurry_protocol::{
Gamedata, ItemIndex, Message, Recipe, RecipeIndex,
- book::{Diagram, DiagramEdge, DiagramNode, NodeStyle},
+ book::{Diagram, DiagramEdge, DiagramNode, EdgeStyle, NodeStyle},
glam::Vec2,
};
use hurrycurry_server::data::Serverdata;
@@ -98,16 +98,29 @@ pub(crate) fn recipe_diagram(
let index = diag.nodes.len();
let recipe = data.recipe(r.index);
- if matches!(recipe, Recipe::Instant { .. }) && r.outputs.len() == 1 && r.inputs.len() >= 1 {
+ if matches!(recipe, Recipe::Instant { .. }) && r.inputs.len() >= 1 && r.outputs.len() >= 1 {
for i in r.inputs {
diag.edges.push(DiagramEdge {
src: item_index[&i],
dst: item_index[&r.outputs[0]],
label: None,
+ style: EdgeStyle::Regular,
});
}
continue;
}
+ if matches!(recipe, Recipe::Passive { tile: None, .. })
+ && r.inputs.len() == 1
+ && r.outputs.len() == 1
+ {
+ diag.edges.push(DiagramEdge {
+ src: item_index[&r.inputs[0]],
+ dst: item_index[&r.outputs[0]],
+ label: None,
+ style: EdgeStyle::ProcessPassive,
+ });
+ continue;
+ }
let (kind, style) = match recipe {
Recipe::Passive { .. } => ("Passive", NodeStyle::ProcessPassive),
@@ -129,6 +142,7 @@ pub(crate) fn recipe_diagram(
src: item_index[&i],
dst: index,
label: None,
+ style: EdgeStyle::Regular,
});
}
for o in r.outputs {
@@ -136,6 +150,7 @@ pub(crate) fn recipe_diagram(
src: index,
dst: item_index[&o],
label: None,
+ style: EdgeStyle::Regular,
});
}
}
@@ -173,10 +188,10 @@ fn merge_combine_clusters(diag: &mut Diagram) {
if outputs
.iter()
- .all(|&(_, i)| diag.nodes[i].style.is_procuct())
- && inputs
- .iter()
- .all(|&(_, i)| diag.nodes[i].style.is_procuct())
+ .all(|&(ei, ni)| diag.nodes[ni].style.is_procuct() && diag.edges[ei].style.is_regular())
+ && inputs.iter().all(|&(ei, ni)| {
+ diag.nodes[ni].style.is_procuct() && diag.edges[ei].style.is_regular()
+ })
{
let mut to_remove = inputs
.iter()
@@ -199,6 +214,7 @@ fn merge_combine_clusters(diag: &mut Diagram) {
src: input.1,
dst: output.1,
label: None,
+ style: EdgeStyle::Regular,
});
}
}