Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
VariableRef.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* VariableRef.cc (C) 2000-2024 */
9/* */
10/* Référence à une variable. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/InvalidArgumentException.h"
17#include "arcane/utils/IStackTraceService.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/PlatformUtils.h"
20
21#include "arcane/VariableRef.h"
22#include "arcane/VariableBuildInfo.h"
23#include "arcane/ISubDomain.h"
24#include "arcane/IModule.h"
25#include "arcane/IVariableMng.h"
26#include "arcane/ArcaneException.h"
27
28#include <set>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38/*!
39 * \brief Classe interne pour gérer les fonctor appelés lors de la mise à jour
40 * de la variable.
41 *
42 * Les fonctors sont en général ceux du wrapper C#. La principale difficulté
43 * pour traiter ces fonctor est qu'ils sont gérer par le runtime C# et donc
44 * utilisent un garbage collector. Il n'est donc pas possible de savoir
45 * exactement quand ces fonctors seront détruits. Une instance de cette
46 * classe ne doit donc pas être détruite explicitement. Lorsque la
47 * variable possédant une instance de cette classe est détruite, elle
48 * appelle destroy() pour signaler que l'objet peut être détruit. Dès
49 * qu'il n'y a plus de fonctor référencés, cela signifie que tous les
50 * objets C# sont détruits et donc on peut détruire l'instance.
51 */
53{
54 public:
55 typedef void (*ChangedFunc)();
56 public:
57 UpdateNotifyFunctorList() : m_is_destroyed(false){}
58 private:
59 std::set<ChangedFunc> m_funcs;
60 bool m_is_destroyed;
61 public:
62 void execute()
63 {
64 std::set<ChangedFunc>::const_iterator begin = m_funcs.begin();
65 std::set<ChangedFunc>::const_iterator end = m_funcs.end();
66 for( ; begin!=end; ++begin ){
67 ChangedFunc f = *begin;
68 (*f)();
69 }
70 }
71
72 void destroy()
73 {
74 // Indique qu'on detruit.
75 // Mais ne fais pas de delete tant que m_funcs n'est pas vide.
76 m_is_destroyed = true;
77 if (m_funcs.empty())
78 delete this;
79 }
80
81 void add(ChangedFunc f)
82 {
83 m_funcs.insert(f);
84 }
85
86 void remove(ChangedFunc f)
87 {
88 m_funcs.erase(f);
89 _checkDestroy();
90 }
91 public:
92 static void* _add(VariableRef* var,void (*func)())
93 {
94 //std::cout << "_SET_MESH_VARIABLE_CHANGED_DELEGATE"
95 // << " name=" << var->name()
96 // << " func=" << (void*)func
97 // << " this=" << var
98 // << '\n';
99 if (!var->m_notify_functor_list){
100 var->m_notify_functor_list = new VariableRef::UpdateNotifyFunctorList();
101 }
102 var->m_notify_functor_list->add(func);
103 return var->m_notify_functor_list;
104 }
105 static void _remove(UpdateNotifyFunctorList* functor_list,
106 void (*func)())
107 {
108 //std::cout << "_REMOVE_MESH_VARIABLE_CHANGED_DELEGATE"
109 // << " functor=" << functor_list
110 // << '\n';
111 functor_list->remove(func);
112 }
113 private:
114
115 void _checkDestroy()
116 {
117 if (m_is_destroyed && m_funcs.empty())
118 delete this;
119 }
120};
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
127: m_module(vbi.module())
128, m_reference_property(vbi.property())
129{
130 //cout << "VAR NAME=" << vbi.name() << " this="
131 // << this << " module=" << m_module << '\n';
132 _setAssignmentStackTrace();
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
140: m_variable(var)
141, m_reference_property(var->property())
142{
143 //cout << "VAR NAME=" << vbi.name() << " this="
144 // << this << " module=" << m_module << '\n';
145 _setAssignmentStackTrace();
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150/*!
151 * \brief Constructeur pour une variable non enregistree.
152 *
153 * Ce constructeur n'est utilise que pour le wrapping C#. En C++,
154 * il n'est pas accessible pour être sur que l'utilisateur n'a pas
155 * de variables non référencées
156 */
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
166VariableRef(const VariableRef& from)
167: m_variable(from.m_variable)
168, m_module(from.m_module)
169, m_reference_property(from.m_reference_property)
170{
171 _setAssignmentStackTrace();
172 //cout << "** TODO: check variable copy constructor with linked list\n";
173 // NOTE:
174 // C'est la variable qui met à jour m_previous_reference et m_next_reference
175 // dans registerVariable.
176 if (from.m_variable)
178}
179
180/*---------------------------------------------------------------------------*/
181/*---------------------------------------------------------------------------*/
182
184operator=(const VariableRef& rhs)
185{
186 if (this != &rhs) {
187 if (rhs.m_variable != m_variable)
188 _internalAssignVariable(rhs);
189 }
190 return (*this);
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
198{
199 //cout << "DESTROY VAR NAME=" << name() << " this=" << this << '\n';
200 //cout << "Unregistering variable ref " << this << '\n';
201 //cout.flush();
202 if (m_notify_functor_list)
203 m_notify_functor_list->destroy();
204 if (m_is_registered)
206}
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211void VariableRef::
212_setAssignmentStackTrace()
213{
214 m_assignment_stack_trace = String();
215 if (hasTraceCreation()){
216 IStackTraceService* stack_service = platform::getStackTraceService();
217 if (stack_service){
218 m_assignment_stack_trace = stack_service->stackTrace().toString();
219 }
220 }
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
228{
229 _checkValid();
230 m_variable->removeVariableRef(this);
231 m_is_registered = false;
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
239{
240 _checkValid();
241 m_variable->addVariableRef(this);
242 m_is_registered = true;
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
249_internalInit(IVariable* variable)
250{
251 m_variable = variable;
254 // Les variables autres que celles sur le maillage sont toujours utilisées
255 // par défaut
257 setUsed(true);
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
264dataType() const
265{
266 _checkValid();
267 return m_variable->dataType();
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
274print(std::ostream& o) const
275{
276 _checkValid();
277 m_variable->print(o);
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
284name() const
285{
286 _checkValid();
287 return m_variable->name();
288}
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
292
294property() const
295{
296 _checkValid();
297 return m_variable->property();
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
304subDomain() const
305{
306 _checkValid();
307 return m_variable->subDomain();
308}
309
310/*---------------------------------------------------------------------------*/
311/*---------------------------------------------------------------------------*/
312
314variableMng() const
315{
316 _checkValid();
317 return m_variable->variableMng();
318}
319
320/*---------------------------------------------------------------------------*/
321/*---------------------------------------------------------------------------*/
322
324checkIfSync(int max_print)
325{
326 _checkValid();
327 return m_variable->checkIfSync(max_print);
328}
329
330/*---------------------------------------------------------------------------*/
331/*---------------------------------------------------------------------------*/
332
334checkIfSameOnAllReplica(int max_print)
335{
336 _checkValid();
337 return m_variable->checkIfSameOnAllReplica(max_print);
338}
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
344referenceProperty() const
345{
346 return m_reference_property;
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360void VariableRef::
361_throwInvalid() const
362{
363 String msg("Using a reference on a uninitialized variable");
364 throw InternalErrorException(A_FUNCINFO,msg);
365}
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
369
371setProperty(int property)
372{
373 if (!_checkValidPropertyChanged(property))
374 throw InvalidArgumentException(A_FUNCINFO,"property",property);
375 m_reference_property |= property;
376 m_variable->notifyReferencePropertyChanged();
377}
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
383unsetProperty(int property)
384{
385 if (!_checkValidPropertyChanged(property))
386 throw InvalidArgumentException(A_FUNCINFO,"property",property);
387 m_reference_property &= ~property;
388 m_variable->notifyReferencePropertyChanged();
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393/*!
394 * \brief Regarde si une propriété peut-être changée dynamiquement.
395 */
396bool VariableRef::
397_checkValidPropertyChanged(int property)
398{
399 switch(property){
409 return true;
412 return false;
413 default:
414 break;
415 }
416 return false;
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
426update()
427{
428 m_variable->update();
429}
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
433
436{
437 m_variable->setUpToDate();
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
445{
446 return m_variable->modifiedTime();
447}
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
454{
455 m_variable->addDepend(var.variable(),IVariable::DPT_CurrentTime);
456}
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
463{
464 m_variable->addDepend(var.variable(),IVariable::DPT_PreviousTime);
465}
466
467/*---------------------------------------------------------------------------*/
468/*---------------------------------------------------------------------------*/
469
471addDependCurrentTime(const VariableRef& var,const TraceInfo& tinfo)
472{
473 m_variable->addDepend(var.variable(),IVariable::DPT_CurrentTime,tinfo);
474}
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
480addDependPreviousTime(const VariableRef& var,const TraceInfo& tinfo)
481{
482 m_variable->addDepend(var.variable(),IVariable::DPT_PreviousTime,tinfo);
483}
484
485/*---------------------------------------------------------------------------*/
486/*---------------------------------------------------------------------------*/
487
489removeDepend(const VariableRef& var)
490{
491 m_variable->removeDepend(var.variable());
492}
493
494/*---------------------------------------------------------------------------*/
495/*---------------------------------------------------------------------------*/
496
497void VariableRef::
498_setComputeFunction(IVariableComputeFunction* v)
499{
500 m_variable->setComputeFunction(v);
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
507addTag(const String& tagname,const String& tagvalue)
508{
509 m_variable->addTag(tagname,tagvalue);
510}
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
516removeTag(const String& tagname)
517{
518 m_variable->removeTag(tagname);
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
525hasTag(const String& tagname) const
526{
527 return m_variable->hasTag(tagname);
528}
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
532
534tagValue(const String& tagname) const
535{
536 return m_variable->tagValue(tagname);
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
544{
545 return m_previous_reference;
546}
547
548/*---------------------------------------------------------------------------*/
549/*---------------------------------------------------------------------------*/
550
553{
554 return m_next_reference;
555}
556
557/*---------------------------------------------------------------------------*/
558/*---------------------------------------------------------------------------*/
559
560void VariableRef::
561setPreviousReference(VariableRef* v)
562{
563 m_previous_reference = v;
564}
565
566/*---------------------------------------------------------------------------*/
567/*---------------------------------------------------------------------------*/
568
569void VariableRef::
570setNextReference(VariableRef* v)
571{
572 m_next_reference = v;
573}
574
575/*---------------------------------------------------------------------------*/
576/*---------------------------------------------------------------------------*/
577
578/*---------------------------------------------------------------------------*/
579/*---------------------------------------------------------------------------*/
580
581bool VariableRef::m_static_has_trace_creation = false;
582
583/*---------------------------------------------------------------------------*/
584/*---------------------------------------------------------------------------*/
585
586void VariableRef::
587setTraceCreation(bool v)
588{
589 m_static_has_trace_creation = v;
590}
591
592/*---------------------------------------------------------------------------*/
593/*---------------------------------------------------------------------------*/
594
595bool VariableRef::
596hasTraceCreation()
597{
598 return m_static_has_trace_creation;
599}
600
601/*---------------------------------------------------------------------------*/
602/*---------------------------------------------------------------------------*/
603
604void VariableRef::
605_executeUpdateFunctors()
606{
607 if (m_notify_functor_list)
608 m_notify_functor_list->execute();
609}
610
611/*---------------------------------------------------------------------------*/
612/*---------------------------------------------------------------------------*/
613
614void VariableRef::
615_internalAssignVariable(const VariableRef& var)
616{
617 _setAssignmentStackTrace();
618 if (m_is_registered)
620 m_module = var.m_module;
621 m_variable = var.m_variable;
622 m_reference_property = var.m_reference_property;
623 m_has_trace = false;
624 // NE PAS TOUCHER A: m_notify_functor_list
625 //NOTE:
626 // C'est la variable qui met à jour m_previous_reference et m_next_reference
627 // dans registerVariable.
628 //cout << "** TODO: check variable operator= with linked list\n";
630}
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634/*
635 * \internal
636 * \brief Ajoute un fonctor pour le wrapping C#.
637 */
638extern "C" ARCANE_CORE_EXPORT void*
639_AddVariableChangedDelegate(VariableRef* var,void (*func)())
640{
641 return VariableRef::UpdateNotifyFunctorList::_add(var,func);
642}
643
644/*
645 * \internal
646 * \brief Supprimer un fonctor pour le wrapping C#.
647 */
648extern "C" ARCANE_CORE_EXPORT void
649_RemoveVariableChangedDelegate(VariableRef::UpdateNotifyFunctorList* functor_list,
650 void (*func)())
651{
652 VariableRef::UpdateNotifyFunctorList::_remove(functor_list,func);
653}
654
655/*---------------------------------------------------------------------------*/
656/*---------------------------------------------------------------------------*/
657
658} // End namespace Arcane
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface de la classe fonctor de recalcul d'une variable.
Interface du gestionnaire de variables.
virtual eDataType dataType() const =0
Type de la donnée gérée par la variable (Real, Integer, ...)
virtual void addTag(const String &tagname, const String &tagvalue)=0
Ajoute le tag tagname avev la valeur tagvalue.
virtual void print(std::ostream &o) const =0
Imprime les valeurs de la variable sur le flot o.
virtual bool hasTag(const String &tagname)=0
true si la variable possède le tag tagname
virtual void setUpToDate()=0
Indique que la variable vient d'être mise à jour.
@ PSubDomainDepend
Indique que la valeur de la variable est dépendante du sous-domaine.
Definition IVariable.h:91
@ PNoExchange
Indique que la variable ne doit pas être échangée.
Definition IVariable.h:143
@ PNoReplicaSync
Indique que la variable n'a pas forcément la même valeur entre les réplicas.
Definition IVariable.h:159
@ PExecutionDepend
Indique que la valeur de la variable est dépendante de l'exécution.
Definition IVariable.h:106
@ PHasTrace
Indique que la variable est tracée (uniquement en mode trace)
Definition IVariable.h:83
@ PPrivate
Indique que la variable est privée.
Definition IVariable.h:114
@ PPersistant
Indique que la variable est persistante.
Definition IVariable.h:150
@ PNoRestore
Indique que la variable ne doit pas être restaurée.
Definition IVariable.h:133
@ PSubDomainPrivate
Indique que la variable est privée au sous-domaine.
Definition IVariable.h:99
@ PNoNeedSync
Indique que la variable n'est pas nécessairement synchronisée.
Definition IVariable.h:80
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
Definition IVariable.h:72
virtual Integer checkIfSameOnAllReplica(Integer max_print=0)=0
Vérifie si la variable a les mêmes valeurs sur tous les réplicas.
virtual int property() const =0
Retourne les propriétés de la variable.
virtual eItemKind itemKind() const =0
Type des entités du maillage sur lequel repose la variable.
virtual Int64 modifiedTime()=0
Temps auquel la variable a été mise à jour.
virtual String tagValue(const String &tagname)=0
Valeur du tag tagname. La chaîne est nulle si le tag n'existe pas.
virtual Integer checkIfSync(Integer max_print=0)=0
Vérifie si la variable est bien synchronisée.
virtual void notifyReferencePropertyChanged()=0
Indique que les propriétés d'une des références à cette variable ont changé (interne)
virtual void removeDepend(IVariable *var)=0
Supprime var de la liste des dépendances.
virtual ISubDomain * subDomain()=0
Sous-domaine associé à la variable (TODO rendre obsolète fin 2023)
virtual void update()=0
Recalcule la variable si nécessaire.
virtual void addDepend(IVariable *var, eDependType dt)=0
Ajoute var à la liste des dépendances.
virtual void setComputeFunction(IVariableComputeFunction *v)=0
Positionne la fonction de recalcul de la variable.
virtual void removeTag(const String &tagname)=0
Supprime le tag tagname.
virtual void addVariableRef(VariableRef *var_ref)=0
Ajoute une référence à cette variable.
virtual String name() const =0
Nom de la variable.
virtual void removeVariableRef(VariableRef *var_ref)=0
Supprime une référence à cette variable.
virtual IVariableMng * variableMng() const =0
Gestionnaire de variable associé à la variable.
Exception lorsqu'une erreur fatale est survenue.
Paramètres nécessaires à la construction d'une variable.
Classe interne pour gérer les fonctor appelés lors de la mise à jour de la variable.
Référence à une variable.
Definition VariableRef.h:56
virtual Integer checkIfSameOnAllReplica(int max_print=0)
Vérifie si la variable a les mêmes valeurs sur tous les réplicas.
virtual void updateFromInternal()
Mise à jour à partir de la partie interne.
VariableRef & operator=(const VariableRef &from)
Opérateur de recopie.
virtual void setProperty(int property)
Positionne la propriété property.
VariableRef()
Constructeur vide.
virtual eDataType dataType() const
Type de la variable (Real, Integer, ...)
void removeTag(const String &tagname)
Supprime le tag tagname.
virtual Integer checkIfSync(int max_print=0)
Vérifie si la variable est bien synchronisée.
virtual void print(std::ostream &o) const
Affiche la valeur de la variable.
virtual int property() const
Propriétés de la variable.
virtual void unsetProperty(int property)
Supprime la propriété property.
void addTag(const String &tagname, const String &tagvalue)
Ajoute le tag tagname avev la valeur tagvalue.
Int64 modifiedTime()
Temps auquel la variable a été mise à jour.
VariableRef * previousReference()
Référence précédente (ou null) sur variable()
String tagValue(const String &tagname) const
Valeur du tag tagname. La chaîne est nulle si le tag n'existe pas.
void setUpToDate()
Indique que la variable vient d'être mise à jour.
void addDependCurrentTime(const VariableRef &var)
Ajoute var à la liste des dépendances au temps courant.
IVariable * variable() const
Variable associée.
void update()
Recalcule la variable si nécessaire.
void _internalInit(IVariable *)
Initialisation interne de la variable.
virtual void unregisterVariable()
Supprime l'enregistrement de la variable (interne)
String name() const
Nom de la variable.
ISubDomain * subDomain() const
Sous-domaine associé à la variable (TODO rendre obsolète fin 2023)
virtual void registerVariable()
Enregistre la variable (interne)
virtual int referenceProperty() const
Propriétés de la référence (interne)
bool hasTag(const String &tagname) const
true si la variable possède le tag tagname
void removeDepend(const VariableRef &var)
Supprime var de la liste des dépendances.
IVariableMng * variableMng() const
Gestionnaire de variable associé à la variable.
void addDependPreviousTime(const VariableRef &var)
Ajoute var à la liste des dépendances au temps précédent.
virtual ~VariableRef()
Libère les ressources.
VariableRef * nextReference()
Référence suivante (ou null) sur variable()
virtual StackTrace stackTrace(int first_function=0)=0
Chaîne de caractère indiquant la pile d'appel.
const String & toString() const
Chaîne de caractères indiquant la pile d'appel.
Chaîne de caractères unicode.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
eDataType
Type d'une donnée.
Definition DataTypes.h:39