WIP: Ability to redefine device combination in Ruby (GenericDeviceClass)

This commit is contained in:
Matthias Koefferlein 2018-12-24 17:22:59 +01:00
parent 764667d8e8
commit d9b0b2f775
6 changed files with 93 additions and 144 deletions

View File

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

View File

@ -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<DevicePortDefinition> m_port_definitions;
std::vector<DeviceParameterDefinition> 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
*

View File

@ -36,6 +36,7 @@ public:
};
class DB_PUBLIC DeviceClassCapacitor

View File

@ -422,21 +422,54 @@ Class<db::DeviceClass> 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<const db::DeviceClass, bool, db::Device *, db::Device *> (&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<db::GenericDeviceClass> decl_dbGenericDeviceClass (decl_dbDeviceClass, "db", "GenericDeviceClass",
Class<GenericDeviceClass> 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<db::GenericDeviceClass> 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<db::GenericDeviceClass> 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"

View File

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

View File

@ -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<db::Netlist> 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", ""));