Skip to content

Commit

Permalink
+ support of Python feature classes without an execute() method
Browse files Browse the repository at this point in the history
+ if execute() method of Python feature is missing or if it returns false call the execute() method of the C++ feature
+ fix SketchObjectPython
  • Loading branch information
wwmayer committed Oct 20, 2015
1 parent 169b2e3 commit e7a3dc4
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 19 deletions.
40 changes: 25 additions & 15 deletions src/App/FeaturePython.cpp
Expand Up @@ -44,24 +44,36 @@ FeaturePythonImp::~FeaturePythonImp()
{
}

DocumentObjectExecReturn *FeaturePythonImp::execute()
/*!
Calls the execute() method of the Python feature class. If the Python feature class doesn't have an execute()
method or if it returns False this method also return false and true otherwise.
*/
bool FeaturePythonImp::execute()
{
// Run the execute method of the proxy object.
Base::PyGILStateLocker lock;
try {
Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == PropertyPythonObject::getClassTypeId()) {
Py::Object feature = static_cast<PropertyPythonObject*>(proxy)->getValue();
if (feature.hasAttr("__object__")) {
Py::Callable method(feature.getAttr(std::string("execute")));
Py::Tuple args;
method.apply(args);
}
else {
Py::Callable method(feature.getAttr(std::string("execute")));
Py::Tuple args(1);
args.setItem(0, Py::Object(object->getPyObject(), true));
method.apply(args);
if (feature.hasAttr(std::string("execute"))) {
if (feature.hasAttr("__object__")) {
Py::Callable method(feature.getAttr(std::string("execute")));
Py::Tuple args;
Py::Object res = method.apply(args);
if (res.isBoolean() && !res.isTrue())
return false;
return true;
}
else {
Py::Callable method(feature.getAttr(std::string("execute")));
Py::Tuple args(1);
args.setItem(0, Py::Object(object->getPyObject(), true));
Py::Object res = method.apply(args);
if (res.isBoolean() && !res.isTrue())
return false;
return true;
}
}
}
}
Expand All @@ -70,10 +82,10 @@ DocumentObjectExecReturn *FeaturePythonImp::execute()
e.ReportException();
std::stringstream str;
str << object->Label.getValue() << ": " << e.what();
return new App::DocumentObjectExecReturn(str.str());
throw Base::RuntimeError(str.str());
}

return DocumentObject::StdReturn;
return false;
}

void FeaturePythonImp::onBeforeChange(const Property* prop)
Expand Down Expand Up @@ -175,5 +187,3 @@ template<> const char* App::GeometryPython::getViewProviderName(void) const {
}
// explicit template instantiation
template class AppExport FeaturePythonT<GeoFeature>;}


Expand Down
12 changes: 10 additions & 2 deletions src/App/FeaturePython.h
Expand Up @@ -44,7 +44,7 @@ class AppExport FeaturePythonImp
FeaturePythonImp(App::DocumentObject*);
~FeaturePythonImp();

DocumentObjectExecReturn *execute();
bool execute();
void onBeforeChange(const Property* prop);
void onChanged(const Property* prop);
PyObject *getPyObject(void);
Expand Down Expand Up @@ -84,7 +84,15 @@ class FeaturePythonT : public FeatureT
}
/// recalculate the Feature
virtual DocumentObjectExecReturn *execute(void) {
return imp->execute();
try {
bool handled = imp->execute();
if (!handled)
return FeatureT::execute();
}
catch (const Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
}
return DocumentObject::StdReturn;
}
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
Expand Down
4 changes: 2 additions & 2 deletions src/App/FeaturePythonPyImp.inl
Expand Up @@ -85,12 +85,12 @@ PyMethodDef FeaturePythonPyT<FeaturePyT>::Methods[] = {
{"addProperty",
(PyCFunction) staticCallback_addProperty,
METH_VARARGS,
"addProperty(string, string) -- Add a generic property.\nThe first argument specifies the type, the second the\nname of the property.\n "
"addProperty(string, string) -- Add a generic property.\nThe first argument specifies the type, the second the\nname of the property.\n"
},
{"removeProperty",
(PyCFunction) staticCallback_removeProperty,
METH_VARARGS,
"removeProperty(string) -- Remove a generic property.\nNote, you can only remove user-defined properties but not built-in ones.\n "
"removeProperty(string) -- Remove a generic property.\nNote, you can only remove user-defined properties but not built-in ones.\n"
},
{"supportedProperties",
(PyCFunction) staticCallback_supportedProperties,
Expand Down
8 changes: 8 additions & 0 deletions src/Mod/Sketcher/App/SketchObject.cpp
Expand Up @@ -49,6 +49,7 @@
#include <boost/bind.hpp>

#include <App/Document.h>
#include <App/FeaturePythonPyImp.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Tools.h>
Expand Down Expand Up @@ -4016,6 +4017,13 @@ PROPERTY_SOURCE_TEMPLATE(Sketcher::SketchObjectPython, Sketcher::SketchObject)
template<> const char* Sketcher::SketchObjectPython::getViewProviderName(void) const {
return "SketcherGui::ViewProviderPython";
}
template<> PyObject* Sketcher::SketchObjectPython::getPyObject(void) {
if (PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new FeaturePythonPyT<SketchObjectPy>(this),true);
}
return Py::new_reference_to(PythonObject);
}
/// @endcond

// explicit template instantiation
Expand Down

0 comments on commit e7a3dc4

Please sign in to comment.