Move Thread classes from Tracker to shared
So that they may be utilized outside of Tracker
This commit is contained in:
@@ -0,0 +1,573 @@
|
||||
/*
|
||||
Open Tracker License
|
||||
|
||||
Terms and Conditions
|
||||
|
||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice applies to all licensees
|
||||
and shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
this Software without prior written authorization from Be Incorporated.
|
||||
|
||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
||||
of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef __FUNCTION_OBJECT__
|
||||
#define __FUNCTION_OBJECT__
|
||||
|
||||
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <MessageFilter.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Node.h>
|
||||
|
||||
|
||||
// parameter binders serve to store a copy of a struct and
|
||||
// pass it in and out by pointers, allowing struct parameters to share
|
||||
// the same syntax as scalar ones
|
||||
|
||||
// You will mostly want to use the NewFunctionObject... convenience
|
||||
// factories
|
||||
//
|
||||
|
||||
// add more function objects and specialized binders as needed
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
template<class P>
|
||||
class ParameterBinder {
|
||||
// primitive default binder for scalars
|
||||
public:
|
||||
ParameterBinder() {}
|
||||
ParameterBinder(P p)
|
||||
: p(p)
|
||||
{}
|
||||
|
||||
P Pass() const
|
||||
{ return p; }
|
||||
private:
|
||||
P p;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
class ParameterBinder<const BEntry*> {
|
||||
public:
|
||||
ParameterBinder() {}
|
||||
ParameterBinder(const BEntry* p)
|
||||
: p(*p)
|
||||
{}
|
||||
|
||||
ParameterBinder &operator=(const BEntry* newp)
|
||||
{ p = *newp; return *this; }
|
||||
|
||||
const BEntry* Pass() const
|
||||
{ return &p; }
|
||||
private:
|
||||
BEntry p;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
class ParameterBinder<const entry_ref*> {
|
||||
public:
|
||||
ParameterBinder() {}
|
||||
ParameterBinder(const entry_ref* p)
|
||||
{
|
||||
if (p)
|
||||
this->p = *p;
|
||||
}
|
||||
|
||||
ParameterBinder &operator=(const entry_ref* newp)
|
||||
{ p = *newp; return *this; }
|
||||
|
||||
const entry_ref* Pass() const
|
||||
{ return &p; }
|
||||
private:
|
||||
entry_ref p;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
class ParameterBinder<const node_ref*> {
|
||||
public:
|
||||
ParameterBinder() {}
|
||||
ParameterBinder(const node_ref* p)
|
||||
: p(*p)
|
||||
{}
|
||||
|
||||
ParameterBinder &operator=(const node_ref* newp)
|
||||
{ p = *newp; return *this; }
|
||||
|
||||
const node_ref* Pass() const
|
||||
{ return &p; }
|
||||
private:
|
||||
node_ref p;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
class ParameterBinder<const BMessage*> {
|
||||
public:
|
||||
ParameterBinder() {}
|
||||
ParameterBinder(const BMessage* p)
|
||||
: p(p ? new BMessage(*p) : NULL)
|
||||
{}
|
||||
|
||||
~ParameterBinder()
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
ParameterBinder &operator=(const BMessage* newp)
|
||||
{
|
||||
delete p;
|
||||
p = (newp ? new BMessage(*newp) : NULL);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const BMessage* Pass() const
|
||||
{ return p; }
|
||||
|
||||
private:
|
||||
BMessage* p;
|
||||
};
|
||||
|
||||
|
||||
class FunctionObject {
|
||||
public:
|
||||
virtual void operator()() = 0;
|
||||
virtual ~FunctionObject() {}
|
||||
};
|
||||
|
||||
|
||||
template<class R>
|
||||
class FunctionObjectWithResult : public FunctionObject {
|
||||
public:
|
||||
const R &Result() const { return result; }
|
||||
|
||||
protected:
|
||||
R result;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1>
|
||||
class SingleParamFunctionObject : public FunctionObject {
|
||||
public:
|
||||
SingleParamFunctionObject(void (*callThis)(Param1),
|
||||
Param1 p1)
|
||||
: function(callThis),
|
||||
p1(p1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()() { (function)(p1.Pass()); }
|
||||
|
||||
private:
|
||||
void (*function)(Param1);
|
||||
ParameterBinder<Param1> p1;
|
||||
};
|
||||
|
||||
|
||||
template <class Result, class Param1>
|
||||
class SingleParamFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<Result> {
|
||||
public:
|
||||
SingleParamFunctionObjectWithResult(Result (*function)(Param1), Param1 p1)
|
||||
: function(function),
|
||||
p1(p1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<Result>::result = (function)(p1.Pass()); }
|
||||
|
||||
private:
|
||||
Result (*function)(Param1);
|
||||
ParameterBinder<Param1> p1;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2>
|
||||
class TwoParamFunctionObject : public FunctionObject {
|
||||
public:
|
||||
TwoParamFunctionObject(void (*callThis)(Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
: function(callThis),
|
||||
p1(p1),
|
||||
p2(p2)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()() { (function)(p1.Pass(), p2.Pass()); }
|
||||
|
||||
private:
|
||||
void (*function)(Param1, Param2);
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2, class Param3>
|
||||
class ThreeParamFunctionObject : public FunctionObject {
|
||||
public:
|
||||
ThreeParamFunctionObject(void (*callThis)(Param1, Param2, Param3),
|
||||
Param1 p1, Param2 p2, Param3 p3)
|
||||
: function(callThis),
|
||||
p1(p1),
|
||||
p2(p2),
|
||||
p3(p3)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()() { (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
|
||||
|
||||
private:
|
||||
void (*function)(Param1, Param2, Param3);
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
ParameterBinder<Param3> p3;
|
||||
};
|
||||
|
||||
|
||||
template <class Result, class Param1, class Param2, class Param3>
|
||||
class ThreeParamFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<Result> {
|
||||
public:
|
||||
ThreeParamFunctionObjectWithResult(
|
||||
Result (*callThis)(Param1, Param2, Param3),
|
||||
Param1 p1, Param2 p2, Param3 p3)
|
||||
: function(callThis),
|
||||
p1(p1),
|
||||
p2(p2),
|
||||
p3(p3)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<Result>::result
|
||||
= (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
|
||||
|
||||
private:
|
||||
Result (*function)(Param1, Param2, Param3);
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
ParameterBinder<Param3> p3;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2, class Param3, class Param4>
|
||||
class FourParamFunctionObject : public FunctionObject {
|
||||
public:
|
||||
FourParamFunctionObject(void (*callThis)(Param1, Param2, Param3, Param4),
|
||||
Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||
: function(callThis),
|
||||
p1(p1),
|
||||
p2(p2),
|
||||
p3(p3),
|
||||
p4(p4)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
|
||||
|
||||
private:
|
||||
void (*function)(Param1, Param2, Param3, Param4);
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
ParameterBinder<Param3> p3;
|
||||
ParameterBinder<Param4> p4;
|
||||
};
|
||||
|
||||
|
||||
template <class Result, class Param1, class Param2, class Param3,
|
||||
class Param4>
|
||||
class FourParamFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<Result> {
|
||||
public:
|
||||
FourParamFunctionObjectWithResult(
|
||||
Result (*callThis)(Param1, Param2, Param3, Param4),
|
||||
Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||
: function(callThis),
|
||||
p1(p1),
|
||||
p2(p2),
|
||||
p3(p3),
|
||||
p4(p4)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<Result>::result
|
||||
= (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
|
||||
|
||||
private:
|
||||
Result (*function)(Param1, Param2, Param3, Param4);
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
ParameterBinder<Param3> p3;
|
||||
ParameterBinder<Param4> p4;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class PlainMemberFunctionObject : public FunctionObject {
|
||||
public:
|
||||
PlainMemberFunctionObject(void (T::*function)(), T* onThis)
|
||||
: function(function),
|
||||
target(onThis)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (target->*function)(); }
|
||||
|
||||
private:
|
||||
void (T::*function)();
|
||||
T* target;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class PlainLockingMemberFunctionObject : public FunctionObject {
|
||||
public:
|
||||
PlainLockingMemberFunctionObject(void (T::*function)(), T* target)
|
||||
: function(function),
|
||||
messenger(target)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{
|
||||
T* target = dynamic_cast<T*>(messenger.Target(NULL));
|
||||
if (!target || !messenger.LockTarget())
|
||||
return;
|
||||
(target->*function)();
|
||||
target->Looper()->Unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
void (T::*function)();
|
||||
BMessenger messenger;
|
||||
};
|
||||
|
||||
|
||||
template<class T, class R>
|
||||
class PlainMemberFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<R> {
|
||||
public:
|
||||
PlainMemberFunctionObjectWithResult(R (T::*function)(), T* onThis)
|
||||
: function(function),
|
||||
target(onThis)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<R>::result = (target->*function)(); }
|
||||
|
||||
|
||||
private:
|
||||
R (T::*function)();
|
||||
T* target;
|
||||
};
|
||||
|
||||
|
||||
template<class T, class Param1>
|
||||
class SingleParamMemberFunctionObject : public FunctionObject {
|
||||
public:
|
||||
SingleParamMemberFunctionObject(void (T::*function)(Param1),
|
||||
T* onThis, Param1 p1)
|
||||
: function(function),
|
||||
target(onThis),
|
||||
p1(p1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (target->*function)(p1.Pass()); }
|
||||
|
||||
private:
|
||||
void (T::*function)(Param1);
|
||||
T* target;
|
||||
ParameterBinder<Param1> p1;
|
||||
};
|
||||
|
||||
|
||||
template<class T, class Param1, class Param2>
|
||||
class TwoParamMemberFunctionObject : public FunctionObject {
|
||||
public:
|
||||
TwoParamMemberFunctionObject(void (T::*function)(Param1, Param2),
|
||||
T* onThis, Param1 p1, Param2 p2)
|
||||
: function(function),
|
||||
target(onThis),
|
||||
p1(p1),
|
||||
p2(p2)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (target->*function)(p1.Pass(), p2.Pass()); }
|
||||
|
||||
|
||||
protected:
|
||||
void (T::*function)(Param1, Param2);
|
||||
T* target;
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
};
|
||||
|
||||
|
||||
template<class T, class R, class Param1>
|
||||
class SingleParamMemberFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<R> {
|
||||
public:
|
||||
SingleParamMemberFunctionObjectWithResult(R (T::*function)(Param1),
|
||||
T* onThis, Param1 p1)
|
||||
: function(function),
|
||||
target(onThis),
|
||||
p1(p1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<R>::result
|
||||
= (target->*function)(p1.Pass()); }
|
||||
|
||||
protected:
|
||||
R (T::*function)(Param1);
|
||||
T* target;
|
||||
ParameterBinder<Param1> p1;
|
||||
};
|
||||
|
||||
|
||||
template<class T, class R, class Param1, class Param2>
|
||||
class TwoParamMemberFunctionObjectWithResult : public
|
||||
FunctionObjectWithResult<R> {
|
||||
public:
|
||||
TwoParamMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2),
|
||||
T* onThis, Param1 p1, Param2 p2)
|
||||
: function(function),
|
||||
target(onThis),
|
||||
p1(p1),
|
||||
p2(p2)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ FunctionObjectWithResult<R>::result
|
||||
= (target->*function)(p1.Pass(), p2.Pass()); }
|
||||
|
||||
protected:
|
||||
R (T::*function)(Param1, Param2);
|
||||
T* target;
|
||||
ParameterBinder<Param1> p1;
|
||||
ParameterBinder<Param2> p2;
|
||||
};
|
||||
|
||||
|
||||
// convenience factory functions
|
||||
// NewFunctionObject
|
||||
// NewMemberFunctionObject
|
||||
// NewMemberFunctionObjectWithResult
|
||||
// NewLockingMemberFunctionObject
|
||||
//
|
||||
// ... add the missing ones as needed
|
||||
|
||||
template<class Param1>
|
||||
SingleParamFunctionObject<Param1>*
|
||||
NewFunctionObject(void (*function)(Param1), Param1 p1)
|
||||
{
|
||||
return new SingleParamFunctionObject<Param1>(function, p1);
|
||||
}
|
||||
|
||||
|
||||
template<class Param1, class Param2>
|
||||
TwoParamFunctionObject<Param1, Param2>*
|
||||
NewFunctionObject(void (*function)(Param1, Param2), Param1 p1, Param2 p2)
|
||||
{
|
||||
return new TwoParamFunctionObject<Param1, Param2>(function, p1, p2);
|
||||
}
|
||||
|
||||
|
||||
template<class Param1, class Param2, class Param3>
|
||||
ThreeParamFunctionObject<Param1, Param2, Param3>*
|
||||
NewFunctionObject(void (*function)(Param1, Param2, Param3),
|
||||
Param1 p1, Param2 p2, Param3 p3)
|
||||
{
|
||||
return new ThreeParamFunctionObject<Param1, Param2, Param3>
|
||||
(function, p1, p2, p3);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
PlainMemberFunctionObject<T>*
|
||||
NewMemberFunctionObject(void (T::*function)(), T* onThis)
|
||||
{
|
||||
return new PlainMemberFunctionObject<T>(function, onThis);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Param1>
|
||||
SingleParamMemberFunctionObject<T, Param1>*
|
||||
NewMemberFunctionObject(void (T::*function)(Param1), T* onThis, Param1 p1)
|
||||
{
|
||||
return new SingleParamMemberFunctionObject<T, Param1>
|
||||
(function, onThis, p1);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Param1, class Param2>
|
||||
TwoParamMemberFunctionObject<T, Param1, Param2>*
|
||||
NewMemberFunctionObject(void (T::*function)(Param1, Param2), T* onThis,
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
return new TwoParamMemberFunctionObject<T, Param1, Param2>
|
||||
(function, onThis, p1, p2);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class R, class Param1, class Param2>
|
||||
TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>*
|
||||
NewMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2),
|
||||
T* onThis, Param1 p1, Param2 p2)
|
||||
{
|
||||
return new TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>
|
||||
(function, onThis, p1, p2);
|
||||
}
|
||||
|
||||
|
||||
template<class HandlerOrSubclass>
|
||||
PlainLockingMemberFunctionObject<HandlerOrSubclass>*
|
||||
NewLockingMemberFunctionObject(void (HandlerOrSubclass::*function)(),
|
||||
HandlerOrSubclass* onThis)
|
||||
{
|
||||
return new PlainLockingMemberFunctionObject<HandlerOrSubclass>
|
||||
(function, onThis);
|
||||
}
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using namespace BPrivate;
|
||||
|
||||
#endif // __FUNCTION_OBJECT__
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
Open Tracker License
|
||||
|
||||
Terms and Conditions
|
||||
|
||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice applies to all licensees
|
||||
and shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
this Software without prior written authorization from Be Incorporated.
|
||||
|
||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
||||
of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef __THREAD__
|
||||
#define __THREAD__
|
||||
|
||||
|
||||
#include <Debug.h>
|
||||
#include <Looper.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "ObjectList.h"
|
||||
#include "FunctionObject.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class MessengerAutoLocker {
|
||||
// move this into AutoLock.h
|
||||
public:
|
||||
MessengerAutoLocker(BMessenger* messenger)
|
||||
: fMessenger(messenger),
|
||||
fHasLock(messenger->LockTarget())
|
||||
{}
|
||||
|
||||
~MessengerAutoLocker()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !fHasLock;
|
||||
}
|
||||
|
||||
bool IsLocked() const
|
||||
{
|
||||
return fHasLock;
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if (fHasLock) {
|
||||
BLooper* looper;
|
||||
fMessenger->Target(&looper);
|
||||
if (looper)
|
||||
looper->Unlock();
|
||||
fHasLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BMessenger* fMessenger;
|
||||
bool fHasLock;
|
||||
};
|
||||
|
||||
|
||||
class SimpleThread {
|
||||
// this should only be used as a base class,
|
||||
// subclass needs to add proper locking mechanism
|
||||
public:
|
||||
SimpleThread(int32 priority = B_LOW_PRIORITY, const char* name = 0);
|
||||
virtual ~SimpleThread();
|
||||
|
||||
void Go();
|
||||
|
||||
private:
|
||||
static status_t RunBinder(void*);
|
||||
virtual void Run() = 0;
|
||||
|
||||
protected:
|
||||
thread_id fScanThread;
|
||||
int32 fPriority;
|
||||
const char* fName;
|
||||
};
|
||||
|
||||
|
||||
class Thread : private SimpleThread {
|
||||
public:
|
||||
static void Launch(FunctionObject* functor,
|
||||
int32 priority = B_LOW_PRIORITY, const char* name = 0);
|
||||
|
||||
private:
|
||||
Thread(FunctionObject*, int32 priority, const char* name);
|
||||
~Thread();
|
||||
virtual void Run();
|
||||
|
||||
FunctionObject* fFunctor;
|
||||
};
|
||||
|
||||
|
||||
class ThreadSequence : private SimpleThread {
|
||||
public:
|
||||
static void Launch(BObjectList<FunctionObject>*, bool async = true,
|
||||
int32 priority = B_LOW_PRIORITY);
|
||||
|
||||
private:
|
||||
ThreadSequence(BObjectList<FunctionObject>*, int32 priority);
|
||||
~ThreadSequence();
|
||||
|
||||
virtual void Run();
|
||||
static void Run(BObjectList<FunctionObject>*list);
|
||||
|
||||
BObjectList<FunctionObject>* fFunctorList;
|
||||
};
|
||||
|
||||
|
||||
// would use SingleParamFunctionObjectWithResult, except mwcc won't handle this
|
||||
template <class Param1>
|
||||
class SingleParamFunctionObjectWorkaround : public
|
||||
FunctionObjectWithResult<status_t> {
|
||||
public:
|
||||
SingleParamFunctionObjectWorkaround(
|
||||
status_t (*function)(Param1), Param1 param1)
|
||||
: fFunction(function),
|
||||
fParam1(param1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (fFunction)(fParam1); }
|
||||
|
||||
virtual ulong Size() const { return sizeof(*this); }
|
||||
|
||||
private:
|
||||
status_t (*fFunction)(Param1);
|
||||
Param1 fParam1;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class SimpleMemberFunctionObjectWorkaround : public
|
||||
FunctionObjectWithResult<status_t> {
|
||||
public:
|
||||
SimpleMemberFunctionObjectWorkaround(status_t (T::*function)(), T* onThis)
|
||||
: fFunction(function),
|
||||
fOnThis(onThis)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (fOnThis->*fFunction)(); }
|
||||
|
||||
virtual ulong Size() const { return sizeof(*this); }
|
||||
|
||||
private:
|
||||
status_t (T::*fFunction)();
|
||||
T fOnThis;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2>
|
||||
class TwoParamFunctionObjectWorkaround : public
|
||||
FunctionObjectWithResult<status_t> {
|
||||
public:
|
||||
TwoParamFunctionObjectWorkaround(status_t (*callThis)(Param1, Param2),
|
||||
Param1 param1, Param2 param2)
|
||||
: function(callThis),
|
||||
fParam1(param1),
|
||||
fParam2(param2)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (function)(fParam1, fParam2); }
|
||||
|
||||
virtual uint32 Size() const { return sizeof(*this); }
|
||||
|
||||
private:
|
||||
status_t (*function)(Param1, Param2);
|
||||
Param1 fParam1;
|
||||
Param2 fParam2;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2, class Param3>
|
||||
class ThreeParamFunctionObjectWorkaround : public
|
||||
FunctionObjectWithResult<status_t> {
|
||||
public:
|
||||
ThreeParamFunctionObjectWorkaround(
|
||||
status_t (*callThis)(Param1, Param2, Param3),
|
||||
Param1 param1, Param2 param2, Param3 param3)
|
||||
: function(callThis),
|
||||
fParam1(param1),
|
||||
fParam2(param2),
|
||||
fParam3(param3)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (function)(fParam1, fParam2, fParam3); }
|
||||
|
||||
virtual uint32 Size() const { return sizeof(*this); }
|
||||
|
||||
private:
|
||||
status_t (*function)(Param1, Param2, Param3);
|
||||
Param1 fParam1;
|
||||
Param2 fParam2;
|
||||
Param3 fParam3;
|
||||
};
|
||||
|
||||
|
||||
template <class Param1, class Param2, class Param3, class Param4>
|
||||
class FourParamFunctionObjectWorkaround : public
|
||||
FunctionObjectWithResult<status_t> {
|
||||
public:
|
||||
FourParamFunctionObjectWorkaround(
|
||||
status_t (*callThis)(Param1, Param2, Param3, Param4),
|
||||
Param1 param1, Param2 param2, Param3 param3, Param4 param4)
|
||||
: function(callThis),
|
||||
fParam1(param1),
|
||||
fParam2(param2),
|
||||
fParam3(param3),
|
||||
fParam4(param4)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()()
|
||||
{ (function)(fParam1, fParam2, fParam3, fParam4); }
|
||||
|
||||
virtual uint32 Size() const { return sizeof(*this); }
|
||||
|
||||
private:
|
||||
status_t (*function)(Param1, Param2, Param3, Param4);
|
||||
Param1 fParam1;
|
||||
Param2 fParam2;
|
||||
Param3 fParam3;
|
||||
Param4 fParam4;
|
||||
};
|
||||
|
||||
|
||||
template<class Param1>
|
||||
void
|
||||
LaunchInNewThread(const char* name, int32 priority, status_t (*func)(Param1),
|
||||
Param1 p1)
|
||||
{
|
||||
Thread::Launch(new SingleParamFunctionObjectWorkaround<Param1>(func, p1),
|
||||
priority, name);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void
|
||||
LaunchInNewThread(const char* name, int32 priority, status_t (T::*function)(),
|
||||
T* onThis)
|
||||
{
|
||||
Thread::Launch(new SimpleMemberFunctionObjectWorkaround<T>(function,
|
||||
onThis), priority, name);
|
||||
}
|
||||
|
||||
|
||||
template<class Param1, class Param2>
|
||||
void
|
||||
LaunchInNewThread(const char* name, int32 priority,
|
||||
status_t (*func)(Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
Thread::Launch(new
|
||||
TwoParamFunctionObjectWorkaround<Param1, Param2>(func, p1, p2),
|
||||
priority, name);
|
||||
}
|
||||
|
||||
|
||||
template<class Param1, class Param2, class Param3>
|
||||
void
|
||||
LaunchInNewThread(const char* name, int32 priority,
|
||||
status_t (*func)(Param1, Param2, Param3),
|
||||
Param1 p1, Param2 p2, Param3 p3)
|
||||
{
|
||||
Thread::Launch(new ThreeParamFunctionObjectWorkaround<Param1, Param2,
|
||||
Param3>(func, p1, p2, p3), priority, name);
|
||||
}
|
||||
|
||||
|
||||
template<class Param1, class Param2, class Param3, class Param4>
|
||||
void
|
||||
LaunchInNewThread(const char* name, int32 priority,
|
||||
status_t (*func)(Param1, Param2, Param3, Param4),
|
||||
Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||
{
|
||||
Thread::Launch(new FourParamFunctionObjectWorkaround<Param1, Param2,
|
||||
Param3, Param4>(func, p1, p2, p3, p4), priority, name);
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
class MouseDownThread {
|
||||
public:
|
||||
static void TrackMouse(View* view, void (View::*)(BPoint),
|
||||
void (View::*)(BPoint, uint32) = 0,
|
||||
bigtime_t pressingPeriod = 100000);
|
||||
|
||||
protected:
|
||||
MouseDownThread(View* view, void (View::*)(BPoint),
|
||||
void (View::*)(BPoint, uint32), bigtime_t pressingPeriod);
|
||||
|
||||
virtual ~MouseDownThread();
|
||||
|
||||
void Go();
|
||||
virtual void Track();
|
||||
|
||||
static status_t TrackBinder(void*);
|
||||
|
||||
private:
|
||||
BMessenger fOwner;
|
||||
void (View::*fDonePressing)(BPoint);
|
||||
void (View::*fPressing)(BPoint, uint32);
|
||||
bigtime_t fPressingPeriod;
|
||||
volatile thread_id fThreadID;
|
||||
};
|
||||
|
||||
|
||||
template<class View>
|
||||
void
|
||||
MouseDownThread<View>::TrackMouse(View* view,
|
||||
void(View::*donePressing)(BPoint),
|
||||
void(View::*pressing)(BPoint, uint32), bigtime_t pressingPeriod)
|
||||
{
|
||||
(new MouseDownThread(view, donePressing, pressing, pressingPeriod))->Go();
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
MouseDownThread<View>::MouseDownThread(View* view,
|
||||
void (View::*donePressing)(BPoint),
|
||||
void (View::*pressing)(BPoint, uint32), bigtime_t pressingPeriod)
|
||||
: fOwner(view, view->Window()),
|
||||
fDonePressing(donePressing),
|
||||
fPressing(pressing),
|
||||
fPressingPeriod(pressingPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
MouseDownThread<View>::~MouseDownThread()
|
||||
{
|
||||
if (fThreadID > 0) {
|
||||
kill_thread(fThreadID);
|
||||
// dead at this point
|
||||
TRESPASS();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
void
|
||||
MouseDownThread<View>::Go()
|
||||
{
|
||||
fThreadID = spawn_thread(&MouseDownThread::TrackBinder,
|
||||
"MouseTrackingThread", B_NORMAL_PRIORITY, this);
|
||||
|
||||
if (fThreadID <= 0 || resume_thread(fThreadID) != B_OK)
|
||||
// didn't start, don't leak self
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
status_t
|
||||
MouseDownThread<View>::TrackBinder(void* castToThis)
|
||||
{
|
||||
MouseDownThread* self = static_cast<MouseDownThread*>(castToThis);
|
||||
self->Track();
|
||||
// dead at this point
|
||||
TRESPASS();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
template<class View>
|
||||
void
|
||||
MouseDownThread<View>::Track()
|
||||
{
|
||||
for (;;) {
|
||||
MessengerAutoLocker lock(&fOwner);
|
||||
if (!lock)
|
||||
break;
|
||||
|
||||
BLooper* looper;
|
||||
View* view = dynamic_cast<View*>(fOwner.Target(&looper));
|
||||
if (!view)
|
||||
break;
|
||||
|
||||
uint32 buttons;
|
||||
BPoint location;
|
||||
view->GetMouse(&location, &buttons, false);
|
||||
if (!buttons) {
|
||||
(view->*fDonePressing)(location);
|
||||
break;
|
||||
}
|
||||
if (fPressing)
|
||||
(view->*fPressing)(location, buttons);
|
||||
|
||||
lock.Unlock();
|
||||
snooze(fPressingPeriod);
|
||||
}
|
||||
|
||||
delete this;
|
||||
ASSERT(!"should not be here");
|
||||
}
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using namespace BPrivate;
|
||||
|
||||
#endif // __THREAD__
|
||||
Reference in New Issue
Block a user