0026005: Problem with transient TFunction_Logbook
[occt.git] / src / TFunction / TFunction_IFunction.cxx
CommitLineData
b311480e 1// Created on: 2008-06-21
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 <Standard_GUID.hxx>
18#include <Standard_NoSuchObject.hxx>
19#include <TColStd_MapIteratorOfMapOfInteger.hxx>
20#include <TDF_Label.hxx>
7fd59977 21#include <TDF_LabelList.hxx>
22#include <TDF_ListIteratorOfLabelList.hxx>
23#include <TDF_MapIteratorOfLabelMap.hxx>
42cf5bc1 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>
7fd59977 34
7fd59977 35//=======================================================================
36//function : NewFunction
37//purpose : Static method to create a new function.
38//=======================================================================
7fd59977 39Standard_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
61Standard_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
116Standard_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
7fd59977 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
7fd59977 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
7fd59977 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
199TFunction_IFunction::TFunction_IFunction()
200{
201
202}
203
204//=======================================================================
205//function : Create
206//purpose : Constructor
207//=======================================================================
208
209TFunction_IFunction::TFunction_IFunction(const TDF_Label& L)
210{
211 Init(L);
212}
213
214//=======================================================================
215//function : Init
216//purpose : Initializes the interface.
217//=======================================================================
218
219void 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
229const 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
239Standard_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
310void 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
322void 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
333void 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
355void 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
377TFunction_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
388void 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
399const 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
f486f64d 409Handle(TFunction_Logbook) TFunction_IFunction::GetLogbook() const
7fd59977 410{
411 return TFunction_Scope::Set(myLabel)->GetLogbook();
412}
413
414//=======================================================================
415//function : GetDriver
416//purpose : Returns the function driver.
417//=======================================================================
418
419Handle(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 Standard_NoSuchObject::Raise("TFunction_IFunction::GetDriver(): A Function is not found attached to this label");
425 if (!TFunction_DriverTable::Get()->FindDriver(func->GetDriverGUID(), driver, thread))
426 Standard_NoSuchObject::Raise("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
436Handle(TFunction_GraphNode) TFunction_IFunction::GetGraphNode() const
437{
438 Handle(TFunction_GraphNode) graphNode;
439 if (!myLabel.FindAttribute(TFunction_GraphNode::GetID(), graphNode))
440 Standard_NoSuchObject::Raise("TFunction_IFunction::GetStatus(): A graph node is not found attached to this label");
441 return graphNode;
442}