Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYElement.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
16 #include <string.h>
17 #include <iostream>
18 
19 #include "Tympan/core/chrono.h"
20 #include "Tympan/core/exceptions.h"
21 #include "Tympan/core/logging.h"
22 #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), _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), _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 #if TY_USE_IHM
256  if (_pGraphicObject != nullptr && isModified)
257  {
258  _pGraphicObject->setModified(isModified);
259  }
260 #endif
261 }
262 
264 {
265  if (this != &other)
266  {
267  setID(other.getID());
268  _name = other._name;
269  _pParent = other._pParent;
271  _copyCount = other._copyCount;
272  _allUses = other._allUses;
273 
274  setIsGeometryModified(true);
275  setIsAcousticModified(true);
276  }
277  return *this;
278 }
279 
280 bool TYElement::operator==(const TYElement& other) const
281 {
282  if (this != &other)
283  {
284  if (getID() != other.getID())
285  {
286  return false;
287  }
288  if (_name != other._name)
289  {
290  return false;
291  }
292  if (_pParent != other._pParent)
293  {
294  return false;
295  }
296  }
297  return true;
298 }
299 
300 bool TYElement::operator!=(const TYElement& other) const
301 {
302  return !operator==(other);
303 }
304 
305 bool TYElement::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*= false*/)
306 {
307  QString copyTag;
308  if (!pOther)
309  {
310  return false;
311  } // XXX assert(pOther);
312 
313  // For now we don't look at the hierarchy. Let's suppose we are expecting
314  // to copy an element of the same class as this
315  if (strcmp(pOther->getClassName(), getClassName()) != 0)
316  {
317  return false;
318  }
319 
320  _name = pOther->_name;
321  _pParent = pOther->_pParent;
323  _copyCount = pOther->_copyCount;
324  _allUses = pOther->_allUses;
325 
326  _copyCount++;
327 
328  if (pUseCopyTag)
329  {
330  copyTag = QString("Copie (%1) de :").arg(_copyCount);
331  }
332  else
333  {
334  copyTag = QString("");
335  }
336 
337  if (copyId)
338  {
339  setID(pOther->getID());
340  copyTag = "";
341  _copyCount > 0 ? _copyCount-- : 0;
342  }
343 
344  TYElement* pOther2 = const_cast<TYElement*>(pOther);
345  pOther2->setCopyCount(_copyCount);
346 
347  if (_copyCount > 1)
348  {
349  QStringList strLst = _name.split(':');
350  if (strLst.size() > 1)
351  {
352  _name = strLst[1];
353  }
354  }
355 
356  _name = copyTag + _name;
357 
358  _pGraphicObject = NULL;
359 
360  setIsGeometryModified(true);
361  setIsAcousticModified(true);
362 
363  return true;
364 }
365 
366 DOM_Element TYElement::toXML(DOM_Element& domElement) /* const */
367 {
368  QDomDocument domDoc = domElement.ownerDocument();
369  QDomElement domNewElem = domDoc.createElement(getMetierName().data());
370 
371  domNewElem.setAttribute("id", getID().toString());
372  domNewElem.setAttribute("name", _name);
373 
374  domElement.appendChild(domNewElem);
375 
376  return domNewElem;
377 }
378 
380 {
381  QString tmpString = TYXMLTools::getElementAttributeToString(domElement, "id");
382  if (tmpString.size() == 0)
383  {
384  // regenerateID(); //XXX
385  }
386  else
387  {
388  setID(tmpString);
389  }
390 
391  QString name = TYXMLTools::getElementAttributeToString(domElement, "name");
392  if (!name.isEmpty())
393  {
394  _name = name;
395  }
396 
397  if (_bRegenerateID)
398  {
399  regenerateID();
400  }
401 
402  setIsGeometryModified(true);
403  setIsAcousticModified(true);
404 
405  return 1;
406 }
407 
408 void TYElement::setInCurrentCalcul(bool state, bool recurschild /*= true*/, bool recursparent /*= true*/)
409 {
410  if (_inCurrentCalcul != state)
411  {
412  // Set state for this object
413  _inCurrentCalcul = state;
414  setIsGeometryModified(true);
415  }
416 
418  // if (recurschild) {
419  // // Collecte des childs
420  // LPTYElementArray childs;
421  // getChilds(childs, false);
422  //
423  // // Appel recursif
424  // for (int i = 0; i < childs.size(); i++)
425  // {
426  // childs[i]->setInCurrentCalcul(state, recurschild, false);
427  // }
428  //}
429 
430  // update parent status (uniquement en cas d'activation)
431  if (recursparent && state)
432  {
433  TYElement* pParent = getParent();
434  if (pParent)
435  {
436  pParent->setInCurrentCalcul(state, false, recursparent);
437  }
438  }
439 }
440 
442 {
443  // Collecte des childs
444  LPTYElementArray childs;
445  getChilds(childs, false);
446 
447  if (childs.size() > 0)
448  {
449  // Appel recursif
450  bool onechildpresent = false;
451  for (int i = 0; i < childs.size(); i++)
452  {
453  onechildpresent = onechildpresent || (childs[i]->isInCurrentCalcul());
454  }
455 
456  // the parent is in the calcul if at least one of its direct children is in the calcul.
457  setInCurrentCalcul(onechildpresent, false);
458  }
459 }
460 
461 void TYElement::updateCurrentCalcul(TYListID& listID, bool recursif) //=true
462 {
463  bool present = false;
464  TYListID::iterator ite;
465 
466  // Parcours de la selection du calcul
467  for (ite = listID.begin(); ite != listID.end(); ++ite)
468  {
469  if ((*ite) == getID())
470  {
471  // Cet element est present dans la liste
472  present = true;
473  break;
474  }
475  }
476 
477  setInCurrentCalcul(present, false);
478 
479  if (recursif)
480  {
481  // Collecte des childs
482  LPTYElementArray childs;
483  getChilds(childs, false);
484  for (unsigned int i = 0; i < childs.size(); i++)
485  {
486  childs[i]->updateCurrentCalcul(listID, recursif);
487  }
488  }
489 }
490 
491 #if TY_USE_IHM
492 void TYElement::drawGraphic(bool draw)
493 {
494  if (draw)
495  {
496  if (getGraphicObject())
497  {
498  getGraphicObject()->setVisible(true);
499  }
500 
501  // Mise a jour
502  updateGraphic();
503  }
504  else
505  {
506  if (getGraphicObject())
507  {
508  getGraphicObject()->setVisible(false);
509  }
510  }
511 }
512 
513 void TYElement::updateGraphic()
514 {
515  if (getGraphicObject())
516  {
517  getGraphicObject()->update();
518  }
519 }
520 
521 void TYElement::updateGraphicTree()
522 {
523  if (getGraphicObject())
524  {
525  getGraphicObject()->updateTree();
526  }
527 }
528 
529 TYEditWidget* TYElement::getEditWidget()
530 {
531  return new TYElementWidget(this);
532 }
533 
534 int TYElement::edit(TYEditWidget* pParent /*=NULL*/)
535 {
536  int ret = -1;
537 
538  ret = TYWidget::edit(this, pParent);
539 
540  return ret;
541 }
542 
543 #endif // TY_USE_IHM
544 
545 bool TYElement::callFromXMLIfEqual(DOM_Element& domElement, int* pRetVal /*=NULL*/)
546 {
547  bool bRet = false;
548  int retVal = 0; // INIT to 0 Projet_Tympan to avoid warnings on g++
549  if (pRetVal)
550  {
551  retVal = *pRetVal;
552  } // Recuperation de la valeur de pRetVal
553 
554  if (domElement.nodeName().compare(QString(getMetierName().data())) == 0)
555  {
556  retVal = fromXML(domElement);
557  bRet = true;
558  }
559 
560  if (pRetVal)
561  {
562  *pRetVal = retVal;
563  } // Si demandee, propagation de la valeur de retval
564 
565  return bRet;
566 }
567 
569 {
570  return &this->getClassName()[2];
571 }
572 
574  const char* type)
575 {
576  LPTYElementArray eltCollection;
577  LPTYElement pElt = NULL;
578  DOM_Element elemCur;
579 
580  QDomNodeList childs = parentElem.childNodes();
581  QString str;
582 
583  for (unsigned int i = 0; i < childs.length(); i++)
584  {
585  elemCur = childs.item(i).toElement();
586 
587  // Ajout du prefixe TY
588  QString nodeName = elemCur.nodeName();
589  str = "TY";
590  str += nodeName;
591 
592  try
593  {
594  // Auto construction
595  pElt = dynamic_cast<TYElement*>(TYElement::findAndClone((char*)str.toLatin1().data()));
596  }
597  catch (tympan::invalid_data&)
598  {
599  pElt = nullptr;
600  }
601 
602  // For now we don't look at the hierarchy. Let's suppose we are
603  // looking for the very type we cloned which is the most likely hypothesis
604  if ((pElt != nullptr) && (strcmp(pElt->getClassName(), type) == 0))
605  {
606  // Parsing XML
607  pElt->fromXML(elemCur);
608 
609  // Ajout
610  eltCollection.push_back(pElt);
611  }
612  }
613  return eltCollection;
614 }
615 
617 {
618  TYUUID newID;
619  newID.GenUniqueID();
621  return newID;
622 }
623 
624 /*static*/ TYUUID TYElement::fromString(QString id)
625 {
626  TYUUID newID(id);
627  return newID;
628 }
629 
630 /*static*/ QString TYElement::toString(TYUUID& uuid)
631 {
632  return uuid.toString();
633 }
634 
636 {
637  return ty_created_counter;
638 }
640 {
641  return ty_destroyed_counter;
642 }
643 
645 {
646  return ty_regen_id_counter;
647 }
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
outil IHM pour un element (fichier header)
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:344
std::map< TYUUID, TYElement * > TYElementContainer
Definition: TYElement.h:346
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:283
virtual ~OPrototype()
Definition: TYElement.cpp:30
static std::unordered_map< std::string, IOProtoFactory::ptr_type > _factory_map
Definition: TYElement.h:329
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:248
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:988
bool _bPutInInstanceList
Definition: TYElement.h:962
void setID(TYUUID id)
Definition: TYElement.cpp:186
static uint64 ty_regen_id_counter
Definition: TYElement.h:994
static TYElementContainer & getInstances()
Definition: TYElement.cpp:95
TYElement * getParent() const
Definition: TYElement.h:697
static bool _logInstances
Indique si on souhaite registrer toutes les instances de type TYElement et derivees.
Definition: TYElement.h:981
void addInstance()
Definition: TYElement.cpp:226
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:305
TYUUID _uuid
Identifiant unique de l'element.
Definition: TYElement.h:952
void remInstance()
Definition: TYElement.cpp:235
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:366
void setCopyCount(const unsigned int copyCount)
Modifie la vaeur du compteur.
Definition: TYElement.h:555
std::string getMetierName()
Definition: TYElement.cpp:568
QString _name
Nom courant de l'element.
Definition: TYElement.h:956
bool operator==(const TYElement &other) const
Definition: TYElement.cpp:280
static void purgeInstances()
Definition: TYElement.cpp:171
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:263
static TYUUID fromString(QString id)
Definition: TYElement.cpp:624
void OnChildInCalculStatusChange()
Definition: TYElement.cpp:441
static uint64 getConstructorCount()
Definition: TYElement.cpp:635
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:545
static bool testId(const TYUUID &id, const TYElement *pElem)
Definition: TYElement.cpp:216
static uint64 getIdGenerationCount()
Definition: TYElement.cpp:644
bool _isAcousticModified
Indicateur de modification acoustique.
Definition: TYElement.h:971
void regenerateID()
Definition: TYElement.cpp:243
bool hasNullID() const
Definition: TYElement.h:656
static uint64 getDestructorCount()
Definition: TYElement.cpp:639
const TYUUID & getID() const
Definition: TYElement.cpp:176
bool operator!=(const TYElement &other) const
Definition: TYElement.cpp:300
static TYUUID newID()
Definition: TYElement.cpp:616
void * _allUses
Multi purpose void pointer (use for compatibility actually)
Definition: TYElement.h:977
virtual std::string toString() const
Definition: TYElement.h:776
TYElement * _pParent
Reference sur l'element parent.
Definition: TYElement.h:959
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYElement.cpp:461
LPTYElementGraphic _pGraphicObject
L'object graphique metier associe a cet element.
Definition: TYElement.h:974
virtual void setInCurrentCalcul(bool state, bool recurschild=true, bool recursparent=true)
Definition: TYElement.cpp:408
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:530
static TYElementContainer * _instances
Collection de toutes les instances de type TYElement et derivees.
Definition: TYElement.h:984
bool _inCurrentCalcul
Indique si cet element est actif dans le Calcul courant.
Definition: TYElement.h:968
static LPTYElementArray findTypeCollectionAndCallFromXML(DOM_Element parentElem, const char *type)
Definition: TYElement.cpp:573
virtual ~TYElement()
Definition: TYElement.cpp:139
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:379
virtual void setIsAcousticModified(bool isModified)
Definition: TYElement.cpp:248
unsigned int _copyCount
Definition: TYElement.h:965
static uint64 ty_destroyed_counter
Definition: TYElement.h:993
static uint64 ty_created_counter
Definition: TYElement.h:992
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:990
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
static int edit(TYElement *pElement, QWidget *pParent=NULL)
Definition: TYWidget.cpp:45
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:91
unsigned long long uint64
Definition: defines.h:80
boost::error_info< struct tag_classname, std::string > oproto_classname_errinfo
Definition: TYElement.h:91
The base exception class for errors due to invalid data.
Definition: exceptions.h:75