From 5f20a509b41b6c96d62df41c4dc4040360abb12e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 23 Oct 2002 01:06:13 +0000 Subject: [PATCH] Added documentation. Some smaller fixes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1605 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/registrar/EventMaskWatcher.cpp | 58 ++++++++ src/servers/registrar/Watcher.cpp | 58 +++++++- src/servers/registrar/Watcher.h | 4 +- src/servers/registrar/WatchingService.cpp | 147 ++++++++++++++++++--- 4 files changed, 247 insertions(+), 20 deletions(-) diff --git a/src/servers/registrar/EventMaskWatcher.cpp b/src/servers/registrar/EventMaskWatcher.cpp index 7ce025cebb..7ec1a4821a 100644 --- a/src/servers/registrar/EventMaskWatcher.cpp +++ b/src/servers/registrar/EventMaskWatcher.cpp @@ -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) { diff --git a/src/servers/registrar/Watcher.cpp b/src/servers/registrar/Watcher.cpp index d3a857a39d..41aabf6b3c 100644 --- a/src/servers/registrar/Watcher.cpp +++ b/src/servers/registrar/Watcher.cpp @@ -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 @@ -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) { diff --git a/src/servers/registrar/Watcher.h b/src/servers/registrar/Watcher.h index 764dd440fb..48635e2226 100644 --- a/src/servers/registrar/Watcher.h +++ b/src/servers/registrar/Watcher.h @@ -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; diff --git a/src/servers/registrar/WatchingService.cpp b/src/servers/registrar/WatchingService.cpp index df21d29772..339995ac3c 100644 --- a/src/servers/registrar/WatchingService.cpp +++ b/src/servers/registrar/WatchingService.cpp @@ -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 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); } }