mirror of https://github.com/KLayout/klayout.git
Convenience methods Shape#properties, Layout#properties, Cell#properties, Instance#properties
This commit is contained in:
parent
6baabc30bb
commit
4cd8772e70
|
|
@ -1104,14 +1104,14 @@ static void set_cell_property (db::Cell *c, const tl::Variant &key, const tl::Va
|
||||||
c->prop_id (layout->properties_repository ().properties_id (props));
|
c->prop_id (layout->properties_repository ().properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::Variant get_cell_property (db::Cell *c, const tl::Variant &key)
|
static tl::Variant get_cell_property (const db::Cell *c, const tl::Variant &key)
|
||||||
{
|
{
|
||||||
db::properties_id_type id = c->prop_id ();
|
db::properties_id_type id = c->prop_id ();
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
return tl::Variant ();
|
return tl::Variant ();
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Layout *layout = c->layout ();
|
const db::Layout *layout = c->layout ();
|
||||||
if (! layout) {
|
if (! layout) {
|
||||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot retrieve properties")));
|
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot retrieve properties")));
|
||||||
}
|
}
|
||||||
|
|
@ -1130,6 +1130,26 @@ static tl::Variant get_cell_property (db::Cell *c, const tl::Variant &key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tl::Variant get_cell_properties (const db::Cell *c)
|
||||||
|
{
|
||||||
|
db::properties_id_type id = c->prop_id ();
|
||||||
|
if (id == 0) {
|
||||||
|
return tl::Variant::empty_array ();
|
||||||
|
}
|
||||||
|
|
||||||
|
const db::Layout *layout = c->layout ();
|
||||||
|
if (! layout) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Cell does not reside inside a layout - cannot retrieve properties")));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::Variant res = tl::Variant::empty_array ();
|
||||||
|
const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (id);
|
||||||
|
for (auto i = props.begin (); i != props.end (); ++i) {
|
||||||
|
res.insert (layout->properties_repository ().prop_name (i->first), i->second);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_pcell_variant (const db::Cell *cell)
|
static bool is_pcell_variant (const db::Cell *cell)
|
||||||
{
|
{
|
||||||
tl_assert (cell->layout () != 0);
|
tl_assert (cell->layout () != 0);
|
||||||
|
|
@ -1841,10 +1861,16 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
||||||
"@brief Gets the user property with the given key\n"
|
"@brief Gets the user property with the given key\n"
|
||||||
"This method is a convenience method that gets the property with the given key. "
|
"This method is a convenience method that gets the property with the given key. "
|
||||||
"If no property with that key exists, it will return nil. Using that method is more "
|
"If no property with that key exists, it will return nil. Using that method is more "
|
||||||
"convenient than using the layout object and the properties ID to retrieve the property value. "
|
"convenient than using the layout object and the properties ID to retrieve the property value.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.23."
|
"This method has been introduced in version 0.23."
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("properties", &get_cell_properties,
|
||||||
|
"@brief Gets the user properties as a hash\n"
|
||||||
|
"This method is a convenience method that gets all user properties as a single hash.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29.5."
|
||||||
|
) +
|
||||||
gsi::method_ext ("add_meta_info", &cell_add_meta_info, gsi::arg ("info"),
|
gsi::method_ext ("add_meta_info", &cell_add_meta_info, gsi::arg ("info"),
|
||||||
"@brief Adds meta information to the cell\n"
|
"@brief Adds meta information to the cell\n"
|
||||||
"See \\LayoutMetaInfo for details about cells and meta information.\n"
|
"See \\LayoutMetaInfo for details about cells and meta information.\n"
|
||||||
|
|
@ -3539,6 +3565,26 @@ static tl::Variant get_property (const db::Instance *i, const tl::Variant &key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tl::Variant get_properties (const db::Instance *i)
|
||||||
|
{
|
||||||
|
db::properties_id_type id = i->prop_id ();
|
||||||
|
if (id == 0) {
|
||||||
|
return tl::Variant::empty_array ();
|
||||||
|
}
|
||||||
|
|
||||||
|
const db::Layout *layout = layout_ptr_const (i);
|
||||||
|
if (! layout) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Instance does not reside inside a layout - cannot retrieve properties")));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::Variant res = tl::Variant::empty_array ();
|
||||||
|
const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (id);
|
||||||
|
for (auto i = props.begin (); i != props.end (); ++i) {
|
||||||
|
res.insert (layout->properties_repository ().prop_name (i->first), i->second);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static bool inst_is_valid (const db::Instance *inst)
|
static bool inst_is_valid (const db::Instance *inst)
|
||||||
{
|
{
|
||||||
return inst->instances () && inst->instances ()->is_valid (*inst);
|
return inst->instances () && inst->instances ()->is_valid (*inst);
|
||||||
|
|
@ -4011,6 +4057,12 @@ Class<db::Instance> decl_Instance ("db", "Instance",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.22."
|
"This method has been introduced in version 0.22."
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("properties", &get_properties,
|
||||||
|
"@brief Gets the user properties as a hash\n"
|
||||||
|
"This method is a convenience method that gets all user properties as a single hash.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29.5."
|
||||||
|
) +
|
||||||
method_ext ("[]", &inst_index, gsi::arg ("key"),
|
method_ext ("[]", &inst_index, gsi::arg ("key"),
|
||||||
"@brief Gets the user property with the given key or, if available, the PCell parameter with the name given by the key\n"
|
"@brief Gets the user property with the given key or, if available, the PCell parameter with the name given by the key\n"
|
||||||
"Getting the PCell parameter has priority over the user property."
|
"Getting the PCell parameter has priority over the user property."
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ static void set_layout_property (db::Layout *l, const tl::Variant &key, const tl
|
||||||
l->prop_id (l->properties_repository ().properties_id (props));
|
l->prop_id (l->properties_repository ().properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::Variant get_layout_property (db::Layout *l, const tl::Variant &key)
|
static tl::Variant get_layout_property (const db::Layout *l, const tl::Variant &key)
|
||||||
{
|
{
|
||||||
// TODO: check if is editable
|
// TODO: check if is editable
|
||||||
|
|
||||||
|
|
@ -367,6 +367,21 @@ static tl::Variant get_layout_property (db::Layout *l, const tl::Variant &key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tl::Variant get_layout_properties (const db::Layout *layout)
|
||||||
|
{
|
||||||
|
db::properties_id_type id = layout->prop_id ();
|
||||||
|
if (id == 0) {
|
||||||
|
return tl::Variant::empty_array ();
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::Variant res = tl::Variant::empty_array ();
|
||||||
|
const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (id);
|
||||||
|
for (auto i = props.begin (); i != props.end (); ++i) {
|
||||||
|
res.insert (layout->properties_repository ().prop_name (i->first), i->second);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static db::cell_index_type cell_by_name (db::Layout *l, const char *name)
|
static db::cell_index_type cell_by_name (db::Layout *l, const char *name)
|
||||||
{
|
{
|
||||||
std::pair<bool, db::cell_index_type> c = l->cell_by_name (name);
|
std::pair<bool, db::cell_index_type> c = l->cell_by_name (name);
|
||||||
|
|
@ -1265,6 +1280,12 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.24."
|
"This method has been introduced in version 0.24."
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("properties", &get_layout_properties,
|
||||||
|
"@brief Gets the user properties as a hash\n"
|
||||||
|
"This method is a convenience method that gets all user properties as a single hash.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29.5."
|
||||||
|
) +
|
||||||
gsi::method_ext ("properties_id", &properties_id, gsi::arg ("properties"),
|
gsi::method_ext ("properties_id", &properties_id, gsi::arg ("properties"),
|
||||||
"@brief Gets the properties ID for a given properties set\n"
|
"@brief Gets the properties ID for a given properties set\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -1004,6 +1004,26 @@ static tl::Variant get_property (const db::Shape *s, const tl::Variant &key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tl::Variant get_properties (const db::Shape *s)
|
||||||
|
{
|
||||||
|
db::properties_id_type id = s->prop_id ();
|
||||||
|
if (id == 0) {
|
||||||
|
return tl::Variant::empty_array ();
|
||||||
|
}
|
||||||
|
|
||||||
|
const db::Layout *layout = layout_ptr_const (s);
|
||||||
|
if (! layout) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Shape does not reside inside a layout - cannot retrieve properties")));
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::Variant res = tl::Variant::empty_array ();
|
||||||
|
const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (id);
|
||||||
|
for (auto i = props.begin (); i != props.end (); ++i) {
|
||||||
|
res.insert (layout->properties_repository ().prop_name (i->first), i->second);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -1354,6 +1374,12 @@ Class<db::Shape> decl_Shape ("db", "Shape",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.22."
|
"This method has been introduced in version 0.22."
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("properties", &get_properties,
|
||||||
|
"@brief Gets the user properties\n"
|
||||||
|
"This method is a convenience method that gets the properties of the shape as a hash. "
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29.5."
|
||||||
|
) +
|
||||||
gsi::iterator ("each_point", &db::Shape::begin_point, &db::Shape::end_point,
|
gsi::iterator ("each_point", &db::Shape::begin_point, &db::Shape::end_point,
|
||||||
"@brief Iterates over all points of the object\n"
|
"@brief Iterates over all points of the object\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -1334,6 +1334,7 @@ class DBLayoutTests1_TestClass < TestBase
|
||||||
i0 = nil
|
i0 = nil
|
||||||
c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i }
|
c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i }
|
||||||
assert_equal(i0.property("p"), 18)
|
assert_equal(i0.property("p"), 18)
|
||||||
|
assert_equal(i0.properties, {"p" => 18})
|
||||||
assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17)
|
assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17)
|
||||||
|
|
||||||
assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)")
|
assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)")
|
||||||
|
|
@ -1379,6 +1380,7 @@ class DBLayoutTests1_TestClass < TestBase
|
||||||
|
|
||||||
tt = RBA::Trans.new
|
tt = RBA::Trans.new
|
||||||
i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
||||||
|
assert_equal(i0.properties, {})
|
||||||
i0.set_property("p", 18)
|
i0.set_property("p", 18)
|
||||||
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
||||||
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1)))
|
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1)))
|
||||||
|
|
|
||||||
|
|
@ -674,6 +674,7 @@ class DBLayoutTests2_TestClass < TestBase
|
||||||
lindex = ly.insert_layer( linfo )
|
lindex = ly.insert_layer( linfo )
|
||||||
|
|
||||||
c1 = ly.cell( ci1 )
|
c1 = ly.cell( ci1 )
|
||||||
|
assert_equal( c1.properties, {} )
|
||||||
c2 = ly.cell( ci2 )
|
c2 = ly.cell( ci2 )
|
||||||
tr = RBA::Trans::new
|
tr = RBA::Trans::new
|
||||||
inst = c2.insert( RBA::CellInstArray::new( c1.cell_index, tr ) )
|
inst = c2.insert( RBA::CellInstArray::new( c1.cell_index, tr ) )
|
||||||
|
|
@ -701,6 +702,7 @@ class DBLayoutTests2_TestClass < TestBase
|
||||||
c1.prop_id = pid
|
c1.prop_id = pid
|
||||||
assert_equal( c1.prop_id, pid )
|
assert_equal( c1.prop_id, pid )
|
||||||
assert_equal( c1.property( 17 ).inspect, "\"a\"" )
|
assert_equal( c1.property( 17 ).inspect, "\"a\"" )
|
||||||
|
assert_equal( c1.properties, { 17 => "a", "b" => [1, 5, 7] } )
|
||||||
c1.set_property( 5, 23 )
|
c1.set_property( 5, 23 )
|
||||||
c1.delete_property( 17 )
|
c1.delete_property( 17 )
|
||||||
assert_equal( c1.property( 17 ).inspect, "nil" )
|
assert_equal( c1.property( 17 ).inspect, "nil" )
|
||||||
|
|
@ -1027,6 +1029,7 @@ class DBLayoutTests2_TestClass < TestBase
|
||||||
def test_11
|
def test_11
|
||||||
|
|
||||||
ly = RBA::Layout::new
|
ly = RBA::Layout::new
|
||||||
|
assert_equal(ly.properties, {})
|
||||||
|
|
||||||
assert_equal(ly.prop_id, 0)
|
assert_equal(ly.prop_id, 0)
|
||||||
ly.prop_id = 1
|
ly.prop_id = 1
|
||||||
|
|
@ -1037,6 +1040,7 @@ class DBLayoutTests2_TestClass < TestBase
|
||||||
ly.set_property("x", 1)
|
ly.set_property("x", 1)
|
||||||
assert_equal(ly.prop_id, 1)
|
assert_equal(ly.prop_id, 1)
|
||||||
assert_equal(ly.property("x"), 1)
|
assert_equal(ly.property("x"), 1)
|
||||||
|
assert_equal(ly.properties, {"x" => 1})
|
||||||
ly.set_property("x", 17)
|
ly.set_property("x", 17)
|
||||||
assert_equal(ly.prop_id, 2)
|
assert_equal(ly.prop_id, 2)
|
||||||
assert_equal(ly.property("x"), 17)
|
assert_equal(ly.property("x"), 17)
|
||||||
|
|
|
||||||
|
|
@ -1656,6 +1656,28 @@ class DBShapes_TestClass < TestBase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Shape objects and properties
|
||||||
|
def test_13
|
||||||
|
|
||||||
|
ly = RBA::Layout::new
|
||||||
|
l1 = ly.layer(1, 0)
|
||||||
|
tc = ly.create_cell("TOP")
|
||||||
|
sh = tc.shapes(l1).insert(RBA::Box::new(0, 0, 100, 200))
|
||||||
|
|
||||||
|
assert_equal(sh.property("k").inspect, "nil")
|
||||||
|
assert_equal(sh.properties.inspect, "{}")
|
||||||
|
|
||||||
|
sh.set_property("k", 17)
|
||||||
|
|
||||||
|
assert_equal(sh.property("k").inspect, "17")
|
||||||
|
assert_equal(sh.property("u").inspect, "nil")
|
||||||
|
assert_equal(sh.properties.inspect, "{\"k\"=>17}")
|
||||||
|
|
||||||
|
sh.set_property("u", "42")
|
||||||
|
assert_equal(sh.properties.inspect, "{\"k\"=>17, \"u\"=>\"42\"}")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
load("test_epilogue.rb")
|
load("test_epilogue.rb")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue