#ifndef __FUNCTION_OBJECT__
#define __FUNCTION_OBJECT__
#include <Message.h>
#include <Messenger.h>
#include <MessageFilter.h>
#include <Entry.h>
#include <Node.h>
namespace BPrivate {
template<class P>
class ParameterBinder {
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;
};
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);
}
}
using namespace BPrivate;
#endif