1 // Created on: 2007-03-16
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2007-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 // The original implementation Copyright: (C) RINA S.p.A
18 #include <TObj_TIntSparseArray.hxx>
19 #include <Standard_GUID.hxx>
20 #include <Standard_ImmutableObject.hxx>
21 #include <TDF_Data.hxx>
22 #include <TDF_DeltaOnModification.hxx>
25 IMPLEMENT_STANDARD_RTTIEXT(TObj_TIntSparseArray,TDF_Attribute)
27 //=======================================================================
28 //function : TObj_TIntSparseArray
29 //purpose : Empty constructor
30 //=======================================================================
32 TObj_TIntSparseArray::TObj_TIntSparseArray ()
33 : myVector(100), myOldMap(100), myDoBackup (Standard_True)
37 //=======================================================================
40 //=======================================================================
42 const Standard_GUID& TObj_TIntSparseArray::GetID()
44 static Standard_GUID GInterfaceID ("7016dc0c-b118-4433-8ef3-aecdccc79198");
48 //=======================================================================
51 //=======================================================================
53 const Standard_GUID& TObj_TIntSparseArray::ID() const
58 //=======================================================================
61 //=======================================================================
63 Handle(TObj_TIntSparseArray) TObj_TIntSparseArray::Set
64 (const TDF_Label& theLabel)
66 Handle(TObj_TIntSparseArray) aTData;
67 if (! theLabel.FindAttribute( GetID(), aTData))
69 aTData = new TObj_TIntSparseArray;
70 theLabel.AddAttribute(aTData);
75 //=======================================================================
78 //=======================================================================
80 void TObj_TIntSparseArray::SetValue (const Standard_Size theId,
81 const Standard_Integer theValue)
83 // check that modification is allowed
84 if ( !Label().Data()->IsModificationAllowed() )
85 throw Standard_ImmutableObject("Attribute TObj_TIntSparseArray is changed outside transaction");
87 if (theId < 1 || theValue < 1)
88 throw Standard_OutOfRange("TObj_TIntSparseArray::SetValue");
90 Standard_Integer anOld = AbsentValue;
91 Standard_Boolean isOld = myVector.HasValue(theId);
94 Standard_Integer& aData = myVector(theId);
95 if (aData == theValue)
96 // no actual modification
105 myVector.SetValue (theId, theValue);
108 TDF_Label aLabel = Label();
109 if (!aLabel.IsNull())
111 Handle(TDF_Data) aData = aLabel.Data();
112 Standard_Integer aCurrentTransaction = aData->Transaction();
113 Standard_Integer aMyTransaction = Transaction();
115 if (myDoBackup && aMyTransaction < aCurrentTransaction)
116 backupValue(theId, anOld, theValue);
120 //=======================================================================
121 //function : UnsetValue
123 //=======================================================================
125 void TObj_TIntSparseArray::UnsetValue (const Standard_Size theId)
127 // check that modification is allowed
128 if ( !Label().Data()->IsModificationAllowed() )
129 throw Standard_ImmutableObject("Attribute TObj_TIntSparseArray is changed outside transaction");
132 throw Standard_OutOfRange("TObj_TIntSparseArray::UnsetValue");
134 Standard_Integer anOld = AbsentValue;
135 Standard_Boolean isOld = myVector.HasValue(theId);
138 anOld = myVector(theId);
140 myVector.UnsetValue(theId);
143 // no actual modification
146 TDF_Label aLabel = Label();
147 if (!aLabel.IsNull())
149 Handle(TDF_Data) aData = aLabel.Data();
150 Standard_Integer aCurrentTransaction = aData->Transaction();
151 Standard_Integer aMyTransaction = Transaction();
153 if (myDoBackup && aMyTransaction < aCurrentTransaction)
154 backupValue(theId, anOld, AbsentValue);
158 //=======================================================================
161 //=======================================================================
163 void TObj_TIntSparseArray::Clear ()
166 TDF_Label aLabel = Label();
167 if (!aLabel.IsNull())
169 Handle(TDF_Data) aData = aLabel.Data();
170 Standard_Integer aCurrentTransaction = aData->Transaction();
171 Standard_Integer aMyTransaction = Transaction();
173 if (myDoBackup && aMyTransaction < aCurrentTransaction)
175 TObj_TIntSparseArray_VecOfData::Iterator anIt (myVector);
176 for (; anIt.More(); anIt.Next())
178 Standard_Size anId = anIt.Key();
179 Standard_Integer aVal = anIt.Value();
180 backupValue(anId, aVal, AbsentValue);
187 //=======================================================================
188 //function : backupValue
190 //=======================================================================
192 void TObj_TIntSparseArray::backupValue (const Standard_Size theId,
193 const Standard_Integer theCurrValue,
194 const Standard_Integer theNewValue)
196 // save the current value if it has not been saved in previous time
197 if ( !myOldMap.IsBound( theId ) )
198 myOldMap.Bind(theId, theCurrValue);
201 // if value in Undo is the same as the new one, the item in Undo map may be cleared
202 Standard_Integer aUData = myOldMap.Value(theId);
203 if (aUData == theNewValue)
204 myOldMap.UnBind(theId);
208 //=======================================================================
209 //function : NewEmpty
211 //=======================================================================
213 Handle(TDF_Attribute) TObj_TIntSparseArray::NewEmpty () const
215 return new TObj_TIntSparseArray;
218 //=======================================================================
219 //function : BackupCopy
220 //purpose : Moves <this> delta into a new other attribute.
221 //=======================================================================
223 Handle(TDF_Attribute) TObj_TIntSparseArray::BackupCopy() const
225 Handle(TObj_TIntSparseArray) aCopy =
226 Handle(TObj_TIntSparseArray)::DownCast(NewEmpty());
228 // save delta data in a copy
229 if (!myOldMap.IsEmpty())
230 aCopy->myOldMap.Exchange ( (TObj_TIntSparseArray_MapOfData&)myOldMap );
235 //=======================================================================
237 //purpose : Restores contents of this with theDelta
238 //=======================================================================
240 void TObj_TIntSparseArray::Restore(const Handle(TDF_Attribute)& theDelta)
242 Handle(TObj_TIntSparseArray) aDelta =
243 Handle(TObj_TIntSparseArray)::DownCast(theDelta);
247 // restore the values from aDelta->myOldMap
248 if (!aDelta->myOldMap.IsEmpty())
250 TObj_TIntSparseArray_MapOfData::Iterator anIt (aDelta->myOldMap);
251 for (; anIt.More(); anIt.Next())
253 Standard_Size anId = anIt.Key();
254 Standard_Integer anOld = anIt.Value();
255 if (anOld == AbsentValue)
258 SetValue (anId, anOld);
263 //=======================================================================
265 //purpose : copy this
266 //=======================================================================
268 void TObj_TIntSparseArray::Paste (const Handle(TDF_Attribute)& theInto,
269 const Handle(TDF_RelocationTable)&) const
271 Handle(TObj_TIntSparseArray) aInto =
272 Handle(TObj_TIntSparseArray)::DownCast(theInto);
276 aInto->myVector.Assign(myVector);
279 //=======================================================================
280 //function : BeforeCommitTransaction
281 //purpose : It is called just before Commit or Abort transaction
282 //=======================================================================
284 void TObj_TIntSparseArray::BeforeCommitTransaction()
286 if (!myOldMap.IsEmpty())
293 //=======================================================================
294 //function : DeltaOnModification
295 //purpose : Applies aDelta to <me>
296 //=======================================================================
298 void TObj_TIntSparseArray::DeltaOnModification
299 (const Handle(TDF_DeltaOnModification)& theDelta)
301 // we do not call Backup here, because a backup data is formed inside Restore.
302 // Backup is called rather from BeforeCommitTransaction
303 Restore(theDelta->Attribute());
306 //=======================================================================
307 //function : AfterUndo
308 //purpose : After application of a TDF_Delta.
309 //=======================================================================
311 Standard_Boolean TObj_TIntSparseArray::AfterUndo
312 (const Handle(TDF_AttributeDelta)&,
313 const Standard_Boolean)
315 // we must be sure that a delta in <me> is cleared
317 return Standard_True;