More support for objects with properties: RDB integration.

This commit is contained in:
Matthias Koefferlein 2025-02-02 17:00:31 +01:00
parent a282a5d665
commit 1bd1bb06ce
11 changed files with 420 additions and 21 deletions

View File

@ -21,14 +21,6 @@
*/
#include "dbObjectWithProperties.h"
#include "dbUserObject.h"
#include "dbText.h"
#include "dbPolygon.h"
#include "dbBox.h"
#include "dbPath.h"
#include "dbPoint.h"
#include "dbEdge.h"
#include "dbEdgePair.h"
namespace db
{
@ -56,3 +48,88 @@ template class db::object_with_properties<db::DEdge>;
template class db::object_with_properties<db::DEdgePair>;
}
namespace tl
{
template <class T> bool _test_extractor_impl (tl::Extractor &ex, db::object_with_properties<T> &p)
{
if (! tl::test_extractor_impl (ex, (T &) p)) {
return false;
}
if (ex.test ("props")) {
if (! ex.test ("=")) {
return false;
}
tl::Variant v;
if (! tl::test_extractor_impl (ex, v)) {
return false;
}
if (! v.is_array ()) {
return false;
}
db::PropertiesSet props;
for (auto i = v.begin_array (); i != v.end_array (); ++i) {
props.insert (i->first, i->second);
}
p.properties_id (db::properties_id (props));
}
return true;
}
template <class T> void _extractor_impl (tl::Extractor &ex, db::object_with_properties<T> &p)
{
if (! test_extractor_impl (ex, p)) {
ex.error (tl::to_string (tr ("Expected a shape specification with properties")));
}
}
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Box> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::UserObject> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Polygon> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::SimplePolygon> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Path> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Text> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Point> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Edge> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::EdgePair> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DBox> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DUserObject> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPolygon> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DSimplePolygon> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPath> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DText> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPoint> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdge> &p) { return _test_extractor_impl (ex, p); }
template <> bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdgePair> &p) { return _test_extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Box> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::UserObject> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Polygon> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::SimplePolygon> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Path> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Text> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Point> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Edge> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::EdgePair> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DBox> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DUserObject> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPolygon> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DSimplePolygon> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPath> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DText> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPoint> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdge> &p) { _extractor_impl (ex, p); }
template <> void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdgePair> &p) { _extractor_impl (ex, p); }
}

View File

@ -26,7 +26,9 @@
#include "tlException.h"
#include "tlTypeTraits.h"
#include "tlString.h"
#include "dbTypes.h"
#include "dbUserObject.h"
#include "dbPolygon.h"
#include "dbPath.h"
#include "dbEdge.h"
@ -340,5 +342,55 @@ operator<< (std::ostream &os, const object_with_properties<T> &p)
} // namespace db
namespace tl
{
/**
* @brief Special extractors
*/
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Box> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::UserObject> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Polygon> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::SimplePolygon> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Path> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Text> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Point> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Edge> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::EdgePair> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DBox> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DUserObject> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPolygon> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DSimplePolygon> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPath> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DText> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPoint> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdge> &p);
template <> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdgePair> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Box> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::UserObject> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Polygon> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::SimplePolygon> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Path> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Text> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Point> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::Edge> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::EdgePair> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DBox> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DUserObject> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPolygon> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DSimplePolygon> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPath> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DText> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DPoint> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdge> &p);
template <> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::object_with_properties<db::DEdgePair> &p);
} // namespace tl
#endif

View File

@ -132,10 +132,25 @@ static T moved_xy_meth_impl (const T *s, typename T::coord_type dx, typename T::
return s->moved (typename T::vector_type (dx, dy));
}
template <class T>
struct downcast_impl_helper;
template <class T>
struct downcast_impl_helper<db::object_with_properties<T> >
{
static T impl (const db::object_with_properties<T> *obj)
{
return *obj;
}
};
template <class T>
static gsi::Methods properties_support_methods ()
{
return
gsi::method_ext ("downcast", &downcast_impl_helper<T>::impl,
"@brief Gets the corresponding object without the properties\n"
) +
gsi::method ("prop_id", (db::properties_id_type (T::*) () const) &T::properties_id,
"@brief Gets the properties ID associated with the object\n"
) +

View File

@ -0,0 +1,53 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2025 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbObjectWithProperties.h"
#include "tlUnitTest.h"
namespace {
TEST(1)
{
db::PropertiesSet ps;
ps.insert (tl::Variant (1), tl::Variant ("one"));
ps.insert (tl::Variant ("key"), tl::Variant (42.0));
db::PolygonWithProperties pwp (db::Polygon (db::Box (0, 0, 100, 200)), db::properties_id (ps));
EXPECT_EQ (pwp.to_string (), "(0,0;0,200;100,200;100,0) props={1=>one,key=>42}");
db::PolygonWithProperties pwp2;
std::string s;
tl::Extractor ex (s.c_str ());
EXPECT_EQ (ex.try_read (pwp2), false);
s = " (0,0;0,200;100,200;100,0) props= {1 => \"one\", key => 42} ";
ex = tl::Extractor (s.c_str ());
EXPECT_EQ (ex.try_read (pwp2), true);
EXPECT_EQ (pwp2.to_string (), "(0,0;0,200;100,200;100,0) props={1=>one,key=>42}");
}
}

View File

@ -11,6 +11,7 @@ SOURCES = \
dbEdgeNeighborhoodTests.cc \
dbFillToolTests.cc \
dbLogTests.cc \
dbObjectWithPropertiesTests.cc \
dbRecursiveInstanceIteratorTests.cc \
dbRegionCheckUtilsTests.cc \
dbTriangleTests.cc \

View File

@ -1211,6 +1211,21 @@ void create_items_from_edge_pair_array (rdb::Database *db, rdb::id_type cell_id,
rdb::create_items_from_sequence (db, cell_id, cat_id, trans, collection.begin (), collection.end ());
}
void create_items_from_polygon_array_with_properties (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const std::vector<db::PolygonWithProperties> &collection, bool with_properties)
{
rdb::create_items_from_sequence_with_properties (db, cell_id, cat_id, trans, collection.begin (), collection.end (), with_properties);
}
void create_items_from_edge_array_with_properties (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const std::vector<db::EdgeWithProperties> &collection, bool with_properties)
{
rdb::create_items_from_sequence_with_properties (db, cell_id, cat_id, trans, collection.begin (), collection.end (), with_properties);
}
void create_items_from_edge_pair_array_with_properties (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const std::vector<db::EdgePairWithProperties> &collection, bool with_properties)
{
rdb::create_items_from_sequence_with_properties (db, cell_id, cat_id, trans, collection.begin (), collection.end (), with_properties);
}
static rdb::Item *create_item (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id)
{
if (! db->cell_by_id (cell_id)) {
@ -1548,6 +1563,18 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
"@param trans The transformation to apply\n"
"@param edges The list of edge pairs (an \\EdgePairs object) for which the items are created\n"
) +
gsi::method_ext ("create_items", &create_items_from_polygon_array_with_properties, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"), gsi::arg ("with_properties", true),
"@brief Creates new polygon items for the given cell/category combination\n"
"This version takes \\PolygonWithProperties objects. If \\with_properties is true (the default), the\n"
"properties are added to the item as tagged values.\n"
"@param cell_id The ID of the cell to which the item is associated\n"
"@param category_id The ID of the category to which the item is associated\n"
"@param trans The transformation to apply\n"
"@param polygons The list of polygons (with properties) for which the items are created\n"
"@param with_properties If true, the properties are transferred into the item as well"
"\n"
"This variant has been introduced in version 0.30."
) +
gsi::method_ext ("create_items", &create_items_from_polygon_array, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"),
"@brief Creates new polygon items for the given cell/category combination\n"
"For each polygon a single item will be created. The value of the item will be this "
@ -1562,6 +1589,18 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
"@param trans The transformation to apply\n"
"@param polygons The list of polygons for which the items are created\n"
) +
gsi::method_ext ("create_items", &create_items_from_edge_array_with_properties, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"), gsi::arg ("with_properties", true),
"@brief Creates new edge items for the given cell/category combination\n"
"This version takes \\EdgeWithProperties objects. If \\with_properties is true (the default), the\n"
"properties are added to the item as tagged values.\n"
"@param cell_id The ID of the cell to which the item is associated\n"
"@param category_id The ID of the category to which the item is associated\n"
"@param trans The transformation to apply\n"
"@param polygons The list of edges (with properties) for which the items are created\n"
"@param with_properties If true, the properties are transferred into the item as well"
"\n"
"This variant has been introduced in version 0.30."
) +
gsi::method_ext ("create_items", &create_items_from_edge_array, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"),
"@brief Creates new edge items for the given cell/category combination\n"
"For each edge a single item will be created. The value of the item will be this "
@ -1576,6 +1615,18 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
"@param trans The transformation to apply\n"
"@param edges The list of edges for which the items are created\n"
) +
gsi::method_ext ("create_items", &create_items_from_edge_pair_array_with_properties, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"), gsi::arg ("with_properties", true),
"@brief Creates new edge pair items for the given cell/category combination\n"
"This version takes \\EdgePairWithProperties objects. If \\with_properties is true (the default), the\n"
"properties are added to the item as tagged values.\n"
"@param cell_id The ID of the cell to which the item is associated\n"
"@param category_id The ID of the category to which the item is associated\n"
"@param trans The transformation to apply\n"
"@param polygons The list of edge pairs (with properties) for which the items are created\n"
"@param with_properties If true, the properties are transferred into the item as well"
"\n"
"This variant has been introduced in version 0.30."
) +
gsi::method_ext ("create_items", &create_items_from_edge_pair_array, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("array"),
"@brief Creates new edge pair items for the given cell/category combination\n"
"For each edge pair a single item will be created. The value of the item will be this "

View File

@ -27,6 +27,7 @@
#include "rdbCommon.h"
#include "dbTrans.h"
#include "dbObjectWithProperties.h"
#include "gsi.h"
#include "tlObject.h"
#include "tlObjectCollection.h"
@ -532,6 +533,15 @@ RDB_PUBLIC_TEMPLATE ValueBase *make_value (const T &value)
return new Value<T> (value);
}
/**
* @brief Type bindings
*/
template <class T>
RDB_PUBLIC_TEMPLATE ValueBase *make_value (const db::object_with_properties<T> &value)
{
return new Value<T> (value);
}
/**
* @brief A class encapsulating ValueBase pointer
*/

View File

@ -290,6 +290,19 @@ void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_id, rdb::id_
}
}
void add_properties_to_item (rdb::Item *item, db::properties_id_type prop_id)
{
if (! item->database ()) {
return;
}
auto ps = db::properties (prop_id);
for (auto i = ps.begin (); i != ps.end (); ++i) {
id_type tag_id = item->database ()->tags ().tag (db::property_name (i->first).to_string (), true /*user tag*/).id ();
add_item_value (item, db::property_value (i->second), db::CplxTrans (), tag_id);
}
}
void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape, bool with_properties)
{
std::unique_ptr<rdb::ValueBase> value (rdb::ValueBase::create_from_shape (shape, trans));
@ -301,19 +314,8 @@ void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_ty
item->values ().add (value.release ());
// translate properties
if (with_properties && shape.has_prop_id () && shape.shapes () && shape.shapes ()->cell ()) {
const db::Layout *layout = shape.shapes ()->cell ()->layout ();
if (layout) {
auto ps = db::properties (shape.prop_id ());
for (auto i = ps.begin (); i != ps.end (); ++i) {
id_type tag_id = db->tags ().tag (db::property_name (i->first).to_string (), true /*user tag*/).id ();
add_item_value (item, db::property_value (i->second), trans, tag_id);
}
}
if (with_properties && shape.has_prop_id ()) {
add_properties_to_item (item, shape.prop_id ());
}
}

View File

@ -109,6 +109,13 @@ RDB_PUBLIC void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_i
*/
RDB_PUBLIC void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape, bool with_properties = true);
/**
* @brief Adds properties to a RDB item
*
* The properties will be added as values with "tags"
*/
RDB_PUBLIC void add_properties_to_item (rdb::Item *item, db::properties_id_type prop_id);
/**
* @brief Creates RDB items from a region
*
@ -154,6 +161,24 @@ RDB_PUBLIC_TEMPLATE void create_items_from_sequence (rdb::Database *db, rdb::id_
}
}
/**
* @brief Creates RDB items from a sequence of integer-type objects
*
* An arbitrary transformation can be applied to translate the shapes before turning them to items.
* This transformation is useful for providing the DBU-to-micron conversion.
*/
template <class Trans, class Iter>
RDB_PUBLIC_TEMPLATE void create_items_from_sequence_with_properties (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const Trans &trans, Iter begin, Iter end, bool with_properties = true)
{
for (Iter o = begin; o != end; ++o) {
rdb::Item *item = db->create_item (cell_id, cat_id);
item->values ().add (rdb::make_value (o->transformed (trans)));
if (with_properties && o->properties_id () != 0) {
add_properties_to_item (item, o->properties_id ());
}
}
}
/**
* @brief Creates a value from a tl::Variant
*

View File

@ -914,6 +914,10 @@ class DBPolygon_TestClass < TestBase
assert_equal(s.to_s, "(0,0;0,200;100,200;100,0) props={}")
assert_equal(s.property(1), nil)
# Test downcast
assert_equal(s.class.to_s, "RBA::PolygonWithProperties")
assert_equal(s.downcast.class.to_s, "RBA::Polygon")
s = RBA::DPolygonWithProperties::new
assert_equal(s.to_s, "() props={}")
@ -932,6 +936,10 @@ class DBPolygon_TestClass < TestBase
assert_equal(s.to_s, "(0,0;0,200;100,200;100,0) props={}")
assert_equal(s.property(1), nil)
# Test downcast
assert_equal(s.class.to_s, "RBA::DPolygonWithProperties")
assert_equal(s.downcast.class.to_s, "RBA::DPolygon")
s = RBA::SimplePolygonWithProperties::new
assert_equal(s.to_s, "() props={}")
@ -950,6 +958,10 @@ class DBPolygon_TestClass < TestBase
assert_equal(s.to_s, "(0,0;0,200;100,200;100,0) props={}")
assert_equal(s.property(1), nil)
# Test downcast
assert_equal(s.class.to_s, "RBA::SimplePolygonWithProperties")
assert_equal(s.downcast.class.to_s, "RBA::SimplePolygon")
s = RBA::DSimplePolygonWithProperties::new
assert_equal(s.to_s, "() props={}")
@ -968,6 +980,10 @@ class DBPolygon_TestClass < TestBase
assert_equal(s.to_s, "(0,0;0,200;100,200;100,0) props={}")
assert_equal(s.property(1), nil)
# Test downcast
assert_equal(s.class.to_s, "RBA::DSimplePolygonWithProperties")
assert_equal(s.downcast.class.to_s, "RBA::DSimplePolygon")
end
end

View File

@ -943,6 +943,103 @@ class RDB_TestClass < TestBase
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[label: ('Hello, world!',r0 0,0),edge: (0.01,0.021;0.031,0.051),polygon: (0.021,0.042;0.021,0.073;0.043,0.073;0.043,0.042)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [ RBA::Polygon::new(RBA::Box::new(0, 0, 100, 200)), RBA::Polygon::new(RBA::Box::new(100, 200, 110, 210)) ])
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[polygon: (0,0;0,0.2;0.1,0.2;0.1,0),polygon: (0.1,0.2;0.1,0.21;0.11,0.21;0.11,0.2)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [ RBA::Edge::new(0, 0, 100, 200), RBA::Edge::new(100, 200, 110, 210) ])
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge: (0,0;0.1,0.2),edge: (0.1,0.2;0.11,0.21)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [ RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 200), RBA::Edge::new(100, 200, 110, 210)) ])
assert_equal(cat1.num_items, 1)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge-pair: (0,0;0.1,0.2)/(0.1,0.2;0.11,0.21)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::PolygonWithProperties::new(RBA::Polygon::new(RBA::Box::new(0, 0, 100, 200)), { 1 => "one" }),
RBA::PolygonWithProperties::new(RBA::Polygon::new(RBA::Box::new(100, 200, 110, 210)), { 42 => 17 })
])
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[polygon: (0,0;0,0.2;0.1,0.2;0.1,0)/text: one,polygon: (0.1,0.2;0.1,0.21;0.11,0.21;0.11,0.2)/float: 17]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::PolygonWithProperties::new(RBA::Polygon::new(RBA::Box::new(0, 0, 100, 200)), { 1 => "one" }),
RBA::PolygonWithProperties::new(RBA::Polygon::new(RBA::Box::new(100, 200, 110, 210)), { 42 => 17 })
], false)
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[polygon: (0,0;0,0.2;0.1,0.2;0.1,0),polygon: (0.1,0.2;0.1,0.21;0.11,0.21;0.11,0.2)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::EdgeWithProperties::new(RBA::Edge::new(0, 0, 100, 200), { 1 => "one" }),
RBA::EdgeWithProperties::new(RBA::Edge::new(100, 200, 110, 210), { 42 => 17 })
])
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge: (0,0;0.1,0.2)/text: one,edge: (0.1,0.2;0.11,0.21)/float: 17]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::EdgeWithProperties::new(RBA::Edge::new(0, 0, 100, 200), { 1 => "one" }),
RBA::EdgeWithProperties::new(RBA::Edge::new(100, 200, 110, 210), { 42 => 17 })
], false)
assert_equal(cat1.num_items, 2)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge: (0,0;0.1,0.2),edge: (0.1,0.2;0.11,0.21)]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::EdgePairWithProperties::new(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 200), RBA::Edge::new(100, 200, 110, 210)), { 1 => "one" })
])
assert_equal(cat1.num_items, 1)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge-pair: (0,0;0.1,0.2)/(0.1,0.2;0.11,0.21)/text: one]")
rdb = RBA::ReportDatabase.new("neu")
cat1 = rdb.create_category("l1")
cell1 = rdb.create_cell("c1")
rdb.create_items(cell1.rdb_id, cat1.rdb_id, RBA::CplxTrans::new(ly.dbu), [
RBA::EdgePairWithProperties::new(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 200), RBA::Edge::new(100, 200, 110, 210)), { 1 => "one" })
], false)
assert_equal(cat1.num_items, 1)
cn = []
rdb.each_cell { |c| cn << c.to_s_items }
assert_equal(cn.join(";"), "c1[edge-pair: (0,0;0.1,0.2)/(0.1,0.2;0.11,0.21)]")
end
def test_13