From 81ce471d0e960d7f0dc30c9889e7e35a6aa80b6b Mon Sep 17 00:00:00 2001 From: Rahix Date: Fri, 23 Jan 2026 14:55:54 +0100 Subject: [PATCH] Only place real "Ultimate Goal" elements at the bottom of the graph "Ultimate Goal" elements are only counted as such if they fulfil the following requirements: - They have the "Ultimate Goal" issue label - They are not depended on by any other elements --- techtree-manager/src/tree.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/techtree-manager/src/tree.rs b/techtree-manager/src/tree.rs index 303b75d..d64c78c 100644 --- a/techtree-manager/src/tree.rs +++ b/techtree-manager/src/tree.rs @@ -199,13 +199,24 @@ impl Tree { } pub fn iter_ultimate_elements<'a>(&'a self) -> impl Iterator + 'a { - self.graph.node_indices().filter(|index| { - // If there are no incoming edges, then this is an ultimate element! - self.graph - .neighbors_directed(*index, petgraph::Direction::Incoming) - .next() - .is_none() - }) + self.graph + .node_indices() + .filter(|index| { + self.graph.node_weight(*index).unwrap().status == ElementStatus::UltimateGoal + }) + .filter(|index| { + // Ultimate goal elements must not have any incoming dependency edges. Warn and + // ignore it, if one does. + let has_no_incoming = self.graph + .neighbors_directed(*index, petgraph::Direction::Incoming) + .next() + .is_none(); + if !has_no_incoming { + let el = self.graph.node_weight(*index).unwrap(); + log::warn!("Element #{} is marked \"Ultimate Goal\" but is depended on by others? Ignoring...", el.issue_number); + } + has_no_incoming + }) } pub fn get_element_role(&self, element: ElementIndex) -> ElementRole {