From 826b81124997130ab436a0d7e60f1fb0ebfcefac Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 4 Jan 2025 19:24:32 +0100 Subject: [PATCH] More generic object-with-properties GSI methods --- src/db/db/dbObjectWithProperties.h | 22 +++-- src/db/db/gsiDeclDbPropertiesSupport.h | 132 +++++++++++++++++++++++++ testdata/ruby/dbEdgeTest.rb | 30 ++++++ 3 files changed, 177 insertions(+), 7 deletions(-) diff --git a/src/db/db/dbObjectWithProperties.h b/src/db/db/dbObjectWithProperties.h index e64b40301..3534930d6 100644 --- a/src/db/db/dbObjectWithProperties.h +++ b/src/db/db/dbObjectWithProperties.h @@ -200,6 +200,14 @@ public: m_id = id; } + /** + * @brief Returns the scaled object + */ + auto scaled (double f) const + { + return make_object_with_properties (Obj::scaled (f), m_id); + } + /** * @brief Returns the transformed object */ @@ -297,19 +305,19 @@ typedef object_with_properties > DCellInstAr */ template -struct result_of_transformation; +struct result_of_method; -template -struct result_of_transformation +template +struct result_of_method { typedef R type; }; template -inline db::object_with_properties)>::type> +inline db::object_with_properties)>::type> operator* (const Tr &t, const db::object_with_properties &obj) { - return db::object_with_properties)>::type> (obj.Obj::transformed (t), obj.properties_id ()); + return db::object_with_properties)>::type> (obj.Obj::transformed (t), obj.properties_id ()); } /** @@ -321,10 +329,10 @@ operator* (const Tr &t, const db::object_with_properties &obj) * @return The scaled object */ template -inline db::object_with_properties +inline db::object_with_properties::type> operator* (const db::object_with_properties &obj, double s) { - return db::object_with_properties (((const Obj &) obj) * s, obj.properties_id ()); + return db::object_with_properties::type> (obj * s, obj.properties_id ()); } /** diff --git a/src/db/db/gsiDeclDbPropertiesSupport.h b/src/db/db/gsiDeclDbPropertiesSupport.h index 14e88b6c5..76f404c18 100644 --- a/src/db/db/gsiDeclDbPropertiesSupport.h +++ b/src/db/db/gsiDeclDbPropertiesSupport.h @@ -25,6 +25,9 @@ #include "gsiDecl.h" #include "dbPropertiesRepository.h" +#include "dbObjectWithProperties.h" +#include "dbTrans.h" +#include "dbEdge.h" namespace gsi { @@ -71,6 +74,63 @@ static tl::Variant get_properties_meth_impl (const T *s) return props.to_dict_var (); } +template +static typename db::result_of_method::type +scaled_meth_impl (const T *s, double scale) +{ + typename db::result_of_method::type res (s->scaled (scale), s->properties_id ()); + return res; +} + +template +static T +transformed_meth_impl0 (const T *s, const db::simple_trans &tr) +{ + return s->transformed (tr); +} + +template +static typename db::result_of_method >)>::type +transformed_meth_impl1 (const T *s, const db::complex_trans &tr) +{ + typename db::result_of_method >)>::type res (s->transformed (tr), s->properties_id ()); + return res; +} + +template +static typename db::result_of_method >)>::type +transformed_meth_impl2 (const T *s, const db::complex_trans &tr) +{ + typename db::result_of_method >)>::type res (s->transformed (tr), s->properties_id ()); + return res; +} + +template +static void +transform_meth_impl0 (T *s, const db::simple_trans &tr) +{ + s->transform (tr); +} + +template +static void +transform_meth_impl1 (T *s, const db::complex_trans &tr) +{ + s->transform (tr); +} + +template +static T &move_xy_meth_impl (T *s, typename T::coord_type dx, typename T::coord_type dy) +{ + return s->move (typename T::vector_type (dx, dy)); +} + +template +static T moved_xy_meth_impl (const T *s, typename T::coord_type dx, typename T::coord_type dy) +{ + return s->moved (typename T::vector_type (dx, dy)); +} + template static gsi::Methods properties_support_methods () { @@ -81,6 +141,78 @@ static gsi::Methods properties_support_methods () gsi::method ("prop_id=", (void (T::*) (db::properties_id_type)) &T::properties_id, gsi::arg ("id"), "@brief Sets the properties ID of the object\n" ) + + gsi::method_ext ("*", &scaled_meth_impl, gsi::arg ("f"), + "@brief Scales the object by some factor\n" + "\n" + "Returns the scaled object. All coordinates are multiplied with the given factor and, if " + "necessary, rounded." + ) + + gsi::method_ext ("transform", &transform_meth_impl0, gsi::arg ("t"), + "@brief Transforms the object (in-place version)\n" + ) + + gsi::method_ext ("transform", &transform_meth_impl1, gsi::arg ("t"), + "@brief Transforms the object (in-place version)\n" + ) + + gsi::method_ext ("transformed", &transformed_meth_impl0, gsi::arg ("t"), + "@brief Returns the transformed object\n" + "\n" + "Returns a copy of the object, transformed by the given transformation. " + "The result is equivalent to 'tr * self'." + ) + + gsi::method_ext ("transformed", &transformed_meth_impl1, gsi::arg ("t"), + "@brief Returns the transformed object\n" + "\n" + "Returns a copy of the object, transformed by the given transformation. " + "The result is equivalent to 'tr * self'." + ) + + gsi::method_ext ("transformed", &transformed_meth_impl2, gsi::arg ("t"), + "@brief Returns the transformed object\n" + "\n" + "Returns a copy of the object, transformed by the given transformation. " + "The result is equivalent to 'tr * self'." + ) + + gsi::method ("move", &T::move, gsi::arg ("v"), + "@brief Moves the object.\n" + "\n" + "Moves the object by the given offset and returns the \n" + "moved object. The object is overwritten.\n" + "\n" + "@param v The distance to move the object.\n" + "\n" + "@return The moved object (self).\n" + ) + + gsi::method_ext ("move", &move_xy_meth_impl, gsi::arg ("dx", 0), gsi::arg ("dy", 0), + "@brief Moves the object.\n" + "\n" + "Moves the object by the given offset and returns the \n" + "moved object. The object is overwritten.\n" + "\n" + "@param dx The x distance to move the object.\n" + "@param dy The y distance to move the object.\n" + "\n" + "@return The moved object (self).\n" + ) + + gsi::method ("moved", &T::moved, gsi::arg ("v"), + "@brief Returns the moved object\n" + "\n" + "Moves the object by the given offset and returns the \n" + "moved object. The object is not modified.\n" + "\n" + "@param v The distance to move the object.\n" + "\n" + "@return The moved object.\n" + ) + + gsi::method_ext ("moved", &moved_xy_meth_impl, gsi::arg ("dx", 0), gsi::arg ("dy", 0), + "@brief Returns the moved object (does not modify self)\n" + "\n" + "Moves the object by the given offset and returns the \n" + "moved object. The object is not modified.\n" + "\n" + "@param dx The x distance to move the object.\n" + "@param dy The y distance to move the object.\n" + "\n" + "@return The moved object.\n" + ) + gsi::method_ext ("delete_property", &delete_property_meth_impl, gsi::arg ("key"), "@brief Deletes the user property with the given key\n" "This method is a convenience method that deletes the property with the given key. " diff --git a/testdata/ruby/dbEdgeTest.rb b/testdata/ruby/dbEdgeTest.rb index e69dd09f9..348f7476d 100644 --- a/testdata/ruby/dbEdgeTest.rb +++ b/testdata/ruby/dbEdgeTest.rb @@ -342,6 +342,21 @@ class DBEdge_TestClass < TestBase s = RBA::EdgeWithProperties::new(RBA::Edge::new(0, 0, 100, 200), pid) assert_equal(s.to_s, "(0,0;100,200) props={1=>one}") assert_equal((RBA::CplxTrans::new(0.001) * s).to_s, "(0,0;0.1,0.2) props={1=>one}") + assert_equal(s.transformed(RBA::CplxTrans::new(0.001)).to_s, "(0,0;0.1,0.2) props={1=>one}") + assert_equal(s.transformed(RBA::ICplxTrans::new(2.5)).to_s, "(0,0;250,500) props={1=>one}") + assert_equal(s.transformed(RBA::Trans::R90).to_s, "(0,0;-200,100) props={1=>one}") + s2 = s.dup + s2.transform(RBA::Trans::R90) + assert_equal(s2.to_s, "(0,0;-200,100) props={1=>one}") + assert_equal((s * 0.001).to_s, "(0,0;0.1,0.2) props={1=>one}") + assert_equal(s.moved(10, 20).to_s, "(10,20;110,220) props={1=>one}") + assert_equal(s.moved(RBA::Vector::new(10, 20)).to_s, "(10,20;110,220) props={1=>one}") + s2 = s.dup + s2.move(10, 20) + assert_equal(s2.to_s, "(10,20;110,220) props={1=>one}") + s2 = s.dup + s2.move(RBA::Vector::new(10, 20)) + assert_equal(s2.to_s, "(10,20;110,220) props={1=>one}") assert_equal(s.property(1), "one") assert_equal(s.properties, { 1 => "one" }) s.set_property(1, "xxx") @@ -357,6 +372,21 @@ class DBEdge_TestClass < TestBase s = RBA::DEdgeWithProperties::new(RBA::DEdge::new(0, 0, 100, 200), pid) assert_equal(s.to_s, "(0,0;100,200) props={1=>one}") assert_equal((RBA::VCplxTrans::new(2.5) * s).to_s, "(0,0;250,500) props={1=>one}") + assert_equal(s.transformed(RBA::DCplxTrans::new(0.001)).to_s, "(0,0;0.1,0.2) props={1=>one}") + assert_equal(s.transformed(RBA::VCplxTrans::new(2.5)).to_s, "(0,0;250,500) props={1=>one}") + assert_equal(s.transformed(RBA::DTrans::R90).to_s, "(0,0;-200,100) props={1=>one}") + s2 = s.dup + s2.transform(RBA::DTrans::R90) + assert_equal(s2.to_s, "(0,0;-200,100) props={1=>one}") + assert_equal((s * 0.001).to_s, "(0,0;0.1,0.2) props={1=>one}") + assert_equal(s.moved(10, 20).to_s, "(10,20;110,220) props={1=>one}") + assert_equal(s.moved(RBA::DVector::new(10, 20)).to_s, "(10,20;110,220) props={1=>one}") + s2 = s.dup + s2.move(10, 20) + assert_equal(s2.to_s, "(10,20;110,220) props={1=>one}") + s2 = s.dup + s2.move(RBA::DVector::new(10, 20)) + assert_equal(s2.to_s, "(10,20;110,220) props={1=>one}") assert_equal(s.property(1), "one") assert_equal(s.properties, { 1 => "one" }) s.set_property(1, "xxx")