mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-21 06:37:42 +01:00
adds priority version of Void delegate/expire/strategy
This commit is contained in:
parent
1de98a00c2
commit
72100d56d8
@ -260,6 +260,214 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class FunctionPriorityDelegate<void,true,true>: public AbstractPriorityDelegate<void>
|
||||
/// Wraps a freestanding function or static member function
|
||||
/// for use as a PriorityDelegate.
|
||||
{
|
||||
public:
|
||||
typedef void (*NotifyMethod)(const void*);
|
||||
|
||||
FunctionPriorityDelegate(NotifyMethod method, int prio):
|
||||
AbstractPriorityDelegate<void>(prio),
|
||||
_receiverMethod(method)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
|
||||
AbstractPriorityDelegate<void>(delegate),
|
||||
_receiverMethod(delegate._receiverMethod)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate)
|
||||
{
|
||||
if (&delegate != this)
|
||||
{
|
||||
this->_receiverMethod = delegate._receiverMethod;
|
||||
this->_priority = delegate._priority;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FunctionPriorityDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
if (_receiverMethod)
|
||||
{
|
||||
(*_receiverMethod)(sender);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
|
||||
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
|
||||
}
|
||||
|
||||
AbstractDelegate<void>* clone() const
|
||||
{
|
||||
return new FunctionPriorityDelegate(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
_receiverMethod = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
NotifyMethod _receiverMethod;
|
||||
Mutex _mutex;
|
||||
|
||||
private:
|
||||
FunctionPriorityDelegate();
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class FunctionPriorityDelegate<void, true, false>: public AbstractPriorityDelegate<void>
|
||||
{
|
||||
public:
|
||||
typedef void (*NotifyMethod)(void*);
|
||||
|
||||
FunctionPriorityDelegate(NotifyMethod method, int prio):
|
||||
AbstractPriorityDelegate<void>(prio),
|
||||
_receiverMethod(method)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
|
||||
AbstractPriorityDelegate<void>(delegate),
|
||||
_receiverMethod(delegate._receiverMethod)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate)
|
||||
{
|
||||
if (&delegate != this)
|
||||
{
|
||||
this->_receiverMethod = delegate._receiverMethod;
|
||||
this->_priority = delegate._priority;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FunctionPriorityDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
if (_receiverMethod)
|
||||
{
|
||||
(*_receiverMethod)(const_cast<void*>(sender));
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
|
||||
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
|
||||
}
|
||||
|
||||
AbstractDelegate<void>* clone() const
|
||||
{
|
||||
return new FunctionPriorityDelegate(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
_receiverMethod = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
NotifyMethod _receiverMethod;
|
||||
Mutex _mutex;
|
||||
|
||||
private:
|
||||
FunctionPriorityDelegate();
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class FunctionPriorityDelegate<void, false>: public AbstractPriorityDelegate<void>
|
||||
{
|
||||
public:
|
||||
typedef void (*NotifyMethod)();
|
||||
|
||||
FunctionPriorityDelegate(NotifyMethod method, int prio):
|
||||
AbstractPriorityDelegate<void>(prio),
|
||||
_receiverMethod(method)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
|
||||
AbstractPriorityDelegate<void>(delegate),
|
||||
_receiverMethod(delegate._receiverMethod)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate)
|
||||
{
|
||||
if (&delegate != this)
|
||||
{
|
||||
this->_receiverMethod = delegate._receiverMethod;
|
||||
this->_priority = delegate._priority;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FunctionPriorityDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
if (_receiverMethod)
|
||||
{
|
||||
(*_receiverMethod)();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
|
||||
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
|
||||
}
|
||||
|
||||
AbstractDelegate<void>* clone() const
|
||||
{
|
||||
return new FunctionPriorityDelegate(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
_receiverMethod = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
NotifyMethod _receiverMethod;
|
||||
Mutex _mutex;
|
||||
|
||||
private:
|
||||
FunctionPriorityDelegate();
|
||||
};
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
|
@ -198,6 +198,152 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class TObj>
|
||||
class PriorityDelegate<TObj, void, true>: public AbstractPriorityDelegate<void>
|
||||
{
|
||||
public:
|
||||
typedef void (TObj::*NotifyMethod)(const void*);
|
||||
|
||||
PriorityDelegate(TObj* obj, NotifyMethod method, int prio):
|
||||
AbstractPriorityDelegate<void>(prio),
|
||||
_receiverObject(obj),
|
||||
_receiverMethod(method)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityDelegate(const PriorityDelegate& delegate):
|
||||
AbstractPriorityDelegate<void>(delegate),
|
||||
_receiverObject(delegate._receiverObject),
|
||||
_receiverMethod(delegate._receiverMethod)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityDelegate& operator = (const PriorityDelegate& delegate)
|
||||
{
|
||||
if (&delegate != this)
|
||||
{
|
||||
this->_pTarget = delegate._pTarget;
|
||||
this->_receiverObject = delegate._receiverObject;
|
||||
this->_receiverMethod = delegate._receiverMethod;
|
||||
this->_priority = delegate._priority;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~PriorityDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
if (_receiverObject)
|
||||
{
|
||||
(_receiverObject->*_receiverMethod)(sender);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap());
|
||||
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
|
||||
}
|
||||
|
||||
AbstractDelegate<void>* clone() const
|
||||
{
|
||||
return new PriorityDelegate(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
_receiverObject = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
TObj* _receiverObject;
|
||||
NotifyMethod _receiverMethod;
|
||||
Mutex _mutex;
|
||||
|
||||
private:
|
||||
PriorityDelegate();
|
||||
};
|
||||
|
||||
template <class TObj>
|
||||
class PriorityDelegate<TObj, void, false>: public AbstractPriorityDelegate<void>
|
||||
{
|
||||
public:
|
||||
typedef void (TObj::*NotifyMethod)();
|
||||
|
||||
PriorityDelegate(TObj* obj, NotifyMethod method, int prio):
|
||||
AbstractPriorityDelegate<void>(prio),
|
||||
_receiverObject(obj),
|
||||
_receiverMethod(method)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityDelegate(const PriorityDelegate& delegate):
|
||||
AbstractPriorityDelegate<void>(delegate),
|
||||
_receiverObject(delegate._receiverObject),
|
||||
_receiverMethod(delegate._receiverMethod)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityDelegate& operator = (const PriorityDelegate& delegate)
|
||||
{
|
||||
if (&delegate != this)
|
||||
{
|
||||
this->_pTarget = delegate._pTarget;
|
||||
this->_receiverObject = delegate._receiverObject;
|
||||
this->_receiverMethod = delegate._receiverMethod;
|
||||
this->_priority = delegate._priority;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~PriorityDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
if (_receiverObject)
|
||||
{
|
||||
(_receiverObject->*_receiverMethod)();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap());
|
||||
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
|
||||
}
|
||||
|
||||
AbstractDelegate<void>* clone() const
|
||||
{
|
||||
return new PriorityDelegate(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
_receiverObject = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
TObj* _receiverObject;
|
||||
NotifyMethod _receiverMethod;
|
||||
Mutex _mutex;
|
||||
|
||||
private:
|
||||
PriorityDelegate();
|
||||
};
|
||||
|
||||
template <class TObj, class TArgs>
|
||||
static PriorityDelegate<TObj, TArgs, true> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio)
|
||||
{
|
||||
@ -268,7 +414,73 @@ static FunctionPriorityDelegate<TArgs, false> priorityDelegate(void (*NotifyMeth
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class TObj>
|
||||
static PriorityDelegate<TObj, void, true> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), int prio)
|
||||
{
|
||||
return PriorityDelegate<TObj, void, true>(pObj, NotifyMethod, prio);
|
||||
}
|
||||
|
||||
|
||||
template <class TObj>
|
||||
static PriorityDelegate<TObj, void, false> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(), int prio)
|
||||
{
|
||||
return PriorityDelegate<TObj, void, false>(pObj, NotifyMethod, prio);
|
||||
}
|
||||
|
||||
|
||||
template <class TObj>
|
||||
static PriorityExpire<void> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), int prio, Timestamp::TimeDiff expireMilliSec)
|
||||
{
|
||||
return PriorityExpire<void>(PriorityDelegate<TObj, void, true>(pObj, NotifyMethod, prio), expireMilliSec);
|
||||
}
|
||||
|
||||
|
||||
template <class TObj>
|
||||
static PriorityExpire<void> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(), int prio, Timestamp::TimeDiff expireMilliSec)
|
||||
{
|
||||
return PriorityExpire<void>(PriorityDelegate<TObj, void, false>(pObj, NotifyMethod, prio), expireMilliSec);
|
||||
}
|
||||
|
||||
|
||||
inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(const void*), int prio, Timestamp::TimeDiff expireMilliSec)
|
||||
{
|
||||
return PriorityExpire<void>(FunctionPriorityDelegate<void, true, true>(NotifyMethod, prio), expireMilliSec);
|
||||
}
|
||||
|
||||
|
||||
inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(void*), int prio, Timestamp::TimeDiff expireMilliSec)
|
||||
{
|
||||
return PriorityExpire<void>(FunctionPriorityDelegate<void, true, false>(NotifyMethod, prio), expireMilliSec);
|
||||
}
|
||||
|
||||
|
||||
inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(), int prio, Timestamp::TimeDiff expireMilliSec)
|
||||
{
|
||||
return PriorityExpire<void>(FunctionPriorityDelegate<void, false>(NotifyMethod, prio), expireMilliSec);
|
||||
}
|
||||
|
||||
|
||||
inline FunctionPriorityDelegate<void, true, true> priorityDelegate(void (*NotifyMethod)(const void*), int prio)
|
||||
{
|
||||
return FunctionPriorityDelegate<void, true, true>(NotifyMethod, prio);
|
||||
}
|
||||
|
||||
|
||||
inline FunctionPriorityDelegate<void, true, false> priorityDelegate(void (*NotifyMethod)(void*), int prio)
|
||||
{
|
||||
return FunctionPriorityDelegate<void, true, false>(NotifyMethod, prio);
|
||||
}
|
||||
|
||||
|
||||
inline FunctionPriorityDelegate<void, false> priorityDelegate(void (*NotifyMethod)(), int prio)
|
||||
{
|
||||
return FunctionPriorityDelegate<void, false>(NotifyMethod, prio);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_PriorityDelegate_INCLUDED
|
||||
|
@ -129,7 +129,85 @@ private:
|
||||
PriorityExpire();
|
||||
};
|
||||
|
||||
template <>
|
||||
class PriorityExpire<void>: public AbstractPriorityDelegate<void>
|
||||
/// Decorator for AbstractPriorityDelegate adding automatic
|
||||
/// expiring of registrations to AbstractPriorityDelegate.
|
||||
{
|
||||
public:
|
||||
PriorityExpire(const AbstractPriorityDelegate<void>& p, Timestamp::TimeDiff expireMilliSec):
|
||||
AbstractPriorityDelegate<void>(p),
|
||||
_pDelegate(static_cast<AbstractPriorityDelegate<void>*>(p.clone())),
|
||||
_expire(expireMilliSec*1000)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityExpire(const PriorityExpire& expire):
|
||||
AbstractPriorityDelegate<void>(expire),
|
||||
_pDelegate(static_cast<AbstractPriorityDelegate<void>*>(expire._pDelegate->clone())),
|
||||
_expire(expire._expire),
|
||||
_creationTime(expire._creationTime)
|
||||
{
|
||||
}
|
||||
|
||||
~PriorityExpire()
|
||||
{
|
||||
delete _pDelegate;
|
||||
}
|
||||
|
||||
PriorityExpire& operator = (const PriorityExpire& expire)
|
||||
{
|
||||
if (&expire != this)
|
||||
{
|
||||
delete this->_pDelegate;
|
||||
this->_pDelegate = static_cast<AbstractPriorityDelegate<void>*>(expire._pDelegate->clone());
|
||||
this->_expire = expire._expire;
|
||||
this->_creationTime = expire._creationTime;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool notify(const void* sender)
|
||||
{
|
||||
if (!expired())
|
||||
return this->_pDelegate->notify(sender);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool equals(const AbstractDelegate<void>& other) const
|
||||
{
|
||||
return other.equals(*_pDelegate);
|
||||
}
|
||||
|
||||
AbstractPriorityDelegate<void>* clone() const
|
||||
{
|
||||
return new PriorityExpire(*this);
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
_pDelegate->disable();
|
||||
}
|
||||
|
||||
const AbstractPriorityDelegate<void>* unwrap() const
|
||||
{
|
||||
return this->_pDelegate;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool expired() const
|
||||
{
|
||||
return _creationTime.isElapsed(_expire);
|
||||
}
|
||||
|
||||
AbstractPriorityDelegate<void>* _pDelegate;
|
||||
Timestamp::TimeDiff _expire;
|
||||
Timestamp _creationTime;
|
||||
|
||||
private:
|
||||
PriorityExpire();
|
||||
};
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
|
@ -135,7 +135,80 @@ protected:
|
||||
Delegates _delegates;
|
||||
};
|
||||
|
||||
template <class TDelegate>
|
||||
class PriorityStrategy<void, TDelegate>
|
||||
/// NotificationStrategy for PriorityEvent.
|
||||
///
|
||||
/// Delegates are kept in a std::vector<>, ordered
|
||||
/// by their priority.
|
||||
{
|
||||
public:
|
||||
typedef SharedPtr<TDelegate> DelegatePtr;
|
||||
typedef std::vector<DelegatePtr> Delegates;
|
||||
typedef typename Delegates::iterator Iterator;
|
||||
|
||||
public:
|
||||
|
||||
void notify(const void* sender)
|
||||
{
|
||||
for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
|
||||
{
|
||||
(*it)->notify(sender);
|
||||
}
|
||||
}
|
||||
|
||||
void add(const TDelegate& delegate)
|
||||
{
|
||||
for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
|
||||
{
|
||||
if ((*it)->priority() > delegate.priority())
|
||||
{
|
||||
_delegates.insert(it, DelegatePtr(static_cast<TDelegate*>(delegate.clone())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
_delegates.push_back(DelegatePtr(static_cast<TDelegate*>(delegate.clone())));
|
||||
}
|
||||
|
||||
void remove(const TDelegate& delegate)
|
||||
{
|
||||
for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
|
||||
{
|
||||
if (delegate.equals(**it))
|
||||
{
|
||||
(*it)->disable();
|
||||
_delegates.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PriorityStrategy& operator = (const PriorityStrategy& s)
|
||||
{
|
||||
if (this != &s)
|
||||
{
|
||||
_delegates = s._delegates;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
|
||||
{
|
||||
(*it)->disable();
|
||||
}
|
||||
_delegates.clear();
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return _delegates.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
Delegates _delegates;
|
||||
};
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user