Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / runtime / CppComponent.cxx
1 //  Copyright (C) 2006-2008  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.
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 #include "RuntimeSALOME.hxx"
20 #include "CppComponent.hxx"
21 #include "CppContainer.hxx"
22 #include "TypeCode.hxx"
23 #include "CppNode.hxx"
24 #include "DynLibLoader.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 //! CppComponent constructor
81 CppComponent::CppComponent(const std::string &name) : ComponentInstance(name)
82 {
83   _container = getRuntime()->createContainer(CppNode::KIND);
84   if (!_container->isAlreadyStarted())
85           _container->start();
86   
87   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);
88   _containerC->createInternalInstance(name, __obj, __run, __terminate);
89 }
90
91 //! CppComponent copy constructor
92 CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._compoName), __run(other.__run),
93                                                         __terminate(other.__terminate), __obj(0)
94 {
95   _container = getRuntime()->createContainer(CppNode::KIND);
96   if (!_container->isAlreadyStarted())
97     _container->start();
98
99   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);  
100    _containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
101 }
102
103 CppComponent::~CppComponent()
104 {
105     DEBTRACE("CppComponent::~CppComponent()");
106     if (__terminate) __terminate(&__obj);
107     if (_container)
108         ((CppContainer *) _container)->unregisterComponentInstance(this);
109 }
110
111 void CppComponent::run (const char * service, int nbIn, int nbOut,
112                                                  Any ** argIn, Any ** argOut) throw (YACS::Exception)
113 {
114   int i;
115   returnInfo return_code;
116     
117 #ifdef _DEVDEBUG_
118   std::ostringstream sDebug;
119   sDebug << _name << "::" << service << "(";
120   for (i=0; i<nbIn; i++) {
121      sDebug << *(argIn[i]);
122      if (i<nbIn-1)
123         sDebug << ", ";
124   }
125   sDebug << ")";
126 #endif
127
128   __run(__obj, service, nbIn, nbOut, argIn, argOut, &return_code);
129     
130   if (return_code.code != 0) {
131 #ifdef _DEVDEBUG_
132     std::cerr << sDebug << " ???" << std::endl;
133 #endif
134     throw YACS::Exception(return_code.message);
135   }
136
137 #ifdef _DEVDEBUG_
138   if (nbOut > 0) {
139     sDebug << "->";
140     for (i=0; i<nbOut; i++) {
141        sDebug << " " << *(argOut[i]);
142     }
143   }
144   DEBTRACE(sDebug.str());
145 #endif
146 }
147
148 //! Unload the component 
149 void CppComponent::unload()
150 {
151   //Not implemented
152   DEBTRACE("CppComponent::unload : not implemented ");
153 }
154
155 //! Is the component instance already loaded ?
156 bool CppComponent::isLoaded()
157 {
158   return NULL != __obj;
159 }
160  
161 void CppComponent::load()
162 {
163    if (!_container) {
164            _container = getRuntime()->createContainer(CppNode::KIND);
165    }
166    
167    if(_container) {
168                 
169       CppContainer * containerC= dynamic_cast< CppContainer *> (_container);
170       
171       containerC->lock();//To be sure
172       if(!_container->isAlreadyStarted())
173         {
174           try
175             {
176               _container->start();
177             }
178           catch(Exception& e)
179             {
180               containerC->unLock();
181               throw e;
182             }
183         }
184       containerC->unLock();
185       containerC->lock();//To be sure
186       
187       YACS::BASES::DynLibLoader D(_compoName + "Local");
188       
189       bool isLoadable = containerC->loadComponentLibrary(_compoName);
190       if (isLoadable) 
191         containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
192         
193       if(NULL == __obj)
194         {
195           containerC->unLock();
196           throw Exception("CppComponent::load : Error while trying to create a new component.");
197         }
198       containerC->unLock();
199       return;
200     }
201         
202 }
203
204 ServiceNode* CppComponent::createNode(const std::string& name)
205 {
206    CppNode* node=new CppNode(name);
207    node->setComponent(this);
208    return node;
209 }
210
211 //! Clone the component instance
212 ComponentInstance* CppComponent::clone() const
213 {
214   if(_isAttachedOnCloning)
215     {
216       incrRef();
217       return (ComponentInstance*) (this);
218     }
219   else
220     return new CppComponent(*this);
221 }
222