Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TFunction / TFunction_IFunction.cxx
1 // File:        TFunction_IFunction.cxx
2 // Created:     Mon Jun 21 14:55:45 2008
3 // Author:      Vladislav ROMASHKO
4 //              <vladislav.romashko@opencascade.com>
5
6
7 #include <TFunction_IFunction.ixx>
8 #include <TFunction_Function.hxx>
9 #include <TFunction_GraphNode.hxx>
10 #include <TFunction_DriverTable.hxx>
11 #include <TFunction_Scope.hxx>
12 #include <TFunction_DataMapOfLabelListOfLabel.hxx>
13 #include <TFunction_DataMapIteratorOfDataMapOfLabelListOfLabel.hxx>
14 #include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx>
15
16 #include <TDF_LabelList.hxx>
17 #include <TDF_ListIteratorOfLabelList.hxx>
18 #include <TDF_MapIteratorOfLabelMap.hxx>
19
20 #include <Standard_NoSuchObject.hxx>
21 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
22
23 #ifdef DEB
24 #include <TDataStd_Name.hxx>
25 #endif // DEB
26
27 //=======================================================================
28 //function : NewFunction
29 //purpose  : Static method to create a new function.
30 //=======================================================================
31
32 Standard_Boolean TFunction_IFunction::NewFunction(const TDF_Label& L, const Standard_GUID& ID) 
33
34   // Set Function (ID, code of failure)
35   TFunction_Function::Set(L, ID)->SetFailure(0);
36
37   // Set graph node (dependencies, status)
38   Handle(TFunction_GraphNode) graphNode = TFunction_GraphNode::Set(L);
39   graphNode->RemoveAllPrevious();
40   graphNode->RemoveAllNext();
41   graphNode->SetStatus(TFunction_ES_WrongDefinition);
42
43   // Check presence of the function in the current scope
44   TFunction_Scope::Set(L)->AddFunction(L);
45
46   return TFunction_DriverTable::Get()->HasDriver(ID);
47 }
48
49 //=======================================================================
50 //function : DeleteFunction
51 //purpose  : Static method to delete a function.
52 //=======================================================================
53
54 Standard_Boolean TFunction_IFunction::DeleteFunction(const TDF_Label& L) 
55
56   // Delete Function
57   Handle(TFunction_Function) func;
58   if (L.FindAttribute(TFunction_Function::GetID(), func))
59     L.ForgetAttribute(func);
60
61   // Take the scope of functions
62   Handle(TFunction_Scope) scope = TFunction_Scope::Set(L);
63   const Standard_Integer funcID = scope->GetFunctions().Find2(L);
64
65   // Delete graph node
66   Handle(TFunction_GraphNode) graphNode;
67   if (L.FindAttribute(TFunction_GraphNode::GetID(), graphNode))
68   {
69     const TColStd_MapOfInteger& prev = graphNode->GetPrevious();
70     const TColStd_MapOfInteger& next = graphNode->GetNext();
71     // Disconnect previous functions
72     TColStd_MapIteratorOfMapOfInteger itrm(prev);
73     for (; itrm.More(); itrm.Next())
74     {
75       const Standard_Integer ID = itrm.Key();
76       const TDF_Label& La = scope->GetFunctions().Find1(ID);
77       Handle(TFunction_GraphNode) G;
78       if (La.FindAttribute(TFunction_GraphNode::GetID(), G))
79       {
80         G->RemoveNext(funcID);
81       }
82     }
83     // Disconnect next functions
84     for (itrm.Initialize(next); itrm.More(); itrm.Next())
85     {
86       const Standard_Integer ID = itrm.Key();
87       const TDF_Label& La = scope->GetFunctions().Find1(ID);
88       Handle(TFunction_GraphNode) G;
89       if (La.FindAttribute(TFunction_GraphNode::GetID(), G))
90       {
91         G->RemovePrevious(funcID);
92       }
93     }
94
95     L.ForgetAttribute(graphNode);
96   }
97
98   // Delete the function from the current scope of functions.
99   scope->RemoveFunction(L);
100
101   return Standard_True;
102 }
103
104 //=======================================================================
105 //function : UpdateDependencies
106 //purpose  : Updates the dependencies of all functions.
107 //=======================================================================
108
109 Standard_Boolean TFunction_IFunction::UpdateDependencies(const TDF_Label& Access)
110 {
111   // Take the scope of functions.
112   Handle(TFunction_Scope) scope = TFunction_Scope::Set(Access);
113
114   // Make a data map of function - results.
115   TFunction_DataMapOfLabelListOfLabel table;
116   TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(scope->GetFunctions());
117   for (; itrm.More(); itrm.Next())
118   {
119     // Label of the function
120     const TDF_Label& L = itrm.Key2();
121     TFunction_IFunction iFunction(L);
122
123 #ifdef DEB
124     /*
125     TCollection_AsciiString fname;
126     Handle(TDataStd_Name) name;
127     if (L.FindAttribute(TDataStd_Name::GetID(), name))
128     {
129       fname = name->Get();
130     }
131     else if (L.Father().FindAttribute(TDataStd_Name::GetID(), name))
132     {
133       fname = name->Get();
134     }
135     */
136 #endif // DEB
137     
138     // Take the driver.
139     Handle(TFunction_Driver) driver = iFunction.GetDriver();
140
141     // Take the results.
142     TDF_LabelList res;
143     driver->Results(res);
144
145     // Fill-in the table
146     table.Bind(L, res);
147     
148     // Clean the graph node
149     Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode();
150     graphNode->RemoveAllPrevious();
151     graphNode->RemoveAllNext();
152   }
153
154   // Update previous and next functions for each function of the scope
155   TFunction_DataMapIteratorOfDataMapOfLabelListOfLabel itrd;
156   for (itrm.Initialize(scope->GetFunctions()); itrm.More(); itrm.Next())
157   {
158     // Label of the functions
159     const TDF_Label& L = itrm.Key2();
160     TFunction_IFunction iFunction(L);
161
162 #ifdef DEB
163     /*
164     TCollection_AsciiString fname;
165     Handle(TDataStd_Name) name;
166     if (L.FindAttribute(TDataStd_Name::GetID(), name))
167     {
168       fname = name->Get();
169     }
170     else if (L.Father().FindAttribute(TDataStd_Name::GetID(), name))
171     {
172       fname = name->Get();
173     }
174     */
175 #endif // DEB
176
177     // Take the driver.
178     Handle(TFunction_Driver) driver = iFunction.GetDriver();
179
180     // Take the arguments.
181     TDF_LabelList args;
182     driver->Arguments(args);
183     
184     // Make a map of arguments
185     TDF_LabelMap argsMap;
186     TDF_ListIteratorOfLabelList itrl(args);
187     for (; itrl.More(); itrl.Next())
188       argsMap.Add(itrl.Value());
189
190     // ID of the function
191     const Standard_Integer funcID = itrm.Key1();
192
193     // Find the functions, which produce the arguments of this function.
194     for (itrd.Initialize(table); itrd.More(); itrd.Next())
195     {
196       const TDF_Label& anotherL = itrd.Key();
197       if (L == anotherL)
198         continue;
199       const TDF_LabelList& anotherRes = itrd.Value();
200
201 #ifdef DEB
202       /*
203       TCollection_AsciiString afname;
204       Handle(TDataStd_Name) aname;
205       if (anotherL.FindAttribute(TDataStd_Name::GetID(), aname))
206       {
207         afname = aname->Get();
208       }
209       else if (anotherL.Father().FindAttribute(TDataStd_Name::GetID(), aname))
210       {
211         afname = aname->Get();
212       }
213       */
214 #endif // DEB
215
216       for (itrl.Initialize(anotherRes); itrl.More(); itrl.Next())
217       {
218         if (argsMap.Contains(itrl.Value()))
219         {
220           iFunction.GetGraphNode()->AddPrevious(anotherL);
221
222           TFunction_IFunction iAnotherFunction(anotherL);
223           iAnotherFunction.GetGraphNode()->AddNext(funcID);
224         }
225       }
226     }
227   }
228
229   return Standard_True;
230 }
231
232 //=======================================================================
233 //function : Create
234 //purpose  : Constructor
235 //=======================================================================
236
237 TFunction_IFunction::TFunction_IFunction() 
238 {  
239
240 }
241
242 //=======================================================================
243 //function : Create
244 //purpose  : Constructor
245 //=======================================================================
246
247 TFunction_IFunction::TFunction_IFunction(const TDF_Label& L)
248 {
249   Init(L);
250 }
251
252 //=======================================================================
253 //function : Init
254 //purpose  : Initializes the interface.
255 //=======================================================================
256
257 void TFunction_IFunction::Init(const TDF_Label& L)
258 {
259   myLabel = L;
260 }
261
262 //=======================================================================
263 //function : Label
264 //purpose  : Returns the label of the interface.
265 //=======================================================================
266
267 const TDF_Label& TFunction_IFunction::Label() const
268 {
269   return myLabel;
270 }
271
272 //=======================================================================
273 //function : UpdateDependencies
274 //purpose  : Updates the dependencies of this function only.
275 //=======================================================================
276
277 Standard_Boolean TFunction_IFunction::UpdateDependencies() const
278 {
279   // Take the arguments & results of the functions
280   TDF_LabelList args, res;
281   Handle(TFunction_Driver) D = GetDriver();
282   D->Arguments(args);
283   D->Results(res);
284
285   // Insert the arguments and results into maps for fast searching.
286   TDF_LabelMap argsMap, resMap;
287   TDF_ListIteratorOfLabelList itrl(args);
288   for (; itrl.More(); itrl.Next())
289   {
290     argsMap.Add(itrl.Value());
291   }
292   for (itrl.Initialize(res); itrl.More(); itrl.Next())
293   {
294     resMap.Add(itrl.Value());
295   }
296
297   // Consider all other functions checking their attitude to this function.
298   Handle(TFunction_Scope) scope = TFunction_Scope::Set(myLabel);
299   TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(scope->GetFunctions());
300   for (; itrm.More(); itrm.Next())
301   {
302     const TDF_Label& L = itrm.Key2();
303     if (L == myLabel)
304       continue;
305     TFunction_IFunction iFunc(L);
306     D = iFunc.GetDriver();
307
308     // Arguments of another function
309     args.Clear();
310     D->Arguments(args);
311
312     // Check presence of the arguments in results of our function
313     for (itrl.Initialize(args); itrl.More(); itrl.Next())
314     {
315       if (resMap.Contains(itrl.Value()))
316       {
317         // Our function is a previous one for this function.
318         GetGraphNode()->AddNext(scope->GetFunctions().Find2(L));
319         iFunc.GetGraphNode()->AddPrevious(scope->GetFunctions().Find2(myLabel));
320       }
321     }
322
323     // Results of another function
324     res.Clear();
325     D->Results(res);
326
327     // Check presence of the results in arguments of our function
328     for (itrl.Initialize(res); itrl.More(); itrl.Next())
329     {
330       if (argsMap.Contains(itrl.Value()))
331       {
332         // Our function is a next one for this function.
333         GetGraphNode()->AddPrevious(scope->GetFunctions().Find2(L));
334         iFunc.GetGraphNode()->AddNext(scope->GetFunctions().Find2(myLabel));
335       }
336     }
337   }
338
339   return Standard_True;
340 }
341
342 //=======================================================================
343 //function : Arguments
344 //purpose  : The method fills-in the list by labels, 
345 //           where the arguments of the function are located.
346 //=======================================================================
347
348 void TFunction_IFunction::Arguments(TDF_LabelList& args) const
349 {
350   Handle(TFunction_Driver) driver = GetDriver();
351   driver->Arguments(args);
352 }
353
354 //=======================================================================
355 //function : Results
356 //purpose  : The method fills-in the list by labels,
357 //           where the results of the function are located.
358 //=======================================================================
359
360 void TFunction_IFunction::Results(TDF_LabelList& res) const
361 {
362   Handle(TFunction_Driver) driver = GetDriver();
363   driver->Results(res);
364 }
365
366 //=======================================================================
367 //function : GetPrevious
368 //purpose  : Returns a list of previous functions.
369 //=======================================================================
370
371 void TFunction_IFunction::GetPrevious(TDF_LabelList& prev) const
372 {
373   Handle(TFunction_GraphNode) graph = GetGraphNode();
374   const TColStd_MapOfInteger& map = graph->GetPrevious();
375   Handle(TFunction_Scope) scope = TFunction_Scope::Set(myLabel);
376
377   TColStd_MapIteratorOfMapOfInteger itrm(map);
378   for (; itrm.More(); itrm.Next())
379   {
380     const Standard_Integer funcID = itrm.Key();
381     if (scope->GetFunctions().IsBound1(funcID))
382     {
383       prev.Append(scope->GetFunctions().Find1(funcID));
384     }
385   }
386 }
387
388 //=======================================================================
389 //function : GetNext
390 //purpose  : Returns a list of next functions.
391 //=======================================================================
392
393 void TFunction_IFunction::GetNext(TDF_LabelList& next) const
394 {
395   Handle(TFunction_GraphNode) graph = GetGraphNode();
396   const TColStd_MapOfInteger& map = graph->GetNext();
397   Handle(TFunction_Scope) scope = TFunction_Scope::Set(myLabel);
398
399   TColStd_MapIteratorOfMapOfInteger itrm(map);
400   for (; itrm.More(); itrm.Next())
401   {
402     const Standard_Integer funcID = itrm.Key();
403     if (scope->GetFunctions().IsBound1(funcID))
404     {
405       next.Append(scope->GetFunctions().Find1(funcID));
406     }
407   }
408 }
409
410 //=======================================================================
411 //function : GetStatus
412 //purpose  : Returns the execution status of the function.
413 //=======================================================================
414
415 TFunction_ExecutionStatus TFunction_IFunction::GetStatus() const
416 {
417   Handle(TFunction_GraphNode) graph = GetGraphNode();
418   return graph->GetStatus();
419 }
420
421 //=======================================================================
422 //function : SetStatus
423 //purpose  : Defines an execution status for a function.
424 //=======================================================================
425
426 void TFunction_IFunction::SetStatus(const TFunction_ExecutionStatus status) const
427 {
428   Handle(TFunction_GraphNode) graph = GetGraphNode();
429   graph->SetStatus(status);
430 }
431
432 //=======================================================================
433 //function : GetFunctions
434 //purpose  : Returns the scope of functions.
435 //=======================================================================
436
437 const TFunction_DoubleMapOfIntegerLabel& TFunction_IFunction::GetAllFunctions() const
438 {
439   return TFunction_Scope::Set(myLabel)->GetFunctions();
440 }
441
442 //=======================================================================
443 //function : GetLogbook
444 //purpose  : Returns the Logbook.
445 //=======================================================================
446
447 TFunction_Logbook& TFunction_IFunction::GetLogbook() const
448 {
449   return TFunction_Scope::Set(myLabel)->GetLogbook();
450 }
451
452 //=======================================================================
453 //function : GetDriver
454 //purpose  : Returns the function driver.
455 //=======================================================================
456
457 Handle(TFunction_Driver) TFunction_IFunction::GetDriver(const Standard_Integer thread) const
458 {
459   Handle(TFunction_Driver) driver;
460   Handle(TFunction_Function) func;
461   if (!myLabel.FindAttribute(TFunction_Function::GetID(), func))
462     Standard_NoSuchObject::Raise("TFunction_IFunction::GetDriver(): A Function is not found attached to this label");
463   if (!TFunction_DriverTable::Get()->FindDriver(func->GetDriverGUID(), driver, thread))
464     Standard_NoSuchObject::Raise("TFunction_IFunction::GetDriver(): A driver is not found for this ID");
465   driver->Init(myLabel);
466   return driver;
467 }
468
469 //=======================================================================
470 //function : GetGraphNode
471 //purpose  : Returns a graph node of the function.
472 //=======================================================================
473
474 Handle(TFunction_GraphNode) TFunction_IFunction::GetGraphNode() const
475 {
476   Handle(TFunction_GraphNode) graphNode;
477   if (!myLabel.FindAttribute(TFunction_GraphNode::GetID(), graphNode))
478     Standard_NoSuchObject::Raise("TFunction_IFunction::GetStatus(): A graph node is not found attached to this label");
479   return graphNode;
480 }