API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPOperation.j
Go to the documentation of this file.
1 /*
2  * CPOperation.j
3  *
4  * Created by Johannes Fahrenkrug.
5  * Copyright 2009, Springenwerk.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 
29 
36 
43 
50 
57 
58 
65 @implementation CPOperation : CPObject
66 {
68  BOOL _cancelled;
69  BOOL _executing;
70  BOOL _finished;
71  BOOL _ready;
72  int _queuePriority;
73  JSObject _completionFunction;
74  CPArray _dependencies;
75 }
76 
77 - (void)main
78 {
79  // should be overridden in child class
80 }
81 
82 - (id)init
83 {
84  self = [super init];
85 
86  if (self)
87  {
88  _cancelled = NO;
89  _executing = NO;
90  _finished = NO;
91  _ready = YES;
92  _dependencies = [[CPArray alloc] init];
93  _queuePriority = CPOperationQueuePriorityNormal;
94  }
95  return self;
96 }
97 
101 - (void)start
102 {
103  if (!_cancelled)
104  {
105  [self willChangeValueForKey:@"isExecuting"];
106  _executing = YES;
107  [self didChangeValueForKey:@"isExecuting"];
108  [self main];
109  if (_completionFunction)
110  {
111  _completionFunction();
112  }
113  [self willChangeValueForKey:@"isExecuting"];
114  _executing = NO;
115  [self didChangeValueForKey:@"isExecuting"];
116  [self willChangeValueForKey:@"isFinished"];
117  _finished = YES;
118  [self didChangeValueForKey:@"isFinished"];
119  }
120 }
121 
126 - (BOOL)isCancelled
127 {
128  return _cancelled;
129 }
130 
135 - (BOOL)isExecuting
136 {
137  return _executing;
138 }
139 
144 - (BOOL)isFinished
145 {
146  return _finished;
147 }
148 
153 - (BOOL)isConcurrent
154 {
155  return NO;
156 }
157 
162 - (BOOL)isReady
163 {
164  return _ready;
165 }
166 
171 - (JSObject)completionFunction
172 {
173  return _completionFunction;
174 }
175 
179 - (void)setCompletionFunction:(JSObject)aJavaScriptFunction
180 {
181  _completionFunction = aJavaScriptFunction;
182 }
183 
188 - (void)addDependency:(CPOperation)anOperation
189 {
190  [self willChangeValueForKey:@"dependencies"];
191  [anOperation addObserver:self
192  forKeyPath:@"isFinished"
193  options:(CPKeyValueObservingOptionNew)
194  context:NULL];
195  [_dependencies addObject:anOperation];
196  [self didChangeValueForKey:@"dependencies"];
197  [self _updateIsReadyState];
198 }
199 
204 - (void)removeDependency:(CPOperation)anOperation
205 {
206  [self willChangeValueForKey:@"dependencies"];
207  [_dependencies removeObject:anOperation];
208  [anOperation removeObserver:self
209  forKeyPath:@"isFinished"];
210  [self didChangeValueForKey:@"dependencies"];
211  [self _updateIsReadyState];
212 }
213 
218 - (CPArray)dependencies
219 {
220  return _dependencies;
221 }
222 
226 - (void)waitUntilFinished
227 {
228 }
229 
233 - (void)cancel
234 {
235  [self willChangeValueForKey:@"isCancelled"];
236  _cancelled = YES;
237  [self didChangeValueForKey:@"isCancelled"];
238 }
239 
244 - (void)setQueuePriority:(int)priority
245 {
246  _queuePriority = priority;
247 }
248 
253 - (int)queuePriority
254 {
255  return _queuePriority;
256 }
257 
258 // We need to observe the "isFinished" key of our dependent operations so we can update our own "isReady" state
259 - (void)observeValueForKeyPath:(CPString)keyPath
260  ofObject:(id)object
261  change:(CPDictionary)change
262  context:(void)context
263 {
264  if (keyPath == @"isFinished")
265  {
266  [self _updateIsReadyState];
267  }
268 }
269 
270 - (void)_updateIsReadyState
271 {
272  var newReady = YES;
273  if (_dependencies && [_dependencies count] > 0)
274  {
275  var i = 0;
276  for (i = 0; i < [_dependencies count]; i++)
277  {
278  if (![[_dependencies objectAtIndex:i] isFinished])
279  {
280  newReady = NO;
281  }
282  }
283  }
284 
285  if (newReady != _ready)
286  {
287  [self willChangeValueForKey:@"isReady"];
288  _ready = newReady;
289  [self didChangeValueForKey:@"isReady"];
290  }
291 }
292 
293 @end