Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / runtime / CppComponent.cxx
1 #include "RuntimeSALOME.hxx"
2 #include "CppComponent.hxx"
3 #include "CppContainer.hxx"
4 #include "TypeCode.hxx"
5 #include "CppNode.hxx"
6 #include "DynLibLoader.hxx"
7
8 using namespace YACS::ENGINE;
9  
10 #include <iostream>
11 #include <sstream>
12 #include <cstdlib>
13
14 //#define _DEVDEBUG_
15 #include "YacsTrace.hxx"
16
17 const char CppComponent::KIND[] = "Cpp";
18
19 static std::ostream & operator<<(std::ostream & f, const Any & A)
20 {
21     const TypeCode * t = A.getType();
22     if (NULL == t)
23        f << "(type NULL)";
24     else 
25        switch (t->kind()) {
26          case NONE :
27             f << "(type None)";
28             break;
29          case Double :
30             f << "(type Double) " << A.getDoubleValue();
31             break;
32          case Int :
33             f << "(type Int) " << A.getIntValue();
34             break;
35          case String :
36             f << "(type String) " << A.getStringValue();
37             break;
38          case Bool :
39             f << "(type Bool) " << A.getBoolValue();
40             break;
41          case Objref :
42             f << "(type Objref)";
43             break;
44          case Sequence :
45             f << "(type Sequence) ";
46             {
47               int i;
48               const SequenceAny * sA = dynamic_cast<const SequenceAny *>(&A);
49               for (i=0; i<sA->size(); i++)
50                       f << " " << *((*sA)[i]);
51             }
52             break;
53        }
54     return f;
55 }
56
57 std::string CppComponent::getKind() const
58 {
59    return CppComponent::KIND;
60 }
61
62 //! CppComponent constructor
63 CppComponent::CppComponent(const std::string &name) : ComponentInstance(name)
64 {
65   _container = getRuntime()->createContainer(CppNode::KIND);
66   if (!_container->isAlreadyStarted())
67           _container->start();
68   
69   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);
70   _containerC->createInternalInstance(name, __obj, __run, __terminate);
71 }
72
73 //! CppComponent copy constructor
74 CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._compoName), __run(other.__run),
75                                                         __terminate(other.__terminate), __obj(0)
76 {
77   _container = getRuntime()->createContainer(CppNode::KIND);
78   if (!_container->isAlreadyStarted())
79     _container->start();
80
81   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);  
82    _containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
83 }
84
85 CppComponent::~CppComponent()
86 {
87     DEBTRACE("CppComponent::~CppComponent()");
88     if (__terminate) __terminate(&__obj);
89     if (_container)
90         ((CppContainer *) _container)->unregisterComponentInstance(this);
91 }
92
93 void CppComponent::run (const char * service, int nbIn, int nbOut,
94                                                  Any ** argIn, Any ** argOut) throw (YACS::Exception)
95 {
96   int i;
97   returnInfo return_code;
98     
99 #ifdef _DEVDEBUG_
100   std::ostringstream sDebug;
101   sDebug << _name << "::" << service << "(";
102   for (i=0; i<nbIn; i++) {
103      sDebug << *(argIn[i]);
104      if (i<nbIn-1)
105         sDebug << ", ";
106   }
107   sDebug << ")";
108 #endif
109
110   __run(__obj, service, nbIn, nbOut, argIn, argOut, &return_code);
111     
112   if (return_code.code != 0) {
113 #ifdef _DEVDEBUG_
114     std::cerr << sDebug << " ???" << std::endl;
115 #endif
116     throw YACS::Exception(return_code.message);
117   }
118
119 #ifdef _DEVDEBUG_
120   if (nbOut > 0) {
121     sDebug << "->";
122     for (i=0; i<nbOut; i++) {
123        sDebug << " " << *(argOut[i]);
124     }
125   }
126   DEBTRACE(sDebug.str());
127 #endif
128 }
129
130 //! Unload the component 
131 void CppComponent::unload()
132 {
133   //Not implemented
134   DEBTRACE("CppComponent::unload : not implemented ");
135 }
136
137 //! Is the component instance already loaded ?
138 bool CppComponent::isLoaded()
139 {
140   return NULL != __obj;
141 }
142  
143 void CppComponent::load()
144 {
145    if (!_container) {
146            _container = getRuntime()->createContainer(CppNode::KIND);
147    }
148    
149    if(_container) {
150                 
151       CppContainer * containerC= dynamic_cast< CppContainer *> (_container);
152       
153       containerC->lock();//To be sure
154       if(!_container->isAlreadyStarted())
155         {
156           try
157             {
158               _container->start();
159             }
160           catch(Exception& e)
161             {
162               containerC->unLock();
163               throw e;
164             }
165         }
166       containerC->unLock();
167       containerC->lock();//To be sure
168       
169       YACS::BASES::DynLibLoader D(_compoName + "Local");
170       
171       bool isLoadable = containerC->loadComponentLibrary(_compoName);
172       if (isLoadable) 
173         containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
174         
175       if(NULL == __obj)
176         {
177           containerC->unLock();
178           throw Exception("CppComponent::load : Error while trying to create a new component.");
179         }
180       containerC->unLock();
181       return;
182     }
183         
184 }
185
186 ServiceNode* CppComponent::createNode(const std::string& name)
187 {
188    CppNode* node=new CppNode(name);
189    node->setComponent(this);
190    return node;
191 }
192
193 //! Clone the component instance
194 ComponentInstance* CppComponent::clone() const
195 {
196   if(_isAttachedOnCloning)
197     {
198       incrRef();
199       return (ComponentInstance*) (this);
200     }
201   else
202     return new CppComponent(*this);
203 }
204