b311480e |
1 | // Created on: 2008-06-23 |
2 | // Created by: Vladislav ROMASHKO |
973c2be1 |
3 | // Copyright (c) 2008-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. |
7fd59977 |
15 | |
7fd59977 |
16 | |
42cf5bc1 |
17 | #include <TColStd_MapIteratorOfMapOfInteger.hxx> |
18 | #include <TDataStd_Name.hxx> |
19 | #include <TDF_DataMapIteratorOfLabelIntegerMap.hxx> |
20 | #include <TDF_Label.hxx> |
21 | #include <TDF_LabelIntegerMap.hxx> |
7fd59977 |
22 | #include <TDF_LabelMap.hxx> |
7fd59977 |
23 | #include <TDF_ListIteratorOfLabelList.hxx> |
42cf5bc1 |
24 | #include <TDF_MapIteratorOfLabelMap.hxx> |
25 | #include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx> |
26 | #include <TFunction_GraphNode.hxx> |
27 | #include <TFunction_IFunction.hxx> |
28 | #include <TFunction_Iterator.hxx> |
29 | #include <TFunction_Scope.hxx> |
7fd59977 |
30 | |
31 | //======================================================================= |
32 | //function : Create |
33 | //purpose : Constructor |
34 | //======================================================================= |
7fd59977 |
35 | TFunction_Iterator::TFunction_Iterator():myUsageOfExecutionStatus(Standard_False) |
36 | { |
37 | |
38 | } |
39 | |
40 | //======================================================================= |
41 | //function : Create |
42 | //purpose : Constructor |
43 | //======================================================================= |
44 | |
45 | TFunction_Iterator::TFunction_Iterator(const TDF_Label& Access):myUsageOfExecutionStatus(Standard_False) |
46 | { |
47 | Init(Access); |
48 | } |
49 | |
50 | //======================================================================= |
51 | //function : Init |
52 | //purpose : Initializes the Iterator. |
53 | //======================================================================= |
54 | |
55 | void TFunction_Iterator::Init(const TDF_Label& Access) |
56 | { |
57 | myCurrent.Clear(); |
58 | myPassedFunctions.Clear(); |
59 | |
60 | // Get the scope of functions |
61 | myScope = TFunction_Scope::Set(Access); |
62 | |
63 | // Find the roots |
64 | TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions()); |
65 | for (; itrm.More(); itrm.Next()) |
66 | { |
67 | const TDF_Label& L = itrm.Key2(); |
68 | |
69 | TFunction_IFunction iFunction(L); |
70 | Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode(); |
71 | TFunction_ExecutionStatus status = graphNode->GetStatus(); |
72 | |
73 | // Check whether the function is a root function |
74 | if (!graphNode->GetPrevious().IsEmpty()) |
75 | continue; |
76 | |
77 | // In execution mode we consider only "not executed" functions. |
78 | if (myUsageOfExecutionStatus && status != TFunction_ES_NotExecuted) |
79 | continue; |
80 | |
81 | myCurrent.Append(L); |
82 | |
83 | // Register already passed functions |
84 | if (!myUsageOfExecutionStatus) |
85 | myPassedFunctions.Add(L); |
86 | } |
87 | } |
88 | |
89 | //======================================================================= |
90 | //function : SetUsageOfExecutionStatus |
91 | //purpose : Defines usage of execution status |
92 | //======================================================================= |
93 | |
94 | void TFunction_Iterator::SetUsageOfExecutionStatus(const Standard_Boolean usage) |
95 | { |
96 | myUsageOfExecutionStatus = usage; |
97 | } |
98 | |
99 | //======================================================================= |
100 | //function : GetUsageOfExecutionStatus |
101 | //purpose : Returns usage of execution status |
102 | //======================================================================= |
103 | |
104 | Standard_Boolean TFunction_Iterator::GetUsageOfExecutionStatus() const |
105 | { |
106 | return myUsageOfExecutionStatus; |
107 | } |
108 | |
109 | //======================================================================= |
110 | //function : GetMaxNbThreads |
111 | //purpose : Defines the maximum number of threads |
112 | //======================================================================= |
113 | |
114 | Standard_Integer TFunction_Iterator::GetMaxNbThreads() const |
115 | { |
116 | int nb_threads = 0; |
117 | TFunction_Iterator fIterator; |
118 | fIterator.myUsageOfExecutionStatus = Standard_False; |
119 | |
120 | // Start iteration from current functions |
121 | TDF_ListIteratorOfLabelList itrl(myCurrent); |
122 | for (; itrl.More(); itrl.Next()) |
123 | { |
124 | fIterator.myCurrent.Append(itrl.Value()); |
125 | } |
126 | |
127 | // Check number of semultenious current functions |
128 | while (!fIterator.Current().IsEmpty()) |
129 | { |
130 | const TDF_LabelList& current = fIterator.Current(); |
131 | if (nb_threads < current.Extent()) |
132 | nb_threads = current.Extent(); |
133 | fIterator.Next(); |
134 | } |
135 | |
136 | return nb_threads; |
137 | } |
138 | |
139 | //======================================================================= |
140 | //function : Current |
141 | //purpose : Returns the current list of functions |
142 | //======================================================================= |
143 | |
144 | const TDF_LabelList& TFunction_Iterator::Current() const |
145 | { |
146 | return myCurrent; |
147 | } |
148 | |
149 | //======================================================================= |
150 | //function : More |
151 | //purpose : Returns true if the iteration is ended |
152 | //======================================================================= |
153 | |
154 | Standard_Boolean TFunction_Iterator::More() const |
155 | { |
156 | if (myUsageOfExecutionStatus) |
157 | { |
158 | TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions()); |
159 | for (; itrm.More(); itrm.Next()) |
160 | { |
161 | const TDF_Label& L = itrm.Key2(); |
162 | if (GetStatus(L) == TFunction_ES_NotExecuted) |
163 | return Standard_True; |
164 | } |
165 | return Standard_False; |
166 | } |
965681c5 |
167 | return !myCurrent.IsEmpty(); |
7fd59977 |
168 | } |
169 | |
170 | //======================================================================= |
171 | //function : Next |
172 | //purpose : Switches the iterator to the next functions |
173 | //======================================================================= |
174 | |
175 | void TFunction_Iterator::Next() |
176 | { |
177 | TDF_LabelMap next_current; |
178 | TDF_ListIteratorOfLabelList itrl(myCurrent); |
179 | for (; itrl.More(); itrl.Next()) |
180 | { |
181 | const TDF_Label& L = itrl.Value(); |
182 | TFunction_IFunction iFunction(L); |
183 | |
184 | Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode(); |
7fd59977 |
185 | const TColStd_MapOfInteger& next = graphNode->GetNext(); |
186 | TFunction_ExecutionStatus status = graphNode->GetStatus(); |
187 | |
188 | // Consider the execution status |
189 | if (myUsageOfExecutionStatus) |
190 | { |
191 | if (status == TFunction_ES_NotExecuted || status == TFunction_ES_Executing) |
192 | { |
193 | next_current.Add(L); |
194 | continue; |
195 | } |
196 | else if (status == TFunction_ES_WrongDefinition || status == TFunction_ES_Failed) |
197 | { |
198 | continue; |
199 | } |
200 | |
201 | // if "succeeded", we consider the next functions... see below. |
202 | } |
203 | |
204 | // Add next functions |
205 | TColStd_MapIteratorOfMapOfInteger itrm(next); |
206 | for (; itrm.More(); itrm.Next()) |
207 | { |
208 | const Standard_Integer IDnext = itrm.Key(); |
209 | const TDF_Label& Lnext = myScope->GetFunctions().Find1(IDnext); |
210 | |
211 | if (myUsageOfExecutionStatus) |
212 | { |
213 | // A previous function is "succeeded", check status of next functions and |
214 | // all other previous functions of the next functions. |
215 | |
216 | // Check status, it should be "not executed" |
217 | TFunction_IFunction iNextFunction(Lnext); |
218 | Handle(TFunction_GraphNode) nextGraphNode = iNextFunction.GetGraphNode(); |
219 | TFunction_ExecutionStatus next_status = nextGraphNode->GetStatus(); |
220 | if (next_status != TFunction_ES_NotExecuted && next_status != TFunction_ES_Executing) |
221 | { |
222 | continue; |
223 | } |
224 | |
225 | // Check all previous functions: all of them should be "succeeded" |
226 | Standard_Boolean is_prev_succeeded = Standard_True; |
227 | const TColStd_MapOfInteger& prevOfNext = nextGraphNode->GetPrevious(); |
228 | TColStd_MapIteratorOfMapOfInteger itrp(prevOfNext); |
229 | for (; itrp.More(); itrp.Next()) |
230 | { |
231 | const Standard_Integer IDprevOfNext = itrp.Key(); |
232 | const TDF_Label& LprevOfNext = myScope->GetFunctions().Find1(IDprevOfNext); |
233 | Handle(TFunction_GraphNode) GprevOfNext; |
234 | LprevOfNext.FindAttribute(TFunction_GraphNode::GetID(), GprevOfNext); |
235 | TFunction_ExecutionStatus prev_status = GprevOfNext->GetStatus(); |
236 | if (prev_status != TFunction_ES_Succeeded) |
237 | { |
238 | is_prev_succeeded = Standard_False; |
239 | break; |
240 | } |
241 | } |
242 | if (!is_prev_succeeded) |
243 | { |
244 | continue; |
245 | } |
246 | } |
247 | |
248 | // Ignore already passed fucntions (for the mode of ignoring the execution status). |
249 | if (!myUsageOfExecutionStatus && myPassedFunctions.Contains(Lnext)) |
250 | continue; |
251 | |
252 | next_current.Add(Lnext); |
253 | |
254 | // Register already passed functions |
255 | if (!myUsageOfExecutionStatus) |
256 | myPassedFunctions.Add(Lnext); |
257 | } |
258 | } |
259 | |
260 | myCurrent.Clear(); |
261 | TDF_MapIteratorOfLabelMap itrm(next_current); |
262 | for (; itrm.More(); itrm.Next()) |
263 | { |
264 | myCurrent.Append(itrm.Key()); |
265 | } |
266 | } |
267 | |
268 | //======================================================================= |
269 | //function : GetStatus |
270 | //purpose : Returns the execution status of the function |
271 | //======================================================================= |
272 | |
273 | TFunction_ExecutionStatus TFunction_Iterator::GetStatus(const TDF_Label& func) const |
274 | { |
275 | TFunction_IFunction iFunction(func); |
276 | return iFunction.GetGraphNode()->GetStatus(); |
277 | } |
278 | |
279 | //======================================================================= |
280 | //function : SetStatus |
281 | //purpose : Defines an execution status for a function |
282 | //======================================================================= |
283 | |
284 | void TFunction_Iterator::SetStatus(const TDF_Label& func, |
285 | const TFunction_ExecutionStatus status) const |
286 | { |
287 | TFunction_IFunction iFunction(func); |
288 | iFunction.GetGraphNode()->SetStatus(status); |
289 | } |
290 | |
291 | //======================================================================= |
292 | //function : Dump |
293 | //purpose : |
294 | //======================================================================= |
295 | Standard_OStream& TFunction_Iterator::Dump (Standard_OStream& anOS) const |
296 | { |
04232180 |
297 | anOS << "Functions:" << std::endl ; |
7fd59977 |
298 | |
299 | if (myCurrent.IsEmpty()) |
300 | return anOS; |
301 | |
302 | // Memorize the status of each function |
303 | // in order to recover it after iteration. |
304 | TDF_LabelIntegerMap saved_status; |
305 | Handle(TFunction_Scope) scope = TFunction_Scope::Set(myCurrent.First()); |
306 | TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrd(scope->GetFunctions()); |
307 | for (; itrd.More(); itrd.Next()) |
308 | { |
309 | const TDF_Label& L = itrd.Key2(); |
310 | Handle(TFunction_GraphNode) G; |
311 | if (L.FindAttribute(TFunction_GraphNode::GetID(), G)) |
312 | { |
313 | saved_status.Bind(L, (Standard_Integer) G->GetStatus()); |
314 | G->SetStatus(TFunction_ES_NotExecuted); |
315 | } |
316 | } |
317 | |
318 | TFunction_Iterator fIterator(myCurrent.First()); |
319 | fIterator.myUsageOfExecutionStatus = Standard_True; |
320 | |
321 | while (fIterator.More()) |
322 | { |
323 | const TDF_LabelList& current = fIterator.Current(); |
324 | |
325 | TDF_ListIteratorOfLabelList itrl(current); |
326 | for (; itrl.More(); itrl.Next()) |
327 | { |
328 | |
329 | const TDF_Label& L = itrl.Value(); |
330 | |
331 | Handle(TDataStd_Name) N; |
332 | if (L.FindAttribute(TDataStd_Name::GetID(), N)) |
333 | { |
334 | anOS << TCollection_AsciiString(N->Get()).ToCString() ; |
335 | } |
336 | |
337 | Handle(TFunction_GraphNode) G; |
338 | if (L.FindAttribute(TFunction_GraphNode::GetID(), G)) |
339 | { |
340 | G->SetStatus(TFunction_ES_Succeeded); |
341 | } |
342 | |
343 | anOS << "\t" ; |
344 | } |
345 | |
346 | fIterator.Next(); |
347 | |
04232180 |
348 | anOS << std::endl; |
7fd59977 |
349 | } |
350 | |
351 | // Recover the status of functions |
352 | TDF_DataMapIteratorOfLabelIntegerMap itrm(saved_status); |
353 | for (; itrm.More(); itrm.Next()) |
354 | { |
355 | const TDF_Label& L = itrm.Key(); |
356 | TFunction_ExecutionStatus status = (TFunction_ExecutionStatus) itrm.Value(); |
357 | |
358 | Handle(TFunction_GraphNode) G; |
359 | if (L.FindAttribute(TFunction_GraphNode::GetID(), G)) |
360 | { |
361 | G->SetStatus(status); |
362 | } |
363 | } |
364 | |
365 | return anOS; |
366 | } |