Skip to content
Snippets Groups Projects
Commit 3d50d482 authored by Julien Malik's avatar Julien Malik
Browse files

ENH: add PyCommand to receive ITK event in Python callable

parent 6071733f
No related branches found
No related tags found
No related merge requests found
......@@ -34,6 +34,7 @@ if ( WRAP_LUA OR WRAP_PYTHON OR WRAP_JAVA OR WRAP_CSHARP OR WRAP_TCL OR WRAP_R O
set ( SWIG_HEADERS ${SWIG_HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/itkBase.i
${CMAKE_CURRENT_SOURCE_DIR}/itkMacro.i
${CMAKE_CURRENT_SOURCE_DIR}/PyCommand.i
${CMAKE_CURRENT_SOURCE_DIR}/Python.i
${CMAKE_CURRENT_SOURCE_DIR}/Java.i
......@@ -63,7 +64,7 @@ if ( WRAP_PYTHON )
set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS})
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR})
set(SWIG_MODULE_otbApplication_EXTRA_DEPS OTBApplicationEngine ${SWIG_HEADERS})
SWIG_add_module ( otbApplication python otbApplication.i otbApplicationPYTHON_wrap.cxx )
SWIG_add_module ( otbApplication python otbApplication.i otbApplicationPYTHON_wrap.cxx itkPyCommand.cxx )
SWIG_link_libraries ( otbApplication ${PYTHON_LIBRARIES} OTBApplicationEngine)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "-w")
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#if SWIGPYTHON
%{
#include "itkPyCommand.h"
typedef itk::PyCommand itkPyCommand;
typedef itk::PyCommand::Pointer itkPyCommand_Pointer;
%}
class itkPyCommand : public itkCommand
{
public:
static itkPyCommand_Pointer New();
virtual char const * GetNameOfClass() const;
void SetCommandCallable(PyObject *obj);
PyObject * GetCommandCallable();
void Execute(itkObject *, const itkEventObject&);
//void Execute(const itkObject *, const EventObject&);
protected:
itkPyCommand();
~itkPyCommand();
};
DECLARE_REF_COUNT_CLASS( itkPyCommand )
#endif
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkPyCommand.cxx,v $
Language: C++
Date: $Date: 2006/09/06 20:58:42 $
Version: $Revision: 1.1 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkPyCommand.h"
namespace itk
{
PyCommand::PyCommand()
{
this->obj = NULL;
}
PyCommand::~PyCommand()
{
if (this->obj)
{
Py_DECREF(this->obj);
}
this->obj = NULL;
}
void PyCommand::SetCommandCallable(PyObject *obj)
{
if (obj != this->obj)
{
if (this->obj)
{
// get rid of our reference
Py_DECREF(this->obj);
}
// store the new object
this->obj = obj;
if (this->obj)
{
// take out reference (so that the calling code doesn't
// have to keep a binding to the callable around)
Py_INCREF(this->obj);
}
}
}
PyObject * PyCommand::GetCommandCallable()
{
return this->obj;
}
void PyCommand::Execute(Object *, const EventObject&)
{
this->PyExecute();
}
void PyCommand::Execute(const Object*, const EventObject&)
{
this->PyExecute();
}
void PyCommand::PyExecute()
{
// make sure that the CommandCallable is in fact callable
if (!PyCallable_Check(this->obj))
{
// we throw a standard ITK exception: this makes it possible for
// our standard CableSwig exception handling logic to take this
// through to the invoking Python process
itkExceptionMacro(<<"CommandCallable is not a callable Python object, "
<<"or it has not been set.");
}
else
{
PyObject *result;
result = PyEval_CallObject(this->obj, (PyObject *)NULL);
if (result)
{
Py_DECREF(result);
}
else
{
// there was a Python error. Clear the error by printing to stdout
PyErr_Print();
// make sure the invoking Python code knows there was a problem
// by raising an exception
itkExceptionMacro(<<"There was an error executing the "
<<"CommandCallable.");
}
}
}
} // namespace itk
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkPyCommand.h,v $
Language: C++
Date: $Date: 2006/09/06 20:58:42 $
Version: $Revision: 1.1 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef _itkPyCommand_h
#define _itkPyCommand_h
#include "itkCommand.h"
// The python header defines _POSIX_C_SOURCE without a preceding #undef
#undef _POSIX_C_SOURCE
#include <Python.h>
namespace itk
{
/** \class PyCommand
* \brief Command subclass that calls a Python callable object, e.g.
* a Python function.
*
* With this class, arbitrary Python callable objects (e.g. functions)
* can be associated with an instance to be used in AddObserver calls.
* This is analogous to itk::TclCommand, but then a tad more flexible. ;)
*
* This class was contributed by Charl P. Botha <cpbotha |AT| ieee.org>
*/
class PyCommand : public Command
{
public:
///! Standard "Self" typedef.
typedef PyCommand Self;
///! Smart pointer typedef support.
typedef SmartPointer<Self> Pointer;
///! Run-time type information (and related methods).
itkTypeMacro(PyCommand,Command);
///! Method for creation through the object factory.
itkNewMacro(Self);
/**
* Assign a Python callable object to be used. You don't have to keep
* a binding to the callable, PyCommand will also take out a reference
* to make sure the Callable sticks around.
*/
void SetCommandCallable(PyObject *obj);
PyObject * GetCommandCallable();
void Execute(Object *, const EventObject&);
void Execute(const Object *, const EventObject&);
protected:
PyCommand();
~PyCommand();
void PyExecute();
PyCommand(const Self&); // Not implemented.
void operator=(const Self&); // Not implemented.
private:
PyObject *obj;
};
} // namespace itk
#endif // _itkPyCommand_h
......@@ -161,3 +161,6 @@ private:
void operator=(const Self&);
};
%include "PyCommand.i"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment