API  1.0.0
CPNotificationQueue.j
Go to the documentation of this file.
1 /*
2  * CPNotificationQueue.j
3  * Foundation
4  *
5  * Created by Alexandre Wilhelm.
6  * Copyright 2015 <[email protected]>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 @typedef CPPostingStyle
25 
26 /*
27  @global
28  @group CPViewAutoresizingMasks
29  The default resizingMask, the view will not resize or reposition itself.
30 */
32 /*
33  @global
34  @group CPPostingStyle
35  The notification is posted at the end of the current notification callout or timer.
36 */
38 /*
39  @global
40  @group CPPostingStyle
41  The notification is posted immediately after coalescing.
42 */
44 
45 
46 @typedef CPNotificationCoalescing
47 
48 /*
49  @global
50  @group CPNotificationCoalescing
51  Do not coalesce notifications in the queue.
52 */
54 /*
55  @global
56  @group CPNotificationCoalescing
57  Coalesce notifications with the same name.
58 */
60 /*
61  @global
62  @group CPNotificationCoalescing
63  Coalesce notifications with the same object.
64 */
66 
67 
69 
71 
87 @implementation CPNotificationQueue : CPObject
88 {
89  BOOL _runLoopLaunched;
90  CPMutableArray _postNowNotifications;
91  CPMutableArray _postIdleNotifications;
92  CPMutableArray _postASAPNotifications;
93  CPNotificationCenter _notificationCenter;
94 }
95 
96 
97 #pragma mark -
98 #pragma mark Class methods
99 
103 + (id)defaultQueue
104 {
107 
109 }
110 
111 
112 #pragma mark -
113 #pragma mark Init methods
114 
120 - (id)initWithNotificationCenter:(CPNotificationCenter)aNotificationCenter
121 {
122  if (self = [super init])
123  {
124  _notificationCenter = aNotificationCenter;
125  _postNowNotifications = [CPMutableArray new];
126  _postIdleNotifications = [CPMutableArray new];
127  _postASAPNotifications = [CPMutableArray new];
128  }
129 
130  return self;
131 }
132 
133 
134 #pragma mark -
135 #pragma mark Enqueue methods
136 
142 - (void)enqueueNotification:(CPNotification)notification postingStyle:(CPPostingStyle)postingStyle
143 {
144  [self enqueueNotification:notification postingStyle:postingStyle coalesceMask:CPNotificationCoalescingOnName|CPNotificationCoalescingOnSender forModes:[CPDefaultRunLoopMode]];
145 }
146 
154 - (void)enqueueNotification:(CPNotification)notification postingStyle:(CPPostingStyle)postingStyle coalesceMask:(CPNotificationCoalescing)coalesceMask forModes:(CPArray)modes
155 {
156  [self _removeNotification:notification coalesceMask:coalesceMask];
157 
158  switch (postingStyle)
159  {
160  case CPPostWhenIdle:
161  [_postIdleNotifications addObject:notification];
162  break;
163 
164  case CPPostASAP:
165  [_postASAPNotifications addObject:notification];
166  break;
167 
168  case CPPostNow:
169  [_postNowNotifications addObject:notification];
170  break;
171  }
172 
173  if ([_postIdleNotifications count] || [_postASAPNotifications count] || [_postNowNotifications count])
174  [self _runRunLoop];
175 
176  if (postingStyle == CPPostNow)
177  {
178  for (var i = [modes count] - 1; i >= 0; i--)
179  [[CPRunLoop currentRunLoop] limitDateForMode:modes[i]];
180  }
181 }
182 
183 
184 #pragma mark -
185 #pragma mark Dequeue methods
186 
192 - (void)dequeueNotificationsMatching:(CPNotification)notification coalesceMask:(CPUInteger)coalesceMask
193 {
194  [self _removeNotification:notification coalesceMask:coalesceMask];
195 }
196 
197 
198 #pragma mark -
199 #pragma mark RunLoop methods
200 
204 - (void)_runRunLoop
205 {
206  if (!_runLoopLaunched)
207  {
208  [runLoop performSelector:@selector(_launchNotificationsInQueue) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
209  _runLoopLaunched = YES;
210  }
211 }
212 
216 - (void)_launchNotificationsInQueue
217 {
218  _runLoopLaunched = NO;
219 
220  if ([_postNowNotifications count])
221  {
222  [self _launchNotificationsForArray:_postNowNotifications];
223  [self _runRunLoop];
224  return;
225  }
226 
227  if ([_postASAPNotifications count])
228  {
229  [self _launchNotificationsForArray:_postASAPNotifications];
230  [self _runRunLoop];
231  return;
232  }
233 
234  if ([_postIdleNotifications count])
235  {
236  [self _launchNotificationsForArray:_postIdleNotifications];
237  [self _runRunLoop];
238  return;
239  }
240 }
241 
242 
243 #pragma mark -
244 #pragma mark Posting methods
245 
249 - (void)_launchNotificationsForArray:(CPArray)anArray
250 {
251  for (var i = [anArray count] - 1; i >= 0; i--)
252  {
253  var notification = anArray[i];
254  [_notificationCenter postNotification:notification];
255  }
256 
257  [anArray removeAllObjects];
258 }
259 
260 
261 #pragma mark -
262 #pragma mark Remove methods
263 
267 - (void)_removeNotification:(CPNotification)notification coalesceMask:(CPUInteger)coalesceMask
268 {
269  [self _removeNotification:notification coalesceMask:coalesceMask inNotifications:_postNowNotifications];
270  [self _removeNotification:notification coalesceMask:coalesceMask inNotifications:_postASAPNotifications];
271  [self _removeNotification:notification coalesceMask:coalesceMask inNotifications:_postIdleNotifications];
272 }
273 
277 - (void)_removeNotification:(CPNotification)aNotification coalesceMask:(CPUInteger)coalesceMask inNotifications:(CPArray)notifications
278 {
279  var notificationsToRemove = [],
280  name = [aNotification name],
281  sender = [aNotification object];
282 
283  for (var i = [notifications count] - 1; i >= 0; i--)
284  {
285  var notification = notifications[i];
286 
287  if (notification == aNotification)
288  {
289  [notificationsToRemove addObject:notification];
290  continue;
291  }
292 
293  if (coalesceMask & CPNotificationNoCoalescing)
294  continue;
295 
296  if (coalesceMask & CPNotificationCoalescingOnName && coalesceMask & CPNotificationCoalescingOnSender)
297  {
298  if ([notification object] == sender && [notification name] == name)
299  [notificationsToRemove addObject:notification];
300 
301  continue;
302  }
303 
304  if (coalesceMask & CPNotificationCoalescingOnName)
305  {
306  if ([notification name] == name)
307  [notificationsToRemove addObject:notification];
308 
309  continue;
310  }
311 
312  if (coalesceMask & CPNotificationCoalescingOnSender)
313  {
314  if ([notification object] == sender)
315  [notificationsToRemove addObject:notification];
316 
317  continue;
318  }
319  }
320 
321  [notifications removeObjectsInArray:notificationsToRemove];
322 }
323 
324 @end
id init()
Definition: CALayer.j:126
The main run loop for the application.
Definition: CPRunLoop.h:2
id initWithNotificationCenter:(CPNotificationCenter aNotificationCenter)
var CPNotificationDefaultQueue
CPNotificationCenter defaultCenter()
var runLoop
CPRunLoop mainRunLoop()
Definition: CPRunLoop.j:240
CPPostingStyle CPPostWhenIdle
CPNotificationCoalescing CPNotificationNoCoalescing
CPNotificationQueue objects act as buffers for notification centers (instances of CPNotificationCente...
A notification that can be posted to a CPNotificationCenter.
Definition: CPNotification.h:2
void enqueueNotification:postingStyle:coalesceMask:forModes:(CPNotification notification, [postingStyle] CPPostingStyle postingStyle, [coalesceMask] CPNotificationCoalescing coalesceMask, [forModes] CPArray modes)
CPString name
Definition: CPException.j:47
CPNotificationCoalescingOnSender
Sends messages (CPNotification) between objects.
CPNotificationCoalescingOnName
id alloc()
Definition: CPObject.j:130