From 51e5c73ecaea4775fbccf174bb1beb4993e57334 Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Fri, 28 Sep 2007 21:14:39 +0000 Subject: [PATCH] Phase I of MessageFilter.dox git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22350 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- docs/user/app/MessageFilter.dox | 329 +++++++++++++++++++++++++++++++ docs/user/app/_app_messaging.dox | 6 +- 2 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 docs/user/app/MessageFilter.dox diff --git a/docs/user/app/MessageFilter.dox b/docs/user/app/MessageFilter.dox new file mode 100644 index 0000000000..a915ee7908 --- /dev/null +++ b/docs/user/app/MessageFilter.dox @@ -0,0 +1,329 @@ +/* + * Copyright 2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Niels Sascha Reedijk, niels.reedijk@gmail.com + */ + + +/*! + \file MessageFilter.h + \brief Provides BMessageFilter class. +*/ + + +/*! + \enum filter_result + \brief Return Codes and Protocol of the #filter_hook. + + These return codes should be used in your own filter_hook function, or by + your overrided BMessageFilter::Filter() function. +*/ + + +/*! + \var B_SKIP_MESSAGE + \brief The message does not pass the filter criteria and should not be + handled. +*/ + + +/*! + \var B_DISPATCH_MESSAGE + \brief The message passes the filter criteria and should be dispatched to + a BHandler. +*/ + + +/*! + \typedef filter_result (*filter_hook) (BMessage* message, + BHandler** target, BMessageFilter* filter) + \brief Prototype for a custom \c filter_hook for use in the BMessageFilter + class. + + This hook can be used when you are constructing a new BMessageFilter + object. It is a custom filter function you can use. + + This hook should handle the following parameters: + + \param[in] message The message that needs to be verified. + \param[out] target If your filter hook is conscious about the available + handlers, you can set a specific BHandler based on your filters + requirements. You do not have to change this field, because there will + always be a working default. + \param[in] filter A pointer to the filter from which this hook is called. + + \return You should return #B_SKIP_MESSAGE in case the message does not + conform to the filter criteria, or #B_DISPATCH_MESSAGE if the message + passes these criteria. + + \see BMessageFilter(uint32, filter_hook) + BMessageFilter(message_delivery, message_source, filter_hook) + BMessageFilter(message_delivery, message_source, uint32, filter_hook) +*/ + + +/*! + \enum message_delivery + \brief BMessageFilter filter criteria on how a message was delivered. + + Two constructors of the BMessageFilter class allow you to specify that it + should filter based on how the message was delivered. There are two ways in + which messages can be delivered within the Haiku API: by direct delivery + using the BLooper::PostMessage() function, and by drag and drop in the GUI. + With this filter you can, for example, specify that your handler only + handles deliveries that were programmed by you, and not any random drag and + drop actions initiated by the user. +*/ + + +/*! + \var B_ANY_DELIVERY + \brief Accept both delivery methods. +*/ + + +/*! + \var B_DROPPED_DELIVERY + \brief Only accept messages that were dropped by the user in the GUI. +*/ + + +/*! + \var B_PROGRAMMED_DELIVERY + \brief Only accept messages that were delivered using the + BLooper::PostMessage() method. +*/ + + +/*! + \enum message_source + \brief BMessageFilter filter criteria on the source of a message. + + One of the key features of the messaging system of Haiku, is the ability + to send messages between applications. However, your handler or looper + might have been written in such a way that it would make no sense to try + to process messages from an external source. Use these filter criteria to + filter the unwanted messages out. + + You use these constants in the constructors of the BMessageFilter class. + + \warning System messages, for example from the \c app_server, are + considered remote messages. Keep this in mind when you want to set up + criteria for your window and application loopers. +*/ + + +/*! + \var B_ANY_SOURCE + \brief Accept both local and remote messages. +*/ + + +/*! + \var B_REMOTE_SOURCE + \brief Only accept messages from a remote source, so from other + applications. +*/ + + +/*! + \var B_LOCAL_SOURCE + \brief Only accept messages from your own local application. +*/ + + +/*! + \class BMessageFilter + \brief Describes a message filter for BLooper and BHandler. + + Objects of this class serve as a description of properties that incoming + messages should have in order to be processed by a handler or a looper. + BMessageFilter provides three default filter criteria, the \c what + constant, the #message_source and the type of message_delivery, + and an extendible #filter_hook. + + BMessageFilter's standard filter criteria can be extended in two ways: + -# Specify a #filter_hook. This is a static function that takes a message + and a pointer to a BHandler as arguments, and allows you to accept or + reject the message, and even redirect it to a specific BHandler. + -# Subclass the BMessageFilter class and override the Filter() function. + This has the same capabilities as using a #filter_hook, but it allows + cleaner code (in some cases). + + Both methods have their merits, but please remember that you have to choose + which one you want to use, since you can't use both. The order of + processing the criteria is in this order: the source, the delivery method, + the filter hook and then the overrided Filter() method. Additionally, if a + #filter_hook is registered, the Filter() method will not be called. + + The BMessageFilter objects are used in two different classes. They can be + associated with specific BHandlers. Using the BHandler::AddFilter() + and the BHandler::SetFilterList() methods, you can add filters to the + filter list. It is also possible to associate filters with BLoopers. In + that case, all incoming messages of that looper are checked against the + criteria. To perform filtering in loopers, have a look at the + BLooper::AddCommonFilter() and the BLooper::SetCommonFilterList() methods. + + An example of a filter that selects on the default criteria: +\code +// Our window does not handle drop events. +BMessageFilter *filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE); +window->AddCommonFilter(filter); +\endcode + + An example of a filter that only allows one type of message: +\code +BMessageFilter *filter = new BMessageFilter(kHappyMessages); +handler->AddFilter(filter); +\endcode + + An example of a #filter_hook: +\code +// The handler depends on the what code of a message +filter_result +ScreenMessage(BMessage* message, BHandler** target, BMessageFilter* filter) +{ + switch (message->what) { + case kTcpEvent: + target = &fTcpHandler; + return B_DISPATCH_MESSAGE; + case kUdpEvent: + target = &fUdpHandler; + return B_DISPATCH_MESSAGE; + } + + return B_SKIP_MESSAGE; +} + +BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, ScreenMessage); +looper->AddCommonFilter(filter); +\endcode + + The two classes that use BMessageFilter are BLooper and BHandler. In the + general messaging introduction, there is also a section on + \ref app-messaging-receiving "handling messages". +*/ + + + +/*! + \fn BMessageFilter::BMessageFilter(uint32 inWhat, filter_hook func) + \brief Construct a new object that filters on a message constant. + + You can also specify a #filter_hook, if you want apply custom filter + criteria. + + \see BMessageFilter(message_delivery, message_source, filter_hook) + \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) +*/ + + +/*! + \fn BMessageFilter::BMessageFilter(message_delivery delivery, + message_source source, filter_hook func) + \brief Construct a new object that filters on delivery method and message + source. + + You can also specify a #filter_hook, if you want to apply custom filter + criteria. + + \see BMessageFilter(uint32 what,filter_hook) + \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) +*/ + + +/*! + \fn BMessageFilter::BMessageFilter(message_delivery delivery, + message_source source, uint32 inWhat, filter_hook func) + \brief Construct a new object that filters on delivery method, message + source and specific message constants. + + You can also specify a #filter_hook, if you want to apply custom filter + criteria. + + \see BMessageFilter(uint32 what,filter_hook) + \see BMessageFilter(message_delivery, message_source, filter_hook) +*/ + + +/*! + \fn BMessageFilter::BMessageFilter(const BMessageFilter& filter) + \brief Copy constructor. Copy the criteria from another object. +*/ + + +/*! + \fn BMessageFilter::BMessageFilter(const BMessageFilter* filter) + \brief Create a new object based on criteria of another object. +*/ + + +/*! + \fn BMessageFilter::~BMessageFilter() + \brief Destructor. Does nothing. +*/ + + +/*! + \fn BMessageFilter &BMessageFilter::operator=(const BMessageFilter& from) + \brief Assignment operator. Copies criteria from another filter. +*/ + + +/*! + \fn filter_result BMessageFilter::Filter(BMessage* message, + BHandler** target) + \brief Filter the message according to custom criteria. + + The default implementation of this method always returns + \c B_DISPATCH_MESSAGE. You can override this method in subclasses to + suit your own criteria. You receive two arguments. + + \param message The message that needs to be filtered. + \param target If you want to, you can specify a handler that should handle + this message. Note that you do have to pass a handler that is + associated with the looper that received the message. + + \return You should return \c B_DISPATCH_MESSAGE in case the message passes + the tests, or \c B_SKIP_MESSAGE in case the message does not pass. +*/ + + +/*! + \fn message_delivery BMessageFilter::MessageDelivery() const + \brief Return the message_delivery criterium of this filter. +*/ + + +/*! + \fn message_source BMessageFilter::MessageSource() const + \brief Return the message_source criterium of this filter. +*/ + + +/*! + \fn uint32 BMessageFilter::Command() const + \brief Return the accepted message constant. + + This method returns zero (0) in case this filter does not filter based on + the message constant. + + \see FiltersAnyCommand() const +*/ + + +/*! + \fn bool BMessageFilter::FiltersAnyCommand() const + \brief Return whether or not this filter has a message command criterium. + + \see Command() const +*/ + + +/*! + \fn BLooper *BMessageFilter::Looper() const + \brief Return the looper this filter is associated with. +*/ + diff --git a/docs/user/app/_app_messaging.dox b/docs/user/app/_app_messaging.dox index aab4f94e1e..4d4ea2c2fe 100644 --- a/docs/user/app/_app_messaging.dox +++ b/docs/user/app/_app_messaging.dox @@ -65,8 +65,8 @@ Messages can be posted to the looper by using the object's PostMessage() method. This method puts the message in the BMessageQueue of the looper. Since PostMessage() is asynchronous, the message might not be handled - immediately. See \link app_messaging_overview_bmessenger BMessenger - \endlink for a synchronous implementation. + immediately. See \ref app_messaging_overview_bmessenger "BMessenger" + for a synchronous implementation. Loopers can have a generic filter that discards messages based on user-definable characteristics. The BMessageFilter class provides the @@ -108,7 +108,7 @@ that the Haiku API classes handle, and not actually handling these messages could lead to inconsistent internal behavior. - \subsection app_messaging-overview-bmessenger BMessenger + \subsection app_messaging_overview_bmessenger BMessenger BMessenger objects can send messages to both local and remote targets. For local targets, a BMessenger provides an advantage over directly calling