| 2038 | } |
| 2039 | |
| 2040 | void |
| 2041 | Layout::do_update () |
| 2042 | { |
| 2043 | if (! update_needed ()) { |
| 2044 | return; |
| 2045 | } |
| 2046 | |
| 2047 | tl::SelfTimer timer (tl::verbosity () > layout_base_verbosity, tl::to_string (tr ("Sorting"))); |
| 2048 | |
| 2049 | // establish a progress report since this operation can take some time. |
| 2050 | // HINT: because of some gcc bug, automatic destruction of the tl::Progress |
| 2051 | // object does not work. We overcome this problem by creating the object with new |
| 2052 | // and catching exceptions. |
| 2053 | // As this operation is critical we don't want to have it cancelled. Plus: do_update is called during ~LayoutLocker and |
| 2054 | // if we throw exceptions then, we'll get a runtime assertion. |
| 2055 | tl::RelativeProgress *pr = new tl::RelativeProgress (tl::to_string (tr ("Sorting layout")), m_cells_size, 0, false /*can't cancel*/); |
| 2056 | pr->set_desc (""); |
| 2057 | |
| 2058 | try { |
| 2059 | |
| 2060 | // if the hierarchy has been changed so far, update |
| 2061 | // the hierarchy management information |
| 2062 | if (hier_dirty ()) { |
| 2063 | { |
| 2064 | tl::SelfTimer timer (tl::verbosity () > layout_base_verbosity + 10, "Updating relations"); |
| 2065 | pr->set_desc (tl::to_string (tr ("Updating relations"))); |
| 2066 | update_relations (); |
| 2067 | } |
| 2068 | { |
| 2069 | tl::SelfTimer timer (tl::verbosity () > layout_base_verbosity + 10, "Topological sort"); |
| 2070 | pr->set_desc (tl::to_string (tr ("Topological sorting"))); |
| 2071 | tl_assert (topological_sort ()); |
| 2072 | } |
| 2073 | } |
| 2074 | |
| 2075 | // KLUDGE: a boolean vector (with size as determined by number of cells) |
| 2076 | // would probably be much faster! |
| 2077 | std::set<cell_index_type> dirty_parents; |
| 2078 | |
| 2079 | // if something on the bboxes (either on shape level or on |
| 2080 | // cell bbox level - i.e. by child instances) has been changed, |
| 2081 | // update the bbox information. In addition sort the shapes |
| 2082 | // lists of region queries, since they might have changed once |
| 2083 | // the bboxes are dirty. |
| 2084 | if (bboxes_dirty ()) { |
| 2085 | |
| 2086 | { |
| 2087 | tl::SelfTimer timer (tl::verbosity () > layout_base_verbosity + 10, "Updating bounding boxes"); |
| 2088 | unsigned int layers = 0; |
| 2089 | pr->set (0); |
| 2090 | pr->set_desc (tl::to_string (tr ("Updating bounding boxes"))); |
| 2091 | for (bottom_up_iterator c = m_top_down_list.rbegin (); c != m_top_down_list.rend (); ++c) { |
| 2092 | ++*pr; |
| 2093 | cell_type &cp (cell (*c)); |
| 2094 | if (cp.is_shape_bbox_dirty () || dirty_parents.find (*c) != dirty_parents.end ()) { |
| 2095 | if (cp.update_bbox (layers)) { |
| 2096 | // the bounding box has changed - need to insert parents into "dirty parents" list |
| 2097 | // NOTE: using "instances" instead of the cell directly avoids a recursive update call |
nothing calls this directly
no test coverage detected