From: vsr Date: Fri, 12 Nov 2010 15:20:11 +0000 (+0000) Subject: Merge from V5_1_5_BR branch 12/11/2010 X-Git-Tag: RELIQUAT_5x_15112010~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ea0fb36d237a6499ca60cbce9691c5ecc3ea9c7c;p=tools%2Fyacsgen.git Merge from V5_1_5_BR branch 12/11/2010 --- diff --git a/Examples/ast2/coupling.xml b/Examples/ast2/coupling.xml index 3625fc7..0a541cb 100644 --- a/Examples/ast2/coupling.xml +++ b/Examples/ast2/coupling.xml @@ -1,147 +1,164 @@ - - - - - - - - - - - 23 - - - - - caster - s1 - - - - - - - - - - - - - - - - - - - - cfort - s1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -node1ba -node2a - - -node1bb -node2b - - -node2ba -node1aa - - -node2bb -node1ab - - -node2bc -node1ac - - -node2bd -node1ad - - -node2be -node1ae - - -node2bf -node1af - - -node2bg -node1ag - - - - node1fort:8 - dataout f1 - - - node1d - node98 p1 - - - datainf1 - node2 a - - - - node1 a - 23 - - - node1 b - 23 - - - node1 c - hello - - - - node2 b - 23 - - - node2 c - hello - - - - node1 jdc - f.comm - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + caster + + s1 + + + + + + + + + + + + + + + + + + cfort + + s1 + + + + + + + + + + + + + + + + + + + + + + + + datain node2 + node1 node98 + node1 dataout + + datain f1 + node2 a + + + node1 fort:8 + dataout f1 + + + node1 d + node98 p1 + + + node1 ba + node2 a + + + node1 bb + node2 b + + + node2 ba + node1 aa + + + node2 bb + node1 ab + + + node2 bc + node1 ac + + + node2 bd + node1 ad + + + node2 be + node1 ae + + + node2 bf + node1 af + + + node2 bg + node1 ag + + + node1jdc + f.comm + + + node1a + 23 + + + node1b + 23 + + + node1c + hello + + + node2b + 23 + + + node2c + hello + + + + + + + - diff --git a/Examples/ast2/myaster/src/op0189.f b/Examples/ast2/myaster/src/op0189.f index 9c669bd..79bc96f 100644 --- a/Examples/ast2/myaster/src/op0189.f +++ b/Examples/ast2/myaster/src/op0189.f @@ -62,9 +62,9 @@ C COMMON/YACS/IFL include 'calcium.hf' real*8 tt,tp,t0,t1,ss,zz - real yr + real*4 yr CHARACTER*8 tch(2) - real tcp(2) + real*4 tcp(2) integer*4 tlo(3) write(6,*) '--> OP196 ' diff --git a/Examples/cpp1/coupling.xml b/Examples/cpp1/coupling.xml index 07b3a26..bf6dbfc 100644 --- a/Examples/cpp1/coupling.xml +++ b/Examples/cpp1/coupling.xml @@ -1,63 +1,73 @@ - - - - - - - - - - - - - - compo1 - s1 - - - - - - - - - - compo1 - s1 - - - - - - - - - - - node1ba - node2aa - - - node2ba - node1aa - - - - node1 a - 23 - - - node1 b - 53 - - - node2 a - 63 - - - node2 b - 73 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + compo1 + + s1 + + + + + + + + compo1 + + s1 + + + + + + + + node1 ba + node2 aa + + + node2 ba + node1 aa + + + node1a + 23 + + + node1b + 53 + + + node2a + 63 + + + node2b + 73 + + + + - diff --git a/Examples/cppgui1/components.py b/Examples/cppgui1/components.py index 43cd326..0fc17ea 100644 --- a/Examples/cppgui1/components.py +++ b/Examples/cppgui1/components.py @@ -21,7 +21,74 @@ execfile("../context.py") import os -from module_generator import Generator,Module,Service,CPPComponent +from module_generator import * + +idldefs=""" +#include "myinterface.idl" +""" + +compodefs=r""" + + +class A: public virtual POA_Idl_A +{ +public: + void createObject(::SALOMEDS::Study_ptr theStudy, const char* name){}; + + // Driver interface + virtual SALOMEDS::TMPFile* Save(SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile){return 0;}; + virtual SALOMEDS::TMPFile* SaveASCII(SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile){return 0;}; + virtual bool Load(SALOMEDS::SComponent_ptr theComponent, const SALOMEDS::TMPFile& theStream, const char* theURL, bool isMultiFile){return 0;}; + virtual bool LoadASCII(SALOMEDS::SComponent_ptr theComponent, const SALOMEDS::TMPFile& theStream, const char* theURL, bool isMultiFile){return 0;}; + virtual void Close(SALOMEDS::SComponent_ptr IORSComponent){}; + virtual char* ComponentDataType(){return "cppcompos";}; + virtual char* IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject, const char* IORString, CORBA::Boolean isMultiFile, CORBA::Boolean isASCII){return 0;}; + virtual char* LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject, const char* aLocalPersistentID, CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII){return 0;}; + virtual bool CanPublishInStudy(CORBA::Object_ptr theIOR){return 0;}; + virtual SALOMEDS::SObject_ptr PublishInStudy(SALOMEDS::Study_ptr theStudy,SALOMEDS::SObject_ptr theSObject,CORBA::Object_ptr theObject, + const char* theName){return 0;}; + virtual CORBA::Boolean CanCopy(SALOMEDS::SObject_ptr theObject){return 0;}; + virtual SALOMEDS::TMPFile* CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID){return 0;}; + virtual CORBA::Boolean CanPaste(const char* theComponentName, CORBA::Long theObjectID){return 0;}; + virtual SALOMEDS::SObject_ptr PasteInto(const SALOMEDS::TMPFile& theStream, CORBA::Long theObjectID, SALOMEDS::SObject_ptr theObject){return 0;}; +}; + +""" + +compomethods=r""" + + Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean& isValidScript) + { + std::cerr << "je suis dans le dump:" << __LINE__ << std::endl; + SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy); + if(CORBA::is_nil(aStudy)) + return new Engines::TMPFile(0); + + SALOMEDS::SObject_var aSO = aStudy->FindComponent("cppcompos"); + if(CORBA::is_nil(aSO)) + return new Engines::TMPFile(0); + + std::string Script = "import cppcompos_ORB\n"; + Script += "import salome\n"; + Script += "compo = salome.lcc.FindOrLoadComponent('FactoryServer','cppcompos')\n"; + Script += "def RebuildData(theStudy):\n"; + Script += " compo.SetCurrentStudy(theStudy)\n"; + const char* aScript=Script.c_str(); + + char* aBuffer = new char[strlen(aScript)+1]; + strcpy(aBuffer, aScript); + CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; + int aBufferSize = strlen(aBuffer)+1; + Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1); + isValidScript = true; + return aStreamFile._retn(); + } + + +""" body=""" std::cerr << "a: " << a << std::endl; @@ -29,18 +96,24 @@ std::cerr << "b: " << b << std::endl; c=a+b; std::cerr << "c: " << c << std::endl; """ -c1=CPPComponent("compo1",services=[ +c1=CPPComponent("cppcompos",services=[ Service("s1",inport=[("a","double"),("b","double")], outport=[("c","double")], defs="//def1",body=body, ), ], includes="-I/usr/include", + idls=["*.idl"], + interfacedefs=idldefs, + inheritedinterface="Idl_A", + compodefs=compodefs, + inheritedclass="A", + addedmethods=compomethods, ) modul=Module("cppcompos",components=[c1],prefix="./install", doc=["*.rst",], - gui=["cppcomposGUI.cxx","cppcomposGUI.h","Makefile.am","demo.ui","*.png"], + gui=["cppcomposGUI.cxx","cppcomposGUI.h","demo.ui","*.png"], ) g=Generator(modul,context) diff --git a/Examples/cppgui1/cppcomposGUI.cxx b/Examples/cppgui1/cppcomposGUI.cxx index 0c2bfcb..47df890 100644 --- a/Examples/cppgui1/cppcomposGUI.cxx +++ b/Examples/cppgui1/cppcomposGUI.cxx @@ -2,7 +2,14 @@ #include #include #include +#include #include +#include + +#include +#include CORBA_CLIENT_HEADER(cppcompos) +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) // QT Includes #include @@ -23,12 +30,17 @@ cppcomposGUI::cppcomposGUI() : { } +static cppcompos_ORB::cppcompos_var engine; + // Module's initialization void cppcomposGUI::initialize( CAM_Application* app ) { SalomeApp_Module::initialize( app ); + Engines::Component_var comp = dynamic_cast(app)->lcc()->FindOrLoad_Component( "FactoryServer","cppcompos" ); + engine = cppcompos_ORB::cppcompos::_narrow(comp); + QWidget* aParent = application()->desktop(); SUIT_ResourceMgr* aResourceMgr = app->resourceMgr(); @@ -48,6 +60,14 @@ void cppcomposGUI::initialize( CAM_Application* app ) createTool( 902, aToolId ); } +// Get compatible dockable windows. +void cppcomposGUI::windows( QMap& theMap ) const +{ + theMap.clear(); + theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea ); + theMap.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); +} + // Module's engine IOR QString cppcomposGUI::engineIOR() const { @@ -62,6 +82,25 @@ bool cppcomposGUI::activateModule( SUIT_Study* theStudy ) setMenuShown( true ); setToolShown( true ); + SALOME_NamingService *aNamingService = SalomeApp_Application::namingService(); + CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject); + SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id()); + + SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent("cppcompos"); + if (aFather->_is_nil()) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = aDSStudy->NewBuilder(); + aFather = aStudyBuilder->NewComponent("cppcompos"); + SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName"); + SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); + aName->SetValue("cppcompos"); + aName->Destroy(); + aStudyBuilder->DefineComponentInstance(aFather, engine); + } + CORBA::Boolean valid; + engine->DumpPython(aDSStudy,1,valid); + return bOk; } @@ -83,6 +122,9 @@ void cppcomposGUI::OnGetBanner() if ( ok && !myName.isEmpty()) { + ::CORBA::Double c; + engine->s1(1.,2.,c); + std::cerr << c << std::endl; QString banner = "Hello " + myName; SUIT_MessageBox::information( getApp()->desktop(), "info", banner, "OK" ); } diff --git a/Examples/cppgui1/cppcomposGUI.h b/Examples/cppgui1/cppcomposGUI.h index a9f5abc..e722eb6 100644 --- a/Examples/cppgui1/cppcomposGUI.h +++ b/Examples/cppgui1/cppcomposGUI.h @@ -12,6 +12,7 @@ public: cppcomposGUI(); void initialize( CAM_Application* ); QString engineIOR() const; + virtual void windows( QMap& theMap ) const; public slots: bool deactivateModule( SUIT_Study* ); diff --git a/Examples/cppgui1/myinterface.idl b/Examples/cppgui1/myinterface.idl new file mode 100644 index 0000000..16207a9 --- /dev/null +++ b/Examples/cppgui1/myinterface.idl @@ -0,0 +1,8 @@ +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" + +interface Idl_A : SALOMEDS::Driver +{ + void createObject(in SALOMEDS::Study theStudy, in string name) raises (SALOME::SALOME_Exception); +}; + diff --git a/Examples/fort1/coupling.xml b/Examples/fort1/coupling.xml index c3d4ef8..8c0e551 100644 --- a/Examples/fort1/coupling.xml +++ b/Examples/fort1/coupling.xml @@ -1,59 +1,67 @@ - - - - - - - - - - - - - - fcode1 - serv1 - - - - - - - - - fcode2 - serv1 - - - - - - - - - - - node1PARAM - node2PARAM - - - - node1 a - 23 - - - node1 b - 53 - - - node2 a - 63 - - - node2 b - 73 - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + fcode1 + + serv1 + + + + + + + fcode2 + + serv1 + + + + + + + node1 PARAM + node2 PARAM + + + node1a + 23 + + + node1b + 53 + + + node2a + 63 + + + node2b + 73 + + + + - diff --git a/Examples/pygui1/components.py b/Examples/pygui1/components.py index f10274b..1ca7ac3 100644 --- a/Examples/pygui1/components.py +++ b/Examples/pygui1/components.py @@ -22,7 +22,7 @@ import os #import context from .. execfile("../context.py") -from module_generator import Generator,Module,Service,PYComponent +from module_generator import * defs=""" """ @@ -31,16 +31,79 @@ body=""" c=a+b d=a-b """ -c1=PYComponent("compo2",services=[ + +idldefs=""" +#include "myinterface.idl" +""" + +compodefs=r""" +import SALOME_DriverPy +import traceback + +class A(SALOME_DriverPy.SALOME_DriverPy_i): + def __init__(self): + SALOME_DriverPy.SALOME_DriverPy_i.__init__(self,"pycompos") + return + + def createObject( self, study, name ): + "Create object. " + try: + print study,name + builder = study.NewBuilder() + father = study.FindComponent( "pycompos" ) + if father is None: + father = builder.NewComponent( "pycompos" ) + attr = builder.FindOrCreateAttribute( father, "AttributeName" ) + attr.SetValue( "pycompos" ) + + object = builder.NewObject( father ) + attr = builder.FindOrCreateAttribute( object, "AttributeName" ) + attr.SetValue( name ) + except: + traceback.print_exc() + + def DumpPython( self, study, isPublished ): + abuffer = [] + abuffer.append( "def RebuildData( theStudy ):" ) + names = [] + father = study.FindComponent( "pycompos" ) + if father: + iter = study.NewChildIterator( father ) + while iter.More(): + name = iter.Value().GetName() + if name: names.append( name ) + iter.Next() + pass + pass + if names: + abuffer += [ " from salome import lcc" ] + abuffer += [ " import pycompos_ORB" ] + abuffer += [ " " ] + abuffer += [ " compo = lcc.FindOrLoadComponent( 'FactoryServerPy', 'pycompos' )" ] + abuffer += [ " " ] + abuffer += [ " compo.createObject( theStudy, '%s' )" % name for name in names ] + pass + abuffer += [ " " ] + + return ("\n".join( abuffer ), 1) + +""" + +c1=PYComponent("pycompos",services=[ Service("s1",inport=[("a","double"),("b","double")], outport=[("c","double"),("d","double")], defs=defs,body=body, ), ], + idls=["*.idl"], + interfacedefs=idldefs, + inheritedinterface="Idl_A", + compodefs=compodefs, + inheritedclass="A", ) modul=Module("pycompos",components=[c1],prefix="./install", - doc=["*.rst",], + doc=["*.rst","*.png"], gui=["pycomposGUI.py","demo.ui","*.png"], ) diff --git a/Examples/pygui1/myinterface.idl b/Examples/pygui1/myinterface.idl new file mode 100644 index 0000000..16207a9 --- /dev/null +++ b/Examples/pygui1/myinterface.idl @@ -0,0 +1,8 @@ +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" + +interface Idl_A : SALOMEDS::Driver +{ + void createObject(in SALOMEDS::Study theStudy, in string name) raises (SALOME::SALOME_Exception); +}; + diff --git a/Examples/pygui1/pycomposGUI.py b/Examples/pygui1/pycomposGUI.py index 933665f..f57dd52 100644 --- a/Examples/pygui1/pycomposGUI.py +++ b/Examples/pygui1/pycomposGUI.py @@ -5,10 +5,34 @@ from PyQt4.QtGui import * from PyQt4.QtWebKit import * from PyQt4 import QtCore, QtGui, uic +import salome +import pycompos_ORB + # Get SALOME PyQt interface import SalomePyQt sgPyQt = SalomePyQt.SalomePyQt() +# Get SALOME Swig interface +import libSALOME_Swig +sg = libSALOME_Swig.SALOMEGUI_Swig() + +# object counter +__objectid__ = 0 + +### +# get active study ID +### +def _getStudyId(): + return sgPyQt.getStudyId() + +### +# get active study +### +def _getStudy(): + studyId = _getStudyId() + study = salome.myStudyManager.GetStudyByID( studyId ) + return study + # called when module is initialized # return map of popup windows to be used by the module def windows(): @@ -36,12 +60,38 @@ def activate(): a = sgPyQt.createAction( 942, "Hello2", "Hello2", "Show hello2 dialog box" ,"exec.png") sgPyQt.createMenu( a, mid ) sgPyQt.createTool( a, tid ) + a = sgPyQt.createAction( 943, "Create object", "Create object", "Create object","exec.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + return True # called when module is deactivated def deactivate(): pass +_engine=None +def getEngine(): + global _engine + if not _engine: + _engine= salome.lcc.FindOrLoadComponent( "FactoryServerPy", "pycompos" ) + return _engine + +### +# Create new object +### +def CreateObject(): + global __objectid__ + default_name = str( sgPyQt.stringSetting( "pycompos", "def_obj_name", "Object" ).trimmed() ) + # generate object name + __objectid__ = __objectid__ + 1 + name = "%s_%d" % ( default_name, __objectid__ ) + if not name: return + getEngine().createObject( _getStudy(), name ) + print getEngine().s1(4,5) + print getEngine().ComponentDataType() + sg.updateObjBrowser( True ) + class DemoImpl(QtGui.QDialog): def __init__(self, *args): super(DemoImpl, self).__init__(*args) @@ -69,5 +119,7 @@ def OnGUIEvent( commandID ): widget = DemoImpl(sgPyQt.getDesktop()) widget.show() + elif commandID==943: + CreateObject() diff --git a/Examples/pygui1/using.rst b/Examples/pygui1/using.rst index f28347d..8321bf3 100644 --- a/Examples/pygui1/using.rst +++ b/Examples/pygui1/using.rst @@ -15,3 +15,6 @@ The Object Browser is in a tab, with tree_view Other ---------- +.. image:: exec.png + :align: center + diff --git a/Examples/pyth1/coupling.xml b/Examples/pyth1/coupling.xml index cd9b441..7c95f94 100644 --- a/Examples/pyth1/coupling.xml +++ b/Examples/pyth1/coupling.xml @@ -1,65 +1,75 @@ - - - - - - - - - - - - - - compo2 - s1 - - - - - - - - - - - compo2 - s1 - - - - - - - - - - - - node1ba - node2aa - - - node2ba - node1aa - - - - node1 a - 23 - - - node1 b - 53 - - - node2 a - 63 - - - node2 b - 73 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + compo2 + + s1 + + + + + + + + + compo2 + + s1 + + + + + + + + + node1 ba + node2 aa + + + node2 ba + node1 aa + + + node1a + 23 + + + node1b + 53 + + + node2a + 63 + + + node2b + 73 + + + + - diff --git a/module_generator/__init__.py b/module_generator/__init__.py index dcfbd53..e79531f 100644 --- a/module_generator/__init__.py +++ b/module_generator/__init__.py @@ -18,9 +18,9 @@ # """ - Package to generate SALOME modules with components - implemented in C++, Fortran or Python - that can use datastream ports +The python module module_generator defines classes which can be used to define a SALOME module, its components and +generates a SALOME source module, its installation and a SALOME application including this module and +other preexisting SALOME modules like GEOM, SMESH or others. """ from gener import Module, Service, Generator from fcompo import F77Component diff --git a/module_generator/astcompo.py b/module_generator/astcompo.py index 879501b..cb99fcf 100644 --- a/module_generator/astcompo.py +++ b/module_generator/astcompo.py @@ -36,6 +36,30 @@ from aster_tmpl import comm, make_etude, cexe, exeaster from aster_tmpl import container, component class ASTERComponent(Component): + """ + A :class:`ASTERComponent` instance represents an ASTER SALOME component (special component for Code_Aster that is a mix of + Fortran and Python code) with services given as a list of :class:`Service` instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + :param aster_dir: gives the Code_Aster installation directory. + :param python_path: If it is given (as a list of paths), all the paths are added to the python path (sys.path). + :param argv: is a list of strings that gives the command line parameters for Code_Aster. This parameter is only useful when + kind is "lib". + + For example, the following call defines a Code_Aster component named "mycompo" with one service s1 (it must have been defined before). + This standalone component takes some command line arguments:: + + >>> c1 = module_generator.ASTERComponent('mycompo', services=[s1,], kind="exe", + exe_path="launch.sh", + argv=["-memjeveux","4"]) + """ def __init__(self, name, services=None, libs="", rlibs="", aster_dir="", python_path=None, argv=None, kind="lib", exe_path=None): """initialise component attributes""" diff --git a/module_generator/aster_tmpl.py b/module_generator/aster_tmpl.py index 3922590..80c255a 100644 --- a/module_generator/aster_tmpl.py +++ b/module_generator/aster_tmpl.py @@ -24,7 +24,7 @@ except: asterCompo=""" import sys,traceback,os -import ${module}__POA +import ${module}_ORB__POA import calcium import dsccalcium import SALOME @@ -48,11 +48,11 @@ except: ${servicesdef} #ENDDEF -class ${component}(${module}__POA.${component},dsccalcium.PyDSCComponent,SUPERV): +class ${component}(${module}_ORB__POA.${component},dsccalcium.PyDSCComponent,SUPERV): ''' To be identified as a SALOME component this Python class must have the same name as the component, inherit omniorb - class ${module}__POA.${component} and DSC class dsccalcium.PyDSCComponent + class ${module}_ORB__POA.${component} and DSC class dsccalcium.PyDSCComponent that implements DSC API. ''' def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ): @@ -78,7 +78,7 @@ asterCompo=Template(asterCompo) asterCEXECompo=""" import sys,traceback,os import string -import ${module}__POA +import ${module}_ORB__POA import calcium import dsccalcium import SALOME @@ -97,11 +97,11 @@ ${servicesdef} class ExecutionError(Exception): '''General exception during execution''' -class ${component}(${module}__POA.${component},dsccalcium.PyDSCComponent,SUPERV): +class ${component}(${module}_ORB__POA.${component},dsccalcium.PyDSCComponent,SUPERV): ''' To be identified as a SALOME component this Python class must have the same name as the component, inherit omniorb - class ${module}__POA.${component} and DSC class dsccalcium.PyDSCComponent + class ${module}_ORB__POA.${component} and DSC class dsccalcium.PyDSCComponent that implements DSC API. ''' def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ): diff --git a/module_generator/cata_tmpl.py b/module_generator/cata_tmpl.py index 1c4c7a1..c8feeff 100644 --- a/module_generator/cata_tmpl.py +++ b/module_generator/cata_tmpl.py @@ -36,7 +36,7 @@ idl=""" ${idldefs} -module ${module} +module ${module}_ORB { typedef sequence stringvec; typedef sequence dblevec; @@ -51,7 +51,7 @@ ${interfaces} idl=Template(idl) interface=""" - interface ${component}:Engines::Superv_Component + interface ${component}:${inheritedinterface} Engines::Superv_Component { ${services} }; @@ -96,22 +96,21 @@ xml_service = Template(xml_service) idlMakefile=""" include $$(top_srcdir)/adm_local/make_common_starter.am -BUILT_SOURCES = ${module}SK.cc ${PACO_BUILT_SOURCES} -IDL_FILES=${module}.idl +BUILT_SOURCES = ${module}SK.cc ${PACO_BUILT_SOURCES} ${other_sks} +IDL_FILES=${module}.idl ${other_idls} -lib_LTLIBRARIES = lib${module}.la +lib_LTLIBRARIES = libSalomeIDL${module}.la salomeidl_DATA = $$(IDL_FILES) ${PACO_salomeidl_DATA} -salomepython_DATA = ${module}_idl.py ${PACO_salomepython_DATA} -lib${module}_la_SOURCES = -nodist_lib${module}_la_SOURCES = ${module}SK.cc +libSalomeIDL${module}_la_SOURCES = +nodist_libSalomeIDL${module}_la_SOURCES = ${module}SK.cc ${other_sks} nodist_salomeinclude_HEADERS= ${module}.hh ${PACO_SALOMEINCLUDE_HEADERS} -lib${module}_la_CXXFLAGS = -I. $$(SALOME_INCLUDES) -lib${module}_la_LIBADD = $$(SALOME_IDL_LIBS) +libSalomeIDL${module}_la_CXXFLAGS = -I. $$(SALOME_INCLUDES) +libSalomeIDL${module}_la_LIBADD = $$(SALOME_IDL_LIBS) ########################################################## %SK.cc %.hh : %.idl -\t$$(OMNIORB_IDL) -bcxx $$(IDLCXXFLAGS) $$(OMNIORB_IDLCXXFLAGS) $$(IDL_INCLUDES) $$< +\t$$(OMNIORB_IDL) -bcxx $$(OMNIORB_IDLCXXFLAGS) $$(IDL_INCLUDES) $$< %_idl.py : %.idl -\t$$(OMNIORB_IDL) -bpython $$(IDL_INCLUDES) ${PACO_INCLUDES} $$< +\t$$(OMNIORB_IDL) $$(OMNIORB_IDLPYFLAGS) $$(IDL_INCLUDES) ${PACO_INCLUDES} $$< %PaCO.hxx %PaCO.cxx : %.idl %.xml \t$$(OMNIORB_IDL) -I@KERNEL_ROOT_DIR@/idl/salome -p@PACOPATH@/lib/python -bpaco -Wb$$(top_srcdir)/idl/$$*.xml,$$(srcdir):@PACOPATH@/idl:@KERNEL_ROOT_DIR@/idl/salome $$(top_srcdir)/idl/$$*.idl @@ -119,16 +118,15 @@ CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx EXTRA_DIST = $$(IDL_FILES) -clean-local: -\trm -rf ${module} ${module}__POA - -install-data-local: -\t$${mkinstalldirs} $$(DESTDIR)$$(salomepythondir) -\tcp -R ${module} ${module}__POA $$(DESTDIR)$$(salomepythondir) +install-data-local: $$(IDL_FILES) +\t$$(INSTALL) -d $$(DESTDIR)$$(salomepythondir) +\tls $$^ | while read file; do \\ +\t$$(OMNIORB_IDL) $$(OMNIORB_IDLPYFLAGS) $$(IDL_INCLUDES) -C$$(DESTDIR)$$(salomepythondir) $$$$file ; \\ +\tdone uninstall-local: -\trm -rf $$(DESTDIR)$$(salomepythondir)/${module} -\trm -rf $$(DESTDIR)$$(salomepythondir)/${module}__POA +\trm -rf $$(DESTDIR)$$(salomepythondir)/* + """ idlMakefile=Template(idlMakefile) diff --git a/module_generator/cpp_tmpl.py b/module_generator/cpp_tmpl.py index 4979bfa..eadcce2 100644 --- a/module_generator/cpp_tmpl.py +++ b/module_generator/cpp_tmpl.py @@ -235,7 +235,7 @@ extern "C" Engines::Container_var container = Engines::Container::_narrow(obj); ${component}_i * myEngine = new ${component}_i(orb, poa, container, instanceName.c_str(), "${component}"); pman->activate(); - obj=myEngine->_this(); + obj=myEngine->POA_${module}_ORB::${component}::_this(); Engines::Component_var component = Engines::Component::_narrow(obj); string component_registerName = containerName + "/" + instanceName; salomens->Register(component,component_registerName.c_str()); @@ -276,9 +276,8 @@ hxxCompo=""" ${compodefs} //ENDDEF -class ${component}_i: ${inheritedclass} - public virtual POA_${module}::${component}, - public virtual Superv_Component_i +class ${component}_i: public virtual POA_${module}_ORB::${component}, + ${inheritedclass} public virtual Superv_Component_i { public: ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, @@ -402,7 +401,7 @@ lib${component}Engine_la_SOURCES = ${component}.cxx ${sources} nodist_lib${component}Engine_la_SOURCES = lib${component}Engine_la_CXXFLAGS = -I$$(top_builddir)/idl $$(SALOME_INCLUDES) ${includes} lib${component}Engine_la_FFLAGS = $$(SALOME_INCLUDES) -fexceptions ${includes} -lib${component}Engine_la_LIBADD = ${libs} -L$$(top_builddir)/idl -l${module} $${SALOME_LIBS} $$(FLIBS) +lib${component}Engine_la_LIBADD = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${module} $${SALOME_LIBS} $$(FLIBS) lib${component}Engine_la_LDFLAGS = ${rlibs} """ compoMakefile=Template(compoMakefile) @@ -412,7 +411,7 @@ lib${component}Exelib_la_SOURCES = ${component}.cxx nodist_lib${component}Exelib_la_SOURCES = lib${component}Exelib_la_CXXFLAGS = -I$$(top_builddir)/idl $$(SALOME_INCLUDES) ${includes} lib${component}Exelib_la_FFLAGS = $$(SALOME_INCLUDES) -fexceptions ${includes} -lib${component}Exelib_la_LIBADD = ${libs} -L$$(top_builddir)/idl -l${module} $${SALOME_LIBS} $$(FLIBS) +lib${component}Exelib_la_LIBADD = ${libs} -L$$(top_builddir)/idl -lSalomeIDL${module} $${SALOME_LIBS} $$(FLIBS) lib${component}Exelib_la_LDFLAGS = ${rlibs} """ compoEXEMakefile=Template(compoEXEMakefile) diff --git a/module_generator/cppcompo.py b/module_generator/cppcompo.py index 8c0819c..3fef424 100644 --- a/module_generator/cppcompo.py +++ b/module_generator/cppcompo.py @@ -28,14 +28,47 @@ from cpp_tmpl import exeCPP, compoEXEMakefile, compoMakefile from yacstypes import corba_rtn_type class CPPComponent(Component): - def __init__(self, name, services=None, libs="", rlibs="", includes="", - kind="lib", exe_path=None, sources=None, inheritedclass="", - compodefs=""): + """ + A :class:`CPPComponent` instance represents a C++ SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param includes: gives all the include options to add when compiling the generated component (-I...). + :param sources: gives all the external source files to add in the compilation step (list of paths). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + :param compodefs: can be used to add extra definition code in the component for example when using a base class + to define the component class by deriving it (see *inheritedclass* parameter) + :param inheritedclass: can be used to define a base class for the component. The base class can be defined in external + source or with the *compodefs* parameter. The value of the *inheritedclass* parameter is the name of the base class. + :param idls: can be used to add extra idl CORBA interfaces to the component. This parameter must gives a list of idl file + names that are added into the generated module (idl directory) and compiled with the generated idl of the module. + :param interfacedefs: can be used to add idl definitions (or includes of idl files) into the generated idl of the module. + :param inheritedinterface: can be used to make the component inherit an extra idl interface that has been included through + the *idls* and *interfacedefs* parameters. See the cppgui1 example for how to use these last parameters. + :param addmethods: is a C++ specific parameter that can be used to redefine a component method (DumpPython for example). This + parameter is a string that must contain the definition and implementation code of the method. See the cppgui1 example + for how to use it. + + For example, the following call defines a standalone component named "mycompo" with one service s1 (it must have been defined before):: + + >>> c1 = module_generator.CPPComponent('mycompo', services=[s1,], kind="exe", + exe_path="./launch.sh") + """ + def __init__(self, name, services=None, libs="", rlibs="", includes="", kind="lib", + exe_path=None, sources=None, inheritedclass="", compodefs="", + idls=None,interfacedefs="",inheritedinterface="",addedmethods=""): self.exe_path = exe_path - Component.__init__(self, name, services, impl="CPP", libs=libs, - rlibs=rlibs, includes=includes, kind=kind, - sources=sources,inheritedclass=inheritedclass, - compodefs=compodefs) + Component.__init__(self, name, services, impl="CPP", libs=libs, rlibs=rlibs, + includes=includes, kind=kind, sources=sources, + inheritedclass=inheritedclass, compodefs=compodefs, idls=idls, + interfacedefs=interfacedefs, inheritedinterface=inheritedinterface, + addedmethods=addedmethods) def validate(self): """ validate component definition parameters""" @@ -102,6 +135,9 @@ AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions service = " %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),serv.name) service = service+gen.makeArgs(serv)+");" services.append(service) + + if self.addedmethods: + services.append(self.addedmethods) servicesdef = "\n".join(services) inheritedclass=self.inheritedclass diff --git a/module_generator/fcompo.py b/module_generator/fcompo.py index 55d2baf..c466fe3 100644 --- a/module_generator/fcompo.py +++ b/module_generator/fcompo.py @@ -29,6 +29,27 @@ else: f77Types = {"double":"double *", "long":"long *", "string":"const char *"} class F77Component(CPPComponent): + """ + A :class:`F77Component` instance represents a Fortran SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param sources: gives all the external source files to add in the compilation step (list of paths). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + + For example, the following call defines a Fortran component named "mycompo" with one service s1 (it must have been defined before). + This component is implemented as a dynamic library linked with a user's library "mylib":: + + >>> c1 = module_generator.F77Component('mycompo', services=[s1,], + libs="-lmylib -Lmydir") + + """ def __init__(self, name, services=None, libs="", rlibs="", kind="lib", exe_path=None, sources=None): CPPComponent.__init__(self, name, services, libs=libs, rlibs=rlibs, diff --git a/module_generator/gener.py b/module_generator/gener.py index fe88916..4fc94e5 100644 --- a/module_generator/gener.py +++ b/module_generator/gener.py @@ -61,6 +61,35 @@ def makedirs(namedir): os.makedirs(namedir) class Module(object): + """ + A :class:`Module` instance represents a SALOME module that contains components given as a list of + component instances (:class:`CPPComponent` or :class:`PYComponent` or :class:`F77Component` or :class:`ASTERComponent`) + with the parameter *components*. + + :param name: gives the name of the module. The SALOME source module + will be located in the directory. + :type name: str + :param components: gives the list of components of the module. + :param prefix: is the path of the installation directory. + :param layout: If given and has the value "monodir", all components + will be generated in a single directory. The default is to generate each component in its + own directory. + :param doc: can be used to add an online documentation to the module. It must be a list of file names (sources, images, ...) that will be + used to build a sphinx documentation (see http://sphinx.pocoo.org, for more information). If not given, the Makefile.am + and the conf.py (sphinx configuration) files are generated. In this case, the file name extension of source files must be .rst. + See small examples in Examples/pygui1 and Examples/cppgui1. + :param gui: can be used to add a GUI to the module. It must be a list of file names (sources, images, qt designer files, ...). + If not given, the Makefile.am and SalomeApp.xml are generated. All image files are put in the resources directory of the module. + The GUI can be implemented in C++ (file name extension '.cxx') or in Python (file name extension '.py'). + See small examples in Examples/pygui1 and Examples/cppgui1. + + For example, the following call defines a module named "mymodule" with 2 components c1 and c2 (they must have been + defined before) that will be installed in the "install" directory:: + + >>> m = module_generator.Module('mymodule', components=[c1,c2], + prefix="./install") + + """ def __init__(self, name, components=None, prefix="",layout="multidir", doc=None, gui=None): self.name = name self.components = components or [] @@ -94,7 +123,8 @@ class Module(object): class Component(object): def __init__(self, name, services=None, impl="PY", libs="", rlibs="", includes="", kind="lib", sources=None, - inheritedclass="",compodefs=""): + inheritedclass="",compodefs="", + idls=None,interfacedefs="",inheritedinterface="",addedmethods=""): self.name = name self.impl = impl self.kind = kind @@ -105,6 +135,10 @@ class Component(object): self.sources = sources or [] self.inheritedclass=inheritedclass self.compodefs=compodefs + self.idls=idls + self.interfacedefs=interfacedefs + self.inheritedinterface=inheritedinterface + self.addedmethods=addedmethods def validate(self): if self.impl not in ValidImpl: @@ -129,8 +163,40 @@ class Component(object): return {} class Service(object): - def __init__(self, name, inport=None, outport=None, ret="void", instream=None, - outstream=None, parallel_instream=None, parallel_outstream=None, body="", defs="", impl_type="sequential"): + """ + A :class:`Service` instance represents a component service with dataflow and datastream ports. + + :param name: gives the name of the service. + :type name: str + :param inport: gives the list of input dataflow ports. + :param outport: gives the list of output dataflow ports. An input or output dataflow port is defined + by a 2-tuple (port name, data type name). The list of supported basic data types is: "double", "long", "string", + "dblevec", "stringvec", "intvec", "file" and "pyobj" only for Python services. Depending on the implementation + language, it is also possible to use some types from SALOME modules (see :ref:`yacstypes`). + :param ret: gives the type of the return parameter + :param instream: gives the list of input datastream ports. + :param outstream: gives the list of output datastream ports. An input or output datastream port is defined + by a 3-tuple (port name, data type name, mode name). The list of possible data types is: "CALCIUM_double", "CALCIUM_integer", + "CALCIUM_real", "CALCIUM_string", "CALCIUM_complex", "CALCIUM_logical", "CALCIUM_long". The mode can be "I" (iterative mode) + or "T" (temporal mode). + :param defs: gives the source code to insert in the definition section of the component. It can be C++ includes + or Python imports + :type defs: str + :param body: gives the source code to insert in the service call. It can be any C++ + or Python code that fits well in the body of the service method. + :type body: str + + For example, the following call defines a minimal Python service with one input dataflow port (name "a", type double) + and one input datastream port:: + + >>> s1 = module_generator.Service('myservice', inport=[("a","double"),], + instream=[("aa","CALCIUM_double","I")], + body="print a") + + + """ + def __init__(self, name, inport=None, outport=None, ret="void", instream=None, outstream=None, + parallel_instream=None, parallel_outstream=None, defs="", body="", impl_type="sequential"): self.name = name self.inport = inport or [] self.outport = outport or [] @@ -170,7 +236,7 @@ class Service(object): if name in lports: raise Invalid("%s is already defined as a stream port" % name) lports.add(name) - + for port in self.parallel_instream: name, typ = self.validateParallelStream(port) if name in lports: @@ -225,6 +291,19 @@ class Service(object): return name, typ class Generator(object): + """ + A :class:`Generator` instance take a :class:`Module` instance as its first parameter and can be used to generate the + SALOME source module, builds it, installs it and includes it in a SALOME application. + + :param module: gives the :class:`Module` instance that will be used for the generation. + :param context: If given , its content is used to specify the prerequisites + environment file (key *"prerequisites"*) and the SALOME KERNEL installation directory (key *"kernel"*). + :type context: dict + + For example, the following call creates a generator for the module m:: + + >>> g = module_generator.Generator(m,context) + """ def __init__(self, module, context=None): self.module = module self.context = context or {} @@ -236,7 +315,7 @@ class Generator(object): raise Invalid("To generate a module with GUI, you need to set the 'gui' parameter in the context dictionnary") def generate(self): - """generate SALOME module as described by module attribute""" + """Generate a SALOME source module""" module = self.module namedir = module.name+"_SRC" force = self.context.get("force") @@ -409,12 +488,24 @@ echo " Qt ..................... : $qt_ok" other_require=other_require, ) + #if components have other idls + other_idls="" + other_sks="" + for compo in module.components: + if compo.idls: + for idl in compo.idls: + for fidl in glob.glob(idl): + other_idls=other_idls+os.path.basename(fidl) +" " + other_sks=other_sks+os.path.splitext(os.path.basename(fidl))[0]+"SK.cc " + idlfiles={"Makefile.am": idlMakefile.substitute(module=module.name, PACO_BUILT_SOURCES=PACO_BUILT_SOURCES, PACO_SALOMEINCLUDE_HEADERS=PACO_SALOMEINCLUDE_HEADERS, PACO_INCLUDES=PACO_INCLUDES, PACO_salomepython_DATA=PACO_salomepython_DATA, - PACO_salomeidl_DATA=PACO_salomeidl_DATA), + PACO_salomeidl_DATA=PACO_salomeidl_DATA, + other_idls=other_idls,other_sks=other_sks, + ), idlfile : self.makeidl(), } if paco: @@ -433,6 +524,12 @@ echo " Qt ..................... : $qt_ok" else: shutil.copyfile(src, os.path.join(namedir, "src", os.path.basename(src))) + if compo.idls: + #copy provided idl files in idl directory + for idl in compo.idls: + for fidl in glob.glob(idl): + shutil.copyfile(fidl, os.path.join(namedir, "idl", os.path.basename(fidl))) + for m4file in ("check_Kernel.m4", "check_omniorb.m4", "ac_linker_options.m4", "ac_cxx_option.m4", "python.m4", "enable_pthreads.m4", "check_f77.m4", @@ -440,6 +537,7 @@ echo " Qt ..................... : $qt_ok" "check_mpi.m4", "check_lam.m4", "check_openmpi.m4", "check_mpich.m4"): shutil.copyfile(os.path.join(self.kernel, "salome_adm", "unix", "config_files", m4file), os.path.join(namedir, "adm_local", m4file)) + if self.module.gui: for m4file in ("check_GUI.m4", "check_qt.m4", "check_opengl.m4"): shutil.copyfile(os.path.join(self.gui, "adm_local", "unix", "config_files", m4file), @@ -617,7 +715,9 @@ echo " Qt ..................... : $qt_ok" service = " void %s(" % serv.name service = service+",".join(params)+");" services.append(service) + interfaces.append(parallel_interface.substitute(component=compo.name, services="\n".join(services))) + else: services = [] for serv in compo.services: @@ -639,21 +739,29 @@ echo " Qt ..................... : $qt_ok" service = " %s %s(" % (idlTypes[serv.ret],serv.name) service = service+",".join(params)+") raises (SALOME::SALOME_Exception);" services.append(service) + from hxxcompo import HXX2SALOMEComponent if isinstance(compo,HXX2SALOMEComponent): from hxx_tmpl import interfaceidlhxx - Inherited="" - if compo.use_medmem==True: - Inherited=", SALOME_MED::MED_Gen_Driver" + Inherited="" + if compo.use_medmem==True: + Inherited=", SALOME_MED::MED_Gen_Driver" interfaces.append(interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services))) else: - interfaces.append(interface.substitute(component=compo.name, services="\n".join(services))) + inheritedinterface="" + if compo.inheritedinterface: + inheritedinterface=compo.inheritedinterface+"," + interfaces.append(interface.substitute(component=compo.name, services="\n".join(services),inheritedinterface=inheritedinterface)) #build idl includes for SALOME modules idldefs="" for mod in self.used_modules: idldefs = idldefs + salome_modules[mod]["idldefs"] + for compo in self.module.components: + if compo.interfacedefs: + idldefs = idldefs + compo.interfacedefs + return idl.substitute(module=self.module.name, interfaces='\n'.join(interfaces),idldefs=idldefs) # For PaCO++ @@ -687,13 +795,13 @@ echo " Qt ..................... : $qt_ok" self.makeFiles(content, filename) def bootstrap(self): - """execute module autogen.sh script: execution of libtool, autoconf, automake""" + """Execute the first build step (bootstrap autotools with autogen.sh script) : execution of libtool, autoconf, automake""" ier = os.system("cd %s_SRC;sh autogen.sh" % self.module.name) if ier != 0: raise Invalid("bootstrap has ended in error") def configure(self): - """execute module configure script with installation prefix (prefix attribute of module)""" + """Execute the second build step (configure) with installation prefix as given by the prefix attribute of module""" prefix = self.module.prefix paco = self.context.get("paco") mpi = self.context.get("mpi") @@ -714,7 +822,7 @@ echo " Qt ..................... : $qt_ok" raise Invalid("configure has ended in error") def make(self): - """execute module Makefile : make""" + """Execute the third build step (compile and link) : make""" make_command = "make " if self.makeflags: make_command += self.makeflags @@ -723,14 +831,39 @@ echo " Qt ..................... : $qt_ok" raise Invalid("make has ended in error") def install(self): - """install module: make install """ + """Execute the installation step : make install """ makedirs(self.module.prefix) ier = os.system("cd %s_SRC;make install" % self.module.name) if ier != 0: raise Invalid("install has ended in error") def make_appli(self, appliname, restrict=None, altmodules=None, resources=""): - """generate SALOME application""" + """ + Create a SALOME application containing the module and preexisting SALOME modules. + + :param appliname: is a string that gives the name of the application (directory path where the application + will be installed). + :type appliname: str + :param restrict: If given (a list of module names), only those SALOME modules will be included in the + application. The default is to include all modules that are located in the same directory as the KERNEL module and have + the same suffix (for example, if KERNEL directory is KERNEL_V5 and GEOM directory is GEOM_V5, GEOM module is automatically + included, except if restrict is used). + :param altmodules: can be used to add SALOME modules that cannot be managed with the precedent rule. This parameter + is a dict with a module name as the key and the installation path as the value. + :param resources: can be used to define an alternative resources catalog (path of the file). + + For example, the following calls create a SALOME application with external modules and resources catalog in "appli" directory:: + + >>> g=Generator(m,context) + >>> g.generate() + >>> g.bootstrap() + >>> g.configure() + >>> g.make() + >>> g.install() + >>> g.make_appli("appli", restrict=["KERNEL"], altmodules={"GUI":GUI_ROOT_DIR, "YACS":YACS_ROOT_DIR}, + resources="myresources.xml") + + """ makedirs(appliname) rootdir, kerdir = os.path.split(self.kernel) diff --git a/module_generator/gui_tmpl.py b/module_generator/gui_tmpl.py index 74f2964..2cc897b 100644 --- a/module_generator/gui_tmpl.py +++ b/module_generator/gui_tmpl.py @@ -36,7 +36,7 @@ BUILT_SOURCES=${uisources} lib_LTLIBRARIES= lib${module}.la lib${module}_la_SOURCES = ${sources} lib${module}_la_CPPFLAGS = $$(SALOME_INCLUDES) $$(GUI_CXXFLAGS) $$(QT_INCLUDES) -I$$(top_builddir)/idl -lib${module}_la_LIBADD = -L$$(top_builddir)/idl -l${module} +lib${module}_la_LIBADD = -L$$(top_builddir)/idl -lSalomeIDL${module} salomeres_DATA =SalomeApp.xml ${other_sources} diff --git a/module_generator/pycompo.py b/module_generator/pycompo.py index 411c936..3e6953d 100644 --- a/module_generator/pycompo.py +++ b/module_generator/pycompo.py @@ -35,13 +35,40 @@ def indent(text, prefix=' '): return join(lines, '\n') class PYComponent(Component): - def __init__(self, name, services=None, python_path=None, kind="lib", - sources=None, inheritedclass="", compodefs=""): + """ + A :class:`PYComponent` instance represents a Python SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (python executable). The default is to build the component as a python module. + :param sources: gives all the external Python source files to add in the component directory (list of paths). + :param python_path: If it is given (as a list of paths), all the paths are added to the python path (sys.path). + :param compodefs: can be used to add extra definition code in the component for example when using a base class + to define the component class by deriving it (see *inheritedclass* parameter) + :param inheritedclass: can be used to define a base class for the component. The base class can be defined in external + source or with the *compodefs* parameter. The value of the *inheritedclass* parameter is the name of the base class. + :param idls: can be used to add extra idl CORBA interfaces. This parameter must gives a list of idl file names that are + added into the generated module (idl directory) and compiled with the generated idl of the module. + :param interfacedefs: can be used to add idl definitions (or includes of idl files) into the generated idl of the module. + :param inheritedinterface: can be used to make the component inherit an extra idl interface that has been included through + the *idls* and *interfacedefs* parameters. See the pygui1 example for how to use these last parameters. + + For example, the following call defines a Python component named "mycompo" with one service s1 (it must have been defined before):: + + >>> c1 = module_generator.PYComponent('mycompo', services=[s1,], + python_path="apath") + + """ + def __init__(self, name, services=None, kind="lib", sources=None, python_path=None, + compodefs="", inheritedclass="", idls=None, interfacedefs="", inheritedinterface=""): """initialise component attributes""" self.python_path = python_path or [] - Component.__init__(self, name, services, impl="PY", kind=kind, - sources=sources, inheritedclass=inheritedclass, - compodefs=compodefs) + Component.__init__(self, name, services, impl="PY", kind=kind, sources=sources, + inheritedclass=inheritedclass, compodefs=compodefs, + idls=idls,interfacedefs=interfacedefs,inheritedinterface=inheritedinterface) def validate(self): """validate component attributes""" diff --git a/module_generator/pyth_tmpl.py b/module_generator/pyth_tmpl.py index 4996d6d..e88595b 100644 --- a/module_generator/pyth_tmpl.py +++ b/module_generator/pyth_tmpl.py @@ -25,7 +25,7 @@ except: pyCompo=""" import sys,traceback,os sys.path=sys.path+[${python_path}] -import ${module}__POA +import ${module}_ORB__POA import calcium import dsccalcium import SALOME @@ -45,11 +45,11 @@ ${compodefs} ${servicesdef} #ENDDEF -class ${component}(${inheritedclass} ${module}__POA.${component},dsccalcium.PyDSCComponent): +class ${component}(${module}_ORB__POA.${component}, ${inheritedclass} dsccalcium.PyDSCComponent): ''' To be identified as a SALOME component this Python class must have the same name as the component, inherit omniorb - class ${module}__POA.${component} and DSC class dsccalcium.PyDSCComponent + class ${module}_ORB__POA.${component} and DSC class dsccalcium.PyDSCComponent that implements DSC API. ''' def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ): diff --git a/module_generator/yacstypes.py b/module_generator/yacstypes.py index e0cd355..8aa90f1 100644 --- a/module_generator/yacstypes.py +++ b/module_generator/yacstypes.py @@ -23,40 +23,42 @@ corbaTypes = {"double":"CORBA::Double", "long":"CORBA::Long", "string":"const char*", "dblevec":"const %s::dblevec&", "stringvec":"const %s::stringvec&", "intvec":"const %s::intvec&", - "file":None, "boolean":"CORBA::Boolean", "void":"void" + "file":None, "boolean":"CORBA::Boolean", "void":"void" } corbaOutTypes = {"double":"CORBA::Double&", "long":"CORBA::Long&", "string":"CORBA::String_out", "dblevec":"%s::dblevec_out", "stringvec":"%s::stringvec_out", "intvec":"%s::intvec_out", - "file":None, "boolean":"CORBA::Boolean_out", "void":None + "file":None, "boolean":"CORBA::Boolean_out", "void":None } +moduleTypes = {"double":"", "long":"", "string":"", "dblevec":"", "stringvec":"", "intvec":"", "file":"", "pyobj":"", "boolean":"", "void":"" } + +idlTypes = {"double":"double", "long":"long", "string":"string", "dblevec":"dblevec", "stringvec":"stringvec", "intvec":"intvec", + "file":"", "boolean":"boolean", "void":"void" } corbaRtnTypes = {"double":"CORBA::Double", "long":"CORBA::Long", "string":"char*", "dblevec":"%s::dblevec*", "stringvec":"%s::stringvec*", "intvec":"%s::intvec*", - "file":None, "boolean":"CORBA::Boolean", "void":"void" + "file":None, "boolean":"CORBA::Boolean", "void":"void" } -moduleTypes = {"double":"", "long":"", "string":"", "dblevec":"", "stringvec":"", "intvec":"", "file":"", "boolean":"", "void":"" } -idlTypes = {"double":"double", "long":"long", "string":"string", "dblevec":"dblevec", "stringvec":"stringvec", "intvec":"intvec", "file":"", "boolean":"boolean", "void":"void" } def corba_in_type(typ, module): if corbaTypes[typ].count("%s")>0: - return corbaTypes[typ] % module + return corbaTypes[typ] % (module+"_ORB") else: return corbaTypes[typ] def corba_out_type(typ, module): if corbaOutTypes[typ].count("%s")>0: - return corbaOutTypes[typ] % module + return corbaOutTypes[typ] % (module+"_ORB") else: return corbaOutTypes[typ] def corba_rtn_type(typ, module): if corbaRtnTypes[typ].count("%s")>0: - return corbaRtnTypes[typ] % module + return corbaRtnTypes[typ] % (module+"_ORB") else: return corbaRtnTypes[typ] diff --git a/setup.py b/setup.py index 6bc29e7..d71293d 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ from distutils.core import setup setup(name='YACSGEN', - version='5.1.4', + version='5.1.5', author='C. Caremoli', packages=['module_generator'], )