source: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template_impl.hpp @ 1848

Last change on this file since 1848 was 1848, checked in by ymipsl, 22 months ago

Supress unusefull idServer context variable that create some trouble when sending context attribute to server.

YM

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 16.9 KB
Line 
1#ifndef __XIOS_CObjectTemplate_impl__
2#define __XIOS_CObjectTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "context_client.hpp"
6#include "object_factory.hpp"
7#include "context.hpp"
8#include "buffer_in.hpp"
9#include "attribute.hpp"
10#include "event_client.hpp"
11#include "object_template.hpp"
12#include "context_client.hpp"
13#include "indent.hpp"
14#include "type_util.hpp"
15#include "message.hpp"
16#include "type.hpp"
17#include "type_util.hpp"
18#include "group_template.hpp"
19
20namespace xios
21{
22   /// ////////////////////// Définitions ////////////////////// ///
23   template <class T>
24      xios_map<StdString,
25      xios_map<StdString,
26      std::shared_ptr<T> > > CObjectTemplate<T>::AllMapObj;
27
28   template <class T>
29      xios_map<StdString,
30      std::vector<std::shared_ptr<T> > > CObjectTemplate<T>::AllVectObj;
31
32   template <class T>
33      xios_map<StdString,long int> CObjectTemplate<T>::GenId;
34
35   template <class T>
36      CObjectTemplate<T>::CObjectTemplate(void)
37         : CAttributeMap()
38         , CObject()
39   { /* Ne rien faire de plus */ }
40
41   template <class T>
42      CObjectTemplate<T>::CObjectTemplate(const StdString & id)
43         : CAttributeMap()
44         , CObject(id, CObjectFactory::IsGenUId<T>(id))
45   { /* Ne rien faire de plus */ }
46
47   template <class T>
48      CObjectTemplate<T>::CObjectTemplate
49         (const CObjectTemplate<T> & object, bool withAttrList, bool withId)
50         : CAttributeMap()
51         , CObject()
52   {
53      if (object.hasId() && withId)
54         this->setId(object.getId(), object.hasAutoGeneratedId());
55      ERROR("CObjectTemplate<T> construtor 3", << "Not completly implemented yet !");
56   }
57
58   template <class T>
59      CObjectTemplate<T>::~CObjectTemplate(void)
60   { /* Ne rien faire de plus */ }
61
62   ///--------------------------------------------------------------
63
64   template <class T>
65      std::vector<std::shared_ptr<T> > &
66         CObjectTemplate<T>::GetAllVectobject(const StdString & contextId)
67   {
68      return (CObjectTemplate<T>::AllVectObj[contextId]);
69   }
70
71   //---------------------------------------------------------------
72
73   template <class T>
74      StdString CObjectTemplate<T>::toString(void) const
75   {
76      StdOStringStream oss;
77      oss << "<" << T::GetName();
78      if (this->hasId())
79         oss << " id=\"" << this->getId() << "\"";
80      oss << " " << SuperClassMap::toString() << "/>";
81      return (oss.str());
82   }
83
84   template <class T>
85      void CObjectTemplate<T>::fromString(const StdString & str)
86   {
87      ERROR("CObjectTemplate<T>::fromString(str)",
88            << "[ str = " << str << "] Not implemented yet !");
89   }
90
91   //---------------------------------------------------------------
92
93/*
94   template <class T>
95      void CObjectTemplate<T>::toBinary(StdOStream & os) const
96   {
97      SuperClassMap::toBinary(os);
98   }
99
100   template <class T>
101      void CObjectTemplate<T>::fromBinary(StdIStream & is)
102   {
103      SuperClassMap::fromBinary(is);
104   }
105*/
106
107   //---------------------------------------------------------------
108
109   template <class T>
110      void CObjectTemplate<T>::parse(xml::CXMLNode & node)
111   TRY
112   {
113      xml::THashAttributes attributes = node.getAttributes();
114      CAttributeMap::setAttributes(attributes);
115   }
116   CATCH
117
118   //---------------------------------------------------------------
119
120   template <class T>
121      ENodeType CObjectTemplate<T>::getType(void) const
122   {
123      return (T::GetType());
124   }
125
126   template <class T>
127   string CObjectTemplate<T>::getName(void) const
128   {
129      return (T::GetName());
130   }
131
132   //---------------------------------------------------------------
133
134   template <class T>
135      bool CObjectTemplate<T>::hasChild(void) const
136   {
137      return (false);
138   }
139
140   /*!
141     Compare two object of same type
142   */
143   template <class T>
144   bool CObjectTemplate<T>::isEqual(const string& id, const vector<StdString>& excludedAttrs)
145   {
146      T* obj = CObjectTemplate<T>::get(id);
147      return this->isEqual(obj, excludedAttrs);
148   }
149
150   template <class T>
151   bool CObjectTemplate<T>::isEqual(T* obj, const vector<StdString>& excludedAttrs)
152   {
153
154      CAttributeMap& attrMapThis = *this;
155      CAttributeMap& attrMapObj  = *obj;
156      return (attrMapThis.isEqual(attrMapObj, excludedAttrs));
157   }
158
159   //---------------------------------------------------------------
160
161   template <class T>
162      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
163   {
164      if (parent != NULL)
165         SuperClassMap::setAttributes(parent, apply);
166   }
167
168   //---------------------------------------------------------------
169
170   template <class T>
171      void CObjectTemplate<T>::ClearAllAttributes(void)
172   {
173      vector<T*> avect = CObjectTemplate<T>::getAll();
174      typename vector<T*>::iterator
175            it = avect.begin(), end = avect.end();
176
177      for (;it != end; it++)
178      {
179         CAttributeMap & amap = **it;
180         amap.clearAllAttributes();
181      }
182   }
183
184   template<typename T>
185   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes(CContextClient* client)
186   {
187     std::map<int, size_t> minimumSizes;
188
189     if (client->isServerLeader())
190     {
191       size_t minimumSize = 0;
192       CAttributeMap& attrMap = *this;
193       CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
194       for (; it != itE; ++it)
195       {
196         if (!it->second->isEmpty())
197         {
198           size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
199           if (size > minimumSize)
200             minimumSize = size;
201         }
202       }
203
204       if (minimumSize)
205       {
206         // Account for extra header info
207         minimumSize += CEventClient::headerSize + getId().size() + sizeof(size_t);
208
209         const std::list<int>& ranks = client->getRanksServerLeader();
210         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
211           minimumSizes.insert(std::make_pair(*itRank, minimumSize));
212       }
213     }
214     return minimumSizes;
215   }
216
217   template<typename T>
218   void CObjectTemplate<T>::sendAllAttributesToServer(CContextClient* client)
219   {
220     CAttributeMap& attrMap = *this;
221     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
222     for (; it != itE; ++it)
223     {
224       if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second), client);
225     }
226   }
227
228   template <class T>
229   void CObjectTemplate<T>::sendAttributToServer(const string& id, CContextClient* client)
230   {
231      CAttributeMap & attrMap = *this;
232      CAttribute* attr=attrMap[id];
233      sendAttributToServer(*attr, client);
234   }
235
236  template <class T>
237  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, CContextClient* client)
238  {
239    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
240    if (client->isServerLeader())
241    {
242      CMessage msg;
243      msg<<this->getId(); 
244      msg << attr.getName();
245      msg << attr;
246      const std::list<int>& ranks = client->getRanksServerLeader();
247      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
248        event.push(*itRank,1,msg);
249      client->sendEvent(event);
250    }
251    else client->sendEvent(event);
252  }
253
254/* specialisation for context, because context Id on client is not the same on server, and no need to transfer context Id */
255  template <>
256  void CObjectTemplate<CContext>::sendAttributToServer(CAttribute& attr, CContextClient* client)
257  {
258    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
259    if (client->isServerLeader())
260    {
261      CMessage msg;
262      msg << attr.getName();
263      msg << attr;
264      const std::list<int>& ranks = client->getRanksServerLeader();
265      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
266        event.push(*itRank,1,msg);
267      client->sendEvent(event);
268    }
269    else client->sendEvent(event);
270  }
271
272  /*!
273    This generic funtion only provides instance for sending, for receving, each
274    child class must define itself.
275    \param [in] id Id of added item
276    \param [in] itemType type of added item
277  */
278
279  template<class T>
280  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, CContextClient* client)
281  {
282    typedef typename T::EEventId ItemType;
283     CEventClient event(this->getType(),ItemType(itemType));
284     if (client->isServerLeader())
285     {
286       CMessage msg;
287       msg << this->getId();
288       msg << id;
289       const std::list<int>& ranks = client->getRanksServerLeader();
290       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
291         event.push(*itRank,1,msg);
292       client->sendEvent(event);
293     }
294     else client->sendEvent(event);
295  }
296
297  template <class T>
298  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
299  {
300
301    CBufferIn* buffer=event.subEvents.begin()->buffer;
302    string id,attrId;
303    *buffer>>id;
304    CAttributeMap & attrMap = *get(id);
305    *buffer>>attrId;
306    CAttribute* attr=attrMap[attrId];
307    info(50) << "attribut recu " << attrId << "  ";
308    if (attr->isEmpty()) info(50) << "--> empty" << endl;
309    else info(50) /*<attr->getValue()*/ << endl;
310    *buffer>>*attr;
311     info(50) << "attribut recu " << attrId << "  ";
312    if (attr->isEmpty()) info(50) << "--> empty" << endl;
313    else info(50) /*attr->getValue()*/ << endl;
314  }
315
316/* specialisation for context, because context Id on client is not the same on server and no need to transfer context Id */
317  template <>
318  void CObjectTemplate<CContext>::recvAttributFromClient(CEventServer& event)
319  {
320
321    CBufferIn* buffer=event.subEvents.begin()->buffer;
322    string attrId;
323    CAttributeMap & attrMap = *CContext::getCurrent();
324    *buffer>>attrId;
325    CAttribute* attr=attrMap[attrId];
326    info(50) << "attribut recu " << attrId << "  ";
327    if (attr->isEmpty()) info(50) << "--> empty" << endl;
328    else info(50) /*<attr->getValue()*/ << endl;
329    *buffer>>*attr;
330     info(50) << "attribut recu " << attrId << "  ";
331    if (attr->isEmpty()) info(50) << "--> empty" << endl;
332    else info(50) /*attr->getValue()*/ << endl;
333  }
334
335
336   template <class T>
337   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
338   {
339      switch(event.type)
340      {
341         case EVENT_ID_SEND_ATTRIBUTE :
342           recvAttributFromClient(event);
343           return true;
344           break;
345
346         default :
347         return false;
348//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
349      }
350   }
351
352   template <typename T>
353   bool CObjectTemplate<T>::has(const string & id)
354   {
355     return CObjectFactory::HasObject<T>(id);
356   }
357
358   template <typename T>
359   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
360   {
361     return CObjectFactory::HasObject<T>(contextId,id);
362   }
363
364   template <typename T>
365   T* CObjectTemplate<T>::get(const string & id)
366   {
367     return CObjectFactory::GetObject<T>(id).get();
368   }
369
370   template <typename T>
371   T* CObjectTemplate<T>::get(const T* ptr)
372   {
373     return CObjectFactory::GetObject<T>(ptr).get();
374   }
375
376   template <typename T>
377   std::shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
378   {
379     return CObjectFactory::GetObject<T>(ptr);
380   }
381
382   template <typename T>
383   std::shared_ptr<T> CObjectTemplate<T>::getShared(void)
384   {
385     return CObjectFactory::GetObject<T>((T*)this);
386   }
387
388   template <typename T>
389   const vector<T*> CObjectTemplate<T>::getAll()
390   {
391     const vector< std::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
392     vector<T*> vect;
393
394     typename vector<std::shared_ptr<T> >::const_iterator it;
395     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
396     return vect;
397   }
398
399   template <typename T>
400   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
401   {
402     const vector< std::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
403     vector<T*> vect;
404
405     typename vector<std::shared_ptr<T> >::const_iterator it;
406     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
407     return vect;
408   }
409
410   template <typename T>
411   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
412   {
413     return CObjectFactory::GetObject<T>(contextId,id).get();
414   }
415
416   template <typename T>
417   T* CObjectTemplate<T>::create(const string & id)
418   {
419     return CObjectFactory::CreateObject<T>(id).get();
420   }   ///--------------------------------------------------------------
421
422  template <typename T>
423  T* CObjectTemplate<T>::get(void)
424  {
425    return CObjectFactory::GetObject<T>((T*)this).get();
426  }
427
428   template <typename T>
429   void CObjectTemplate<T>::generateCInterface(ostream& oss)
430   {
431     string className=getName();
432     int found=className.rfind("_group");
433     if (found!=string::npos) className.replace(found,1,0,'x');
434
435     oss << "/* ************************************************************************** *" << iendl;
436     oss << " *               Interface auto generated - do not modify                     *" << iendl;
437     oss << " * ************************************************************************** */" << iendl;
438     oss << iendl;
439     oss << "#include <boost/multi_array.hpp>" << iendl;
440     oss << "#include \"xios.hpp\"" << iendl;
441     oss << "#include \"attribute_template.hpp\"" << iendl;
442     oss << "#include \"object_template.hpp\"" << iendl;
443     oss << "#include \"group_template.hpp\"" << iendl;
444     oss << "#include \"icutil.hpp\"" << iendl;
445     oss << "#include \"icdate.hpp\"" << iendl;
446     oss << "#include \"timer.hpp\"" << iendl;
447     oss << "#include \"node_type.hpp\"" << iendl;
448     oss << iendl;
449     oss << "extern \"C\"" << iendl;
450     oss << "{" << iendl++;
451     oss << "typedef xios::" << getStrType<T>() << "* " << className << "_Ptr;";
452     SuperClassMap::generateCInterface(oss,className);
453     oss << "}" << iendl--;
454   }
455
456   template <typename T>
457   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
458   {
459     string className=getName();
460     int found=className.rfind("_group");
461     if (found!=string::npos) className.replace(found,1,0,'x');
462
463     oss << "! * ************************************************************************** *" << iendl;
464     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
465     oss << "! * ************************************************************************** *" << iendl;
466     oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl;
467     oss << iendl;
468     oss << "MODULE " << className << "_interface_attr" << iendl++;
469     oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl;
470     oss << iendl;
471     oss << "INTERFACE" << iendl++;
472     oss << "! Do not call directly / interface FORTRAN 2003 <-> C99";
473     SuperClassMap::generateFortran2003Interface(oss, className);
474     oss << iendl--;
475     oss << "END INTERFACE" << iendl--;
476     oss << iendl;
477     oss << "END MODULE " << className << "_interface_attr" << iendl;
478   }
479
480   template <typename T>
481   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
482   {
483     string className=getName();
484     int found=className.rfind("_group");
485     if (found!=string::npos) className.erase(found,1);
486     string superClassName=getName();
487     found=superClassName.find("_group");
488     if (found!=string::npos) superClassName.erase(found,6);
489
490     oss << "! * ************************************************************************** *" << iendl;
491     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
492     oss << "! * ************************************************************************** *" << iendl;
493     oss << "#include \"xios_fortran_prefix.hpp\"" << iendl;
494     oss << iendl;
495     oss << "MODULE i" << className << "_attr" << iendl++;
496     oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl;
497     oss << "USE i" << superClassName << iendl;
498     oss << "USE " << className << "_interface_attr" << iendl--;
499//   oss << "TYPE txios(" << className << ")" << iendl;
500//   oss << "  INTEGER(kind = C_INTPTR_T) :: daddr" << iendl;
501//   oss << "END TYPE txios(" << className << ")" << iendl;
502     oss << iendl;
503     oss << "CONTAINS" << iendl;
504     oss << iendl++;
505     SuperClassMap::generateFortranInterface_id(oss,className);
506     oss << iendl;
507     SuperClassMap::generateFortranInterface_hdl(oss,className);
508     oss << iendl;
509     SuperClassMap::generateFortranInterface_hdl_(oss,className);
510     oss << iendl;
511     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
512     oss << iendl;
513     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
514     oss << iendl;
515     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
516     oss << iendl;
517     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
518     oss << iendl;
519     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
520     oss << iendl;
521     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
522     oss << iendl--;
523     oss << "END MODULE i" << className << "_attr" << iendl;
524   }
525} // namespace xios
526
527#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.