trunk: backport eventing from 1.4.3

This commit is contained in:
Marian Krivos
2012-02-05 12:16:58 +00:00
parent 59fe68edbe
commit 7d7c02c579
412 changed files with 3564 additions and 3634 deletions

View File

@@ -1,7 +1,7 @@
// //
// AbstractDelegate.h // AbstractDelegate.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/AbstractDelegate.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/AbstractDelegate.h#4 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the AbstractDelegate template. // Implementation of the AbstractDelegate template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -48,20 +48,15 @@ namespace Poco {
template <class TArgs> template <class TArgs>
class AbstractDelegate class AbstractDelegate
/// Interface for Delegate and Expire /// Base class for Delegate and Expire.
/// Very similar to AbstractPriorityDelegate but having two separate files (no inheritance)
/// allows one to have compile-time checks when registering an observer
/// instead of run-time checks.
{ {
public: public:
AbstractDelegate(void* pTarget): _pTarget(pTarget) AbstractDelegate()
{ {
poco_assert_dbg (_pTarget != 0);
} }
AbstractDelegate(const AbstractDelegate& del): _pTarget(del._pTarget) AbstractDelegate(const AbstractDelegate& del)
{ {
poco_assert_dbg (_pTarget != 0);
} }
virtual ~AbstractDelegate() virtual ~AbstractDelegate()
@@ -69,24 +64,25 @@ public:
} }
virtual bool notify(const void* sender, TArgs& arguments) = 0; virtual bool notify(const void* sender, TArgs& arguments) = 0;
/// Returns false, if the Delegate is no longer valid, thus indicating an expire. /// Invokes the delegate's callback function.
/// Returns true if successful, or false if the delegate
/// has been disabled or has expired.
virtual bool equals(const AbstractDelegate& other) const = 0;
/// Compares the AbstractDelegate with the other one for equality.
virtual AbstractDelegate* clone() const = 0; virtual AbstractDelegate* clone() const = 0;
/// Returns a deep-copy of the AbstractDelegate /// Returns a deep copy of the AbstractDelegate.
bool operator < (const AbstractDelegate<TArgs>& other) const virtual void disable() = 0;
/// For comparing AbstractDelegates in a collection. /// Disables the delegate, which is done prior to removal.
virtual const AbstractDelegate* unwrap() const
/// Returns the unwrapped delegate. Must be overridden by decorators
/// like Expire.
{ {
return _pTarget < other._pTarget; return this;
} }
void* target() const
{
return _pTarget;
}
protected:
void* _pTarget;
}; };

View File

@@ -1,7 +1,7 @@
// //
// AbstractEvent.h // AbstractEvent.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/AbstractEvent.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/AbstractEvent.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Definition of the AbstractEvent class. // Definition of the AbstractEvent class.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -53,28 +53,31 @@ namespace Poco {
template <class TArgs, class TStrategy, class TDelegate, class TMutex = FastMutex> template <class TArgs, class TStrategy, class TDelegate, class TMutex = FastMutex>
class AbstractEvent class AbstractEvent
/// An AbstractEvent is the super-class of all events. /// An AbstractEvent is the base class of all events.
/// It works similar to the way C# handles notifications (aka events in C#). /// 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 /// Events can be used to send information to a set of delegates
/// which are registered with the event. The type of the data is specified with
/// the template parameter TArgs. The TStrategy parameter must be a subclass /// the template parameter TArgs. The TStrategy parameter must be a subclass
/// of NotificationStrategy. The parameter TDelegate can either be a subclass of AbstractDelegate /// of NotificationStrategy. The parameter TDelegate can either be a subclass of AbstractDelegate
/// or of PriorityAbstractDelegate. /// or of AbstractPriorityDelegate.
/// ///
/// Note that AbstractEvent should never be used directly. One ought to use /// Note that AbstractEvent should never be used directly. One ought to use
/// one of its subclasses which set the TStrategy and TDelegate template parameters /// 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/BasicEvent.h"
/// #include "Poco/Delegate.h" /// #include "Poco/Delegate.h"
/// ///
/// If one requires delegates to be called in the order they registered, use FIFOEvent: /// Note that as of release 1.4.2, the behavior of BasicEvent equals that of FIFOEvent,
/// #include "Poco/FIFOEvent.h" /// so the FIFOEvent class is no longer necessary and provided for backwards compatibility
/// #include "Poco/Delegate.h" /// only.
/// ///
/// Both FIFOEvent and BasicEvent work with a standard delegate. They allow one object to register /// BasicEvent works 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 /// onr or more delegates with an event. In contrast, a PriorityDelegate comes with an attached priority value
/// and allows one object to register for one priority value one delegate. Note that PriorityDelegates /// and allows one object to register for one priority value one or more delegates. Note that PriorityDelegates
/// only work with PriorityEvents: /// only work with PriorityEvents:
///
/// #include "Poco/PriorityEvent.h" /// #include "Poco/PriorityEvent.h"
/// #include "Poco/PriorityDelegate.h" /// #include "Poco/PriorityDelegate.h"
/// ///
@@ -83,32 +86,43 @@ class AbstractEvent
/// class MyData /// class MyData
/// { /// {
/// public: /// public:
/// Poco::BasicEvent<int> AgeChanged; /// Poco::BasicEvent<int> dataChanged;
/// ///
/// MyData(); /// MyData();
/// ... /// ...
/// void setData(int i);
/// ...
/// private:
/// int _data;
/// }; /// };
/// ///
/// Throwing the event can be done either by the events notify() or notifyAsync() method: /// Firing the event is done either by calling the event's notify() or notifyAsync() method:
/// ///
/// void MyData::setData(int i)
/// {
/// this->_data = i;
/// dataChanged.notify(this, this->_data);
/// }
/// ///
/// Alternatively, instead of notify(), operator () can be used. /// Alternatively, instead of notify(), operator () can be used.
/// ///
/// void MyData::setAge(int i) /// void MyData::setData(int i)
/// { /// {
/// this->_age = i; /// this->_data = i;
/// AgeChanged(this, this->_age); /// dataChanged(this, this->_data);
/// } /// }
/// ///
/// Note that notify and notifyAsync do not catch exceptions, i.e. in case a delegate /// Note that operator (), notify() and notifyAsync() do not catch exceptions, i.e. in case a
/// throws an exception, the notify is immediately aborted and the exception is thrown /// delegate throws an exception, notifying is immediately aborted and the exception is propagated
/// back to the caller. /// back to the caller.
/// ///
/// Delegates can register methods at the event. In the case of a BasicEvent or FIFOEvent /// Delegates can register methods at the event. In the case of a BasicEvent
/// the Delegate template is used, in case of an PriorityEvent a PriorityDelegate is used. /// 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 /// Mixing of delegates, e.g. using a PriorityDelegate with a BasicEvent is not allowed and
/// checked for during compile time. /// can lead to compile-time and/or run-time errors. The standalone delegate() functions
/// Events require the observers to follow one of the following method signature: /// can be used to construct Delegate objects.
///
/// Events require the observers to have one of the following method signatures:
/// ///
/// void onEvent(const void* pSender, TArgs& args); /// void onEvent(const void* pSender, TArgs& args);
/// void onEvent(TArgs& args); /// void onEvent(TArgs& args);
@@ -117,7 +131,7 @@ class AbstractEvent
/// static void onEvent(TArgs& args); /// static void onEvent(TArgs& args);
/// ///
/// For performance reasons arguments are always sent by reference. This also allows observers /// For performance reasons arguments are always sent by reference. This also allows observers
/// to modify the sent argument. To prevent that, use <const TArg> as template /// to modify the event argument. To prevent that, use <[const TArg]> as template
/// parameter. A non-conformant method signature leads to compile errors. /// parameter. A non-conformant method signature leads to compile errors.
/// ///
/// Assuming that the observer meets the method signature requirement, it can register /// Assuming that the observer meets the method signature requirement, it can register
@@ -134,13 +148,13 @@ class AbstractEvent
/// ///
/// MyController::MyController() /// MyController::MyController()
/// { /// {
/// _data.AgeChanged += delegate(this, &MyController::onDataChanged); /// _data.dataChanged += delegate(this, &MyController::onDataChanged);
/// } /// }
/// ///
/// In some cases it might be desirable to work with automatically expiring registrations. Simply add /// In some cases it might be desirable to work with automatically expiring registrations. Simply add
/// to delegate as 3rd parameter a expireValue (in milliseconds): /// to delegate as 3rd parameter a expireValue (in milliseconds):
/// ///
/// _data.DataChanged += 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. /// This will add a delegate to the event which will automatically be removed in 1000 millisecs.
/// ///
@@ -149,13 +163,12 @@ class AbstractEvent
/// ///
/// MyController::~MyController() /// 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'' /// Working with PriorityDelegate's as similar to working with BasicEvent.
/// simply use ''priorityDelegate''. /// Instead of delegate(), the priorityDelegate() function must be used
/// /// to create the PriorityDelegate.
/// For further examples refer to the event testsuites.
{ {
public: public:
AbstractEvent(): AbstractEvent():
@@ -176,38 +189,45 @@ public:
} }
void operator += (const TDelegate& aDelegate) void operator += (const TDelegate& aDelegate)
/// Adds a delegate to the event. If the observer is equal to an /// Adds a delegate to the event.
/// already existing one (determined by the < operator), ///
/// it will simply replace the existing observer. /// Exact behavior is determined by the TStrategy.
/// This behavior is determined by the TStrategy. Current implementations
/// (DefaultStrategy, FIFOStrategy) follow that guideline but future ones
/// can deviate.
{ {
typename TMutex::ScopedLock lock(_mutex); typename TMutex::ScopedLock lock(_mutex);
_strategy.add(aDelegate); _strategy.add(aDelegate);
} }
void operator -= (const TDelegate& aDelegate) void operator -= (const TDelegate& aDelegate)
/// Removes a delegate from the event. If the delegate is equal to an /// Removes a delegate from the event.
/// already existing one is determined by the < operator. ///
/// If the observer is not found, the unregister will be ignored /// If the delegate is not found, this function does nothing.
{ {
typename TMutex::ScopedLock lock(_mutex); typename TMutex::ScopedLock lock(_mutex);
_strategy.remove(aDelegate); _strategy.remove(aDelegate);
} }
void operator () (const void* pSender, TArgs& args) void operator () (const void* pSender, TArgs& args)
/// Shortcut for notify(pSender, args);
{ {
notify(pSender, args); notify(pSender, args);
} }
void operator () (TArgs& args)
/// Shortcut for notify(args).
{
notify(0, args);
}
void notify(const void* pSender, TArgs& args) void notify(const void* pSender, TArgs& args)
/// Sends a notification to all registered delegates. The order is /// Sends a notification to all registered delegates. The order is
/// determined by the TStrategy. This method is blocking. While executing, /// determined by the TStrategy. This method is blocking. While executing,
/// other objects can change the list of delegates. These changes don't /// the list of delegates may be modified. These changes don't
/// influence the current active notifications but are activated with /// influence the current active notifications but are activated with
/// the next notify. If one of the delegates throws an exception, the notify /// the next notify. If a delegate is removed during a notify(), the
/// method is immediately aborted and the exception is reported to the caller. /// delegate will no longer be invoked (unless it has already been
/// invoked prior to removal). If one of the delegates throws an exception,
/// the notify method is immediately aborted and the exception is propagated
/// to the caller.
{ {
Poco::ScopedLockWithUnlock<TMutex> lock(_mutex); Poco::ScopedLockWithUnlock<TMutex> lock(_mutex);
@@ -228,11 +248,12 @@ public:
/// Call activeResult.wait() to wait until the notification has ended. /// Call activeResult.wait() to wait until the notification has ended.
/// While executing, other objects can change the delegate list. These changes don't /// While executing, other objects can change the delegate list. These changes don't
/// influence the current active notifications but are activated with /// influence the current active notifications but are activated with
/// the next notify. If one of the delegates throws an exception, the execution /// the next notify. If a delegate is removed during a notify(), the
/// is aborted and the exception is reported to the caller. /// delegate will no longer be invoked (unless it has already been
/// invoked prior to removal). If one of the delegates throws an exception,
/// the execution is aborted and the exception is propagated to the caller.
{ {
NotifyAsyncParams params(pSender, args); NotifyAsyncParams params(pSender, args);
{ {
typename TMutex::ScopedLock lock(_mutex); typename TMutex::ScopedLock lock(_mutex);
@@ -245,7 +266,6 @@ public:
params.ptrStrat = SharedPtr<TStrategy>(new TStrategy(_strategy)); params.ptrStrat = SharedPtr<TStrategy>(new TStrategy(_strategy));
params.enabled = _enabled; params.enabled = _enabled;
} }
ActiveResult<TArgs> result = _executeAsync(params); ActiveResult<TArgs> result = _executeAsync(params);
return result; return result;
} }
@@ -294,7 +314,7 @@ protected:
bool enabled; bool enabled;
NotifyAsyncParams(const void* pSend, const TArgs& a):ptrStrat(), pSender(pSend), args(a), enabled(true) NotifyAsyncParams(const void* pSend, const TArgs& a):ptrStrat(), pSender(pSend), args(a), enabled(true)
/// default constructor reduces the need for TArgs to have an empty constructor, only copy constructor is needed. /// Default constructor reduces the need for TArgs to have an empty constructor, only copy constructor is needed.
{ {
} }
}; };

View File

@@ -1,7 +1,7 @@
// //
// AbstractObserver.h // AbstractObserver.h
// //
// $Id: //poco/svn/Foundation/include/Poco/AbstractObserver.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/AbstractObserver.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Notifications // Package: Notifications

View File

@@ -1,7 +1,7 @@
// //
// AbstractPriorityDelegate.h // AbstractPriorityDelegate.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/AbstractPriorityDelegate.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/AbstractPriorityDelegate.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the AbstractPriorityDelegate template. // Implementation of the AbstractPriorityDelegate template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -41,27 +41,26 @@
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/AbstractDelegate.h"
namespace Poco { namespace Poco {
template <class TArgs> template <class TArgs>
class AbstractPriorityDelegate class AbstractPriorityDelegate: public AbstractDelegate<TArgs>
/// Interface for PriorityDelegate and PriorityExpire. /// Base class for PriorityDelegate and PriorityExpire.
/// Very similar to AbstractDelegate but having two separate files (no inheritance) ///
/// allows to have compile-time checks when registering an observer /// Extends AbstractDelegate with a priority value.
/// instead of run-time checks.
{ {
public: public:
AbstractPriorityDelegate(void* pTarget, int prio): AbstractPriorityDelegate(int prio):
_pTarget(pTarget),
_priority(prio) _priority(prio)
{ {
} }
AbstractPriorityDelegate(const AbstractPriorityDelegate& del): AbstractPriorityDelegate(const AbstractPriorityDelegate& del):
_pTarget(del._pTarget), AbstractDelegate<TArgs>(del),
_priority(del._priority) _priority(del._priority)
{ {
} }
@@ -70,35 +69,12 @@ public:
{ {
} }
virtual bool notify(const void* sender, TArgs & arguments) = 0;
/// Returns false, if the Delegate is no longer valid, thus indicating an expire
virtual AbstractPriorityDelegate* clone() const = 0;
// Returns a deep-copy of the object.
bool operator < (const AbstractPriorityDelegate<TArgs>& other) const
/// Operator used for comparing AbstractPriorityDelegates in a collection.
{
if (_priority == other._priority)
{
return _pTarget < other._pTarget;
}
return (_priority < other._priority);
}
void* target() const
{
return _pTarget;
}
int priority() const int priority() const
{ {
return _priority; return _priority;
} }
protected: protected:
void* _pTarget;
int _priority; int _priority;
}; };

View File

@@ -1,7 +1,7 @@
// //
// AccessExpirationDecorator.h // AccessExpirationDecorator.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/AccessExpirationDecorator.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/AccessExpirationDecorator.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Cache // Package: Cache

View File

@@ -1,7 +1,7 @@
// //
// ActiveDispatcher.h // ActiveDispatcher.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ActiveDispatcher.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ActiveDispatcher.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// ActiveResult.h // ActiveResult.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ActiveResult.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ActiveResult.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// ActiveRunnable.h // ActiveRunnable.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ActiveRunnable.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ActiveRunnable.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// ActiveStarter.h // ActiveStarter.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ActiveStarter.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ActiveStarter.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// Activity.h // Activity.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Activity.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Activity.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// Any.h // Any.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Any.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Any.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// ArchiveStrategy.h // ArchiveStrategy.h
// //
// $Id: //poco/Main/Foundation/include/Poco/ArchiveStrategy.h#5 $ // $Id: //poco/1.4/Foundation/include/Poco/ArchiveStrategy.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// AsyncChannel.h // AsyncChannel.h
// //
// $Id: //poco/svn/Foundation/include/Poco/AsyncChannel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/AsyncChannel.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// AutoPtr.h // AutoPtr.h
// //
// $Id: //poco/svn/Foundation/include/Poco/AutoPtr.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/AutoPtr.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// AutoReleasePool.h // AutoReleasePool.h
// //
// $Id: //poco/svn/Foundation/include/Poco/AutoReleasePool.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/AutoReleasePool.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Base64Decoder.h // Base64Decoder.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Base64Decoder.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Base64Decoder.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// Base64Encoder.h // Base64Encoder.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Base64Encoder.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Base64Encoder.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// BasicEvent.h // BasicEvent.h
// //
// $Id: //poco/svn/Foundation/include/Poco/BasicEvent.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/BasicEvent.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the BasicEvent template. // Implementation of the BasicEvent template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -43,7 +43,7 @@
#include "Poco/AbstractEvent.h" #include "Poco/AbstractEvent.h"
#include "Poco/DefaultStrategy.h" #include "Poco/DefaultStrategy.h"
#include "Poco/AbstractDelegate.h" #include "Poco/AbstractDelegate.h"
#include "Poco/CompareFunctions.h" #include "Poco/Mutex.h"
namespace Poco { namespace Poco {
@@ -51,22 +51,15 @@ namespace Poco {
template <class TArgs, class TMutex = FastMutex> template <class TArgs, class TMutex = FastMutex>
class BasicEvent: public AbstractEvent < class BasicEvent: public AbstractEvent <
TArgs, DefaultStrategy<TArgs, AbstractDelegate<TArgs>, p_less<AbstractDelegate<TArgs> > >, TArgs, DefaultStrategy<TArgs, AbstractDelegate<TArgs> >,
AbstractDelegate<TArgs>, AbstractDelegate<TArgs>,
TMutex TMutex
> >
/// A BasicEvent uses internally a DefaultStrategy which /// A BasicEvent uses the DefaultStrategy which
/// invokes delegates in an arbitrary manner. /// invokes delegates in the order they have been registered.
/// Note that one object can only register one method to a BasicEvent.
/// Subsequent registrations will overwrite the existing delegate.
/// For example:
/// BasicEvent<int> event;
/// MyClass myObject;
/// event += delegate(&myObject, &MyClass::myMethod1);
/// event += delegate(&myObject, &MyClass::myMethod2);
/// ///
/// The second registration will overwrite the first one. The reason is simply that /// Please see the AbstractEvent class template documentation
/// function pointers can only be compared by equality but not by lower than. /// for more information.
{ {
public: public:
BasicEvent() BasicEvent()
@@ -86,4 +79,4 @@ private:
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_BasicEvent_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// BinaryReader.h // BinaryReader.h
// //
// $Id: //poco/svn/Foundation/include/Poco/BinaryReader.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/BinaryReader.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// Buffer.h // Buffer.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Buffer.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Buffer.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// BufferAllocator.h // BufferAllocator.h
// //
// $Id: //poco/svn/Foundation/include/Poco/BufferAllocator.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/BufferAllocator.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// BufferedBidirectionalStreamBuf.h // BufferedBidirectionalStreamBuf.h
// //
// $Id: //poco/Main/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h#7 $ // $Id: //poco/1.4/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// BufferedStreamBuf.h // BufferedStreamBuf.h
// //
// $Id: //poco/Main/Foundation/include/Poco/BufferedStreamBuf.h#6 $ // $Id: //poco/1.4/Foundation/include/Poco/BufferedStreamBuf.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// Bugcheck.h // Bugcheck.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Bugcheck.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Bugcheck.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// ByteOrder.h // ByteOrder.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ByteOrder.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ByteOrder.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Channel.h // Channel.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Channel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Channel.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// Checksum.h // Checksum.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Checksum.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Checksum.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// ClassLibrary.h // ClassLibrary.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ClassLibrary.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ClassLibrary.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: SharedLibrary // Package: SharedLibrary

View File

@@ -1,7 +1,7 @@
// //
// ClassLoader.h // ClassLoader.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ClassLoader.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ClassLoader.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: SharedLibrary // Package: SharedLibrary

View File

@@ -1,7 +1,7 @@
// //
// Condition.h // Condition.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Condition.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Condition.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// Config.h // Config.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Config.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Config.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Configurable.h // Configurable.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Configurable.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Configurable.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// ConsoleChannel.h // ConsoleChannel.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ConsoleChannel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ConsoleChannel.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// CountingStream.h // CountingStream.h
// //
// $Id: //poco/svn/Foundation/include/Poco/CountingStream.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/CountingStream.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// DateTime.h // DateTime.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DateTime.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DateTime.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: DateTime // Package: DateTime
@@ -431,16 +431,6 @@ inline void swap(DateTime& d1, DateTime& d2)
} }
inline void DateTime::checkLimit(short& lower, short& higher, short limit)
{
if (lower >= limit)
{
higher += short(lower / limit);
lower = short(lower % limit);
}
}
} // namespace Poco } // namespace Poco

View File

@@ -1,7 +1,7 @@
// //
// DateTimeFormat.h // DateTimeFormat.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DateTimeFormat.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DateTimeFormat.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: DateTime // Package: DateTime

View File

@@ -1,7 +1,7 @@
// //
// DateTimeFormatter.h // DateTimeFormatter.h
// //
// $Id: //poco/Main/Foundation/include/Poco/DateTimeFormatter.h#4 $ // $Id: //poco/1.4/Foundation/include/Poco/DateTimeFormatter.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: DateTime // Package: DateTime

View File

@@ -1,7 +1,7 @@
// //
// DateTimeParser.h // DateTimeParser.h
// //
// $Id: //poco/Main/Foundation/include/Poco/DateTimeParser.h#4 $ // $Id: //poco/1.4/Foundation/include/Poco/DateTimeParser.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: DateTime // Package: DateTime

View File

@@ -1,7 +1,7 @@
// //
// Debugger.h // Debugger.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Debugger.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Debugger.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// DefaultStrategy.h // DefaultStrategy.h
// //
// $Id: //poco/Main/Foundation/include/Poco/DefaultStrategy.h#5 $ // $Id: //poco/1.4/Foundation/include/Poco/DefaultStrategy.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the DefaultStrategy template. // Implementation of the DefaultStrategy template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -41,84 +41,63 @@
#include "Poco/NotificationStrategy.h" #include "Poco/NotificationStrategy.h"
#include <memory> #include "Poco/SharedPtr.h"
#include <set>
#include <vector> #include <vector>
namespace Poco { namespace Poco {
template <class TArgs, class TDelegate, class TCompare> template <class TArgs, class TDelegate>
class DefaultStrategy//: public NotificationStrategy<TArgs, TDelegate> class DefaultStrategy: public NotificationStrategy<TArgs, TDelegate>
/// Default notification strategy. Allows one observer /// Default notification strategy.
/// to register exactly once. The observer must provide an ///
/// < (less-than) operator. /// Internally, a std::vector<> is used to store
/// delegate objects. Delegates are invoked in the
/// order in which they have been registered.
{ {
public: public:
typedef std::set<TDelegate*, TCompare> Delegates; typedef SharedPtr<TDelegate> DelegatePtr;
typedef std::vector<DelegatePtr> Delegates;
typedef typename Delegates::iterator Iterator; typedef typename Delegates::iterator Iterator;
typedef typename Delegates::const_iterator ConstIterator;
public: public:
DefaultStrategy() DefaultStrategy()
{ {
} }
DefaultStrategy(const DefaultStrategy& s) DefaultStrategy(const DefaultStrategy& s):
_delegates(s._delegates)
{ {
operator = (s);
} }
~DefaultStrategy() ~DefaultStrategy()
{ {
clear();
} }
void notify(const void* sender, TArgs& arguments) void notify(const void* sender, TArgs& arguments)
{ {
std::vector<Iterator> delMe; for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
for (Iterator it = _observers.begin(); it != _observers.end(); ++it)
{ {
if (!(*it)->notify(sender, arguments)) (*it)->notify(sender, arguments);
{
// schedule for deletion
delMe.push_back(it);
}
}
while (!delMe.empty())
{
typename std::vector<Iterator>::iterator vit = delMe.end();
--vit;
delete **vit;
_observers.erase(*vit);
delMe.pop_back();
} }
} }
void add(const TDelegate& delegate) void add(const TDelegate& delegate)
{ {
Iterator it = _observers.find(const_cast<TDelegate*>(&delegate)); _delegates.push_back(DelegatePtr(static_cast<TDelegate*>(delegate.clone())));
if (it != _observers.end())
{
delete *it;
_observers.erase(it);
}
std::auto_ptr<TDelegate> pDelegate(delegate.clone());
bool tmp = _observers.insert(pDelegate.get()).second;
poco_assert (tmp);
pDelegate.release();
} }
void remove(const TDelegate& delegate) void remove(const TDelegate& delegate)
{ {
Iterator it = _observers.find(const_cast<TDelegate*>(&delegate)); for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
if (it != _observers.end())
{ {
delete *it; if (delegate.equals(**it))
_observers.erase(it); {
(*it)->disable();
_delegates.erase(it);
return;
}
} }
} }
@@ -126,34 +105,31 @@ public:
{ {
if (this != &s) if (this != &s)
{ {
for (ConstIterator it = s._observers.begin(); it != s._observers.end(); ++it) _delegates = s._delegates;
{
add(**it);
}
} }
return *this; return *this;
} }
void clear() void clear()
{ {
for (Iterator it = _observers.begin(); it != _observers.end(); ++it) for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
{ {
delete *it; (*it)->disable();
} }
_observers.clear(); _delegates.clear();
} }
bool empty() const bool empty() const
{ {
return _observers.empty(); return _delegates.empty();
} }
protected: protected:
Delegates _observers; Delegates _delegates;
}; };
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_DefaultStrategy_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// Delegate.h // Delegate.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/Delegate.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/Delegate.h#5 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the Delegate template. // Implementation of the Delegate template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -44,6 +44,7 @@
#include "Poco/AbstractDelegate.h" #include "Poco/AbstractDelegate.h"
#include "Poco/FunctionDelegate.h" #include "Poco/FunctionDelegate.h"
#include "Poco/Expire.h" #include "Poco/Expire.h"
#include "Poco/Mutex.h"
namespace Poco { namespace Poco {
@@ -56,7 +57,6 @@ public:
typedef void (TObj::*NotifyMethod)(const void*, TArgs&); typedef void (TObj::*NotifyMethod)(const void*, TArgs&);
Delegate(TObj* obj, NotifyMethod method): Delegate(TObj* obj, NotifyMethod method):
AbstractDelegate<TArgs>(obj),
_receiverObject(obj), _receiverObject(obj),
_receiverMethod(method) _receiverMethod(method)
{ {
@@ -77,7 +77,6 @@ public:
{ {
if (&delegate != this) if (&delegate != this)
{ {
this->_pTarget = delegate._pTarget;
this->_receiverObject = delegate._receiverObject; this->_receiverObject = delegate._receiverObject;
this->_receiverMethod = delegate._receiverMethod; this->_receiverMethod = delegate._receiverMethod;
} }
@@ -85,9 +84,20 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{ {
(_receiverObject->*_receiverMethod)(sender, arguments); (_receiverObject->*_receiverMethod)(sender, arguments);
return true; // a "standard" delegate never expires return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const Delegate* pOtherDelegate = reinterpret_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
} }
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
@@ -95,9 +105,16 @@ public:
return new Delegate(*this); return new Delegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected: protected:
TObj* _receiverObject; TObj* _receiverObject;
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
Delegate(); Delegate();
@@ -111,7 +128,6 @@ public:
typedef void (TObj::*NotifyMethod)(TArgs&); typedef void (TObj::*NotifyMethod)(TArgs&);
Delegate(TObj* obj, NotifyMethod method): Delegate(TObj* obj, NotifyMethod method):
AbstractDelegate<TArgs>(obj),
_receiverObject(obj), _receiverObject(obj),
_receiverMethod(method) _receiverMethod(method)
{ {
@@ -140,9 +156,20 @@ public:
} }
bool notify(const void*, TArgs& arguments) bool notify(const void*, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{ {
(_receiverObject->*_receiverMethod)(arguments); (_receiverObject->*_receiverMethod)(arguments);
return true; // a "standard" delegate never expires return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const Delegate* pOtherDelegate = reinterpret_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
} }
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
@@ -150,9 +177,16 @@ public:
return new Delegate(*this); return new Delegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected: protected:
TObj* _receiverObject; TObj* _receiverObject;
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
Delegate(); Delegate();
@@ -173,7 +207,6 @@ static Delegate<TObj, TArgs, false> delegate(TObj* pObj, void (TObj::*NotifyMeth
} }
template <class TObj, class TArgs> template <class TObj, class TArgs>
static Expire<TArgs> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs) static Expire<TArgs> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs)
{ {

View File

@@ -1,7 +1,7 @@
// //
// DigestEngine.h // DigestEngine.h
// //
// $Id: //poco/Main/Foundation/include/Poco/DigestEngine.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/DigestEngine.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Crypt // Package: Crypt

View File

@@ -1,7 +1,7 @@
// //
// DigestStream.h // DigestStream.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DigestStream.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DigestStream.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Crypt // Package: Crypt

View File

@@ -1,7 +1,7 @@
// //
// DirectoryIterator.h // DirectoryIterator.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DirectoryIterator.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DirectoryIterator.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// DirectoryIterator_UNIX.h // DirectoryIterator_UNIX.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DirectoryIterator_UNIX.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DirectoryIterator_UNIX.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// DirectoryIterator_VMS.h // DirectoryIterator_VMS.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DirectoryIterator_VMS.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DirectoryIterator_VMS.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// DirectoryIterator_WIN32.h // DirectoryIterator_WIN32.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DirectoryIterator_WIN32.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DirectoryIterator_WIN32.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// DirectoryIterator_WIN32U.h // DirectoryIterator_WIN32U.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DirectoryIterator_WIN32U.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DirectoryIterator_WIN32U.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// DynamicFactory.h // DynamicFactory.h
// //
// $Id: //poco/svn/Foundation/include/Poco/DynamicFactory.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/DynamicFactory.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment.h // Environment.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Environment.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_UNIX.h // Environment_UNIX.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Environment_UNIX.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_UNIX.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_VMS.h // Environment_VMS.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Environment_VMS.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_VMS.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_VX.h // Environment_VX.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/Environment_VX.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_VX.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_WIN32.h // Environment_WIN32.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Environment_WIN32.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_WIN32.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_WIN32U.h // Environment_WIN32U.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Environment_WIN32U.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_WIN32U.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Environment_WINCE.h // Environment_WINCE.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/Environment_WINCE.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/Environment_WINCE.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// ErrorHandler.h // ErrorHandler.h
// //
// $Id: //poco/svn/Foundation/include/Poco/ErrorHandler.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/ErrorHandler.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading
@@ -59,7 +59,7 @@ class Foundation_API ErrorHandler
/// global ErrorHandler that is invoked whenever a thread has /// global ErrorHandler that is invoked whenever a thread has
/// been terminated by an unhandled exception. /// been terminated by an unhandled exception.
/// The ErrorHandler must be derived from this class and can /// The ErrorHandler must be derived from this class and can
/// provide implementations of all three handleException() overloads. /// provide implementations of all three exception() overloads.
/// ///
/// The ErrorHandler is always invoked within the context of /// The ErrorHandler is always invoked within the context of
/// the offending thread. /// the offending thread.

View File

@@ -1,7 +1,7 @@
// //
// Event.h // Event.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Event.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Event.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// EventLogChannel.h // EventLogChannel.h
// //
// $Id: //poco/svn/Foundation/include/Poco/EventLogChannel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/EventLogChannel.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// Event_POSIX.h // Event_POSIX.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Event_POSIX.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Event_POSIX.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading

View File

@@ -1,7 +1,7 @@
// //
// Event_WIN32.h // Event_WIN32.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Event_WIN32.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Event_WIN32.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Threading // Package: Threading
@@ -51,7 +51,7 @@ namespace Poco {
class Foundation_API EventImpl class Foundation_API EventImpl
{ {
protected: protected:
EventImpl(bool autoReset = false); EventImpl(bool autoReset);
~EventImpl(); ~EventImpl();
void setImpl(); void setImpl();
void waitImpl(); void waitImpl();

View File

@@ -1,7 +1,7 @@
// //
// Expire.h // Expire.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Expire.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Expire.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the Expire template. // Implementation of the Expire template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -51,11 +51,10 @@ namespace Poco {
template <class TArgs> template <class TArgs>
class Expire: public AbstractDelegate<TArgs> class Expire: public AbstractDelegate<TArgs>
/// Decorator for AbstractDelegate adding automatic /// Decorator for AbstractDelegate adding automatic
/// expiring of registrations to AbstractDelegates. /// expiration of registrations to AbstractDelegate's.
{ {
public: public:
Expire(const AbstractDelegate<TArgs>& p, Timestamp::TimeDiff expireMillisecs): Expire(const AbstractDelegate<TArgs>& p, Timestamp::TimeDiff expireMillisecs):
AbstractDelegate<TArgs>(p),
_pDelegate(p.clone()), _pDelegate(p.clone()),
_expire(expireMillisecs*1000) _expire(expireMillisecs*1000)
{ {
@@ -71,7 +70,7 @@ public:
~Expire() ~Expire()
{ {
destroy(); delete _pDelegate;
} }
Expire& operator = (const Expire& expire) Expire& operator = (const Expire& expire)
@@ -95,20 +94,24 @@ public:
return false; return false;
} }
bool equals(const AbstractDelegate<TArgs>& other) const
{
return other.equals(*_pDelegate);
}
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
{ {
return new Expire(*this); return new Expire(*this);
} }
void destroy() void disable()
{ {
delete this->_pDelegate; _pDelegate->disable();
this->_pDelegate = 0;
} }
const AbstractDelegate<TArgs>& getDelegate() const const AbstractDelegate<TArgs>* unwrap() const
{ {
return *this->_pDelegate; return this->_pDelegate;
} }
protected: protected:
@@ -129,4 +132,4 @@ private:
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_Expire_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// FIFOEvent.h // FIFOEvent.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FIFOEvent.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FIFOEvent.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the FIFOEvent template. // Implementation of the FIFOEvent template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -43,16 +43,16 @@
#include "Poco/AbstractEvent.h" #include "Poco/AbstractEvent.h"
#include "Poco/FIFOStrategy.h" #include "Poco/FIFOStrategy.h"
#include "Poco/AbstractDelegate.h" #include "Poco/AbstractDelegate.h"
#include "Poco/CompareFunctions.h"
namespace Poco { namespace Poco {
//@ deprecated
template <class TArgs, class TMutex = FastMutex> template <class TArgs, class TMutex = FastMutex>
class FIFOEvent: public AbstractEvent < class FIFOEvent: public AbstractEvent <
TArgs, TArgs,
FIFOStrategy<TArgs, AbstractDelegate<TArgs>, p_less<AbstractDelegate< TArgs> > >, FIFOStrategy<TArgs, AbstractDelegate<TArgs> >,
AbstractDelegate<TArgs>, AbstractDelegate<TArgs>,
TMutex TMutex
> >
@@ -60,15 +60,9 @@ class FIFOEvent: public AbstractEvent <
/// that delegates are invoked in the order they were added to /// that delegates are invoked in the order they were added to
/// the event. /// the event.
/// ///
/// Note that one object can only register one method to a FIFOEvent. /// Note that as of release 1.4.2, this is the default behavior
/// Subsequent registrations will overwrite the existing delegate. /// implemented by BasicEvent, so this class is provided
/// For example: /// for backwards compatibility only.
/// FIFOEvent<int> tmp;
/// MyClass myObject;
/// tmp += delegate(&myObject, &MyClass::myMethod1);
/// tmp += delegate(&myObject, &MyClass::myMethod2);
///
/// The second registration will overwrite the first one.
{ {
public: public:
FIFOEvent() FIFOEvent()
@@ -88,4 +82,4 @@ private:
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_FIFOEvent_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// FIFOStrategy.h // FIFOStrategy.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FIFOStrategy.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FIFOStrategy.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the FIFOStrategy template. // Implementation of the FIFOStrategy template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -35,132 +35,47 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// //
#ifndef Foundation_FIFOStrategy_INCLUDED #ifndef Foundation_FIFOStrategy_INCLUDED
#define Foundation_FIFOStrategy_INCLUDED #define Foundation_FIFOStrategy_INCLUDED
#include "Poco/NotificationStrategy.h" #include "Poco/DefaultStrategy.h"
#include <map>
#include <list>
#include <memory>
namespace Poco { namespace Poco {
template <class TArgs, class TDelegate, class TCompare> //@ deprecated
class FIFOStrategy//: public NotificationStrategy<TArgs, TDelegate> template <class TArgs, class TDelegate>
class FIFOStrategy: public DefaultStrategy<TArgs, TDelegate>
/// Note: As of release 1.4.2, DefaultStrategy already
/// implements FIFO behavior, so this class is provided
/// for backwards compatibility only.
{ {
public: public:
typedef std::list<TDelegate*> Delegates;
typedef typename Delegates::iterator Iterator;
typedef typename Delegates::const_iterator ConstIterator;
typedef std::map<TDelegate*, Iterator, TCompare> DelegateIndex;
typedef typename DelegateIndex::iterator IndexIterator;
typedef typename DelegateIndex::const_iterator ConstIndexIterator;
FIFOStrategy() FIFOStrategy()
{ {
} }
FIFOStrategy(const FIFOStrategy& s) FIFOStrategy(const FIFOStrategy& s):
DefaultStrategy<TArgs, TDelegate>(s)
{ {
operator = (s);
} }
~FIFOStrategy() ~FIFOStrategy()
{ {
clear();
}
void notify(const void* sender, TArgs& arguments)
{
std::vector<Iterator> delMe;
Iterator it = _observers.begin();
Iterator itEnd = _observers.end();
for (; it != itEnd; ++it)
{
if (!(*it)->notify(sender, arguments))
{
// schedule for deletion
delMe.push_back(it);
}
}
while (!delMe.empty())
{
typename std::vector<Iterator>::iterator vit = delMe.end();
--vit;
delete **vit;
_observers.erase(*vit);
delMe.pop_back();
}
}
void add(const TDelegate& delegate)
{
IndexIterator it = _observerIndex.find(const_cast<TDelegate*>(&delegate));
if (it != _observerIndex.end())
{
delete *it->second;
_observers.erase(it->second);
_observerIndex.erase(it);
}
std::auto_ptr<TDelegate> pDelegate(delegate.clone());
_observers.push_back(pDelegate.get());
bool tmp = _observerIndex.insert(make_pair(pDelegate.get(), --_observers.end())).second;
poco_assert (tmp);
pDelegate.release();
}
void remove(const TDelegate& delegate)
{
IndexIterator it = _observerIndex.find(const_cast<TDelegate*>(&delegate));
if (it != _observerIndex.end())
{
delete *it->second;
_observers.erase(it->second);
_observerIndex.erase(it);
}
} }
FIFOStrategy& operator = (const FIFOStrategy& s) FIFOStrategy& operator = (const FIFOStrategy& s)
{ {
if (this != &s) DefaultStrategy<TArgs, TDelegate>::operator = (s);
{
for (ConstIterator it = s._observers.begin(); it != s._observers.end(); ++it)
{
add(**it);
}
}
return *this; return *this;
} }
void clear()
{
for (Iterator it = _observers.begin(); it != _observers.end(); ++it)
{
delete *it;
}
_observers.clear();
_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.
}; };
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_FIFOStrategy_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment.h // FPEnvironment.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment_C99.h // FPEnvironment_C99.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment_C99.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment_C99.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment_DEC.h // FPEnvironment_DEC.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment_DEC.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment_DEC.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment_DUMMY.h // FPEnvironment_DUMMY.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment_DUMMY.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment_DUMMY.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment_SUN.h // FPEnvironment_SUN.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment_SUN.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment_SUN.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// FPEnvironment_WIN32.h // FPEnvironment_WIN32.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FPEnvironment_WIN32.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FPEnvironment_WIN32.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// File.h // File.h
// //
// $Id: //poco/Main/Foundation/include/Poco/File.h#9 $ // $Id: //poco/1.4/Foundation/include/Poco/File.h#3 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// FileChannel.h // FileChannel.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/FileChannel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FileChannel.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// FileStream.h // FileStream.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FileStream.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FileStream.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// FileStreamFactory.h // FileStreamFactory.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FileStreamFactory.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FileStreamFactory.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: URI // Package: URI

View File

@@ -1,7 +1,7 @@
// //
// FileStream_POSIX.h // FileStream_POSIX.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FileStream_POSIX.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FileStream_POSIX.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// FileStream_WIN32.h // FileStream_WIN32.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FileStream_WIN32.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FileStream_WIN32.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// File_UNIX.h // File_UNIX.h
// //
// $Id: //poco/Main/Foundation/include/Poco/File_UNIX.h#6 $ // $Id: //poco/1.4/Foundation/include/Poco/File_UNIX.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// File_VMS.h // File_VMS.h
// //
// $Id: //poco/Main/Foundation/include/Poco/File_VMS.h#6 $ // $Id: //poco/1.4/Foundation/include/Poco/File_VMS.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// File_WIN32.h // File_WIN32.h
// //
// $Id: //poco/Main/Foundation/include/Poco/File_WIN32.h#6 $ // $Id: //poco/1.4/Foundation/include/Poco/File_WIN32.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// File_WIN32U.h // File_WIN32U.h
// //
// $Id: //poco/Main/Foundation/include/Poco/File_WIN32U.h#6 $ // $Id: //poco/1.4/Foundation/include/Poco/File_WIN32U.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// Format.h // Format.h
// //
// $Id: //poco/1.4/Foundation/include/Poco/Format.h#1 $ // $Id: //poco/1.4/Foundation/include/Poco/Format.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// Formatter.h // Formatter.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Formatter.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Formatter.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// FormattingChannel.h // FormattingChannel.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FormattingChannel.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FormattingChannel.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Logging // Package: Logging

View File

@@ -1,7 +1,7 @@
// //
// FunctionDelegate.h // FunctionDelegate.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FunctionDelegate.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FunctionDelegate.h#4 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the FunctionDelegate template. // Implementation of the FunctionDelegate template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -42,6 +42,7 @@
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/AbstractDelegate.h" #include "Poco/AbstractDelegate.h"
#include "Poco/Mutex.h"
namespace Poco { namespace Poco {
@@ -49,14 +50,13 @@ namespace Poco {
template <class TArgs, bool hasSender = true, bool senderIsConst = true> template <class TArgs, bool hasSender = true, bool senderIsConst = true>
class FunctionDelegate: public AbstractDelegate<TArgs> class FunctionDelegate: public AbstractDelegate<TArgs>
/// Wraps a C style function (or a C++ static function) to be used as /// Wraps a freestanding function or static member function
/// a delegate /// for use as a Delegate.
{ {
public: public:
typedef void (*NotifyMethod)(const void*, TArgs&); typedef void (*NotifyMethod)(const void*, TArgs&);
FunctionDelegate(NotifyMethod method): FunctionDelegate(NotifyMethod method):
AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method)),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
@@ -82,9 +82,20 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(sender, arguments); (*_receiverMethod)(sender, arguments);
return true; // a "standard" delegate never expires return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionDelegate* pOtherDelegate = dynamic_cast<const FunctionDelegate*>(other.unwrap());
return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod;
} }
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
@@ -92,8 +103,15 @@ public:
return new FunctionDelegate(*this); return new FunctionDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionDelegate(); FunctionDelegate();
@@ -107,7 +125,6 @@ public:
typedef void (*NotifyMethod)(void*, TArgs&); typedef void (*NotifyMethod)(void*, TArgs&);
FunctionDelegate(NotifyMethod method): FunctionDelegate(NotifyMethod method):
AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method)),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
@@ -133,9 +150,20 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(const_cast<void*>(sender), arguments); (*_receiverMethod)(const_cast<void*>(sender), arguments);
return true; // a "standard" delegate never expires return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionDelegate* pOtherDelegate = dynamic_cast<const FunctionDelegate*>(other.unwrap());
return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod;
} }
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
@@ -143,8 +171,15 @@ public:
return new FunctionDelegate(*this); return new FunctionDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionDelegate(); FunctionDelegate();
@@ -158,7 +193,6 @@ public:
typedef void (*NotifyMethod)(TArgs&); typedef void (*NotifyMethod)(TArgs&);
FunctionDelegate(NotifyMethod method): FunctionDelegate(NotifyMethod method):
AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method)),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
@@ -184,9 +218,20 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(arguments); (*_receiverMethod)(arguments);
return true; // a "standard" delegate never expires return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionDelegate* pOtherDelegate = dynamic_cast<const FunctionDelegate*>(other.unwrap());
return pOtherDelegate && _receiverMethod == pOtherDelegate->_receiverMethod;
} }
AbstractDelegate<TArgs>* clone() const AbstractDelegate<TArgs>* clone() const
@@ -194,8 +239,15 @@ public:
return new FunctionDelegate(*this); return new FunctionDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionDelegate(); FunctionDelegate();
@@ -205,4 +257,4 @@ private:
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_FunctionDelegate_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// FunctionPriorityDelegate.h // FunctionPriorityDelegate.h
// //
// $Id: //poco/svn/Foundation/include/Poco/FunctionPriorityDelegate.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/FunctionPriorityDelegate.h#5 $
// //
// Library: Foundation // Library: Foundation
// Package: Events // Package: Events
@@ -9,7 +9,7 @@
// //
// Implementation of the FunctionPriorityDelegate template. // Implementation of the FunctionPriorityDelegate template.
// //
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
@@ -42,6 +42,7 @@
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/AbstractPriorityDelegate.h" #include "Poco/AbstractPriorityDelegate.h"
#include "Poco/Mutex.h"
namespace Poco { namespace Poco {
@@ -49,20 +50,20 @@ namespace Poco {
template <class TArgs, bool useSender = true, bool senderIsConst = true> template <class TArgs, bool useSender = true, bool senderIsConst = true>
class FunctionPriorityDelegate: public AbstractPriorityDelegate<TArgs> class FunctionPriorityDelegate: public AbstractPriorityDelegate<TArgs>
/// Wraps a C style function (or a C++ static fucntion) to be used as /// Wraps a freestanding function or static member function
/// a priority delegate /// for use as a PriorityDelegate.
{ {
public: public:
typedef void (*NotifyMethod)(const void*, TArgs&); typedef void (*NotifyMethod)(const void*, TArgs&);
FunctionPriorityDelegate(NotifyMethod method, int prio): FunctionPriorityDelegate(NotifyMethod method, int prio):
AbstractPriorityDelegate<TArgs>(*reinterpret_cast<void**>(&method), prio), AbstractPriorityDelegate<TArgs>(prio),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
AbstractPriorityDelegate<TArgs>(delegate._pTarget, delegate._priority), AbstractPriorityDelegate<TArgs>(delegate),
_receiverMethod(delegate._receiverMethod) _receiverMethod(delegate._receiverMethod)
{ {
} }
@@ -83,18 +84,36 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(sender, arguments); (*_receiverMethod)(sender, arguments);
return true; // per default the delegate never expires return true;
}
else return false;
} }
AbstractPriorityDelegate<TArgs>* clone() const bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<TArgs>* clone() const
{ {
return new FunctionPriorityDelegate(*this); return new FunctionPriorityDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionPriorityDelegate(); FunctionPriorityDelegate();
@@ -108,13 +127,13 @@ public:
typedef void (*NotifyMethod)(void*, TArgs&); typedef void (*NotifyMethod)(void*, TArgs&);
FunctionPriorityDelegate(NotifyMethod method, int prio): FunctionPriorityDelegate(NotifyMethod method, int prio):
AbstractPriorityDelegate<TArgs>(*reinterpret_cast<void**>(&method), prio), AbstractPriorityDelegate<TArgs>(prio),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
AbstractPriorityDelegate<TArgs>(delegate._pTarget, delegate._priority), AbstractPriorityDelegate<TArgs>(delegate),
_receiverMethod(delegate._receiverMethod) _receiverMethod(delegate._receiverMethod)
{ {
} }
@@ -135,25 +154,42 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(const_cast<void*>(sender), arguments); (*_receiverMethod)(const_cast<void*>(sender), arguments);
return true; // per default the delegate never expires return true;
}
else return false;
} }
AbstractPriorityDelegate<TArgs>* clone() const bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<TArgs>* clone() const
{ {
return new FunctionPriorityDelegate(*this); return new FunctionPriorityDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionPriorityDelegate(); FunctionPriorityDelegate();
}; };
template <class TArgs> template <class TArgs>
class FunctionPriorityDelegate<TArgs, false>: public AbstractPriorityDelegate<TArgs> class FunctionPriorityDelegate<TArgs, false>: public AbstractPriorityDelegate<TArgs>
{ {
@@ -161,13 +197,13 @@ public:
typedef void (*NotifyMethod)(TArgs&); typedef void (*NotifyMethod)(TArgs&);
FunctionPriorityDelegate(NotifyMethod method, int prio): FunctionPriorityDelegate(NotifyMethod method, int prio):
AbstractPriorityDelegate<TArgs>(*reinterpret_cast<void**>(&method), prio), AbstractPriorityDelegate<TArgs>(prio),
_receiverMethod(method) _receiverMethod(method)
{ {
} }
FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate):
AbstractPriorityDelegate<TArgs>(delegate._pTarget, delegate._priority), AbstractPriorityDelegate<TArgs>(delegate),
_receiverMethod(delegate._receiverMethod) _receiverMethod(delegate._receiverMethod)
{ {
} }
@@ -188,18 +224,36 @@ public:
} }
bool notify(const void* sender, TArgs& arguments) bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverMethod)
{ {
(*_receiverMethod)(arguments); (*_receiverMethod)(arguments);
return true; // per default the delegate never expires return true;
}
else return false;
} }
AbstractPriorityDelegate<TArgs>* clone() const bool equals(const AbstractDelegate<TArgs>& other) const
{
const FunctionPriorityDelegate* pOtherDelegate = dynamic_cast<const FunctionPriorityDelegate*>(other.unwrap());
return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<TArgs>* clone() const
{ {
return new FunctionPriorityDelegate(*this); return new FunctionPriorityDelegate(*this);
} }
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverMethod = 0;
}
protected: protected:
NotifyMethod _receiverMethod; NotifyMethod _receiverMethod;
Mutex _mutex;
private: private:
FunctionPriorityDelegate(); FunctionPriorityDelegate();
@@ -209,4 +263,4 @@ private:
} // namespace Poco } // namespace Poco
#endif #endif // Foundation_FunctionPriorityDelegate_INCLUDED

View File

@@ -1,7 +1,7 @@
// //
// Glob.h // Glob.h
// //
// $Id: //poco/1.3/Foundation/include/Poco/Glob.h#3 $ // $Id: //poco/1.4/Foundation/include/Poco/Glob.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Filesystem // Package: Filesystem

View File

@@ -1,7 +1,7 @@
// //
// HMACEngine.h // HMACEngine.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HMACEngine.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HMACEngine.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Crypt // Package: Crypt

View File

@@ -1,7 +1,7 @@
// //
// Hash.h // Hash.h
// //
// $Id: //poco/Main/Foundation/include/Poco/Hash.h#4 $ // $Id: //poco/1.4/Foundation/include/Poco/Hash.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HashFunction.h // HashFunction.h
// //
// $Id: //poco/Main/Foundation/include/Poco/HashFunction.h#5 $ // $Id: //poco/1.4/Foundation/include/Poco/HashFunction.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HashMap.h // HashMap.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HashMap.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HashMap.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HashSet.h // HashSet.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HashSet.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HashSet.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HashStatistic.h // HashStatistic.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HashStatistic.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HashStatistic.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HashTable.h // HashTable.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HashTable.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HashTable.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Hashing // Package: Hashing

View File

@@ -1,7 +1,7 @@
// //
// HexBinaryDecoder.h // HexBinaryDecoder.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HexBinaryDecoder.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HexBinaryDecoder.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// HexBinaryEncoder.h // HexBinaryEncoder.h
// //
// $Id: //poco/svn/Foundation/include/Poco/HexBinaryEncoder.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/HexBinaryEncoder.h#2 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

View File

@@ -1,7 +1,7 @@
// //
// Instantiator.h // Instantiator.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Instantiator.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Instantiator.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core

View File

@@ -1,7 +1,7 @@
// //
// KeyValueArgs.h // KeyValueArgs.h
// //
// $Id: //poco/svn/Foundation/include/Poco/KeyValueArgs.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/KeyValueArgs.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Cache // Package: Cache

View File

@@ -1,7 +1,7 @@
// //
// LRUCache.h // LRUCache.h
// //
// $Id: //poco/svn/Foundation/include/Poco/LRUCache.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/LRUCache.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Cache // Package: Cache

View File

@@ -1,7 +1,7 @@
// //
// Latin9Encoding.h // Latin9Encoding.h
// //
// $Id: //poco/svn/Foundation/include/Poco/Latin9Encoding.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/Latin9Encoding.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Text // Package: Text

View File

@@ -1,7 +1,7 @@
// //
// LineEndingConverter.h // LineEndingConverter.h
// //
// $Id: //poco/svn/Foundation/include/Poco/LineEndingConverter.h#2 $ // $Id: //poco/1.4/Foundation/include/Poco/LineEndingConverter.h#1 $
// //
// Library: Foundation // Library: Foundation
// Package: Streams // Package: Streams

Some files were not shown because too many files have changed in this diff Show More