diff --git a/CHANGELOG b/CHANGELOG index 896d80838..18e896e1d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,12 @@ This is the changelog file for the POCO C++ Libraries. -Release 1.3.3 (2008-09-29) +Release 1.3.3 (2008-09-30) ========================== - Threads now have optional user-settable stack size (if the OS supports that feature) +- Events now support simplified delegate syntax based on delegate function template. + See Poco::AbstractEvent documentation for new syntax. +- Cache supports new access expire strategy. - Upgraded to SQLite 3.6.2 - Upgraded to PCRE 7.8 - added HttpOnly support to Poco::Net::HTTPCookie @@ -908,4 +911,4 @@ building the libraries. -- -$Id: //poco/1.3/dist/CHANGELOG#30 $ +$Id: //poco/1.3/dist/CHANGELOG#31 $ diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6abe9512d..096c36a24 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,23 +1,23 @@ Guenter Obiltschnig Alex Fabijanic Peter Schojer -Claus Dabringer -Andrew Marlow -Caleb Epstein -Andrew J. P. Maclean -Paschal Mushubi -Sergey N. Yatskevich +Ferdinand Beyer Krzysztof Burghardt -David Shawley -Larry Lewis -Ryan Kraay +Claus Dabringer +Caleb Epstein Eran Hammer-Lahav -Tom Tan <> Chris Johnson Sergey Kholodilov +Ryan Kraay +Larry Lewis +Andrew J. P. Maclean +Andrew Marlow +Paschal Mushubi +Jiang Shan +David Shawley Sergey Skorokhodov -Ferdinand Beyer -Jiang +Tom Tan <> +Sergey N. Yatskevich -- $Id: //poco/1.3/dist/CONTRIBUTORS#5 $ diff --git a/Foundation/Foundation_vs71.vcproj b/Foundation/Foundation_vs71.vcproj index 828313b12..f17406ddb 100644 --- a/Foundation/Foundation_vs71.vcproj +++ b/Foundation/Foundation_vs71.vcproj @@ -3475,6 +3475,9 @@ + + @@ -3499,6 +3502,12 @@ + + + + @@ -3536,6 +3545,15 @@ + + + + + + @@ -3560,6 +3578,15 @@ + + + + + + diff --git a/Foundation/Foundation_vs80.vcproj b/Foundation/Foundation_vs80.vcproj index 2952f90f2..1700ae68f 100644 --- a/Foundation/Foundation_vs80.vcproj +++ b/Foundation/Foundation_vs80.vcproj @@ -4521,6 +4521,10 @@ RelativePath=".\include\Poco\AbstractPriorityDelegate.h" > + + @@ -4553,6 +4557,14 @@ RelativePath=".\include\Poco\FIFOStrategy.h" > + + + + @@ -4593,6 +4605,18 @@ RelativePath=".\include\Poco\AbstractStrategy.h" > + + + + + + @@ -4625,6 +4649,18 @@ RelativePath=".\include\Poco\StrategyCollection.h" > + + + + + + diff --git a/Foundation/Foundation_vs90.vcproj b/Foundation/Foundation_vs90.vcproj index ca46c63ef..9d5f4c8d7 100644 --- a/Foundation/Foundation_vs90.vcproj +++ b/Foundation/Foundation_vs90.vcproj @@ -4516,6 +4516,10 @@ RelativePath=".\include\Poco\AbstractPriorityDelegate.h" > + + @@ -4548,6 +4552,14 @@ RelativePath=".\include\Poco\FIFOStrategy.h" > + + + + @@ -4588,6 +4600,18 @@ RelativePath=".\include\Poco\AbstractStrategy.h" > + + + + + + @@ -4620,6 +4644,18 @@ RelativePath=".\include\Poco\StrategyCollection.h" > + + + + + + diff --git a/Foundation/include/Poco/AbstractDelegate.h b/Foundation/include/Poco/AbstractDelegate.h index 575cb3053..e2c2f4851 100644 --- a/Foundation/include/Poco/AbstractDelegate.h +++ b/Foundation/include/Poco/AbstractDelegate.h @@ -1,7 +1,7 @@ // // AbstractDelegate.h // -// $Id: //poco/1.3/Foundation/include/Poco/AbstractDelegate.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/AbstractDelegate.h#2 $ // // Library: Foundation // Package: Events @@ -59,7 +59,7 @@ public: poco_assert_dbg (_pTarget != 0); } - AbstractDelegate(const AbstractDelegate& del):_pTarget(del._pTarget) + AbstractDelegate(const AbstractDelegate& del): _pTarget(del._pTarget) { poco_assert_dbg (_pTarget != 0); } diff --git a/Foundation/include/Poco/AbstractEvent.h b/Foundation/include/Poco/AbstractEvent.h index 4df9ec373..738c2497a 100644 --- a/Foundation/include/Poco/AbstractEvent.h +++ b/Foundation/include/Poco/AbstractEvent.h @@ -1,7 +1,7 @@ // // AbstractEvent.h // -// $Id: //poco/1.3/Foundation/include/Poco/AbstractEvent.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/AbstractEvent.h#2 $ // // Library: Foundation // Package: Events @@ -53,7 +53,7 @@ namespace Poco { template class AbstractEvent - /// An abstractEvent is the super-class of all events. + /// An AbstractEvent is the super-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 observers /// which are registered at the event. The type of the data is specified with @@ -63,7 +63,20 @@ class AbstractEvent /// /// 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. + /// to fixed values. For most use-cases the BasicEvent template will be sufficient: + /// #include "Poco/BasicEvent.h" + /// #include "Poco/Delegate.h" + /// + /// If one requires delegates to be called in the order they registered, use FIFOEvent: + /// #include "Poco/FIFOEvent.h" + /// #include "Poco/Delegate.h" + /// + /// Both FIFOEvent and BasicEvent work with a standard delegate. They allow one object to register + /// exactly one delegate at an event. In contrast, a PriorityDelegate comes with an attached priority value + /// and allows one object to register for one priority value one delegate. 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: /// @@ -95,9 +108,13 @@ class AbstractEvent /// the Delegate template is used, in case of an PriorityEvent a PriorityDelegate is used. /// Mixing of observers, e.g. using a PriorityDelegate with a BasicEvent is not possible and /// checked for during compile time. - /// Events require the observers to follow the following method signature: + /// Events require the observers to follow one of the following method signature: /// /// 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 sent argument. To prevent that, use as template @@ -117,12 +134,13 @@ class AbstractEvent /// /// MyController::MyController() /// { - /// _data.AgeChanged += Delegate(this, &MyController::onDataChanged); + /// _data.AgeChanged += delegate(this, &MyController::onDataChanged); /// } /// - /// In some cases it might be desirable to work with automatically expiring registrations: + /// 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 += Expire(Delegate(this, &MyController::onDataChanged), 1000); + /// _data.DataChanged += delegate(this, &MyController::onDataChanged, 1000); /// /// This will add a delegate to the event which will automatically be removed in 1000 millisecs. /// @@ -131,9 +149,12 @@ class AbstractEvent /// /// MyController::~MyController() /// { - /// _data.DataChanged -= Delegate(this, &MyController::onDataChanged); + /// _data.DataChanged -= delegate(this, &MyController::onDataChanged); /// } /// + /// Working with PriorityDelegates as similar to working with BasicEvent/FIFOEvent.Instead of ''delegate'' + /// simply use ''priorityDelegate''. + /// /// For further examples refer to the event testsuites. { public: diff --git a/Foundation/include/Poco/AccessExpirationDecorator.h b/Foundation/include/Poco/AccessExpirationDecorator.h new file mode 100644 index 000000000..1cb0f016e --- /dev/null +++ b/Foundation/include/Poco/AccessExpirationDecorator.h @@ -0,0 +1,105 @@ +// +// AccessExpirationDecorator.h +// +// $Id: //poco/1.3/Foundation/include/Poco/AccessExpirationDecorator.h#1 $ +// +// Library: Foundation +// Package: Events +// Module: AccessExpirationDecorator +// +// Implementation of the AccessExpirationDecorator template. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_AccessExpirationDecorator_INCLUDED +#define Foundation_AccessExpirationDecorator_INCLUDED + + +#include "Poco/Timestamp.h" +#include "Poco/Timespan.h" + + +namespace Poco { + + +template +class AccessExpirationDecorator + /// AccessExpirationDecorator adds an expiration method to values so that they can be used + /// with the UniqueAccessExpireCache +{ +public: + AccessExpirationDecorator(): + _value(), + _span() + { + } + + AccessExpirationDecorator(const TArgs& p, const Poco::Timespan::TimeDiff& diffInMs): + /// Creates an element that will expire in diff milliseconds + _value(p), + _span(diffInMs*1000) + { + } + + AccessExpirationDecorator(const TArgs& p, const Poco::Timespan& timeSpan): + /// Creates an element that will expire after the given timeSpan + _value(p), + _span(timeSpan) + { + } + + + ~AccessExpirationDecorator() + { + } + + const Poco::Timespan& getTimeout() const + { + return _span; + } + + const TArgs& value() const + { + return _value; + } + + TArgs& value() + { + return _value; + } + +private: + TArgs _value; + Timespan _span; +}; + + +} // namespace Poco + + +#endif // Foundation_AccessExpirationDecorator_INCLUDED diff --git a/Foundation/include/Poco/AccessExpireCache.h b/Foundation/include/Poco/AccessExpireCache.h new file mode 100644 index 000000000..bc22b94d3 --- /dev/null +++ b/Foundation/include/Poco/AccessExpireCache.h @@ -0,0 +1,80 @@ +// +// AccessExpireCache.h +// +// $Id: //poco/1.3/Foundation/include/Poco/AccessExpireCache.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: AccessExpireCache +// +// Definition of the AccessExpireCache class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_AccessExpireCache_INCLUDED +#define Foundation_AccessExpireCache_INCLUDED + + +#include "Poco/AbstractCache.h" +#include "Poco/AccessExpireStrategy.h" + + +namespace Poco { + + +template +class AccessExpireCache: public AbstractCache > + /// An AccessExpireCache caches entries for a fixed time period (per default 10 minutes). + /// Entries expire when they are not accessed with get() during this time period. Each access resets + /// the start time for expiration. + /// Be careful when using an AccessExpireCache. A cache is often used + /// like cache.has(x) followed by cache.get x). Note that it could happen + /// that the "has" call works, then the current execution thread gets descheduled, time passes, + /// the entry gets invalid, thus leading to an empty SharedPtr being returned + /// when "get" is invoked. +{ +public: + AccessExpireCache(Timestamp::TimeDiff expire = 600000): + AbstractCache >(AccessExpireStrategy(expire)) + { + } + + ~AccessExpireCache() + { + } + +private: + AccessExpireCache(const AccessExpireCache& aCache); + AccessExpireCache& operator = (const AccessExpireCache& aCache); +}; + + +} // namespace Poco + + +#endif // Foundation_AccessExpireCache_INCLUDED diff --git a/Foundation/include/Poco/AccessExpireLRUCache.h b/Foundation/include/Poco/AccessExpireLRUCache.h new file mode 100644 index 000000000..e9c1c4947 --- /dev/null +++ b/Foundation/include/Poco/AccessExpireLRUCache.h @@ -0,0 +1,82 @@ +// +// AccessExpireLRUCache.h +// +// $Id: //poco/1.3/Foundation/include/Poco/AccessExpireLRUCache.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: AccessExpireLRUCache +// +// Definition of the AccessExpireLRUCache class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_AccessExpireLRUCache_INCLUDED +#define Foundation_AccessExpireLRUCache_INCLUDED + + +#include "Poco/AbstractCache.h" +#include "Poco/StrategyCollection.h" +#include "Poco/AccessExpireStrategy.h" +#include "Poco/LRUStrategy.h" + + +namespace Poco { + + +template < + class TKey, + class TValue +> +class AccessExpireLRUCache: public AbstractCache > + /// An AccessExpireLRUCache combines LRU caching and time based expire caching. + /// It cache entries for a fixed time period (per default 10 minutes) + /// but also limits the size of the cache (per default: 1024). +{ +public: + AccessExpireLRUCache(long cacheSize = 1024, Timestamp::TimeDiff expire = 600000): + AbstractCache >(StrategyCollection()) + { + this->_strategy.pushBack(new LRUStrategy(cacheSize)); + this->_strategy.pushBack(new AccessExpireStrategy(expire)); + } + + ~AccessExpireLRUCache() + { + } + +private: + AccessExpireLRUCache(const AccessExpireLRUCache& aCache); + AccessExpireLRUCache& operator = (const AccessExpireLRUCache& aCache); +}; + + +} // namespace Poco + + +#endif // Foundation_AccessExpireLRUCache_INCLUDED diff --git a/Foundation/include/Poco/AccessExpireStrategy.h b/Foundation/include/Poco/AccessExpireStrategy.h new file mode 100644 index 000000000..21190aede --- /dev/null +++ b/Foundation/include/Poco/AccessExpireStrategy.h @@ -0,0 +1,93 @@ +// +// AccessExpireStrategy.h +// +// $Id: //poco/1.3/Foundation/include/Poco/AccessExpireStrategy.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: AccessExpireStrategy +// +// Definition of the AccessExpireStrategy class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_AccessExpireStrategy_INCLUDED +#define Foundation_AccessExpireStrategy_INCLUDED + + +#include "Poco/KeyValueArgs.h" +#include "Poco/ValidArgs.h" +#include "Poco/ExpireStrategy.h" +#include "Poco/Bugcheck.h" +#include "Poco/Timestamp.h" +#include "Poco/EventArgs.h" +#include +#include + + +namespace Poco { + + +template < + class TKey, + class TValue +> +class AccessExpireStrategy: public ExpireStrategy + /// An AccessExpireStrategy implements time and access based expiration of cache entries +{ +public: + AccessExpireStrategy(Timestamp::TimeDiff expireTimeInMilliSec): ExpireStrategy(expireTimeInMilliSec) + /// Create an expire strategy. Note that the smallest allowed caching time is 25ms. + /// Anything lower than that is not useful with current operating systems. + { + } + + ~AccessExpireStrategy() + { + } + + void onGet(const void*, const TKey& key) + { + // get triggers an update to the expiration time + typename ExpireStrategy::Iterator it = this->_keys.find(key); + if (it != this->_keys.end()) + { + this->_keyIndex.erase(it->second); + Timestamp now; + typename ExpireStrategy::IndexIterator itIdx = + this->_keyIndex.insert(typename ExpireStrategy::TimeIndex::value_type(now, key)); + it->second = itIdx; + } + } +}; + + +} // namespace Poco + + +#endif // Foundation_AccessExpireStrategy_INCLUDED diff --git a/Foundation/include/Poco/BasicEvent.h b/Foundation/include/Poco/BasicEvent.h index d824b197e..691ca5490 100644 --- a/Foundation/include/Poco/BasicEvent.h +++ b/Foundation/include/Poco/BasicEvent.h @@ -1,7 +1,7 @@ // // BasicEvent.h // -// $Id: //poco/1.3/Foundation/include/Poco/BasicEvent.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/BasicEvent.h#2 $ // // Library: Foundation // Package: Events @@ -61,8 +61,8 @@ class BasicEvent: public AbstractEvent < /// For example: /// BasicEvent event; /// MyClass myObject; - /// event += Delegate(&myObject, &MyClass::myMethod1); - /// event += Delegate(&myObject, &MyClass::myMethod2); + /// event += delegate(&myObject, &MyClass::myMethod1); + /// event += delegate(&myObject, &MyClass::myMethod2); /// /// The second registration will overwrite the first one. The reason is simply that /// function pointers can only be compared by equality but not by lower than. diff --git a/Foundation/include/Poco/DefaultStrategy.h b/Foundation/include/Poco/DefaultStrategy.h index bcc3f339b..772ea9873 100644 --- a/Foundation/include/Poco/DefaultStrategy.h +++ b/Foundation/include/Poco/DefaultStrategy.h @@ -1,7 +1,7 @@ // // DefaultStrategy.h // -// $Id: //poco/1.3/Foundation/include/Poco/DefaultStrategy.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/DefaultStrategy.h#2 $ // // Library: Foundation // Package: Events @@ -143,6 +143,11 @@ public: _observers.clear(); } + bool empty() const + { + return _observers.empty(); + } + protected: Delegates _observers; }; diff --git a/Foundation/include/Poco/Delegate.h b/Foundation/include/Poco/Delegate.h index 1cb38d388..8057a4c21 100644 --- a/Foundation/include/Poco/Delegate.h +++ b/Foundation/include/Poco/Delegate.h @@ -1,7 +1,7 @@ // // Delegate.h // -// $Id: //poco/1.3/Foundation/include/Poco/Delegate.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/Delegate.h#2 $ // // Library: Foundation // Package: Events @@ -42,13 +42,14 @@ #include "Poco/Foundation.h" #include "Poco/AbstractDelegate.h" +#include "Poco/FunctionDelegate.h" #include "Poco/Expire.h" namespace Poco { -template +template class Delegate: public AbstractDelegate { public: @@ -103,6 +104,132 @@ private: }; +template +class Delegate: public AbstractDelegate +{ +public: + typedef void (TObj::*NotifyMethod)(TArgs&); + + Delegate(TObj* obj, NotifyMethod method): + AbstractDelegate(obj), + _receiverObject(obj), + _receiverMethod(method) + { + } + + Delegate(const Delegate& delegate): + AbstractDelegate(delegate), + _receiverObject(delegate._receiverObject), + _receiverMethod(delegate._receiverMethod) + { + } + + ~Delegate() + { + } + + Delegate& operator = (const Delegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverObject = delegate._receiverObject; + this->_receiverMethod = delegate._receiverMethod; + } + return *this; + } + + bool notify(const void*, TArgs& arguments) + { + (_receiverObject->*_receiverMethod)(arguments); + return true; // a "standard" delegate never expires + } + + AbstractDelegate* clone() const + { + return new Delegate(*this); + } + +protected: + TObj* _receiverObject; + NotifyMethod _receiverMethod; + +private: + Delegate(); +}; + + +template +static Delegate delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&)) +{ + return Delegate(pObj, NotifyMethod); +} + + +template +static 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) +{ + return Expire(Delegate(pObj, NotifyMethod), expireMillisecs); +} + + +template +static 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) +{ + return Expire(FunctionDelegate(NotifyMethod), expireMillisecs); +} + + +template +static Expire delegate(void (*NotifyMethod)(void*, TArgs&), Timestamp::TimeDiff expireMillisecs) +{ + return Expire(FunctionDelegate(NotifyMethod), expireMillisecs); +} + + +template +static Expire delegate(void (*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs) +{ + return Expire(FunctionDelegate( NotifyMethod), expireMillisecs); +} + + +template +static FunctionDelegate delegate(void (*NotifyMethod)(const void*, TArgs&)) +{ + return FunctionDelegate(NotifyMethod); +} + + +template +static FunctionDelegate delegate(void (*NotifyMethod)(void*, TArgs&)) +{ + return FunctionDelegate(NotifyMethod); +} + + +template +static FunctionDelegate delegate(void (*NotifyMethod)(TArgs&)) +{ + return FunctionDelegate(NotifyMethod); +} + + } // namespace Poco diff --git a/Foundation/include/Poco/ExpirationDecorator.h b/Foundation/include/Poco/ExpirationDecorator.h index 0b88b19db..9a18f96ef 100644 --- a/Foundation/include/Poco/ExpirationDecorator.h +++ b/Foundation/include/Poco/ExpirationDecorator.h @@ -1,7 +1,7 @@ // // ExpirationDecorator.h // -// $Id: //poco/1.3/Foundation/include/Poco/ExpirationDecorator.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/ExpirationDecorator.h#2 $ // // Library: Foundation // Package: Events @@ -59,13 +59,14 @@ public: { } - ExpirationDecorator(const TArgs& p, const Poco::Timespan::TimeDiff& diffInMs): + ExpirationDecorator(const TArgs& p, const Poco::Timespan::TimeDiff& diffInMs): /// Creates an element that will expire in diff milliseconds _value(p), _expiresAt() { _expiresAt += (diffInMs*1000); } + ExpirationDecorator(const TArgs& p, const Poco::Timespan& timeSpan): /// Creates an element that will expire after the given timeSpan _value(p), diff --git a/Foundation/include/Poco/Expire.h b/Foundation/include/Poco/Expire.h index a4c66d03b..f006f824e 100644 --- a/Foundation/include/Poco/Expire.h +++ b/Foundation/include/Poco/Expire.h @@ -1,7 +1,7 @@ // // Expire.h // -// $Id: //poco/1.3/Foundation/include/Poco/Expire.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/Expire.h#2 $ // // Library: Foundation // Package: Events diff --git a/Foundation/include/Poco/ExpireCache.h b/Foundation/include/Poco/ExpireCache.h index e996c87b8..03a217523 100644 --- a/Foundation/include/Poco/ExpireCache.h +++ b/Foundation/include/Poco/ExpireCache.h @@ -1,7 +1,7 @@ // // ExpireCache.h // -// $Id: //poco/1.3/Foundation/include/Poco/ExpireCache.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/ExpireCache.h#2 $ // // Library: Foundation // Package: Cache @@ -49,7 +49,11 @@ namespace Poco { template class ExpireCache: public AbstractCache > - /// An ExpireCache caches entries for a fixed time period (per default 10 minutes) + /// An ExpireCache caches entries for a fixed time period (per default 10 minutes). + /// Entries expire independently of the access pattern, i.e. after a constant time. + /// If you require your objects to expire after they were not accessed for a given time + /// period use a Poco::AccessExpireCache. + /// /// Be careful when using an ExpireCache. A cache is often used /// like cache.has(x) followed by cache.get x). Note that it could happen /// that the "has" call works, then the current execution thread gets descheduled, time passes, diff --git a/Foundation/include/Poco/ExpireStrategy.h b/Foundation/include/Poco/ExpireStrategy.h index 4c4a84d62..ff71b88df 100644 --- a/Foundation/include/Poco/ExpireStrategy.h +++ b/Foundation/include/Poco/ExpireStrategy.h @@ -1,7 +1,7 @@ // // ExpireStrategy.h // -// $Id: //poco/1.3/Foundation/include/Poco/ExpireStrategy.h#2 $ +// $Id: //poco/1.3/Foundation/include/Poco/ExpireStrategy.h#3 $ // // Library: Foundation // Package: Cache @@ -122,6 +122,8 @@ public: args.invalidate(); } } + else //not found: probably removed by onReplace + args.invalidate(); } void onReplace(const void*, std::set& elemsToRemove) diff --git a/Foundation/include/Poco/FIFOEvent.h b/Foundation/include/Poco/FIFOEvent.h index 1e7efca74..87d7d9740 100644 --- a/Foundation/include/Poco/FIFOEvent.h +++ b/Foundation/include/Poco/FIFOEvent.h @@ -1,7 +1,7 @@ // // FIFOEvent.h // -// $Id: //poco/1.3/Foundation/include/Poco/FIFOEvent.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/FIFOEvent.h#2 $ // // Library: Foundation // Package: Events @@ -64,8 +64,8 @@ class FIFOEvent: public AbstractEvent < /// For example: /// FIFOEvent tmp; /// MyClass myObject; - /// tmp += Delegate(&myObject, &MyClass::myMethod1); - /// tmp += Delegate(&myObject, &MyClass::myMethod2); + /// tmp += delegate(&myObject, &MyClass::myMethod1); + /// tmp += delegate(&myObject, &MyClass::myMethod2); /// /// The second registration will overwrite the first one. { diff --git a/Foundation/include/Poco/FIFOStrategy.h b/Foundation/include/Poco/FIFOStrategy.h index 105c825d8..d82ed73d6 100644 --- a/Foundation/include/Poco/FIFOStrategy.h +++ b/Foundation/include/Poco/FIFOStrategy.h @@ -1,7 +1,7 @@ // // FIFOStrategy.h // -// $Id: //poco/1.3/Foundation/include/Poco/FIFOStrategy.h#3 $ +// $Id: //poco/1.3/Foundation/include/Poco/FIFOStrategy.h#4 $ // // Library: Foundation // Package: Events @@ -149,6 +149,11 @@ public: _observerIndex.clear(); } + bool empty() const + { + return _observers.empty(); + } + protected: Delegates _observers; /// Stores the delegates in the order they were added. DelegateIndex _observerIndex; /// For faster lookup when add/remove is used. diff --git a/Foundation/include/Poco/FunctionDelegate.h b/Foundation/include/Poco/FunctionDelegate.h new file mode 100644 index 000000000..346bc2808 --- /dev/null +++ b/Foundation/include/Poco/FunctionDelegate.h @@ -0,0 +1,208 @@ +// +// FunctionDelegate.h +// +// $Id: //poco/1.3/Foundation/include/Poco/FunctionDelegate.h#1 $ +// +// Library: Foundation +// Package: Events +// Module: FunctionDelegate +// +// Implementation of the FunctionDelegate template. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_FunctionDelegate_INCLUDED +#define Foundation_FunctionDelegate_INCLUDED + + +#include "Poco/Foundation.h" +#include "Poco/AbstractDelegate.h" + + +namespace Poco { + + +template +class FunctionDelegate: public AbstractDelegate + /// Wraps a C style function (or a C++ static fucntion) to be used as + /// a delegate +{ +public: + typedef void (*NotifyMethod)(const void*, TArgs&); + + FunctionDelegate(NotifyMethod method): + AbstractDelegate(*reinterpret_cast(&method)), + _receiverMethod(method) + { + } + + FunctionDelegate(const FunctionDelegate& delegate): + AbstractDelegate(delegate), + _receiverMethod(delegate._receiverMethod) + { + } + + ~FunctionDelegate() + { + } + + FunctionDelegate& operator = (const FunctionDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + } + return *this; + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(sender, arguments); + return true; // a "standard" delegate never expires + } + + AbstractDelegate* clone() const + { + return new FunctionDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionDelegate(); +}; + + +template +class FunctionDelegate: public AbstractDelegate +{ +public: + typedef void (*NotifyMethod)(void*, TArgs&); + + FunctionDelegate(NotifyMethod method): + AbstractDelegate(*reinterpret_cast(&method)), + _receiverMethod(method) + { + } + + FunctionDelegate(const FunctionDelegate& delegate): + AbstractDelegate(delegate), + _receiverMethod(delegate._receiverMethod) + { + } + + ~FunctionDelegate() + { + } + + FunctionDelegate& operator = (const FunctionDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + } + return *this; + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(const_cast(sender), arguments); + return true; // a "standard" delegate never expires + } + + AbstractDelegate* clone() const + { + return new FunctionDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionDelegate(); +}; + + +template +class FunctionDelegate: public AbstractDelegate +{ +public: + typedef void (*NotifyMethod)(TArgs&); + + FunctionDelegate(NotifyMethod method): + AbstractDelegate(*reinterpret_cast(&method)), + _receiverMethod(method) + { + } + + FunctionDelegate(const FunctionDelegate& delegate): + AbstractDelegate(delegate), + _receiverMethod(delegate._receiverMethod) + { + } + + ~FunctionDelegate() + { + } + + FunctionDelegate& operator = (const FunctionDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + } + return *this; + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(arguments); + return true; // a "standard" delegate never expires + } + + AbstractDelegate* clone() const + { + return new FunctionDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionDelegate(); +}; + + +} // namespace Poco + + +#endif // Foundation_FunctionDelegate_INCLUDED diff --git a/Foundation/include/Poco/FunctionPriorityDelegate.h b/Foundation/include/Poco/FunctionPriorityDelegate.h new file mode 100644 index 000000000..62d6416fb --- /dev/null +++ b/Foundation/include/Poco/FunctionPriorityDelegate.h @@ -0,0 +1,212 @@ +// +// FunctionPriorityDelegate.h +// +// $Id: //poco/1.3/Foundation/include/Poco/FunctionPriorityDelegate.h#1 $ +// +// Library: Foundation +// Package: Events +// Module: FunctionPriorityDelegate +// +// Implementation of the FunctionPriorityDelegate template. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_FunctionPriorityDelegate_INCLUDED +#define Foundation_FunctionPriorityDelegate_INCLUDED + + +#include "Poco/Foundation.h" +#include "Poco/AbstractPriorityDelegate.h" + + +namespace Poco { + + +template +class FunctionPriorityDelegate: public AbstractPriorityDelegate + /// Wraps a C style function (or a C++ static fucntion) to be used as + /// a priority delegate +{ +public: + typedef void (*NotifyMethod)(const void*, TArgs&); + + FunctionPriorityDelegate(NotifyMethod method, int prio): + AbstractPriorityDelegate(*reinterpret_cast(&method), prio), + _receiverMethod(method) + { + } + + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): + AbstractPriorityDelegate(delegate._pTarget, delegate._priority), + _receiverMethod(delegate._receiverMethod) + { + } + + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + this->_priority = delegate._priority; + } + return *this; + } + + ~FunctionPriorityDelegate() + { + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(sender, arguments); + return true; // per default the delegate never expires + } + + AbstractPriorityDelegate* clone() const + { + return new FunctionPriorityDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionPriorityDelegate(); +}; + + +template +class FunctionPriorityDelegate: public AbstractPriorityDelegate +{ +public: + typedef void (*NotifyMethod)(void*, TArgs&); + + FunctionPriorityDelegate(NotifyMethod method, int prio): + AbstractPriorityDelegate(*reinterpret_cast(&method), prio), + _receiverMethod(method) + { + } + + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): + AbstractPriorityDelegate(delegate._pTarget, delegate._priority), + _receiverMethod(delegate._receiverMethod) + { + } + + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + this->_priority = delegate._priority; + } + return *this; + } + + ~FunctionPriorityDelegate() + { + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(const_cast(sender), arguments); + return true; // per default the delegate never expires + } + + AbstractPriorityDelegate* clone() const + { + return new FunctionPriorityDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionPriorityDelegate(); +}; + + + +template +class FunctionPriorityDelegate: public AbstractPriorityDelegate +{ +public: + typedef void (*NotifyMethod)(TArgs&); + + FunctionPriorityDelegate(NotifyMethod method, int prio): + AbstractPriorityDelegate(*reinterpret_cast(&method), prio), + _receiverMethod(method) + { + } + + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): + AbstractPriorityDelegate(delegate._pTarget, delegate._priority), + _receiverMethod(delegate._receiverMethod) + { + } + + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) + { + if (&delegate != this) + { + this->_pTarget = delegate._pTarget; + this->_receiverMethod = delegate._receiverMethod; + this->_priority = delegate._priority; + } + return *this; + } + + ~FunctionPriorityDelegate() + { + } + + bool notify(const void* sender, TArgs& arguments) + { + (*_receiverMethod)(arguments); + return true; // per default the delegate never expires + } + + AbstractPriorityDelegate* clone() const + { + return new FunctionPriorityDelegate(*this); + } + +protected: + NotifyMethod _receiverMethod; + +private: + FunctionPriorityDelegate(); +}; + + +} // namespace Poco + + +#endif // Foundation_FunctionPriorityDelegate_INCLUDED diff --git a/Foundation/include/Poco/NotificationStrategy.h b/Foundation/include/Poco/NotificationStrategy.h index 4b4dab609..c395e1b1f 100644 --- a/Foundation/include/Poco/NotificationStrategy.h +++ b/Foundation/include/Poco/NotificationStrategy.h @@ -1,7 +1,7 @@ // // NotificationStrategy.h // -// $Id: //poco/1.3/Foundation/include/Poco/NotificationStrategy.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/NotificationStrategy.h#2 $ // // Library: Foundation // Package: Events @@ -70,6 +70,9 @@ public: virtual void clear() = 0; /// Removes all delegates from the strategy. + + virtual bool empty() const = 0; + /// Returns false if the strategy contains at least one delegate. }; diff --git a/Foundation/include/Poco/PriorityDelegate.h b/Foundation/include/Poco/PriorityDelegate.h index bf34678e1..e3b73cee0 100644 --- a/Foundation/include/Poco/PriorityDelegate.h +++ b/Foundation/include/Poco/PriorityDelegate.h @@ -1,7 +1,7 @@ // // PriorityDelegate.h // -// $Id: //poco/1.3/Foundation/include/Poco/PriorityDelegate.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/PriorityDelegate.h#2 $ // // Library: Foundation // Package: Events @@ -43,12 +43,13 @@ #include "Poco/Foundation.h" #include "Poco/AbstractPriorityDelegate.h" #include "Poco/PriorityExpire.h" +#include "Poco/FunctionPriorityDelegate.h" namespace Poco { -template +template class PriorityDelegate: public AbstractPriorityDelegate { public: @@ -104,6 +105,133 @@ private: }; + +template +class PriorityDelegate: public AbstractPriorityDelegate +{ +public: + typedef void (TObj::*NotifyMethod)(TArgs&); + + PriorityDelegate(TObj* obj, NotifyMethod method, int prio): + AbstractPriorityDelegate(obj, prio), + _receiverObject(obj), + _receiverMethod(method) + { + } + + PriorityDelegate(const PriorityDelegate& delegate): + AbstractPriorityDelegate(delegate._pTarget, delegate._priority), + _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, TArgs& arguments) + { + (_receiverObject->*_receiverMethod)(arguments); + return true; // per default the delegate never expires + } + + AbstractPriorityDelegate* clone() const + { + return new PriorityDelegate(*this); + } + +protected: + TObj* _receiverObject; + NotifyMethod _receiverMethod; + +private: + PriorityDelegate(); +}; + + +template +static PriorityDelegate priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio) +{ + return PriorityDelegate(pObj, NotifyMethod, prio); +} + + +template +static PriorityDelegate priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), int prio) +{ + return PriorityDelegate(pObj, NotifyMethod, prio); +} + + +template +static PriorityExpire priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) +{ + return PriorityExpire(PriorityDelegate(pObj, NotifyMethod, prio), expireMilliSec); +} + + +template +static PriorityExpire priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) +{ + return PriorityExpire(PriorityDelegate(pObj, NotifyMethod, prio), expireMilliSec); +} + + +template +static PriorityExpire priorityDelegate(void (*NotifyMethod)(const void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) +{ + return PriorityExpire(FunctionPriorityDelegate(NotifyMethod, prio), expireMilliSec); +} + + +template +static PriorityExpire priorityDelegate(void (*NotifyMethod)(void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) +{ + return PriorityExpire(FunctionPriorityDelegate(NotifyMethod, prio), expireMilliSec); +} + + +template +static PriorityExpire priorityDelegate(void (*NotifyMethod)(TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) +{ + return PriorityExpire(FunctionPriorityDelegate(NotifyMethod, prio), expireMilliSec); +} + + +template +static FunctionPriorityDelegate priorityDelegate(void (*NotifyMethod)(const void*, TArgs&), int prio) +{ + return FunctionPriorityDelegate(NotifyMethod, prio); +} + + +template +static FunctionPriorityDelegate priorityDelegate(void (*NotifyMethod)(void*, TArgs&), int prio) +{ + return FunctionPriorityDelegate(NotifyMethod, prio); +} + + +template +static FunctionPriorityDelegate priorityDelegate(void (*NotifyMethod)(TArgs&), int prio) +{ + return FunctionPriorityDelegate(NotifyMethod, prio); +} + + } // namespace Poco diff --git a/Foundation/include/Poco/PriorityEvent.h b/Foundation/include/Poco/PriorityEvent.h index 2789b1f8e..1d042687c 100644 --- a/Foundation/include/Poco/PriorityEvent.h +++ b/Foundation/include/Poco/PriorityEvent.h @@ -1,7 +1,7 @@ // // PriorityEvent.h // -// $Id: //poco/1.3/Foundation/include/Poco/PriorityEvent.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/PriorityEvent.h#2 $ // // Library: Foundation // Package: Events @@ -66,8 +66,8 @@ class PriorityEvent: public AbstractEvent < /// in their priority value: /// PriorityEvent tmp; /// MyClass myObject; - /// tmp += PriorityDelegate(&myObject, &MyClass::myMethod1, 1); - /// tmp += PriorityDelegate(&myObject, &MyClass::myMethod2, 2); + /// tmp += priorityDelegate(&myObject, &MyClass::myMethod1, 1); + /// tmp += priorityDelegate(&myObject, &MyClass::myMethod2, 2); { public: PriorityEvent() diff --git a/Foundation/include/Poco/PriorityExpire.h b/Foundation/include/Poco/PriorityExpire.h index 31a2a9ecc..f2697dc69 100644 --- a/Foundation/include/Poco/PriorityExpire.h +++ b/Foundation/include/Poco/PriorityExpire.h @@ -1,7 +1,7 @@ // // PriorityExpire.h // -// $Id: //poco/1.3/Foundation/include/Poco/PriorityExpire.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/PriorityExpire.h#2 $ // // Library: Foundation // Package: Events diff --git a/Foundation/include/Poco/UniqueAccessExpireCache.h b/Foundation/include/Poco/UniqueAccessExpireCache.h new file mode 100644 index 000000000..ca728c2b5 --- /dev/null +++ b/Foundation/include/Poco/UniqueAccessExpireCache.h @@ -0,0 +1,90 @@ +// +// UniqueAccessExpireCache.h +// +// $Id: //poco/1.3/Foundation/include/Poco/UniqueAccessExpireCache.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: UniqueAccessExpireCache +// +// Definition of the UniqueAccessExpireCache class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_UniqueAccessExpireCache_INCLUDED +#define Foundation_UniqueAccessExpireCache_INCLUDED + + +#include "Poco/AbstractCache.h" +#include "Poco/UniqueAccessExpireStrategy.h" + + +namespace Poco { + + +template +class UniqueAccessExpireCache: public AbstractCache > + /// An UniqueAccessExpireCache caches entries for a given time span. In contrast + /// to ExpireCache which only allows to set a per cache expiration value, it allows to define + /// expiration per CacheEntry. + /// Each TValue object must thus offer the following method: + /// + /// const Poco::Timespan& getTimeout() const; + /// + /// which returns the relative timespan for how long the entry should be valid without being accessed! + /// The absolute expire timepoint is calculated as now() + getTimeout(). + /// Accessing an object will update this absolute expire timepoint. + /// You can use the Poco::AccessExpirationDecorator to add the getExpiration + /// method to values that do not have a getExpiration function. + /// + /// Be careful when using an UniqueAccessExpireCache. A cache is often used + /// like cache.has(x) followed by cache.get x). Note that it could happen + /// that the "has" call works, then the current execution thread gets descheduled, time passes, + /// the entry gets invalid, thus leading to an empty SharedPtr being returned + /// when "get" is invoked. +{ +public: + UniqueAccessExpireCache(): + AbstractCache >(UniqueAccessExpireStrategy()) + { + } + + ~UniqueAccessExpireCache() + { + } + +private: + UniqueAccessExpireCache(const UniqueAccessExpireCache& aCache); + UniqueAccessExpireCache& operator = (const UniqueAccessExpireCache& aCache); +}; + + +} // namespace Poco + + +#endif // Foundation_UniqueAccessExpireCache_INCLUDED diff --git a/Foundation/include/Poco/UniqueAccessExpireLRUCache.h b/Foundation/include/Poco/UniqueAccessExpireLRUCache.h new file mode 100644 index 000000000..b7700026a --- /dev/null +++ b/Foundation/include/Poco/UniqueAccessExpireLRUCache.h @@ -0,0 +1,91 @@ +// +// UniqueAccessExpireLRUCache.h +// +// $Id: //poco/1.3/Foundation/include/Poco/UniqueAccessExpireLRUCache.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: UniqueAccessExpireLRUCache +// +// Definition of the UniqueAccessExpireLRUCache class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_UniqueAccessExpireLRUCache_INCLUDED +#define Foundation_UniqueAccessExpireLRUCache_INCLUDED + + +#include "Poco/AbstractCache.h" +#include "Poco/StrategyCollection.h" +#include "Poco/UniqueAccessExpireStrategy.h" +#include "Poco/LRUStrategy.h" + + +namespace Poco { + + +template < + class TKey, + class TValue +> +class UniqueAccessExpireLRUCache: public AbstractCache > + /// A UniqueAccessExpireLRUCache combines LRU caching and time based per entry expire caching. + /// One can define for each cache entry a seperate timepoint + /// but also limit the size of the cache (per default: 1024). + /// Each TValue object must thus offer the following method: + /// + /// const Poco::Timespan& getTimeout() const; + /// + /// which returns the relative timespan for how long the entry should be valid without being accessed! + /// The absolute expire timepoint is calculated as now() + getTimeout(). + /// Accessing an object will update this absolute expire timepoint. + /// You can use the Poco::AccessExpirationDecorator to add the getExpiration + /// method to values that do not have a getExpiration function. +{ +public: + UniqueAccessExpireLRUCache(long cacheSize = 1024): + AbstractCache >(StrategyCollection()) + { + this->_strategy.pushBack(new LRUStrategy(cacheSize)); + this->_strategy.pushBack(new UniqueAccessExpireStrategy()); + } + + ~UniqueAccessExpireLRUCache() + { + } + +private: + UniqueAccessExpireLRUCache(const UniqueAccessExpireLRUCache& aCache); + UniqueAccessExpireLRUCache& operator = (const UniqueAccessExpireLRUCache& aCache); +}; + + +} // namespace Poco + + +#endif // Foundation_UniqueAccessExpireLRUCache_INCLUDED diff --git a/Foundation/include/Poco/UniqueAccessExpireStrategy.h b/Foundation/include/Poco/UniqueAccessExpireStrategy.h new file mode 100644 index 000000000..d72b1ac3c --- /dev/null +++ b/Foundation/include/Poco/UniqueAccessExpireStrategy.h @@ -0,0 +1,178 @@ +// +// UniqueAccessExpireStrategy.h +// +// $Id: //poco/1.3/Foundation/include/Poco/UniqueAccessExpireStrategy.h#1 $ +// +// Library: Foundation +// Package: Cache +// Module: UniqueAccessExpireStrategy +// +// Definition of the UniqueAccessExpireStrategy class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_UniqueAccessExpireStrategy_INCLUDED +#define Foundation_UniqueAccessExpireStrategy_INCLUDED + + +#include "Poco/KeyValueArgs.h" +#include "Poco/ValidArgs.h" +#include "Poco/AbstractStrategy.h" +#include "Poco/Bugcheck.h" +#include "Poco/Timestamp.h" +#include "Poco/Timespan.h" +#include "Poco/EventArgs.h" +#include "Poco/UniqueExpireStrategy.h" +#include +#include + + +namespace Poco { + + +template < + class TKey, + class TValue +> +class UniqueAccessExpireStrategy: public AbstractStrategy + /// An UniqueExpireStrategy implements time based expiration of cache entries. In contrast + /// to ExpireStrategy which only allows to set a per cache expiration value, it allows to define + /// expiration per CacheEntry. + /// Each TValue object must thus offer the following method: + /// + /// const Poco::Timestamp& getTimeout() const; + /// + /// which returns the timespan for how long an object will be valid without being accessed. +{ +public: + typedef std::pair KeyExpire; + typedef std::multimap TimeIndex; + typedef typename TimeIndex::iterator IndexIterator; + typedef typename TimeIndex::const_iterator ConstIndexIterator; + typedef std::map Keys; + typedef typename Keys::iterator Iterator; + +public: + UniqueAccessExpireStrategy() + /// Create an unique expire strategy. + { + } + + ~UniqueAccessExpireStrategy() + { + } + + void onAdd(const void*, const KeyValueArgs & args) + { + // the expire value defines how many millisecs in the future the + // value will expire, even insert negative values! + Timestamp expire; + expire += args.value().getTimeout().totalMicroseconds(); + + IndexIterator it = _keyIndex.insert(std::make_pair(expire, std::make_pair(args.key(), args.value().getTimeout()))); + std::pair stat = _keys.insert(std::make_pair(args.key(), it)); + if (!stat.second) + { + _keyIndex.erase(stat.first->second); + stat.first->second = it; + } + } + + void onRemove(const void*, const TKey& key) + { + Iterator it = _keys.find(key); + if (it != _keys.end()) + { + _keyIndex.erase(it->second); + _keys.erase(it); + } + } + + void onGet(const void*, const TKey& key) + { + // get updates the expiration time stamp + Iterator it = _keys.find(key); + if (it != _keys.end()) + { + KeyExpire ke = it->second->second; + // gen new absolute expire value + Timestamp expire; + expire += ke.second.totalMicroseconds(); + // delete old index + _keyIndex.erase(it->second); + IndexIterator itt = _keyIndex.insert(std::make_pair(expire, ke)); + // update iterator + it->second = itt; + } + } + + void onClear(const void*, const EventArgs& args) + { + _keys.clear(); + _keyIndex.clear(); + } + + void onIsValid(const void*, ValidArgs& args) + { + Iterator it = _keys.find(args.key()); + if (it != _keys.end()) + { + Timestamp now; + if (it->second->first <= now) + { + args.invalidate(); + } + } + else //not found: probably removed by onReplace + args.invalidate(); + } + + void onReplace(const void*, std::set& elemsToRemove) + { + // Note: replace only informs the cache which elements + // it would like to remove! + // it does not remove them on its own! + IndexIterator it = _keyIndex.begin(); + Timestamp now; + while (it != _keyIndex.end() && it->first < now) + { + elemsToRemove.insert(it->second.first); + ++it; + } + } + +protected: + Keys _keys; /// For faster replacement of keys, the iterator points to the _keyIndex map + TimeIndex _keyIndex; /// Maps time to key value +}; + + +} // namespace Poco + + +#endif // Foundation_UniqueAccessExpireStrategy_INCLUDED diff --git a/Foundation/include/Poco/UniqueExpireCache.h b/Foundation/include/Poco/UniqueExpireCache.h index 47afee2b3..9e13b270b 100644 --- a/Foundation/include/Poco/UniqueExpireCache.h +++ b/Foundation/include/Poco/UniqueExpireCache.h @@ -1,7 +1,7 @@ // // UniqueExpireCache.h // -// $Id: //poco/1.3/Foundation/include/Poco/UniqueExpireCache.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/UniqueExpireCache.h#2 $ // // Library: Foundation // Package: Cache @@ -57,6 +57,9 @@ class UniqueExpireCache: public AbstractCache class UniqueExpireLRUCache: public AbstractCache > /// A UniqueExpireLRUCache combines LRU caching and time based per entry expire caching. - /// Once can define for each cache entry a seperate timepoint + /// One can define for each cache entry a seperate timepoint /// but also limit the size of the cache (per default: 1024). /// Each TValue object must thus offer the following method: /// /// const Poco::Timestamp& getExpiration() const; /// /// which returns the absolute timepoint when the entry will be invalidated. + /// Accessing an object will NOT update this absolute expire timepoint. + /// You can use the Poco::ExpirationDecorator to add the getExpiration + /// method to values that do not have a getExpiration function. { public: UniqueExpireLRUCache(long cacheSize = 1024): diff --git a/Foundation/include/Poco/UniqueExpireStrategy.h b/Foundation/include/Poco/UniqueExpireStrategy.h index 296496039..cdbd86b81 100644 --- a/Foundation/include/Poco/UniqueExpireStrategy.h +++ b/Foundation/include/Poco/UniqueExpireStrategy.h @@ -1,7 +1,7 @@ // // UniqueExpireStrategy.h // -// $Id: //poco/1.3/Foundation/include/Poco/UniqueExpireStrategy.h#1 $ +// $Id: //poco/1.3/Foundation/include/Poco/UniqueExpireStrategy.h#2 $ // // Library: Foundation // Package: Cache @@ -130,6 +130,8 @@ public: args.invalidate(); } } + else //not found: probably removed by onReplace + args.invalidate(); } void onReplace(const void*, std::set& elemsToRemove) @@ -146,7 +148,7 @@ public: } } -private: +protected: Keys _keys; /// For faster replacement of keys, the iterator points to the _keyIndex map TimeIndex _keyIndex; /// Maps time to key value }; diff --git a/Foundation/src/TemporaryFile.cpp b/Foundation/src/TemporaryFile.cpp index e7e19c724..d9172e0ef 100644 --- a/Foundation/src/TemporaryFile.cpp +++ b/Foundation/src/TemporaryFile.cpp @@ -1,7 +1,7 @@ // // TemporaryFile.cpp // -// $Id: //poco/1.3/Foundation/src/TemporaryFile.cpp#1 $ +// $Id: //poco/1.3/Foundation/src/TemporaryFile.cpp#2 $ // // Library: Foundation // Package: Filesystem @@ -93,7 +93,8 @@ TemporaryFile::~TemporaryFile() { try { - remove(true); + if (exists()) + remove(true); } catch (Exception&) { diff --git a/Foundation/testsuite/src/BasicEventTest.cpp b/Foundation/testsuite/src/BasicEventTest.cpp index 328e71655..407742bca 100644 --- a/Foundation/testsuite/src/BasicEventTest.cpp +++ b/Foundation/testsuite/src/BasicEventTest.cpp @@ -1,7 +1,7 @@ // // BasicEventTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/BasicEventTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/BasicEventTest.cpp#2 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -34,8 +34,9 @@ #include "DummyDelegate.h" #include "CppUnit/TestCaller.h" #include "CppUnit/TestSuite.h" -#include "Poco/Delegate.h" #include "Poco/Expire.h" +#include "Poco/Delegate.h" +#include "Poco/FunctionDelegate.h" #include "Poco/Thread.h" #include "Poco/Exception.h" @@ -64,38 +65,52 @@ void BasicEventTest::testNoDelegate() Simple.notify(this, tmp); assert (_count == 0); - Simple += Delegate(this, &BasicEventTest::onSimple); - Simple -= Delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); + Simple -= delegate(this, &BasicEventTest::onSimple); + Simple.notify(this, tmp); + assert (_count == 0); + + Simple += delegate(this, &BasicEventTest::onSimpleNoSender); + Simple -= delegate(this, &BasicEventTest::onSimpleNoSender); Simple.notify(this, tmp); assert (_count == 0); - ConstSimple += Delegate(this, &BasicEventTest::onConstSimple); - ConstSimple -= Delegate(this, &BasicEventTest::onConstSimple); + ConstSimple += delegate(this, &BasicEventTest::onConstSimple); + ConstSimple -= delegate(this, &BasicEventTest::onConstSimple); ConstSimple.notify(this, tmp); assert (_count == 0); //Note: passing &args will not work due to & EventArgs* pArgs = &args; - Complex += Delegate(this, &BasicEventTest::onComplex); - Complex -= Delegate(this, &BasicEventTest::onComplex); + Complex += delegate(this, &BasicEventTest::onComplex); + Complex -= delegate(this, &BasicEventTest::onComplex); Complex.notify(this, pArgs); assert (_count == 0); - Complex2 += Delegate(this, &BasicEventTest::onComplex2); - Complex2 -= Delegate(this, &BasicEventTest::onComplex2); + Complex2 += delegate(this, &BasicEventTest::onComplex2); + Complex2 -= delegate(this, &BasicEventTest::onComplex2); Complex2.notify(this, args); assert (_count == 0); const EventArgs* pCArgs = &args; - ConstComplex += Delegate(this, &BasicEventTest::onConstComplex); - ConstComplex -= Delegate(this, &BasicEventTest::onConstComplex); + ConstComplex += delegate(this, &BasicEventTest::onConstComplex); + ConstComplex -= delegate(this, &BasicEventTest::onConstComplex); ConstComplex.notify(this, pCArgs); assert (_count == 0); - Const2Complex += Delegate(this, &BasicEventTest::onConst2Complex); - Const2Complex -= Delegate(this, &BasicEventTest::onConst2Complex); + Const2Complex += delegate(this, &BasicEventTest::onConst2Complex); + Const2Complex -= delegate(this, &BasicEventTest::onConst2Complex); Const2Complex.notify(this, pArgs); assert (_count == 0); + + Simple += delegate(&BasicEventTest::onStaticSimple); + Simple += delegate(&BasicEventTest::onStaticSimple); + Simple += delegate(&BasicEventTest::onStaticSimple2); + Simple += delegate(&BasicEventTest::onStaticSimple3); + + Simple.notify(this, tmp); + assert (_count == 2); + Simple -= delegate(BasicEventTest::onStaticSimple); } void BasicEventTest::testSingleDelegate() @@ -105,29 +120,29 @@ void BasicEventTest::testSingleDelegate() assert (_count == 0); - Simple += Delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - ConstSimple += Delegate(this, &BasicEventTest::onConstSimple); + ConstSimple += delegate(this, &BasicEventTest::onConstSimple); ConstSimple.notify(this, tmp); assert (_count == 2); EventArgs* pArgs = &args; - Complex += Delegate(this, &BasicEventTest::onComplex); + Complex += delegate(this, &BasicEventTest::onComplex); Complex.notify(this, pArgs); assert (_count == 3); - Complex2 += Delegate(this, &BasicEventTest::onComplex2); + Complex2 += delegate(this, &BasicEventTest::onComplex2); Complex2.notify(this, args); assert (_count == 4); const EventArgs* pCArgs = &args; - ConstComplex += Delegate(this, &BasicEventTest::onConstComplex); + ConstComplex += delegate(this, &BasicEventTest::onConstComplex); ConstComplex.notify(this, pCArgs); assert (_count == 5); - Const2Complex += Delegate(this, &BasicEventTest::onConst2Complex); + Const2Complex += delegate(this, &BasicEventTest::onConst2Complex); Const2Complex.notify(this, pArgs); assert (_count == 6); // check if 2nd notify also works @@ -142,11 +157,11 @@ void BasicEventTest::testDuplicateRegister() assert (_count == 0); - Simple += Delegate(this, &BasicEventTest::onSimple); - Simple += Delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &BasicEventTest::onSimple); + Simple -= delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); } @@ -158,19 +173,19 @@ void BasicEventTest::testDuplicateUnregister() assert (_count == 0); - Simple -= Delegate(this, &BasicEventTest::onSimple); // should work + Simple -= delegate(this, &BasicEventTest::onSimple); // should work Simple.notify(this, tmp); assert (_count == 0); - Simple += Delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &BasicEventTest::onSimple); + Simple -= delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &BasicEventTest::onSimple); + Simple -= delegate(this, &BasicEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); } @@ -181,7 +196,7 @@ void BasicEventTest::testDisabling() assert (_count == 0); - Simple += Delegate(this, &BasicEventTest::onSimple); + Simple += delegate(this, &BasicEventTest::onSimple); Simple.disable(); Simple.notify(this, tmp); assert (_count == 0); @@ -191,7 +206,7 @@ void BasicEventTest::testDisabling() // unregister should also work with disabled event Simple.disable(); - Simple -= Delegate(this, &BasicEventTest::onSimple); + Simple -= delegate(this, &BasicEventTest::onSimple); Simple.enable(); Simple.notify(this, tmp); assert (_count == 1); @@ -203,12 +218,22 @@ void BasicEventTest::testExpire() assert (_count == 0); - Simple += Expire(Delegate(this, &BasicEventTest::onSimple), 500); + Simple += delegate(this, &BasicEventTest::onSimple, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(700); Simple.notify(this, tmp); assert (_count == 1); + + Simple += delegate(&BasicEventTest::onStaticSimple, 400); + Simple += delegate(&BasicEventTest::onStaticSimple, 400); + Simple += delegate(&BasicEventTest::onStaticSimple2, 400); + Simple += delegate(&BasicEventTest::onStaticSimple3, 400); + Simple.notify(this, tmp); + assert (_count == 3); + Poco::Thread::sleep(700); + Simple.notify(this, tmp); + assert (_count == 3); } void BasicEventTest::testExpireReRegister() @@ -217,14 +242,14 @@ void BasicEventTest::testExpireReRegister() assert (_count == 0); - Simple += Expire(Delegate(this, &BasicEventTest::onSimple), 500); + Simple += delegate(this, &BasicEventTest::onSimple, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(200); Simple.notify(this, tmp); assert (_count == 2); // renew registration - Simple += Expire(Delegate(this, &BasicEventTest::onSimple), 600); + Simple += delegate(this, &BasicEventTest::onSimple, 600); Poco::Thread::sleep(400); Simple.notify(this, tmp); assert (_count == 3); @@ -236,7 +261,7 @@ void BasicEventTest::testExpireReRegister() void BasicEventTest::testReturnParams() { DummyDelegate o1; - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o1, &DummyDelegate::onSimple); int tmp = 0; Simple.notify(this, tmp); @@ -246,15 +271,15 @@ void BasicEventTest::testReturnParams() void BasicEventTest::testOverwriteDelegate() { DummyDelegate o1; - Simple += Delegate(&o1, &DummyDelegate::onSimple2); + Simple += delegate(&o1, &DummyDelegate::onSimple2); // o1 can only have one entry, thus the next line will replace the entry - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o1, &DummyDelegate::onSimple); int tmp = 0; // onsimple requires 0 as input Simple.notify(this, tmp); assert (tmp == 1); // now overwrite with onsimple2 with requires as input tmp = 1 - Simple += Expire(Delegate(&o1, &DummyDelegate::onSimple2), 23000); + Simple += delegate(&o1, &DummyDelegate::onSimple2, 23000); Simple.notify(this, tmp); assert (tmp == 2); } @@ -262,7 +287,7 @@ void BasicEventTest::testOverwriteDelegate() void BasicEventTest::testAsyncNotify() { Poco::BasicEvent* pSimple= new Poco::BasicEvent(); - (*pSimple) += Delegate(this, &BasicEventTest::onAsync); + (*pSimple) += delegate(this, &BasicEventTest::onAsync); assert (_count == 0); int tmp = 0; Poco::ActiveResultretArg = pSimple->notifyAsync(this, tmp); @@ -274,11 +299,38 @@ void BasicEventTest::testAsyncNotify() assert (_count == LARGEINC); } + +void BasicEventTest::onSimpleNoSender(int& i) +{ + _count++; +} + + void BasicEventTest::onSimple(const void* pSender, int& i) { _count++; } + +void BasicEventTest::onStaticSimple(const void* pSender, int& i) +{ + BasicEventTest* p = const_cast(reinterpret_cast(pSender)); + p->_count++; +} + + +void BasicEventTest::onStaticSimple2(void* pSender, int& i) +{ + BasicEventTest* p = reinterpret_cast(pSender); + p->_count++; +} + + +void BasicEventTest::onStaticSimple3(int& i) +{ +} + + void BasicEventTest::onSimpleOther(const void* pSender, int& i) { _count+=100; diff --git a/Foundation/testsuite/src/BasicEventTest.h b/Foundation/testsuite/src/BasicEventTest.h index 4e0a94d4a..60b19607f 100644 --- a/Foundation/testsuite/src/BasicEventTest.h +++ b/Foundation/testsuite/src/BasicEventTest.h @@ -1,7 +1,7 @@ // // BasicEventTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/BasicEventTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/BasicEventTest.h#2 $ // // Tests for BasicEvent // @@ -71,6 +71,10 @@ public: protected: + static void onStaticSimple(const void* pSender, int& i); + static void onStaticSimple2(void* pSender, int& i); + static void onStaticSimple3(int& i); + void onSimpleNoSender(int& i); void onSimple(const void* pSender, int& i); void onSimpleOther(const void* pSender, int& i); void onConstSimple(const void* pSender, const int& i); diff --git a/Foundation/testsuite/src/ExpireCacheTest.cpp b/Foundation/testsuite/src/ExpireCacheTest.cpp index 636dbfbf2..456a1997a 100644 --- a/Foundation/testsuite/src/ExpireCacheTest.cpp +++ b/Foundation/testsuite/src/ExpireCacheTest.cpp @@ -1,7 +1,7 @@ // // ExpireCacheTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/ExpireCacheTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/ExpireCacheTest.cpp#2 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -35,6 +35,7 @@ #include "CppUnit/TestSuite.h" #include "Poco/Exception.h" #include "Poco/ExpireCache.h" +#include "Poco/AccessExpireCache.h" #include "Poco/Bugcheck.h" #include "Poco/Thread.h" @@ -155,6 +156,59 @@ void ExpireCacheTest::testDuplicateAdd() } + +void ExpireCacheTest::testAccessExpireN() +{ + // 3-1 represents the cache sorted by age, elements get replaced at the end of the list + // 3-1|5 -> 5 gets removed + AccessExpireCache aCache(DURSLEEP); + aCache.add(1, 2); // 1 + assert (aCache.has(1)); + SharedPtr tmp = aCache.get(1); + assert (!tmp.isNull()); + assert (*tmp == 2); + assert (aCache.size() == 1); + Thread::sleep(DURWAIT); + assert (aCache.size() == 0); + assert (!aCache.has(1)); + + // tmp must still be valid, access it + assert (*tmp == 2); + tmp = aCache.get(1); + assert (!tmp); + + aCache.add(1, 2); // 1 + Thread::sleep(DURHALFSLEEP); + aCache.add(3, 4); // 3-1 + assert (aCache.has(1)); + assert (aCache.has(3)); + + Thread::sleep(DURHALFSLEEP+50); //3|1 + assert (!aCache.has(1)); + assert (*aCache.get(3) == 4); + Thread::sleep(DURHALFSLEEP+25); //3|1 + assert (*aCache.get(3) == 4); + // removing illegal entries should work too + aCache.remove(666); + + aCache.clear(); + assert (!aCache.has(5)); + assert (!aCache.has(3)); +} + + +void ExpireCacheTest::testExpireWithHas() +{ + // 3-1 represents the cache sorted by age, elements get replaced at the end of the list + // 3-1|5 -> 5 gets removed + ExpireCache aCache(DURSLEEP); + aCache.add(1, 2); // 1 + assert (aCache.has(1)); + Thread::sleep(DURWAIT); + assert (!aCache.has(1)); +} + + void ExpireCacheTest::setUp() { } @@ -173,6 +227,8 @@ CppUnit::Test* ExpireCacheTest::suite() CppUnit_addTest(pSuite, ExpireCacheTest, testExpire0); CppUnit_addTest(pSuite, ExpireCacheTest, testExpireN); CppUnit_addTest(pSuite, ExpireCacheTest, testDuplicateAdd); + CppUnit_addTest(pSuite, ExpireCacheTest, testAccessExpireN); + CppUnit_addTest(pSuite, ExpireCacheTest, testExpireWithHas); return pSuite; } diff --git a/Foundation/testsuite/src/ExpireCacheTest.h b/Foundation/testsuite/src/ExpireCacheTest.h index c3243d017..f73eae23e 100644 --- a/Foundation/testsuite/src/ExpireCacheTest.h +++ b/Foundation/testsuite/src/ExpireCacheTest.h @@ -1,7 +1,7 @@ // // ExpireCacheTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/ExpireCacheTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/ExpireCacheTest.h#2 $ // // Tests for ExpireCache // @@ -49,6 +49,8 @@ public: void testDuplicateAdd(); void testExpire0(); void testExpireN(); + void testAccessExpireN(); + void testExpireWithHas(); void setUp(); diff --git a/Foundation/testsuite/src/ExpireLRUCacheTest.cpp b/Foundation/testsuite/src/ExpireLRUCacheTest.cpp index f95b3fad1..bec2e3ae2 100644 --- a/Foundation/testsuite/src/ExpireLRUCacheTest.cpp +++ b/Foundation/testsuite/src/ExpireLRUCacheTest.cpp @@ -1,7 +1,7 @@ // // ExpireLRUCacheTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/ExpireLRUCacheTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/ExpireLRUCacheTest.cpp#2 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -35,6 +35,7 @@ #include "CppUnit/TestSuite.h" #include "Poco/Exception.h" #include "Poco/ExpireLRUCache.h" +#include "Poco/AccessExpireLRUCache.h" #include "Poco/Bugcheck.h" #include "Poco/Thread.h" @@ -141,6 +142,46 @@ void ExpireLRUCacheTest::testExpireN() } +void ExpireLRUCacheTest::testAccessExpireN() +{ + // 3-1 represents the cache sorted by age, elements get replaced at the end of the list + // 3-1|5 -> 5 gets removed + AccessExpireLRUCache aCache(3, DURSLEEP); + aCache.add(1, 2); // 1 + assert (aCache.has(1)); + SharedPtr tmp = aCache.get(1); + assert (!tmp.isNull()); + assert (*tmp == 2); + assert (aCache.size() == 1); + Thread::sleep(DURWAIT); + assert (aCache.size() == 0); + assert (!aCache.has(1)); + + // tmp must still be valid, access it + assert (*tmp == 2); + tmp = aCache.get(1); + assert (!tmp); + + aCache.add(1, 2); // 1 + Thread::sleep(DURHALFSLEEP); + aCache.add(3, 4); // 3-1 + assert (aCache.has(1)); + assert (aCache.has(3)); + + Thread::sleep(DURHALFSLEEP+50); //3|1 + assert (!aCache.has(1)); + assert (*aCache.get(3) == 4); + Thread::sleep(DURHALFSLEEP+25); //3|1 + assert (*aCache.get(3) == 4); + // removing illegal entries should work too + aCache.remove(666); + + aCache.clear(); + assert (!aCache.has(5)); + assert (!aCache.has(3)); +} + + void ExpireLRUCacheTest::testCacheSize0() { // cache size 0 is illegal @@ -301,6 +342,7 @@ CppUnit::Test* ExpireLRUCacheTest::suite() CppUnit_addTest(pSuite, ExpireLRUCacheTest, testClear); CppUnit_addTest(pSuite, ExpireLRUCacheTest, testExpire0); CppUnit_addTest(pSuite, ExpireLRUCacheTest, testExpireN); + CppUnit_addTest(pSuite, ExpireLRUCacheTest, testAccessExpireN); CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize0); CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize1); CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize2); diff --git a/Foundation/testsuite/src/ExpireLRUCacheTest.h b/Foundation/testsuite/src/ExpireLRUCacheTest.h index f9c866f47..0cf539d50 100644 --- a/Foundation/testsuite/src/ExpireLRUCacheTest.h +++ b/Foundation/testsuite/src/ExpireLRUCacheTest.h @@ -1,7 +1,7 @@ // // ExpireLRUCacheTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/ExpireLRUCacheTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/ExpireLRUCacheTest.h#2 $ // // Tests for ExpireLRUCache // @@ -48,6 +48,7 @@ public: void testClear(); void testExpire0(); void testExpireN(); + void testAccessExpireN(); void testCacheSize0(); void testCacheSize1(); void testCacheSize2(); diff --git a/Foundation/testsuite/src/FIFOEventTest.cpp b/Foundation/testsuite/src/FIFOEventTest.cpp index 9ea7a86b4..6cd9cb72f 100644 --- a/Foundation/testsuite/src/FIFOEventTest.cpp +++ b/Foundation/testsuite/src/FIFOEventTest.cpp @@ -1,7 +1,7 @@ // // FIFOEventTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/FIFOEventTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/FIFOEventTest.cpp#2 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -64,36 +64,36 @@ void FIFOEventTest::testNoDelegate() Simple.notify(this, tmp); assert (_count == 0); - Simple += Delegate(this, &FIFOEventTest::onSimple); - Simple -= Delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); + Simple -= delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 0); - ConstSimple += Delegate(this, &FIFOEventTest::onConstSimple); - ConstSimple -= Delegate(this, &FIFOEventTest::onConstSimple); + ConstSimple += delegate(this, &FIFOEventTest::onConstSimple); + ConstSimple -= delegate(this, &FIFOEventTest::onConstSimple); ConstSimple.notify(this, tmp); assert (_count == 0); //Note: passing &args will not work due to & EventArgs* pArgs = &args; - Complex += Delegate(this, &FIFOEventTest::onComplex); - Complex -= Delegate(this, &FIFOEventTest::onComplex); + Complex += delegate(this, &FIFOEventTest::onComplex); + Complex -= delegate(this, &FIFOEventTest::onComplex); Complex.notify(this, pArgs); assert (_count == 0); - Complex2 += Delegate(this, &FIFOEventTest::onComplex2); - Complex2 -= Delegate(this, &FIFOEventTest::onComplex2); + Complex2 += delegate(this, &FIFOEventTest::onComplex2); + Complex2 -= delegate(this, &FIFOEventTest::onComplex2); Complex2.notify(this, args); assert (_count == 0); const EventArgs* pCArgs = &args; - ConstComplex += Delegate(this, &FIFOEventTest::onConstComplex); - ConstComplex -= Delegate(this, &FIFOEventTest::onConstComplex); + ConstComplex += delegate(this, &FIFOEventTest::onConstComplex); + ConstComplex -= delegate(this, &FIFOEventTest::onConstComplex); ConstComplex.notify(this, pCArgs); assert (_count == 0); - Const2Complex += Delegate(this, &FIFOEventTest::onConst2Complex); - Const2Complex -= Delegate(this, &FIFOEventTest::onConst2Complex); + Const2Complex += delegate(this, &FIFOEventTest::onConst2Complex); + Const2Complex -= delegate(this, &FIFOEventTest::onConst2Complex); Const2Complex.notify(this, pArgs); assert (_count == 0); } @@ -105,29 +105,29 @@ void FIFOEventTest::testSingleDelegate() assert (_count == 0); - Simple += Delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - ConstSimple += Delegate(this, &FIFOEventTest::onConstSimple); + ConstSimple += delegate(this, &FIFOEventTest::onConstSimple); ConstSimple.notify(this, tmp); assert (_count == 2); EventArgs* pArgs = &args; - Complex += Delegate(this, &FIFOEventTest::onComplex); + Complex += delegate(this, &FIFOEventTest::onComplex); Complex.notify(this, pArgs); assert (_count == 3); - Complex2 += Delegate(this, &FIFOEventTest::onComplex2); + Complex2 += delegate(this, &FIFOEventTest::onComplex2); Complex2.notify(this, args); assert (_count == 4); const EventArgs* pCArgs = &args; - ConstComplex += Delegate(this, &FIFOEventTest::onConstComplex); + ConstComplex += delegate(this, &FIFOEventTest::onConstComplex); ConstComplex.notify(this, pCArgs); assert (_count == 5); - Const2Complex += Delegate(this, &FIFOEventTest::onConst2Complex); + Const2Complex += delegate(this, &FIFOEventTest::onConst2Complex); Const2Complex.notify(this, pArgs); assert (_count == 6); // check if 2nd notify also works @@ -142,11 +142,11 @@ void FIFOEventTest::testDuplicateRegister() assert (_count == 0); - Simple += Delegate(this, &FIFOEventTest::onSimple); - Simple += Delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &FIFOEventTest::onSimple); + Simple -= delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); } @@ -158,19 +158,19 @@ void FIFOEventTest::testDuplicateUnregister() assert (_count == 0); - Simple -= Delegate(this, &FIFOEventTest::onSimple); // should work + Simple -= delegate(this, &FIFOEventTest::onSimple); // should work Simple.notify(this, tmp); assert (_count == 0); - Simple += Delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &FIFOEventTest::onSimple); + Simple -= delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); - Simple -= Delegate(this, &FIFOEventTest::onSimple); + Simple -= delegate(this, &FIFOEventTest::onSimple); Simple.notify(this, tmp); assert (_count == 1); } @@ -182,7 +182,7 @@ void FIFOEventTest::testDisabling() assert (_count == 0); - Simple += Delegate(this, &FIFOEventTest::onSimple); + Simple += delegate(this, &FIFOEventTest::onSimple); Simple.disable(); Simple.notify(this, tmp); assert (_count == 0); @@ -192,7 +192,7 @@ void FIFOEventTest::testDisabling() // unregister should also work with disabled event Simple.disable(); - Simple -= Delegate(this, &FIFOEventTest::onSimple); + Simple -= delegate(this, &FIFOEventTest::onSimple); Simple.enable(); Simple.notify(this, tmp); assert (_count == 1); @@ -205,18 +205,18 @@ void FIFOEventTest::testFIFOOrder() assert (_count == 0); - Simple += Delegate(&o1, &DummyDelegate::onSimple); - Simple += Delegate(&o2, &DummyDelegate::onSimple2); + Simple += delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o2, &DummyDelegate::onSimple2); int tmp = 0; Simple.notify(this, tmp); assert (tmp == 2); - Simple -= Delegate(&o1, &DummyDelegate::onSimple); - Simple -= Delegate(&o2, &DummyDelegate::onSimple2); + Simple -= delegate(&o1, &DummyDelegate::onSimple); + Simple -= delegate(&o2, &DummyDelegate::onSimple2); // now try with the wrong order - Simple += Delegate(&o2, &DummyDelegate::onSimple2); - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o2, &DummyDelegate::onSimple2); + Simple += delegate(&o1, &DummyDelegate::onSimple); try { @@ -237,34 +237,34 @@ void FIFOEventTest::testFIFOOrderExpire() assert (_count == 0); - Simple += Expire(Delegate(&o1, &DummyDelegate::onSimple), 5000); - Simple += Expire(Delegate(&o2, &DummyDelegate::onSimple2), 5000); + Simple += delegate(&o1, &DummyDelegate::onSimple, 5000); + Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); int tmp = 0; Simple.notify(this, tmp); assert (tmp == 2); // both ways of unregistering should work - Simple -= Expire(Delegate(&o1, &DummyDelegate::onSimple), 6000); - Simple -= Delegate(&o2, &DummyDelegate::onSimple2); + Simple -= delegate(&o1, &DummyDelegate::onSimple, 6000); + Simple -= delegate(&o2, &DummyDelegate::onSimple2); Simple.notify(this, tmp); assert (tmp == 2); // now start mixing of expire and non expire tmp = 0; - Simple += Delegate(&o1, &DummyDelegate::onSimple); - Simple += Expire(Delegate(&o2, &DummyDelegate::onSimple2), 5000); + Simple += delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); Simple.notify(this, tmp); assert (tmp == 2); - Simple -= Delegate(&o2, &DummyDelegate::onSimple2); + Simple -= delegate(&o2, &DummyDelegate::onSimple2); // it is not forbidden to unregister a non expiring event with an expire decorator (it is just stupid ;-)) - Simple -= Expire(Delegate(&o1, &DummyDelegate::onSimple), 6000); + Simple -= delegate(&o1, &DummyDelegate::onSimple, 6000); Simple.notify(this, tmp); assert (tmp == 2); // now try with the wrong order - Simple += Expire(Delegate(&o2, &DummyDelegate::onSimple2), 5000); - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); + Simple += delegate(&o1, &DummyDelegate::onSimple); try { @@ -285,7 +285,7 @@ void FIFOEventTest::testExpire() assert (_count == 0); - Simple += Expire(Delegate(this, &FIFOEventTest::onSimple), 500); + Simple += delegate(this, &FIFOEventTest::onSimple, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(700); @@ -300,14 +300,14 @@ void FIFOEventTest::testExpireReRegister() assert (_count == 0); - Simple += Expire(Delegate(this, &FIFOEventTest::onSimple), 500); + Simple += delegate(this, &FIFOEventTest::onSimple, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(200); Simple.notify(this, tmp); assert (_count == 2); // renew registration - Simple += Expire(Delegate(this, &FIFOEventTest::onSimple), 600); + Simple += delegate(this, &FIFOEventTest::onSimple, 600); Poco::Thread::sleep(400); Simple.notify(this, tmp); assert (_count == 3); @@ -320,7 +320,7 @@ void FIFOEventTest::testExpireReRegister() void FIFOEventTest::testReturnParams() { DummyDelegate o1; - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o1, &DummyDelegate::onSimple); int tmp = 0; Simple.notify(this, tmp); @@ -330,15 +330,15 @@ void FIFOEventTest::testReturnParams() void FIFOEventTest::testOverwriteDelegate() { DummyDelegate o1; - Simple += Delegate(&o1, &DummyDelegate::onSimple2); + Simple += delegate(&o1, &DummyDelegate::onSimple2); // o1 can only have one entry, thus the next line will replace the entry - Simple += Delegate(&o1, &DummyDelegate::onSimple); + Simple += delegate(&o1, &DummyDelegate::onSimple); int tmp = 0; // onsimple requires 0 as input Simple.notify(this, tmp); assert (tmp == 1); // now overwrite with onsimple2 with requires as input tmp = 1 - Simple += Expire(Delegate(&o1, &DummyDelegate::onSimple2), 23000); + Simple += delegate(&o1, &DummyDelegate::onSimple2, 23000); Simple.notify(this, tmp); assert (tmp == 2); } @@ -346,7 +346,7 @@ void FIFOEventTest::testOverwriteDelegate() void FIFOEventTest::testAsyncNotify() { Poco::FIFOEvent* pSimple= new Poco::FIFOEvent(); - (*pSimple) += Delegate(this, &FIFOEventTest::onAsync); + (*pSimple) += delegate(this, &FIFOEventTest::onAsync); assert (_count == 0); int tmp = 0; Poco::ActiveResultretArg = pSimple->notifyAsync(this, tmp); diff --git a/Foundation/testsuite/src/FIFOEventTest.h b/Foundation/testsuite/src/FIFOEventTest.h index 27c8fc055..400870f56 100644 --- a/Foundation/testsuite/src/FIFOEventTest.h +++ b/Foundation/testsuite/src/FIFOEventTest.h @@ -1,7 +1,7 @@ // // FIFOEventTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/FIFOEventTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/FIFOEventTest.h#2 $ // // Definition of the FIFOEventTest class. // diff --git a/Foundation/testsuite/src/PriorityEventTest.cpp b/Foundation/testsuite/src/PriorityEventTest.cpp index c8d54b1fe..e5d57199b 100644 --- a/Foundation/testsuite/src/PriorityEventTest.cpp +++ b/Foundation/testsuite/src/PriorityEventTest.cpp @@ -1,7 +1,7 @@ // // PriorityEventTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/PriorityEventTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/PriorityEventTest.cpp#2 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -64,38 +64,53 @@ void PriorityEventTest::testNoDelegate() Simple.notify(this, tmp); assert (_count == 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple.notify(this, tmp); + assert (_count == 0); + + Simple += priorityDelegate(this, &PriorityEventTest::onSimpleNoSender, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimpleNoSender, 0); Simple.notify(this, tmp); assert (_count == 0); - ConstSimple += PriorityDelegate(this, &PriorityEventTest::onConstSimple, 0); - ConstSimple -= PriorityDelegate(this, &PriorityEventTest::onConstSimple, 0); + ConstSimple += priorityDelegate(this, &PriorityEventTest::onConstSimple, 0); + ConstSimple -= priorityDelegate(this, &PriorityEventTest::onConstSimple, 0); ConstSimple.notify(this, tmp); assert (_count == 0); //Note: passing &args will not work due to & EventArgs* pArgs = &args; - Complex += PriorityDelegate(this, &PriorityEventTest::onComplex, 0); - Complex -= PriorityDelegate(this, &PriorityEventTest::onComplex, 0); + Complex += priorityDelegate(this, &PriorityEventTest::onComplex, 0); + Complex -= priorityDelegate(this, &PriorityEventTest::onComplex, 0); Complex.notify(this, pArgs); assert (_count == 0); - Complex2 += PriorityDelegate(this, &PriorityEventTest::onComplex2, 0); - Complex2 -= PriorityDelegate(this, &PriorityEventTest::onComplex2, 0); + Complex2 += priorityDelegate(this, &PriorityEventTest::onComplex2, 0); + Complex2 -= priorityDelegate(this, &PriorityEventTest::onComplex2, 0); Complex2.notify(this, args); assert (_count == 0); const EventArgs* pCArgs = &args; - ConstComplex += PriorityDelegate(this, &PriorityEventTest::onConstComplex, 0); - ConstComplex -= PriorityDelegate(this, &PriorityEventTest::onConstComplex, 0); + ConstComplex += priorityDelegate(this, &PriorityEventTest::onConstComplex, 0); + ConstComplex -= priorityDelegate(this, &PriorityEventTest::onConstComplex, 0); ConstComplex.notify(this, pCArgs); assert (_count == 0); - Const2Complex += PriorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); - Const2Complex -= PriorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); + Const2Complex += priorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); + Const2Complex -= priorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); Const2Complex.notify(this, pArgs); assert (_count == 0); + + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple, 0); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple, 0); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple, 1); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple2, 2); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple3, 3); + + Simple.notify(this, tmp); + assert (_count == 3); + Simple -= priorityDelegate(PriorityEventTest::onStaticSimple, 0); } void PriorityEventTest::testSingleDelegate() @@ -105,36 +120,36 @@ void PriorityEventTest::testSingleDelegate() assert (_count == 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); // unregistering with a different priority --> different observer, is ignored - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 3); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 3); Simple.notify(this, tmp); assert (_count == 1); - ConstSimple += PriorityDelegate(this, &PriorityEventTest::onConstSimple, 0); - ConstSimple -= PriorityDelegate(this, &PriorityEventTest::onConstSimple, 3); + ConstSimple += priorityDelegate(this, &PriorityEventTest::onConstSimple, 0); + ConstSimple -= priorityDelegate(this, &PriorityEventTest::onConstSimple, 3); ConstSimple.notify(this, tmp); assert (_count == 2); EventArgs* pArgs = &args; - Complex += PriorityDelegate(this, &PriorityEventTest::onComplex, 0); - Complex -= PriorityDelegate(this, &PriorityEventTest::onComplex, 3); + Complex += priorityDelegate(this, &PriorityEventTest::onComplex, 0); + Complex -= priorityDelegate(this, &PriorityEventTest::onComplex, 3); Complex.notify(this, pArgs); assert (_count == 3); - Complex2 += PriorityDelegate(this, &PriorityEventTest::onComplex2, 0); - Complex2 -= PriorityDelegate(this, &PriorityEventTest::onComplex2, 3); + Complex2 += priorityDelegate(this, &PriorityEventTest::onComplex2, 0); + Complex2 -= priorityDelegate(this, &PriorityEventTest::onComplex2, 3); Complex2.notify(this, args); assert (_count == 4); const EventArgs* pCArgs = &args; - ConstComplex += PriorityDelegate(this, &PriorityEventTest::onConstComplex, 0); - ConstComplex -= PriorityDelegate(this, &PriorityEventTest::onConstComplex, 3); + ConstComplex += priorityDelegate(this, &PriorityEventTest::onConstComplex, 0); + ConstComplex -= priorityDelegate(this, &PriorityEventTest::onConstComplex, 3); ConstComplex.notify(this, pCArgs); assert (_count == 5); - Const2Complex += PriorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); - Const2Complex -= PriorityDelegate(this, &PriorityEventTest::onConst2Complex, 3); + Const2Complex += priorityDelegate(this, &PriorityEventTest::onConst2Complex, 0); + Const2Complex -= priorityDelegate(this, &PriorityEventTest::onConst2Complex, 3); Const2Complex.notify(this, pArgs); assert (_count == 6); // check if 2nd notify also works @@ -149,19 +164,19 @@ void PriorityEventTest::testDuplicateRegister() assert (_count == 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.notify(this, tmp); assert (_count == 1); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.notify(this, tmp); assert (_count == 1); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimpleOther, 1); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimpleOther, 1); Simple.notify(this, tmp); assert (_count == 2 + LARGEINC); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimpleOther, 1); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimpleOther, 1); Simple.notify(this, tmp); assert (_count == 3 + LARGEINC); } @@ -173,19 +188,19 @@ void PriorityEventTest::testDuplicateUnregister() assert (_count == 0); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); // should work + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); // should work Simple.notify(this, tmp); assert (_count == 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.notify(this, tmp); assert (_count == 1); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.notify(this, tmp); assert (_count == 1); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.notify(this, tmp); assert (_count == 1); } @@ -197,7 +212,7 @@ void PriorityEventTest::testDisabling() assert (_count == 0); - Simple += PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.disable(); Simple.notify(this, tmp); assert (_count == 0); @@ -207,7 +222,7 @@ void PriorityEventTest::testDisabling() // unregister should also work with disabled event Simple.disable(); - Simple -= PriorityDelegate(this, &PriorityEventTest::onSimple, 0); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 0); Simple.enable(); Simple.notify(this, tmp); assert (_count == 1); @@ -256,35 +271,35 @@ void PriorityEventTest::testPriorityOrderExpire() assert (_count == 0); - Simple += PriorityExpire(PriorityDelegate(&o2, &DummyDelegate::onSimple2, 1), 500000); - Simple += PriorityExpire(PriorityDelegate(&o1, &DummyDelegate::onSimple, 0), 500000); + Simple += priorityDelegate(&o2, &DummyDelegate::onSimple2, 1, 500000); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple, 0, 500000); int tmp = 0; Simple.notify(this, tmp); assert (tmp == 2); // both ways of unregistering should work - Simple -= PriorityExpire(PriorityDelegate(&o1, &DummyDelegate::onSimple, 0), 600000); - Simple -= PriorityDelegate(&o2, &DummyDelegate::onSimple2, 1); + Simple -= priorityDelegate(&o1, &DummyDelegate::onSimple, 0, 600000); + Simple -= priorityDelegate(&o2, &DummyDelegate::onSimple2, 1); Simple.notify(this, tmp); assert (tmp == 2); // now start mixing of expire and non expire tmp = 0; - Simple += PriorityExpire(PriorityDelegate(&o2, &DummyDelegate::onSimple2, 1), 500000); - Simple += PriorityDelegate(&o1, &DummyDelegate::onSimple, 0); + Simple += priorityDelegate(&o2, &DummyDelegate::onSimple2, 1, 500000); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple, 0); Simple.notify(this, tmp); assert (tmp == 2); - Simple -= PriorityDelegate(&o2, &DummyDelegate::onSimple2, 1); + Simple -= priorityDelegate(&o2, &DummyDelegate::onSimple2, 1); // it is not forbidden to unregister a non expiring event with an expire decorator (it is just stupid ;-)) - Simple -= PriorityExpire(PriorityDelegate(&o1, &DummyDelegate::onSimple, 0), 600000); + Simple -= priorityDelegate(&o1, &DummyDelegate::onSimple, 0, 600000); Simple.notify(this, tmp); assert (tmp == 2); // now try with the wrong order - Simple += PriorityExpire(PriorityDelegate(&o2, &DummyDelegate::onSimple2, 0), 500000); - Simple += PriorityDelegate(&o1, &DummyDelegate::onSimple, 1); + Simple += priorityDelegate(&o2, &DummyDelegate::onSimple2, 0, 500000); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple, 1); try { @@ -296,8 +311,8 @@ void PriorityEventTest::testPriorityOrderExpire() { } - Simple -= PriorityExpire(PriorityDelegate(&o2, &DummyDelegate::onSimple2, 0), 500000); - Simple -= PriorityDelegate(&o1, &DummyDelegate::onSimple, 1); + Simple -= priorityDelegate(&o2, &DummyDelegate::onSimple2, 0, 500000); + Simple -= priorityDelegate(&o1, &DummyDelegate::onSimple, 1); } @@ -307,13 +322,22 @@ void PriorityEventTest::testExpire() assert (_count == 0); - Simple += PriorityExpire(PriorityDelegate(this, &PriorityEventTest::onSimple, 1), 500); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 1, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(700); Simple.notify(this, tmp); assert (_count == 1); - Simple -= PriorityExpire(PriorityDelegate(this, &PriorityEventTest::onSimple, 1), 500); + Simple -= priorityDelegate(this, &PriorityEventTest::onSimple, 1, 500); + + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple, 1, 500); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple2, 1, 500); + Simple += priorityDelegate(&PriorityEventTest::onStaticSimple3, 1, 500); + Simple.notify(this, tmp); + assert (_count == 3); + Poco::Thread::sleep(700); + Simple.notify(this, tmp); + assert (_count == 3); } @@ -323,14 +347,14 @@ void PriorityEventTest::testExpireReRegister() assert (_count == 0); - Simple += PriorityExpire(PriorityDelegate(this, &PriorityEventTest::onSimple, 1), 500); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 1, 500); Simple.notify(this, tmp); assert (_count == 1); Poco::Thread::sleep(200); Simple.notify(this, tmp); assert (_count == 2); // renew registration - Simple += PriorityExpire(PriorityDelegate(this, &PriorityEventTest::onSimple, 1), 600); + Simple += priorityDelegate(this, &PriorityEventTest::onSimple, 1, 600); Poco::Thread::sleep(400); Simple.notify(this, tmp); assert (_count == 3); @@ -343,7 +367,7 @@ void PriorityEventTest::testExpireReRegister() void PriorityEventTest::testReturnParams() { DummyDelegate o1; - Simple += PriorityDelegate(&o1, &DummyDelegate::onSimple, 0); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple, 0); int tmp = 0; Simple.notify(this, tmp); @@ -353,24 +377,24 @@ void PriorityEventTest::testReturnParams() void PriorityEventTest::testOverwriteDelegate() { DummyDelegate o1; - Simple += PriorityDelegate(&o1, &DummyDelegate::onSimple2, 0); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple2, 0); // o1 can only have one entry per priority, thus the next line will replace the entry - Simple += PriorityDelegate(&o1, &DummyDelegate::onSimple, 0); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple, 0); int tmp = 0; // onsimple requires 0 as input Simple.notify(this, tmp); assert (tmp == 1); // now overwrite with onsimple2 with requires as input tmp = 1 - Simple += PriorityExpire(PriorityDelegate(&o1, &DummyDelegate::onSimple2, 0), 23000); + Simple += priorityDelegate(&o1, &DummyDelegate::onSimple2, 0, 23000); Simple.notify(this, tmp); assert (tmp == 2); - Simple -= PriorityExpire(PriorityDelegate(&o1, &DummyDelegate::onSimple2, 0), 23000); + Simple -= priorityDelegate(&o1, &DummyDelegate::onSimple2, 0, 23000); } void PriorityEventTest::testAsyncNotify() { Poco::PriorityEvent* pSimple= new Poco::PriorityEvent(); - (*pSimple) += PriorityDelegate(this, &PriorityEventTest::onAsync, 0); + (*pSimple) += priorityDelegate(this, &PriorityEventTest::onAsync, 0); assert (_count == 0); int tmp = 0; Poco::ActiveResultretArg = pSimple->notifyAsync(this, tmp); @@ -383,6 +407,32 @@ void PriorityEventTest::testAsyncNotify() } + +void PriorityEventTest::onStaticSimple(const void* pSender, int& i) +{ + PriorityEventTest* p = const_cast(reinterpret_cast(pSender)); + p->_count++; +} + + +void PriorityEventTest::onStaticSimple2(void* pSender, int& i) +{ + PriorityEventTest* p = reinterpret_cast(pSender); + p->_count++; +} + + +void PriorityEventTest::onStaticSimple3(int& i) +{ +} + + +void PriorityEventTest::onSimpleNoSender(int& i) +{ + _count++; +} + + void PriorityEventTest::onSimple(const void* pSender, int& i) { _count++; diff --git a/Foundation/testsuite/src/PriorityEventTest.h b/Foundation/testsuite/src/PriorityEventTest.h index a22d533cc..153e103c2 100644 --- a/Foundation/testsuite/src/PriorityEventTest.h +++ b/Foundation/testsuite/src/PriorityEventTest.h @@ -1,7 +1,7 @@ // // PriorityEventTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/PriorityEventTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/PriorityEventTest.h#2 $ // // Definition of the PriorityEventTest class. // @@ -72,7 +72,11 @@ public: static CppUnit::Test* suite(); protected: + static void onStaticSimple(const void* pSender, int& i); + static void onStaticSimple2(void* pSender, int& i); + static void onStaticSimple3(int& i); + void onSimpleNoSender(int& i); void onSimple(const void* pSender, int& i); void onSimpleOther(const void* pSender, int& i); void onConstSimple(const void* pSender, const int& i); diff --git a/Foundation/testsuite/src/UniqueExpireCacheTest.cpp b/Foundation/testsuite/src/UniqueExpireCacheTest.cpp index 7b1e9c301..aecf11baf 100644 --- a/Foundation/testsuite/src/UniqueExpireCacheTest.cpp +++ b/Foundation/testsuite/src/UniqueExpireCacheTest.cpp @@ -1,7 +1,7 @@ // // UniqueExpireCacheTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireCacheTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireCacheTest.cpp#2 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -35,7 +35,9 @@ #include "CppUnit/TestSuite.h" #include "Poco/Exception.h" #include "Poco/UniqueExpireCache.h" +#include "Poco/UniqueAccessExpireCache.h" #include "Poco/ExpirationDecorator.h" +#include "Poco/AccessExpirationDecorator.h" #include "Poco/Bugcheck.h" #include "Poco/Thread.h" @@ -58,6 +60,7 @@ struct IntVal } }; +typedef AccessExpirationDecorator DIntVal; #define DURSLEEP 250 #define DURHALFSLEEP DURSLEEP / 2 @@ -93,6 +96,52 @@ void UniqueExpireCacheTest::testClear() } +void UniqueExpireCacheTest::testAccessClear() +{ + UniqueAccessExpireCache aCache; + aCache.add(1, DIntVal(2, DURSLEEP)); + aCache.add(3, DIntVal(4, DURSLEEP)); + aCache.add(5, DIntVal(6, DURSLEEP)); + assert (aCache.has(1)); + assert (aCache.has(3)); + assert (aCache.has(5)); + assert (aCache.get(1)->value() == 2); + assert (aCache.get(3)->value() == 4); + assert (aCache.get(5)->value() == 6); + aCache.clear(); + assert (!aCache.has(1)); + assert (!aCache.has(3)); + assert (!aCache.has(5)); +} + + +void UniqueExpireCacheTest::testAccessUpdate() +{ + UniqueAccessExpireCache aCache; + aCache.add(1, DIntVal(2, DURSLEEP)); + aCache.add(3, DIntVal(4, DURSLEEP)); + aCache.add(5, DIntVal(6, DURSLEEP)); + assert (aCache.has(1)); + assert (aCache.has(3)); + assert (aCache.has(5)); + assert (aCache.get(1)->value() == 2); + Thread::sleep(DURSLEEP/2); + assert (aCache.get(1)->value() == 2); + Thread::sleep(DURSLEEP/2); + assert (aCache.get(1)->value() == 2); + Thread::sleep(DURSLEEP/2); + assert (aCache.get(1)->value() == 2); + assert (!aCache.has(3)); + assert (!aCache.has(5)); + Thread::sleep(DURSLEEP*2); + + assert (!aCache.has(1)); + assert (!aCache.has(3)); + assert (!aCache.has(5)); + aCache.remove(666); //must work too +} + + void UniqueExpireCacheTest::testExpire0() { UniqueExpireCache aCache; @@ -101,6 +150,15 @@ void UniqueExpireCacheTest::testExpire0() } + +void UniqueExpireCacheTest::testAccessExpire0() +{ + UniqueAccessExpireCache aCache; + aCache.add(1, DIntVal(2, Timespan(0, 0))); + assert (!aCache.has(1)); +} + + void UniqueExpireCacheTest::testExpireN() { // 3-1 represents the cache sorted by age, elements get replaced at the end of the list @@ -165,6 +223,18 @@ void UniqueExpireCacheTest::testDuplicateAdd() } +void UniqueExpireCacheTest::testAccessDuplicateAdd() +{ + UniqueAccessExpireCache aCache; + aCache.add(1, DIntVal(2, DURSLEEP)); // 1 + assert (aCache.has(1)); + assert (aCache.get(1)->value() == 2); + aCache.add(1, DIntVal(3, DURSLEEP)); + assert (aCache.has(1)); + assert (aCache.get(1)->value() == 3); +} + + void UniqueExpireCacheTest::testExpirationDecorator() { typedef ExpirationDecorator ExpireInt; @@ -193,9 +263,13 @@ CppUnit::Test* UniqueExpireCacheTest::suite() CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("UniqueExpireCacheTest"); CppUnit_addTest(pSuite, UniqueExpireCacheTest, testClear); + CppUnit_addTest(pSuite, UniqueExpireCacheTest, testAccessClear); + CppUnit_addTest(pSuite, UniqueExpireCacheTest, testAccessUpdate); CppUnit_addTest(pSuite, UniqueExpireCacheTest, testExpire0); + CppUnit_addTest(pSuite, UniqueExpireCacheTest, testAccessExpire0); CppUnit_addTest(pSuite, UniqueExpireCacheTest, testExpireN); CppUnit_addTest(pSuite, UniqueExpireCacheTest, testDuplicateAdd); + CppUnit_addTest(pSuite, UniqueExpireCacheTest, testAccessDuplicateAdd); CppUnit_addTest(pSuite, UniqueExpireCacheTest, testExpirationDecorator); return pSuite; diff --git a/Foundation/testsuite/src/UniqueExpireCacheTest.h b/Foundation/testsuite/src/UniqueExpireCacheTest.h index f4c156c62..3dbd1c244 100644 --- a/Foundation/testsuite/src/UniqueExpireCacheTest.h +++ b/Foundation/testsuite/src/UniqueExpireCacheTest.h @@ -1,7 +1,7 @@ // // UniqueExpireCacheTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireCacheTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireCacheTest.h#2 $ // // Tests for ExpireCache // @@ -46,11 +46,14 @@ public: ~UniqueExpireCacheTest(); void testClear(); + void testAccessClear(); void testDuplicateAdd(); + void testAccessDuplicateAdd(); void testExpire0(); + void testAccessExpire0(); void testExpireN(); void testExpirationDecorator(); - + void testAccessUpdate(); void setUp(); void tearDown(); diff --git a/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp b/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp index 6735370a1..ab10af4d1 100644 --- a/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp +++ b/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp @@ -1,7 +1,7 @@ // // UniqueExpireLRUCacheTest.cpp // -// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireLRUCacheTest.cpp#2 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -35,6 +35,8 @@ #include "CppUnit/TestSuite.h" #include "Poco/Exception.h" #include "Poco/UniqueExpireLRUCache.h" +#include "Poco/UniqueAccessExpireLRUCache.h" +#include "Poco/AccessExpirationDecorator.h" #include "Poco/Bugcheck.h" #include "Poco/Thread.h" @@ -57,6 +59,10 @@ struct IntVal } }; + +typedef AccessExpirationDecorator DIntVal; + + #define DURSLEEP 250 #define DURHALFSLEEP DURSLEEP / 2 #define DURWAIT 300 @@ -91,6 +97,25 @@ void UniqueExpireLRUCacheTest::testClear() } + +void UniqueExpireLRUCacheTest::testAccessClear() +{ + UniqueAccessExpireLRUCache aCache; + aCache.add(1, DIntVal(2, DURSLEEP)); + aCache.add(3, DIntVal(4, DURSLEEP)); + aCache.add(5, DIntVal(6, DURSLEEP)); + assert (aCache.has(1)); + assert (aCache.has(3)); + assert (aCache.has(5)); + assert (aCache.get(1)->value() == 2); + assert (aCache.get(3)->value() == 4); + assert (aCache.get(5)->value() == 6); + aCache.clear(); + assert (!aCache.has(1)); + assert (!aCache.has(3)); + assert (!aCache.has(5)); +} + void UniqueExpireLRUCacheTest::testExpire0() { UniqueExpireLRUCache aCache; @@ -309,6 +334,7 @@ CppUnit::Test* UniqueExpireLRUCacheTest::suite() CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("UniqueExpireLRUCacheTest"); CppUnit_addTest(pSuite, UniqueExpireLRUCacheTest, testClear); + CppUnit_addTest(pSuite, UniqueExpireLRUCacheTest, testAccessClear); CppUnit_addTest(pSuite, UniqueExpireLRUCacheTest, testExpire0); CppUnit_addTest(pSuite, UniqueExpireLRUCacheTest, testExpireN); CppUnit_addTest(pSuite, UniqueExpireLRUCacheTest, testCacheSize0); diff --git a/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h b/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h index 3d0a37fa8..536098d03 100644 --- a/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h +++ b/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h @@ -1,7 +1,7 @@ // // UniqueExpireLRUCacheTest.h // -// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h#1 $ +// $Id: //poco/1.3/Foundation/testsuite/src/UniqueExpireLRUCacheTest.h#2 $ // // Tests for UniqueExpireLRUCache // @@ -46,6 +46,7 @@ public: ~UniqueExpireLRUCacheTest(); void testClear(); + void testAccessClear(); void testExpire0(); void testExpireN(); void testCacheSize0(); diff --git a/VERSION b/VERSION index bf1b072d3..b7f5466ff 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.3-rc2-data (2008-09-29) +1.3.3-rc2-data (2008-09-30)