mirror of https://github.com/KLayout/klayout.git
Implemented feature request: a method to clear properties on shapes, instances, cells and layout
This commit is contained in:
parent
d6193c2862
commit
2369c69f69
|
|
@ -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")));
|
||||
}
|
||||
|
||||
if (! ref.is_null ()) {
|
||||
if (ref.prop_id () != prop_id) {
|
||||
invalidate_prop_ids ();
|
||||
}
|
||||
if (! ref.is_null () && (!ref.has_prop_id () || ref.prop_id () != prop_id)) {
|
||||
invalidate_prop_ids ();
|
||||
cell_inst_wp_array_type new_inst (ref.cell_inst (), prop_id);
|
||||
return replace (ref, new_inst);
|
||||
} else {
|
||||
|
|
@ -1622,7 +1620,29 @@ Instances::replace_prop_id (const instance_type &ref, db::properties_id_type pro
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
Instances::do_clear_insts ()
|
||||
{
|
||||
if (m_generic.any) {
|
||||
|
|
|
|||
|
|
@ -1497,6 +1497,13 @@ public:
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -79,6 +79,17 @@ db::properties_id_type properties_id (const PropertiesSet &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)
|
||||
{
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1098,18 +1098,6 @@ public:
|
|||
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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -738,16 +738,87 @@ Shapes::find (const Shapes::shape_type &shape) const
|
|||
}
|
||||
|
||||
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 ());
|
||||
|
||||
if (ref.has_prop_id ()) {
|
||||
|
||||
if (ref.prop_id () != prop_id) {
|
||||
invalidate_prop_ids ();
|
||||
if (! is_editable ()) {
|
||||
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 ..
|
||||
switch (ref.m_type) {
|
||||
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));
|
||||
}
|
||||
|
||||
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>
|
||||
Shapes::shape_type
|
||||
Shapes::reinsert_member_with_props (typename db::object_tag<Sh1>, const shape_type &ref, const Sh2 &sh)
|
||||
|
|
|
|||
|
|
@ -1149,12 +1149,22 @@ public:
|
|||
* of type object_with_properties<X>.
|
||||
* 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.
|
||||
* @return The reference to the new object
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
|
@ -1638,6 +1648,9 @@ private:
|
|||
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);
|
||||
|
||||
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
|
||||
// Sh2 must not be a shape with properties
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
db::properties_id_type id = c->prop_id ();
|
||||
|
|
@ -1831,6 +1841,22 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"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"),
|
||||
"@brief Gets the user property with the given key\n"
|
||||
"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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
db::properties_id_type id = i->prop_id ();
|
||||
|
|
@ -4019,6 +4057,25 @@ Class<db::Instance> decl_Instance ("db", "Instance",
|
|||
"\n"
|
||||
"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"),
|
||||
"@brief Gets the user property with the given key\n"
|
||||
"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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
return db::properties_id (properties);
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
@ -607,13 +611,13 @@ static tl::Variant get_properties_list_meth (const db::Layout *, db::properties_
|
|||
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 ();
|
||||
}
|
||||
|
||||
// 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 ();
|
||||
}
|
||||
|
|
@ -1320,6 +1324,22 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"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"),
|
||||
"@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. "
|
||||
|
|
@ -1364,10 +1384,10 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"@return The unique properties ID for that set"
|
||||
) +
|
||||
// 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"
|
||||
) +
|
||||
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"
|
||||
"\n"
|
||||
"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."
|
||||
) +
|
||||
// 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"
|
||||
) +
|
||||
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"
|
||||
"\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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
db::properties_id_type id = s->prop_id ();
|
||||
|
|
@ -1312,6 +1323,25 @@ Class<db::Shape> decl_Shape ("db", "Shape",
|
|||
"\n"
|
||||
"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"),
|
||||
"@brief Gets the user property with the given key\n"
|
||||
"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);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
@ -2494,7 +2494,7 @@ TEST(12C)
|
|||
|
||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
@ -2578,7 +2578,7 @@ TEST(12E)
|
|||
|
||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
@ -2677,7 +2677,7 @@ TEST(12G)
|
|||
|
||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
@ -2774,7 +2774,7 @@ TEST(12I)
|
|||
|
||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
@ -2834,7 +2834,7 @@ TEST(12J)
|
|||
|
||||
shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All);
|
||||
while (! shape.at_end ()) {
|
||||
if (shape->with_props ()) {
|
||||
if (shape->has_prop_id ()) {
|
||||
topcell.shapes (lindex).replace_prop_id (*shape, shape->prop_id () + 100);
|
||||
}
|
||||
++shape;
|
||||
|
|
|
|||
|
|
@ -905,6 +905,41 @@ class DBInstance_TestClass < TestBase
|
|||
|
||||
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
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
|
|
@ -715,6 +715,12 @@ class DBLayoutTests2_TestClass < TestBase
|
|||
c1.delete_property( 17 )
|
||||
assert_equal( c1.property( 17 ).inspect, "nil" )
|
||||
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
|
||||
|
||||
|
|
@ -1057,6 +1063,13 @@ class DBLayoutTests2_TestClass < TestBase
|
|||
ly.delete_property("x")
|
||||
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
|
||||
|
||||
# Meta information
|
||||
|
|
|
|||
|
|
@ -1683,6 +1683,13 @@ class DBShapes_TestClass < TestBase
|
|||
sh.set_property("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
|
||||
|
||||
# Shape objects with properties
|
||||
|
|
|
|||
Loading…
Reference in New Issue