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 | |
14 | IMPLEMENT_STANDARD_HANDLE(TObj_TIntSparseArray,TDF_Attribute) |
15 | IMPLEMENT_STANDARD_RTTIEXT(TObj_TIntSparseArray,TDF_Attribute) |
16 | |
17 | //======================================================================= |
18 | //function : TObj_TIntSparseArray |
19 | //purpose : Empty constructor |
20 | //======================================================================= |
21 | |
22 | TObj_TIntSparseArray::TObj_TIntSparseArray () |
23 | : myVector(100), myOldMap(100), myDoBackup (Standard_True) |
24 | { |
25 | } |
26 | |
27 | //======================================================================= |
28 | //function : GetID |
29 | //purpose : |
30 | //======================================================================= |
31 | |
32 | const 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 | |
43 | const Standard_GUID& TObj_TIntSparseArray::ID() const |
44 | { |
45 | return GetID(); |
46 | } |
47 | |
48 | //======================================================================= |
49 | //function : Set |
50 | //purpose : |
51 | //======================================================================= |
52 | |
53 | Handle(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 | |
70 | void 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 | |
116 | void 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 | |
155 | void 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 | |
184 | void 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 | |
205 | Handle(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 | |
215 | Handle(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 | |
232 | void 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 | |
260 | void 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 | |
276 | void 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 | |
290 | void 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 | |
303 | Standard_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 | } |