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