source: XIOS/dev/dev_trunk_omp/src/object_template_impl.hpp @ 1601

Last change on this file since 1601 was 1601, checked in by yushan, 2 years ago

branch_openmp merged with trunk r1597

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