Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.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  *  \class SALOME_Event
41  *  Description: 
42  *  This class encapsulates data and functionality required for 
43  *  posting component-specific events to perform arbitrary operations in main GUI thread. 
44  *  SALOME_Event objects can be posted by any thread belonging to the GUI process.
45  *
46  *  It is necessary to derive a custom event class from SALOME_Event and 
47  *  re-implement virtual Execute() method. This method should actually perform 
48  *  the desirable operation. To pass all the required data to Execute() and store a return value,
49  *  arbitrary data fields can be added to the custom event class. There is 
50  *  no need to protect such fields with a mutex, for only one thread working with
51  *  a SALOME_Event object is active at any moment.
52  *
53  *  Usage:
54  *  - create SALOME_Event. 
55  *    Components can derive their own event class from SALOME_Event
56  *    in order to pass custom data to the event handler.
57  *  - call process() method to post the event. After process() execution
58  *    it is possible to examine fields of your custom event object.
59  *  - perform delete operator on the event to wake up the desktop (you can also set <autoRelease>
60  *    parameter to TRUE to automatically wake up desktop after process()
61  * 
62  *  processed() method is used by the desktop to signal that event processing 
63  *  has been completed.
64  *  
65  *  Caveats: 
66  *    There is no.
67  */
68
69 #include <Event.h>
70
71 class EVENT_EXPORT SALOME_Event{
72 public:
73   SALOME_Event();
74   virtual ~SALOME_Event();
75
76   // To do real work
77   virtual void Execute() = 0;
78
79   static bool IsSessionThread();
80   void process();
81
82 protected:
83   void processed();
84   friend class SalomeApp_EventFilter;
85
86   static void GetSessionThread();
87   friend int main(int, char **);
88
89 private:
90   QSemaphore* mySemaphore;
91 };
92
93
94 /*!
95   \class TMemFunEvent
96   \brief Template class for member function
97 */
98 template<class TObject, typename TRes> class EVENT_EXPORT 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 /*!
119   \class TVoidMemFunEvent
120   \brief Template class for member function
121 */
122 template<class TObject> class EVENT_EXPORT TVoidMemFunEvent: public SALOME_Event{
123 public:
124   typedef void (TObject::* TAction)();
125   TVoidMemFunEvent(TObject* theObject, TAction theAction):
126     myObject(theObject),
127     myAction(theAction)
128   {}
129   virtual void Execute(){
130     (myObject->*myAction)();
131   }
132 private:
133   TObject* myObject;
134   TAction myAction;
135 };
136
137
138 /*!
139   \class TMemFun1ArgEvent
140   \brief Template for member function with one argument
141 */
142 template<class TObject, typename TRes, typename TArg, typename TStoreArg = TArg> class EVENT_EXPORT TMemFun1ArgEvent:
143 public SALOME_Event{
144 public:
145   typedef TRes TResult;
146   TResult myResult;
147   typedef TResult (TObject::* TAction)(TArg);
148   TMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg, 
149                    TResult theResult = TResult()):
150     myObject(theObject),
151     myAction(theAction),
152     myResult(theResult),
153     myArg(theArg)
154   {}
155   virtual void Execute(){
156     myResult = (myObject->*myAction)(myArg);
157   }
158 private:
159   TObject* myObject;
160   TAction myAction;
161   TStoreArg myArg;
162 };
163
164
165 /*!
166   \class TVoidMemFun1ArgEvent
167   \brief Template for member function with one argument
168 */
169 template<class TObject, typename TArg, typename TStoreArg = TArg> class EVENT_EXPORT TVoidMemFun1ArgEvent: public SALOME_Event{
170 public:
171   typedef void (TObject::* TAction)(TArg);
172   TVoidMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg):
173     myObject(theObject),
174     myAction(theAction),
175     myArg(theArg)
176   {}
177   virtual void Execute(){
178     (myObject->*myAction)(myArg);
179   }
180 private:
181   TObject* myObject;
182   TAction myAction;
183   TStoreArg myArg;
184 };
185
186
187 /*!
188   \class TMemFun2ArgEvent
189   \brief Template for member function with two arguments
190 */
191 template<class TObject, typename TRes, typename TArg, typename TArg1, typename TStoreArg = TArg, typename TStoreArg1 = TArg1> class
192 EVENT_EXPORT TMemFun2ArgEvent: public SALOME_Event{
193 public:
194   typedef TRes TResult;
195   TResult myResult;
196   typedef TResult (TObject::* TAction)(TArg,TArg1);
197   TMemFun2ArgEvent(TObject* theObject, TAction theAction, 
198                    TArg theArg, TArg1 theArg1,
199                    TResult theResult = TResult()):
200     myObject(theObject),
201     myAction(theAction),
202     myResult(theResult),
203     myArg(theArg),
204     myArg1(theArg1)
205   {}
206   virtual void Execute(){
207     myResult = (myObject->*myAction)(myArg,myArg1);
208   }
209 private:
210   TObject* myObject;
211   TAction myAction;
212   TStoreArg myArg;
213   TStoreArg1 myArg1;
214 };
215
216
217 /*!
218   \class TVoidMemFun2ArgEvent
219   \brief Template for member function with two arguments
220 */
221 template<class TObject, typename TArg, typename TArg1, typename TStoreArg = TArg, typename TStoreArg1 = TArg1> class
222 EVENT_EXPORT TVoidMemFun2ArgEvent: public SALOME_Event{
223 public:
224   typedef void (TObject::* TAction)(TArg,TArg1);
225   TVoidMemFun2ArgEvent(TObject* theObject, TAction theAction, TArg theArg, TArg1 theArg1):
226     myObject(theObject),
227     myAction(theAction),
228     myArg(theArg),
229     myArg1(theArg1)
230   {}
231   virtual void Execute(){
232     (myObject->*myAction)(myArg,myArg1);
233   }
234 private:
235   TObject* myObject;
236   TAction myAction;
237   TStoreArg myArg;
238   TStoreArg1 myArg1;
239 };
240
241
242 /*!
243   \fn ProcessEvent
244   \brief Template function for processing events with result returing
245 */
246 template<class TEvent> inline typename TEvent::TResult ProcessEvent(TEvent* theEvent){
247   typename TEvent::TResult aResult;
248   if(SALOME_Event::IsSessionThread()){
249     theEvent->Execute();
250     aResult = theEvent->myResult;
251   }else{
252     theEvent->process();
253     aResult = theEvent->myResult;
254   }
255   delete theEvent;
256   return aResult;
257 }
258
259
260 /*!
261   \fn ProcessEvent
262   \brief Template function for processing events without result
263 */
264 inline void ProcessVoidEvent(SALOME_Event* theEvent){
265   if(SALOME_Event::IsSessionThread()){
266     theEvent->Execute();
267   }else{
268     theEvent->process();
269   }
270   delete theEvent;
271 }
272
273
274 #endif