Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYElement.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 #include <string.h>
17 #include <iostream>
18 
19 #include "Tympan/core/idgen.h"
20 #include "Tympan/core/chrono.h"
21 #include "Tympan/core/exceptions.h"
22 #include "Tympan/core/logging.h"
23 #include "TYElement.h"
24 
25 // Declaration des membres statiques.
26 std::unordered_map<std::string, OPrototype::IOProtoFactory::ptr_type> OPrototype::_factory_map;
27 
29 
31 
32 /* static */ void OPrototype::add_factory(const char* classname, IOProtoFactory::ptr_type factory)
33 {
34  _factory_map[std::string(classname)] = move(factory);
35 }
36 
37 /*static*/ OPrototype* OPrototype::findAndClone(const char* className)
38 {
39  auto it = _factory_map.find(className);
40 
41  if (it == _factory_map.end())
42  {
43  std::string err_msg("Asked to clone class ");
44  err_msg.append(className);
45  err_msg.append(" which isn't registered in OPrototype.");
46  throw tympan::invalid_data(err_msg)
48  }
49  else
50  {
51  return _factory_map[className]->make().release();
52  }
53 }
54 
55 /*static*/ int OPrototype::findPrototype(const char* className)
56 {
57  if (className == 0)
58  {
59  return -1;
60  }
61  // Return 1 if the class className exists, -1 otherwise
62  return (_factory_map.count(className) > 0 ? 1 : -1);
63 }
64 
65 bool OPrototype::isA(const char* className) const
66 {
67  // Test le nom du type
68  return (!strcmp(className, this->getClassName()));
69 }
70 
72 {
73  return (OPrototype*)pObject;
74 }
75 
76 // -------------------------------------------------------------------------
77 // classe TYElement
78 // -------------------------------------------------------------------------
79 
84 bool TYElement::_logInstances = false;
85 // TYListPtrElement* TYElement::_instances = NULL;
87 
88 bool TYElement::_toSave = false;
89 bool TYElement::_bRegenerateID = false;
90 
94 
96 {
97  if (_instances == NULL)
98  {
100  }
101 
102  return *_instances;
103 }
104 
106  : _pParent(nullptr), _bPutInInstanceList(true), _copyCount(0), _inCurrentCalcul(true),
107  _isAcousticModified(true), _isGeometryModified(true), _pGraphicObject(nullptr), _allUses(nullptr)
108 {
110  {
111  addInstance();
112  }
114 }
115 
116 TYElement::TYElement(TYElement* pParent, bool PutInInstanceList)
117  : _pParent(pParent), _bPutInInstanceList(PutInInstanceList), _copyCount(0), _inCurrentCalcul(true),
118  _isAcousticModified(true), _isGeometryModified(true), _pGraphicObject(nullptr), _allUses(nullptr)
119 {
121  {
122  addInstance();
123  }
124 
126 }
127 
128 TYElement::TYElement(const TYElement& other, bool PutInInstanceList /*= true*/)
129  : _bPutInInstanceList(PutInInstanceList)
130 {
131  *this = other;
132 
134  {
135  addInstance();
136  }
137 }
138 
140 {
142  {
143  remInstance();
144  }
145 #if TY_USE_IHM
146  if (_pGraphicObject)
147  {
149  _pGraphicObject = NULL;
150  }
151 #endif
152 
153  _pParent = nullptr;
154 
156 }
157 
159 {
160  TYElementContainer::const_iterator elt_it = getInstances().find(uuid);
161  if (elt_it != getInstances().end())
162  {
163  return elt_it->second;
164  }
165 
166  OMessageManager::get()->error("instance not found: %s", uuid.toString().toUtf8().data());
167 
168  return NULL;
169 }
170 
172 {
173  getInstances().clear();
174 }
175 
176 const TYUUID& TYElement::getID() const
177 {
178  if (hasNullID())
179  {
180  _uuid = newID();
181  }
182 
183  return _uuid;
184 }
185 
187 {
188  // If the _uuid is not NULL, we remove it from the map.
189  bool was_registered = false;
190  if (!hasNullID())
191  {
192  // size_t remove_count = getInstances().erase(_uuid);
193  TYElementContainer::iterator it = getInstances().find(_uuid);
194  if (it != getInstances().end())
195  {
196  getInstances().erase(it);
197  was_registered = true;
198  }
199  }
200 
201  _uuid = id;
202 
203  // If the element was registered, we update the map (new insertion).
204  if (was_registered)
205  {
206  getInstances().insert(std::make_pair(_uuid, this));
207  }
208 }
209 
210 void TYElement::setID(const QString& str_id)
211 {
212  TYUUID new_uuid(str_id);
213  setID(new_uuid);
214 }
215 
216 bool TYElement::testId(const TYUUID& id, const TYElement* pElem)
217 {
218  TYElement* pEl = getInstance(id);
219  if (pEl != pElem)
220  {
221  return true;
222  }
223  return false;
224 }
225 
227 {
228  if (_logInstances)
229  {
230  const TYUUID& uuid = getID(); // Could force the generation of the UUID.
231  getInstances().insert(std::make_pair(uuid, this));
232  }
233 }
234 
236 {
237  if (!hasNullID())
238  {
239  getInstances().erase(getID());
240  }
241 }
242 
244 {
245  setID(newID());
246 }
247 
248 void TYElement::setIsAcousticModified(bool isModified)
249 {
250  _isAcousticModified = isModified;
251 }
252 
253 void TYElement::setIsGeometryModified(bool isModified)
254 {
255  _isGeometryModified = isModified;
256 
257 #if TY_USE_IHM
258  if (_pGraphicObject && isModified)
259  {
261  }
262 #endif
263 }
264 
266 {
267  if (this != &other)
268  {
269  setID(other.getID());
270  _name = other._name;
271  _pParent = other._pParent;
273  _copyCount = other._copyCount;
274  _allUses = other._allUses;
275 
276  setIsGeometryModified(true);
277  setIsAcousticModified(true);
278  }
279  return *this;
280 }
281 
282 bool TYElement::operator==(const TYElement& other) const
283 {
284  if (this != &other)
285  {
286  if (getID() != other.getID())
287  {
288  return false;
289  }
290  if (_name != other._name)
291  {
292  return false;
293  }
294  if (_pParent != other._pParent)
295  {
296  return false;
297  }
298  }
299  return true;
300 }
301 
302 bool TYElement::operator!=(const TYElement& other) const
303 {
304  return !operator==(other);
305 }
306 
307 bool TYElement::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*= false*/)
308 {
309  QString copyTag;
310  if (!pOther)
311  {
312  return false;
313  } // XXX assert(pOther);
314 
315  // For now we don't look at the hierarchy. Let's suppose we are expecting
316  // to copy an element of the same class as this
317  if (strcmp(pOther->getClassName(), getClassName()) != 0)
318  {
319  return false;
320  }
321 
322  _name = pOther->_name;
323  _pParent = pOther->_pParent;
325  _copyCount = pOther->_copyCount;
326  _allUses = pOther->_allUses;
327 
328  _copyCount++;
329 
330  if (pUseCopyTag)
331  {
332  copyTag = QString("Copie (%1) de :").arg(_copyCount);
333  }
334  else
335  {
336  copyTag = QString("");
337  }
338 
339  if (copyId)
340  {
341  setID(pOther->getID());
342  copyTag = "";
343  _copyCount > 0 ? _copyCount-- : 0;
344  }
345 
346  TYElement* pOther2 = const_cast<TYElement*>(pOther);
347  pOther2->setCopyCount(_copyCount);
348 
349  if (_copyCount > 1)
350  {
351  QStringList strLst = _name.split(':');
352  if (strLst.size() > 1)
353  {
354  _name = strLst[1];
355  }
356  }
357 
358  _name = copyTag + _name;
359 
360  _pGraphicObject = NULL;
361 
362  setIsGeometryModified(true);
363  setIsAcousticModified(true);
364 
365  return true;
366 }
367 
368 DOM_Element TYElement::toXML(DOM_Element& domElement) /* const */
369 {
370  QDomDocument domDoc = domElement.ownerDocument();
371  QDomElement domNewElem = domDoc.createElement(getMetierName().data());
372 
373  domNewElem.setAttribute("id", getID().toString());
374  domNewElem.setAttribute("name", _name);
375 
376  domElement.appendChild(domNewElem);
377 
378  return domNewElem;
379 }
380 
382 {
383  QString tmpString = TYXMLTools::getElementAttributeToString(domElement, "id");
384  if (tmpString.size() == 0)
385  {
386  // regenerateID(); //XXX
387  }
388  else
389  {
390  setID(tmpString);
391  }
392 
393  QString name = TYXMLTools::getElementAttributeToString(domElement, "name");
394  if (!name.isEmpty())
395  {
396  _name = name;
397  }
398 
399  if (_bRegenerateID)
400  {
401  regenerateID();
402  }
403 
404  setIsGeometryModified(true);
405  setIsAcousticModified(true);
406 
407  return 1;
408 }
409 
410 void TYElement::setInCurrentCalcul(bool state, bool recurschild /*= true*/, bool recursparent /*= true*/)
411 {
412  // Set state for this object
413  _inCurrentCalcul = state;
414  setIsGeometryModified(true);
415 
417  // if (recurschild) {
418  // // Collecte des childs
419  // LPTYElementArray childs;
420  // getChilds(childs, false);
421  //
422  // // Appel recursif
423  // for (int i = 0; i < childs.size(); i++)
424  // {
425  // childs[i]->setInCurrentCalcul(state, recurschild, false);
426  // }
427  //}
428 
429  // update parent status (uniquement en cas d'activation)
430  if (recursparent && state)
431  {
432  TYElement* pParent = getParent();
433  if (pParent)
434  {
435  pParent->setInCurrentCalcul(state, false, recursparent);
436  }
437  }
438 }
439 
441 {
442  // Collecte des childs
443  LPTYElementArray childs;
444  getChilds(childs, false);
445 
446  if (childs.size() > 0)
447  {
448  // Appel recursif
449  bool onechildpresent = false;
450  for (int i = 0; i < childs.size(); i++)
451  {
452  onechildpresent = onechildpresent || (childs[i]->isInCurrentCalcul());
453  }
454 
455  // the parent is in the calcul if at least one of its direct children is in the calcul.
456  setInCurrentCalcul(onechildpresent, false);
457  }
458 }
459 
460 void TYElement::updateCurrentCalcul(TYListID& listID, bool recursif) //=true
461 {
462  bool present = false;
463  TYListID::iterator ite;
464 
465  // Parcours de la selection du calcul
466  for (ite = listID.begin(); ite != listID.end(); ++ite)
467  {
468  if ((*ite) == getID())
469  {
470  // Cet element est present dans la liste
471  present = true;
472  break;
473  }
474  }
475 
476  setInCurrentCalcul(present, false);
477 
478  if (recursif)
479  {
480  // Collecte des childs
481  LPTYElementArray childs;
482  getChilds(childs, false);
483  for (unsigned int i = 0; i < childs.size(); i++)
484  {
485  childs[i]->updateCurrentCalcul(listID, recursif);
486  }
487  }
488 }
489 
490 #if TY_USE_IHM
491 void TYElement::drawGraphic(bool draw)
492 {
493  if (draw)
494  {
495  if (getGraphicObject())
496  {
497  getGraphicObject()->setVisible(true);
498  }
499 
500  // Mise a jour
501  updateGraphic();
502  }
503  else
504  {
505  if (getGraphicObject())
506  {
507  getGraphicObject()->setVisible(false);
508  }
509  }
510 }
511 
512 void TYElement::updateGraphic()
513 {
514  if (getGraphicObject())
515  {
516  getGraphicObject()->update();
517  }
518 }
519 
520 void TYElement::updateGraphicTree()
521 {
522  if (getGraphicObject())
523  {
524  getGraphicObject()->updateTree();
525  }
526 }
527 
528 TYEditWidget* TYElement::getEditWidget()
529 {
530  return new TYElementWidget(this);
531 }
532 
533 int TYElement::edit(TYEditWidget* pParent /*=NULL*/)
534 {
535  int ret = -1;
536 
537  ret = TYWidget::edit(this, pParent);
538 
539  return ret;
540 }
541 
542 #endif // TY_USE_IHM
543 
544 bool TYElement::callFromXMLIfEqual(DOM_Element& domElement, int* pRetVal /*=NULL*/)
545 {
546  bool bRet = false;
547  int retVal = 0; // INIT to 0 Projet_Tympan to avoid warnings on g++
548  if (pRetVal)
549  {
550  retVal = *pRetVal;
551  } // Recuperation de la valeur de pRetVal
552 
553  if (domElement.nodeName().compare(QString(getMetierName().data())) == 0)
554  {
555  retVal = fromXML(domElement);
556  bRet = true;
557  }
558 
559  if (pRetVal)
560  {
561  *pRetVal = retVal;
562  } // Si demandee, propagation de la valeur de retval
563 
564  return bRet;
565 }
566 
568 {
569  return &this->getClassName()[2];
570 }
571 
573  const char* type)
574 {
575  LPTYElementArray eltCollection;
576  LPTYElement pElt = NULL;
577  DOM_Element elemCur;
578 
579  QDomNodeList childs = parentElem.childNodes();
580  QString str;
581 
582  for (unsigned int i = 0; i < childs.length(); i++)
583  {
584  elemCur = childs.item(i).toElement();
585 
586  // Ajout du prefixe TY
587  QString nodeName = elemCur.nodeName();
588  str = "TY";
589  str += nodeName;
590 
591  try
592  {
593  // Auto construction
594  pElt = dynamic_cast<TYElement*>(TYElement::findAndClone((char*)str.toLatin1().data()));
595  }
596  catch (tympan::invalid_data&)
597  {
598  pElt = nullptr;
599  }
600 
601  // For now we don't look at the hierarchy. Let's suppose we are
602  // looking for the very type we cloned which is the most likely hypothesis
603  if ((pElt != nullptr) && (strcmp(pElt->getClassName(), type) == 0))
604  {
605  // Parsing XML
606  pElt->fromXML(elemCur);
607 
608  // Ajout
609  eltCollection.push_back(pElt);
610  }
611  }
612  return eltCollection;
613 }
614 
616 {
617  TYUUID newID;
618  newID.GenUniqueID();
620  return newID;
621 }
622 
623 /*static*/ TYUUID TYElement::fromString(QString id)
624 {
625  TYUUID newID(id);
626  return newID;
627 }
628 
629 /*static*/ QString TYElement::toString(TYUUID& uuid)
630 {
631  return uuid.toString();
632 }
633 
635 {
636  return ty_created_counter;
637 }
639 {
640  return ty_destroyed_counter;
641 }
642 
644 {
645  return ty_regen_id_counter;
646 }
QDomElement DOM_Element
Definition: QT2DOM.h:30
void TYEditWidget
Declarations de types pour l'API IHM et l'Impression.
Definition: TYDefines.h:50
class OGenID TYUUID
Definition: TYDefines.h:59
std::list< TYUUID > TYListID
Collection d'identifiants.
Definition: TYDefines.h:331
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:345
std::map< TYUUID, TYElement * > TYElementContainer
Definition: TYElement.h:347
int id
const char * name
virtual void error(const char *message,...)
Definition: logging.cpp:127
static OMessageManager * get()
Definition: logging.cpp:108
std::unique_ptr< IOProtoFactory > ptr_type
Definition: TYElement.h:284
virtual ~OPrototype()
Definition: TYElement.cpp:30
static std::unordered_map< std::string, IOProtoFactory::ptr_type > _factory_map
Definition: TYElement.h:330
static void add_factory(const char *, IOProtoFactory::ptr_type factory)
Definition: TYElement.cpp:32
static int findPrototype(const char *className)
Definition: TYElement.cpp:55
virtual const char * getClassName() const
Definition: TYElement.h:249
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:71
static OPrototype * findAndClone(const char *className)
Definition: TYElement.cpp:37
bool isA(const char *className) const
Definition: TYElement.cpp:65
void setModified(bool modified=true)
void setElement(TYElement *pElt)
classe de l'objet IHM pour un element
static bool _toSave
Definition: TYElement.h:1001
bool _bPutInInstanceList
Definition: TYElement.h:972
void setID(TYUUID id)
Definition: TYElement.cpp:186
static uint64 ty_regen_id_counter
Definition: TYElement.h:1007
static TYElementContainer & getInstances()
Definition: TYElement.cpp:95
TYElement * getParent() const
Definition: TYElement.h:699
static bool _logInstances
Indique si on souhaite registrer toutes les instances de type TYElement et derivees.
Definition: TYElement.h:994
void addInstance()
Definition: TYElement.cpp:226
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:307
TYUUID _uuid
Identifiant unique de l'element.
Definition: TYElement.h:962
void remInstance()
Definition: TYElement.cpp:235
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:368
void setCopyCount(const unsigned int copyCount)
Modifie la vaeur du compteur.
Definition: TYElement.h:557
std::string getMetierName()
Definition: TYElement.cpp:567
bool _isGeometryModified
Indicateur de modification de la geometrie.
Definition: TYElement.h:984
QString _name
Nom courant de l'element.
Definition: TYElement.h:966
bool operator==(const TYElement &other) const
Definition: TYElement.cpp:282
static void purgeInstances()
Definition: TYElement.cpp:171
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:265
static TYUUID fromString(QString id)
Definition: TYElement.cpp:623
void OnChildInCalculStatusChange()
Definition: TYElement.cpp:440
static uint64 getConstructorCount()
Definition: TYElement.cpp:634
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:544
static bool testId(const TYUUID &id, const TYElement *pElem)
Definition: TYElement.cpp:216
static uint64 getIdGenerationCount()
Definition: TYElement.cpp:643
bool _isAcousticModified
Indicateur de modification acoustique.
Definition: TYElement.h:981
void regenerateID()
Definition: TYElement.cpp:243
bool hasNullID() const
Definition: TYElement.h:658
static uint64 getDestructorCount()
Definition: TYElement.cpp:638
const TYUUID & getID() const
Definition: TYElement.cpp:176
bool operator!=(const TYElement &other) const
Definition: TYElement.cpp:302
static TYUUID newID()
Definition: TYElement.cpp:615
void * _allUses
Multi purpose void pointer (use for compatibility actually)
Definition: TYElement.h:990
virtual std::string toString() const
Definition: TYElement.h:786
TYElement * _pParent
Reference sur l'element parent.
Definition: TYElement.h:969
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYElement.cpp:460
LPTYElementGraphic _pGraphicObject
L'object graphique metier associe a cet element.
Definition: TYElement.h:987
virtual void setInCurrentCalcul(bool state, bool recurschild=true, bool recursparent=true)
Definition: TYElement.cpp:410
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:532
static TYElementContainer * _instances
Collection de toutes les instances de type TYElement et derivees.
Definition: TYElement.h:997
bool _inCurrentCalcul
Indique si cet element est actif dans le Calcul courant.
Definition: TYElement.h:978
static LPTYElementArray findTypeCollectionAndCallFromXML(DOM_Element parentElem, const char *type)
Definition: TYElement.cpp:572
virtual ~TYElement()
Definition: TYElement.cpp:139
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:381
virtual void setIsAcousticModified(bool isModified)
Definition: TYElement.cpp:248
unsigned int _copyCount
Definition: TYElement.h:975
static uint64 ty_destroyed_counter
Definition: TYElement.h:1006
static uint64 ty_created_counter
Definition: TYElement.h:1005
static TYElement * getInstance(TYUUID uuid)
Definition: TYElement.cpp:158
static bool _bRegenerateID
Indicateur de regeneration d'ID true si regeneration d'ID a la lecture d'un fichier XML.
Definition: TYElement.h:1003
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
static int edit(TYElement *pElement, QWidget *pParent=NULL)
Definition: TYWidget.cpp:43
static QString getElementAttributeToString(DOM_Element parentElem, DOMString attName)
Definition: TYXMLTools.cpp:276
Utilities to handle exceptions and to pretty-print value.
#define tympan_source_loc
This macro build a source_loc object to be attached to a tympan::Exception.
Definition: exceptions.h:76
unsigned long long uint64
Definition: defines.h:65
boost::error_info< struct tag_classname, std::string > oproto_classname_errinfo
Definition: TYElement.h:92
The base exception class for errors due to invalid data.
Definition: exceptions.h:60