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

Last change on this file since 2203 was 2203, checked in by ymipsl, 3 years ago

New functionnality : domain, axis and scalar can now be retrieve with new syntax id :
ex. for domain :

id="domainId" : old syntax, working as before
id="fieldId::domainId" : get the domain related to "domainId" associated to the field "fieldId", work if only 1 domain related to domainId is associated to the field.
id="fieldId::domainId[n]" : get the nth domain related to "domainId" associated to the field "fieldId"
id="fieldId::" : get the domain associated the the field "fieldId, work if grid associated to th field is composed with exactly 1 domain (and possibly other components axis or scalars)
id="fieldId::[n] : get the nth domain composing the grid associated to the field

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: 18.4 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   template <class T>
161   void CObjectTemplate<T>::setInheritedId(T* obj)
162   {
163     if (!hasInheritedId_)
164     {
165       if (!(hasId() && !hasAutoGeneratedId())) 
166        if (obj->hasId() && !obj->hasAutoGeneratedId()) 
167        {
168          hasInheritedId_=true ;
169          inheritedId_=obj->getId() ;
170        } 
171     }
172   }
173
174   template <class T>
175   void CObjectTemplate<T>::setTemplateId(T* obj)
176   {
177     if (hasId() && !hasAutoGeneratedId())
178     {
179        templateId_ = getId() ;
180        hasTemplateId_ = true ;
181     }
182     else if (obj->hasId() && !obj->hasAutoGeneratedId())
183     {
184       templateId_ = obj->getId() ;
185       hasTemplateId_ = true ;
186     }
187     else if (obj->hasTemplateId())
188     {
189       templateId_= obj->getTemplateId() ;
190       hasTemplateId_=true ;
191     }
192   }
193   
194   
195   //---------------------------------------------------------------
196
197   template <class T>
198      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
199   {
200      if (parent != NULL)
201         SuperClassMap::setAttributes(parent, apply);
202   }
203
204   //---------------------------------------------------------------
205
206   template <class T>
207      void CObjectTemplate<T>::ClearAllAttributes(void)
208   {
209      vector<T*> avect = CObjectTemplate<T>::getAll();
210      typename vector<T*>::iterator
211            it = avect.begin(), end = avect.end();
212
213      for (;it != end; it++)
214      {
215         CAttributeMap & amap = **it;
216         amap.clearAllAttributes();
217      }
218   }
219
220   template<typename T>
221   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes(CContextClient* client)
222   {
223     std::map<int, size_t> minimumSizes;
224
225     if (client->isServerLeader())
226     {
227       size_t minimumSize = 0;
228       CAttributeMap& attrMap = *this;
229       CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
230       for (; it != itE; ++it)
231       {
232         if (!it->second->isEmpty())
233         {
234           size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
235           if (size > minimumSize)
236             minimumSize = size;
237         }
238       }
239
240       if (minimumSize)
241       {
242         // Account for extra header info
243         minimumSize += CEventClient::headerSize + getId().size() + sizeof(size_t);
244
245         const std::list<int>& ranks = client->getRanksServerLeader();
246         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
247           minimumSizes.insert(std::make_pair(*itRank, minimumSize));
248       }
249     }
250     return minimumSizes;
251   }
252
253   template<typename T>
254   void CObjectTemplate<T>::sendAllAttributesToServer(CContextClient* client, const string& objectId)
255   {
256     CAttributeMap& attrMap = *this;
257     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
258     for (; it != itE; ++it)
259     {
260       if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second), client, objectId);
261     }
262   }
263
264   template <class T>
265   void CObjectTemplate<T>::sendAttributToServer(const string& id, CContextClient* client, const string& objectId )
266   {
267      CAttributeMap & attrMap = *this;
268      CAttribute* attr=attrMap[id];
269      sendAttributToServer(*attr, client);
270   }
271
272  template <class T>
273  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, CContextClient* client, const string& objectId)
274  {
275    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
276    if (client->isServerLeader())
277    {
278      CMessage msg;
279      if (objectId.empty()) msg << this->getId();
280      else msg << objectId;
281      msg << attr.getName();
282      msg << attr;
283      const std::list<int>& ranks = client->getRanksServerLeader();
284      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
285        event.push(*itRank,1,msg);
286      client->sendEvent(event);
287    }
288    else client->sendEvent(event);
289  }
290
291/* specialisation for context, because context Id on client is not the same on server, and no need to transfer context Id */
292  template <>
293  void CObjectTemplate<CContext>::sendAttributToServer(CAttribute& attr, CContextClient* client, const string& objectId)
294  {
295    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
296    if (client->isServerLeader())
297    {
298      CMessage msg;
299      msg << attr.getName();
300      msg << attr;
301      const std::list<int>& ranks = client->getRanksServerLeader();
302      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
303        event.push(*itRank,1,msg);
304      client->sendEvent(event);
305    }
306    else client->sendEvent(event);
307  }
308
309  /*!
310    This generic funtion only provides instance for sending, for receving, each
311    child class must define itself.
312    \param [in] id Id of added item
313    \param [in] itemType type of added item
314  */
315
316  template<class T>
317  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, CContextClient* client, const string& objectId)
318  {
319    typedef typename T::EEventId ItemType;
320     CEventClient event(this->getType(),ItemType(itemType));
321     if (client->isServerLeader())
322     {
323       CMessage msg;
324       if (objectId.empty()) msg << this->getId();
325       else msg << objectId;
326       msg << id;
327       const std::list<int>& ranks = client->getRanksServerLeader();
328       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
329         event.push(*itRank,1,msg);
330       client->sendEvent(event);
331     }
332     else client->sendEvent(event);
333  }
334
335  template <class T>
336  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
337  {
338
339    CBufferIn* buffer=event.subEvents.begin()->buffer;
340    string id,attrId;
341    *buffer>>id;
342    CAttributeMap & attrMap = *get(id);
343    *buffer>>attrId;
344    CAttribute* attr=attrMap[attrId];
345    info(50) << "attribut recu " << attrId << "  ";
346    if (attr->isEmpty()) info(50) << "--> empty" << endl;
347    else info(50) /*<attr->getValue()*/ << endl;
348    *buffer>>*attr;
349     info(50) << "attribut recu " << attrId << "  ";
350    if (attr->isEmpty()) info(50) << "--> empty" << endl;
351    else info(50) /*attr->getValue()*/ << endl;
352  }
353
354/* specialisation for context, because context Id on client is not the same on server and no need to transfer context Id */
355  template <>
356  void CObjectTemplate<CContext>::recvAttributFromClient(CEventServer& event)
357  {
358
359    CBufferIn* buffer=event.subEvents.begin()->buffer;
360    string attrId;
361    CAttributeMap & attrMap = *CContext::getCurrent();
362    *buffer>>attrId;
363    CAttribute* attr=attrMap[attrId];
364    info(50) << "attribut recu " << attrId << "  ";
365    if (attr->isEmpty()) info(50) << "--> empty" << endl;
366    else info(50) /*<attr->getValue()*/ << endl;
367    *buffer>>*attr;
368     info(50) << "attribut recu " << attrId << "  ";
369    if (attr->isEmpty()) info(50) << "--> empty" << endl;
370    else info(50) /*attr->getValue()*/ << endl;
371  }
372
373
374   template <class T>
375   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
376   {
377      switch(event.type)
378      {
379         case EVENT_ID_SEND_ATTRIBUTE :
380           recvAttributFromClient(event);
381           return true;
382           break;
383
384         default :
385         return false;
386//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
387      }
388   }
389
390   template <typename T>
391   bool CObjectTemplate<T>::has(const string & id)
392   {
393     return CObjectFactory::HasObject<T>(id);
394   }
395
396   template <typename T>
397   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
398   {
399     return CObjectFactory::HasObject<T>(contextId,id);
400   }
401
402   template <typename T>
403   T* CObjectTemplate<T>::get(const string & id)
404   {
405     return CObjectFactory::GetObject<T>(id).get();
406   }
407
408   template <typename T>
409   T* CObjectTemplate<T>::get(const T* ptr)
410   {
411     return CObjectFactory::GetObject<T>(ptr).get();
412   }
413
414   template <typename T>
415   std::shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
416   {
417     return CObjectFactory::GetObject<T>(ptr);
418   }
419
420   template <typename T>
421   std::shared_ptr<T> CObjectTemplate<T>::getShared(void)
422   {
423     return CObjectFactory::GetObject<T>((T*)this);
424   }
425
426   template <typename T>
427   const vector<T*> CObjectTemplate<T>::getAll()
428   {
429     const vector< std::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
430     vector<T*> vect;
431
432     typename vector<std::shared_ptr<T> >::const_iterator it;
433     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
434     return vect;
435   }
436
437   template <typename T>
438   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
439   {
440     const vector< std::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
441     vector<T*> vect;
442
443     typename vector<std::shared_ptr<T> >::const_iterator it;
444     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
445     return vect;
446   }
447
448   template <typename T>
449   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
450   {
451     return CObjectFactory::GetObject<T>(contextId,id).get();
452   }
453
454   template <typename T>
455   T* CObjectTemplate<T>::create(const string & id)
456   {
457     return CObjectFactory::CreateObject<T>(id).get();
458   }   ///--------------------------------------------------------------
459
460   template <typename T>
461   T* CObjectTemplate<T>::createAlias(const string & id, const string& alias)
462   {
463     return CObjectFactory::CreateAlias<T>(id, alias).get();
464   }   ///--------------------------------------------------------------
465
466   template <typename T>
467   void CObjectTemplate<T>::createAlias(const string& alias)
468   {
469     get()->createAlias(getId(),alias) ;
470   }   //
471
472  template <typename T>
473  T* CObjectTemplate<T>::get(void)
474  {
475    return CObjectFactory::GetObject<T>((T*)this).get();
476  }
477
478   template <typename T>
479   void CObjectTemplate<T>::generateCInterface(ostream& oss)
480   {
481     string className=getName();
482     int found=className.rfind("_group");
483     if (found!=string::npos) className.replace(found,1,0,'x');
484
485     oss << "/* ************************************************************************** *" << iendl;
486     oss << " *               Interface auto generated - do not modify                     *" << iendl;
487     oss << " * ************************************************************************** */" << iendl;
488     oss << iendl;
489     oss << "#include <boost/multi_array.hpp>" << iendl;
490     oss << "#include \"xios.hpp\"" << iendl;
491     oss << "#include \"attribute_template.hpp\"" << iendl;
492     oss << "#include \"object_template.hpp\"" << iendl;
493     oss << "#include \"group_template.hpp\"" << iendl;
494     oss << "#include \"icutil.hpp\"" << iendl;
495     oss << "#include \"icdate.hpp\"" << iendl;
496     oss << "#include \"timer.hpp\"" << iendl;
497     oss << "#include \"node_type.hpp\"" << iendl;
498     oss << iendl;
499     oss << "extern \"C\"" << iendl;
500     oss << "{" << iendl++;
501     oss << "typedef xios::" << getStrType<T>() << "* " << className << "_Ptr;";
502     SuperClassMap::generateCInterface(oss,className);
503     oss << "}" << iendl--;
504   }
505
506   template <typename T>
507   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
508   {
509     string className=getName();
510     int found=className.rfind("_group");
511     if (found!=string::npos) className.replace(found,1,0,'x');
512
513     oss << "! * ************************************************************************** *" << iendl;
514     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
515     oss << "! * ************************************************************************** *" << iendl;
516     oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl;
517     oss << iendl;
518     oss << "MODULE " << className << "_interface_attr" << iendl++;
519     oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl;
520     oss << iendl;
521     oss << "INTERFACE" << iendl++;
522     oss << "! Do not call directly / interface FORTRAN 2003 <-> C99";
523     SuperClassMap::generateFortran2003Interface(oss, className);
524     oss << iendl--;
525     oss << "END INTERFACE" << iendl--;
526     oss << iendl;
527     oss << "END MODULE " << className << "_interface_attr" << iendl;
528   }
529
530   template <typename T>
531   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
532   {
533     string className=getName();
534     int found=className.rfind("_group");
535     if (found!=string::npos) className.erase(found,1);
536     string superClassName=getName();
537     found=superClassName.find("_group");
538     if (found!=string::npos) superClassName.erase(found,6);
539
540     oss << "! * ************************************************************************** *" << iendl;
541     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
542     oss << "! * ************************************************************************** *" << iendl;
543     oss << "#include \"xios_fortran_prefix.hpp\"" << iendl;
544     oss << iendl;
545     oss << "MODULE i" << className << "_attr" << iendl++;
546     oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl;
547     oss << "USE i" << superClassName << iendl;
548     oss << "USE " << className << "_interface_attr" << iendl--;
549//   oss << "TYPE txios(" << className << ")" << iendl;
550//   oss << "  INTEGER(kind = C_INTPTR_T) :: daddr" << iendl;
551//   oss << "END TYPE txios(" << className << ")" << iendl;
552     oss << iendl;
553     oss << "CONTAINS" << iendl;
554     oss << iendl++;
555     SuperClassMap::generateFortranInterface_id(oss,className);
556     oss << iendl;
557     SuperClassMap::generateFortranInterface_hdl(oss,className);
558     oss << iendl;
559     SuperClassMap::generateFortranInterface_hdl_(oss,className);
560     oss << iendl;
561     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
562     oss << iendl;
563     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
564     oss << iendl;
565     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
566     oss << iendl;
567     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
568     oss << iendl;
569     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
570     oss << iendl;
571     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
572     oss << iendl--;
573     oss << "END MODULE i" << className << "_attr" << iendl;
574   }
575} // namespace xios
576
577#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.