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