0022627: Change OCCT memory management defaults
[occt.git] / src / TObj / TObj_TIntSparseArray.cxx
CommitLineData
7fd59977 1// File : TObj_TIntSparseArray.cxx
2// Created : 16.03.2007
3// Author : Michael SAZONOV
4// Copyright: Open CASCADE 2007
5// The original implementation Copyright: (C) RINA S.p.A
6
7#include <TObj_TIntSparseArray.hxx>
8#include <Standard_GUID.hxx>
9#include <Standard_ImmutableObject.hxx>
10#include <TDF_Data.hxx>
11#include <TDF_AttributeDelta.hxx>
12#include <TDF_DeltaOnModification.hxx>
13
14IMPLEMENT_STANDARD_HANDLE(TObj_TIntSparseArray,TDF_Attribute)
15IMPLEMENT_STANDARD_RTTIEXT(TObj_TIntSparseArray,TDF_Attribute)
16
17//=======================================================================
18//function : TObj_TIntSparseArray
19//purpose : Empty constructor
20//=======================================================================
21
22TObj_TIntSparseArray::TObj_TIntSparseArray ()
23: myVector(100), myOldMap(100), myDoBackup (Standard_True)
24{
25}
26
27//=======================================================================
28//function : GetID
29//purpose :
30//=======================================================================
31
32const Standard_GUID& TObj_TIntSparseArray::GetID()
33{
34 static Standard_GUID GInterfaceID ("7016dc0c-b118-4433-8ef3-aecdccc79198");
35 return GInterfaceID;
36}
37
38//=======================================================================
39//function : ID
40//purpose :
41//=======================================================================
42
43const Standard_GUID& TObj_TIntSparseArray::ID() const
44{
45 return GetID();
46}
47
48//=======================================================================
49//function : Set
50//purpose :
51//=======================================================================
52
53Handle(TObj_TIntSparseArray) TObj_TIntSparseArray::Set
54 (const TDF_Label& theLabel)
55{
56 Handle(TObj_TIntSparseArray) aTData;
57 if (! theLabel.FindAttribute( GetID(), aTData))
58 {
59 aTData = new TObj_TIntSparseArray;
60 theLabel.AddAttribute(aTData);
61 }
62 return aTData;
63}
64
65//=======================================================================
66//function : SetValue
67//purpose :
68//=======================================================================
69
70void TObj_TIntSparseArray::SetValue (const Standard_Integer theId,
71 const Standard_Integer theValue)
72{
73 // check that modification is allowed
74 if ( !Label().Data()->IsModificationAllowed() )
75 Standard_ImmutableObject::Raise
76 ("Attribute TObj_TIntSparseArray is changed outside transaction");
77
78 if (theId < 1 || theValue < 1)
79 Standard_OutOfRange::Raise ("TObj_TIntSparseArray::SetValue");
80
81 Standard_Integer anOld = AbsentValue;
82 Standard_Boolean isOld = myVector.HasValue(theId);
83 if (isOld)
84 {
85 Standard_Integer& aData = myVector(theId);
86 if (aData == theValue)
87 // no actual modification
88 return;
89 anOld = aData;
90 // set new value
91 aData = theValue;
92 }
93 else
94 {
95 // set the new value
96 myVector.SetValue (theId, theValue);
97 }
98
99 TDF_Label aLabel = Label();
100 if (!aLabel.IsNull())
101 {
102 Handle(TDF_Data) aData = aLabel.Data();
103 Standard_Integer aCurrentTransaction = aData->Transaction();
104 Standard_Integer aMyTransaction = Transaction();
105
106 if (myDoBackup && aMyTransaction < aCurrentTransaction)
107 backupValue(theId, anOld, theValue);
108 }
109}
110
111//=======================================================================
112//function : UnsetValue
113//purpose :
114//=======================================================================
115
116void TObj_TIntSparseArray::UnsetValue (const Standard_Integer theId)
117{
118 // check that modification is allowed
119 if ( !Label().Data()->IsModificationAllowed() )
120 Standard_ImmutableObject::Raise
121 ("Attribute TObj_TIntSparseArray is changed outside transaction");
122
123 if (theId < 1)
124 Standard_OutOfRange::Raise ("TObj_TIntSparseArray::UnsetValue");
125
126 Standard_Integer anOld = AbsentValue;
127 Standard_Boolean isOld = myVector.HasValue(theId);
128 if (isOld)
129 {
130 anOld = myVector(theId);
131 // unset the value
132 myVector.UnsetValue(theId);
133 }
134 else
135 // no actual modification
136 return;
137
138 TDF_Label aLabel = Label();
139 if (!aLabel.IsNull())
140 {
141 Handle(TDF_Data) aData = aLabel.Data();
142 Standard_Integer aCurrentTransaction = aData->Transaction();
143 Standard_Integer aMyTransaction = Transaction();
144
145 if (myDoBackup && aMyTransaction < aCurrentTransaction)
146 backupValue(theId, anOld, AbsentValue);
147 }
148}
149
150//=======================================================================
151//function : Clear
152//purpose :
153//=======================================================================
154
155void TObj_TIntSparseArray::Clear ()
156{
157 // backup old values
158 TDF_Label aLabel = Label();
159 if (!aLabel.IsNull())
160 {
161 Handle(TDF_Data) aData = aLabel.Data();
162 Standard_Integer aCurrentTransaction = aData->Transaction();
163 Standard_Integer aMyTransaction = Transaction();
164
165 if (myDoBackup && aMyTransaction < aCurrentTransaction)
166 {
167 TObj_TIntSparseArray_VecOfData::Iterator anIt (myVector);
168 for (; anIt.More(); anIt.Next())
169 {
170 Standard_Integer anId = anIt.Key();
171 Standard_Integer aVal = anIt.Value();
172 backupValue(anId, aVal, AbsentValue);
173 }
174 }
175 }
176 myVector.Clear();
177}
178
179//=======================================================================
180//function : backupValue
181//purpose :
182//=======================================================================
183
184void TObj_TIntSparseArray::backupValue (const Standard_Integer theId,
185 const Standard_Integer theCurrValue,
186 const Standard_Integer theNewValue)
187{
188 // save the current value if it has not been saved in previous time
189 if ( !myOldMap.IsBound( theId ) )
190 myOldMap.Bind(theId, theCurrValue);
191 else
192 {
193 // if value in Undo is the same as the new one, the item in Undo map may be cleared
194 Standard_Integer aUData = myOldMap.Value(theId);
195 if (aUData == theNewValue)
196 myOldMap.UnBind(theId);
197 }
198}
199
200//=======================================================================
201//function : NewEmpty
202//purpose :
203//=======================================================================
204
205Handle(TDF_Attribute) TObj_TIntSparseArray::NewEmpty () const
206{
207 return new TObj_TIntSparseArray;
208}
209
210//=======================================================================
211//function : BackupCopy
212//purpose : Moves <this> delta into a new other attribute.
213//=======================================================================
214
215Handle(TDF_Attribute) TObj_TIntSparseArray::BackupCopy() const
216{
217 Handle(TObj_TIntSparseArray) aCopy =
218 Handle(TObj_TIntSparseArray)::DownCast(NewEmpty());
219
220 // save delta data in a copy
221 if (!myOldMap.IsEmpty())
222 aCopy->myOldMap.Exchange ( (TObj_TIntSparseArray_MapOfData&)myOldMap );
223
224 return aCopy;
225}
226
227//=======================================================================
228//function : Restore
229//purpose : Restores contents of this with theDelta
230//=======================================================================
231
232void TObj_TIntSparseArray::Restore(const Handle(TDF_Attribute)& theDelta)
233{
234 Handle(TObj_TIntSparseArray) aDelta =
235 Handle(TObj_TIntSparseArray)::DownCast(theDelta);
236 if (aDelta.IsNull())
237 return;
238
239 // restore the values from aDelta->myOldMap
240 if (!aDelta->myOldMap.IsEmpty())
241 {
242 TObj_TIntSparseArray_MapOfData::Iterator anIt (aDelta->myOldMap);
243 for (; anIt.More(); anIt.Next())
244 {
245 Standard_Integer anId = anIt.Key();
246 Standard_Integer anOld = anIt.Value();
247 if (anOld == AbsentValue)
248 UnsetValue (anId);
249 else
250 SetValue (anId, anOld);
251 }
252 }
253}
254
255//=======================================================================
256//function : Paste
257//purpose : copy this
258//=======================================================================
259
260void TObj_TIntSparseArray::Paste (const Handle(TDF_Attribute)& theInto,
261 const Handle(TDF_RelocationTable)&) const
262{
263 Handle(TObj_TIntSparseArray) aInto =
264 Handle(TObj_TIntSparseArray)::DownCast(theInto);
265 if(aInto.IsNull())
266 return;
267
268 aInto->myVector.Assign(myVector);
269}
270
271//=======================================================================
272//function : BeforeCommitTransaction
273//purpose : It is called just before Commit or Abort transaction
274//=======================================================================
275
276void TObj_TIntSparseArray::BeforeCommitTransaction()
277{
278 if (!myOldMap.IsEmpty())
279 {
280 Backup();
281 ClearDelta();
282 }
283}
284
285//=======================================================================
286//function : DeltaOnModification
287//purpose : Applies aDelta to <me>
288//=======================================================================
289
290void TObj_TIntSparseArray::DeltaOnModification
291 (const Handle(TDF_DeltaOnModification)& theDelta)
292{
293 // we do not call Backup here, because a backup data is formed inside Restore.
294 // Backup is called rather from BeforeCommitTransaction
295 Restore(theDelta->Attribute());
296}
297
298//=======================================================================
299//function : AfterUndo
300//purpose : After application of a TDF_Delta.
301//=======================================================================
302
303Standard_Boolean TObj_TIntSparseArray::AfterUndo
304 (const Handle(TDF_AttributeDelta)&,
305 const Standard_Boolean)
306{
307 // we must be sure that a delta in <me> is cleared
308 ClearDelta();
309 return Standard_True;
310}