6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
42 #include "ObjectList.h"
43 #include "FunctionObject.h"
48 class MessengerAutoLocker
{
49 // move this into AutoLock.h
51 MessengerAutoLocker(BMessenger
* messenger
)
52 : fMessenger(messenger
),
53 fHasLock(messenger
->LockTarget())
56 ~MessengerAutoLocker()
61 bool operator!() const
75 fMessenger
->Target(&looper
);
83 BMessenger
* fMessenger
;
89 // this should only be used as a base class,
90 // subclass needs to add proper locking mechanism
92 SimpleThread(int32 priority
= B_LOW_PRIORITY
, const char* name
= 0);
93 virtual ~SimpleThread();
98 static status_t
RunBinder(void*);
99 virtual void Run() = 0;
102 thread_id fScanThread
;
108 class Thread
: private SimpleThread
{
110 static void Launch(FunctionObject
* functor
,
111 int32 priority
= B_LOW_PRIORITY
, const char* name
= 0);
114 Thread(FunctionObject
*, int32 priority
, const char* name
);
118 FunctionObject
* fFunctor
;
122 class ThreadSequence
: private SimpleThread
{
124 static void Launch(BObjectList
<FunctionObject
>*, bool async
= true,
125 int32 priority
= B_LOW_PRIORITY
);
128 ThreadSequence(BObjectList
<FunctionObject
>*, int32 priority
);
132 static void Run(BObjectList
<FunctionObject
>*list
);
134 BObjectList
<FunctionObject
>* fFunctorList
;
138 // would use SingleParamFunctionObjectWithResult, except mwcc won't handle this
139 template <class Param1
>
140 class SingleParamFunctionObjectWorkaround
: public
141 FunctionObjectWithResult
<status_t
> {
143 SingleParamFunctionObjectWorkaround(
144 status_t (*function
)(Param1
), Param1 param1
)
145 : fFunction(function
),
150 virtual void operator()()
151 { (fFunction
)(fParam1
); }
153 virtual ulong
Size() const { return sizeof(*this); }
156 status_t (*fFunction
)(Param1
);
162 class SimpleMemberFunctionObjectWorkaround
: public
163 FunctionObjectWithResult
<status_t
> {
165 SimpleMemberFunctionObjectWorkaround(status_t (T::*function
)(), T
* onThis
)
166 : fFunction(function
),
171 virtual void operator()()
172 { (fOnThis
->*fFunction
)(); }
174 virtual ulong
Size() const { return sizeof(*this); }
177 status_t (T::*fFunction
)();
182 template <class Param1
, class Param2
>
183 class TwoParamFunctionObjectWorkaround
: public
184 FunctionObjectWithResult
<status_t
> {
186 TwoParamFunctionObjectWorkaround(status_t (*callThis
)(Param1
, Param2
),
187 Param1 param1
, Param2 param2
)
188 : function(callThis
),
194 virtual void operator()()
195 { (function
)(fParam1
, fParam2
); }
197 virtual uint32
Size() const { return sizeof(*this); }
200 status_t (*function
)(Param1
, Param2
);
206 template <class Param1
, class Param2
, class Param3
>
207 class ThreeParamFunctionObjectWorkaround
: public
208 FunctionObjectWithResult
<status_t
> {
210 ThreeParamFunctionObjectWorkaround(
211 status_t (*callThis
)(Param1
, Param2
, Param3
),
212 Param1 param1
, Param2 param2
, Param3 param3
)
213 : function(callThis
),
220 virtual void operator()()
221 { (function
)(fParam1
, fParam2
, fParam3
); }
223 virtual uint32
Size() const { return sizeof(*this); }
226 status_t (*function
)(Param1
, Param2
, Param3
);
233 template <class Param1
, class Param2
, class Param3
, class Param4
>
234 class FourParamFunctionObjectWorkaround
: public
235 FunctionObjectWithResult
<status_t
> {
237 FourParamFunctionObjectWorkaround(
238 status_t (*callThis
)(Param1
, Param2
, Param3
, Param4
),
239 Param1 param1
, Param2 param2
, Param3 param3
, Param4 param4
)
240 : function(callThis
),
248 virtual void operator()()
249 { (function
)(fParam1
, fParam2
, fParam3
, fParam4
); }
251 virtual uint32
Size() const { return sizeof(*this); }
254 status_t (*function
)(Param1
, Param2
, Param3
, Param4
);
262 template<class Param1
>
264 LaunchInNewThread(const char* name
, int32 priority
, status_t (*func
)(Param1
),
267 Thread::Launch(new SingleParamFunctionObjectWorkaround
<Param1
>(func
, p1
),
274 LaunchInNewThread(const char* name
, int32 priority
, status_t (T::*function
)(),
277 Thread::Launch(new SimpleMemberFunctionObjectWorkaround
<T
>(function
,
278 onThis
), priority
, name
);
282 template<class Param1
, class Param2
>
284 LaunchInNewThread(const char* name
, int32 priority
,
285 status_t (*func
)(Param1
, Param2
),
286 Param1 p1
, Param2 p2
)
289 TwoParamFunctionObjectWorkaround
<Param1
, Param2
>(func
, p1
, p2
),
294 template<class Param1
, class Param2
, class Param3
>
296 LaunchInNewThread(const char* name
, int32 priority
,
297 status_t (*func
)(Param1
, Param2
, Param3
),
298 Param1 p1
, Param2 p2
, Param3 p3
)
300 Thread::Launch(new ThreeParamFunctionObjectWorkaround
<Param1
, Param2
,
301 Param3
>(func
, p1
, p2
, p3
), priority
, name
);
305 template<class Param1
, class Param2
, class Param3
, class Param4
>
307 LaunchInNewThread(const char* name
, int32 priority
,
308 status_t (*func
)(Param1
, Param2
, Param3
, Param4
),
309 Param1 p1
, Param2 p2
, Param3 p3
, Param4 p4
)
311 Thread::Launch(new FourParamFunctionObjectWorkaround
<Param1
, Param2
,
312 Param3
, Param4
>(func
, p1
, p2
, p3
, p4
), priority
, name
);
317 class MouseDownThread
{
319 static void TrackMouse(View
* view
, void (View::*)(BPoint
),
320 void (View::*)(BPoint
, uint32
) = 0,
321 bigtime_t pressingPeriod
= 100000);
324 MouseDownThread(View
* view
, void (View::*)(BPoint
),
325 void (View::*)(BPoint
, uint32
), bigtime_t pressingPeriod
);
327 virtual ~MouseDownThread();
330 virtual void Track();
332 static status_t
TrackBinder(void*);
336 void (View::*fDonePressing
)(BPoint
);
337 void (View::*fPressing
)(BPoint
, uint32
);
338 bigtime_t fPressingPeriod
;
339 volatile thread_id fThreadID
;
345 MouseDownThread
<View
>::TrackMouse(View
* view
,
346 void(View::*donePressing
)(BPoint
),
347 void(View::*pressing
)(BPoint
, uint32
), bigtime_t pressingPeriod
)
349 (new MouseDownThread(view
, donePressing
, pressing
, pressingPeriod
))->Go();
354 MouseDownThread
<View
>::MouseDownThread(View
* view
,
355 void (View::*donePressing
)(BPoint
),
356 void (View::*pressing
)(BPoint
, uint32
), bigtime_t pressingPeriod
)
357 : fOwner(view
, view
->Window()),
358 fDonePressing(donePressing
),
360 fPressingPeriod(pressingPeriod
)
366 MouseDownThread
<View
>::~MouseDownThread()
373 MouseDownThread
<View
>::Go()
375 fThreadID
= spawn_thread(&MouseDownThread::TrackBinder
,
376 "MouseTrackingThread", B_NORMAL_PRIORITY
, this);
378 if (fThreadID
<= 0 || resume_thread(fThreadID
) != B_OK
)
379 // didn't start, don't leak self
386 MouseDownThread
<View
>::TrackBinder(void* castToThis
)
388 MouseDownThread
* self
= static_cast<MouseDownThread
*>(castToThis
);
390 // dead at this point
397 MouseDownThread
<View
>::Track()
400 MessengerAutoLocker
lock(&fOwner
);
405 View
* view
= dynamic_cast<View
*>(fOwner
.Target(&looper
));
411 view
->GetMouse(&location
, &buttons
, false);
413 (view
->*fDonePressing
)(location
);
417 (view
->*fPressing
)(location
, buttons
);
420 snooze(fPressingPeriod
);
427 } // namespace BPrivate
429 using namespace BPrivate
;