WIP: post-fix for #1780 - minimizing access to 'selection' which is mutable.

This commit is contained in:
Matthias Koefferlein 2024-07-08 23:51:36 +02:00
parent 3cf6ef2cec
commit 12d09687cd
1 changed files with 49 additions and 63 deletions

View File

@ -375,7 +375,14 @@ MainService::cm_ascend ()
new_selections.reserve (edt_services.size ());
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
new_selections.push_back (std::vector<lay::ObjectInstPath> ());
new_selections.back ().insert (new_selections.back ().end (), (*es)->selection ().begin (), (*es)->selection ().end ());
size_t n = 0;
for (EditableSelectionIterator i = (*es)->begin_selection (); ! i.at_end (); ++i) {
++n;
}
new_selections.back ().reserve (n);
for (EditableSelectionIterator i = (*es)->begin_selection (); ! i.at_end (); ++i) {
new_selections.back ().push_back (*i);
}
}
// this will clear the selection:
@ -436,8 +443,7 @@ MainService::cm_flatten_insts ()
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &sel = (*es)->selection ();
for (edt::Service::objects::const_iterator r = sel.begin (); r != sel.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
const lay::CellView &cv = view ()->cellview (r->cv_index ());
if (cv.is_valid ()) {
@ -491,12 +497,10 @@ MainService::cm_move_hier_up ()
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
std::vector<lay::ObjectInstPath> new_selection;
new_selection.reserve (selection.size ());
new_selection.reserve ((*es)->selection_size ());
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
const lay::CellView &cv = view ()->cellview (r->cv_index ());
if (cv.is_valid ()) {
@ -728,8 +732,7 @@ MainService::cm_make_cell_variants ()
// TODO: this limitation is not really necessary, but makes the code somewhat simpler
int cv_index = -1;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
if (cv_index < 0) {
cv_index = r->cv_index ();
} else if (cv_index != int (r->cv_index ())) {
@ -752,8 +755,15 @@ MainService::cm_make_cell_variants ()
}
std::vector<lay::ObjectInstPath> new_selection;
size_t n = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
new_selection.insert (new_selection.end (), (*es)->selection ().begin (), (*es)->selection ().end ());
n += (*es)->selection_size ();
}
new_selection.reserve (n);
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
new_selection.push_back (*s);
}
}
size_t num_sel = new_selection.size ();
@ -913,7 +923,7 @@ MainService::cm_make_cell_variants ()
// Install the new selection
size_t i0 = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
size_t n = (*es)->selection ().size ();
size_t n = (*es)->selection_size ();
if (n + i0 <= new_selection.size ()) {
(*es)->set_selection (new_selection.begin () + i0, new_selection.begin () + i0 + n);
}
@ -941,8 +951,7 @@ MainService::cm_resolve_arefs ()
int cv_index = -1;
const edt::Service::objects &selection = inst_service->selection ();
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = inst_service->begin_selection (); ! r.at_end (); ++r) {
if (r->is_cell_inst () && r->back ().inst_ptr.size () > 1) {
if (cv_index < 0) {
cv_index = r->cv_index ();
@ -1023,8 +1032,7 @@ MainService::cm_make_cell ()
int cv_index = -1;
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection () ;
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
if (cv_index < 0) {
cv_index = r->cv_index ();
} else if (cv_index != int (r->cv_index ())) {
@ -1048,8 +1056,7 @@ MainService::cm_make_cell ()
db::Box selection_bbox;
db::box_convert<db::CellInst> bc (cv->layout ());
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection () ;
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
if (r->is_cell_inst ()) {
selection_bbox += db::ICplxTrans (r->trans ()) * r->back ().bbox (bc);
} else {
@ -1083,8 +1090,7 @@ MainService::cm_make_cell ()
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection () ;
for (edt::Service::objects::const_iterator r = selection.begin (); r != selection.end (); ++r) {
for (EditableSelectionIterator r = (*es)->begin_selection (); ! r.at_end (); ++r) {
if (r->is_cell_inst ()) {
@ -1145,8 +1151,7 @@ MainService::cm_convert_to_cell ()
// Do the conversion
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection () ;
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
const lay::CellView &cv = view ()->cellview (s->cv_index ());
db::cell_index_type ci = s->cell_index_tot ();
@ -1216,9 +1221,8 @@ MainService::cm_convert_to_pcell ()
// check whether the selection contains instances and reject it in that case
size_t num_selected = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
num_selected += selection.size ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
num_selected += (*es)->selection_size ();
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (s->is_cell_inst ()) {
throw tl::Exception (tl::to_string (tr ("Selection contains instances - they cannot be converted to PCells.")));
}
@ -1240,8 +1244,7 @@ MainService::cm_convert_to_pcell ()
const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pc->second);
size_t n = 1000; // 1000 tries max.
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); n > 0 && pc_decl && es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); n > 0 && pc_decl && s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); n > 0 && pc_decl && ! s.at_end (); ++s) {
const lay::CellView &cv = view ()->cellview (s->cv_index ());
if (pc_decl->can_create_from_shape (cv->layout (), s->shape (), s->layer ())) {
--n;
@ -1306,7 +1309,7 @@ MainService::cm_convert_to_pcell ()
manager ()->transaction (tl::to_string (tr ("Convert to PCell")));
}
std::vector<edt::Service::obj_iterator> to_delete;
std::vector<EditableSelectionIterator::pointer> to_delete;
std::vector<lay::ObjectInstPath> new_selection;
bool any_non_converted = false;
@ -1318,8 +1321,7 @@ MainService::cm_convert_to_pcell ()
// convert the shapes which can be converted
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
const lay::CellView &cv = view ()->cellview (s->cv_index ());
@ -1343,7 +1345,7 @@ MainService::cm_convert_to_pcell ()
new_selection.back ().add_path (db::InstElement (cell_inst));
// mark the shape for delete (later)
to_delete.push_back (s);
to_delete.push_back (s.operator-> ());
any_converted = true;
@ -1366,7 +1368,7 @@ MainService::cm_convert_to_pcell ()
}
// Delete the shapes which have been converted
for (std::vector<edt::Service::obj_iterator>::const_iterator td = to_delete.begin (); td != to_delete.end (); ++td) {
for (std::vector<EditableSelectionIterator::pointer>::const_iterator td = to_delete.begin (); td != to_delete.end (); ++td) {
db::Cell &cell = view ()->cellview ((*td)->cv_index ())->layout ().cell ((*td)->cell_index ());
if (cell.shapes ((*td)->layer ()).is_valid ((*td)->shape ())) {
cell.shapes ((*td)->layer ()).erase_shape ((*td)->shape ());
@ -1418,8 +1420,7 @@ void MainService::cm_area_perimeter ()
// get (common) cellview index of the primary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (s->is_cell_inst ()) {
continue;
@ -1525,8 +1526,7 @@ MainService::cm_round_corners ()
// get (common) cellview index of the primary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
@ -1600,8 +1600,7 @@ MainService::cm_round_corners ()
// Delete the current selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
db::Cell &cell = view ()->cellview (s->cv_index ())->layout ().cell (s->cell_index ());
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
@ -1661,8 +1660,7 @@ MainService::cm_size ()
// get (common) cellview index of the primary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
@ -1732,8 +1730,7 @@ MainService::cm_size ()
// Delete the current selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
db::Cell &cell = view ()->cellview (s->cv_index ())->layout ().cell (s->cell_index ());
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
@ -1789,8 +1786,7 @@ MainService::boolean_op (int mode)
// get (common) cellview index of the primary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (s->seq () == 0 && ! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
@ -1824,8 +1820,7 @@ MainService::boolean_op (int mode)
// get the secondary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (s->seq () > 0 && ! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
@ -1862,8 +1857,7 @@ MainService::boolean_op (int mode)
// Let's see whether this heuristics is more accepted.
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst () && int (s->layer ()) == layer_index && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
db::Cell &cell = view ()->cellview (s->cv_index ())->layout ().cell (s->cell_index ());
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
@ -1998,8 +1992,7 @@ MainService::cm_align ()
// get (common) bbox index of the primary selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (s->seq () == 0) {
@ -2029,13 +2022,11 @@ MainService::cm_align ()
// do the alignment
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
// create a transformation vector that describes each shape's transformation
std::vector <db::DCplxTrans> tv;
tv.reserve (selection.size ());
tv.reserve ((*es)->selection_size ());
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
db::DVector v;
@ -2102,8 +2093,7 @@ MainService::cm_distribute ()
// count the items
size_t n = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
++n;
}
}
@ -2125,8 +2115,7 @@ MainService::cm_distribute ()
objects_for_service.push_back (std::make_pair (i, i));
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
const db::Layout &layout = view ()->cellview (s->cv_index ())->layout ();
db::CplxTrans tr = db::CplxTrans (layout.dbu ()) * s->trans ();
@ -2208,8 +2197,7 @@ MainService::cm_make_array ()
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
++n;
}
}
@ -2243,8 +2231,7 @@ MainService::cm_make_array ()
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
const lay::CellView &cv = view ()->cellview (s->cv_index ());
if (! cv.is_valid ()) {
@ -2541,8 +2528,7 @@ MainService::check_no_guiding_shapes ()
{
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
const edt::Service::objects &selection = (*es)->selection ();
for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) {
for (EditableSelectionIterator s = (*es)->begin_selection (); ! s.at_end (); ++s) {
if (! s->is_cell_inst ()) {
if (s->layer () == view ()->cellview (s->cv_index ())->layout ().guiding_shape_layer ()) {
throw tl::Exception (tl::to_string (tr ("This function cannot be applied to PCell guiding shapes")));