source: XIOS/dev/XIOS_DEV_CMIP6/src/object_template_impl.hpp @ 1291

Last change on this file since 1291 was 1283, checked in by ymipsl, 7 years ago

Some code lines forgetten during last merge (rev. 1158)

Side effects are expected...

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