![]() |
API 0.9.5
|
00001 /* 00002 * CPOperation.j 00003 * 00004 * Created by Johannes Fahrenkrug. 00005 * Copyright 2009, Springenwerk. 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 00028 CPOperationQueuePriorityVeryLow = -8; 00029 00035 CPOperationQueuePriorityLow = -4; 00036 00042 CPOperationQueuePriorityNormal = 0; 00043 00049 CPOperationQueuePriorityHigh = 4; 00050 00056 CPOperationQueuePriorityVeryHigh = 8; 00057 00058 00065 @implementation CPOperation : CPObject 00066 { 00067 CPArray operations; 00068 BOOL _cancelled; 00069 BOOL _executing; 00070 BOOL _finished; 00071 BOOL _ready; 00072 int _queuePriority; 00073 JSObject _completionFunction; 00074 CPArray _dependencies; 00075 } 00076 00077 - (void)main 00078 { 00079 // should be overridden in child class 00080 } 00081 00082 - (id)init 00083 { 00084 self = [super init]; 00085 00086 if (self) 00087 { 00088 _cancelled = NO; 00089 _executing = NO; 00090 _finished = NO; 00091 _ready = YES; 00092 _dependencies = [[CPArray alloc] init]; 00093 _queuePriority = CPOperationQueuePriorityNormal; 00094 } 00095 return self; 00096 } 00097 00101 - (void)start 00102 { 00103 if (!_cancelled) 00104 { 00105 [self willChangeValueForKey:@"isExecuting"]; 00106 _executing = YES; 00107 [self didChangeValueForKey:@"isExecuting"]; 00108 [self main]; 00109 if (_completionFunction) 00110 { 00111 _completionFunction(); 00112 } 00113 [self willChangeValueForKey:@"isExecuting"]; 00114 _executing = NO; 00115 [self didChangeValueForKey:@"isExecuting"]; 00116 [self willChangeValueForKey:@"isFinished"]; 00117 _finished = YES; 00118 [self didChangeValueForKey:@"isFinished"]; 00119 } 00120 } 00121 00126 - (BOOL)isCancelled 00127 { 00128 return _cancelled; 00129 } 00130 00135 - (BOOL)isExecuting 00136 { 00137 return _executing; 00138 } 00139 00144 - (BOOL)isFinished 00145 { 00146 return _finished; 00147 } 00148 00153 - (BOOL)isConcurrent 00154 { 00155 return NO; 00156 } 00157 00162 - (BOOL)isReady 00163 { 00164 return _ready; 00165 } 00166 00171 - (JSObject)completionFunction 00172 { 00173 return _completionFunction; 00174 } 00175 00179 - (void)setCompletionFunction:(JSObject)aJavaScriptFunction 00180 { 00181 _completionFunction = aJavaScriptFunction; 00182 } 00183 00188 - (void)addDependency:(CPOperation)anOperation 00189 { 00190 [self willChangeValueForKey:@"dependencies"]; 00191 [anOperation addObserver:self 00192 forKeyPath:@"isFinished" 00193 options:(CPKeyValueObservingOptionNew) 00194 context:NULL]; 00195 [_dependencies addObject:anOperation]; 00196 [self didChangeValueForKey:@"dependencies"]; 00197 [self _updateIsReadyState]; 00198 } 00199 00204 - (void)removeDependency:(CPOperation)anOperation 00205 { 00206 [self willChangeValueForKey:@"dependencies"]; 00207 [_dependencies removeObject:anOperation]; 00208 [anOperation removeObserver:self 00209 forKeyPath:@"isFinished"]; 00210 [self didChangeValueForKey:@"dependencies"]; 00211 [self _updateIsReadyState]; 00212 } 00213 00218 - (CPArray)dependencies 00219 { 00220 return _dependencies; 00221 } 00222 00226 - (void)waitUntilFinished 00227 { 00228 } 00229 00233 - (void)cancel 00234 { 00235 [self willChangeValueForKey:@"isCancelled"]; 00236 _cancelled = YES; 00237 [self didChangeValueForKey:@"isCancelled"]; 00238 } 00239 00244 - (void)setQueuePriority:(int)priority 00245 { 00246 _queuePriority = priority; 00247 } 00248 00253 - (int)queuePriority 00254 { 00255 return _queuePriority; 00256 } 00257 00258 // We need to observe the "isFinished" key of our dependent operations so we can update our own "isReady" state 00259 - (void)observeValueForKeyPath:(CPString)keyPath 00260 ofObject:(id)object 00261 change:(CPDictionary)change 00262 context:(void)context 00263 { 00264 if (keyPath == @"isFinished") 00265 { 00266 [self _updateIsReadyState]; 00267 } 00268 } 00269 00270 - (void)_updateIsReadyState 00271 { 00272 var newReady = YES; 00273 if (_dependencies && [_dependencies count] > 0) 00274 { 00275 var i = 0; 00276 for (i = 0; i < [_dependencies count]; i++) 00277 { 00278 if (![[_dependencies objectAtIndex:i] isFinished]) 00279 { 00280 newReady = NO; 00281 } 00282 } 00283 } 00284 00285 if (newReady != _ready) 00286 { 00287 [self willChangeValueForKey:@"isReady"]; 00288 _ready = newReady; 00289 [self didChangeValueForKey:@"isReady"]; 00290 } 00291 } 00292 00293 @end