1#![allow(unused_variables)]
9#![allow(missing_docs)] use crate::layout::types::{LayerInfo, UInt};
12use crate::prelude::PropertyValue;
13use crate::prelude::{Geometry, Rect};
14use crate::traits::{
15 HierarchyBase, HierarchyBaseMT, HierarchyEdit, HierarchyIds, IdType, IdTypeMT,
16};
17use iron_shapes::transform::SimpleTransform;
18use iron_shapes::CoordinateType;
19use num_traits::Num;
20use std::hash::Hash;
21
22#[portrait::make]
25pub trait LayoutBaseMT:
26 LayoutBase<LayerId = Self::LayerIdMT, ShapeId = Self::ShapeIdMT> + HierarchyBaseMT
27{
28 type LayerIdMT: IdTypeMT;
30 type ShapeIdMT: IdTypeMT;
32}
33
34impl<L> LayoutBaseMT for L
35where
36 L: LayoutBase + HierarchyBaseMT,
37 L::LayerId: Send + Sync,
38 L::ShapeId: Send + Sync,
39{
40 type LayerIdMT = L::LayerId;
41 type ShapeIdMT = L::ShapeId;
42}
43
44#[portrait::make(import(crate::prelude::*))]
46pub trait LayoutIds: HierarchyIds {
47 type Coord: CoordinateType + std::fmt::Debug + std::fmt::Display + Hash + 'static + Send + Sync;
49 type Area: Num + Copy + PartialOrd + From<Self::Coord> + 'static + Send + Sync;
55 type LayerId: IdType;
57 type ShapeId: IdType;
59}
60
61#[portrait::make(import(crate::prelude::*))]
65pub trait LayoutBase: LayoutIds + HierarchyBase {
66 fn dbu(&self) -> Self::Coord;
68
69 fn each_layer(&self) -> Box<dyn Iterator<Item = Self::LayerId> + '_>;
71
72 fn layer_info(&self, layer: &Self::LayerId) -> LayerInfo<Self::NameType>;
74
75 fn find_layer(&self, index: UInt, datatype: UInt) -> Option<Self::LayerId>;
77
78 fn layer_by_name(&self, name: &str) -> Option<Self::LayerId>;
80
81 fn bounding_box_per_layer(
84 &self,
85 cell: &Self::CellId,
86 layer: &Self::LayerId,
87 ) -> Option<Rect<Self::Coord>>;
88
89 fn bounding_box(&self, cell: &Self::CellId) -> Option<Rect<Self::Coord>> {
93 self.each_layer()
94 .map(|layer| self.bounding_box_per_layer(cell, &layer))
95 .fold(None, |a, b| match (a, b) {
96 (None, None) => None,
97 (Some(a), None) | (None, Some(a)) => Some(a),
98 (Some(a), Some(b)) => Some(a.add_rect(&b)),
99 })
100 }
101
102 fn each_shape_id(
104 &self,
105 cell: &Self::CellId,
106 layer: &Self::LayerId,
107 ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_>;
108
109 fn for_each_shape<F>(&self, cell: &Self::CellId, layer: &Self::LayerId, f: F)
111 where
112 F: FnMut(&Self::ShapeId, &Geometry<Self::Coord>);
113
114 fn with_shape<F, R>(&self, shape_id: &Self::ShapeId, f: F) -> R
116 where
117 F: FnMut(&Self::LayerId, &Geometry<Self::Coord>) -> R;
118
119 fn shape_geometry(&self, shape_id: &Self::ShapeId) -> Geometry<Self::Coord> {
121 self.with_shape(shape_id, |_, geo| geo.clone())
122 }
123
124 fn shape_layer(&self, shape_id: &Self::ShapeId) -> Self::LayerId {
126 self.with_shape(shape_id, |layer, _| layer.clone())
127 }
128
129 fn parent_of_shape(&self, shape_id: &Self::ShapeId) -> (Self::CellId, Self::LayerId);
131
132 fn for_each_shape_recursive<F>(&self, cell: &Self::CellId, layer: &Self::LayerId, mut f: F)
136 where
137 F: FnMut(SimpleTransform<Self::Coord>, &Self::ShapeId, &Geometry<Self::Coord>),
138 {
139 let mut stack = Vec::new();
144 stack.push((cell.clone(), SimpleTransform::identity()));
145
146 while let Some((cell, tf)) = stack.pop() {
147 self.for_each_cell_instance(&cell, |inst| {
149 let template = self.template_cell(&inst);
150 let transform = self.get_transform(&inst);
151 let tf2 = transform.then(&tf);
152 stack.push((template, tf2));
153 });
154
155 self.for_each_shape(&cell, layer, |id, g| f(tf, id, g));
157 }
158 }
159
160 fn get_transform(&self, cell_inst: &Self::CellInstId) -> SimpleTransform<Self::Coord>;
162
163 fn get_shape_property(
165 &self,
166 shape: &Self::ShapeId,
167 key: &Self::NameType,
168 ) -> Option<PropertyValue> {
169 None
170 }
171}
172
173#[portrait::make]
175pub trait RegionSearch: LayoutBase {
176 fn each_shape_in_region(
178 &self,
179 cell: &Self::CellId,
180 search_region: &Rect<Self::Coord>,
181 ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_> {
182 let cell = cell.clone(); let search_region = *search_region; Box::new(self.each_layer().flat_map(move |layer_id| {
185 self.each_shape_in_region_per_layer(&cell, &layer_id, &search_region)
186 }))
187 }
188
189 fn each_shape_in_region_per_layer(
191 &self,
192 cell: &Self::CellId,
193 layer_id: &Self::LayerId,
194 search_region: &Rect<Self::Coord>,
195 ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_>;
196
197 fn each_cell_instance_in_region(
199 &self,
200 cell: &Self::CellId,
201 search_region: &Rect<Self::Coord>,
202 ) -> Box<dyn Iterator<Item = Self::CellInstId> + '_>;
203}
204
205#[portrait::make(import(crate::prelude::*))]
207pub trait LayoutEdit: LayoutBase + HierarchyEdit {
208 fn set_dbu(&mut self, dbu: Self::Coord) {} fn create_layer(&mut self, index: UInt, datatype: UInt) -> Self::LayerId;
214
215 fn create_layer_with_id(
218 &mut self,
219 layer_id: Self::LayerId,
220 index: UInt,
221 datatype: UInt,
222 ) -> Result<(), ()>;
223
224 fn set_layer_name(
228 &mut self,
229 layer: &Self::LayerId,
230 name: Option<Self::NameType>,
231 ) -> Option<Self::NameType>;
232
233 fn insert_shape(
235 &mut self,
236 parent_cell: &Self::CellId,
237 layer: &Self::LayerId,
238 geometry: Geometry<Self::Coord>,
239 ) -> Self::ShapeId;
240
241 fn remove_shape(&mut self, shape_id: &Self::ShapeId) -> Option<Geometry<Self::Coord>>;
243
244 fn replace_shape(
246 &mut self,
247 shape_id: &Self::ShapeId,
248 geometry: Geometry<Self::Coord>,
249 ) -> Geometry<Self::Coord>;
250
251 fn set_transform(&mut self, cell_inst: &Self::CellInstId, tf: SimpleTransform<Self::Coord>);
253
254 fn set_shape_property(
256 &mut self,
257 shape: &Self::ShapeId,
258 key: Self::NameType,
259 value: PropertyValue,
260 ) {
261 }
262}