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

Last change on this file since 1961 was 1875, checked in by ymipsl, 4 years ago

XIOS coupling branch
Some updates.

First coupling test is beginning to work...

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