Complete source 6 engineering workflows and preserve release validation evidence
This commit is contained in:
@@ -226,8 +226,58 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView {
|
||||
};
|
||||
project_diagram(p, d)
|
||||
}
|
||||
/// Reuse an index built for this accepted semantic revision during presentation
|
||||
/// previews. Callers must invalidate it when semantic records change.
|
||||
pub fn project_view_with_index(
|
||||
p: &Project,
|
||||
diagram: Id,
|
||||
index: &crate::view_options::ViewIndex,
|
||||
) -> ProjectedView {
|
||||
p.diagrams
|
||||
.get(&diagram)
|
||||
.map_or_else(ProjectedView::default, |d| {
|
||||
project_diagram_with_index(p, d, index)
|
||||
})
|
||||
}
|
||||
/// Project alternate placement geometry without copying or mutating semantics.
|
||||
pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
let index = crate::view_options::ViewIndex::new(p);
|
||||
project_diagram_with_index(p, d, &index)
|
||||
}
|
||||
pub fn project_diagram_with_index(
|
||||
p: &Project,
|
||||
d: &Diagram,
|
||||
index: &crate::view_options::ViewIndex,
|
||||
) -> ProjectedView {
|
||||
project_diagram_impl(p, d, None, Some(index))
|
||||
}
|
||||
/// Unfiltered eligibility from the same projection/anchor/fold decisions used
|
||||
/// for drawing. Compute once for a view-options editor, then combine with the
|
||||
/// prepared filter's reasons; hidden lines remain geometrically eligible here.
|
||||
pub fn edge_availability(
|
||||
p: &Project,
|
||||
d: &Diagram,
|
||||
) -> BTreeMap<Id, crate::view_options::EdgeAvailability> {
|
||||
let mut availability = p
|
||||
.relations
|
||||
.keys()
|
||||
.chain(p.traces.keys())
|
||||
.map(|id| {
|
||||
(
|
||||
*id,
|
||||
crate::view_options::EdgeAvailability::OutsideProjection,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
project_diagram_impl(p, d, Some(&mut availability), None);
|
||||
availability
|
||||
}
|
||||
fn project_diagram_impl(
|
||||
p: &Project,
|
||||
d: &Diagram,
|
||||
mut availability: Option<&mut BTreeMap<Id, crate::view_options::EdgeAvailability>>,
|
||||
index: Option<&crate::view_options::ViewIndex>,
|
||||
) -> ProjectedView {
|
||||
let parents = parents(p, d);
|
||||
let mut nodes = Vec::new();
|
||||
for n in d.nodes.values() {
|
||||
@@ -354,6 +404,7 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
RelationKind::Interaction
|
||||
| RelationKind::FunctionalExchange
|
||||
| RelationKind::BoundaryExchange
|
||||
| RelationKind::CommunicationMean
|
||||
),
|
||||
ProjectionKind::FunctionalDataflow => matches!(
|
||||
r.kind(),
|
||||
@@ -367,20 +418,36 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
| RelationKind::MissionCapability
|
||||
| RelationKind::MissionInvolvement
|
||||
| RelationKind::CapabilityInvolvement
|
||||
| RelationKind::CommunicationMean
|
||||
),
|
||||
_ => true,
|
||||
};
|
||||
if !included {
|
||||
continue;
|
||||
}
|
||||
if let (Some(source), Some(target)) = (anchor(r.source()), anchor(r.target()))
|
||||
&& (source != target
|
||||
|| ((d.projection.state_machine().is_some()
|
||||
|| r.kind() == RelationKind::DataAssociation)
|
||||
&& r.source() == r.target()
|
||||
&& nodes
|
||||
.iter()
|
||||
.any(|n| n.id == source && n.element == r.source())))
|
||||
let ends = (anchor(r.source()), anchor(r.target()));
|
||||
let self_loop = (d.projection.state_machine().is_some()
|
||||
|| r.kind() == RelationKind::DataAssociation)
|
||||
&& r.source() == r.target()
|
||||
&& nodes
|
||||
.iter()
|
||||
.any(|n| Some(n.id) == ends.0 && n.element == r.source());
|
||||
if let Some(availability) = availability.as_deref_mut() {
|
||||
use crate::view_options::EdgeAvailability as A;
|
||||
availability.insert(
|
||||
r.id,
|
||||
match ends {
|
||||
(Some(a), Some(b)) if a != b || self_loop => A::Visible,
|
||||
(Some(_), Some(_)) => A::FoldedInternal,
|
||||
(a, b) => A::EndpointNotShown {
|
||||
source: a.is_none(),
|
||||
target: b.is_none(),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
if let (Some(source), Some(target)) = ends
|
||||
&& (source != target || self_loop)
|
||||
{
|
||||
let (source_port, target_port) = match &r.body {
|
||||
RelationBody::FunctionalExchange {
|
||||
@@ -402,6 +469,9 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
RelationBody::BoundaryExchange {
|
||||
oriented: false,
|
||||
..
|
||||
} | RelationBody::CommunicationMean {
|
||||
oriented: false,
|
||||
..
|
||||
} | RelationBody::DataAssociation { .. }
|
||||
),
|
||||
source_port: source_port.filter(|id| visible_ports.contains(id)),
|
||||
@@ -411,7 +481,22 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
}
|
||||
if d.projection == ProjectionKind::Traceability {
|
||||
for t in p.traces.values() {
|
||||
if let (Some(source), Some(target)) = (anchor(t.oa), anchor(t.sa))
|
||||
let ends = (anchor(t.oa), anchor(t.sa));
|
||||
if let Some(availability) = availability.as_deref_mut() {
|
||||
use crate::view_options::EdgeAvailability as A;
|
||||
availability.insert(
|
||||
t.id,
|
||||
match ends {
|
||||
(Some(a), Some(b)) if a != b => A::Visible,
|
||||
(Some(_), Some(_)) => A::FoldedInternal,
|
||||
(a, b) => A::EndpointNotShown {
|
||||
source: a.is_none(),
|
||||
target: b.is_none(),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
if let (Some(source), Some(target)) = ends
|
||||
&& source != target
|
||||
{
|
||||
edges.push(ProjectedEdge {
|
||||
@@ -433,6 +518,16 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
|
||||
} else {
|
||||
port_layout::layout(p, d, &mut nodes, &edges)
|
||||
};
|
||||
// Port geometry uses every eligible edge. Presentation filters must never
|
||||
// move visible ports when another line is hidden or a category is selected.
|
||||
if let Some(index) = index {
|
||||
let filter = if d.projection == ProjectionKind::Traceability {
|
||||
index.prepare_cross_layer(d.layer, &d.view_options)
|
||||
} else {
|
||||
index.prepare(d.layer, &d.view_options)
|
||||
};
|
||||
edges.retain(|edge| filter.includes(edge.id));
|
||||
}
|
||||
ProjectedView {
|
||||
nodes,
|
||||
edges,
|
||||
|
||||
Reference in New Issue
Block a user