1996-03-03 02:18:46 +00:00
|
|
|
|
/* Interface to object for broadcasting Notification objects
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
|
|
|
|
|
Created: March 1996
|
|
|
|
|
|
|
|
|
|
This file is part of the GNU Objective C Class Library.
|
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __NotificationDispatcher_h_OBJECTS_INCLUDE
|
|
|
|
|
#define __NotificationDispatcher_h_OBJECTS_INCLUDE
|
|
|
|
|
|
|
|
|
|
/* A class for posting notifications to observer objects that request
|
|
|
|
|
them.
|
|
|
|
|
|
|
|
|
|
This implementation has several advantages over OpenStep's
|
|
|
|
|
NSNotificationCenter:
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
(1) Heavy use of hash tables and the use of LinkedList's make it
|
1996-03-03 02:18:46 +00:00
|
|
|
|
faster. Removing from the middle of LinkedList's is much more
|
|
|
|
|
efficient than removing from the middle of Array's.
|
|
|
|
|
|
|
|
|
|
(2) The way in which notifications are dispatched can be specified as
|
|
|
|
|
invocation objects instead of just selectors. Invocation objects
|
|
|
|
|
are more flexible than selectors in that they can hold more context
|
|
|
|
|
and, if desired, can call C functions instead of sending a message
|
1996-03-07 00:29:05 +00:00
|
|
|
|
to an object; (this way you may be able to avoid creating a new
|
1996-03-03 02:18:46 +00:00
|
|
|
|
class just to handle certain notifications).
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
(3) Instead of sending +defaultCenter, you can simply send +add...,
|
|
|
|
|
+remove... and +post... messages directly to the class object.
|
1996-03-03 02:18:46 +00:00
|
|
|
|
The class uses a static variable directly, instead of taking
|
|
|
|
|
the time for the extra +defaultCenter method call. It's both
|
|
|
|
|
easier for the user and more time efficient.
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
(4) You can call -addObserver:... with both name and object being
|
|
|
|
|
nil. This request will receive postings of *all* notifications.
|
|
|
|
|
Wow.
|
|
|
|
|
|
1996-03-03 02:18:46 +00:00
|
|
|
|
Although it offers extra features, the implementation has an
|
|
|
|
|
OpenStep-style interface also.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <objects/stdobjects.h>
|
|
|
|
|
#include <objects/LinkedList.h>
|
1996-03-07 00:29:05 +00:00
|
|
|
|
#include <objects/Array.h>
|
1996-03-03 02:18:46 +00:00
|
|
|
|
#include <Foundation/NSMapTable.h>
|
|
|
|
|
#include <objects/NSString.h>
|
|
|
|
|
|
|
|
|
|
@interface NotificationDispatcher : NSObject
|
|
|
|
|
{
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* `nr' stands for Notification Request Object; the interface for
|
|
|
|
|
this class is defined in the .m file. One of these is created
|
|
|
|
|
for each -add... call. */
|
|
|
|
|
|
1996-03-03 02:18:46 +00:00
|
|
|
|
/* For those observer requests with NAME=nil and OBJECT=nil. */
|
1996-03-07 00:29:05 +00:00
|
|
|
|
LinkedList *_anonymous_nr_list;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
/* For those observer requests with NAME=nil and OBJECT!=nil. */
|
1996-03-07 00:29:05 +00:00
|
|
|
|
NSMapTable *_object_2_nr_list;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
|
1996-03-07 00:29:05 +00:00
|
|
|
|
NSMapTable *_name_2_nr_list;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
/* The keys are observers; the values are Array's containing all
|
|
|
|
|
NotificationInvocation objects associated with the observer key. */
|
1996-03-07 00:29:05 +00:00
|
|
|
|
NSMapTable *_observer_2_nr_array;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Adding new observers. */
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Register INVOCATION to receive future notifictions that match NAME
|
|
|
|
|
and OBJECT. A nil passed as either NAME or OBJECT acts as a
|
|
|
|
|
wild-card. If NAME is nil, the NotificationDispatcher will send to
|
|
|
|
|
the observer all notification pertaining to OBJECT. If OBJECT is
|
|
|
|
|
nil, the NotificationDispatcher will send to the observer all
|
|
|
|
|
notification pertaining to NAME. If both OBJECT and NAME are nil,
|
|
|
|
|
send to the observer all notifications.
|
|
|
|
|
|
|
|
|
|
The notification will be posted by sending -invokeWithObject: to
|
|
|
|
|
INVOCATION argument. The argument of -invokeWithObject: will be a
|
|
|
|
|
Notification object. This use of Invocation objects is more
|
1996-03-03 02:18:46 +00:00
|
|
|
|
flexible than using a selector, since Invocation's can be set up
|
|
|
|
|
with more arguments, hold more context, and can be C functions.
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
OBJECT is not retained; this is done so these objects can tell when
|
|
|
|
|
there are no outstanding non-notification references remaining. If
|
|
|
|
|
an object may have added itself as an observer, it should call
|
|
|
|
|
+removeObserver: in its -dealloc method.
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
INVOCATION and NAME, however, are retained. */
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
- (void) addInvocation: (id <Invoking>)invocation
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Register OBSERVER to receive future notifications that match NAME
|
|
|
|
|
and OBJECT. A nil passed as either NAME or OBJECT acts as a
|
|
|
|
|
wild-card. If NAME is nil, the NotificationDispatcher will send to
|
|
|
|
|
the observer all notification pertaining to OBJECT. If OBJECT is
|
|
|
|
|
nil, the NotificationDispatcher will send to the observer all
|
|
|
|
|
notification pertaining to NAME. If both OBJECT and NAME are nil,
|
|
|
|
|
send to the observer all notifications.
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
The notification will be posted by sending -perform:withObject:
|
1996-03-07 00:29:05 +00:00
|
|
|
|
to the observer, with SEL and a Notification object as arguments.
|
|
|
|
|
|
|
|
|
|
Neither OBSERVER nor OBJECT are retained; this is done so these
|
|
|
|
|
objects can tell when there are no outstanding non-notification
|
|
|
|
|
references remaining. If an object may have added itself as an
|
|
|
|
|
observer, it should call +removeObserver: in its -dealloc method.
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
INVOCATION and NAME, however, are retained. */
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
- (void) addObserver: observer
|
|
|
|
|
selector: (SEL)sel
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
|
|
|
|
|
/* Class versions of the above two methods that send these messages
|
|
|
|
|
to the default NotificationDispatcher for the class. */
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
+ (void) addInvocation: (id <Invoking>)invocation
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
+ (void) addObserver: observer
|
|
|
|
|
selector: (SEL)sel
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Removing observers. */
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Remove all notification requests that would be sent to INVOCATION. */
|
|
|
|
|
|
|
|
|
|
- (void) removeInvocation: invocation;
|
|
|
|
|
|
|
|
|
|
/* Remove the notification requests matching NAME and OBJECT that
|
|
|
|
|
would be sent to INVOCATION. As with adding an observation
|
|
|
|
|
request, nil NAME or OBJECT act as wildcards. */
|
|
|
|
|
|
|
|
|
|
- (void) removeInvocation: invocation
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
|
1996-03-03 02:18:46 +00:00
|
|
|
|
/* Remove all records pertaining to OBSERVER. For instance, this
|
|
|
|
|
should be called before the OBSERVER is -dealloc'ed. */
|
|
|
|
|
|
|
|
|
|
- (void) removeObserver: observer;
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Remove the notification requests for the given NAME and OBJECT
|
|
|
|
|
parameters. As with adding an observation request, nil NAME or
|
|
|
|
|
OBJECT act as wildcards. */
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
- (void) removeObserver: observer
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Class versions of the above four methods that send these messages
|
1996-03-03 02:18:46 +00:00
|
|
|
|
to the default NotificationDispatcher for the class. */
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
+ (void) removeInvocation: invocation;
|
|
|
|
|
+ (void) removeInvocation: invocation
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
+ (void) removeObserver: observer;
|
|
|
|
|
+ (void) removeObserver: observer
|
|
|
|
|
name: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT.
|
|
|
|
|
The INFO arguent does not have to be a Dictionary. If there is a single
|
|
|
|
|
object that should be associated with the notification, you can simply
|
|
|
|
|
pass that single object instead of a Dictionary containing the object. */
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
|
|
|
|
- (void) postNotification: notification;
|
|
|
|
|
- (void) postNotificationName: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
- (void) postNotificationName: (id <String>)name
|
|
|
|
|
object: object
|
1996-03-07 00:29:05 +00:00
|
|
|
|
userInfo: info;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
1996-03-07 00:29:05 +00:00
|
|
|
|
/* Class versions of the above three methods that send these messages
|
1996-03-03 02:18:46 +00:00
|
|
|
|
to the default NotificationDispatcher for the class. */
|
|
|
|
|
|
|
|
|
|
+ (void) postNotification: notification;
|
|
|
|
|
+ (void) postNotificationName: (id <String>)name
|
|
|
|
|
object: object;
|
|
|
|
|
+ (void) postNotificationName: (id <String>)name
|
|
|
|
|
object: object
|
1996-03-07 00:29:05 +00:00
|
|
|
|
userInfo: info;
|
1996-03-03 02:18:46 +00:00
|
|
|
|
|
1996-03-12 14:55:49 +00:00
|
|
|
|
+ defaultInstance;
|
|
|
|
|
|
1996-03-03 02:18:46 +00:00
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@interface NotificationDispatcher (OpenStepCompat)
|
|
|
|
|
+ defaultCenter;
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
#endif /* __NotificationDispatcher_h_OBJECTS_INCLUDE */
|