6 A SALOME component is a CORBA component as described in the previous chapter, using services of the SALOME kernel.
7 This component also has to be “declared” to SALOME (i.e. SALOME resource files need to be supplied or completed with
8 information about this component). The following operations need to be carried out:
11 2. declare the component to the SALOME modules catalog
12 3. modify the implementation class (C++ or python) to
14 - monitor adaptation of the IDL file (point 1)
15 - enable supervision of the component by SALOME, in the different component services
16 - prepare use of the notification service (send messages to monitor execution of calculations in the component) – optional (but useful)
17 4. Declare any graphic resources
24 The IDL description is similar to the description of a standard CORBA component with the following special features:
26 - the component must form part of the basic ``Engines`` module (CORBA)
27 - the component must inherit from the SALOME basic component: ``Engines::EngineComponent`` (defined in the IDL ``“SALOME_Component.idl”`` file)
28 - the services of the component may have ``in``, ``out`` parameters and /or a return value, but no ``inout`` parameters.
32 #. The ``Engines`` module includes all SALOME components other than the SALOME central components
33 #. The ``Engines::EngineComponent`` basic component avoids the need to redefine common services (stop, restart, etc.) for each
34 component added to the system
35 #. This is not a limitation, an ``inout`` parameter can be decoupled into an ``in`` parameter and an ``out``
36 parameter (in any case, this is the form in which python clients will see it).
40 We will reuse the ``alglin.idl`` file and adapt it:
44 .. include:: ./exemples/exemple9/alglin.idl
48 It is important to take care when structures are defined in the IDL (like the ``vecteur`` structure in ``algin.idl``).
49 The chosen name ``vecteur`` might be “reserved” by another SALOME component.
53 Similar modifications are made on the IDL ``FreeFem.idl`` file:
57 .. include:: ./exemples/exemple10/FreeFemComponent.idl
61 Registration into the modules catalog
62 --------------------------------------------
63 Before they can be used in SALOME, components must be registered in one of the SALOME modules catalogs. This catalog is
64 distributed in several files (general catalog, user catalog). It will be assumed that the component will be declared in
65 a user's personal catalog. The component catalog file is an XML file that contains:
67 #. the list of services of the component and their parameters
68 #. the name of the file containing the icon of the component, version information, comments, default service, etc. (this information is optional).
70 This catalog can be completed by hand or a utility supplied by SALOME can be used that generates information in
71 point 1 above (nevertheless, this file must be edited to enter information in point 2). This tool is available in
72 the SALOME graphic interface (``Tools->Catalog Generator`` menu) indicating the name of the catalog (XML file) and
73 the name of the IDL file of the component.
75 C++ implementation class
76 ---------------------------
77 **In this section, it will be assumed that the IDL file defines a CORBA class: A and that the C++ implementation class A_impl will be used.**
79 Making conforming with the component IDL
80 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
81 Proceed as follows to adapt the standard CORBA / C++ implementation classes (as seen in the previous chapter):
83 #. Insert the ``SALOMEconfig.h`` file that contains a number of useful definitions to make the code of the implementation
84 class independent from the CORBA version used::
86 #include <SALOMEconfig.h>
88 #. then insert the ``SALOME_Component_i.hxx`` file that contains the interface of the C++ implementation class of the SALOME basic component::
90 #include "SALOME_Component_i.hxx"
92 #. for the CORBA class that is implemented, add the following line::
94 #include CORBA_SERVER_HEADER(A)
96 ``CORBA_SERVER_HEADER`` is a macro defined in ``SALOMEconfig.h`` that makes CORBA inclusion file names independent
97 from the CORBA implementation used.
99 #. for each CORBA class used in the implementation class, add the following line::
101 #include CORBA_CLIENT_HEADER(<CORBA class name>)
103 ``CORBA_CLIENT_HEADER`` is a macro defined in ``SALOMEconfig.h`` that makes CORBA inclusion file names independent
104 from the CORBA implementation used.
106 #. derive the implementation class from the class of the basic SALOME component::
109 public POA_Engines::A,
110 public Engines_Component_i {
112 #. define the (sole) constructor as follows in the C++ header file (.hxx)::
114 A_impl(CORBA::ORB_ptr orb,
115 PortableServer::POA_ptr poa,
116 PortableServer::ObjectId * contId,
117 const char *instanceName,
118 const char *interfaceName);
120 and in the C++ implementation file (.cxx)::
124 PortableServer::POA_ptr poa,
125 PortableServer::ObjectId * contId,
126 const char *instanceName,
127 const char *interfaceName) :
128 Engines_Component_i(orb, poa, contId,
129 instanceName, interfaceName)
132 _id = _poa->activate_object(_thisObj);
135 This constructor may possibly be responsible for creation and initialisation of the internal object associated with the CORBA component.
137 #. If structures are defined by the IDL file in the Engines module, adapt declarations of the implementation class methods.
139 The above example illustrates the modifications made on example 6.
143 Enable component supervision
144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
145 The following needs to be inserted in each service of the component (i.e. in each method of the implementation class
146 called during a CORBA request), before the component can be controlled from supervision.
148 - at the beginning, the instruction::
150 beginService(<nom du service>);
152 - at the end, the instruction::
154 endService(<nom du service>);
156 These two instructions notify the SALOME supervision that the component service has actually received the CORBA request (beginService)
157 and that execution of the service has actually terminated (endService).
160 Put beginService and endService in the methods of the implementation class of a component declares to SALOME that the component
161 is "supervisable”. This is not an assurance that this component can be used without precautions in the case in which the
162 component has an internal state modified by one or more services.
165 Consider a component with an internal variable ``Quantity`` and two services:
167 * ``S1(x): Quantity = Quantity + x;`` returns ``Quantity`` and
168 * ``S2(x) : Quantity = Quantity * x ;`` returns ``Quantity``.
170 *A priori*, it is impossible to know the value of ``Quantity`` after the calculation graph on the following figure has been executed.
175 .. image:: images/parallele.png
179 Calculation graph containing parallel branches
181 Using the notification
182 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
183 The constructor of the implementation class must be modified as follows, so as to signal use of the notification (that will
184 cause opening of a connection to an events channel)::
188 PortableServer::POA_ptr poa,
189 PortableServer::ObjectId * contId,
190 const char *instanceName,
191 const char *interfaceName) :
192 Engines_Component_i(orb, poa, contId,
193 instanceName, interfaceName, 1)
196 _id = _poa->activate_object(_thisObj);
199 in which the parameter “1” has been added to the end of the call to the ``Engines_Component_i`` of the constructor.
200 The component can then use the instruction::
202 void sendMessage(const char *event_type, const char *message);
204 to send messages indicating progress with the calculation or an abnormal situation, etc. These messages will be visible to the
205 SALOME user. The first parameter indicates the message type (“warning”, “step”, “trace”, “verbose”), and the second parameter
206 indicates the message contents (character string).
208 Connection to the “factory” object of a container
209 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210 A “C” function has to be provided with an imposed name and code, for a component to be loaded and initialised by a container::
214 PortableServer::ObjectId * <nom du composant>Engine_factory(
216 PortableServer::POA_ptr poa,
217 PortableServer::ObjectId * contId,
218 const char *instanceName,
219 const char *interfaceName)
221 <classe d'implementation> * O
222 = new <classe d'implementation>(orb, poa, contId,
223 instanceName, interfaceName);
228 ``<component name>`` (or CORBA class name, ``A`` in this case) and ``<implementation class>`` (``A_impl`` here) are specific
229 to each component. This function is called by the container when a component is loaded. It creates a CORBA object that
230 will receive requests to the component and will forward them to the different services of the component.
232 Example 9 (continued)
233 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
234 We will use the implementation files ``algin_i.hxx`` and ``algin_i.cxx`` again and adapt them:
238 .. include:: ./exemples/exemple9/alglin_i.hxx
244 .. include:: ./exemples/exemple9/alglin_i.cxx
247 Python implementation class
248 ------------------------------
249 **In this section, it is assumed that the IDL file defines a CORBA class: B and that we will use the python implementation class: B.**
251 The procedure is similar to the case of the C++ server interface:
253 Making conforming with the component IDL
254 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
256 #. import the class of the basic component::
258 from SALOME_ComponentPy import *
260 #. derive the implementation class from the class of the basic SALOME component::
262 class B(Engines__POA.B,
263 SALOME_ComponentPy_i):
265 #. The constructor of the implementation class must begin by::
267 def __init__(self, orb, poa, this, containerName,
268 instanceName, interfaceName):
269 SALOME_ComponentPy_i.__init__(self, orb, poa, this,
270 containerName, instanceName,
273 Enable supervision of the component
274 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
275 Before the component can be controlled from supervision, the following have to be inserted in each service of the
276 component (i.e. in each method of the implementation class called during a CORBA request).
278 * at the beginning, the instruction::
280 beginService(<service name>);
282 * at the end, the instruction::
284 endService(<service name>);
286 These two instructions notify the SALOME supervision that the component service has actually received the CORBA
287 request (beginService) and that execution of the service has actually terminated (endService).
288 Same comment as in the C++ case (:ref:`remsuper`).
290 Using the notification
291 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
292 The implementation class constructor should be modified as follows to signal use of the notification::
294 def __init__(self, orb, poa, this, containerName,
295 instanceName, interfaceName):
296 SALOME_ComponentPy_i.__init__(self, orb, poa, this,
297 containerName, instanceName,
300 in which the parameter “1” is added to the end of the call to the ``SALOME_ComponentPy_i`` of the constructor.
301 The component can then use the following instruction::
303 sendMessage(event_type, message);
305 to send messages providing information about progress with the calculation or an abnormal situation, etc.
306 These messages will be visible to the SALOME user. The first parameter indicates the message
307 type (“warning”, “step”, “trace”, “verbose”), and the second parameter indicates the message contents (character string).
310 Example 10 (continued)
311 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
312 Consider the ``FreeFem.py`` implementation file and adapt it:
314 ``FreeFemComponent.py``
316 .. include:: ./exemples/exemple10/FreeFemComponent.py
320 Using the SALOME compilation and execution environment
321 -----------------------------------------------------------------------
322 Autotools like SALOME will be used.
324 Using data structures provided by SALOME or returned by the component
325 ---------------------------------------------------------------------------------------
326 This part will be done with reference to CORBA [CORBA]_ specifications, and particularly IDL specifications – languages [LANG]_
327 or the different CORBA manuals, for example [HENVIN]_ (C++) and [PyCorba]_ (python).
329 Meshes and MED fields
330 ^^^^^^^^^^^^^^^^^^^^^^^
331 This part will be done with reference to MED and MEDMemory documentation [MEDDoc]_ and [MEDMemory]_.