Merge pull request #4316 from wwmayer/J-Dunn-master

Path: fix unnecessary copy on read for Command.parameters dict
This commit is contained in:
sliptonic
2021-01-25 09:10:44 -06:00
committed by GitHub
2 changed files with 21 additions and 5 deletions

View File

@@ -43,7 +43,7 @@ pairs, or a placement, or a vector</UserDocu>
</Methode>
<Methode Name="setFromGCode">
<Documentation>
<UserDocu>toGCode(): returns a GCode representation of the command</UserDocu>
<UserDocu>setFromGCode(): sets the path from the contents of the given GCode string</UserDocu>
</Documentation>
</Methode>
<Methode Name="transform">
@@ -51,5 +51,8 @@ pairs, or a placement, or a vector</UserDocu>
<UserDocu>transform(Placement): returns a copy of this command transformed by the given placement</UserDocu>
</Documentation>
</Methode>
<ClassDeclarations>
mutable Py::Dict parameters_copy_dict;
</ClassDeclarations>
</PythonExport>
</GenerateModel>

View File

@@ -56,6 +56,11 @@ std::string CommandPy::representation(void) const
return str.str();
}
//
// Py::Dict parameters_copy_dict is now a class member to avoid delete/create/copy on every read access from python code
// Now the pre-filled Py::Dict is returned which is more consistent with normal python behaviour.
// It should be cleared whenever the c++ Parameters object is changed eg setParameters() or other objects invalidate its content, eg setPlacement()
// https://forum.freecadweb.org/viewtopic.php?f=15&t=50583
PyObject *CommandPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
@@ -117,6 +122,7 @@ int CommandPy::PyInit(PyObject* args, PyObject* kwd)
}
getCommandPtr()->Parameters[ckey]=cvalue;
}
parameters_copy_dict.clear();
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
@@ -157,11 +163,13 @@ void CommandPy::setName(Py::String arg)
Py::Dict CommandPy::getParameters(void) const
{
Py::Dict dict;
for(std::map<std::string,double>::iterator i = getCommandPtr()->Parameters.begin(); i != getCommandPtr()->Parameters.end(); ++i) {
dict.setItem(i->first, Py::Float(i->second));
// dict now a class member , https://forum.freecadweb.org/viewtopic.php?f=15&t=50583
if (parameters_copy_dict.length()==0) {
for(std::map<std::string,double>::iterator i = getCommandPtr()->Parameters.begin(); i != getCommandPtr()->Parameters.end(); ++i) {
parameters_copy_dict.setItem(i->first, Py::Float(i->second));
}
}
return dict;
return parameters_copy_dict;
}
void CommandPy::setParameters(Py::Dict arg)
@@ -200,6 +208,7 @@ void CommandPy::setParameters(Py::Dict arg)
throw Py::TypeError("The dictionary can only contain number values");
}
getCommandPtr()->Parameters[ckey]=cvalue;
parameters_copy_dict.clear();
}
}
@@ -224,6 +233,7 @@ PyObject* CommandPy::setFromGCode(PyObject *args)
std::string gcode(pstr);
try {
getCommandPtr()->setFromGCode(gcode);
parameters_copy_dict.clear();
}
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ValueError, e.what());
@@ -249,6 +259,7 @@ void CommandPy::setPlacement(Py::Object arg)
Py::Type PlacementType(pyType.o);
if(arg.isType(PlacementType)) {
getCommandPtr()->setFromPlacement( *static_cast<Base::PlacementPy*>((*arg))->getPlacementPtr() );
parameters_copy_dict.clear();
} else
throw Py::TypeError("Argument must be a placement");
}
@@ -259,6 +270,7 @@ PyObject* CommandPy::transform(PyObject *args)
if ( PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &placement) ) {
Base::PlacementPy *p = static_cast<Base::PlacementPy*>(placement);
Path::Command trCmd = getCommandPtr()->transform( *p->getPlacementPtr() );
parameters_copy_dict.clear();
return new CommandPy(new Path::Command(trCmd));
} else
throw Py::TypeError("Argument must be a placement");
@@ -302,6 +314,7 @@ int CommandPy::setCustomAttributes(const char* attr, PyObject* obj)
return 0;
}
getCommandPtr()->Parameters[satt]=cvalue;
parameters_copy_dict.clear();
return 1;
}
}