Salome HOME
Moved some functionality to VTKViewer_Utilities.h
[modules/kernel.git] / src / Event / SALOME_Event.hxx
1 //  KERNEL SALOME_Event : Define event posting mechanism
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOME_Event.hxx
25 //  Author : Sergey ANIKIN
26 //  Module : KERNEL
27 //  $Header$
28
29
30 #ifndef SALOME_Event_HeaderFile
31 #define SALOME_Event_HeaderFile
32
33 #include <qevent.h>
34
35 #define SALOME_EVENT QEvent::Type( QEvent::User + 10000 )
36
37 class QSemaphore;
38
39 //===========================================================
40 /*!
41  *  Class: SALOME_Event
42  *  Description: 
43  *  This class encapsulates data and functionality required for 
44  *  posting component-specific events to perform arbitrary operations in main GUI thread. 
45  *  SALOME_Event objects can be posted by any thread belonging to the GUI process.
46  *
47  *  It is necessary to derive a custom event class from SALOME_Event and 
48  *  re-implement virtual Execute() method. This method should actually perform 
49  *  the desirable operation. To pass all the required data to Execute() and store a return value,
50  *  arbitrary data fields can be added to the custom event class. There is 
51  *  no need to protect such fields with a mutex, for only one thread working with
52  *  a SALOME_Event object is active at any moment.
53  *
54  *  Usage:
55  *  - create SALOME_Event. 
56  *    Components can derive their own event class from SALOME_Event
57  *    in order to pass custom data to the event handler.
58  *  - call process() method to post the event. After process() execution
59  *    it is possible to examine fields of your custom event object.
60  *  - perform delete operator on the event to wake up the desktop (you can also set <autoRelease>
61  *    parameter to TRUE to automatically wake up desktop after process()
62  * 
63  *  processed() method is used by the desktop to signal that event processing 
64  *  has been completed.
65  *  
66  *  Caveats: 
67  *    There is no.
68  */
69 //===========================================================
70
71
72 class SALOME_Event{
73 public:
74   SALOME_Event();
75   virtual ~SALOME_Event();
76
77   // To do real work
78   virtual void Execute() = 0;
79
80   static bool IsSessionThread();
81   void process();
82
83 protected:
84   void processed();
85   friend class QAD_Desktop;
86
87   static void GetSessionThread();
88   friend int main(int, char **);
89
90 private:
91   QSemaphore* mySemaphore;
92 };
93
94
95 // Template classes for member function
96 //-------------------------------------
97 template<class TObject, typename TRes>
98 class TMemFunEvent: public SALOME_Event{
99 public:
100   typedef TRes TResult;
101   TResult myResult;
102   typedef TResult (TObject::* TAction)();
103   TMemFunEvent(TObject* theObject, TAction theAction, 
104                TResult theResult = TResult()):
105     myObject(theObject),
106     myAction(theAction),
107     myResult(theResult)
108   {}
109   virtual void Execute(){
110     myResult = (myObject->*myAction)();
111   }
112 private:
113   TObject* myObject;
114   TAction myAction;
115 };
116
117
118 template<class TObject>
119 class TVoidMemFunEvent: public SALOME_Event{
120 public:
121   typedef void (TObject::* TAction)();
122   TVoidMemFunEvent(TObject* theObject, TAction theAction):
123     myObject(theObject),
124     myAction(theAction)
125   {}
126   virtual void Execute(){
127     (myObject->*myAction)();
128   }
129 private:
130   TObject* myObject;
131   TAction myAction;
132 };
133
134
135 // Template for member function with one argument
136 //-----------------------------------------------
137 template<class TObject, typename TRes, 
138          typename TArg, typename TStoreArg = TArg>
139 class TMemFun1ArgEvent: public SALOME_Event{
140 public:
141   typedef TRes TResult;
142   TResult myResult;
143   typedef TResult (TObject::* TAction)(TArg);
144   TMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg, 
145                    TResult theResult = TResult()):
146     myObject(theObject),
147     myAction(theAction),
148     myResult(theResult),
149     myArg(theArg)
150   {}
151   virtual void Execute(){
152     myResult = (myObject->*myAction)(myArg);
153   }
154 private:
155   TObject* myObject;
156   TAction myAction;
157   TStoreArg myArg;
158 };
159
160
161 template<class TObject, typename TArg, typename TStoreArg = TArg>
162 class TVoidMemFun1ArgEvent: public SALOME_Event{
163 public:
164   typedef void (TObject::* TAction)(TArg);
165   TVoidMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg):
166     myObject(theObject),
167     myAction(theAction),
168     myArg(theArg)
169   {}
170   virtual void Execute(){
171     (myObject->*myAction)(myArg);
172   }
173 private:
174   TObject* myObject;
175   TAction myAction;
176   TStoreArg myArg;
177 };
178
179
180 // Template for member function with one argument
181 //-----------------------------------------------
182 template<class TObject, typename TRes,
183          typename TArg, typename TArg1, 
184          typename TStoreArg = TArg, typename TStoreArg1 = TArg1>
185 class TMemFun2ArgEvent: public SALOME_Event{
186 public:
187   typedef TRes TResult;
188   TResult myResult;
189   typedef TResult (TObject::* TAction)(TArg,TArg1);
190   TMemFun2ArgEvent(TObject* theObject, TAction theAction, 
191                    TArg theArg, TArg1 theArg1,
192                    TResult theResult = TResult()):
193     myObject(theObject),
194     myAction(theAction),
195     myResult(theResult),
196     myArg(theArg),
197     myArg1(theArg1)
198   {}
199   virtual void Execute(){
200     myResult = (myObject->*myAction)(myArg,myArg1);
201   }
202 private:
203   TObject* myObject;
204   TAction myAction;
205   TStoreArg myArg;
206   TStoreArg1 myArg1;
207 };
208
209
210 template<class TObject, typename TArg, typename TArg1, 
211          typename TStoreArg = TArg, typename TStoreArg1 = TArg1>
212 class TVoidMemFun2ArgEvent: public SALOME_Event{
213 public:
214   typedef void (TObject::* TAction)(TArg,TArg1);
215   TVoidMemFun2ArgEvent(TObject* theObject, TAction theAction, TArg theArg, TArg1 theArg1):
216     myObject(theObject),
217     myAction(theAction),
218     myArg(theArg),
219     myArg1(theArg1)
220   {}
221   virtual void Execute(){
222     (myObject->*myAction)(myArg,myArg1);
223   }
224 private:
225   TObject* myObject;
226   TAction myAction;
227   TStoreArg myArg;
228   TStoreArg1 myArg1;
229 };
230
231
232 // Template function for processing events with result returing
233 template<class TEvent> inline typename TEvent::TResult ProcessEvent(TEvent* theEvent){
234   typename TEvent::TResult aResult;
235   if(SALOME_Event::IsSessionThread()){
236     theEvent->Execute();
237     aResult = theEvent->myResult;
238   }else{
239     theEvent->process();
240     aResult = theEvent->myResult;
241   }
242   delete theEvent;
243   return aResult;
244 }
245
246
247 // Template function for processing events without result
248 inline void ProcessVoidEvent(SALOME_Event* theEvent){
249   if(SALOME_Event::IsSessionThread()){
250     theEvent->Execute();
251   }else{
252     theEvent->process();
253   }
254   delete theEvent;
255 }
256
257
258 #endif