source: XIOS/dev/dev_olga/src/object_template_impl.hpp @ 987

Last change on this file since 987 was 987, checked in by mhnguyen, 6 years ago

First working version.
There are more things to do with it

  • 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
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      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>
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<boost::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   {
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
140   template <class T>
141      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
142   {
143      if (parent != NULL)
144         SuperClassMap::setAttributes(parent, apply);
145   }
146
147   //---------------------------------------------------------------
148
149   template <class T>
150      void CObjectTemplate<T>::ClearAllAttributes(void)
151   {
152      vector<T*> avect = CObjectTemplate<T>::getAll();
153      typename vector<T*>::iterator
154            it = avect.begin(), end = avect.end();
155
156      for (;it != end; it++)
157      {
158         CAttributeMap & amap = **it;
159         amap.clearAllAttributes();
160      }
161   }
162
163   template<typename T>
164   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes()
165   {
166     // CContextClient* client = CContext::getCurrent()->client;
167     CContext* context = CContext::getCurrent();
168
169          // Use correct context client to send message
170     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
171
172     std::map<int, size_t> minimumSizes;
173
174     if (contextClientTmp->isServerLeader())
175     {
176       size_t minimumSize = 0;
177       CAttributeMap& attrMap = *this;
178       CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
179       for (; it != itE; ++it)
180       {
181         if (!it->second->isEmpty())
182         {
183           size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
184           if (size > minimumSize)
185             minimumSize = size;
186         }
187       }
188
189       if (minimumSize)
190       {
191         // Account for extra header info
192         minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
193
194         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
195         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
196           minimumSizes.insert(std::make_pair(*itRank, minimumSize));
197       }
198     }
199
200     // if (client->isServerLeader())
201     // {
202     //   size_t minimumSize = 0;
203     //   CAttributeMap& attrMap = *this;
204     //   CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
205     //   for (; it != itE; ++it)
206     //   {
207     //     if (!it->second->isEmpty())
208     //     {
209     //       size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
210     //       if (size > minimumSize)
211     //         minimumSize = size;
212     //     }
213     //   }
214
215     //   if (minimumSize)
216     //   {
217     //     // Account for extra header info
218     //     minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
219
220     //     const std::list<int>& ranks = client->getRanksServerLeader();
221     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
222     //       minimumSizes.insert(std::make_pair(*itRank, minimumSize));
223     //   }
224     // }
225
226     return minimumSizes;
227   }
228
229   template<typename T>
230   void CObjectTemplate<T>::sendAllAttributesToServer()
231   {
232     CAttributeMap& attrMap = *this;
233     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
234     for (; it != itE; ++it)
235     {
236       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second));
237     }
238   }
239
240   template <class T>
241   void CObjectTemplate<T>::sendAttributToServer(const string& id)
242   {
243      CAttributeMap & attrMap = *this;
244      CAttribute* attr=attrMap[id];
245      sendAttributToServer(*attr);
246   }
247
248  template <class T>
249  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr)
250  {
251    CContext* context=CContext::getCurrent();
252
253     // Use correct context client to send message
254     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
255
256    // if (!context->hasServer)
257    if (context->hasClient)
258    {
259       // CContextClient* contextClientTmp=context->contextClientTmp;
260
261       CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
262       if (contextClientTmp->isServerLeader())
263       {
264         CMessage msg;
265//       msg << this->getId();
266         msg << this->getIdServer();
267         msg << attr.getName();
268         msg << attr;
269         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
270         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
271           event.push(*itRank,1,msg);
272         contextClientTmp->sendEvent(event);
273       }
274       else contextClientTmp->sendEvent(event);
275    }
276
277//     // if (!context->hasServer)
278//     if (context->hasClient)
279//     {
280//        CContextClient* client=context->client;
281
282//        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
283//        if (client->isServerLeader())
284//        {
285//          CMessage msg;
286// //       msg << this->getId();
287//          msg << this->getIdServer();
288//          msg << attr.getName();
289//          msg << attr;
290//          const std::list<int>& ranks = client->getRanksServerLeader();
291//          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
292//            event.push(*itRank,1,msg);
293//          client->sendEvent(event);
294//        }
295//        else client->sendEvent(event);
296//     }
297
298  }
299
300  /*!
301    This generic funtion only provides instance for sending, for receving, each
302    child class must define itself.
303    \param [in] id Id of added item
304    \param [in] itemType type of added item
305  */
306  template<class T>
307  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType)
308  {
309    CContext* context = CContext::getCurrent();
310    typedef typename T::EEventId ItemType;
311    if (context->hasClient)
312    {
313       // Use correct context client to send message
314       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
315       CEventClient event(this->getType(),ItemType(itemType));
316       if (contextClientTmp->isServerLeader())
317       {
318         CMessage msg;
319         msg << this->getId();
320         msg << id;
321         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
322         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
323           event.push(*itRank,1,msg);
324         contextClientTmp->sendEvent(event);
325       }
326       else contextClientTmp->sendEvent(event);
327    }
328  }
329
330  template <class T>
331  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
332  {
333
334    CBufferIn* buffer=event.subEvents.begin()->buffer;
335    string id,attrId;
336    *buffer>>id;
337    CAttributeMap & attrMap = *get(id);
338    *buffer>>attrId;
339    CAttribute* attr=attrMap[attrId];
340    info(50) << "attribut recu " << attrId << "  ";
341    if (attr->isEmpty()) info(50) << "--> empty" << endl;
342    else info(50) /*<attr->getValue()*/ << endl;
343    *buffer>>*attr;
344     info(50) << "attribut recu " << attrId << "  ";
345    if (attr->isEmpty()) info(50) << "--> empty" << endl;
346    else info(50) /*attr->getValue()*/ << endl;
347  }
348
349   template <class T>
350   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
351   {
352      switch(event.type)
353      {
354         case EVENT_ID_SEND_ATTRIBUTE :
355           recvAttributFromClient(event);
356           return true;
357           break;
358
359         default :
360         return false;
361//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
362      }
363   }
364
365   template <typename T>
366   bool CObjectTemplate<T>::has(const string & id)
367   {
368     return CObjectFactory::HasObject<T>(id);
369   }
370
371   template <typename T>
372   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
373   {
374     return CObjectFactory::HasObject<T>(contextId,id);
375   }
376
377   template <typename T>
378   T* CObjectTemplate<T>::get(const string & id)
379   {
380     return CObjectFactory::GetObject<T>(id).get();
381   }
382
383   template <typename T>
384   T* CObjectTemplate<T>::get(const T* ptr)
385   {
386     return CObjectFactory::GetObject<T>(ptr).get();
387   }
388
389   template <typename T>
390   shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
391   {
392     return CObjectFactory::GetObject<T>(ptr);
393   }
394
395   template <typename T>
396   shared_ptr<T> CObjectTemplate<T>::getShared(void)
397   {
398     return CObjectFactory::GetObject<T>((T*)this);
399   }
400
401   template <typename T>
402   const vector<T*> CObjectTemplate<T>::getAll()
403   {
404     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
405     vector<T*> vect;
406
407     typename vector<shared_ptr<T> >::const_iterator it;
408     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
409     return vect;
410   }
411
412   template <typename T>
413   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
414   {
415     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
416     vector<T*> vect;
417
418     typename vector<shared_ptr<T> >::const_iterator it;
419     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
420     return vect;
421   }
422
423   template <typename T>
424   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
425   {
426     return CObjectFactory::GetObject<T>(contextId,id).get();
427   }
428
429   template <typename T>
430   T* CObjectTemplate<T>::create(const string & id)
431   {
432     return CObjectFactory::CreateObject<T>(id).get();
433   }   ///--------------------------------------------------------------
434
435  template <typename T>
436  T* CObjectTemplate<T>::get(void)
437  {
438    return CObjectFactory::GetObject<T>((T*)this).get();
439  }
440
441   template <typename T>
442   void CObjectTemplate<T>::generateCInterface(ostream& oss)
443   {
444     string className=getName();
445     int found=className.rfind("_group");
446     if (found!=string::npos) className.replace(found,1,0,'x');
447
448     oss << "/* ************************************************************************** *" << iendl;
449     oss << " *               Interface auto generated - do not modify                     *" << iendl;
450     oss << " * ************************************************************************** */" << iendl;
451     oss << iendl;
452     oss << "#include <boost/multi_array.hpp>" << iendl;
453     oss << "#include <boost/shared_ptr.hpp>" << iendl;
454     oss << "#include \"xios.hpp\"" << iendl;
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;";
466     SuperClassMap::generateCInterface(oss,className);
467     oss << "}" << iendl--;
468   }
469
470   template <typename T>
471   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
472   {
473     string className=getName();
474     int found=className.rfind("_group");
475     if (found!=string::npos) className.replace(found,1,0,'x');
476
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";
487     SuperClassMap::generateFortran2003Interface(oss,className);
488     oss << iendl--;
489     oss << "END INTERFACE" << iendl--;
490     oss << iendl;
491     oss << "END MODULE " << className << "_interface_attr" << iendl;
492   }
493
494   template <typename T>
495   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
496   {
497     string className=getName();
498     int found=className.rfind("_group");
499     if (found!=string::npos) className.erase(found,1);
500     string superClassName=getName();
501     found=superClassName.find("_group");
502     if (found!=string::npos) superClassName.erase(found,6);
503
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++;
519     SuperClassMap::generateFortranInterface_id(oss,className);
520     oss << iendl;
521     SuperClassMap::generateFortranInterface_hdl(oss,className);
522     oss << iendl;
523     SuperClassMap::generateFortranInterface_hdl_(oss,className);
524     oss << iendl;
525     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
526     oss << iendl;
527     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
528     oss << iendl;
529     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
530     oss << iendl;
531     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
532     oss << iendl;
533     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
534     oss << iendl;
535     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
536     oss << iendl--;
537     oss << "END MODULE i" << className << "_attr" << iendl;
538   }
539} // namespace xios
540
541#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.