1 // -*- C++ -*- 2 /** 3 * @brief Class PersistentObject saves and reloads the object's internal state 4 * 5 * Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca 6 * 7 * This library is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 #ifndef OPENTURNS_PERSISTENTOBJECT_HXX 22 #define OPENTURNS_PERSISTENTOBJECT_HXX 23 24 #include "openturns/OSS.hxx" 25 #include "openturns/Object.hxx" 26 #include "openturns/StorageManager.hxx" 27 #include "openturns/IdFactory.hxx" 28 #include "openturns/Pointer.hxx" 29 30 BEGIN_NAMESPACE_OPENTURNS 31 32 33 class StorageManager; 34 class Advocate; 35 template <class PERSISTENT> class Factory; 36 37 /** 38 * @class PersistentObject 39 * 40 * @brief This class defines load and save mechanisms. 41 * 42 * This is the base class of all objects that can be stored into 43 * and reloaded from the study. 44 * 45 * The class defines an unique Id for every object so they can be 46 * equal but not identical. This Id is an essential part for the management 47 * of objects in studies. 48 * @sa Study 49 */ 50 51 class OT_API PersistentObject 52 : public Object 53 { 54 public: 55 CLASSNAME 56 57 /** 58 * Default constructor 59 * 60 * The constructor sets a new Id to the object, 61 * so it can be later referenced by a Study object. 62 * It is also declared visible if member of a study. 63 * 64 * The object has the default name but it does not 65 * use storage for it. 66 */ PersistentObject()67 PersistentObject() 68 : p_name_(), 69 id_(0), 70 shadowedId_(id_), 71 studyVisible_(true) 72 {} 73 74 /** Copy constructor */ PersistentObject(const PersistentObject & other)75 PersistentObject(const PersistentObject & other) 76 : p_name_(other.p_name_), 77 id_(0), 78 shadowedId_(other.shadowedId_), 79 studyVisible_(other.studyVisible_) 80 {} 81 82 /** 83 * Virtual constructor 84 * 85 * @warning This method MUST be overloaded in derived classes. 86 * @return A pointer to a newly allocated object similar to this one 87 */ 88 virtual PersistentObject * clone() const = 0; 89 90 /** Destructor */ ~PersistentObject()91 virtual ~PersistentObject() {} 92 93 /** Assignment */ 94 inline operator =(const PersistentObject & other)95 PersistentObject & operator =(const PersistentObject & other) 96 { 97 if (this != &other) // Other is NOT me, so I can assign it to me 98 { 99 p_name_ = other.p_name_; 100 studyVisible_ = other.studyVisible_; 101 } 102 return *this; 103 } 104 105 106 /** 107 * Comparison operator 108 * 109 * This method compares objects based on their content. 110 */ 111 inline virtual operator ==(const PersistentObject &) const112 Bool operator ==(const PersistentObject & /*other*/) const 113 { 114 return true; 115 } 116 117 /** 118 * Comparison operator 119 * 120 * This method compares objects based on their content. 121 */ 122 inline virtual operator !=(const PersistentObject & other) const123 Bool operator !=(const PersistentObject & other) const 124 { 125 return !operator==(other); 126 } 127 128 /** 129 * Identity comparator 130 * 131 * This method compares objects based on their Id. 132 * @return True if objects are the same 133 */ 134 inline is(const PersistentObject & other) const135 Bool is(const PersistentObject & other) const 136 { 137 return (getId() == other.getId()); 138 } 139 140 /* String converter */ 141 inline __repr__() const142 String __repr__() const override 143 { 144 return OSS() << "class=" << getClassName() << " name=" << getName(); 145 } 146 147 /* String converter */ 148 inline __str__(const String & offset="") const149 String __str__(const String & offset = "") const override 150 { 151 return OSS() << offset << __repr__(); 152 } 153 154 155 /** 156 * Id accessor 157 * @return The id of this object 158 */ 159 inline getId() const160 Id getId() const 161 { 162 if (!id_) 163 id_ = IdFactory::BuildId(); 164 return id_; 165 } 166 167 /** 168 * Shadowed id accessor 169 * @internal 170 */ 171 inline setShadowedId(Id id)172 void setShadowedId(Id id) 173 { 174 shadowedId_ = id; 175 } 176 inline getShadowedId() const177 Id getShadowedId() const 178 { 179 if (!shadowedId_) 180 shadowedId_ = getId(); 181 return shadowedId_; 182 } 183 184 /** Visibility accessor */ 185 inline setVisibility(Bool visible)186 void setVisibility(Bool visible) 187 { 188 studyVisible_ = visible; 189 } 190 inline getVisibility() const191 Bool getVisibility() const 192 { 193 return studyVisible_; 194 } 195 196 /** 197 * %Object name query 198 * 199 * This methos returns true if a name was given to the object 200 * @return True if object has a name 201 */ 202 inline hasName() const203 Bool hasName() const 204 { 205 return p_name_; 206 } 207 208 /** 209 * %Object name visibility query 210 * 211 * This method returns true if a non-empty name was given to the object 212 * @return True if object has a non-empty name 213 */ 214 inline hasVisibleName() const215 Bool hasVisibleName() const 216 { 217 return (p_name_ && !p_name_->empty()); 218 } 219 220 /** 221 * %Object name accessor 222 * 223 * This method returns the name of the object if it has been previously set 224 * or the default name. Accessing the default name does not cause storage 225 * allocation as a side effect. 226 * @return The name of this object 227 */ 228 inline getName() const229 String getName() const 230 { 231 return ( hasName() ? *p_name_ : "Unnamed" ); 232 } 233 234 /** 235 * %Object name accessor 236 * 237 * This method sets \p name as the new name for the object. Setting the name 238 * may cause storage allocation for the new name, especially of the name was 239 * not defined so far. 240 * @param name The new name for this object 241 */ 242 inline setName(const String & name)243 void setName(const String & name) 244 { 245 if (name.empty()) p_name_.reset(); 246 else p_name_.reset(new String(name)); 247 } 248 249 250 /** Method save() stores the object through the StorageManager 251 * @internal 252 */ 253 void save(StorageManager & mgr, const String & label, bool fromStudy = false) const; 254 255 /** Method save() stores the object through the StorageManager 256 * @internal 257 */ 258 void save(StorageManager & mgr, bool fromStudy = false) const; 259 260 /** Method save() stores the object through the StorageManager 261 * 262 * @warning This method MUST be overloaded in derived classes. 263 * @internal 264 */ 265 virtual void save(Advocate & adv) const; 266 267 /** Method load() reloads the object from the StorageManager 268 * 269 * @warning This method MUST be overloaded in derived classes. 270 * @internal 271 */ 272 virtual void load(Advocate & adv); 273 274 275 protected: 276 277 private: 278 279 /** The name of the object */ 280 mutable Pointer<String> p_name_; 281 282 /** 283 * The unique identifier of the object 284 * 285 * This identifier is needed when saving and reloading the object 286 * because it allows the chaining of objects even if they are 287 * relocated. 288 */ 289 mutable Id id_; 290 291 /** 292 * The shadowed id is used when object is reloaded. The object gets 293 * a new id that is almost always different from that stored in the study. 294 * So when we need to rebuild the objects dependency tree (ie, when 295 * object A embed object B), we have to make the id translation: the 296 * object holds the both ids, the new one (aka the Id as returned by getId) 297 * and the former one stored in the study (aka the shadowed id). This latter 298 * is never seen except by the object factory. 299 * @internal 300 */ 301 mutable Id shadowedId_; 302 303 /** 304 * This flag is used by the Study to know if the object should be displayed 305 * even if it had been added to the study (in particular, when the object 306 * was rebuild from file) 307 */ 308 Bool studyVisible_; 309 310 }; /* class PersistentObject */ 311 312 313 END_NAMESPACE_OPENTURNS 314 315 #endif /* OPENTURNS_PERSISTENTOBJECT_HXX */ 316