mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-22 14:07:15 +02:00
Implemented feature request: a method to clear properties on shapes, instances, cells and layout
This commit is contained in:
@@ -1611,10 +1611,8 @@ Instances::replace_prop_id (const instance_type &ref, db::properties_id_type pro
|
|||||||
throw tl::Exception (tl::to_string (tr ("Trying to replace an object in a list that it does not belong to")));
|
throw tl::Exception (tl::to_string (tr ("Trying to replace an object in a list that it does not belong to")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ref.is_null ()) {
|
if (! ref.is_null () && (!ref.has_prop_id () || ref.prop_id () != prop_id)) {
|
||||||
if (ref.prop_id () != prop_id) {
|
invalidate_prop_ids ();
|
||||||
invalidate_prop_ids ();
|
|
||||||
}
|
|
||||||
cell_inst_wp_array_type new_inst (ref.cell_inst (), prop_id);
|
cell_inst_wp_array_type new_inst (ref.cell_inst (), prop_id);
|
||||||
return replace (ref, new_inst);
|
return replace (ref, new_inst);
|
||||||
} else {
|
} else {
|
||||||
@@ -1622,6 +1620,28 @@ Instances::replace_prop_id (const instance_type &ref, db::properties_id_type pro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instances::instance_type
|
||||||
|
Instances::clear_properties (const instance_type &ref)
|
||||||
|
{
|
||||||
|
if (ref.instances () != this) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Trying to replace an object in a list that it does not belong to")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! ref.is_null () && ref.has_prop_id ()) {
|
||||||
|
|
||||||
|
invalidate_prop_ids ();
|
||||||
|
|
||||||
|
cell_inst_array_type new_inst (ref.cell_inst ());
|
||||||
|
erase (ref);
|
||||||
|
return insert (new_inst);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Instances::do_clear_insts ()
|
Instances::do_clear_insts ()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1497,6 +1497,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
instance_type replace_prop_id (const instance_type &ref, db::properties_id_type prop_id);
|
instance_type replace_prop_id (const instance_type &ref, db::properties_id_type prop_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the properties
|
||||||
|
*
|
||||||
|
* @return The reference to the new instance
|
||||||
|
*/
|
||||||
|
instance_type clear_properties (const instance_type &ref);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replace the instance pointed to by the iterator with the given instance
|
* @brief Replace the instance pointed to by the iterator with the given instance
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -79,6 +79,17 @@ db::properties_id_type properties_id (const PropertiesSet &ps)
|
|||||||
return PropertiesRepository::instance ().properties_id (ps);
|
return PropertiesRepository::instance ().properties_id (ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db::properties_id_type properties_id (const std::map<tl::Variant, tl::Variant> &dict)
|
||||||
|
{
|
||||||
|
db::PropertiesSet props;
|
||||||
|
|
||||||
|
for (std::map<tl::Variant, tl::Variant>::const_iterator v = dict.begin (); v != dict.end (); ++v) {
|
||||||
|
props.insert (v->first, v->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return db::properties_id (props);
|
||||||
|
}
|
||||||
|
|
||||||
size_t hash_for_properties_id (properties_id_type id)
|
size_t hash_for_properties_id (properties_id_type id)
|
||||||
{
|
{
|
||||||
return id == 0 ? 0 : db::properties (id).hash ();
|
return id == 0 ? 0 : db::properties (id).hash ();
|
||||||
|
|||||||
@@ -310,6 +310,11 @@ DB_PUBLIC const PropertiesSet &properties (db::properties_id_type id);
|
|||||||
*/
|
*/
|
||||||
DB_PUBLIC db::properties_id_type properties_id (const PropertiesSet &ps);
|
DB_PUBLIC db::properties_id_type properties_id (const PropertiesSet &ps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the properties ID from a raw properties set
|
||||||
|
*/
|
||||||
|
DB_PUBLIC db::properties_id_type properties_id (const std::map<tl::Variant, tl::Variant> &dict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The properties repository
|
* @brief The properties repository
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1098,18 +1098,6 @@ public:
|
|||||||
m_type = UserObject;
|
m_type = UserObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Determine, if the shape is of "object_with_properties" type.
|
|
||||||
*
|
|
||||||
* Usually, the properties id (see prop_id()) should be used.
|
|
||||||
*
|
|
||||||
* @return true, if the shape is of "object_with_properties<Sh> type".
|
|
||||||
*/
|
|
||||||
bool with_props () const
|
|
||||||
{
|
|
||||||
return m_with_props;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the properties Id associated with the shape
|
* @brief Get the properties Id associated with the shape
|
||||||
*/
|
*/
|
||||||
|
|||||||
+91
-3
@@ -738,16 +738,87 @@ Shapes::find (const Shapes::shape_type &shape) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
Shapes::shape_type
|
Shapes::shape_type
|
||||||
Shapes::replace_prop_id (const Shapes::shape_type &ref, db::properties_id_type prop_id)
|
Shapes::clear_properties (const Shapes::shape_type &ref)
|
||||||
{
|
{
|
||||||
tl_assert (! ref.is_array_member ());
|
tl_assert (! ref.is_array_member ());
|
||||||
|
|
||||||
if (ref.has_prop_id ()) {
|
if (ref.has_prop_id ()) {
|
||||||
|
|
||||||
if (ref.prop_id () != prop_id) {
|
if (! is_editable ()) {
|
||||||
invalidate_prop_ids ();
|
throw tl::Exception (tl::to_string (tr ("Function 'clear_properties' is permitted only in editable mode when going to property-less shapes from some with properties")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (ref.m_type) {
|
||||||
|
case shape_type::Null:
|
||||||
|
return ref;
|
||||||
|
case shape_type::Polygon:
|
||||||
|
return clear_properties_iter (shape_type::polygon_type::tag (), ref.basic_iter (object_with_properties<shape_type::polygon_type>::tag ()));
|
||||||
|
case shape_type::PolygonRef:
|
||||||
|
return clear_properties_iter (shape_type::polygon_ref_type::tag (), ref.basic_iter (object_with_properties<shape_type::polygon_ref_type>::tag ()));
|
||||||
|
case shape_type::PolygonPtrArray:
|
||||||
|
return clear_properties_iter (shape_type::polygon_ptr_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::polygon_ptr_array_type>::tag ()));
|
||||||
|
case shape_type::SimplePolygon:
|
||||||
|
return clear_properties_iter (shape_type::simple_polygon_type::tag (), ref.basic_iter (object_with_properties<shape_type::simple_polygon_type>::tag ()));
|
||||||
|
case shape_type::SimplePolygonRef:
|
||||||
|
return clear_properties_iter (shape_type::simple_polygon_ref_type::tag (), ref.basic_iter (object_with_properties<shape_type::simple_polygon_ref_type>::tag ()));
|
||||||
|
case shape_type::SimplePolygonPtrArray:
|
||||||
|
// HINT: since we are in editing mode, this type should not appear ..
|
||||||
|
return clear_properties_iter (shape_type::simple_polygon_ptr_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::simple_polygon_ptr_array_type>::tag ()));
|
||||||
|
case shape_type::Edge:
|
||||||
|
return clear_properties_iter (shape_type::edge_type::tag (), ref.basic_iter (object_with_properties<shape_type::edge_type>::tag ()));
|
||||||
|
case shape_type::Point:
|
||||||
|
return clear_properties_iter (shape_type::point_type::tag (), ref.basic_iter (object_with_properties<shape_type::point_type>::tag ()));
|
||||||
|
case shape_type::EdgePair:
|
||||||
|
return clear_properties_iter (shape_type::edge_pair_type::tag (), ref.basic_iter (object_with_properties<shape_type::edge_pair_type>::tag ()));
|
||||||
|
case shape_type::Path:
|
||||||
|
return clear_properties_iter (shape_type::path_type::tag (), ref.basic_iter (object_with_properties<shape_type::path_type>::tag ()));
|
||||||
|
case shape_type::PathRef:
|
||||||
|
return clear_properties_iter (shape_type::path_ref_type::tag (), ref.basic_iter (object_with_properties<shape_type::path_ref_type>::tag ()));
|
||||||
|
case shape_type::PathPtrArray:
|
||||||
|
// HINT: since we are in editing mode, this type should not appear ..
|
||||||
|
return clear_properties_iter (shape_type::path_ptr_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::path_ptr_array_type>::tag ()));
|
||||||
|
case shape_type::Box:
|
||||||
|
return clear_properties_iter (shape_type::box_type::tag (), ref.basic_iter (object_with_properties<shape_type::box_type>::tag ()));
|
||||||
|
case shape_type::BoxArray:
|
||||||
|
// HINT: since we are in editing mode, this type should not appear ..
|
||||||
|
return clear_properties_iter (shape_type::box_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::box_array_type>::tag ()));
|
||||||
|
case shape_type::ShortBox:
|
||||||
|
return clear_properties_iter (shape_type::short_box_type::tag (), ref.basic_iter (object_with_properties<shape_type::short_box_type>::tag ()));
|
||||||
|
case shape_type::ShortBoxArray:
|
||||||
|
// HINT: since we are in editing mode, this type should not appear ..
|
||||||
|
return clear_properties_iter (shape_type::short_box_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::short_box_array_type>::tag ()));
|
||||||
|
case shape_type::Text:
|
||||||
|
return clear_properties_iter (shape_type::text_type::tag (), ref.basic_iter (object_with_properties<shape_type::text_type>::tag ()));
|
||||||
|
case shape_type::TextRef:
|
||||||
|
return clear_properties_iter (shape_type::text_ref_type::tag (), ref.basic_iter (object_with_properties<shape_type::text_ref_type>::tag ()));
|
||||||
|
case shape_type::TextPtrArray:
|
||||||
|
// HINT: since we are in editing mode, this type should not appear ..
|
||||||
|
return clear_properties_iter (shape_type::text_ptr_array_type::tag (), ref.basic_iter (object_with_properties<shape_type::text_ptr_array_type>::tag ()));
|
||||||
|
case shape_type::UserObject:
|
||||||
|
return clear_properties_iter (shape_type::user_object_type::tag (), ref.basic_iter (object_with_properties<shape_type::user_object_type>::tag ()));
|
||||||
|
default:
|
||||||
|
return ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shapes::shape_type
|
||||||
|
Shapes::replace_prop_id (const Shapes::shape_type &ref, db::properties_id_type prop_id)
|
||||||
|
{
|
||||||
|
tl_assert (! ref.is_array_member ());
|
||||||
|
|
||||||
|
// nothing to do?
|
||||||
|
if (ref.has_prop_id () && ref.prop_id () == prop_id) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref.has_prop_id ()) {
|
||||||
|
|
||||||
|
invalidate_prop_ids ();
|
||||||
|
|
||||||
// this assumes we can simply patch the properties ID ..
|
// this assumes we can simply patch the properties ID ..
|
||||||
switch (ref.m_type) {
|
switch (ref.m_type) {
|
||||||
case shape_type::Null:
|
case shape_type::Null:
|
||||||
@@ -1311,6 +1382,23 @@ Shapes::replace_prop_id_iter (typename db::object_tag<Sh>, const Iter &iter, db:
|
|||||||
return shape_type (this, get_layer <db::object_with_properties <Sh>, db::stable_layer_tag> ().insert (wp));
|
return shape_type (this, get_layer <db::object_with_properties <Sh>, db::stable_layer_tag> ().insert (wp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Sh, class Iter>
|
||||||
|
Shapes::shape_type
|
||||||
|
Shapes::clear_properties_iter (typename db::object_tag<Sh>, const Iter &iter)
|
||||||
|
{
|
||||||
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
db::layer_op<db::object_with_properties <Sh>, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *iter);
|
||||||
|
}
|
||||||
|
Sh wop (*iter);
|
||||||
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
get_layer<db::object_with_properties <Sh>, db::stable_layer_tag> ().erase (iter);
|
||||||
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, wop);
|
||||||
|
}
|
||||||
|
return shape_type (this, get_layer <Sh, db::stable_layer_tag> ().insert (wop));
|
||||||
|
}
|
||||||
|
|
||||||
template <class Sh1, class Sh2>
|
template <class Sh1, class Sh2>
|
||||||
Shapes::shape_type
|
Shapes::shape_type
|
||||||
Shapes::reinsert_member_with_props (typename db::object_tag<Sh1>, const shape_type &ref, const Sh2 &sh)
|
Shapes::reinsert_member_with_props (typename db::object_tag<Sh1>, const shape_type &ref, const Sh2 &sh)
|
||||||
|
|||||||
+14
-1
@@ -1149,12 +1149,22 @@ public:
|
|||||||
* of type object_with_properties<X>.
|
* of type object_with_properties<X>.
|
||||||
* This method is only allowed in editable mode.
|
* This method is only allowed in editable mode.
|
||||||
*
|
*
|
||||||
* @param ref The shape reference which to replace the properties ID with
|
* @param ref The shape reference for which to replace the properties ID with
|
||||||
* @param prop_id The properties Id to replace.
|
* @param prop_id The properties Id to replace.
|
||||||
* @return The reference to the new object
|
* @return The reference to the new object
|
||||||
*/
|
*/
|
||||||
shape_type replace_prop_id (const shape_type &ref, db::properties_id_type prop_id);
|
shape_type replace_prop_id (const shape_type &ref, db::properties_id_type prop_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the user properties
|
||||||
|
*
|
||||||
|
* This method is only allowed in editable mode.
|
||||||
|
*
|
||||||
|
* @param ref The shape reference for which to clear the properties
|
||||||
|
* @return The reference to the new object
|
||||||
|
*/
|
||||||
|
shape_type clear_properties (const shape_type &ref);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replace an element by a given shape
|
* @brief Replace an element by a given shape
|
||||||
*
|
*
|
||||||
@@ -1638,6 +1648,9 @@ private:
|
|||||||
template <class Sh, class Iter>
|
template <class Sh, class Iter>
|
||||||
shape_type replace_prop_id_iter (typename db::object_tag<Sh>, const Iter &iter, db::properties_id_type prop_id);
|
shape_type replace_prop_id_iter (typename db::object_tag<Sh>, const Iter &iter, db::properties_id_type prop_id);
|
||||||
|
|
||||||
|
template <class Sh, class Iter>
|
||||||
|
shape_type clear_properties_iter (typename db::object_tag<Sh>, const Iter &iter);
|
||||||
|
|
||||||
// A helper function to replace a shape given by a generic reference by doing an erase & insert
|
// A helper function to replace a shape given by a generic reference by doing an erase & insert
|
||||||
// Sh2 must not be a shape with properties
|
// Sh2 must not be a shape with properties
|
||||||
template <class Sh1, class Sh2>
|
template <class Sh1, class Sh2>
|
||||||
|
|||||||
@@ -1076,6 +1076,16 @@ static void set_cell_property (db::Cell *c, const tl::Variant &key, const tl::Va
|
|||||||
c->prop_id (db::properties_id (props));
|
c->prop_id (db::properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_cell_properties (db::Cell *c, const std::map<tl::Variant, tl::Variant> &dict)
|
||||||
|
{
|
||||||
|
c->prop_id (db::properties_id (dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_cell_properties (db::Cell *c)
|
||||||
|
{
|
||||||
|
c->prop_id (0);
|
||||||
|
}
|
||||||
|
|
||||||
static tl::Variant get_cell_property (const 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 ();
|
||||||
@@ -1831,6 +1841,22 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.23."
|
"This method has been introduced in version 0.23."
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("set_properties", &set_cell_properties, gsi::arg ("dict"),
|
||||||
|
"@brief Sets all user properties from the given dict\n"
|
||||||
|
"This method is a convenience method that replaces all user properties of the cell. Using that method is more "
|
||||||
|
"convenient than creating a new property set with a new ID and assigning that properties ID.\n"
|
||||||
|
"This method may change the properties ID. "
|
||||||
|
"Note: GDS only supports integer keys. OASIS supports numeric and string keys. "
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("clear_properties", &clear_cell_properties,
|
||||||
|
"@brief Clears all user properties\n"
|
||||||
|
"This method will remove all user properties. After it has been called, \\has_prop_id? will return false.\n"
|
||||||
|
"It is equivalent to setting the properties ID to zero.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
gsi::method_ext ("property", &get_cell_property, gsi::arg ("key"),
|
gsi::method_ext ("property", &get_cell_property, gsi::arg ("key"),
|
||||||
"@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. "
|
||||||
@@ -3539,6 +3565,18 @@ static void set_property (db::Instance *i, const tl::Variant &key, const tl::Var
|
|||||||
set_prop_id (i, db::properties_id (props));
|
set_prop_id (i, db::properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_properties (db::Instance *inst, const std::map<tl::Variant, tl::Variant> &dict)
|
||||||
|
{
|
||||||
|
set_prop_id (inst, db::properties_id (dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_properties (db::Instance *inst)
|
||||||
|
{
|
||||||
|
tl_assert (inst->instances () != 0);
|
||||||
|
check_is_editable (inst->instances ());
|
||||||
|
*inst = inst->instances ()->clear_properties (*inst);
|
||||||
|
}
|
||||||
|
|
||||||
static tl::Variant get_property (const db::Instance *i, const tl::Variant &key)
|
static tl::Variant get_property (const db::Instance *i, const tl::Variant &key)
|
||||||
{
|
{
|
||||||
db::properties_id_type id = i->prop_id ();
|
db::properties_id_type id = i->prop_id ();
|
||||||
@@ -4019,6 +4057,25 @@ 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 ("set_properties", &set_properties, gsi::arg ("dict"),
|
||||||
|
"@brief Sets all user properties from the given dict\n"
|
||||||
|
"This method is a convenience method that replaces all user properties of the instance. Using that method is more "
|
||||||
|
"convenient than creating a new property set with a new ID and assigning that properties ID.\n"
|
||||||
|
"This method may change the properties ID. "
|
||||||
|
"Note: GDS only supports integer keys. OASIS supports numeric and string keys. "
|
||||||
|
"Calling this method may invalidate any iterators. It should not be called inside a "
|
||||||
|
"loop iterating over instances.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("clear_properties", &clear_properties,
|
||||||
|
"@brief Clears all user properties\n"
|
||||||
|
"This method will remove all user properties. After it has been called, \\has_prop_id? will return false.\n"
|
||||||
|
"Calling this method may invalidate any iterators. It should not be called inside a "
|
||||||
|
"loop iterating over instances.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
gsi::method_ext ("property", &get_property, gsi::arg ("key"),
|
gsi::method_ext ("property", &get_property, gsi::arg ("key"),
|
||||||
"@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. "
|
||||||
|
|||||||
@@ -323,6 +323,16 @@ static void set_layout_property (db::Layout *l, const tl::Variant &key, const tl
|
|||||||
l->prop_id (db::properties_id (props));
|
l->prop_id (db::properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_layout_properties (db::Layout *l, const std::map<tl::Variant, tl::Variant> &dict)
|
||||||
|
{
|
||||||
|
l->prop_id (db::properties_id (dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_layout_properties (db::Layout *l)
|
||||||
|
{
|
||||||
|
l->prop_id (0);
|
||||||
|
}
|
||||||
|
|
||||||
static tl::Variant get_layout_property (const db::Layout *l, const tl::Variant &key)
|
static tl::Variant get_layout_property (const db::Layout *l, const tl::Variant &key)
|
||||||
{
|
{
|
||||||
db::properties_id_type id = l->prop_id ();
|
db::properties_id_type id = l->prop_id ();
|
||||||
@@ -579,21 +589,15 @@ static db::properties_id_type properties_id_from_list_meth (const db::Layout *,
|
|||||||
return properties_id_from_list (properties);
|
return properties_id_from_list (properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static db::properties_id_type properties_id_from_hash (const std::map<tl::Variant, tl::Variant> &properties)
|
static db::properties_id_type properties_id_from_dict (const std::map<tl::Variant, tl::Variant> &properties)
|
||||||
{
|
{
|
||||||
db::PropertiesSet props;
|
return db::properties_id (properties);
|
||||||
|
|
||||||
for (std::map<tl::Variant, tl::Variant>::const_iterator v = properties.begin (); v != properties.end (); ++v) {
|
|
||||||
props.insert (v->first, v->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
return db::properties_id (props);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for backward compatibility
|
// for backward compatibility
|
||||||
static db::properties_id_type properties_id_from_hash_meth (const db::Layout *, const std::map<tl::Variant, tl::Variant> &properties)
|
static db::properties_id_type properties_id_from_dict_meth (const db::Layout *, const std::map<tl::Variant, tl::Variant> &properties)
|
||||||
{
|
{
|
||||||
return properties_id_from_hash (properties);
|
return properties_id_from_dict (properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::Variant get_properties_list (db::properties_id_type id)
|
static tl::Variant get_properties_list (db::properties_id_type id)
|
||||||
@@ -607,13 +611,13 @@ static tl::Variant get_properties_list_meth (const db::Layout *, db::properties_
|
|||||||
return db::properties (id).to_list_var ();
|
return db::properties (id).to_list_var ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::Variant get_properties_hash (db::properties_id_type id)
|
static tl::Variant get_properties_dict (db::properties_id_type id)
|
||||||
{
|
{
|
||||||
return db::properties (id).to_dict_var ();
|
return db::properties (id).to_dict_var ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// for backward compatibility
|
// for backward compatibility
|
||||||
static tl::Variant get_properties_hash_meth (const db::Layout *, db::properties_id_type id)
|
static tl::Variant get_properties_dict_meth (const db::Layout *, db::properties_id_type id)
|
||||||
{
|
{
|
||||||
return db::properties (id).to_dict_var ();
|
return db::properties (id).to_dict_var ();
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1324,22 @@ 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 ("set_properties", &set_layout_properties, gsi::arg ("dict"),
|
||||||
|
"@brief Sets all user properties from the given dict\n"
|
||||||
|
"This method is a convenience method that replaces all user properties of the layout object. Using that method is more "
|
||||||
|
"convenient than creating a new property set with a new ID and assigning that properties ID.\n"
|
||||||
|
"This method may change the properties ID. "
|
||||||
|
"Note: GDS only supports integer keys. OASIS supports numeric and string keys. "
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("clear_properties", &clear_layout_properties,
|
||||||
|
"@brief Clears all user properties\n"
|
||||||
|
"This method will remove all user properties. After it has been called, \\has_prop_id? will return false.\n"
|
||||||
|
"It is equivalent to setting the properties ID to zero.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
gsi::method_ext ("property", &get_layout_property, gsi::arg ("key"),
|
gsi::method_ext ("property", &get_layout_property, gsi::arg ("key"),
|
||||||
"@brief Gets the Layout's user property with the given key\n"
|
"@brief Gets the Layout's 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. "
|
||||||
@@ -1364,10 +1384,10 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||||||
"@return The unique properties ID for that set"
|
"@return The unique properties ID for that set"
|
||||||
) +
|
) +
|
||||||
// backward-compatible version as method
|
// backward-compatible version as method
|
||||||
gsi::method_ext ("properties_id", &properties_id_from_hash_meth, gsi::arg ("properties"),
|
gsi::method_ext ("properties_id", &properties_id_from_dict_meth, gsi::arg ("properties"),
|
||||||
"@hide"
|
"@hide"
|
||||||
) +
|
) +
|
||||||
gsi::method ("properties_id", &properties_id_from_hash, gsi::arg ("properties"),
|
gsi::method ("properties_id", &properties_id_from_dict, 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"
|
||||||
"This variant accepts a hash of value vs. key for the properties instead of array of key/value pairs. "
|
"This variant accepts a hash of value vs. key for the properties instead of array of key/value pairs. "
|
||||||
@@ -1413,10 +1433,10 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||||||
"In version 0.30, this method was turned into a static (class method), providing universal conversions without need for a Layout object."
|
"In version 0.30, this method was turned into a static (class method), providing universal conversions without need for a Layout object."
|
||||||
) +
|
) +
|
||||||
// backward-compatible version as method
|
// backward-compatible version as method
|
||||||
gsi::method_ext ("properties_hash", &get_properties_hash_meth, gsi::arg ("properties_id"),
|
gsi::method_ext ("properties_hash", &get_properties_dict_meth, gsi::arg ("properties_id"),
|
||||||
"@hide"
|
"@hide"
|
||||||
) +
|
) +
|
||||||
gsi::method ("properties_hash", &get_properties_hash, gsi::arg ("properties_id"),
|
gsi::method ("properties_hash", &get_properties_dict, gsi::arg ("properties_id"),
|
||||||
"@brief Gets the properties set for a given properties ID as a hash\n"
|
"@brief Gets the properties set for a given properties ID as a hash\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Returns the properties for a given properties ID as a hash.\n"
|
"Returns the properties for a given properties ID as a hash.\n"
|
||||||
|
|||||||
@@ -954,6 +954,17 @@ static void set_property (db::Shape *s, const tl::Variant &key, const tl::Varian
|
|||||||
set_prop_id (s, db::properties_id (props));
|
set_prop_id (s, db::properties_id (props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_properties (db::Shape *shape, const std::map<tl::Variant, tl::Variant> &dict)
|
||||||
|
{
|
||||||
|
set_prop_id (shape, db::properties_id (dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_properties (db::Shape *shape)
|
||||||
|
{
|
||||||
|
db::Shapes *shapes = shapes_checked (shape);
|
||||||
|
*shape = shapes->clear_properties (*shape);
|
||||||
|
}
|
||||||
|
|
||||||
static tl::Variant get_property (const db::Shape *s, const tl::Variant &key)
|
static tl::Variant get_property (const db::Shape *s, const tl::Variant &key)
|
||||||
{
|
{
|
||||||
db::properties_id_type id = s->prop_id ();
|
db::properties_id_type id = s->prop_id ();
|
||||||
@@ -1312,6 +1323,25 @@ 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 ("set_properties", &set_properties, gsi::arg ("dict"),
|
||||||
|
"@brief Sets all user properties from the given dict\n"
|
||||||
|
"This method is a convenience method that replaces all user properties of the shape. Using that method is more "
|
||||||
|
"convenient than creating a new property set with a new ID and assigning that properties ID.\n"
|
||||||
|
"This method may change the properties ID. "
|
||||||
|
"Note: GDS only supports integer keys. OASIS supports numeric and string keys. "
|
||||||
|
"Calling this method may invalidate any iterators. It should not be called inside a "
|
||||||
|
"loop iterating over instances.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("clear_properties", &clear_properties,
|
||||||
|
"@brief Clears all user properties\n"
|
||||||
|
"This method will remove all user properties. After it has been called, \\has_prop_id? will return false.\n"
|
||||||
|
"Calling this method may invalidate any iterators. It should not be called inside a "
|
||||||
|
"loop iterating over instances.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.30.3."
|
||||||
|
) +
|
||||||
gsi::method_ext ("property", &get_property, gsi::arg ("key"),
|
gsi::method_ext ("property", &get_property, gsi::arg ("key"),
|
||||||
"@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. "
|
||||||
|
|||||||
@@ -2421,7 +2421,7 @@ TEST(12A)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
@@ -2494,7 +2494,7 @@ TEST(12C)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
@@ -2578,7 +2578,7 @@ TEST(12E)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
@@ -2677,7 +2677,7 @@ TEST(12G)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
@@ -2774,7 +2774,7 @@ TEST(12I)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
@@ -2834,7 +2834,7 @@ TEST(12J)
|
|||||||
|
|
||||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
if (shape->with_props ()) {
|
if (shape->has_prop_id ()) {
|
||||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||||
}
|
}
|
||||||
++shape;
|
++shape;
|
||||||
|
|||||||
Vendored
+35
@@ -905,6 +905,41 @@ class DBInstance_TestClass < TestBase
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# User properties
|
||||||
|
def test_8_UserProperties
|
||||||
|
|
||||||
|
ly = RBA::Layout::new
|
||||||
|
|
||||||
|
ci1 = ly.add_cell("c1")
|
||||||
|
ci2 = ly.add_cell("c2")
|
||||||
|
|
||||||
|
c1 = ly.cell(ci1)
|
||||||
|
c2 = ly.cell(ci2)
|
||||||
|
|
||||||
|
inst = RBA::CellInstArray::new(c1.cell_index, RBA::Trans::new)
|
||||||
|
i = c2.insert(inst)
|
||||||
|
|
||||||
|
assert_equal(i.property("k").inspect, "nil")
|
||||||
|
assert_equal(i.properties.inspect, "{}")
|
||||||
|
|
||||||
|
i.set_property("k", 17)
|
||||||
|
|
||||||
|
assert_equal(i.property("k").inspect, "17")
|
||||||
|
assert_equal(i.property("u").inspect, "nil")
|
||||||
|
assert_equal(i.properties.inspect, "{\"k\"=>17}")
|
||||||
|
|
||||||
|
i.set_property("u", "42")
|
||||||
|
assert_equal(i.properties.inspect, "{\"k\"=>17, \"u\"=>\"42\"}")
|
||||||
|
|
||||||
|
i.set_properties({ "a" => 17, 42 => "u" })
|
||||||
|
assert_equal(i.properties, {42=>"u", "a"=>17})
|
||||||
|
assert_equal(i.has_prop_id?, true)
|
||||||
|
i.clear_properties
|
||||||
|
assert_equal(i.properties, {})
|
||||||
|
assert_equal(i.has_prop_id?, false)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
load("test_epilogue.rb")
|
load("test_epilogue.rb")
|
||||||
|
|||||||
Vendored
+13
@@ -715,6 +715,12 @@ class DBLayoutTests2_TestClass < TestBase
|
|||||||
c1.delete_property( 17 )
|
c1.delete_property( 17 )
|
||||||
assert_equal( c1.property( 17 ).inspect, "nil" )
|
assert_equal( c1.property( 17 ).inspect, "nil" )
|
||||||
assert_equal( c1.property( 5 ).inspect, "23" )
|
assert_equal( c1.property( 5 ).inspect, "23" )
|
||||||
|
c1.set_properties({ "a" => 17, 42 => "u" })
|
||||||
|
assert_equal(c1.properties, {42=>"u", "a"=>17})
|
||||||
|
assert_equal(c1.has_prop_id?, true)
|
||||||
|
c1.clear_properties
|
||||||
|
assert_equal(c1.properties, {})
|
||||||
|
assert_equal(c1.has_prop_id?, false)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1057,6 +1063,13 @@ class DBLayoutTests2_TestClass < TestBase
|
|||||||
ly.delete_property("x")
|
ly.delete_property("x")
|
||||||
assert_equal(ly.property("x"), nil)
|
assert_equal(ly.property("x"), nil)
|
||||||
|
|
||||||
|
ly.set_properties({ "a" => 17, 42 => "u" })
|
||||||
|
assert_equal(ly.properties, {42=>"u", "a"=>17})
|
||||||
|
assert_equal(ly.has_prop_id?, true)
|
||||||
|
ly.clear_properties
|
||||||
|
assert_equal(ly.properties, {})
|
||||||
|
assert_equal(ly.has_prop_id?, false)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Meta information
|
# Meta information
|
||||||
|
|||||||
Vendored
+7
@@ -1683,6 +1683,13 @@ class DBShapes_TestClass < TestBase
|
|||||||
sh.set_property("u", "42")
|
sh.set_property("u", "42")
|
||||||
assert_equal(sh.properties.inspect, "{\"k\"=>17, \"u\"=>\"42\"}")
|
assert_equal(sh.properties.inspect, "{\"k\"=>17, \"u\"=>\"42\"}")
|
||||||
|
|
||||||
|
sh.set_properties({ "a" => 17, 42 => "u" })
|
||||||
|
assert_equal(sh.properties, {42=>"u", "a"=>17})
|
||||||
|
assert_equal(sh.has_prop_id?, true)
|
||||||
|
sh.clear_properties
|
||||||
|
assert_equal(sh.properties, {})
|
||||||
|
assert_equal(sh.has_prop_id?, false)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shape objects with properties
|
# Shape objects with properties
|
||||||
|
|||||||
Reference in New Issue
Block a user