From d9b0b2f775e3ad68d607aceb0fa1dfcb55b06d4c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 24 Dec 2018 17:22:59 +0100 Subject: [PATCH] WIP: Ability to redefine device combination in Ruby (GenericDeviceClass) --- src/db/db/dbNetlist.cc | 37 +----- src/db/db/dbNetlist.h | 138 ++++++-------------- src/db/db/dbNetlistDeviceClasses.h | 1 + src/db/db/gsiDeclDbNetlist.cc | 47 ++++++- src/db/unit_tests/dbNetlistPropertyTests.cc | 2 +- src/db/unit_tests/dbNetlistTests.cc | 12 +- 6 files changed, 93 insertions(+), 144 deletions(-) diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 277a3b21d..0c2a134e3 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -836,22 +836,12 @@ DeviceClass &DeviceClass::operator= (const DeviceClass &other) { if (this != &other) { m_port_definitions = other.m_port_definitions; + m_name = other.m_name; + m_description = other.m_description; } return *this; } -const std::string &DeviceClass::name () const -{ - static std::string no_name; - return no_name; -} - -const std::string &DeviceClass::description () const -{ - static std::string no_description; - return no_description; -} - const DevicePortDefinition &DeviceClass::add_port_definition (const DevicePortDefinition &pd) { m_port_definitions.push_back (pd); @@ -894,29 +884,6 @@ const DeviceParameterDefinition *DeviceClass::parameter_definition (size_t id) c } } -// -------------------------------------------------------------------------------- -// GenericDeviceClass class implementation - -GenericDeviceClass::GenericDeviceClass () -{ - // .. nothing yet .. -} - -GenericDeviceClass::GenericDeviceClass (const GenericDeviceClass &other) -{ - operator= (other); -} - -GenericDeviceClass &GenericDeviceClass::operator= (const GenericDeviceClass &other) -{ - if (this != &other) { - DeviceClass::operator= (other); - m_name = other.m_name; - m_description = other.m_description; - } - return *this; -} - // -------------------------------------------------------------------------------- // Netlist class implementation diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index c53b003b2..7ba2ebc00 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -1305,14 +1305,6 @@ public: */ DeviceClass &operator= (const DeviceClass &other); - /** - * @brief Clears the circuit - */ - virtual DeviceClass *clone () const - { - return new DeviceClass (*this); - } - /** * @brief Gets the netlist the device class lives in */ @@ -1334,7 +1326,18 @@ public: * * The name is a formal name which identifies the class. */ - virtual const std::string &name () const; + const std::string &name () const + { + return m_name; + } + + /** + * @brief Sets the device name + */ + void set_name (const std::string &n) + { + m_name = n; + } /** * @brief Gets the description text for the device class @@ -1342,21 +1345,17 @@ public: * The description text is a human-readable text that * identifies the device class. */ - virtual const std::string &description () const; + const std::string &description () const + { + return m_description; + } /** - * @brief Combines two devices - * - * This method shall test, whether the two devices can be combined. Both devices - * are guaranteed to share the same device class (this). - * If they cannot be combined, this method shall do nothing and return false. - * If they can be combined, this method shall reconnect the nets of the first - * device and entirely disconnect the nets of the second device. - * The second device will be deleted afterwards. + * @brief Sets the description text */ - virtual bool combine_devices (db::Device * /*a*/, db::Device * /*b*/) const + void set_description (const std::string &d) { - return false; + m_description = d; } /** @@ -1409,9 +1408,33 @@ public: */ const DeviceParameterDefinition *parameter_definition (size_t id) const; + /** + * @brief Clears the circuit + */ + virtual DeviceClass *clone () const + { + return new DeviceClass (*this); + } + + /** + * @brief Combines two devices + * + * This method shall test, whether the two devices can be combined. Both devices + * are guaranteed to share the same device class (this). + * If they cannot be combined, this method shall do nothing and return false. + * If they can be combined, this method shall reconnect the nets of the first + * device and entirely disconnect the nets of the second device. + * The second device will be deleted afterwards. + */ + virtual bool combine_devices (db::Device * /*a*/, db::Device * /*b*/) const + { + return false; + } + private: friend class Netlist; + std::string m_name, m_description; std::vector m_port_definitions; std::vector m_parameter_definitions; db::Netlist *mp_netlist; @@ -1422,81 +1445,6 @@ private: } }; -/** - * @brief A generic device class - * - * The generic device class is a push version of the DeviceClassBase - */ -class DB_PUBLIC GenericDeviceClass - : public DeviceClass -{ -public: - /** - * @brief Constructor - * - * Creates an empty circuit. - */ - GenericDeviceClass (); - - /** - * @brief Copy constructor - */ - GenericDeviceClass (const GenericDeviceClass &other); - - /** - * @brief Assignment - */ - GenericDeviceClass &operator= (const GenericDeviceClass &other); - - /** - * @brief Clears the circuit - */ - virtual DeviceClass *clone () const - { - return new GenericDeviceClass (*this); - } - - /** - * @brief Gets the name of the device class - * - * The name is a formal name which identifies the class. - */ - virtual const std::string &name () const - { - return m_name; - } - - /** - * @brief Sets the device name - */ - void set_name (const std::string &n) - { - m_name = n; - } - - /** - * @brief Gets the description text for the device class - * - * The description text is a human-readable text that - * identifies the device class. - */ - virtual const std::string &description () const - { - return m_description; - } - - /** - * @brief Sets the description text - */ - void set_description (const std::string &d) - { - m_description = d; - } - -private: - std::string m_name, m_description; -}; - /** * @brief The netlist class * diff --git a/src/db/db/dbNetlistDeviceClasses.h b/src/db/db/dbNetlistDeviceClasses.h index ab6511907..255154033 100644 --- a/src/db/db/dbNetlistDeviceClasses.h +++ b/src/db/db/dbNetlistDeviceClasses.h @@ -36,6 +36,7 @@ public: + }; class DB_PUBLIC DeviceClassCapacitor diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index d388f1805..2ceef14cd 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -422,21 +422,54 @@ Class decl_dbDeviceClass ("db", "DeviceClass", "This class has been added in version 0.26." ); -static void gdc_add_port_definition (db::GenericDeviceClass *cls, db::DevicePortDefinition *port_def) +namespace { + +/** + * @brief A DeviceClass implementation that allows reimplementation of the virtual methods + * + * NOTE: cloning of the generic device class is not supported currently. Hence when the + * netlist is copied, the device class attributes will remain, but the functionality is lost. + */ +class GenericDeviceClass + : public db::DeviceClass +{ +public: + GenericDeviceClass () + : db::DeviceClass () + { + // .. nothing yet .. + } + + virtual bool combine_devices (db::Device *a, db::Device *b) const + { + if (cb_combine_devices.can_issue ()) { + return cb_combine_devices.issue (&db::DeviceClass::combine_devices, a, b); + } else { + return db::DeviceClass::combine_devices (a, b); + } + } + +private: + gsi::Callback cb_combine_devices; +}; + +} + +static void gdc_add_port_definition (GenericDeviceClass *cls, db::DevicePortDefinition *port_def) { if (port_def) { *port_def = cls->add_port_definition (*port_def); } } -static void gdc_add_parameter_definition (db::GenericDeviceClass *cls, db::DeviceParameterDefinition *parameter_def) +static void gdc_add_parameter_definition (GenericDeviceClass *cls, db::DeviceParameterDefinition *parameter_def) { if (parameter_def) { *parameter_def = cls->add_parameter_definition (*parameter_def); } } -Class decl_dbGenericDeviceClass (decl_dbDeviceClass, "db", "GenericDeviceClass", +Class decl_GenericDeviceClass (decl_dbDeviceClass, "db", "GenericDeviceClass", gsi::method_ext ("add_port", &gsi::gdc_add_port_definition, gsi::arg ("port_def"), "@brief Adds the given port definition to the device class\n" "This method will define a new port. The new port is added at the end of existing ports. " @@ -446,7 +479,7 @@ Class decl_dbGenericDeviceClass (decl_dbDeviceClass, "db "The port is copied into the device class. Modifying the port object later " "does not have the effect of changing the port definition." ) + - gsi::method ("clear_ports", &db::GenericDeviceClass::clear_port_definitions, + gsi::method ("clear_ports", &GenericDeviceClass::clear_port_definitions, "@brief Clears the list of ports\n" ) + gsi::method_ext ("add_parameter", &gsi::gdc_add_parameter_definition, gsi::arg ("parameter_def"), @@ -458,13 +491,13 @@ Class decl_dbGenericDeviceClass (decl_dbDeviceClass, "db "The parameter is copied into the device class. Modifying the parameter object later " "does not have the effect of changing the parameter definition." ) + - gsi::method ("clear_parameters", &db::GenericDeviceClass::clear_parameter_definitions, + gsi::method ("clear_parameters", &GenericDeviceClass::clear_parameter_definitions, "@brief Clears the list of parameters\n" ) + - gsi::method ("name=", &db::GenericDeviceClass::set_name, gsi::arg ("name"), + gsi::method ("name=", &GenericDeviceClass::set_name, gsi::arg ("name"), "@brief Sets the name of the device\n" ) + - gsi::method ("description=", &db::GenericDeviceClass::set_description, gsi::arg ("description"), + gsi::method ("description=", &GenericDeviceClass::set_description, gsi::arg ("description"), "@brief Sets the description of the device\n" ), "@brief A generic device class\n" diff --git a/src/db/unit_tests/dbNetlistPropertyTests.cc b/src/db/unit_tests/dbNetlistPropertyTests.cc index aca2afcc7..e415664d4 100644 --- a/src/db/unit_tests/dbNetlistPropertyTests.cc +++ b/src/db/unit_tests/dbNetlistPropertyTests.cc @@ -49,7 +49,7 @@ TEST(1_NameBasic) TEST(2_PortRefBasic) { - db::GenericDeviceClass dc; + db::DeviceClass dc; dc.add_port_definition (db::DevicePortDefinition ("A", "Port A")); dc.add_port_definition (db::DevicePortDefinition ("B", "Port B")); diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 59320d566..423c56351 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -87,7 +87,7 @@ TEST(2_DeviceClass) pd2.set_name ("name2"); pd2.set_description ("now it has something"); - db::GenericDeviceClass dc; + db::DeviceClass dc; dc.set_name ("devname"); dc.set_description ("devdesc"); EXPECT_EQ (dc.name (), "devname"); @@ -102,7 +102,7 @@ TEST(2_DeviceClass) EXPECT_EQ (pd2string (*dc.port_definition (dc.port_definitions ()[1].id ())), "name2(now it has something) #1"); EXPECT_EQ (dc.port_definition (3), 0); - db::GenericDeviceClass dc2 = dc; + db::DeviceClass dc2 = dc; EXPECT_EQ (dc2.name (), "devname"); EXPECT_EQ (dc2.description (), "devdesc"); EXPECT_EQ (dc2.port_definitions ().size (), size_t (2)); @@ -242,7 +242,7 @@ static std::string netlist2 (const db::Circuit &c) TEST(4_CircuitDevices) { - db::GenericDeviceClass dc1; + db::DeviceClass dc1; dc1.set_name ("dc1"); dc1.add_port_definition (db::DevicePortDefinition ("S", "Source")); dc1.add_port_definition (db::DevicePortDefinition ("G", "Gate")); @@ -250,7 +250,7 @@ TEST(4_CircuitDevices) dc1.add_parameter_definition (db::DeviceParameterDefinition ("U", "", 1.0)); dc1.add_parameter_definition (db::DeviceParameterDefinition ("V", "", 2.0)); - db::GenericDeviceClass dc2; + db::DeviceClass dc2; dc2.set_name ("dc2"); dc2.add_port_definition (db::DevicePortDefinition ("A", "")); dc2.add_port_definition (db::DevicePortDefinition ("B", "")); @@ -376,7 +376,7 @@ TEST(4_NetlistSubcircuits) { std::auto_ptr nl (new db::Netlist ()); - db::GenericDeviceClass *dc = new db::GenericDeviceClass (); + db::DeviceClass *dc = new db::DeviceClass (); dc->set_name ("dc2"); dc->add_port_definition (db::DevicePortDefinition ("A", "")); dc->add_port_definition (db::DevicePortDefinition ("B", "")); @@ -538,7 +538,7 @@ TEST(6_Net) TEST(7_NetPortsEditing) { db::Circuit c; - db::GenericDeviceClass dc; + db::DeviceClass dc; dc.add_port_definition (db::DevicePortDefinition ("A", "")); dc.add_port_definition (db::DevicePortDefinition ("B", ""));