Salome HOME
[EDF27816] : fix all non regression tests
[modules/yacs.git] / src / runtime / CppComponent.cxx
1 // Copyright (C) 2006-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "RuntimeSALOME.hxx"
21 #include "CppComponent.hxx"
22 #include "CppContainer.hxx"
23 #include "TypeCode.hxx"
24 #include "CppNode.hxx"
25
26 using namespace YACS::ENGINE;
27  
28 #include <iostream>
29 #include <sstream>
30 #include <cstdlib>
31
32 //#define _DEVDEBUG_
33 #include "YacsTrace.hxx"
34
35 const char CppComponent::KIND[] = "Cpp";
36
37 static std::ostream & operator<<(std::ostream & f, const Any & A)
38 {
39     const TypeCode * t = A.getType();
40     if (NULL == t)
41        f << "(type NULL)";
42     else 
43        switch (t->kind()) {
44          case NONE :
45             f << "(type None)";
46             break;
47          case Double :
48             f << "(type Double) " << A.getDoubleValue();
49             break;
50          case Int :
51             f << "(type Int) " << A.getIntValue();
52             break;
53          case String :
54             f << "(type String) " << A.getStringValue();
55             break;
56          case Bool :
57             f << "(type Bool) " << A.getBoolValue();
58             break;
59          case Objref :
60             f << "(type Objref)";
61             break;
62          case Sequence :
63             f << "(type Sequence) ";
64             {
65               int i;
66               const SequenceAny * sA = dynamic_cast<const SequenceAny *>(&A);
67               for (i=0; i<sA->size(); i++)
68                 f << " " << *((*sA)[i]);
69             }
70             break;
71        }
72     return f;
73 }
74
75 std::string CppComponent::getKind() const
76 {
77   return CppComponent::KIND;
78 }
79
80 std::string CppComponent::getKindForNode() const
81 {
82   return CppComponent::KIND;
83 }
84
85 //! CppComponent constructor
86 CppComponent::CppComponent(const std::string &name) : ComponentInstance(name), __obj(0), __run(0),__terminate(0)
87 {
88   _container = getRuntime()->createContainer(CppNode::KIND);
89   /* This part of code has been commented because the load part is supposed to do that !
90   if (!_container->isAlreadyStarted(0))
91     _container->start(0);
92   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);
93   _containerC->createInternalInstance(name, __obj, __run, __terminate);*/
94 }
95
96 //! CppComponent copy constructor
97 CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._compoName), __obj(0), __run(0),__terminate(0)
98 {
99   _container = getRuntime()->createContainer(CppNode::KIND);
100   /* This part of code has been commented because the load part is supposed to do that !
101   if (!_container->isAlreadyStarted(0))
102     _container->start(0);
103   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);  
104    _containerC->createInternalInstance(_compoName, __obj, __run, __terminate);*/
105 }
106
107 CppComponent::~CppComponent()
108 {
109   DEBTRACE("CppComponent::~CppComponent()");
110   if (__terminate) __terminate(&__obj);
111   if (_container)
112     ((CppContainer *) _container)->unregisterComponentInstance(this);
113 }
114
115 void CppComponent::run (const char * service, int nbIn, int nbOut,
116                         Any ** argIn, Any ** argOut)
117 {
118   int i;
119   returnInfo return_code;
120     
121 #ifdef _DEVDEBUG_
122   std::ostringstream sDebug;
123   sDebug << getInstanceName() << "::" << service << "(";
124   for (i=0; i<nbIn; i++) {
125      sDebug << *(argIn[i]);
126      if (i<nbIn-1)
127         sDebug << ", ";
128   }
129   sDebug << ")";
130 #endif
131
132   __run(__obj, service, nbIn, nbOut, argIn, argOut, &return_code);
133     
134   if (return_code.code != 0) {
135 #ifdef _DEVDEBUG_
136     std::cerr << sDebug << " ???" << std::endl;
137 #endif
138     throw YACS::Exception(return_code.message);
139   }
140
141 #ifdef _DEVDEBUG_
142   if (nbOut > 0) {
143     sDebug << "->";
144     for (i=0; i<nbOut; i++) {
145        sDebug << " " << *(argOut[i]);
146     }
147   }
148   DEBTRACE(sDebug.str());
149 #endif
150 }
151
152 //! Unload the component 
153 void CppComponent::unload(Task *askingNode)
154 {
155   //Not implemented
156   DEBTRACE("CppComponent::unload : not implemented ");
157 }
158
159 //! Is the component instance already loaded ?
160 bool CppComponent::isLoaded(Task *askingNode) const
161 {
162   return NULL != __obj;
163 }
164  
165 void CppComponent::load(Task *askingNode)
166 {
167   if (!_container)
168     {
169       _container = getRuntime()->createContainer(CppNode::KIND);
170     }
171
172   if(_container)
173     {
174       CppContainer *containerC(dynamic_cast< CppContainer *> (_container));
175       if(!containerC)
176         throw Exception("The type of container should be CPP for component CPP !");
177       containerC->lock();//To be sure
178       if(!_container->isAlreadyStarted(askingNode))
179         {
180           try
181           {
182               _container->start(askingNode);
183           }
184           catch(Exception& e)
185           {
186               containerC->unLock();
187               throw e;
188           }
189         }
190       containerC->unLock();
191       containerC->lock();//To be sure
192
193       bool isLoadable(containerC->loadComponentLibrary(_compoName));
194       if (isLoadable) 
195         containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
196
197       if(NULL == __obj)
198         {
199           containerC->unLock();
200           throw Exception("CppComponent::load : Error while trying to create a new component.");
201         }
202       containerC->unLock();
203       return;
204     }
205 }
206
207 ServiceNode* CppComponent::createNode(const std::string& name)
208 {
209    CppNode* node=new CppNode(name);
210    node->setComponent(this);
211    return node;
212 }
213
214 //! Clone the component instance
215 ComponentInstance* CppComponent::clone() const
216 {
217   if(_isAttachedOnCloning)
218     {
219       incrRef();
220       return (ComponentInstance*) (this);
221     }
222   else
223     return new CppComponent(*this);
224 }
225
226 YACS::ENGINE::ComponentInstance *CppComponent::cloneAlways() const
227 {
228   return new CppComponent(*this);
229 }