From d5d048e68991c977a92af38e29d49c137a6ea1ed Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 24 Nov 2014 11:17:27 +0100 Subject: [PATCH] Poco::BasicEvent improvements and preparations for future support of lambdas/std::function --- Foundation/include/Poco/AbstractDelegate.h | 2 + Foundation/include/Poco/AbstractEvent.h | 167 ++++++------------ Foundation/include/Poco/DefaultStrategy.h | 42 ++++- Foundation/include/Poco/Delegate.h | 32 ++-- Foundation/include/Poco/Expire.h | 2 +- Foundation/include/Poco/FunctionDelegate.h | 132 +++++++------- .../include/Poco/FunctionPriorityDelegate.h | 138 +++++++-------- .../include/Poco/NotificationStrategy.h | 19 +- Foundation/include/Poco/PriorityDelegate.h | 6 +- Foundation/include/Poco/PriorityExpire.h | 3 + Foundation/include/Poco/PriorityStrategy.h | 53 +++++- Zip/testsuite/test.dat | 98 +++++----- 12 files changed, 351 insertions(+), 343 deletions(-) diff --git a/Foundation/include/Poco/AbstractDelegate.h b/Foundation/include/Poco/AbstractDelegate.h index 9732b1065..2538cabe9 100644 --- a/Foundation/include/Poco/AbstractDelegate.h +++ b/Foundation/include/Poco/AbstractDelegate.h @@ -65,6 +65,7 @@ public: } }; + template <> class AbstractDelegate /// Base class for Delegate and Expire. @@ -104,6 +105,7 @@ public: } }; + } // namespace Poco diff --git a/Foundation/include/Poco/AbstractEvent.h b/Foundation/include/Poco/AbstractEvent.h index c26e2b1ab..88169fa43 100644 --- a/Foundation/include/Poco/AbstractEvent.h +++ b/Foundation/include/Poco/AbstractEvent.h @@ -151,6 +151,7 @@ class AbstractEvent /// to create the PriorityDelegate. { public: + typedef TDelegate* DelegateHandle; typedef TArgs Args; AbstractEvent(): @@ -188,6 +189,28 @@ public: _strategy.remove(aDelegate); } + DelegateHandle add(const TDelegate& aDelegate) + /// Adds a delegate to the event. + /// + /// Exact behavior is determined by the TStrategy. + /// + /// Returns a DelegateHandle which can be used in call to + /// remove() to remove the delegate. + { + typename TMutex::ScopedLock lock(_mutex); + return _strategy.add(aDelegate); + } + + void remove(DelegateHandle delegateHandle) + /// Removes a delegate from the event using a DelegateHandle + /// returned by add(). + /// + /// If the delegate is not found, this function does nothing. + { + typename TMutex::ScopedLock lock(_mutex); + _strategy.remove(delegateHandle); + } + void operator () (const void* pSender, TArgs& args) /// Shortcut for notify(pSender, args); { @@ -330,126 +353,13 @@ private: AbstractEvent& operator = (const AbstractEvent& other); }; + template -class AbstractEvent - /// An AbstractEvent is the base class of all events. - /// It works similar to the way C# handles notifications (aka events in C#). - /// - /// Events can be used to send information to a set of delegates - /// which are registered with the event. The type of the data is specified with - /// the template parameter TArgs. The TStrategy parameter must be a subclass - /// of NotificationStrategy. The parameter TDelegate can either be a subclass of AbstractDelegate - /// or of AbstractPriorityDelegate. - /// - /// Note that AbstractEvent should never be used directly. One ought to use - /// one of its subclasses which set the TStrategy and TDelegate template parameters - /// to fixed values. For most use-cases the BasicEvent template will be sufficient: - /// - /// #include "Poco/BasicEvent.h" - /// #include "Poco/Delegate.h" - /// - /// Note that as of release 1.4.2, the behavior of BasicEvent equals that of FIFOEvent, - /// so the FIFOEvent class is no longer necessary and provided for backwards compatibility - /// only. - /// - /// BasicEvent works with a standard delegate. They allow one object to register - /// onr or more delegates with an event. In contrast, a PriorityDelegate comes with an attached priority value - /// and allows one object to register for one priority value one or more delegates. Note that PriorityDelegates - /// only work with PriorityEvents: - /// - /// #include "Poco/PriorityEvent.h" - /// #include "Poco/PriorityDelegate.h" - /// - /// Use events by adding them as public members to the object which is throwing notifications: - /// - /// class MyData - /// { - /// public: - /// Poco::BasicEvent dataChanged; - /// - /// MyData(); - /// ... - /// void setData(int i); - /// ... - /// private: - /// int _data; - /// }; - /// - /// Firing the event is done either by calling the event's notify() or notifyAsync() method: - /// - /// void MyData::setData(int i) - /// { - /// this->_data = i; - /// dataChanged.notify(this, this->_data); - /// } - /// - /// Alternatively, instead of notify(), operator () can be used. - /// - /// void MyData::setData(int i) - /// { - /// this->_data = i; - /// dataChanged(this, this->_data); - /// } - /// - /// Note that operator (), notify() and notifyAsync() do not catch exceptions, i.e. in case a - /// delegate throws an exception, notifying is immediately aborted and the exception is propagated - /// back to the caller. - /// - /// Delegates can register methods at the event. In the case of a BasicEvent - /// the Delegate template is used, in case of an PriorityEvent a PriorityDelegate is used. - /// Mixing of delegates, e.g. using a PriorityDelegate with a BasicEvent is not allowed and - /// can lead to compile-time and/or run-time errors. The standalone delegate() functions - /// can be used to construct Delegate objects. - /// - /// Events require the observers to have one of the following method signatures: - /// - /// void onEvent(const void* pSender, TArgs& args); - /// void onEvent(TArgs& args); - /// static void onEvent(const void* pSender, TArgs& args); - /// static void onEvent(void* pSender, TArgs& args); - /// static void onEvent(TArgs& args); - /// - /// For performance reasons arguments are always sent by reference. This also allows observers - /// to modify the event argument. To prevent that, use <[const TArg]> as template - /// parameter. A non-conformant method signature leads to compile errors. - /// - /// Assuming that the observer meets the method signature requirement, it can register - /// this method with the += operator: - /// - /// class MyController - /// { - /// protected: - /// MyData _data; - /// - /// void onDataChanged(void* pSender, int& data); - /// ... - /// }; - /// - /// MyController::MyController() - /// { - /// _data.dataChanged += delegate(this, &MyController::onDataChanged); - /// } - /// - /// In some cases it might be desirable to work with automatically expiring registrations. Simply add - /// to delegate as 3rd parameter a expireValue (in milliseconds): - /// - /// _data.dataChanged += delegate(this, &MyController::onDataChanged, 1000); - /// - /// This will add a delegate to the event which will automatically be removed in 1000 millisecs. - /// - /// Unregistering happens via the -= operator. Forgetting to unregister a method will lead to - /// segmentation faults later, when one tries to send a notify to a no longer existing object. - /// - /// MyController::~MyController() - /// { - /// _data.dataChanged -= delegate(this, &MyController::onDataChanged); - /// } - /// - /// Working with PriorityDelegate's as similar to working with BasicEvent. - /// Instead of delegate(), the priorityDelegate() function must be used - /// to create the PriorityDelegate. +class AbstractEvent { public: + typedef TDelegate* DelegateHandle; + AbstractEvent(): _executeAsync(this, &AbstractEvent::executeAsyncImpl), _enabled(true) @@ -484,6 +394,28 @@ public: typename TMutex::ScopedLock lock(_mutex); _strategy.remove(aDelegate); } + + DelegateHandle add(const TDelegate& aDelegate) + /// Adds a delegate to the event. + /// + /// Exact behavior is determined by the TStrategy. + /// + /// Returns a DelegateHandle which can be used in call to + /// remove() to remove the delegate. + { + typename TMutex::ScopedLock lock(_mutex); + return _strategy.add(aDelegate); + } + + void remove(DelegateHandle delegateHandle) + /// Removes a delegate from the event using a DelegateHandle + /// returned by add(). + /// + /// If the delegate is not found, this function does nothing. + { + typename TMutex::ScopedLock lock(_mutex); + _strategy.remove(delegateHandle); + } void operator () (const void* pSender) /// Shortcut for notify(pSender, args); @@ -621,6 +553,7 @@ private: AbstractEvent& operator = (const AbstractEvent& other); }; + } // namespace Poco diff --git a/Foundation/include/Poco/DefaultStrategy.h b/Foundation/include/Poco/DefaultStrategy.h index 1ba9ade91..35133c453 100644 --- a/Foundation/include/Poco/DefaultStrategy.h +++ b/Foundation/include/Poco/DefaultStrategy.h @@ -37,6 +37,7 @@ class DefaultStrategy: public NotificationStrategy /// order in which they have been registered. { public: + typedef TDelegate* DelegateHandle; typedef SharedPtr DelegatePtr; typedef std::vector Delegates; typedef typename Delegates::iterator Iterator; @@ -63,9 +64,11 @@ public: } } - void add(const TDelegate& delegate) + DelegateHandle add(const TDelegate& delegate) { - _delegates.push_back(DelegatePtr(static_cast(delegate.clone()))); + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.push_back(pDelegate); + return pDelegate.get(); } void remove(const TDelegate& delegate) @@ -80,6 +83,19 @@ public: } } } + + void remove(DelegateHandle delegateHandle) + { + for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) + { + if (*it == delegateHandle) + { + (*it)->disable(); + _delegates.erase(it); + return; + } + } + } DefaultStrategy& operator = (const DefaultStrategy& s) { @@ -108,6 +124,7 @@ protected: Delegates _delegates; }; + template class DefaultStrategy: public NotificationStrategy /// Default notification strategy. @@ -117,6 +134,7 @@ class DefaultStrategy: public NotificationStrategy DelegatePtr; typedef std::vector Delegates; typedef typename Delegates::iterator Iterator; @@ -143,9 +161,11 @@ public: } } - void add(const TDelegate& delegate) + DelegateHandle add(const TDelegate& delegate) { - _delegates.push_back(DelegatePtr(static_cast(delegate.clone()))); + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.push_back(pDelegate); + return pDelegate.get(); } void remove(const TDelegate& delegate) @@ -161,6 +181,19 @@ public: } } + void remove(DelegateHandle delegateHandle) + { + for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) + { + if (*it == delegateHandle) + { + (*it)->disable(); + _delegates.erase(it); + return; + } + } + } + DefaultStrategy& operator = (const DefaultStrategy& s) { if (this != &s) @@ -188,6 +221,7 @@ protected: Delegates _delegates; }; + } // namespace Poco diff --git a/Foundation/include/Poco/Delegate.h b/Foundation/include/Poco/Delegate.h index c6e5dbed4..eaed9c3e3 100644 --- a/Foundation/include/Poco/Delegate.h +++ b/Foundation/include/Poco/Delegate.h @@ -174,78 +174,75 @@ private: template -static Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&)) +inline Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&)) { return Delegate(pObj, NotifyMethod); } template -static Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&)) +inline Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&)) { return Delegate(pObj, NotifyMethod); } template -static Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs) { return Expire(Delegate(pObj, NotifyMethod), expireMillisecs); } template -static Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs) { return Expire(Delegate(pObj, NotifyMethod), expireMillisecs); } template -static Expire delegate(void (*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(void (*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs) { return Expire(FunctionDelegate(NotifyMethod), expireMillisecs); } template -static Expire delegate(void (*NotifyMethod)(void*, TArgs&), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(void (*NotifyMethod)(void*, TArgs&), Timestamp::TimeDiff expireMillisecs) { return Expire(FunctionDelegate(NotifyMethod), expireMillisecs); } template -static Expire delegate(void (*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(void (*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs) { return Expire(FunctionDelegate(NotifyMethod), expireMillisecs); } template -static FunctionDelegate delegate(void (*NotifyMethod)(const void*, TArgs&)) +inline FunctionDelegate delegate(void (*NotifyMethod)(const void*, TArgs&)) { return FunctionDelegate(NotifyMethod); } template -static FunctionDelegate delegate(void (*NotifyMethod)(void*, TArgs&)) +inline FunctionDelegate delegate(void (*NotifyMethod)(void*, TArgs&)) { return FunctionDelegate(NotifyMethod); } template -static FunctionDelegate delegate(void (*NotifyMethod)(TArgs&)) +inline FunctionDelegate delegate(void (*NotifyMethod)(TArgs&)) { return FunctionDelegate(NotifyMethod); } - - - template class Delegate: public AbstractDelegate { @@ -390,28 +387,28 @@ private: template -static Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*)) +inline Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*)) { return Delegate(pObj, NotifyMethod); } template -static Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)()) +inline Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)()) { return Delegate(pObj, NotifyMethod); } template -static Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), Timestamp::TimeDiff expireMillisecs) { return Expire(Delegate(pObj, NotifyMethod), expireMillisecs); } template -static Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(), Timestamp::TimeDiff expireMillisecs) +inline Expire delegate(TObj* pObj, void (TObj::*NotifyMethod)(), Timestamp::TimeDiff expireMillisecs) { return Expire(Delegate(pObj, NotifyMethod), expireMillisecs); } @@ -452,6 +449,7 @@ inline FunctionDelegate delegate(void (*NotifyMethod)()) return FunctionDelegate(NotifyMethod); } + } // namespace Poco diff --git a/Foundation/include/Poco/Expire.h b/Foundation/include/Poco/Expire.h index 1bfa44676..647f0c2ee 100644 --- a/Foundation/include/Poco/Expire.h +++ b/Foundation/include/Poco/Expire.h @@ -108,6 +108,7 @@ private: Expire(); }; + template <> class Expire: public AbstractDelegate /// Decorator for AbstractDelegate adding automatic @@ -189,7 +190,6 @@ private: }; - } // namespace Poco diff --git a/Foundation/include/Poco/FunctionDelegate.h b/Foundation/include/Poco/FunctionDelegate.h index 8d68113b2..9e0b3a460 100644 --- a/Foundation/include/Poco/FunctionDelegate.h +++ b/Foundation/include/Poco/FunctionDelegate.h @@ -34,16 +34,16 @@ class FunctionDelegate: public AbstractDelegate /// for use as a Delegate. { public: - typedef void (*NotifyMethod)(const void*, TArgs&); + typedef void (*NotifyFunction)(const void*, TArgs&); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -55,8 +55,7 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -64,9 +63,9 @@ public: bool notify(const void* sender, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(sender, arguments); + (*_function)(sender, arguments); return true; } else return false; @@ -75,7 +74,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -86,11 +85,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -102,16 +101,16 @@ template class FunctionDelegate: public AbstractDelegate { public: - typedef void (*NotifyMethod)(void*, TArgs&); + typedef void (*NotifyFunction)(void*, TArgs&); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -123,8 +122,7 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -132,9 +130,9 @@ public: bool notify(const void* sender, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(const_cast(sender), arguments); + (*_function)(const_cast(sender), arguments); return true; } else return false; @@ -143,7 +141,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -154,11 +152,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -170,16 +168,16 @@ template class FunctionDelegate: public AbstractDelegate { public: - typedef void (*NotifyMethod)(TArgs&); + typedef void (*NotifyFunction)(TArgs&); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -191,8 +189,7 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -200,9 +197,9 @@ public: bool notify(const void* /*sender*/, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(arguments); + (*_function)(arguments); return true; } else return false; @@ -211,7 +208,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -222,11 +219,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -234,26 +231,22 @@ private: }; - - - - template <> -class FunctionDelegate: public AbstractDelegate +class FunctionDelegate: public AbstractDelegate /// Wraps a freestanding function or static member function /// for use as a Delegate. { public: - typedef void (*NotifyMethod)(const void*); + typedef void (*NotifyFunction)(const void*); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -265,8 +258,7 @@ public: { if (&delegate != this) { - //this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -274,9 +266,9 @@ public: bool notify(const void* sender) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(sender); + (*_function)(sender); return true; } else return false; @@ -285,7 +277,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -296,11 +288,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -312,16 +304,16 @@ template <> class FunctionDelegate: public AbstractDelegate { public: - typedef void (*NotifyMethod)(void*); + typedef void (*NotifyFunction)(void*); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -333,8 +325,7 @@ public: { if (&delegate != this) { - //this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -342,9 +333,9 @@ public: bool notify(const void* sender) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(const_cast(sender)); + (*_function)(const_cast(sender)); return true; } else return false; @@ -353,7 +344,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -364,11 +355,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -380,16 +371,16 @@ template class FunctionDelegate: public AbstractDelegate { public: - typedef void (*NotifyMethod)(); + typedef void (*NotifyFunction)(); - FunctionDelegate(NotifyMethod method): - _receiverMethod(method) + FunctionDelegate(NotifyFunction function): + _function(function) { } FunctionDelegate(const FunctionDelegate& delegate): AbstractDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -401,8 +392,7 @@ public: { if (&delegate != this) { - //this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; + this->_function = delegate._function; } return *this; } @@ -410,9 +400,9 @@ public: bool notify(const void* /*sender*/) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(); + (*_function)(); return true; } else return false; @@ -421,7 +411,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -432,11 +422,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: diff --git a/Foundation/include/Poco/FunctionPriorityDelegate.h b/Foundation/include/Poco/FunctionPriorityDelegate.h index 9213eab84..625fb4ab1 100644 --- a/Foundation/include/Poco/FunctionPriorityDelegate.h +++ b/Foundation/include/Poco/FunctionPriorityDelegate.h @@ -34,17 +34,17 @@ class FunctionPriorityDelegate: public AbstractPriorityDelegate /// for use as a PriorityDelegate. { public: - typedef void (*NotifyMethod)(const void*, TArgs&); + typedef void (*NotifyFunction)(const void*, TArgs&); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -52,9 +52,8 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -66,9 +65,9 @@ public: bool notify(const void* sender, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(sender, arguments); + (*_function)(sender, arguments); return true; } else return false; @@ -77,7 +76,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -88,11 +87,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -104,17 +103,17 @@ template class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: - typedef void (*NotifyMethod)(void*, TArgs&); + typedef void (*NotifyFunction)(void*, TArgs&); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -122,9 +121,8 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -136,9 +134,9 @@ public: bool notify(const void* sender, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(const_cast(sender), arguments); + (*_function)(const_cast(sender), arguments); return true; } else return false; @@ -147,7 +145,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -158,11 +156,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -174,17 +172,17 @@ template class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: - typedef void (*NotifyMethod)(TArgs&); + typedef void (*NotifyFunction)(TArgs&); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -192,9 +190,8 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -206,9 +203,9 @@ public: bool notify(const void* sender, TArgs& arguments) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(arguments); + (*_function)(arguments); return true; } else return false; @@ -217,7 +214,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -228,11 +225,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -241,22 +238,22 @@ private: template <> -class FunctionPriorityDelegate: public AbstractPriorityDelegate +class FunctionPriorityDelegate: public AbstractPriorityDelegate /// Wraps a freestanding function or static member function /// for use as a PriorityDelegate. { public: - typedef void (*NotifyMethod)(const void*); + typedef void (*NotifyFunction)(const void*); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -264,8 +261,8 @@ public: { if (&delegate != this) { - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -277,9 +274,9 @@ public: bool notify(const void* sender) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(sender); + (*_function)(sender); return true; } else return false; @@ -288,7 +285,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -299,11 +296,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -315,17 +312,17 @@ template <> class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: - typedef void (*NotifyMethod)(void*); + typedef void (*NotifyFunction)(void*); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -333,8 +330,8 @@ public: { if (&delegate != this) { - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -346,9 +343,9 @@ public: bool notify(const void* sender) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(const_cast(sender)); + (*_function)(const_cast(sender)); return true; } else return false; @@ -357,7 +354,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -368,11 +365,11 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: @@ -384,17 +381,17 @@ template <> class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: - typedef void (*NotifyMethod)(); + typedef void (*NotifyFunction)(); - FunctionPriorityDelegate(NotifyMethod method, int prio): + FunctionPriorityDelegate(NotifyFunction function, int prio): AbstractPriorityDelegate(prio), - _receiverMethod(method) + _function(function) { } FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), - _receiverMethod(delegate._receiverMethod) + _function(delegate._function) { } @@ -402,8 +399,8 @@ public: { if (&delegate != this) { - this->_receiverMethod = delegate._receiverMethod; - this->_priority = delegate._priority; + this->_function = delegate._function; + this->_priority = delegate._priority; } return *this; } @@ -415,9 +412,9 @@ public: bool notify(const void* sender) { Mutex::ScopedLock lock(_mutex); - if (_receiverMethod) + if (_function) { - (*_receiverMethod)(); + (*_function)(); return true; } else return false; @@ -426,7 +423,7 @@ public: bool equals(const AbstractDelegate& other) const { const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast(other.unwrap()); - return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod; + return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _function == pOtherDelegate->_function; } AbstractDelegate* clone() const @@ -437,17 +434,18 @@ public: void disable() { Mutex::ScopedLock lock(_mutex); - _receiverMethod = 0; + _function = 0; } protected: - NotifyMethod _receiverMethod; + NotifyFunction _function; Mutex _mutex; private: FunctionPriorityDelegate(); }; + } // namespace Poco diff --git a/Foundation/include/Poco/NotificationStrategy.h b/Foundation/include/Poco/NotificationStrategy.h index e49a28c34..25da46dd9 100644 --- a/Foundation/include/Poco/NotificationStrategy.h +++ b/Foundation/include/Poco/NotificationStrategy.h @@ -35,6 +35,8 @@ class NotificationStrategy /// but does not need to inherit from NotificationStrategy. { public: + typedef TDelegate* DelegateHandle; + NotificationStrategy() { } @@ -46,13 +48,17 @@ public: virtual void notify(const void* sender, TArgs& arguments) = 0; /// Sends a notification to all registered delegates. - virtual void add(const TDelegate& delegate) = 0; + virtual DelegateHandle add(const TDelegate& delegate) = 0; /// Adds a delegate to the strategy. virtual void remove(const TDelegate& delegate) = 0; /// Removes a delegate from the strategy, if found. /// Does nothing if the delegate has not been added. + virtual void remove(DelegateHandle delegateHandle) = 0; + /// Removes a delegate from the strategy, if found. + /// Does nothing if the delegate has not been added. + virtual void clear() = 0; /// Removes all delegates from the strategy. @@ -60,8 +66,9 @@ public: /// Returns false if the strategy contains at least one delegate. }; + template -class NotificationStrategy +class NotificationStrategy /// The interface that all notification strategies must implement. /// /// Note: Event is based on policy-driven design, so every strategy implementation @@ -69,6 +76,8 @@ class NotificationStrategy /// but does not need to inherit from NotificationStrategy. { public: + typedef TDelegate* DelegateHandle; + NotificationStrategy() { } @@ -80,13 +89,17 @@ public: virtual void notify(const void* sender) = 0; /// Sends a notification to all registered delegates. - virtual void add(const TDelegate& delegate) = 0; + virtual DelegateHandle add(const TDelegate& delegate) = 0; /// Adds a delegate to the strategy. virtual void remove(const TDelegate& delegate) = 0; /// Removes a delegate from the strategy, if found. /// Does nothing if the delegate has not been added. + virtual void remove(DelegateHandle delegateHandle) = 0; + /// Removes a delegate from the strategy, if found. + /// Does nothing if the delegate has not been added. + virtual void clear() = 0; /// Removes all delegates from the strategy. diff --git a/Foundation/include/Poco/PriorityDelegate.h b/Foundation/include/Poco/PriorityDelegate.h index f7d5a61e3..056cb5b3c 100644 --- a/Foundation/include/Poco/PriorityDelegate.h +++ b/Foundation/include/Poco/PriorityDelegate.h @@ -251,6 +251,7 @@ private: PriorityDelegate(); }; + template class PriorityDelegate: public AbstractPriorityDelegate { @@ -324,6 +325,7 @@ private: PriorityDelegate(); }; + template static PriorityDelegate priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio) { @@ -394,9 +396,6 @@ static FunctionPriorityDelegate priorityDelegate(void (*NotifyMeth } - - - template static PriorityDelegate priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), int prio) { @@ -463,4 +462,5 @@ inline FunctionPriorityDelegate priorityDelegate(void (*NotifyMetho } // namespace Poco + #endif // Foundation_PriorityDelegate_INCLUDED diff --git a/Foundation/include/Poco/PriorityExpire.h b/Foundation/include/Poco/PriorityExpire.h index c719547ad..e0a8957f1 100644 --- a/Foundation/include/Poco/PriorityExpire.h +++ b/Foundation/include/Poco/PriorityExpire.h @@ -109,6 +109,7 @@ private: PriorityExpire(); }; + template <> class PriorityExpire: public AbstractPriorityDelegate /// Decorator for AbstractPriorityDelegate adding automatic @@ -188,6 +189,8 @@ protected: private: PriorityExpire(); }; + + } // namespace Poco diff --git a/Foundation/include/Poco/PriorityStrategy.h b/Foundation/include/Poco/PriorityStrategy.h index 8e4a73a5c..b2c88865a 100644 --- a/Foundation/include/Poco/PriorityStrategy.h +++ b/Foundation/include/Poco/PriorityStrategy.h @@ -36,6 +36,7 @@ class PriorityStrategy: public NotificationStrategy /// by their priority. { public: + typedef TDelegate* DelegateHandle; typedef SharedPtr DelegatePtr; typedef std::vector Delegates; typedef typename Delegates::iterator Iterator; @@ -62,17 +63,20 @@ public: } } - void add(const TDelegate& delegate) + DelegateHandle add(const TDelegate& delegate) { for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) { if ((*it)->priority() > delegate.priority()) { - _delegates.insert(it, DelegatePtr(static_cast(delegate.clone()))); - return; + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.insert(it, pDelegate); + return pDelegate.get(); } } - _delegates.push_back(DelegatePtr(static_cast(delegate.clone()))); + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.push_back(pDelegate); + return pDelegate.get(); } void remove(const TDelegate& delegate) @@ -88,6 +92,19 @@ public: } } + void remove(DelegateHandle delegateHandle) + { + for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) + { + if (*it == delegateHandle) + { + (*it)->disable(); + _delegates.erase(it); + return; + } + } + } + PriorityStrategy& operator = (const PriorityStrategy& s) { if (this != &s) @@ -115,6 +132,7 @@ protected: Delegates _delegates; }; + template class PriorityStrategy /// NotificationStrategy for PriorityEvent. @@ -123,6 +141,7 @@ class PriorityStrategy /// by their priority. { public: + typedef TDelegate* DelegateHandle; typedef SharedPtr DelegatePtr; typedef std::vector Delegates; typedef typename Delegates::iterator Iterator; @@ -137,17 +156,20 @@ public: } } - void add(const TDelegate& delegate) + DelegateHandle add(const TDelegate& delegate) { for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) { if ((*it)->priority() > delegate.priority()) { - _delegates.insert(it, DelegatePtr(static_cast(delegate.clone()))); - return; + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.insert(it, pDelegate); + return pDelegate.get(); } } - _delegates.push_back(DelegatePtr(static_cast(delegate.clone()))); + DelegatePtr pDelegate(static_cast(delegate.clone())); + _delegates.push_back(pDelegate); + return pDelegate.get(); } void remove(const TDelegate& delegate) @@ -163,6 +185,19 @@ public: } } + void remove(DelegateHandle delegateHandle) + { + for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) + { + if (*it == delegateHandle) + { + (*it)->disable(); + _delegates.erase(it); + return; + } + } + } + PriorityStrategy& operator = (const PriorityStrategy& s) { if (this != &s) @@ -189,6 +224,8 @@ public: protected: Delegates _delegates; }; + + } // namespace Poco diff --git a/Zip/testsuite/test.dat b/Zip/testsuite/test.dat index e2897f381..ef1683290 100644 --- a/Zip/testsuite/test.dat +++ b/Zip/testsuite/test.dat @@ -1,49 +1,49 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae arcu -ac arcu semper mollis. Donec lobortis mi at dui. Integer placerat, -sapien at suscipit faucibus, mi quam sodales sapien, non accumsan enim -justo sit amet sem. Proin fermentum dui vitae metus. Donec a velit et -lectus fermentum bibendum. Donec risus magna, fermentum tempor, tempor -cursus, elementum ac, turpis. Suspendisse ultricies tincidunt quam. Nam -quis risus. Suspendisse in lacus. Vivamus et est ac nisi sollicitudin -ullamcorper. Sed vitae ligula non sem suscipit tempus. Donec tincidunt, -justo nec tristique euismod, sapien velit consequat ante, in vestibulum -dolor justo nec orci. Sed placerat eros. Suspendisse potenti. Vestibulum -eu sem at ante aliquet varius. In quis diam nec libero pretium -vestibulum. Morbi ipsum. Vivamus eros. - -Nam pellentesque ante. Donec sit amet nisl. Vestibulum blandit risus sit -amet quam facilisis mollis. Lorem ipsum dolor sit amet, consectetur -adipiscing elit. Nulla mattis orci a diam. Duis ultricies massa rhoncus -neque. Morbi hendrerit arcu vel mi. Suspendisse lorem. Pellentesque non -nunc molestie metus pretium tristique. Maecenas ante. Nunc sagittis. - -Proin ornare. Donec mi tellus, venenatis nec, ultrices ac, hendrerit in, -quam. Mauris nunc. Vivamus cursus rhoncus felis. Nunc at justo. In hac -habitasse platea dictumst. Nulla metus sapien, cursus nec, luctus eget, -malesuada sed, odio. Sed augue orci, sollicitudin id, auctor eu, -porttitor id, eros. Proin arcu dolor, iaculis quis, ullamcorper sit -amet, ullamcorper nec, ante. Sed dictum luctus est. Phasellus nibh. -Morbi fringilla magna et mi. In eleifend sem non dui luctus suscipit. -Duis dapibus. Proin molestie. Cras vel dui. - -In et orci vel erat euismod sodales. Integer porta. Vivamus congue -turpis eu eros tincidunt fermentum. Curabitur consequat ultrices mi. -Praesent sit amet ante. Proin ante. Phasellus vitae nibh. Aliquam ipsum -massa, pretium quis, mattis sed, sagittis sit amet, justo. Integer quam. -Aenean leo erat, commodo quis, elementum sit amet, placerat sed, lacus. -Nam a nunc in sapien scelerisque sodales. Phasellus luctus arcu at -nulla. Pellentesque habitant morbi tristique senectus et netus et -malesuada fames ac turpis egestas. Donec facilisis. - -Nam scelerisque lacus a eros. Praesent ac arcu et nisl eleifend commodo. -Aenean vestibulum, augue vel posuere mattis, sem massa varius mauris, -non porttitor diam felis eu libero. Suspendisse vulputate, urna quis -dictum scelerisque, risus est pharetra orci, a iaculis dui sem quis -quam. Nam imperdiet quam eget velit. Mauris dui lacus, posuere in, -cursus eget, ultrices ut, eros. Etiam eget purus. Curabitur accumsan -lacinia urna. Donec aliquet dictum erat. Nulla ac magna. Quisque -ultrices vehicula lacus. Fusce eu quam quis est mollis adipiscing. -Pellentesque non libero at eros vulputate iaculis. Praesent vitae orci -ac sapien laoreet scelerisque. Ut ut libero. Vivamus massa urna, -convallis at, laoreet a, adipiscing et, eros. Suspendisse feugiat -malesuada felis. Suspendisse a odio eget tortor tempus pretium. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae arcu +ac arcu semper mollis. Donec lobortis mi at dui. Integer placerat, +sapien at suscipit faucibus, mi quam sodales sapien, non accumsan enim +justo sit amet sem. Proin fermentum dui vitae metus. Donec a velit et +lectus fermentum bibendum. Donec risus magna, fermentum tempor, tempor +cursus, elementum ac, turpis. Suspendisse ultricies tincidunt quam. Nam +quis risus. Suspendisse in lacus. Vivamus et est ac nisi sollicitudin +ullamcorper. Sed vitae ligula non sem suscipit tempus. Donec tincidunt, +justo nec tristique euismod, sapien velit consequat ante, in vestibulum +dolor justo nec orci. Sed placerat eros. Suspendisse potenti. Vestibulum +eu sem at ante aliquet varius. In quis diam nec libero pretium +vestibulum. Morbi ipsum. Vivamus eros. + +Nam pellentesque ante. Donec sit amet nisl. Vestibulum blandit risus sit +amet quam facilisis mollis. Lorem ipsum dolor sit amet, consectetur +adipiscing elit. Nulla mattis orci a diam. Duis ultricies massa rhoncus +neque. Morbi hendrerit arcu vel mi. Suspendisse lorem. Pellentesque non +nunc molestie metus pretium tristique. Maecenas ante. Nunc sagittis. + +Proin ornare. Donec mi tellus, venenatis nec, ultrices ac, hendrerit in, +quam. Mauris nunc. Vivamus cursus rhoncus felis. Nunc at justo. In hac +habitasse platea dictumst. Nulla metus sapien, cursus nec, luctus eget, +malesuada sed, odio. Sed augue orci, sollicitudin id, auctor eu, +porttitor id, eros. Proin arcu dolor, iaculis quis, ullamcorper sit +amet, ullamcorper nec, ante. Sed dictum luctus est. Phasellus nibh. +Morbi fringilla magna et mi. In eleifend sem non dui luctus suscipit. +Duis dapibus. Proin molestie. Cras vel dui. + +In et orci vel erat euismod sodales. Integer porta. Vivamus congue +turpis eu eros tincidunt fermentum. Curabitur consequat ultrices mi. +Praesent sit amet ante. Proin ante. Phasellus vitae nibh. Aliquam ipsum +massa, pretium quis, mattis sed, sagittis sit amet, justo. Integer quam. +Aenean leo erat, commodo quis, elementum sit amet, placerat sed, lacus. +Nam a nunc in sapien scelerisque sodales. Phasellus luctus arcu at +nulla. Pellentesque habitant morbi tristique senectus et netus et +malesuada fames ac turpis egestas. Donec facilisis. + +Nam scelerisque lacus a eros. Praesent ac arcu et nisl eleifend commodo. +Aenean vestibulum, augue vel posuere mattis, sem massa varius mauris, +non porttitor diam felis eu libero. Suspendisse vulputate, urna quis +dictum scelerisque, risus est pharetra orci, a iaculis dui sem quis +quam. Nam imperdiet quam eget velit. Mauris dui lacus, posuere in, +cursus eget, ultrices ut, eros. Etiam eget purus. Curabitur accumsan +lacinia urna. Donec aliquet dictum erat. Nulla ac magna. Quisque +ultrices vehicula lacus. Fusce eu quam quis est mollis adipiscing. +Pellentesque non libero at eros vulputate iaculis. Praesent vitae orci +ac sapien laoreet scelerisque. Ut ut libero. Vivamus massa urna, +convallis at, laoreet a, adipiscing et, eros. Suspendisse feugiat +malesuada felis. Suspendisse a odio eget tortor tempus pretium.