Simplificate and generalize the way to pass arguments to Python scrips.

* New: In Isobar::Script, scripts arguments are now passed through a
    "keywords" argument (Python: **kw), that is a dictionnary.
    To add *any* Python object to that dictionnary, uses the new
    method Script::addKwArgument(const char* key, PyObject*).
      The "cell" and "editor" variables are now passed that way.
    This means that, for the editor, the old way of inserting
    a symbol in the module global dictionary is no longer used
    and the Python scripts must be modificateds.
* New: In Hurricane::PyCellViewer, create the Python link function
    for translation from Hurricane to Python.
* New: In Unicorn, modifications for the new argument passing for
    the Python scripts.
This commit is contained in:
Jean-Paul Chaput 2014-07-05 15:49:32 +02:00
parent 2b243fc0ca
commit 9e3f9e4082
9 changed files with 83 additions and 39 deletions

View File

@ -39,7 +39,6 @@
hurricane/viewer/DisplayFilterWidget.h hurricane/viewer/DisplayFilterWidget.h
hurricane/viewer/ControllerWidget.h hurricane/viewer/ControllerWidget.h
hurricane/viewer/ScriptWidget.h hurricane/viewer/ScriptWidget.h
hurricane/viewer/StratusWidget.h
) )
set ( includes hurricane/viewer/ScreenUtilities.h set ( includes hurricane/viewer/ScreenUtilities.h
hurricane/viewer/DisplayStyle.h hurricane/viewer/DisplayStyle.h
@ -56,7 +55,6 @@
hurricane/viewer/HierarchyCommand.h hurricane/viewer/HierarchyCommand.h
hurricane/viewer/SelectorCriterion.h hurricane/viewer/SelectorCriterion.h
hurricane/viewer/CellWidgets.h hurricane/viewer/CellWidgets.h
hurricane/viewer/StratusScript.h
) )
set ( pyincludes hurricane/viewer/PyHSVr.h set ( pyincludes hurricane/viewer/PyHSVr.h
hurricane/viewer/PyDrawingStyle.h hurricane/viewer/PyDrawingStyle.h
@ -108,8 +106,6 @@
DisplayFilterWidget.cpp DisplayFilterWidget.cpp
ControllerWidget.cpp ControllerWidget.cpp
ScriptWidget.cpp ScriptWidget.cpp
StratusScript.cpp
StratusWidget.cpp
) )
set ( pycpps PyHSVr.cpp set ( pycpps PyHSVr.cpp
PyDrawingStyle.cpp PyDrawingStyle.cpp

View File

@ -35,6 +35,7 @@
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
//#include "MapView.h" //#include "MapView.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/Script.h" #include "hurricane/viewer/Script.h"
#include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/CellViewer.h" #include "hurricane/viewer/CellViewer.h"
@ -46,10 +47,13 @@
#include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/ExceptionWidget.h"
#include "hurricane/viewer/GotoWidget.h" #include "hurricane/viewer/GotoWidget.h"
#include "hurricane/viewer/SelectCommand.h" #include "hurricane/viewer/SelectCommand.h"
#include "hurricane/viewer/PyCellViewer.h"
namespace Hurricane { namespace Hurricane {
using Isobar::PyCell_Link;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "CellObserver". // Class : "CellObserver".
@ -768,8 +772,9 @@ namespace Hurricane {
Isobar::Script::addPath( userDirectory.string() ); Isobar::Script::addPath( userDirectory.string() );
dbo_ptr<Isobar::Script> script = Isobar::Script::create(userScript.basename().string()); dbo_ptr<Isobar::Script> script = Isobar::Script::create(userScript.basename().string());
script->setEditor ( this ); script->addKwArgument( "cell" , (PyObject*)PyCell_Link(getCell()) );
script->runFunction( "ScriptMain", getCell() ); script->addKwArgument( "editor" , (PyObject*)PyCellViewer_Link(this) );
script->runFunction ( "ScriptMain", getCell() );
Isobar::Script::removePath( userDirectory.string() ); Isobar::Script::removePath( userDirectory.string() );
} }

View File

@ -298,6 +298,7 @@ extern "C" {
// +=================================================================+ // +=================================================================+
LinkCreateMethod(CellViewer)
PyTypeRootObjectDefinitions(CellViewer) PyTypeRootObjectDefinitions(CellViewer)

View File

@ -25,7 +25,9 @@
namespace { namespace {
#if THIS_IS_DISABLED
const char* __editorKw = "__editor"; const char* __editorKw = "__editor";
#endif
} // End of anonymous namespace. } // End of anonymous namespace.
@ -67,8 +69,11 @@ namespace Isobar {
, _userModule (NULL) , _userModule (NULL)
, _pyFunction (NULL) , _pyFunction (NULL)
, _pyArgs (NULL) , _pyArgs (NULL)
, _pyKw (NULL)
, _pyResult (NULL) , _pyResult (NULL)
#if THIS_IS_DISABLED
, _cellViewer (NULL) , _cellViewer (NULL)
#endif
, _globalState (NULL) , _globalState (NULL)
, _subInterpreter (NULL) , _subInterpreter (NULL)
, _flags (0) , _flags (0)
@ -95,47 +100,55 @@ namespace Isobar {
} }
#if THIS_IS_DISABLED
void Script::setEditor ( CellViewer* viewer ) void Script::setEditor ( CellViewer* viewer )
{ _cellViewer = viewer; } { _cellViewer = viewer; }
#endif
bool Script::runFunction ( const std::string& function, Cell* cell, unsigned int flags ) bool Script::runFunction ( const std::string& function, Cell* cell, unsigned int flags )
{ {
bool returnCode = true; bool returnCode = true;
_initialize (); _initialize();
_userModule = PyImport_ImportModule ( const_cast<char*>(_moduleName.c_str()) ); _userModule = PyImport_ImportModule( const_cast<char*>(_moduleName.c_str()) );
if ( _userModule == NULL ) { if (_userModule == NULL) {
if ( PyErr_Occurred() ) { if (PyErr_Occurred()) {
PyErr_Print (); PyErr_Print();
} }
_finalize (); _finalize();
throw Error("Cannot load python module: <%s>",_moduleName.c_str()); throw Error( "Cannot load python module: %s",_moduleName.c_str() );
} }
_setEditor (); #if THIS_IS_DISABLED
_setEditor();
#endif
_pyFunction = PyObject_GetAttrString(_userModule, const_cast<char*>(function.c_str())); _pyFunction = PyObject_GetAttrString( _userModule, const_cast<char*>(function.c_str()) );
if ( (_pyFunction == NULL) or not PyCallable_Check(_pyFunction) ) { if ( (_pyFunction == NULL) or not PyCallable_Check(_pyFunction) ) {
_finalize (); _finalize();
throw Error("Python module <%s> doesn't contains any <%s> function." throw Error( "Python module %s doesn't contains any %s function."
,_moduleName.c_str(),function.c_str()); , _moduleName.c_str(),function.c_str());
} }
_pyArgs = PyTuple_New(1); _pyArgs = PyTuple_New( 0 );
if ( cell != NULL ) PyTuple_SetItem ( _pyArgs, 0, (PyObject*)PyCell_Link(cell) ); #if THIS_IS_DISABLED
else PyTuple_SetItem ( _pyArgs, 0, Py_None ); if (cell != NULL) addKwArgument( "cell" , (PyObject*)PyCell_Link(cell) );
if (_cellViewer != NULL) addKwArgument( "editor", (PyObject*)PyCellViewer_Link(_cellViewer) );
#endif
_pyResult = PyEval_CallObject ( _pyFunction, (flags&NoScriptArgs) ? NULL : _pyArgs ); _pyResult = PyObject_Call( _pyFunction, _pyArgs, _pyKw );
_pyArgs = NULL;
_pyKw = NULL;
if ( _pyResult == NULL ) { if (_pyResult == NULL) {
cerr << "Something has gone slightly wrong" << endl; cerr << "Something has gone slightly wrong" << endl;
} }
if ( PyErr_Occurred() ) { if (PyErr_Occurred()) {
PyErr_Print (); PyErr_Print();
returnCode = false; returnCode = false;
} }
@ -174,7 +187,9 @@ namespace Isobar {
if ( _hurricaneModule == NULL ) if ( _hurricaneModule == NULL )
throw Error("Script::_importModule(): No Hurricane module."); throw Error("Script::_importModule(): No Hurricane module.");
#if THIS_IS_DISABLED
PyModule_AddObject ( _hurricaneModule, const_cast<char*>(__editorKw), Py_None ); PyModule_AddObject ( _hurricaneModule, const_cast<char*>(__editorKw), Py_None );
#endif
} }
@ -237,6 +252,7 @@ namespace Isobar {
} }
#if THIS_IS_DISABLED
void Script::_setEditor () void Script::_setEditor ()
{ {
if ( _userModule == NULL ) return; if ( _userModule == NULL ) return;
@ -252,6 +268,22 @@ namespace Isobar {
PyDict_SetItemString ( dictionary, __editorKw, Py_None ); PyDict_SetItemString ( dictionary, __editorKw, Py_None );
} }
} }
#endif
void Script::addKwArgument ( const char* key, PyObject* object )
{
if (_pyKw == NULL) _pyKw = PyDict_New();
PyObject* pyKey = PyString_FromString( key );
if (PyDict_Contains(_pyKw,pyKey) == 1) {
cerr << Error( "Script::addKwArgument(): Attempt to add twice key %s (nothing done)."
, key ) << endl;
return;
}
PyDict_SetItem( _pyKw, pyKey, object );
}
} // End of Isobar namespace. } // End of Isobar namespace.

View File

@ -42,6 +42,7 @@ extern "C" {
extern PyMethodDef PyCellViewer_Methods[]; extern PyMethodDef PyCellViewer_Methods[];
extern PyObject* PyCellViewer_create ( PyObject* self, PyObject* args ); extern PyObject* PyCellViewer_create ( PyObject* self, PyObject* args );
extern PyObject* PyCellViewer_Link ( Hurricane::CellViewer* object );
extern void PyCellViewer_LinkPyType (); extern void PyCellViewer_LinkPyType ();
extern void PyCellViewer_postModuleInit (); extern void PyCellViewer_postModuleInit ();

View File

@ -39,8 +39,11 @@ namespace Isobar {
inline PyObject* getSysModule (); inline PyObject* getSysModule ();
inline PyObject* getHurricaneModule (); inline PyObject* getHurricaneModule ();
inline PyObject* getUserModule (); inline PyObject* getUserModule ();
#if THIS_IS_DISABLED
void setEditor ( Hurricane::CellViewer* ); void setEditor ( Hurricane::CellViewer* );
#endif
bool runFunction ( const std::string& function, Hurricane::Cell* cell, unsigned int flags=0 ); bool runFunction ( const std::string& function, Hurricane::Cell* cell, unsigned int flags=0 );
void addKwArgument ( const char* key, PyObject* object );
protected: protected:
static std::vector<std::string> _pathes; static std::vector<std::string> _pathes;
std::string _moduleName; std::string _moduleName;
@ -49,8 +52,11 @@ namespace Isobar {
PyObject* _userModule; PyObject* _userModule;
PyObject* _pyFunction; PyObject* _pyFunction;
PyObject* _pyArgs; PyObject* _pyArgs;
PyObject* _pyKw;
PyObject* _pyResult; PyObject* _pyResult;
#if THIS_IS_DISABLED
Hurricane::CellViewer* _cellViewer; Hurricane::CellViewer* _cellViewer;
#endif
PyThreadState* _globalState; PyThreadState* _globalState;
PyThreadState* _subInterpreter; PyThreadState* _subInterpreter;
long _flags; long _flags;
@ -64,7 +70,9 @@ namespace Isobar {
PyObject* _importModule ( const std::string& ); PyObject* _importModule ( const std::string& );
void _initialize (); void _initialize ();
void _finalize (); void _finalize ();
#if THIS_IS_DISABLED
void _setEditor (); void _setEditor ();
#endif
}; };

View File

@ -42,7 +42,6 @@ namespace bopts = boost::program_options;
#include "hurricane/viewer/HApplication.h" #include "hurricane/viewer/HApplication.h"
#include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/StratusScript.h"
#include "hurricane/viewer/SelectCommand.h" #include "hurricane/viewer/SelectCommand.h"
using namespace Hurricane; using namespace Hurricane;
@ -287,14 +286,14 @@ int main ( int argc, char *argv[] )
cout << endl; cout << endl;
//cmess2 << af->getPrint() << endl; //cmess2 << af->getPrint() << endl;
if ( arguments.count("stratus-script") ) { // if ( arguments.count("stratus-script") ) {
string scriptName = arguments["stratus-script"].as<string>(); // string scriptName = arguments["stratus-script"].as<string>();
cmess1 << " o Running stratus script:" << endl; // cmess1 << " o Running stratus script:" << endl;
cmess1 << " - <" << scriptName << ">" << endl; // cmess1 << " - <" << scriptName << ">" << endl;
dbo_ptr<StratusScript> script = StratusScript::create ( scriptName, NULL ); // dbo_ptr<StratusScript> script = StratusScript::create ( scriptName, NULL );
script->run (); // script->run ();
} // }
if ( cell ) { if ( cell ) {
// Python Script test. // Python Script test.

View File

@ -19,7 +19,8 @@
#include <QMenu> #include <QMenu>
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/viewer/Script.h" #include "hurricane/viewer/Script.h"
#include "hurricane/viewer/CellWidget.h" #include "hurricane/viewer/CellViewer.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "crlcore/Catalog.h" #include "crlcore/Catalog.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/GraphicToolEngine.h" #include "crlcore/GraphicToolEngine.h"
@ -36,6 +37,7 @@ namespace Unicorn {
using Hurricane::dbo_ptr; using Hurricane::dbo_ptr;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::PyCellViewer_Link;
using CRL::System; using CRL::System;
using CRL::Catalog; using CRL::Catalog;
using CRL::AllianceFramework; using CRL::AllianceFramework;
@ -83,8 +85,8 @@ namespace Unicorn {
Isobar::Script::addPath( systemConfDir.string() ); Isobar::Script::addPath( systemConfDir.string() );
dbo_ptr<Isobar::Script> script = Isobar::Script::create( systemConfFile.stem().string() ); dbo_ptr<Isobar::Script> script = Isobar::Script::create( systemConfFile.stem().string() );
script->setEditor ( this ); script->addKwArgument( "editor" , (PyObject*)PyCellViewer_Link(this) );
script->runFunction( "unicornConfigure", getCell() ); script->runFunction ( "unicornConfigure", getCell() );
Isobar::Script::removePath( systemConfDir.string() ); Isobar::Script::removePath( systemConfDir.string() );
} else { } else {

View File

@ -19,10 +19,10 @@ except Exception, e:
sys.exit(2) sys.exit(2)
def unicornConfigure ( cell=None ): def unicornConfigure ( **kw ):
editor = None editor = None
if globals().has_key('__editor'): if kw.has_key('editor'):
editor = __editor editor = kw['editor']
else: else:
print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' ) print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' )
return return