More generic object-with-properties GSI methods

This commit is contained in:
Matthias Koefferlein 2025-01-04 19:24:32 +01:00
parent 322b9419ad
commit 826b811249
3 changed files with 177 additions and 7 deletions

View File

@ -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<db::array<db::CellInst, db::DTrans> > DCellInstAr
*/
template <class R>
struct result_of_transformation;
struct result_of_method;
template <class R, class Obj, class Tr>
struct result_of_transformation<R (Obj::*) (const Tr &) const>
template <class R, class Obj, class A1>
struct result_of_method<R (Obj::*) (A1) const>
{
typedef R type;
};
template <class Tr, class Obj>
inline db::object_with_properties<typename result_of_transformation<decltype (& Obj::template transformed<Tr>)>::type>
inline db::object_with_properties<typename result_of_method<decltype (& Obj::template transformed<Tr>)>::type>
operator* (const Tr &t, const db::object_with_properties<Obj> &obj)
{
return db::object_with_properties<typename result_of_transformation<decltype (& Obj::template transformed<Tr>)>::type> (obj.Obj::transformed (t), obj.properties_id ());
return db::object_with_properties<typename result_of_method<decltype (& Obj::template transformed<Tr>)>::type> (obj.Obj::transformed (t), obj.properties_id ());
}
/**
@ -321,10 +329,10 @@ operator* (const Tr &t, const db::object_with_properties<Obj> &obj)
* @return The scaled object
*/
template <class Obj>
inline db::object_with_properties<Obj>
inline db::object_with_properties<typename result_of_method<decltype (& Obj::operator*)>::type>
operator* (const db::object_with_properties<Obj> &obj, double s)
{
return db::object_with_properties<Obj> (((const Obj &) obj) * s, obj.properties_id ());
return db::object_with_properties<typename result_of_method<decltype (& Obj::operator*)>::type> (obj * s, obj.properties_id ());
}
/**

View File

@ -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 <class T>
static typename db::result_of_method<decltype (& T::scaled)>::type
scaled_meth_impl (const T *s, double scale)
{
typename db::result_of_method<decltype (& T::scaled)>::type res (s->scaled (scale), s->properties_id ());
return res;
}
template <class T>
static T
transformed_meth_impl0 (const T *s, const db::simple_trans<typename T::coord_type> &tr)
{
return s->transformed (tr);
}
template <class T>
static typename db::result_of_method<decltype (& T::template transformed<db::complex_trans<typename T::coord_type, db::DCoord> >)>::type
transformed_meth_impl1 (const T *s, const db::complex_trans<typename T::coord_type, db::DCoord> &tr)
{
typename db::result_of_method<decltype (& T::template transformed<db::complex_trans<typename T::coord_type, db::DCoord> >)>::type res (s->transformed (tr), s->properties_id ());
return res;
}
template <class T>
static typename db::result_of_method<decltype (& T::template transformed<db::complex_trans<typename T::coord_type, db::Coord> >)>::type
transformed_meth_impl2 (const T *s, const db::complex_trans<typename T::coord_type, db::Coord> &tr)
{
typename db::result_of_method<decltype (& T::template transformed<db::complex_trans<typename T::coord_type, db::Coord> >)>::type res (s->transformed (tr), s->properties_id ());
return res;
}
template <class T>
static void
transform_meth_impl0 (T *s, const db::simple_trans<typename T::coord_type> &tr)
{
s->transform (tr);
}
template <class T>
static void
transform_meth_impl1 (T *s, const db::complex_trans<typename T::coord_type, typename T::coord_type> &tr)
{
s->transform (tr);
}
template <class T>
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 <class T>
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 <class T>
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<T>, 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<T>, gsi::arg ("t"),
"@brief Transforms the object (in-place version)\n"
) +
gsi::method_ext ("transform", &transform_meth_impl1<T>, gsi::arg ("t"),
"@brief Transforms the object (in-place version)\n"
) +
gsi::method_ext ("transformed", &transformed_meth_impl0<T>, 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<T>, 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<T>, 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<T>, 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<T>, 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<T>, 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. "

View File

@ -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")