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