Code_TYMPAN  4.2.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 
17 #include <string.h>
18 #include <iostream>
19 
20 #include "Tympan/core/idgen.h"
21 #include "Tympan/core/chrono.h"
22 #include "Tympan/core/exceptions.h"
23 #include "Tympan/core/logging.h"
24 #include "TYElement.h"
25 
26 
27 
28 // Declaration des membres statiques.
29 std::unordered_map<std::string, OPrototype::IOProtoFactory::ptr_type> OPrototype::_factory_map;
30 
32 {
33 }
34 
36 {
37 }
38 
39 /* static */ void OPrototype::add_factory(const char * classname,
41 {
42  _factory_map[std::string(classname)] = move(factory);
43 }
44 
45 /*static*/ OPrototype* OPrototype::findAndClone(const char* className)
46 {
47  auto it = _factory_map.find(className);
48 
49  if (it == _factory_map.end())
50  {
51  std::string err_msg ("Asked to clone class ");
52  err_msg.append (className);
53  err_msg.append (" which isn't registered in OPrototype.");
54  throw tympan::invalid_data(err_msg) << tympan_source_loc
56  }
57  else
58  {
59  return _factory_map[className]->make().release();
60  }
61 }
62 
63 /*static*/ int OPrototype::findPrototype(const char* className)
64 {
65  if (className == 0) { return -1; }
66  // Return 1 if the class className exists, -1 otherwise
67  return (_factory_map.count(className) > 0 ? 1 : -1);
68 }
69 
70 bool OPrototype::isA(const char* className) const
71 {
72  // Test le nom du type
73  return (!strcmp(className, this->getClassName()));
74 }
75 
77 {
78  return (OPrototype*) pObject;
79 }
80 
81 
82 // -------------------------------------------------------------------------
83 // classe TYElement
84 // -------------------------------------------------------------------------
85 
86 
92 bool TYElement::_logInstances = false;
93 // TYListPtrElement* TYElement::_instances = NULL;
95 
96 bool TYElement::_toSave = false;
97 bool TYElement::_bRegenerateID = false;
98 
99 
103 
105 {
106  if (_instances == NULL)
107  {
108  _instances = new TYElementContainer();
109  }
110 
111  return *_instances;
112 }
113 
114 TYElement::TYElement() : _pParent(nullptr),
115  _bPutInInstanceList(true),
116  _copyCount(0),
117  _inCurrentCalcul(true),
118  _isAcousticModified(true),
119  _isGeometryModified(true),
120  _pGraphicObject(nullptr),
121  _allUses(nullptr)
122 {
124  {
125  addInstance();
126  }
128 }
129 
130 TYElement::TYElement(TYElement* pParent, bool PutInInstanceList) :
131  _pParent(pParent),
132  _bPutInInstanceList(PutInInstanceList),
133  _copyCount(0),
134  _inCurrentCalcul(true),
135  _isAcousticModified(true),
136  _isGeometryModified(true),
137  _pGraphicObject(nullptr),
138  _allUses(nullptr)
139 {
141  {
142  addInstance();
143  }
144 
146 }
147 
148 TYElement::TYElement(const TYElement& other, bool PutInInstanceList/*= true*/) :
149  _bPutInInstanceList(PutInInstanceList)
150 {
151  *this = other;
152 
154  {
155  addInstance();
156  }
157 }
158 
160 {
162  {
163  remInstance();
164  }
165 #if TY_USE_IHM
166  if (_pGraphicObject)
167  {
169  _pGraphicObject = NULL;
170  }
171 #endif
172 
173  _pParent = nullptr;
174 
176 }
177 
179 {
180  TYElementContainer::const_iterator elt_it = getInstances().find(uuid);
181  if (elt_it != getInstances().end())
182  {
183  return elt_it->second;
184  }
185 
186  OMessageManager::get()->error("instance not found: %s",
187  uuid.toString().toUtf8().data());
188 
189  return NULL;
190 }
191 
193 {
194  getInstances().clear();
195 }
196 
197 const TYUUID& TYElement::getID() const
198 {
199  if (hasNullID())
200  {
201  _uuid = newID();
202  }
203 
204  return _uuid;
205 }
206 
208 {
209  // If the _uuid is not NULL, we remove it from the map.
210  bool was_registered = false;
211  if (!hasNullID())
212  {
213  // size_t remove_count = getInstances().erase(_uuid);
214  TYElementContainer::iterator it = getInstances().find(_uuid);
215  if (it != getInstances().end())
216  {
217  getInstances().erase(it);
218  was_registered = true;
219  }
220  }
221 
222  _uuid = id;
223 
224  // If the element was registered, we update the map (new insertion).
225  if (was_registered)
226  {
227  getInstances().insert(std::make_pair(_uuid, this));
228  }
229 }
230 
231 void TYElement::setID(const QString& str_id)
232 {
233  TYUUID new_uuid(str_id);
234  setID(new_uuid);
235 }
236 
237 
238 bool TYElement::testId(const TYUUID& id, const TYElement* pElem)
239 {
240  TYElement* pEl = getInstance(id);
241  if (pEl != pElem) { return true; }
242  return false;
243 }
244 
246 {
247  if (_logInstances)
248  {
249  const TYUUID& uuid = getID(); // Could force the generation of the UUID.
250  getInstances().insert(std::make_pair(uuid, this));
251  }
252 }
253 
254 
256 {
257  if (!hasNullID())
258  {
259  getInstances().erase(getID());
260  }
261 }
262 
263 
265 {
266  setID(newID());
267 }
268 
269 void TYElement::setIsAcousticModified(bool isModified)
270 {
271  _isAcousticModified = isModified;
272 }
273 
274 void TYElement::setIsGeometryModified(bool isModified)
275 {
276  _isGeometryModified = isModified;
277 
278 #if TY_USE_IHM
279  if (_pGraphicObject && isModified)
280  {
282  }
283 #endif
284 }
285 
287 {
288  if (this != &other)
289  {
290  setID(other.getID());
291  _name = other._name;
292  _pParent = other._pParent;
294  _copyCount = other._copyCount;
295  _allUses = other._allUses;
296 
297  setIsGeometryModified(true);
298  setIsAcousticModified(true);
299  }
300  return *this;
301 }
302 
303 bool TYElement::operator == (const TYElement& other) const
304 {
305  if (this != &other)
306  {
307  if (getID() != other.getID()) { return false; }
308  if (_name != other._name) { return false; }
309  if (_pParent != other._pParent) { return false; }
310  }
311  return true;
312 }
313 
314 bool TYElement::operator != (const TYElement& other) const
315 {
316  return !operator==(other);
317 }
318 
319 bool TYElement::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*= false*/ )
320 {
321  QString copyTag;
322  if (!pOther) { return false; } // XXX assert(pOther);
323 
324  // For now we don't look at the hierarchy. Let's suppose we are expecting
325  // to copy an element of the same class as this
326  if (strcmp(pOther->getClassName(), getClassName()) != 0) { return false; }
327 
328  _name = pOther->_name;
329  _pParent = pOther->_pParent;
331  _copyCount = pOther->_copyCount;
332  _allUses = pOther->_allUses;
333 
334  _copyCount++;
335 
336  if (pUseCopyTag)
337  {
338  copyTag = QString("Copie (%1) de :").arg(_copyCount);
339  }
340  else
341  {
342  copyTag = QString("");
343  }
344 
345  if (copyId)
346  {
347  setID(pOther->getID());
348  copyTag = "";
349  _copyCount > 0 ? _copyCount-- : 0 ;
350  }
351 
352  TYElement* pOther2 = const_cast<TYElement*>(pOther);
353  pOther2->setCopyCount(_copyCount);
354 
355  if (_copyCount > 1)
356  {
357  QStringList strLst = _name.split(':');
358  if (strLst.size() > 1)
359  {
360  _name = strLst[1];
361  }
362  }
363 
364  _name = copyTag + _name;
365 
366  _pGraphicObject = NULL;
367 
368  setIsGeometryModified(true);
369  setIsAcousticModified(true);
370 
371  return true;
372 }
373 
374 DOM_Element TYElement::toXML(DOM_Element& domElement) /* const */
375 {
376  QDomDocument domDoc = domElement.ownerDocument();
377  QDomElement domNewElem = domDoc.createElement(getMetierName().data());
378 
379  domNewElem.setAttribute("id", getID().toString());
380  domNewElem.setAttribute("name", _name);
381 
382  domElement.appendChild(domNewElem);
383 
384  return domNewElem;
385 }
386 
388 {
389  QString tmpString = TYXMLTools::getElementAttributeToString(domElement, "id");
390  if (tmpString.size() == 0)
391  {
392  // regenerateID(); //XXX
393  }
394  else
395  {
396  setID(tmpString);
397  }
398 
399  QString name = TYXMLTools::getElementAttributeToString(domElement, "name");
400  if (!name.isEmpty())
401  {
402  _name = name;
403  }
404 
405  if (_bRegenerateID) { regenerateID(); }
406 
407  setIsGeometryModified(true);
408  setIsAcousticModified(true);
409 
410  return 1;
411 }
412 
413 void TYElement::setInCurrentCalcul(bool state, bool recurschild /*= true*/, bool recursparent /*= true*/)
414 {
415  // Set state for this object
416  _inCurrentCalcul = state;
417  setIsGeometryModified(true);
418 
420  //if (recurschild) {
421  // // Collecte des childs
422  // LPTYElementArray childs;
423  // getChilds(childs, false);
424  //
425  // // Appel recursif
426  // for (int i = 0; i < childs.size(); i++)
427  // {
428  // childs[i]->setInCurrentCalcul(state, recurschild, false);
429  // }
430  //}
431 
432 
433  // update parent status (uniquement en cas d'activation)
434  if (recursparent && state)
435  {
436  TYElement* pParent = getParent();
437  if (pParent) { pParent->setInCurrentCalcul(state, false, recursparent); }
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) { retVal = *pRetVal; } // Recuperation de la valeur de pRetVal
550 
551  if (domElement.nodeName().compare(QString(getMetierName().data())) == 0)
552  {
553  retVal = fromXML(domElement);
554  bRet = true;
555  }
556 
557  if (pRetVal) { *pRetVal = retVal; } // Si demandee, propagation de la valeur de retval
558 
559  return bRet;
560 }
561 
563 {
564  return &this->getClassName()[2];
565 }
566 
567 
569 {
570  LPTYElementArray eltCollection;
571  LPTYElement pElt = NULL;
572  DOM_Element elemCur;
573 
574  QDomNodeList childs = parentElem.childNodes();
575  QString str;
576 
577  for (unsigned int i = 0; i < childs.length(); i++)
578  {
579  elemCur = childs.item(i).toElement();
580 
581  // Ajout du prefixe TY
582  QString nodeName = elemCur.nodeName();
583  str = "TY";
584  str += nodeName;
585 
586  try
587  {
588  // Auto construction
589  pElt = dynamic_cast<TYElement*>(TYElement::findAndClone((char*)str.toLatin1().data()));
590  }
591  catch(tympan::invalid_data&) {pElt = nullptr;}
592 
593  // For now we don't look at the hierarchy. Let's suppose we are
594  // looking for the very type we cloned which is the most likely hypothesis
595  if ((pElt != nullptr) && (strcmp(pElt->getClassName(), type) == 0))
596  {
597  // Parsing XML
598  pElt->fromXML(elemCur);
599 
600  // Ajout
601  eltCollection.push_back(pElt);
602  }
603  }
604  return eltCollection;
605 }
606 
607 
608 
610 {
611  TYUUID newID;
612  newID.GenUniqueID(); ++ty_regen_id_counter;
613  return newID;
614 }
615 
616 /*static*/ TYUUID TYElement::fromString(QString id)
617 {
618  TYUUID newID(id);
619  return newID;
620 }
621 
622 /*static*/ QString TYElement::toString(TYUUID& uuid)
623 {
624  return uuid.toString();
625 }
626 
628 {
629  return ty_created_counter;
630 }
632 {
633  return ty_destroyed_counter;
634 }
635 
637 {
638  return ty_regen_id_counter;
639 }
static uint64 ty_regen_id_counter
Definition: TYElement.h:925
LPTYElementGraphic _pGraphicObject
L&#39;object graphique metier associe a cet element.
Definition: TYElement.h:906
std::map< TYUUID, TYElement * > TYElementContainer
Definition: TYElement.h:340
The base exception class for errors due to invalid data.
Definition: exceptions.h:60
QDomElement DOM_Element
Definition: QT2DOM.h:31
static uint64 getConstructorCount()
Definition: TYElement.cpp:627
static bool _toSave
Indicateur de modification. Passe a true si un TYElement a ete modifie, Indique la necessite de sauve...
Definition: TYElement.h:919
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:76
TYElement * _pParent
Reference sur l&#39;element parent.
Definition: TYElement.h:888
bool operator!=(const TYElement &other) const
Definition: TYElement.cpp:314
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:387
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:274
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:517
const char * name
static TYElementContainer & getInstances()
Definition: TYElement.cpp:104
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:338
static TYElementContainer * _instances
Collection de toutes les instances de type TYElement et derivees.
Definition: TYElement.h:916
static uint64 getDestructorCount()
Definition: TYElement.cpp:631
static void add_factory(const char *, IOProtoFactory::ptr_type factory)
Definition: TYElement.cpp:39
static void purgeInstances()
Definition: TYElement.cpp:192
static bool _logInstances
Indique si on souhaite registrer toutes les instances de type TYElement et derivees.
Definition: TYElement.h:913
void remInstance()
Definition: TYElement.cpp:255
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:286
virtual ~OPrototype()
Definition: TYElement.cpp:35
void setID(TYUUID id)
Definition: TYElement.cpp:207
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:319
void TYEditWidget
Declarations de types pour l&#39;API IHM et l&#39;Impression.
Definition: TYDefines.h:53
virtual std::string toString() const
Definition: TYElement.h:735
bool operator==(const TYElement &other) const
Definition: TYElement.cpp:303
bool _isGeometryModified
Indicateur de modification de la geometrie.
Definition: TYElement.h:903
static QString getElementAttributeToString(DOM_Element parentElem, DOMString attName)
Definition: TYXMLTools.cpp:250
void setCopyCount(const unsigned int copyCount)
Modifie la vaeur du compteur.
Definition: TYElement.h:536
const TYUUID & getID() const
Definition: TYElement.cpp:197
void regenerateID()
Definition: TYElement.cpp:264
void * _allUses
Multi purpose void pointer (use for compatibility actually)
Definition: TYElement.h:909
bool isA(const char *className) const
Definition: TYElement.cpp:70
unsigned int _copyCount
Definition: TYElement.h:894
static bool _bRegenerateID
Indicateur de regeneration d&#39;ID true si regeneration d&#39;ID a la lecture d&#39;un fichier XML...
Definition: TYElement.h:921
unsigned long long uint64
Definition: defines.h:66
static TYUUID newID()
Definition: TYElement.cpp:609
static OPrototype * findAndClone(const char *className)
Definition: TYElement.cpp:45
TYElement * getParent() const
Definition: TYElement.h:656
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:374
static OMessageManager * get()
Definition: logging.cpp:110
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYElement.cpp:461
virtual void setIsAcousticModified(bool isModified)
Definition: TYElement.cpp:269
QString _name
Nom courant de l&#39;element.
Definition: TYElement.h:885
classe de l&#39;objet IHM pour un element
static TYElement * getInstance(TYUUID uuid)
Definition: TYElement.cpp:178
boost::error_info< struct tag_classname, std::string > oproto_classname_errinfo
Definition: TYElement.h:88
static std::unordered_map< std::string, IOProtoFactory::ptr_type > _factory_map
Definition: TYElement.h:324
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:545
virtual const char * getClassName() const
Definition: TYElement.h:248
TYUUID _uuid
Identifiant unique de l&#39;element.
Definition: TYElement.h:881
static bool testId(const TYUUID &id, const TYElement *pElem)
Definition: TYElement.cpp:238
int id
bool _bPutInInstanceList
Definition: TYElement.h:891
static int edit(TYElement *pElement, QWidget *pParent=NULL)
Definition: TYWidget.cpp:49
class OGenID TYUUID
Definition: TYDefines.h:63
static int findPrototype(const char *className)
Definition: TYElement.cpp:63
void OnChildInCalculStatusChange()
Definition: TYElement.cpp:441
virtual void error(const char *message,...)
Definition: logging.cpp:129
static LPTYElementArray findTypeCollectionAndCallFromXML(DOM_Element parentElem, const char *type)
Definition: TYElement.cpp:568
std::list< TYUUID > TYListID
Collection d&#39;identifiants.
Definition: TYDefines.h:336
bool _isAcousticModified
Indicateur de modification acoustique.
Definition: TYElement.h:900
void setElement(TYElement *pElt)
void setModified(bool modified=true)
#define tympan_source_loc
This macro build a source_loc object to be attached to a tympan::Exception.
Definition: exceptions.h:78
virtual void setInCurrentCalcul(bool state, bool recurschild=true, bool recursparent=true)
Definition: TYElement.cpp:413
static uint64 ty_created_counter
Definition: TYElement.h:923
virtual ~TYElement()
Definition: TYElement.cpp:159
std::unique_ptr< IOProtoFactory > ptr_type
Definition: TYElement.h:280
static uint64 getIdGenerationCount()
Definition: TYElement.cpp:636
bool _inCurrentCalcul
Indique si cet element est actif dans le Calcul courant.
Definition: TYElement.h:897
static TYUUID fromString(QString id)
Definition: TYElement.cpp:616
std::string getMetierName()
Definition: TYElement.cpp:562
bool hasNullID() const
Definition: TYElement.h:630
static uint64 ty_destroyed_counter
Definition: TYElement.h:924
void addInstance()
Definition: TYElement.cpp:245