Fixed issue #1425: enhancement - allow searching for layers in layouts by name even if they have layer/datatype

This commit is contained in:
Matthias Koefferlein 2023-07-23 10:05:20 +02:00
parent abf2970438
commit 393aacbcff
2 changed files with 78 additions and 14 deletions

View File

@ -128,6 +128,19 @@ size_t hash_value (const db::LayerProperties *l)
return std::hfunc (*l);
}
static bool log_equal_ext (const db::LayerProperties *lp1, const db::LayerProperties &lp2)
{
if (lp1->log_equal (lp2)) {
return true;
}
// compare by name as fallback if one argument is named and the other is not
// (this gives a way to look up
if ((lp1->is_named () || lp2.is_named()) && ! lp1->name.empty () && ! lp2.name.empty ()) {
return lp1->name == lp2.name;
}
return false;
}
// since there already exists a "LayerProperties" object, we call this one "LayerInfo"
Class<db::LayerProperties> decl_LayerInfo ("db", "LayerInfo",
gsi::constructor ("new", &ctor_layer_info_default,
@ -194,14 +207,15 @@ Class<db::LayerProperties> decl_LayerInfo ("db", "LayerInfo",
"\n"
"This method was added in version 0.18.\n"
) +
gsi::method ("is_equivalent?", &db::LayerProperties::log_equal, gsi::arg ("b"),
gsi::method_ext ("is_equivalent?", &log_equal_ext, gsi::arg ("b"),
"@brief Equivalence of two layer info objects\n"
"@return True, if both are equivalent\n"
"\n"
"First, layer and datatype are compared. The name is of second order and used only if no layer or datatype is given.\n"
"First, layer and datatype are compared. The name is of second order and used only if no layer or datatype is given "
"for one of the operands.\n"
"This is basically a weak comparison that reflects the search preferences.\n"
"\n"
"This method was added in version 0.18.\n"
"This method was added in version 0.18 and modified to compare non-named vs. named layers in version 0.28.11.\n"
) +
gsi::method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
@ -506,7 +520,7 @@ static tl::Variant find_layer (db::Layout *l, const db::LayerProperties &lp)
} else {
// if we have a layer with the requested properties already, return this.
for (db::Layout::layer_iterator li = l->begin_layers (); li != l->end_layers (); ++li) {
if ((*li).second->log_equal (lp)) {
if (log_equal_ext ((*li).second, lp)) {
return tl::Variant ((*li).first);
}
}
@ -530,7 +544,7 @@ static tl::Variant find_layer3 (db::Layout *l, int ln, int dn, const std::string
return find_layer (l, db::LayerProperties (ln, dn, name));
}
static std::vector<unsigned int> layer_indices (const db::Layout *l)
static std::vector<unsigned int> layer_indexes (const db::Layout *l)
{
std::vector<unsigned int> layers;
for (unsigned int i = 0; i < l->layers (); ++i) {
@ -1755,7 +1769,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"@param layer_index The index of the layer to delete.\n"
) +
gsi::method_ext ("layer_indexes|#layer_indices", &layer_indices,
gsi::method_ext ("layer_indexes|#layer_indices", &layer_indexes,
"@brief Gets a list of valid layer's indices\n"
"This method returns an array with layer indices representing valid layers.\n"
"\n"

View File

@ -64,16 +64,38 @@ class DBLayoutTests1_TestClass < TestBase
assert_equal(l3.anonymous?, false)
assert_equal(l3.is_named?, true)
assert_equal(l3.is_equivalent?(l2), false)
l3.layer = 1
l3.datatype = 100
assert_equal(l3.is_named?, false)
assert_equal(l3.is_equivalent?(l2), true)
assert_equal(l2.is_equivalent?(l3), false)
l4 = RBA::LayerInfo::new(1, 100, "aber")
assert_equal(l4.to_s, "aber (1/100)")
assert_equal(l4.anonymous?, false)
assert_equal(l4.is_named?, false)
assert_equal(l4.is_equivalent?(l2), true)
assert_equal(l2.is_equivalent?(l4), true)
assert_equal(l4.is_equivalent?(l3), true)
assert_equal(l3.is_equivalent?(l4), true)
assert_equal(l4.is_equivalent?(RBA::LayerInfo::new(1, 100, "xyz")), true)
assert_equal(l4.is_equivalent?(RBA::LayerInfo::new(1, 101, "aber")), false)
l1.assign(l4)
l1.assign(l3)
assert_equal(l1.to_s, "aber (1/100)")
assert_equal(l1.is_named?, false)
assert_equal(l1.is_equivalent?(l3), true)
assert_equal(l1 == l3, true)
assert_equal(l1.is_equivalent?(l4), true)
assert_equal(l1 == l4, true)
l1.layer = -1
l1.datatype = -1
assert_equal(l1.is_named?, true)
assert_equal(l1.to_s, "aber")
l1.name = "xyz"
assert_equal(l1.is_named?, true)
assert_equal(l1.to_s, "xyz")
l1.layer = 100
l1.datatype = 0
assert_equal(l1.is_named?, false)
assert_equal(l1.to_s, "xyz (100/0)")
end
@ -164,16 +186,44 @@ class DBLayoutTests1_TestClass < TestBase
assert_equal(a, nil)
a = ly.find_layer(RBA::LayerInfo.new(2, 0))
assert_equal(a, li)
a = ly.find_layer(3, 0, "hallo")
assert_equal(a, nil)
li2 = ly.layer("hallo")
a = ly.find_layer("hillo")
assert_equal(a, nil)
a = ly.find_layer("hallo")
assert_equal(a, li2)
a = ly.find_layer(3, 0, "hallo")
assert_equal(a, nil)
assert_equal(a, li2)
a = ly.find_layer(2, 0, "hallo")
assert_equal(a, li)
ly = RBA::Layout.new
li = ly.layer(2, 0, "hallo")
a = ly.find_layer(3, 0)
assert_equal(a, nil)
a = ly.find_layer(2, 0)
assert_equal(a, li)
a = ly.find_layer("hallo")
assert_equal(a, li)
a = ly.find_layer(2, 0, "hillo")
assert_equal(a, li)
a = ly.find_layer(1, 0, "hallo")
assert_equal(a, nil)
ly = RBA::Layout.new
li = ly.layer("hallo")
a = ly.find_layer(3, 0)
assert_equal(a, nil)
a = ly.find_layer(2, 0)
assert_equal(a, nil)
a = ly.find_layer("hallo")
assert_equal(a, li)
a = ly.find_layer(2, 0, "hillo")
assert_equal(a, nil)
a = ly.find_layer(1, 0, "hallo")
assert_equal(a, li)
end
def collect(s, l)