summaryrefslogtreecommitdiff
path: root/src/TDF/TDF_Delta.cxx
blob: 7b88bc2904cfb67c26374fc4962002483ea157bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// File:	TDF_Delta.cxx
//      	-------------
// Author:	DAUTRY Philippe
//		<fid@fox.paris1.matra-dtv.fr>
// Copyright:	Matra Datavision 1997

// Version:	0.0
// History:	Version	Date		Purpose
//		0.0	Sep  8 1997	Creation



#include <TDF_Delta.ixx>

#include <TDF_LabelMap.hxx>
#include <TDF_ListIteratorOfAttributeDeltaList.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
#include <TDF_MapIteratorOfLabelMap.hxx>

#ifdef DEB
#include <Standard_ConstructionError.hxx>
#endif

#undef DEB_DELTA

//=======================================================================
//function : TDF_Delta
//purpose  : 
//=======================================================================

TDF_Delta::TDF_Delta() 
: myBeginTime(0),
  myEndTime(0)
{}


//=======================================================================
//function : Validity
//purpose  : 
//=======================================================================

void TDF_Delta::Validity
(const Standard_Integer aBeginTime,
 const Standard_Integer anEndTime)
{
  myBeginTime   = aBeginTime;
  myEndTime     = anEndTime;
}


//=======================================================================
//function : AddAttributeDelta
//purpose  : 
//=======================================================================

void TDF_Delta::AddAttributeDelta
(const Handle(TDF_AttributeDelta)& anAttributeDelta)
{ if (!anAttributeDelta.IsNull()) myAttDeltaList.Append(anAttributeDelta); }


//=======================================================================
//function : BeforeOrAfterApply
//purpose  : 
//=======================================================================

void TDF_Delta::BeforeOrAfterApply(const Standard_Boolean before) const
{
  TDF_AttributeDeltaList ADlist;
//  for (TDF_ListIteratorOfAttributeDeltaList itr(myAttDeltaList);
  TDF_ListIteratorOfAttributeDeltaList itr(myAttDeltaList) ;
  for ( ; itr.More(); itr.Next()) ADlist.Append(itr.Value());

  Handle(TDF_AttributeDelta) attDelta;
  Handle(TDF_Attribute) att;

  Standard_Boolean noDeadLock = Standard_True;
  Standard_Integer nbAD = ADlist.Extent();
  Standard_Boolean next;
  while (noDeadLock && (nbAD != 0)) {
    itr.Initialize(ADlist);
    while (itr.More()) {
      next = Standard_True;
      attDelta = itr.Value();
      att = attDelta->Attribute();
      if (before)
	next = !att->BeforeUndo(attDelta);
      else
	next = !att->AfterUndo(attDelta);

      if (next)
	itr.Next();
      else
	ADlist.Remove(itr);
    }
    noDeadLock = (nbAD > ADlist.Extent());
    nbAD = ADlist.Extent();
  }

  if (!noDeadLock) {
#ifdef DEB
    if (before) cout<<"Before"; else cout<<"After";
    cout<<"Undo(): dead lock between these attributes:"<<endl;
    for (itr.Initialize(ADlist); itr.More(); itr.Next()) {
      cout<<"AttributeDelta type = "<<itr.Value()->DynamicType()->Name();
      cout<<"  Attribute type = "<<itr.Value()->Attribute()->DynamicType()->Name()<<endl;;
    if (before)
      Standard_ConstructionError::Raise("BeforeUndo(): dead lock.");
    else
      Standard_ConstructionError::Raise("AfterUndo(): dead lock.");
    }
#endif
    for (itr.Initialize(ADlist); itr.More(); itr.Next()) {
      attDelta = itr.Value();
      att = attDelta->Attribute();
      if (before)
	att->BeforeUndo(attDelta,Standard_True);
      else
	att->AfterUndo(attDelta,Standard_True);
    }
  }
}


//=======================================================================
//function : Apply
//purpose  : 
//=======================================================================

void TDF_Delta::Apply()
{
  TDF_ListIteratorOfAttributeDeltaList itr;
  for (itr.Initialize(myAttDeltaList); itr.More(); itr.Next()) {
    const Handle(TDF_AttributeDelta)& attDelta = itr.Value();
    attDelta->Apply();
  }
}


//=======================================================================
//function : Labels
//purpose  : 
//=======================================================================

void TDF_Delta::Labels(TDF_LabelList& aLabelList) const
{
  TDF_LabelMap labMap;
  // If <aLabelList> is not empty...
#ifdef DEB_DELTA
  Standard_Boolean inList;
  if (aLabelList.Extent() > 0) cout<<"Previously added as modified label(s) ";
#endif
  for (TDF_ListIteratorOfLabelList it1(aLabelList);
       it1.More(); it1.Next()) {
#ifdef DEB_DELTA
    const TDF_Label& lab1 = it1.Value();
    inList = labMap.Add(lab1);
    if (!inList) {
      lab1.EntryDump(cout);cout<<" | ";
    }
#endif
  }
#ifdef DEB_DELTA
  cout<<endl;
#endif

  // New labels to add.
#ifdef DEB_DELTA
  if (myAttDeltaList.Extent() > 0) cout<<"New added as modified label(s) ";
#endif
  for (TDF_ListIteratorOfAttributeDeltaList it2(myAttDeltaList);
       it2.More();
       it2.Next()) {
#ifdef DEB_DELTA
    const TDF_Label& lab1 = it2.Value()->Label();
    inList = labMap.Add(lab1);
    if (!inList) {
      lab1.EntryDump(cout);cout<<" | ";
    }
#endif
  }
#ifdef DEB_DELTA
  cout<<endl;
#endif

  // Now put labels into <aLabelList>.
  aLabelList.Clear();
  for (TDF_MapIteratorOfLabelMap it3(labMap);
       it3.More(); it3.Next()) {
    aLabelList.Append(it3.Key());
  }
}

//=======================================================================
//function : Dump
//purpose  : 
//=======================================================================

void TDF_Delta::Dump(Standard_OStream& OS) const
{
  OS<<"DELTA available from time \t#"<<myBeginTime<<" to time \t#"<<myEndTime<<endl;
  Standard_Integer n = 0;
//  for (TDF_ListIteratorOfAttributeDeltaList itr(myAttDeltaList);
  TDF_ListIteratorOfAttributeDeltaList itr(myAttDeltaList) ;
  for ( ; itr.More(); itr.Next()) ++n;
  OS<<"Nb Attribute Delta(s): "<<n<<endl;
  for (itr.Initialize(myAttDeltaList); itr.More(); itr.Next()) {
    const Handle(TDF_AttributeDelta)& attDelta = itr.Value();
    OS<<"| "; attDelta->Dump(OS); OS<<endl;
  }
}