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

Last change on this file since 2338 was 2243, checked in by jderouillat, 3 years ago

Move context cleaning in xios_finalize (for clients) and when servers have finished their work

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