home *** CD-ROM | disk | FTP | other *** search
/ OpenStep (Enterprise) / OpenStepENTCD.toast / OEDEV / EODEV.Z / EOObserver.h < prev    next >
Encoding:
Text File  |  1996-09-11  |  7.1 KB  |  164 lines

  1. // EOObserver.h
  2. // Copyright (c) 1995, NeXT Software, Inc. All rights reserved. 
  3. //
  4. // The EOObserver provides an efficient specialized notification mechanism
  5. // for an observing object to find out when another object is about to change
  6. // its state.
  7. // "Observable" objects (typically all business objects) are reponsible for calling
  8. // [self willChange] prior to altering their state (in a set method, for instance).
  9. // Observers, such as the EOEditingContext, add themselves as observers to the objects
  10. // they care about in the EOObserverCenter, and receive objectWillChange: notification
  11. // whenever an observed object sends [self willChange].
  12. // Application objects interested in notification of object change are usually better
  13. // of listening for aggregate change notification from the EOEditingContext rather than
  14. // observing the objects directly.
  15. #import <Foundation/Foundation.h>
  16.  
  17. @interface NSObject (EOObserver)
  18. - (void)willChange;
  19.     // Called by a subject to message all of its observers.
  20.     // Convenience for [EOObserverCenter notifyObserversObjectWillChange:self]
  21. @end
  22.  
  23. @protocol EOObserving <NSObject>
  24. - (void)objectWillChange:(id)subject;
  25.     // called when object being observed is about to change
  26. @end
  27.  
  28. @interface EOObserverCenter : NSObject
  29. + (void)addObserver:(id <EOObserving>)observer forObject:(id)object;
  30.     // Registers the given observer to receive objectWillChange:
  31.     // notification when the given object calls [self willChange];
  32.     // Multiple calls with same observer and same object are coalesced.
  33.  
  34. + (void)removeObserver:(id <EOObserving>)observer forObject:(id)object;
  35.     // Unregisters the given observer from observing the given object.
  36.     // Observers are responsible for removing themselves from every subject
  37.     // they observe (perhaps in dealloc)
  38.  
  39. + (void)notifyObserversObjectWillChange:(id)object;
  40.     // Notifies all observers of this object that it will change.
  41.     // This is called by [NSObject willChange];
  42.     // As an optimization, multiple consecutive willChange notifications for
  43.     // the same object are automatically suppressed.  If an observer wants to
  44.     // ensure that it receives notification the next time the last object
  45.     // to change changes again, it should call
  46.     // [EOObserverCenter notifyObserversObjectWillChange:nil]
  47.  
  48. + (NSArray *)observersForObject:(id)object;
  49.     // Returns a list of all objects currently observing the given object.
  50.  
  51. + (id)observerForObject:(id)object ofClass:(Class)targetClass;
  52.     // returns an observer of the given object (if any) of the target class.
  53.     // If many such observers exist, just one is returned.
  54.  
  55. + (void)suppressObserverNotification;
  56. + (void)enableObserverNotification;
  57.     // Turn on and off listening to object change notifications.
  58.     // Supressed notifications are lost forever.
  59.     // These calls nest.
  60. + (unsigned)observerNotificationSuppressCount;
  61.  
  62. + (void)addOmniscientObserver:(id <EOObserving>)observer;
  63. + (void)removeOmniscientObserver:(id <EOObserving>)observer;
  64.     // The observer will see ALL [self willChange] notifications
  65.     // on all objects.  Use with care!
  66. @end
  67.  
  68.  
  69. // EODelayedObservers are observers that receive asynchronous notification
  70. // of changes to observed objects.  EOAssociations, for examples are
  71. // asynchronous observers of their EODisplayGroups.  The EODelayedObserverQueue
  72. // supports the asynchronous notfication of EODelayedObservers.
  73. // Multiple notifications to the same observer are coalesced.
  74. // DelayedObservers have a static priority and are notified in priority order.
  75. @class EODelayedObserverQueue;
  76.  
  77. typedef enum {
  78.         EOObserverPriorityImmediate,  // Synchronous delivery, not delayed
  79.         EOObserverPriorityFirst,      // 
  80.         EOObserverPrioritySecond,     // Master EODetailAssociation delivery
  81.         EOObserverPriorityThird,      // Default EOAssociation priority
  82.         EOObserverPriorityFourth,     // 
  83.         EOObserverPriorityFifth,      // 
  84.         EOObserverPrioritySixth,      // EODisplayGroup clears didChange state
  85.         EOObserverPriorityLater       // 
  86. } EOObserverPriority;
  87. #define EOObserverNumberOfPriorities ((unsigned)EOObserverPriorityLater + 1)
  88.  
  89.  
  90. @interface EODelayedObserver : NSObject <EOObserving> {
  91.     @public // Public only to the observer queue.  do not use.
  92.     EODelayedObserver *_next;   // linked list.  Nil if not on list.
  93. }
  94. - (void)objectWillChange:(id)subject;
  95.     // overridden by EODelayedObserver to put observer on queue
  96.  
  97. - (EOObserverPriority)priority;
  98.     // the observer should return its notification priority (order)
  99.     // default is EOObserverPriorityThird
  100. - (EODelayedObserverQueue *)observerQueue;
  101.     // allows observer to determine the queue it waits on.
  102.     // default is [EODelayedObserverQueue defaultQueue]
  103.  
  104. // Must be implemented by subclasses
  105. - (void)subjectChanged;
  106.     // called by the delayed observer queue to let observer take
  107.     // appropriate action.  The observer may have been "watching"
  108.     // more than one subject, and any change notifications from these
  109.     // subjects are coalesced into a single subjectChanged call.
  110.     // Therefore, the observer is responsible for keeping track of
  111.     // the set of of subjects it is observing, and checking with them
  112.     // upon receiving the subjectChanged message
  113.  
  114. - (void)discardPendingNotification;
  115.     // if this observer is currently enqueued for delayed notification,
  116.     // removes it from the queue.  It may be appropriate to call this when
  117.     // a DelayedObserver is dealloced.
  118. @end
  119.  
  120. // used with NSRunLoop's performSelector:target:argument:order:modes:
  121. enum {
  122.     EOFlushDelayedObserversRunLoopOrdering        = 400000
  123. };
  124.  
  125.  
  126. @interface EODelayedObserverQueue : NSObject
  127. {
  128.     EODelayedObserver *_queue[EOObserverNumberOfPriorities];  // lists for each priority
  129.     unsigned _highestNonEmptyQueue;
  130.     BOOL _haveEntryInNotificationQueue;
  131.     NSArray *_modes;
  132. }
  133. + (EODelayedObserverQueue *)defaultObserverQueue;
  134.  
  135. - (void)enqueueObserver:(EODelayedObserver *)observer;
  136.     // Called by EODelayedObserver objectWillChange: to enqueue the object for
  137.     // asynchronous notification.  Already enqueued observers are not enqueued again.
  138. - (void)dequeueObserver:(EODelayedObserver *)observer;
  139.     // remove an observer from the queue.
  140. - (void)notifyObserversUpToPriority:(EOObserverPriority)lastPriority;
  141.     // Do the updating of all observers with priority no lower than lastPriority.
  142.     // The first time an observer is added to the queue, the queue registers for
  143.     // ASAP notification from the NSNotificationQueue.  When this notification is
  144.     // received, the queue calls [self notifyObserversUpToPriority:EOObserverPrioritySixth];
  145.  
  146. - (void)setRunLoopModes:(NSArray *)modes;
  147. - (NSArray *)runLoopModes;
  148.     // Set the modes passed to the notificationQueue to determine
  149.     // when DelayedObservers are notified.
  150. @end
  151.  
  152.  
  153. // Observer that passes on notification to its target.  When proxy receives
  154. // subjectChanged it send its target its action passing itself as the argument.
  155. // This is useful for objects that want to be asynchronous observers, but cannot
  156. // subclass from EODelayedObserver.
  157. @interface EOObserverProxy : EODelayedObserver {
  158.     id _target;
  159.     SEL _action;
  160.     EOObserverPriority _priority;
  161. }
  162. - initWithTarget:(id)target action:(SEL)action priority:(EOObserverPriority)priority;
  163. @end
  164.