mirror of https://github.com/KLayout/klayout.git
Some refactoring
This commit is contained in:
parent
b7ee16b63f
commit
22bab6d6a6
|
|
@ -93,7 +93,7 @@ Cell::box_type Cell::ms_empty_box = Cell::box_type ();
|
||||||
Cell::Cell (cell_index_type ci, db::Layout &l)
|
Cell::Cell (cell_index_type ci, db::Layout &l)
|
||||||
: db::Object (l.manager ()),
|
: db::Object (l.manager ()),
|
||||||
m_cell_index (ci), mp_layout (&l), m_instances (this), m_prop_id (0), m_hier_levels (0),
|
m_cell_index (ci), mp_layout (&l), m_instances (this), m_prop_id (0), m_hier_levels (0),
|
||||||
m_instances_need_sort (false), m_instances_need_sort_box_tree (false), m_bbox_needs_update (false), m_ghost_cell (false),
|
m_bbox_needs_update (false), m_ghost_cell (false),
|
||||||
mp_last (0), mp_next (0)
|
mp_last (0), mp_next (0)
|
||||||
{
|
{
|
||||||
// .. nothing yet
|
// .. nothing yet
|
||||||
|
|
@ -132,10 +132,6 @@ Cell::operator= (const Cell &d)
|
||||||
m_prop_id = d.m_prop_id;
|
m_prop_id = d.m_prop_id;
|
||||||
m_bbox_needs_update = d.m_bbox_needs_update;
|
m_bbox_needs_update = d.m_bbox_needs_update;
|
||||||
|
|
||||||
// need to update the instances inst_by_cell_index pointers
|
|
||||||
m_instances_need_sort = true;
|
|
||||||
m_instances_need_sort_box_tree = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -618,8 +614,6 @@ Cell::invalidate_insts ()
|
||||||
{
|
{
|
||||||
mp_layout->invalidate_hier (); // HINT: must come before the change is done!
|
mp_layout->invalidate_hier (); // HINT: must come before the change is done!
|
||||||
mp_layout->invalidate_bboxes (std::numeric_limits<unsigned int>::max ());
|
mp_layout->invalidate_bboxes (std::numeric_limits<unsigned int>::max ());
|
||||||
m_instances_need_sort = true;
|
|
||||||
m_instances_need_sort_box_tree = true;
|
|
||||||
m_bbox_needs_update = true;
|
m_bbox_needs_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -707,10 +701,7 @@ Cell::clear_parent_insts (size_t sz)
|
||||||
void
|
void
|
||||||
Cell::sort_child_insts ()
|
Cell::sort_child_insts ()
|
||||||
{
|
{
|
||||||
if (m_instances_need_sort) {
|
m_instances.sort_child_insts ();
|
||||||
m_instances.sort_child_insts ();
|
|
||||||
}
|
|
||||||
m_instances_need_sort = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, db::pcell_id_type>
|
std::pair<bool, db::pcell_id_type>
|
||||||
|
|
@ -756,10 +747,7 @@ Cell::change_pcell_parameters (const instance_type &ref, const std::vector<tl::V
|
||||||
void
|
void
|
||||||
Cell::sort_inst_tree (bool force)
|
Cell::sort_inst_tree (bool force)
|
||||||
{
|
{
|
||||||
if (force || m_instances_need_sort_box_tree) {
|
m_instances.sort_inst_tree (mp_layout, force);
|
||||||
m_instances.sort_inst_tree (mp_layout);
|
|
||||||
}
|
|
||||||
m_instances_need_sort_box_tree = false;
|
|
||||||
|
|
||||||
// update the number of hierarchy levels
|
// update the number of hierarchy levels
|
||||||
m_hier_levels = count_hier_levels ();
|
m_hier_levels = count_hier_levels ();
|
||||||
|
|
|
||||||
|
|
@ -1076,9 +1076,7 @@ private:
|
||||||
db::properties_id_type m_prop_id;
|
db::properties_id_type m_prop_id;
|
||||||
|
|
||||||
// packed fields
|
// packed fields
|
||||||
unsigned int m_hier_levels : 28;
|
unsigned int m_hier_levels : 30;
|
||||||
bool m_instances_need_sort : 1;
|
|
||||||
bool m_instances_need_sort_box_tree : 1;
|
|
||||||
bool m_bbox_needs_update : 1;
|
bool m_bbox_needs_update : 1;
|
||||||
bool m_ghost_cell : 1;
|
bool m_ghost_cell : 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -940,6 +940,9 @@ Instances::operator= (const Instances &d)
|
||||||
|
|
||||||
m_parent_insts = d.m_parent_insts;
|
m_parent_insts = d.m_parent_insts;
|
||||||
|
|
||||||
|
set_instance_by_cell_index_needs_made (true);
|
||||||
|
set_instance_tree_needs_sort (true);
|
||||||
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -947,13 +950,24 @@ Instances::operator= (const Instances &d)
|
||||||
bool
|
bool
|
||||||
Instances::is_editable () const
|
Instances::is_editable () const
|
||||||
{
|
{
|
||||||
return mp_cell && mp_cell->layout () ? mp_cell->layout ()->is_editable () : true;
|
return cell () && cell ()->layout () ? cell ()->layout ()->is_editable () : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Layout *
|
db::Layout *
|
||||||
Instances::layout () const
|
Instances::layout () const
|
||||||
{
|
{
|
||||||
return mp_cell ? mp_cell->layout () : 0;
|
return cell () ? cell ()->layout () : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Instances::invalidate_insts ()
|
||||||
|
{
|
||||||
|
if (cell ()) {
|
||||||
|
cell ()->invalidate_insts ();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_instance_by_cell_index_needs_made (true);
|
||||||
|
set_instance_tree_needs_sort (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Tag, class ET, class I>
|
template <class Tag, class ET, class I>
|
||||||
|
|
@ -962,14 +976,15 @@ Instances::erase_positions (Tag tag, ET editable_tag, I first, I last)
|
||||||
{
|
{
|
||||||
typedef instances_editable_traits<ET> editable_traits;
|
typedef instances_editable_traits<ET> editable_traits;
|
||||||
|
|
||||||
if (mp_cell) {
|
invalidate_insts (); // HINT: must come before the change is done!
|
||||||
mp_cell->invalidate_insts (); // HINT: must come before the change is done!
|
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()) {
|
||||||
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
if (! is_editable ()) {
|
if (! is_editable ()) {
|
||||||
throw tl::Exception (tl::to_string (tr ("No undo/redo support for non-editable instance lists in 'erase_positions'")));
|
throw tl::Exception (tl::to_string (tr ("No undo/redo support for non-editable instance lists in 'erase_positions'")));
|
||||||
}
|
}
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, first, last, true /*dummy*/));
|
cell ()->manager ()->queue (cell (), new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, first, last, true /*dummy*/));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -983,18 +998,19 @@ Instances::insert (const InstArray &inst)
|
||||||
{
|
{
|
||||||
bool editable = is_editable ();
|
bool editable = is_editable ();
|
||||||
|
|
||||||
if (mp_cell) {
|
if (cell ()) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
if (editable) {
|
if (editable) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, inst));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, inst));
|
||||||
} else {
|
} else {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesNonEditableTag> (true /*insert*/, inst));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesNonEditableTag> (true /*insert*/, inst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidate_insts ();
|
||||||
|
|
||||||
// TODO: simplify this, i.e. through instance_from_pointer
|
// TODO: simplify this, i.e. through instance_from_pointer
|
||||||
if (editable) {
|
if (editable) {
|
||||||
return instance_type (this, inst_tree (typename InstArray::tag (), InstancesEditableTag ()).insert (inst));
|
return instance_type (this, inst_tree (typename InstArray::tag (), InstancesEditableTag ()).insert (inst));
|
||||||
|
|
@ -1010,14 +1026,14 @@ Instances::insert (I from, I to)
|
||||||
typedef std::iterator_traits<I> it_traits;
|
typedef std::iterator_traits<I> it_traits;
|
||||||
typedef typename it_traits::value_type value_type;
|
typedef typename it_traits::value_type value_type;
|
||||||
|
|
||||||
if (mp_cell) {
|
if (cell ()) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename it_traits::value_type, ET> (true /*insert*/, from, to));
|
cell ()->manager ()->queue (cell (), new db::InstOp<typename it_traits::value_type, ET> (true /*insert*/, from, to));
|
||||||
}
|
}
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidate_insts ();
|
||||||
inst_tree (typename value_type::tag (), ET ()).insert (from, to);
|
inst_tree (typename value_type::tag (), ET ()).insert (from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1061,20 +1077,21 @@ template <class InstArray>
|
||||||
void
|
void
|
||||||
Instances::replace (const InstArray *replace, const InstArray &with)
|
Instances::replace (const InstArray *replace, const InstArray &with)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
if (cell ()) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (false /*not insert*/, *replace));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesEditableTag> (false /*not insert*/, *replace));
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, with));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, with));
|
||||||
} else {
|
} else {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesNonEditableTag> (false /*not insert*/, *replace));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesNonEditableTag> (false /*not insert*/, *replace));
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesNonEditableTag> (true /*insert*/, with));
|
cell ()->manager ()->queue (cell (), new db::InstOp<InstArray, InstancesNonEditableTag> (true /*insert*/, with));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidate_insts ();
|
||||||
|
|
||||||
// HINT: this only works because we know our box trees well:
|
// HINT: this only works because we know our box trees well:
|
||||||
*((InstArray *)replace) = with;
|
*((InstArray *)replace) = with;
|
||||||
}
|
}
|
||||||
|
|
@ -1150,11 +1167,12 @@ Instances::erase_inst_by_iter (Tag tag, ET editable_tag, I iter)
|
||||||
throw tl::Exception (tl::to_string (tr ("Trying to erase an object from a list that it does not belong to")));
|
throw tl::Exception (tl::to_string (tr ("Trying to erase an object from a list that it does not belong to")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()) {
|
||||||
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, *iter));
|
cell ()->manager ()->queue (cell (), new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, *iter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1165,11 +1183,12 @@ template <class Tag, class ET>
|
||||||
void
|
void
|
||||||
Instances::erase_inst_by_tag (Tag tag, ET editable_tag, const typename Tag::object_type &obj)
|
Instances::erase_inst_by_tag (Tag tag, ET editable_tag, const typename Tag::object_type &obj)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()) {
|
||||||
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, obj));
|
cell ()->manager ()->queue (cell (), new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1197,16 +1216,17 @@ template <class ET>
|
||||||
void
|
void
|
||||||
Instances::clear_insts (ET editable_tag)
|
Instances::clear_insts (ET editable_tag)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()) {
|
||||||
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
const Instances *const_this = this;
|
const Instances *const_this = this;
|
||||||
if (! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ()) {
|
if (! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ()) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
if (! const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).empty ()) {
|
if (! const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).empty ()) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_wp_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_wp_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1227,9 +1247,7 @@ Instances::clear_insts ()
|
||||||
void
|
void
|
||||||
Instances::clear (Instances::cell_inst_array_type::tag)
|
Instances::clear (Instances::cell_inst_array_type::tag)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_generic.any) {
|
if (m_generic.any) {
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
|
|
@ -1244,9 +1262,7 @@ Instances::clear (Instances::cell_inst_array_type::tag)
|
||||||
void
|
void
|
||||||
Instances::clear (Instances::cell_inst_wp_array_type::tag)
|
Instances::clear (Instances::cell_inst_wp_array_type::tag)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_generic_wp.any) {
|
if (m_generic_wp.any) {
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
|
|
@ -1373,6 +1389,11 @@ struct cell_inst_compare_f
|
||||||
void
|
void
|
||||||
Instances::sort_child_insts ()
|
Instances::sort_child_insts ()
|
||||||
{
|
{
|
||||||
|
if (! instance_by_cell_index_needs_made ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
set_instance_by_cell_index_needs_made (false);
|
||||||
|
|
||||||
m_insts_by_cell_index = sorted_inst_vector ();
|
m_insts_by_cell_index = sorted_inst_vector ();
|
||||||
m_insts_by_cell_index.reserve (cell_instances ());
|
m_insts_by_cell_index.reserve (cell_instances ());
|
||||||
|
|
||||||
|
|
@ -1406,8 +1427,13 @@ Instances::sort_child_insts ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Instances::sort_inst_tree (const Layout *g)
|
Instances::sort_inst_tree (const Layout *g, bool force)
|
||||||
{
|
{
|
||||||
|
if (! force && ! instance_tree_needs_sort ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
set_instance_tree_needs_sort (false);
|
||||||
|
|
||||||
if (m_generic.any) {
|
if (m_generic.any) {
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
m_generic.stable_tree->sort (cell_inst_array_box_converter (*g));
|
m_generic.stable_tree->sort (cell_inst_array_box_converter (*g));
|
||||||
|
|
@ -1603,16 +1629,17 @@ void Instances::apply_op (const Op &op, ET editable_tag)
|
||||||
bool has_insts = ! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ();
|
bool has_insts = ! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ();
|
||||||
bool has_wp_insts = ! const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).empty ();
|
bool has_wp_insts = ! const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).empty ();
|
||||||
|
|
||||||
if (mp_cell) {
|
invalidate_insts ();
|
||||||
mp_cell->invalidate_insts ();
|
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (cell ()) {
|
||||||
|
if (cell ()->manager () && cell ()->manager ()->transacting ()) {
|
||||||
check_is_editable_for_undo_redo (this);
|
check_is_editable_for_undo_redo (this);
|
||||||
transacting = true;
|
transacting = true;
|
||||||
if (has_insts) {
|
if (has_insts) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
if (has_wp_insts) {
|
if (has_wp_insts) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_wp_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_wp_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1637,10 +1664,10 @@ void Instances::apply_op (const Op &op, ET editable_tag)
|
||||||
|
|
||||||
if (transacting) {
|
if (transacting) {
|
||||||
if (has_insts) {
|
if (has_insts) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (true /*insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_array_type, ET> (true /*insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
if (has_wp_insts) {
|
if (has_wp_insts) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_wp_array_type, ET> (true /*insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
cell ()->manager ()->queue (cell (), new db::InstOp<cell_inst_wp_array_type, ET> (true /*insert*/, const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_wp_array_type::tag (), editable_tag).end ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1553,10 +1553,11 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Sort the cell instance list
|
* @brief Sort the cell instance list
|
||||||
*
|
*
|
||||||
* This will sort the cell instance list. As a prerequesite
|
* This will sort the cell instance list (quad tree sort). As a prerequesite
|
||||||
* the cell's bounding boxes must have been computed.
|
* the cell's bounding boxes must have been computed.
|
||||||
|
* If force is true, the instance tree is always sorted.
|
||||||
*/
|
*/
|
||||||
void sort_inst_tree (const layout_type *g);
|
void sort_inst_tree (const layout_type *g, bool force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update the child-parent relationships
|
* @brief Update the child-parent relationships
|
||||||
|
|
@ -1701,14 +1702,6 @@ public:
|
||||||
return m_parent_insts.end () == m_parent_insts.begin ();
|
return m_parent_insts.end () == m_parent_insts.begin ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the cell pointer the instance container is in
|
|
||||||
*/
|
|
||||||
db::Cell *cell () const
|
|
||||||
{
|
|
||||||
return mp_cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the layout the instances collection lives in
|
* @brief Gets the layout the instances collection lives in
|
||||||
*/
|
*/
|
||||||
|
|
@ -1724,6 +1717,14 @@ public:
|
||||||
*/
|
*/
|
||||||
bool is_editable () const;
|
bool is_editable () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the cell pointer
|
||||||
|
*/
|
||||||
|
cell_type *cell () const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<cell_type *> (size_t (mp_cell) & ~size_t (3));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Delegate for the undo method
|
* @brief Delegate for the undo method
|
||||||
*/
|
*/
|
||||||
|
|
@ -1735,6 +1736,7 @@ public:
|
||||||
void redo (db::Op *op);
|
void redo (db::Op *op);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Instance;
|
||||||
friend struct NormalInstanceIteratorTraits;
|
friend struct NormalInstanceIteratorTraits;
|
||||||
friend struct TouchingInstanceIteratorTraits;
|
friend struct TouchingInstanceIteratorTraits;
|
||||||
friend struct OverlappingInstanceIteratorTraits;
|
friend struct OverlappingInstanceIteratorTraits;
|
||||||
|
|
@ -1761,6 +1763,43 @@ private:
|
||||||
static stable_cell_inst_wp_tree_type ms_empty_stable_wp_tree;
|
static stable_cell_inst_wp_tree_type ms_empty_stable_wp_tree;
|
||||||
static stable_cell_inst_tree_type ms_empty_stable_tree;
|
static stable_cell_inst_tree_type ms_empty_stable_tree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a flag indicating that the instance tree needs sorting
|
||||||
|
*/
|
||||||
|
void set_instance_tree_needs_sort (bool f)
|
||||||
|
{
|
||||||
|
mp_cell = reinterpret_cast<cell_type *> ((size_t (mp_cell) & ~size_t (1)) | size_t (f ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a flag indicating that the instance tree needs sorting
|
||||||
|
*/
|
||||||
|
bool instance_tree_needs_sort () const
|
||||||
|
{
|
||||||
|
return (size_t (mp_cell) & 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a flag indicating that the instance by cell index cache needs made
|
||||||
|
*/
|
||||||
|
void set_instance_by_cell_index_needs_made (bool f)
|
||||||
|
{
|
||||||
|
mp_cell = reinterpret_cast<cell_type *> ((size_t (mp_cell) & ~size_t (2)) | size_t (f ? 2 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a flag indicating that the instance tree needs sorting
|
||||||
|
*/
|
||||||
|
bool instance_by_cell_index_needs_made () const
|
||||||
|
{
|
||||||
|
return (size_t (mp_cell) & 2) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalidates the instance information - called whenever something changes
|
||||||
|
*/
|
||||||
|
void invalidate_insts ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the non-editable instance tree by instance type
|
* @brief Get the non-editable instance tree by instance type
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1097,15 +1097,17 @@ Layout::do_prune_cell_or_subcell (cell_index_type id, int levels, bool subcells)
|
||||||
// collect the called cells
|
// collect the called cells
|
||||||
std::set <cell_index_type> called;
|
std::set <cell_index_type> called;
|
||||||
cref.collect_called_cells (called, levels);
|
cref.collect_called_cells (called, levels);
|
||||||
called.insert (id);
|
if (! subcells) {
|
||||||
|
called.insert (id);
|
||||||
|
}
|
||||||
|
|
||||||
// From these cells erase all cells that have parents outside the subtree of our cell.
|
// From these cells erase all cells that have parents outside the subtree of our cell.
|
||||||
// Make sure this is done recursively by doing this top-down.
|
// Make sure this is done recursively by doing this top-down.
|
||||||
for (top_down_iterator c = begin_top_down (); c != end_top_down (); ++c) {
|
for (top_down_iterator c = begin_top_down (); c != end_top_down (); ++c) {
|
||||||
if (called.find (*c) != called.end () && *c != id) {
|
if (*c != id && called.find (*c) != called.end ()) {
|
||||||
db::Cell &ccref = cell (*c);
|
db::Cell &ccref = cell (*c);
|
||||||
for (db::Cell::parent_cell_iterator pc = ccref.begin_parent_cells (); pc != ccref.end_parent_cells (); ++pc) {
|
for (db::Cell::parent_cell_iterator pc = ccref.begin_parent_cells (); pc != ccref.end_parent_cells (); ++pc) {
|
||||||
if (called.find (*pc) == called.end ()) {
|
if (*pc != id && called.find (*pc) == called.end ()) {
|
||||||
// we have a parent outside the subset considered currently (either the cell was never in or
|
// we have a parent outside the subset considered currently (either the cell was never in or
|
||||||
// it was removed itself already): remove this cell from the set of valid subcells.
|
// it was removed itself already): remove this cell from the set of valid subcells.
|
||||||
called.erase (*c);
|
called.erase (*c);
|
||||||
|
|
@ -1115,17 +1117,8 @@ Layout::do_prune_cell_or_subcell (cell_index_type id, int levels, bool subcells)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// order the called cells bottom-up
|
// and delete the cells
|
||||||
std::vector <cell_index_type> cells_to_delete;
|
delete_cells (called);
|
||||||
cells_to_delete.reserve (called.size ());
|
|
||||||
for (bottom_up_iterator c = begin_bottom_up (); c != end_bottom_up (); ++c) {
|
|
||||||
if (called.find (*c) != called.end () && (!subcells || *c != id)) {
|
|
||||||
cells_to_delete.push_back (*c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// and delete these cells
|
|
||||||
delete_cells (cells_to_delete.begin (), cells_to_delete.end ());
|
|
||||||
|
|
||||||
// erase all instances in the subcells case (because, by definition we don't have any more instances)
|
// erase all instances in the subcells case (because, by definition we don't have any more instances)
|
||||||
if (subcells) {
|
if (subcells) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue