aff5997d |
1 | #include "FThread.h" |
6396eacb |
2 | #include "graphwidget.h" |
aff5997d |
3 | |
4 | #include <TFunction_Function.hxx> |
5 | #include <TFunction_IFunction.hxx> |
6 | #include <TFunction_Driver.hxx> |
7 | #include <TFunction_GraphNode.hxx> |
8 | |
9 | #include <TDataStd_Tick.hxx> |
10 | #include <TDF_ListIteratorOfLabelList.hxx> |
11 | |
12 | FThread::FThread(QObject* parent):QThread(parent),thread_index(0) |
13 | { |
14 | |
15 | } |
16 | |
17 | FThread::~FThread() |
18 | { |
19 | |
20 | } |
21 | |
22 | void FThread::setIterator(const TFunction_Iterator& itr) |
23 | { |
24 | this->itr = itr; |
25 | } |
26 | |
27 | void FThread::setLogbook(const Handle(TFunction_Logbook)& log) |
28 | { |
29 | this->log = log; |
30 | } |
31 | |
32 | void FThread::setGraph(GraphWidget* graph) |
33 | { |
34 | this->graph = graph; |
35 | } |
36 | |
37 | void FThread::setThreadIndex(const int thread_index) |
38 | { |
39 | this->thread_index = thread_index; |
40 | } |
41 | |
42 | // Returns any free (not executed yet) function |
43 | TDF_Label FThread::getFreeFunction() |
44 | { |
45 | TDF_Label L; |
46 | TDF_ListIteratorOfLabelList itrl(itr.Current()); |
47 | for (; itrl.More(); itrl.Next()) |
48 | { |
49 | if (itr.GetStatus(itrl.Value()) == TFunction_ES_NotExecuted) |
50 | { |
51 | L = itrl.Value(); |
52 | itr.SetStatus(L, TFunction_ES_Executing); |
53 | break; |
54 | } |
55 | } |
56 | return L; |
57 | } |
58 | |
59 | void FThread::run() |
60 | { |
61 | while (itr.More()) |
62 | { |
63 | // Take current function, |
64 | // choose one and set its status to "executing". |
65 | TDF_Label L; |
66 | for (; itr.More(); itr.Next()) |
67 | { |
68 | L = getFreeFunction(); |
69 | if (L.IsNull()) |
6396eacb |
70 | #ifdef __GNUC__ |
71 | sleep(0.001); |
72 | #else |
73 | ::Sleep(100); |
74 | #endif |
aff5997d |
75 | else |
76 | break; |
77 | } |
78 | |
79 | // Nothing to compute? Finish. |
80 | if (L.IsNull()) |
81 | { |
82 | graph->setFinished(); |
83 | return; |
84 | } |
85 | |
86 | // Check a Tick attribute - a marker of skipped for execution functions. |
87 | // It is used only for visual presentation of skipped (not modified) functions. |
88 | Handle(TDataStd_Tick) tick; |
89 | if (L.FindAttribute(TDataStd_Tick::GetID(), tick)) |
90 | L.ForgetAttribute(tick); |
91 | |
92 | // Execute the function |
93 | Handle(TFunction_Driver) D = TFunction_IFunction(L).GetDriver(thread_index); |
94 | const bool must = D->MustExecute(log); |
95 | if (must) |
96 | { |
97 | // Usage of mutex for execution of Open CASCADE code is the most stupid thing!!! |
98 | // But it makes the execution more reliable... |
99 | const int ret = D->Execute(log); |
100 | if (ret == 0) |
101 | { |
102 | // Successfuly executed! |
103 | itr.SetStatus(L, TFunction_ES_Succeeded); |
104 | |
105 | TDF_LabelList res; |
106 | D->Results(res); |
107 | TDF_ListIteratorOfLabelList itrr(res); |
108 | for (; itrr.More(); itrr.Next()) |
109 | { |
110 | log->SetImpacted(itrr.Value()); |
111 | } |
112 | } |
113 | else |
114 | { |
115 | // Failed... |
116 | itr.SetStatus(L, TFunction_ES_Failed); |
117 | graph->setFinished(); |
118 | return; |
119 | } |
120 | } |
121 | else if (itr.GetStatus(L) == TFunction_ES_Executing) |
122 | { |
123 | itr.SetStatus(L, TFunction_ES_Succeeded); |
124 | TDataStd_Tick::Set(L); |
125 | } |
126 | |
127 | }// while (More()) |
128 | |
129 | graph->setFinished(); |
6396eacb |
130 | } |