adds priority version of Void delegate/expire/strategy

This commit is contained in:
arturo 2013-01-23 10:11:04 +01:00
parent 1de98a00c2
commit 72100d56d8
4 changed files with 572 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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