Updated the solution

This commit is contained in:
Matthias Koefferlein 2021-07-15 23:39:02 +02:00
parent d14892382c
commit 2fee924103
6 changed files with 114 additions and 92 deletions

View File

@ -333,21 +333,13 @@ void
Cell::copy (unsigned int src, unsigned int dest)
{
if (src != dest) {
db::Shapes &dest_shapes = shapes (dest);
db::Cell::shape_iterator src_shape = begin (src, db::Shapes::shape_iterator::All);
while (! src_shape.at_end ()) {
dest_shapes.insert (*src_shape);
++src_shape;
}
shapes (dest).insert (shapes (src));
} else {
// When duplicating the layer, first create a copy to avoid problems with non-stable containers
// Hint: using the assignment and not the copy ctor does not copy the db::Manager association.
db::Shapes shape_copy;
shape_copy = shapes (src);
db::Shapes &dest_shapes = shapes (dest);
for (db::Cell::shape_iterator src_shape = shape_copy.begin (db::Shapes::shape_iterator::All); ! src_shape.at_end (); ++src_shape) {
dest_shapes.insert (*src_shape);
}
shapes (dest).insert (shape_copy);
}
}

View File

@ -138,11 +138,25 @@ void
FullLayerOp::insert (Shapes *shapes)
{
for (tl::vector<LayerBase *>::iterator l = shapes->get_layers ().end (); l != shapes->get_layers ().begin (); ) {
--l;
if (*l == mp_layer) {
return;
} else if ((*l)->is_same_type (mp_layer)) {
delete (*l);
*l = mp_layer;
m_owns_layer = false;
shapes->invalidate_state ();
return;
}
}
shapes->get_layers ().push_back (mp_layer);
shapes->invalidate_state ();
m_owns_layer = false;
@ -984,7 +998,10 @@ Shapes::clear ()
{
if (!m_layers.empty ()) {
for (tl::vector<LayerBase *>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
for (tl::vector<LayerBase *>::const_iterator l = m_layers.end (); l != m_layers.begin (); ) {
// because the undo stack will do a push, we need to remove layers from the back (this is the last undo
// element to be executed)
--l;
if (manager () && manager ()->transacting ()) {
check_is_editable_for_undo_redo ();
manager ()->queue (this, new FullLayerOp (false, (*l)));

View File

@ -487,6 +487,7 @@ public:
virtual bool empty () const = 0;
virtual void sort () = 0;
virtual LayerBase *clone () const = 0;
virtual bool is_same_type (const LayerBase *other) const = 0;
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const = 0;
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const = 0;
virtual void transform_into (Shapes *target, const Trans &trans, GenericRepository &rep, ArrayRepository &array_rep) const = 0;

View File

@ -141,6 +141,11 @@ public:
m_layer.sort ();
}
virtual bool is_same_type (const LayerBase *other) const
{
return dynamic_cast<const layer_class<Sh, StableTag> *> (other);
}
virtual LayerBase *clone () const;
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const;
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const;

View File

@ -557,9 +557,13 @@ TEST(5)
EXPECT_EQ (l2s (l), "begin_lib 0.001\nbegin_cell {LIBCELL}\nbox 1 0 {0 0} {100 200}\nend_cell\nend_lib\n");
// switch to another LIBCELL, this time using layer 2/0
m.transaction ("switch_to_b");
l.set_technology_name ("B");
m.commit ();
if (l.is_editable ()) {
m.transaction ("switch_to_b");
l.set_technology_name ("B");
m.commit ();
} else {
l.set_technology_name ("B");
}
EXPECT_EQ (l.technology_name (), "B");
cell = &l.cell (l.cell_by_name ("LIBCELL").second);
@ -609,9 +613,13 @@ TEST(6)
info.pcell_parameters ["npoints"] = tl::Variant (8);
info.pcell_parameters ["layer"] = tl::Variant (db::LayerProperties (1, 0));
m.transaction ("import");
if (l.is_editable ()) {
m.transaction ("import");
}
cell = l.recover_proxy (info);
m.commit ();
if (l.is_editable ()) {
m.commit ();
}
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");
EXPECT_EQ (cell->get_display_name (), "Basic.CIRCLE(l=1/0,r=10,n=8)");
@ -622,10 +630,14 @@ TEST(6)
l.get_context_info (cell->cell_index (), info2);
info2.pcell_parameters ["actual_radius"] = tl::Variant (5.0);
m.transaction ("modify");
if (l.is_editable ()) {
m.transaction ("modify");
}
db::cell_index_type ci = cell->cell_index ();
l.recover_proxy_as (ci, info2);
m.commit ();
if (l.is_editable ()) {
m.commit ();
}
cell = &l.cell (ci);
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");

View File

@ -901,103 +901,98 @@ class DBLayout_TestClass < TestBase
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
# TODO: undo tests crashes in non-editable mode! Should be checked properly.
if lll.is_editable?
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, false)
assert_equal(m.transaction_for_undo, "9")
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, false)
assert_equal(m.transaction_for_undo, "9")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "8")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "8")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "7")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "7")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "6")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "6")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "5")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "5")
assert_equal(dump_layer(l, 0, "c0"), "(1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
assert_equal(dump_layer(l, 0, "c0"), "(1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "4")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "4")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "3")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "3")
assert_equal(dump_layer(l, 1, "c0"), "")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "2")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "2")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "1")
m.undo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_undo, "1")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
m.undo
assert_equal(m.has_undo?, false)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_redo, "1")
m.undo
assert_equal(m.has_undo?, false)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_redo, "1")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "")
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 1, "c0"), "")
m.redo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_redo, "2")
m.redo
assert_equal(m.has_undo?, true)
assert_equal(m.has_redo?, true)
assert_equal(m.transaction_for_redo, "2")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(l, 0, "c0"), "")
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
assert_equal(dump_layer(ll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(ll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
assert_equal(dump_layer(ll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(ll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
l.destroy
m.destroy
l.destroy
m.destroy
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
end
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
end