Added documentation. Some smaller fixes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1605 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2002-10-23 01:06:13 +00:00
parent 313fe24d7c
commit 5f20a509b4
4 changed files with 247 additions and 20 deletions

View File

@ -30,7 +30,27 @@
// EventMaskWatcher
/*! \class EventMaskWatcher
\brief EventMaskWatcher is a Watcher extended by an event mask.
Each set bit in the watcher's event mask specifies an event the watcher
wants to get notified about.
This class is intended to be used together with EventMaskWatcherFilter.
Such a filter object is created with a certain event and its
EventMaskWatcherFilter::Filter() method only selects those
EventMaskWatchers with an event mask that contains the event.
*/
/*! \var uint32 EventMaskWatcher::fEventMask
\brief The watcher's event mask.
*/
// constructor
/*! \brief Creates a new EventMaskWatcher with a given target and event mask.
\param target The watcher's message target.
\param eventMask the watcher's event mask.
*/
EventMaskWatcher::EventMaskWatcher(const BMessenger &target, uint32 eventMask)
: Watcher(target),
fEventMask(eventMask)
@ -38,6 +58,9 @@ EventMaskWatcher::EventMaskWatcher(const BMessenger &target, uint32 eventMask)
}
// EventMask
/*! \brief Returns the watcher's event mask.
\return The watcher's event mask.
*/
uint32
EventMaskWatcher::EventMask() const
{
@ -47,7 +70,31 @@ EventMaskWatcher::EventMask() const
// EventMaskWatcherFilter
/*! \class EventMaskWatcherFilter
\brief EventMaskWatcherFilter filters EventMaskWatchers with respect to
their event mask and a specific event.
This class is intended to be used together with EventMaskWatcher.
A filter object is created with a certain event and its Filter() method
only selects those EventMaskWatchers with an event mask that contains
the event.
*/
/*! \var uint32 EventMaskWatcherFilter::fEvent
\brief The filter's event.
Filter only returns \c true for watchers whose event mask contains the
event.
*/
// constructor
/*! \brief Creates a new EventMaskWatcherFilter with a specified event.
Actually \a event may specify more than one event. Usually each set bit
represents an event.
\param event The event.
*/
EventMaskWatcherFilter::EventMaskWatcherFilter(uint32 event)
: WatcherFilter(),
fEvent(event)
@ -55,6 +102,17 @@ EventMaskWatcherFilter::EventMaskWatcherFilter(uint32 event)
}
// Filter
/*! \brief Returns whether the watcher-message pair satisfies the predicate
represented by this object.
Returns \c true, if the supplied watcher is an EventMaskWatcher and its
event mask contains this filter's event, or more precise the bitwise AND
on event mask and event is not 0.
\param watcher The watcher in question.
\param message The message in question.
\return \c true, if the watcher's event mask contains the filter's event.
*/
bool
EventMaskWatcherFilter::Filter(Watcher *watcher, BMessage *message)
{

View File

@ -22,7 +22,7 @@
// File Name: Watcher.cpp
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: A Watcher represents a target of a watching service.
// A WatcherFilter represents a predicate on a Watcher.
// A WatcherFilter represents a predicate on Watchers.
//------------------------------------------------------------------------------
#include <Message.h>
@ -31,18 +31,43 @@
// Watcher
/*! \class Watcher
\brief A Watcher represents a target of a watching service.
The Watcher base class only has one attribute, a BMessenger which
specifies the target to which notification messages shall be sent.
SendMessage() actually sends the message to the target. It can be
overridden in case of special needs.
*/
/*! \var Watcher::fTarget
\brief The watcher's message target.
*/
// constructor
/*! \brief Creates a new watcher with a specified target.
The supplied BMessenger is copied, that is the caller can delete the
object when the constructor returns.
\param target The watcher's message target.
*/
Watcher::Watcher(const BMessenger &target)
: fTarget(target)
{
}
// destructor
/*! \brief Frees all resources associated with the object.
*/
Watcher::~Watcher()
{
}
// Target
/*! \brief Returns the watcher's message target.
\return The watcher's message target.
*/
const BMessenger&
Watcher::Target() const
{
@ -50,6 +75,16 @@ Watcher::Target() const
}
// SendMessage
/*! \brief Sends the supplied message to the watcher's message target.
The method can be overridden by a derived class to e.g. add additional
fields to the message. Note, that in this case the message must not be
modified directly, but a copy has to be made.
\param message The message to be sent.
\return \c B_OK, if everything went fine, another error code, if an error
occured.
*/
status_t
Watcher::SendMessage(BMessage *message)
{
@ -59,17 +94,38 @@ Watcher::SendMessage(BMessage *message)
// WatcherFilter
/*! \class WatcherFilter
\brief A WatcherFilter represents a predicate on Watchers.
It's only method Filter() returns whether a given Watcher and a BMessage
satisfy the predicate. This class' Filter() implementation always returns
\c true. Derived classes override it.
*/
// constructor
/*! \brief Creates a new WatchingFilter.
*/
WatcherFilter::WatcherFilter()
{
}
// destructor
/*! \brief Frees all resources associated with the object.
*/
WatcherFilter::~WatcherFilter()
{
}
// Filter
/*! \brief Returns whether the watcher-message pair satisfies the predicate
represented by this object.
Derived classes override this method. This version always returns \c true.
\param watcher The watcher in question.
\param message The message in question.
\return \c true.
*/
bool
WatcherFilter::Filter(Watcher *watcher, BMessage *message)
{

View File

@ -22,7 +22,7 @@
// File Name: Watcher.h
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: A Watcher represents a target of a watching service.
// A WatcherFilter represents a predicate on a Watcher.
// A WatcherFilter represents a predicate on Watchers.
//------------------------------------------------------------------------------
#ifndef WATCHER_H
@ -38,7 +38,7 @@ public:
const BMessenger &Target() const;
status_t SendMessage(BMessage *message);
virtual status_t SendMessage(BMessage *message);
private:
BMessenger fTarget;

View File

@ -29,13 +29,48 @@
#include "Watcher.h"
#include "WatchingService.h"
/*! \class WatchingService
\brief Features everything needed to provide a watching service.
A watcher is represented by an object of the Watcher or a derived class.
It is identified by its target BMessenger. The service can't contain
more than one watcher with the same target BMessenger at a time.
New watchers can be registered with AddWatcher(), registered ones
unregistered via RemoveRegister(). NotifyWatchers() sends a specified
message to all registered watchers, or, if an optional WatcherFilter is
supplied, only to those watchers it selects.
*/
/*! \var typedef map<BMessenger,Watcher*> WatchingService::watcher_map
\brief Watcher container type.
Defined for convenience.
*/
/*! \var WatchingService::watcher_map WatchingService::fWatchers
\brief Container for the watchers registered to the service.
For each registered watcher \code Watcher *watcher \endcode, the map
contains an entry \code (watcher->Target(), watcher) \endcode.
*/
// constructor
/*! \brief Creates a new watching service.
The list of watchers is initially empty.
*/
WatchingService::WatchingService()
: fWatchers()
{
}
// destructor
/*! \brief Frees all resources associated with the object.
All registered watchers are deleted.
*/
WatchingService::~WatchingService()
{
// delete the watchers
@ -47,6 +82,19 @@ WatchingService::~WatchingService()
}
// AddWatcher
/*! \brief Registers a new watcher to the watching service.
The ownership of \a watcher is transfered to the watching service, that
is the caller must not delete it after the method returns.
If the service already contains a Watcher with the same target BMessenger
(Watcher::Target()), the old watcher is removed and deleted before the
new one is added..
\param watcher The watcher to be registered.
\return \c true, if \a watcher is not \c NULL and adding was successfully,
\c false otherwise.
*/
bool
WatchingService::AddWatcher(Watcher *watcher)
{
@ -59,6 +107,20 @@ WatchingService::AddWatcher(Watcher *watcher)
}
// AddWatcher
/*! \brief Registers a new watcher to the watching service.
A new \c Watcher is created with \a target as its target and added to
the watching service. The caller retains ownership of \a target, but the
newly created Watcher is owned by the watching service.
If the service already contains a Watcher with the same target BMessenger
(Watcher::Target()), the old watcher is removed and deleted before the
new one is added..
\param target The target BMessenger a Watcher shall be registered for.
\return \c true, if a new Watcher could be created and added successfully,
\c false otherwise.
*/
bool
WatchingService::AddWatcher(const BMessenger &target)
{
@ -66,13 +128,47 @@ WatchingService::AddWatcher(const BMessenger &target)
}
// RemoveWatcher
/*! \brief Unregisters a watcher from the watching service and optionally
deletes it.
If \a deleteWatcher is \c false, the ownership of \a watcher is transfered
to the caller, otherwise it is deleted.
\param watcher The watcher to be unregistered.
\param deleteWatcher If \c true, the watcher is deleted after being
removed.
\return \c true, if \a watcher was not \c NULL and registered to the
watching service before, \c false otherwise.
*/
bool
WatchingService::RemoveWatcher(Watcher *watcher, bool deleteWatcher)
{
return (watcher && RemoveWatcher(watcher->Target(), deleteWatcher));
watcher_map::iterator it = fWatchers.find(watcher->Target());
bool result = (it != fWatchers.end() && it->second == watcher);
if (result) {
if (deleteWatcher)
delete it->second;
fWatchers.erase(it);
}
return result;
}
// RemoveWatcher
/*! \brief Unregisters a watcher from the watching service and optionally
deletes it.
The watcher is identified by its target BMessenger.
If \a deleteWatcher is \c false, the ownership of the concerned watcher is
transfered to the caller, otherwise it is deleted.
\param target The target BMessenger identifying the watcher to be
unregistered.
\param deleteWatcher If \c true, the watcher is deleted after being
removed.
\return \c true, if a watcher with the specified target was registered to
the watching service before, \c false otherwise.
*/
bool
WatchingService::RemoveWatcher(const BMessenger &target, bool deleteWatcher)
{
@ -87,28 +183,45 @@ WatchingService::RemoveWatcher(const BMessenger &target, bool deleteWatcher)
}
// NotifyWatchers
/*! \brief Sends a notification message to all watcher targets selected by a
supplied filter.
If no filter is supplied the message is sent to all watchers. Otherwise
each watcher (and the notification message) is passed to its
WatcherFilter::Filter() method and the message is sent only to those
watchers for which \c true is returned.
If a sending a message to a watcher's target failed, because it became
invalid, the watcher is unregistered and deleted.
\param message The message to be sent to the watcher targets.
\param filter The filter selecting the watchers to which the message
is be sent. May be \c NULL.
*/
void
WatchingService::NotifyWatchers(BMessage *message, WatcherFilter *filter)
{
BList staleWatchers;
// deliver the message
for (watcher_map::iterator it = fWatchers.begin();
it != fWatchers.end();
++it) {
Watcher *watcher = it->second;
if (message) {
BList staleWatchers;
// deliver the message
for (watcher_map::iterator it = fWatchers.begin();
it != fWatchers.end();
++it) {
Watcher *watcher = it->second;
// TODO: If a watcher is invalid, but the filter never selects it, it will
// not be removed.
if (!filter || filter->Filter(watcher, message)) {
status_t error = watcher->SendMessage(message);
if (error != B_OK && error != B_WOULD_BLOCK)
staleWatchers.AddItem(watcher);
if (!filter || filter->Filter(watcher, message)) {
status_t error = watcher->SendMessage(message);
if (error != B_OK && !watcher->Target().IsValid())
staleWatchers.AddItem(watcher);
}
}
// remove the stale watchers
for (int32 i = 0;
Watcher *watcher = (Watcher*)staleWatchers.ItemAt(i);
i++) {
RemoveWatcher(watcher, true);
}
}
// remove the stale watchers
for (int32 i = 0;
Watcher *watcher = (Watcher*)staleWatchers.ItemAt(i);
i++) {
RemoveWatcher(watcher, true);
}
}