COPASI API  4.16.103
CCopasiObject.h
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2014 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2002 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 /**
16  * Class CCopasiObject
17  *
18  * This class is the base class for all global accessible objects in COPASI.
19  *
20  * Copyright Stefan Hoops 2002
21  */
22 
23 #ifndef COPASI_CCopasiObject
24 #define COPASI_CCopasiObject
25 
26 #include <string>
27 #include <iostream>
28 #include <vector>
29 #include <set>
30 #include <list>
31 
32 #include "copasi/copasi.h"
33 
34 #include "copasi/math/CMathEnum.h"
35 
36 class CCopasiObjectName;
37 class CCopasiContainer;
38 class CCopasiObject;
39 class CModel;
40 class CCopasiDataModel;
42 
43 template <class CType> class CCopasiObjectReference;
44 template <class CType> class CCopasiVectorReference;
45 template <class CType> class CCopasiMatrixReference;
46 
47 #ifdef WIN32
48 template <class CType> class CCopasiVector;
49 #endif // WIN32
50 
52 {
53 public:
54 
55  virtual ~UpdateMethod() {};
56 
57  virtual void operator()(const C_FLOAT64 & C_UNUSED(value))
58  {return;}
59 
60  virtual void operator()(const C_INT32 & C_UNUSED(value))
61  {return;}
62 
63  virtual void operator()(const bool & C_UNUSED(value))
64  {return;}
65 };
66 
67 template <class CType, class VType> class SpecificUpdateMethod : public UpdateMethod
68 {
69 private:
70  void (CType::*mMethod)(const VType &); // pointer to member function
71  CType * mpType; // pointer to object
72 
73 public:
74 
75  // constructor - takes pointer to an object and pointer to a member and stores
76  // them in two private variables
77  SpecificUpdateMethod(CType * pType,
78  void(CType::*method)(const VType &))
79  {
80  mpType = pType;
81  mMethod = method;
82  };
83 
84  virtual ~SpecificUpdateMethod() {};
85 
86  // override operator "()"
87  virtual void operator()(const VType & value)
88  {(*mpType.*mMethod)(value);} ; // execute member function
89 };
90 
91 class Refresh
92 {
93 protected:
95  {}
96 
97 public:
98  virtual ~Refresh() {}
99 
100  virtual void operator()(void)
101  {return;}
102 
103  virtual bool isEqual(Refresh *const rhs) const
104  {return (this == rhs);}
105 
106  virtual CCopasiObject * getObject() const
107  {return NULL;}
108 };
109 
110 template <typename CClass> class RefreshTemplate : public Refresh
111 {
112 private:
113  CClass * mpInstance; // pointer to object
114  void (CClass::*mMethod)(void); // pointer to member function
115 
116 private:
118  Refresh(),
119  mpInstance(NULL),
120  mMethod(NULL)
121  {}
122 
123 public:
124  // constructor - takes pointer to an object and pointer to a member and stores
125  // them in two private variables
126  RefreshTemplate(CClass * pInstance, void (CClass::*method)(void)):
127  Refresh(),
128  mpInstance(pInstance),
129  mMethod(method)
130  {}
131 
132  virtual ~RefreshTemplate() {};
133 
134  // override operator "()"
135  virtual void operator()(void)
136  {(*mpInstance.*mMethod)();} // execute member function
137 
138  virtual CCopasiObject * getObject() const
139  {return mpInstance;}
140 
141  virtual bool isEqual(Refresh *const rhs) const
142  {
143  const RefreshTemplate< CClass > * pRhs =
144  static_cast< RefreshTemplate< CClass > * >(rhs);
145 
146  return (mpInstance == pRhs->mpInstance && mMethod == pRhs->mMethod);
147  }
148 };
149 
150 class CRenameHandler;
151 
152 //********************************************************************************
153 
155 {
156 public:
157  typedef std::set< const CObjectInterface * > ObjectSet;
158  typedef std::vector< CObjectInterface * > UpdateSequence;
159 
160  /**
161  * Constructor
162  */
164 
165  /**
166  * Destructor
167  */
168  virtual ~CObjectInterface() {};
169 
170  /**
171  * Retrieve the CN of the object
172  * @return CCopasiObjectName
173  */
174  virtual CCopasiObjectName getCN() const = 0;
175 
176  /**
177  * Retrieve a descendant object by its CN.
178  * @param const CCopasiObjectName & cn
179  * @return const CObjectInterface * pObject
180  */
181  virtual const CObjectInterface * getObject(const CCopasiObjectName & cn) const = 0;
182 
183  /**
184  * Retrieve the prerequisites, i.e., the objects which need to be evaluated
185  * before this.
186  * @return const CObjectInterface::ObjectSet & prerequisites
187  */
188  virtual const CObjectInterface::ObjectSet & getPrerequisites() const = 0;
189 
190  /**
191  * Check whether a given object is a prerequisite for a context.
192  * @param const CObjectInterface * pObject
193  * @param const CMath::SimulationContextFlag & context
194  * @param const CObjectInterface::ObjectSet & changedObjects
195  * @return bool isPrerequisiteForContext
196  */
197  virtual bool isPrerequisiteForContext(const CObjectInterface * pObject,
198  const CMath::SimulationContextFlag & context,
199  const CObjectInterface::ObjectSet & changedObjects) const = 0;
200 
201  /**
202  * This is the output method for any object. The default implementation
203  * provided with CCopasiObject uses the ostream operator<< of the object
204  * to print the object.To override this default behavior one needs to
205  * reimplement the virtual print function.
206  * @param std::ostream * ostream
207  */
208  virtual void print(std::ostream * ostream) const = 0;
209 
210  /**
211  * Retrieve a pointer to the value of the object
212  */
213  virtual void * getValuePointer() const = 0;
214 };
215 
217 {
218 #ifdef WIN32
220 #endif // WIN32
221 
223 
224 public:
225  typedef std::set< const CCopasiObject * > DataObjectSet;
226  typedef std::vector< Refresh * > DataUpdateSequence;
227 
228  //Attributes
229 protected:
230  enum Flag
231  {
232  Container = 0x1,
233  Vector = 0x2,
234  Matrix = 0x4,
235  NameVector = 0x8,
236  Reference = 0x10,
237  ValueBool = 0x20,
238  ValueInt = 0x40,
239  ValueInt64 = 0x80,
240  ValueDbl = 0x100,
241  NonUniqueName = 0x200,
242  StaticString = 0x400,
243  ValueString = 0x800,
244  Separator = 0x1000,
245  ModelEntity = 0x2000,
246  Array = 0x4000,
247  DataModel = 0x8000,
248  Root = 0x10000,
249  Gui = 0x20000
250  };
251 
252 private:
253  std::string mObjectName;
254 
255  std::string mObjectType;
256 
258 
260 
262 
263 private:
264  /**
265  * A list of all objects the object depends on directly, i.e, the
266  * objects which are used to calculate the object.
267  */
269 
270 private:
271 
273 
275 
276  static const C_FLOAT64 DummyValue;
277 
279 
280 protected:
282 
283  //Operations
284  CCopasiObject();
285 
286  CCopasiObject(const std::string & name,
287  const CCopasiContainer * pParent = NULL,
288  const std::string & type = "CN",
289  const unsigned C_INT32 & flag = 0);
290 
291 public:
292  CCopasiObject(const CCopasiObject & src,
293  const CCopasiContainer * pParent = NULL);
294 
295  virtual ~CCopasiObject();
296 
297  /**
298  * This is the output method for any object. The default implementation
299  * provided with CCopasiObject uses the ostream operator<< of the object
300  * to print the object.To override this default behavior one needs to
301  * reimplement the virtual print function.
302  * @param std::ostream * ostream
303  */
304  virtual void print(std::ostream * ostream) const;
305 
306  /**
307  * Set the name of the object.
308  * Note: An attempt set the name to "" results in the name
309  * being set to "No Name".
310  * @param const std::string & name
311  * @return success
312  */
313  bool setObjectName(const std::string & name);
314 
315  const std::string & getObjectName() const;
316 
317  virtual std::string getObjectDisplayName(bool regular = true, bool richtext = false) const;
318 
319  const std::string & getObjectType() const;
320 
321  virtual bool setObjectParent(const CCopasiContainer * pParent);
322 
324 
325  /**
326  * Returns a pointer to the CCopasiDataModel the element belongs to.
327  * If there is no instance of CCopasiDataModel in the ancestor tree, NULL
328  * is returned.
329  */
331 
332  /**
333  * Returns a const pointer to the CCopasiDataModel the element belongs to.
334  * If there is no instance of CCopasiDataModel in the ancestor tree, NULL
335  * is returned.
336  */
337  const CCopasiDataModel* getObjectDataModel() const;
338 
339  CCopasiContainer * getObjectAncestor(const std::string & type) const;
340 
341  virtual CCopasiObjectName getCN() const;
342 
343  virtual const CObjectInterface * getObject(const CCopasiObjectName & cn) const;
344 
345  /**
346  * Set the direct dependencies
347  * @param const Set & directDependencies
348  */
349  void setDirectDependencies(const DataObjectSet & directDependencies);
350 
351  /**
352  * Retrieve the list of direct dependencies
353  * @param const DataObjectSet & context (default empty set)
354  * @return const DataObjectSet & directDependencies
355  */
356  virtual const DataObjectSet &
357  getDirectDependencies(const DataObjectSet & context = DataObjectSet()) const;
358 
359  /**
360  * Clear the list of direct dependencies.
361  */
363 
364  /**
365  * Add a the object to the direct dependencies
366  * @param const CCopasiObject * pObject
367  */
368  void addDirectDependency(const CCopasiObject * pObject);
369 
370  /**
371  * Remove an object from the direct dependencies
372  * @param const CCopasiObject * pObject
373  */
374  void removeDirectDependency(const CCopasiObject * pObject);
375 
376  /**
377  * Retrieve the prerequisites, i.e., the objects which need to be evaluated
378  * before this.
379  * @return const CObjectInterface::ObjectSet & prerequisites
380  */
381  virtual const CObjectInterface::ObjectSet & getPrerequisites() const;
382 
383  /**
384  * Check whether a given object is a prerequisite for a context.
385  * @param const CObjectInterface * pObject
386  * @param const CMath::SimulationContextFlag & context
387  * @param const CObjectInterface::ObjectSet & changedObjects
388  * @return bool isPrerequisiteForContext
389  */
390  virtual bool isPrerequisiteForContext(const CObjectInterface * pObject,
391  const CMath::SimulationContextFlag & context,
392  const CObjectInterface::ObjectSet & changedObjects) const;
393 
394  /**
395  * If called with an empty set of dependencies it retrieves the complete list
396  * of all dependencies (including all indirect) of the current object.
397  * If called with a non empty set it will only add any dependency and all its
398  * dependencies to the list if the dependency is not already among the dependencies
399  * @param DataObjectSet & dependencies
400  * @param const DataObjectSet & context
401  */
402  void getAllDependencies(DataObjectSet & dependencies,
403  const DataObjectSet & context) const;
404 
405  /**
406  * Check whether an object must be deleted because its prerequisites can
407  * no longer be fulfilled due to the given deleted objects
408  * @param const DataObjectSet & deletedObjects
409  * @return bool mustBeDeleted
410  */
411  virtual bool mustBeDeleted(const DataObjectSet & deletedObjects) const;
412 
413  /**
414  * Check whether the current object depends on any objects in the candidates.
415  * @param DataObjectSet candidates
416  * @param const DataObjectSet & context (default: empty set)
417  * @return bool dependsOn
418  */
419  bool dependsOn(DataObjectSet candidates,
420  const DataObjectSet & context = DataObjectSet()) const;
421 
422  /**
423  * If called with an empty set it will check whether the current object and all its
424  * dependencies (including all indirect) form a circular dependency.
425  * If called with a non empty set it check whether the candidates plus the current object
426  * and all its dependencies form a circular dependency.
427  * @param DataObjectSet & dependencies
428  * @param DataObjectSet & verified
429  * @param const DataObjectSet & context
430  * @return bool hasCircularDependencies
431  */
432  bool hasCircularDependencies(DataObjectSet & candidates,
433  DataObjectSet & verified,
434  const DataObjectSet & context) const;
435 
436  /**
437  * Build the update sequence for the given list of objects. The resulting sequence
438  * takes the dependencies of the objects in consideration. If circular dependencies
439  * are detected an exception is thrown
440  * @param DataObjectSet & objects
441  * @param const DataObjectSet & uptoDateObjects
442  * @param const DataObjectSet & context (default: empty set)
443  * @return std::vector< Refresh * > updateSequence
444  */
445  static std::vector< Refresh * > buildUpdateSequence(const DataObjectSet & objects,
446  const DataObjectSet & uptoDateObjects,
447  const DataObjectSet & context = DataObjectSet());
448 
449  /**
450  * Retrieve the units of the object.
451  * @return std::string units
452  */
453  virtual std::string getUnits() const;
454 
455  /**
456  * Comparison operator which can be used to sort objects based on their dependencies
457  * If the object *lhs is a dependency of *rhs and must be evaluated first the operator
458  * return true.
459  * @param const CCopasiObject * lhs
460  * @param const CCopasiObject * rhs
461  * @return bool isLess
462  */
463  // static
464  // bool compare(const CCopasiObject * lhs, const CCopasiObject * rhs);
465 
466  bool isContainer() const;
467 
468  bool isVector() const;
469 
470  bool isMatrix() const;
471 
472  bool isNameVector() const;
473 
474  bool isReference() const;
475 
476  bool isValueBool() const;
477  bool isValueInt() const;
478  bool isValueInt64() const;
479  bool isValueDbl() const;
480  bool isNonUniqueName() const;
481  bool isStaticString() const;
482  bool isValueString() const;
483  bool isSeparator() const;
484  bool isArray() const;
485  bool isDataModel() const;
486  bool isRoot() const;
487 
488  virtual void * getValuePointer() const;
489 
490  virtual const CCopasiObject * getValueObject() const;
491 
492  friend std::ostream &operator<<(std::ostream &os, const CCopasiObject & o);
493 
494  virtual const std::string & getKey() const;
495 
496  void setObjectValue(const C_FLOAT64 & value);
497  void setObjectValue(const C_INT32 & value);
498  void setObjectValue(const bool & value);
499 
500  template <class CType>
501  void setUpdateMethod(CType * pType,
502  void (CType::*method)(const C_FLOAT64 &))
503  {
506 
508  new SpecificUpdateMethod< CType, C_FLOAT64 >(pType, method);
509 
510  return;
511  }
512 
513  template <class CType>
514  void setUpdateMethod(CType * pType,
515  void (CType::*method)(const C_INT32 &))
516  {
519 
521  new SpecificUpdateMethod< CType, C_INT32 >(pType, method);
522 
523  return;
524  }
525 
526  template <class CType>
527  void setUpdateMethod(CType * pType,
528  void (CType::*method)(const bool &))
529  {
532 
534  new SpecificUpdateMethod< CType, bool >(pType, method);
535 
536  return;
537  }
538 
539  UpdateMethod * getUpdateMethod() const;
540 
541  bool hasUpdateMethod() const;
542 
543  template <class CType>
544  void setRefresh(CType * pType,
545  void (CType::*method)(void))
546  {
547  Refresh * pRefresh =
548  new RefreshTemplate< CType >(pType, method);
549 
550  if (mpRefresh != NULL &&
551  mpRefresh->isEqual(pRefresh))
552  {
553  delete pRefresh;
554  }
555  else
556  {
558  mpRefresh = pRefresh;
559  }
560 
561  return;
562  }
563 
564  void clearRefresh();
565 
566  virtual Refresh * getRefresh() const;
567 
569  {smpRenameHandler = rh;}
570 };
571 
572 template <class CType> CCopasiObjectReference< CType > *
573 createReference(const std::string & name,
574  const CCopasiContainer * pParent,
575  CType & reference,
576  const unsigned C_INT32 & flag = 0)
577 {return new CCopasiObjectReference< CType >(name, pParent, reference, flag);}
578 
579 template <class CType> CCopasiVectorReference< CType > *
580 createVectorReference(const std::string & name,
581  const CCopasiContainer * pParent,
582  CType & reference,
583  const unsigned C_INT32 & flag = 0)
584 {return new CCopasiVectorReference< CType >(name, pParent, reference, flag);}
585 
586 template <class CType> CCopasiMatrixReference< CType > *
587 createMatrixReference(const std::string & name,
588  const CCopasiContainer * pParent,
589  CType & reference,
590  const unsigned C_INT32 & flag = 0)
591 {return new CCopasiMatrixReference< CType >(name, pParent, reference, flag);}
592 
593 /**
594  * Sort the CCopasiObjects in the interval [begin, end) according to
595  * their dependencies
596  * @param ForwardAccessIterator begin
597  * @param ForwardAccessIterator end
598  * @param const DataObjectSet & context
599  * @return std::list< const CCopasiObject * >
600  */
601 template <typename ForwardAccessIterator>
602 std::list< const CCopasiObject * > sortObjectsByDependency(ForwardAccessIterator begin,
603  ForwardAccessIterator end,
604  const CCopasiObject::DataObjectSet & context)
605 {
606  std::list< const CCopasiObject * > SortedList;
607  std::list< const CCopasiObject * >::iterator itList;
608  std::list< const CCopasiObject * >::iterator endList;
609 
610  CCopasiObject::DataObjectSet AllDependencies;
611  std::list< CCopasiObject::DataObjectSet > DependencySet;
612  std::list< CCopasiObject::DataObjectSet >::iterator itDependencies;
613 
614  for (; begin != end; ++begin)
615  {
616  AllDependencies.clear();
617  (*begin)->getAllDependencies(AllDependencies, context);
618 
619  itList = SortedList.begin();
620  endList = SortedList.end();
621  itDependencies = DependencySet.begin();
622 
623  for (; itList != endList; ++itList, ++itDependencies)
624  if (itDependencies->count(*begin)) break;
625 
626  SortedList.insert(itList, *begin);
627  DependencySet.insert(itDependencies, AllDependencies);
628  }
629 
630  return SortedList;
631 }
632 
633 #endif // COPASI_CCopasiObject
CCopasiDataModel * getObjectDataModel()
virtual bool setObjectParent(const CCopasiContainer *pParent)
virtual Refresh * getRefresh() const
bool isContainer() const
CCopasiContainer * getObjectAncestor(const std::string &type) const
virtual void operator()(const VType &value)
Definition: CCopasiObject.h:87
bool isValueInt() const
bool isRoot() const
unsigned C_INT32 mObjectFlag
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
void clearDirectDependencies()
void setRefresh(CType *pType, void(CType::*method)(void))
CCopasiStaticString * mpObjectDisplayName
#define pdelete(p)
Definition: copasi.h:215
UpdateMethod * getUpdateMethod() const
bool isNameVector() const
void setObjectValue(const C_FLOAT64 &value)
friend std::ostream & operator<<(std::ostream &os, const CCopasiObject &o)
virtual CCopasiObjectName getCN() const
virtual ~SpecificUpdateMethod()
Definition: CCopasiObject.h:84
CCopasiMatrixReference< CType > * createMatrixReference(const std::string &name, const CCopasiContainer *pParent, CType &reference, const unsigned C_INT32 &flag=0)
const std::string & getObjectName() const
virtual ~CCopasiObject()
virtual ~RefreshTemplate()
virtual const CObjectInterface * getObject(const CCopasiObjectName &cn) const
virtual CCopasiObjectName getCN() const =0
virtual const CObjectInterface::ObjectSet & getPrerequisites() const =0
virtual ~CObjectInterface()
bool hasCircularDependencies(DataObjectSet &candidates, DataObjectSet &verified, const DataObjectSet &context) const
static CRenameHandler * smpRenameHandler
bool isSeparator() const
void setDirectDependencies(const DataObjectSet &directDependencies)
virtual CCopasiObject * getObject() const
bool isNonUniqueName() const
void(CClass::* mMethod)(void)
UpdateMethod * mpUpdateMethod
const std::string & getObjectType() const
virtual CCopasiObject * getObject() const
#define C_UNUSED(p)
Definition: copasi.h:220
#define C_INT32
Definition: copasi.h:90
bool isMatrix() const
SpecificUpdateMethod(CType *pType, void(CType::*method)(const VType &))
Definition: CCopasiObject.h:77
virtual bool isEqual(Refresh *const rhs) const
virtual void operator()(const C_INT32 &C_UNUSED(value))
Definition: CCopasiObject.h:60
DataObjectSet mDependencies
std::vector< Refresh * > DataUpdateSequence
virtual ~UpdateMethod()
Definition: CCopasiObject.h:55
std::string mObjectName
void setUpdateMethod(CType *pType, void(CType::*method)(const C_FLOAT64 &))
std::list< const CCopasiObject * > sortObjectsByDependency(ForwardAccessIterator begin, ForwardAccessIterator end, const CCopasiObject::DataObjectSet &context)
void setUpdateMethod(CType *pType, void(CType::*method)(const C_INT32 &))
virtual void operator()(void)
virtual const std::string & getKey() const
CClass * mpInstance
void addDirectDependency(const CCopasiObject *pObject)
bool isReference() const
bool isDataModel() const
void(CType::* mMethod)(const VType &)
Definition: CCopasiObject.h:70
virtual void operator()(const bool &C_UNUSED(value))
Definition: CCopasiObject.h:63
virtual void operator()(const C_FLOAT64 &C_UNUSED(value))
Definition: CCopasiObject.h:57
virtual void print(std::ostream *ostream) const =0
virtual const CObjectInterface::ObjectSet & getPrerequisites() const
static UpdateMethod mDefaultUpdateMethod
RefreshTemplate(CClass *pInstance, void(CClass::*method)(void))
virtual bool isEqual(Refresh *const rhs) const
void setUpdateMethod(CType *pType, void(CType::*method)(const bool &))
bool hasUpdateMethod() const
virtual bool isPrerequisiteForContext(const CObjectInterface *pObject, const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects) const =0
virtual bool mustBeDeleted(const DataObjectSet &deletedObjects) const
bool dependsOn(DataObjectSet candidates, const DataObjectSet &context=DataObjectSet()) const
long int flag
Definition: f2c.h:52
std::set< const CObjectInterface * > ObjectSet
virtual const DataObjectSet & getDirectDependencies(const DataObjectSet &context=DataObjectSet()) const
CCopasiContainer * mpObjectParent
virtual const CObjectInterface * getObject(const CCopasiObjectName &cn) const =0
virtual std::string getUnits() const
bool isValueString() const
#define C_FLOAT64
Definition: copasi.h:92
bool isValueBool() const
CCopasiObject referenceType
bool isValueInt64() const
std::string mObjectType
void removeDirectDependency(const CCopasiObject *pObject)
bool isVector() const
static std::vector< Refresh * > buildUpdateSequence(const DataObjectSet &objects, const DataObjectSet &uptoDateObjects, const DataObjectSet &context=DataObjectSet())
bool isArray() const
bool isValueDbl() const
virtual ~Refresh()
Definition: CCopasiObject.h:98
virtual void * getValuePointer() const
virtual void operator()(void)
() void(yyvaluep))
CCopasiVectorReference< CType > * createVectorReference(const std::string &name, const CCopasiContainer *pParent, CType &reference, const unsigned C_INT32 &flag=0)
Definition: CModel.h:50
bool isStaticString() const
void getAllDependencies(DataObjectSet &dependencies, const DataObjectSet &context) const
virtual void * getValuePointer() const =0
Refresh * mpRefresh
static void setRenameHandler(CRenameHandler *rh)
virtual const CCopasiObject * getValueObject() const
static const C_FLOAT64 DummyValue
bool setObjectName(const std::string &name)
std::set< const CCopasiObject * > DataObjectSet
virtual void print(std::ostream *ostream) const
CCopasiContainer * getObjectParent() const
virtual bool isPrerequisiteForContext(const CObjectInterface *pObject, const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects) const
std::vector< CObjectInterface * > UpdateSequence
CCopasiObjectReference< CType > * createReference(const std::string &name, const CCopasiContainer *pParent, CType &reference, const unsigned C_INT32 &flag=0)