Salome HOME
Python3 porting for Examples.
[tools/yacsgen.git] / module_generator / pacocompo.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 *-
3 # Copyright (C) 2009-2016  EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 #  Author : Andre RIBES (EDF R&D)
23
24 """
25   Module that defines PACOComponent for SALOME PaCO++ components implemented in C++
26 """
27 import os
28 from module_generator.gener import Component, Invalid
29 from module_generator.paco_tmpl import compoMakefile, hxxCompo, cxxService
30 from module_generator.paco_tmpl import initService, cxxCompo, paco_sources
31 from module_generator.paco_tmpl import cxxFactoryDummy, cxxFactoryMpi, cxx_des_parallel_stream
32 from module_generator.paco_tmpl import hxxparallel_instream, hxxparallel_outstream, hxxinit_ok
33 from module_generator.paco_tmpl import hxxparallel_instream_init, hxxparallel_outstream_init, cxxService_connect
34 from module_generator.paco_tmpl import cxx_cons_service, cxx_cons_parallel_outstream, cxx_cons_parallel_instream
35 from module_generator.cata_tmpl import parallel_interface
36
37 class PACOComponent(Component):
38
39   def __init__(self, name, parallel_lib, services=None, libs="", rlibs="", includes="", 
40                      kind="lib", exe_path=None, sources=None):
41     self.exe_path = exe_path
42     self.parallel_lib = parallel_lib
43     Component.__init__(self, name, services, impl="PACO", libs=libs, 
44                        rlibs=rlibs, includes=includes, kind=kind,
45                        sources=sources)
46   def validate(self):
47     """ validate component definition parameters"""
48     Component.validate(self)
49     kinds = ("lib")
50     if self.kind not in kinds:
51       raise Invalid("kind must be one of %s for component %s" % (kinds,self.name))
52     parallel_libs = ("dummy", "mpi")
53     if self.parallel_lib not in parallel_libs:
54       raise Invalid("parallel_lib must be one of %s" % parallel_libs)
55
56   def makeCompo(self, gen):
57     """generate files for PaCO++ component
58        
59        return a dict where key is the file name and value is the content of the file
60     """
61     cxxfile = "%s.cxx" % self.name
62     hxxfile = "%s.hxx" % self.name
63     if self.kind == "lib":
64       sources = " ".join(map(os.path.basename, self.sources))
65       sources += " "
66       sources += paco_sources.substitute(module=gen.module.name,
67                                          component=self.name)
68       return {"Makefile.am":compoMakefile.substitute(module=gen.module.name, 
69                                                      component=self.name,
70                                                      libs=self.libs, 
71                                                      rlibs=self.rlibs,
72                                                      sources=sources,
73                                                      includes=self.includes),
74               cxxfile:self.makecxx(gen), 
75               hxxfile:self.makehxx(gen)}
76
77   def makehxx(self, gen):
78     """return a string that is the content of .hxx file
79     """
80     services = []
81     parallel_instream = ""
82     parallel_outstream = ""
83     services_init_ok = ""
84     parallelstreamports = ""
85     for serv in self.services:
86       service = "    void %s(" % serv.name
87       service = service+gen.makeArgs(serv)+");"
88       services.append(service)
89       services_init_ok += hxxinit_ok.substitute(service_name=serv.name)
90
91       # Ajout des ports parallel DataStream
92       for name, type in serv.parallel_instream:
93         parallel_instream += hxxparallel_instream.substitute(name=name,
94                                                              type=type)
95       for name, type in serv.parallel_outstream:
96         parallel_outstream += hxxparallel_outstream.substitute(name=name,
97                                                                type=type)
98     servicesdef = "\n".join(services)
99     parallelstreamports += parallel_instream
100     parallelstreamports += parallel_outstream
101     return hxxCompo.substitute(component=self.name, 
102                                module=gen.module.name, 
103                                servicesdef=servicesdef,
104                                services_init_ok=services_init_ok,
105                                parallelstreamports=parallelstreamports,
106                                parallel_lib=self.parallel_lib)
107
108   def makecxx(self, gen):
109     """return a string that is the content of .cxx file
110     """
111     services = []
112     inits = []
113     defs = []
114     cons_services = ""
115     des_services = ""
116     for serv in self.services:
117       defs.append(serv.defs)
118     
119       # Constructeur
120       cons_services += cxx_cons_service.substitute(service_name=serv.name)
121       for name, type in serv.parallel_instream:
122         cons_services += cxx_cons_parallel_instream.substitute(name=name)
123       for name, type in serv.parallel_outstream:
124         cons_services += cxx_cons_parallel_outstream.substitute(name=name)
125
126       # Destructeur  
127       # On détruit uniquement les ports uses
128       # Les ports provides sont détruit lors de la destruction du poa
129       for name, type in serv.parallel_outstream:
130         des_services += cxx_des_parallel_stream.substitute(name=name)
131
132       # init_service
133       init_parallel_datastream_ports=""
134       for name, type in serv.parallel_instream:
135         init_parallel_datastream_ports += hxxparallel_instream_init.substitute(name=name,
136                                                                                type=type)
137       for name, type in serv.parallel_outstream:
138         init_parallel_datastream_ports += hxxparallel_outstream_init.substitute(name=name,
139                                                                                 type=type)
140       init = initService.substitute(service_name=serv.name,
141                                     init_parallel_datastream_ports=init_parallel_datastream_ports)
142       inits.append(init)
143
144       # Code du service
145       connect_parallel_streamport = ""
146       for name, type in serv.parallel_outstream:
147         connect_parallel_streamport += cxxService_connect.substitute(name=name)
148
149       service = cxxService.substitute(component=self.name, service=serv.name, 
150                                       parameters=gen.makeArgs(serv),
151                                       body=serv.body,
152                                       connect_parallel_streamport=connect_parallel_streamport)
153       services.append(service)
154     
155     cxxfile = cxxCompo.substitute(component=self.name, module=gen.module.name, 
156                                   servicesdef="\n".join(defs), 
157                                   servicesimpl="\n".join(services), 
158                                   initservice='\n'.join(inits),
159                                   cons_services=cons_services,
160                                   des_services=des_services)
161
162     if self.parallel_lib == "dummy":
163       cxxfile += cxxFactoryDummy.substitute(component=self.name, module=gen.module.name)
164     elif self.parallel_lib == "mpi":
165       cxxfile += cxxFactoryMpi.substitute(component=self.name, module=gen.module.name)
166
167     return cxxfile
168
169   def getIdlServices(self):
170     services = []
171     for serv in self.services:
172       params = []
173       for name, typ in serv.inport:
174         if typ == "file":continue #files are not passed through IDL interface
175         params.append("in %s %s" % (idlTypes[typ], name))
176       for name, typ in serv.outport:
177         if typ == "file":continue #files are not passed through IDL interface
178         params.append("out %s %s" % (idlTypes[typ], name))
179       service = "    void %s(" % serv.name
180       service = service+",".join(params)+");"
181       services.append(service)
182     return services
183
184   def getIdlInterfaces(self):
185     services = self.getIdlServices()
186     return parallel_interface.substitute(component=self.name, services="\n".join(services))
187
188   def getIdlDefs(self):
189     idldefs = """
190 #include "SALOME_PACOExtension.idl"
191 """
192     if self.interfacedefs:
193       idldefs = idldefs + self.interfacedefs
194     return idldefs