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