Commit f4c1e8e7 authored by Georg Martin Reinke's avatar Georg Martin Reinke
Browse files

add general possibility to access component attributes from Python


Former-commit-id: 8d51db66
parent f94a3bbe
......@@ -10,6 +10,16 @@
namespace DPsim {
enum AttrType {
AttrReal,
AttrInt,
};
struct CompAttr {
AttrType type;
void* value;
};
/// Base class for all elements that might be added to the matrix.
class BaseComponent {
protected:
......@@ -26,6 +36,9 @@ namespace DPsim {
/// Component node 3
int mNode3;
/// Map of all attributes that should be exported to the Python interface
std::map<std::string, CompAttr> attrMap;
public:
BaseComponent() { }
BaseComponent(std::string name) { this->mName = name; }
......@@ -41,6 +54,8 @@ namespace DPsim {
/// get value of node3
int getNode3() { return mNode3; }
std::map<std::string, CompAttr>& getAttrMap() { return attrMap; }
std::string getName() { return mName; }
/// Initializes variables of components
......@@ -64,6 +79,7 @@ namespace DPsim {
std::exit(1);
return Complex(0, 0);
}
};
}
......
......@@ -8,6 +8,8 @@ RxLine::RxLine(std::string name, int node1, int node2, Real resistance, Real ind
mInductance = inductance;
type = LineTypes::RxLine2Node;
mNode3 = -1;
attrMap["resistance"] = {AttrReal, &mResistance};
attrMap["inductance"] = {AttrReal, &mInductance};
}
RxLine::RxLine(std::string name, int node1, int node2, int node3, Real resistance, Real inductance) : BaseComponent(name, node1, node2, node3) {
......
......@@ -11,8 +11,8 @@ PyTypeObject DPsim::PyComponentType = {
0, /* tp_itemsize */
(destructor)PyComponent::dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(getattrfunc)PyComponent::getattr, /* tp_getattr */
(setattrfunc)PyComponent::setattr, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
......@@ -116,3 +116,60 @@ PyObject* DPsim::pyLoadCim(PyObject* self, PyObject* args) {
delete reader;
return list;
}
PyObject* PyComponent::getattr(PyComponent* self, char* name) {
if (!self->comp) {
PyErr_SetString(PyExc_ValueError, "getattr on unitialized Component");
return nullptr;
}
std::map<std::string, CompAttr>& attrMap = self->comp->getAttrMap();
auto search = attrMap.find(name);
if (search == attrMap.end()) {
PyErr_Format(PyExc_AttributeError, "Component has no attribute '%s'", name);
return nullptr;
}
CompAttr attr = search->second;
switch (attr.type) {
case AttrReal:
return PyFloat_FromDouble(*((Real*) attr.value));
case AttrInt:
return PyLong_FromLong(*((Integer*) attr.value));
}
PyErr_Format(PyExc_SystemError, "invalid type in internal attribute map");
return nullptr;
}
int PyComponent::setattr(PyComponent* self, char* name, PyObject *v) {
Integer i;
Real r;
if (!self->comp) {
PyErr_SetString(PyExc_ValueError, "setattr on unitialized Component");
return -1;
}
std::map<std::string, CompAttr>& attrMap = self->comp->getAttrMap();
auto search = attrMap.find(name);
if (search == attrMap.end()) {
PyErr_Format(PyExc_AttributeError, "Component has no attribute '%s'", name);
return -1;
}
CompAttr attr = search->second;
switch (attr.type) {
case AttrReal:
r = PyFloat_AsDouble(v);
if (PyErr_Occurred())
return -1;
*((Real*) attr.value) = r;
break;
case AttrInt:
i = PyLong_AsLong(v);
if (PyErr_Occurred())
return -1;
*((Integer*) attr.value) = i;
break;
default:
PyErr_Format(PyExc_SystemError, "invalid type in internal attribute map");
return -1;
}
return 0;
}
......@@ -16,6 +16,9 @@ namespace DPsim {
static PyObject* newfunc(PyTypeObject* type, PyObject *args, PyObject *kwds);
static void dealloc(PyComponent*);
static PyObject* getattr(PyComponent* self, char* name);
static int setattr(PyComponent *self, char* name, PyObject *v);
};
extern PyTypeObject PyComponentType;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment