1 // Copyright (c) 2015 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13 
14 
15 #ifndef _StdObjMgt_SharedObject_HeaderFile
16 #define _StdObjMgt_SharedObject_HeaderFile
17 
18 #include <Standard_NoSuchObject.hxx>
19 #include <StdObjMgt_Persistent.hxx>
20 
21 class StdObjMgt_SharedObject
22 {
23 public:
24   template <class Transient>
25   class AbstractPersistentBase : public Standard_Transient
26   {
27   public:
28     virtual Handle(Transient) Import() const = 0;
29   };
30 
31   template <class TransientT, class Base = StdObjMgt_Persistent>
32   class SharedBase : public Base
33   {
34   public:
35     //! Changes transient object
Transient(const Handle (TransientT)& theTransient)36     inline void Transient(const Handle(TransientT)& theTransient)
37       { myTransient = theTransient; }
38 
39     //! Import transient object from the persistent data.
Handle(TransientT)40     inline const Handle(TransientT)& Import()  { return myTransient; }
41 
42   protected:
43     Handle(TransientT) myTransient;
44   };
45 
46   template <class Base,
47             class Transient,
48             class Persistent = AbstractPersistentBase<Transient> >
49   class DelayedBase : public Base
50   {
51   public:
52     typedef Transient  TransientBase;
53     typedef Persistent PersistentBase;
54 
55     //! Import transient object from the persistent data.
Import()56     virtual Handle(Transient) Import()
57       { return myTransient; }
58 
59   public:
60     Handle(Transient) myTransient;
61   };
62 
63   template <class Base,
64             class PersistentData,
65             class Transient = typename Base::TransientBase>
66   class IgnoreData : public Base
67   {
68   public:
69     //! Read persistent data from a file.
Read(StdObjMgt_ReadData & theReadData)70     virtual void Read (StdObjMgt_ReadData& theReadData)
71       { PersistentData().Read (theReadData); }
72     //! Write persistent data to a file.
Write(StdObjMgt_WriteData & theWriteData) const73     virtual void Write (StdObjMgt_WriteData& theWriteData) const
74       { PersistentData().Write (theWriteData); }
75     //! Gets persistent child objects
PChildren(StdObjMgt_Persistent::SequenceOfPersistent & theChildren) const76     virtual void PChildren(StdObjMgt_Persistent::SequenceOfPersistent& theChildren) const
77       { PersistentData().PChildren(theChildren); }
78     //! Returns persistent type name
PName() const79     virtual Standard_CString PName() const
80       { return PersistentData().PName(); }
81 
82     //! Import transient object from the persistent data.
Import()83     virtual Handle(Transient) Import()
84       { return NULL; }
85   };
86 
87 private:
88   template <class Base>
89   class delayedSubBase : public Base
90   {
91   public:
92     //! Import transient object from the persistent data.
Import()93     virtual Handle(typename Base::TransientBase) Import()
94     {
95       if (Base::myTransient.IsNull() && !myPersistent.IsNull())
96       {
97         Base::myTransient = myPersistent->Import();
98         myPersistent.Nullify();
99       }
100 
101       return Base::myTransient;
102     }
103 
104   public:
105     Handle(typename Base::PersistentBase) myPersistent;
106   };
107 
108 public:
109   template <class Base, class Persistent = typename Base::PersistentBase>
110   class Delayed : public delayedSubBase<Base>
111   {
112   private:
113     template <class T1, class T2>
114     struct DownCast {
makeStdObjMgt_SharedObject::Delayed::DownCast115       static Handle(T1) make(const Handle(T2)& theT2)
116         { return Handle(T1)::DownCast(theT2); }
117     };
118 
119     template <class T>
120     struct DownCast<T, T> {
makeStdObjMgt_SharedObject::Delayed::DownCast121       static Handle(T) make(const Handle(T)& theT)
122         { return theT; }
123     };
124 
125   public:
126     //! Read persistent data from a file.
Read(StdObjMgt_ReadData & theReadData)127     virtual void Read (StdObjMgt_ReadData& theReadData)
128     {
129       Handle(Persistent) aPersistent = new Persistent;
130       aPersistent->Read (theReadData);
131       this->myPersistent = aPersistent;
132     }
133     //! Write persistent data to a file.
Write(StdObjMgt_WriteData & theWriteData) const134     virtual void Write(StdObjMgt_WriteData& theWriteData) const
135     {
136       Handle(Persistent) aPersistent =
137         DownCast<Persistent, typename Base::PersistentBase>::make(this->myPersistent);
138       Standard_NoSuchObject_Raise_if(aPersistent.IsNull(),
139         "StdObjMgt_SharedObject::Delayed::Write - persistent object wasn't set for writing!");
140       aPersistent->Write(theWriteData);
141     }
142     //! Gets persistent child objects
PChildren(StdObjMgt_Persistent::SequenceOfPersistent & theChildren) const143     virtual void PChildren(StdObjMgt_Persistent::SequenceOfPersistent& theChildren) const
144     {
145       Handle(Persistent) aPersistent =
146         DownCast<Persistent, typename Base::PersistentBase>::make(this->myPersistent);
147       Standard_NoSuchObject_Raise_if(aPersistent.IsNull(),
148         "StdObjMgt_SharedObject::Delayed::PChildren - persistent object wasn't set for writing!");
149       aPersistent->PChildren(theChildren);
150     }
151     //! Returns persistent type name
PName() const152     virtual Standard_CString PName() const
153     {
154       Handle(Persistent) aPersistent =
155         DownCast<Persistent, typename Base::PersistentBase>::make(this->myPersistent);
156       Standard_NoSuchObject_Raise_if(aPersistent.IsNull(),
157         "StdObjMgt_SharedObject::Delayed::PName - persistent object wasn't set for writing!");
158       return aPersistent->PName();
159     }
160   };
161 };
162 
163 #endif
164