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/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

View File

@ -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<Isobar::Script> 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() );
}

View File

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

View File

@ -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<char*>(_moduleName.c_str()) );
_userModule = PyImport_ImportModule( const_cast<char*>(_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<char*>(function.c_str()));
_pyFunction = PyObject_GetAttrString( _userModule, const_cast<char*>(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<char*>(__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.

View File

@ -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 ();

View File

@ -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<std::string> _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
};

View File

@ -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<string>();
cmess1 << " o Running stratus script:" << endl;
cmess1 << " - <" << scriptName << ">" << endl;
// if ( arguments.count("stratus-script") ) {
// string scriptName = arguments["stratus-script"].as<string>();
// cmess1 << " o Running stratus script:" << endl;
// cmess1 << " - <" << scriptName << ">" << endl;
dbo_ptr<StratusScript> script = StratusScript::create ( scriptName, NULL );
script->run ();
}
// dbo_ptr<StratusScript> script = StratusScript::create ( scriptName, NULL );
// script->run ();
// }
if ( cell ) {
// Python Script test.

View File

@ -19,7 +19,8 @@
#include <QMenu>
#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<Isobar::Script> 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 {

View File

@ -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