From 9e3f9e40820cf18b6199a2d5f7bf540b7e979c56 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 5 Jul 2014 15:49:32 +0200 Subject: [PATCH] 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. --- hurricane/src/viewer/CMakeLists.txt | 4 -- hurricane/src/viewer/CellViewer.cpp | 9 ++- hurricane/src/viewer/PyCellViewer.cpp | 1 + hurricane/src/viewer/Script.cpp | 70 ++++++++++++++----- .../viewer/hurricane/viewer/PyCellViewer.h | 1 + .../src/viewer/hurricane/viewer/Script.h | 8 +++ unicorn/src/CgtMain.cpp | 15 ++-- unicorn/src/UnicornGui.cpp | 8 ++- unicorn/src/init/unicornInit.py | 6 +- 9 files changed, 83 insertions(+), 39 deletions(-) diff --git a/hurricane/src/viewer/CMakeLists.txt b/hurricane/src/viewer/CMakeLists.txt index 170b99cf..70d2537b 100644 --- a/hurricane/src/viewer/CMakeLists.txt +++ b/hurricane/src/viewer/CMakeLists.txt @@ -39,7 +39,6 @@ hurricane/viewer/DisplayFilterWidget.h hurricane/viewer/ControllerWidget.h hurricane/viewer/ScriptWidget.h - hurricane/viewer/StratusWidget.h ) set ( includes hurricane/viewer/ScreenUtilities.h hurricane/viewer/DisplayStyle.h @@ -56,7 +55,6 @@ hurricane/viewer/HierarchyCommand.h hurricane/viewer/SelectorCriterion.h hurricane/viewer/CellWidgets.h - hurricane/viewer/StratusScript.h ) set ( pyincludes hurricane/viewer/PyHSVr.h hurricane/viewer/PyDrawingStyle.h @@ -108,8 +106,6 @@ DisplayFilterWidget.cpp ControllerWidget.cpp ScriptWidget.cpp - StratusScript.cpp - StratusWidget.cpp ) set ( pycpps PyHSVr.cpp PyDrawingStyle.cpp diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index a9d26630..7e04b3b8 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -35,6 +35,7 @@ #include "hurricane/DataBase.h" #include "hurricane/Cell.h" //#include "MapView.h" +#include "hurricane/isobar/PyCell.h" #include "hurricane/viewer/Script.h" #include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/CellViewer.h" @@ -46,10 +47,13 @@ #include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/GotoWidget.h" #include "hurricane/viewer/SelectCommand.h" +#include "hurricane/viewer/PyCellViewer.h" namespace Hurricane { + using Isobar::PyCell_Link; + // ------------------------------------------------------------------- // Class : "CellObserver". @@ -768,8 +772,9 @@ namespace Hurricane { Isobar::Script::addPath( userDirectory.string() ); dbo_ptr script = Isobar::Script::create(userScript.basename().string()); - script->setEditor ( this ); - script->runFunction( "ScriptMain", getCell() ); + script->addKwArgument( "cell" , (PyObject*)PyCell_Link(getCell()) ); + script->addKwArgument( "editor" , (PyObject*)PyCellViewer_Link(this) ); + script->runFunction ( "ScriptMain", getCell() ); Isobar::Script::removePath( userDirectory.string() ); } diff --git a/hurricane/src/viewer/PyCellViewer.cpp b/hurricane/src/viewer/PyCellViewer.cpp index 55a634b8..0916396d 100644 --- a/hurricane/src/viewer/PyCellViewer.cpp +++ b/hurricane/src/viewer/PyCellViewer.cpp @@ -298,6 +298,7 @@ extern "C" { // +=================================================================+ + LinkCreateMethod(CellViewer) PyTypeRootObjectDefinitions(CellViewer) diff --git a/hurricane/src/viewer/Script.cpp b/hurricane/src/viewer/Script.cpp index c698d2f9..0cd78947 100644 --- a/hurricane/src/viewer/Script.cpp +++ b/hurricane/src/viewer/Script.cpp @@ -25,7 +25,9 @@ namespace { +#if THIS_IS_DISABLED const char* __editorKw = "__editor"; +#endif } // End of anonymous namespace. @@ -67,8 +69,11 @@ namespace Isobar { , _userModule (NULL) , _pyFunction (NULL) , _pyArgs (NULL) + , _pyKw (NULL) , _pyResult (NULL) +#if THIS_IS_DISABLED , _cellViewer (NULL) +#endif , _globalState (NULL) , _subInterpreter (NULL) , _flags (0) @@ -95,47 +100,55 @@ namespace Isobar { } +#if THIS_IS_DISABLED void Script::setEditor ( CellViewer* viewer ) { _cellViewer = viewer; } +#endif bool Script::runFunction ( const std::string& function, Cell* cell, unsigned int flags ) { bool returnCode = true; - _initialize (); + _initialize(); - _userModule = PyImport_ImportModule ( const_cast(_moduleName.c_str()) ); + _userModule = PyImport_ImportModule( const_cast(_moduleName.c_str()) ); - if ( _userModule == NULL ) { - if ( PyErr_Occurred() ) { - PyErr_Print (); + if (_userModule == NULL) { + if (PyErr_Occurred()) { + PyErr_Print(); } - _finalize (); - throw Error("Cannot load python module: <%s>",_moduleName.c_str()); + _finalize(); + throw Error( "Cannot load python module: %s",_moduleName.c_str() ); } - _setEditor (); +#if THIS_IS_DISABLED + _setEditor(); +#endif - _pyFunction = PyObject_GetAttrString(_userModule, const_cast(function.c_str())); + _pyFunction = PyObject_GetAttrString( _userModule, const_cast(function.c_str()) ); if ( (_pyFunction == NULL) or not PyCallable_Check(_pyFunction) ) { - _finalize (); - throw Error("Python module <%s> doesn't contains any <%s> function." - ,_moduleName.c_str(),function.c_str()); + _finalize(); + throw Error( "Python module %s doesn't contains any %s function." + , _moduleName.c_str(),function.c_str()); } - _pyArgs = PyTuple_New(1); - if ( cell != NULL ) PyTuple_SetItem ( _pyArgs, 0, (PyObject*)PyCell_Link(cell) ); - else PyTuple_SetItem ( _pyArgs, 0, Py_None ); + _pyArgs = PyTuple_New( 0 ); +#if THIS_IS_DISABLED + 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; } - if ( PyErr_Occurred() ) { - PyErr_Print (); + if (PyErr_Occurred()) { + PyErr_Print(); returnCode = false; } @@ -174,7 +187,9 @@ namespace Isobar { if ( _hurricaneModule == NULL ) throw Error("Script::_importModule(): No Hurricane module."); +#if THIS_IS_DISABLED PyModule_AddObject ( _hurricaneModule, const_cast(__editorKw), Py_None ); +#endif } @@ -237,6 +252,7 @@ namespace Isobar { } +#if THIS_IS_DISABLED void Script::_setEditor () { if ( _userModule == NULL ) return; @@ -252,6 +268,22 @@ namespace Isobar { 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. diff --git a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h index ea52e336..7f3e2fc2 100644 --- a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h @@ -42,6 +42,7 @@ extern "C" { extern PyMethodDef PyCellViewer_Methods[]; extern PyObject* PyCellViewer_create ( PyObject* self, PyObject* args ); + extern PyObject* PyCellViewer_Link ( Hurricane::CellViewer* object ); extern void PyCellViewer_LinkPyType (); extern void PyCellViewer_postModuleInit (); diff --git a/hurricane/src/viewer/hurricane/viewer/Script.h b/hurricane/src/viewer/hurricane/viewer/Script.h index ddc94f88..ccbfe2d9 100644 --- a/hurricane/src/viewer/hurricane/viewer/Script.h +++ b/hurricane/src/viewer/hurricane/viewer/Script.h @@ -39,8 +39,11 @@ namespace Isobar { inline PyObject* getSysModule (); inline PyObject* getHurricaneModule (); inline PyObject* getUserModule (); +#if THIS_IS_DISABLED void setEditor ( Hurricane::CellViewer* ); +#endif bool runFunction ( const std::string& function, Hurricane::Cell* cell, unsigned int flags=0 ); + void addKwArgument ( const char* key, PyObject* object ); protected: static std::vector _pathes; std::string _moduleName; @@ -49,8 +52,11 @@ namespace Isobar { PyObject* _userModule; PyObject* _pyFunction; PyObject* _pyArgs; + PyObject* _pyKw; PyObject* _pyResult; +#if THIS_IS_DISABLED Hurricane::CellViewer* _cellViewer; +#endif PyThreadState* _globalState; PyThreadState* _subInterpreter; long _flags; @@ -64,7 +70,9 @@ namespace Isobar { PyObject* _importModule ( const std::string& ); void _initialize (); void _finalize (); +#if THIS_IS_DISABLED void _setEditor (); +#endif }; diff --git a/unicorn/src/CgtMain.cpp b/unicorn/src/CgtMain.cpp index f43ef677..4070bdeb 100644 --- a/unicorn/src/CgtMain.cpp +++ b/unicorn/src/CgtMain.cpp @@ -42,7 +42,6 @@ namespace bopts = boost::program_options; #include "hurricane/viewer/HApplication.h" #include "hurricane/viewer/Graphics.h" -#include "hurricane/viewer/StratusScript.h" #include "hurricane/viewer/SelectCommand.h" using namespace Hurricane; @@ -287,14 +286,14 @@ int main ( int argc, char *argv[] ) cout << endl; //cmess2 << af->getPrint() << endl; - if ( arguments.count("stratus-script") ) { - string scriptName = arguments["stratus-script"].as(); - cmess1 << " o Running stratus script:" << endl; - cmess1 << " - <" << scriptName << ">" << endl; + // if ( arguments.count("stratus-script") ) { + // string scriptName = arguments["stratus-script"].as(); + // cmess1 << " o Running stratus script:" << endl; + // cmess1 << " - <" << scriptName << ">" << endl; - dbo_ptr script = StratusScript::create ( scriptName, NULL ); - script->run (); - } + // dbo_ptr script = StratusScript::create ( scriptName, NULL ); + // script->run (); + // } if ( cell ) { // Python Script test. diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index 8feadae5..03595f35 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -19,7 +19,8 @@ #include #include "hurricane/Warning.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/AllianceFramework.h" #include "crlcore/GraphicToolEngine.h" @@ -36,6 +37,7 @@ namespace Unicorn { using Hurricane::dbo_ptr; using Hurricane::Warning; + using Hurricane::PyCellViewer_Link; using CRL::System; using CRL::Catalog; using CRL::AllianceFramework; @@ -83,8 +85,8 @@ namespace Unicorn { Isobar::Script::addPath( systemConfDir.string() ); dbo_ptr script = Isobar::Script::create( systemConfFile.stem().string() ); - script->setEditor ( this ); - script->runFunction( "unicornConfigure", getCell() ); + script->addKwArgument( "editor" , (PyObject*)PyCellViewer_Link(this) ); + script->runFunction ( "unicornConfigure", getCell() ); Isobar::Script::removePath( systemConfDir.string() ); } else { diff --git a/unicorn/src/init/unicornInit.py b/unicorn/src/init/unicornInit.py index d7025ef1..c16413ac 100644 --- a/unicorn/src/init/unicornInit.py +++ b/unicorn/src/init/unicornInit.py @@ -19,10 +19,10 @@ except Exception, e: sys.exit(2) -def unicornConfigure ( cell=None ): +def unicornConfigure ( **kw ): editor = None - if globals().has_key('__editor'): - editor = __editor + if kw.has_key('editor'): + editor = kw['editor'] else: print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' ) return