0024665: A sample for advanced function mechanism
[occt.git] / samples / qt / FuncDemo / src / FThread.cpp
1 #include "FThread.h"
2 #include "graphwidget.h"
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())
70             #ifdef __GNUC__
71                sleep(0.001);
72             #else
73                ::Sleep(100);
74             #endif
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();
130 }