Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

296 lines (264 sloc) 6.97 kB
/*
* CPOperation.j
*
* Created by Johannes Fahrenkrug.
* Copyright 2009, Springenwerk.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPObject.j"
/*!
Operations receive very low priority for execution.
@global
@group CPOperationQueuePriority
*/
CPOperationQueuePriorityVeryLow = -8;
/*!
Operations receive low priority for execution.
@global
@group CPOperationQueuePriority
*/
CPOperationQueuePriorityLow = -4;
/*!
Operations receive normal priority for execution.
@global
@group CPOperationQueuePriority
*/
CPOperationQueuePriorityNormal = 0;
/*!
Operations receive high priority for execution.
@global
@group CPOperationQueuePriority
*/
CPOperationQueuePriorityHigh = 4;
/*!
Operations receive very high priority for execution.
@global
@group CPOperationQueuePriority
*/
CPOperationQueuePriorityVeryHigh = 8;
/*!
@class CPOperation
@brief Represents an operation that can be run in an CPOperationQueue
It should be subclassed an the subclass should implement its own main method to do the actual work.
*/
@implementation CPOperation : CPObject
{
CPArray operations;
BOOL _cancelled;
BOOL _executing;
BOOL _finished;
BOOL _ready;
int _queuePriority;
JSObject _completionFunction;
CPArray _dependencies;
}
- (void)main
{
// should be overridden in child class
}
- (id)init
{
self = [super init];
if (self)
{
_cancelled = NO;
_executing = NO;
_finished = NO;
_ready = YES;
_dependencies = [[CPArray alloc] init];
_queuePriority = CPOperationQueuePriorityNormal;
}
return self;
}
/*!
Starts the operation (runs the main method), sets all the status flags and runs the completion function if it's set
*/
- (void)start
{
if (!_cancelled)
{
[self willChangeValueForKey:@"isExecuting"];
_executing = YES;
[self didChangeValueForKey:@"isExecuting"];
[self main];
if (_completionFunction)
{
_completionFunction();
}
[self willChangeValueForKey:@"isExecuting"];
_executing = NO;
[self didChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_finished = YES;
[self didChangeValueForKey:@"isFinished"];
}
}
/*!
Indicates if this operation has been cancelled
@return if this operation has been cancelled
*/
- (BOOL)isCancelled
{
return _cancelled;
}
/*!
Indicates if this operation is currently executing
@return if this operation is currently executing
*/
- (BOOL)isExecuting
{
return _executing;
}
/*!
Indicates if this operation has finished running
@return if this operation has finished running
*/
- (BOOL)isFinished
{
return _finished;
}
/*!
Just added for Cocoa compatibility
@return always false
*/
- (BOOL)isConcurrent
{
return NO;
}
/*!
Indicates if this operation is ready to be executed. Takes the "isFinished" state of dependent operations into account
@return if this operation is ready to run
*/
- (BOOL)isReady
{
return _ready;
}
/*!
The JS function that should be run after the main method
@return JS function
*/
- (JSObject)completionFunction
{
return _completionFunction;
}
/*!
Sets the JS function that should be run after the main method
*/
- (void)setCompletionFunction:(JSObject)aJavaScriptFunction
{
_completionFunction = aJavaScriptFunction;
}
/*!
Makes the receiver dependent on the completion of the specified operation.
@param anOperation the operation that the receiver should depend on
*/
- (void)addDependency:(CPOperation)anOperation
{
[self willChangeValueForKey:@"dependencies"];
[anOperation addObserver:self
forKeyPath:@"isFinished"
options:(CPKeyValueObservingOptionNew)
context:NULL];
[_dependencies addObject:anOperation];
[self didChangeValueForKey:@"dependencies"];
[self _updateIsReadyState];
}
/*!
Removes the receiver’s dependence on the specified operation.
@param anOperation the operation that the receiver should no longer depend on
*/
- (void)removeDependency:(CPOperation)anOperation
{
[self willChangeValueForKey:@"dependencies"];
[_dependencies removeObject:anOperation];
[anOperation removeObserver:self
forKeyPath:@"isFinished"];
[self didChangeValueForKey:@"dependencies"];
[self _updateIsReadyState];
}
/*!
The operations that the receiver depends on
@return array of operations
*/
- (CPArray)dependencies
{
return _dependencies;
}
/*!
Just added for Cocoa compatibility, doesn't do anything
*/
- (void)waitUntilFinished
{
}
/*!
Advises the operation object that it should stop executing its task.
*/
- (void)cancel
{
[self willChangeValueForKey:@"isCancelled"];
_cancelled = YES;
[self didChangeValueForKey:@"isCancelled"];
}
/*!
Sets the priority of the operation when used in an operation queue.
@param priority the priority
*/
- (void)setQueuePriority:(int)priority
{
_queuePriority = priority;
}
/*!
The priority of the operation when used in an operation queue.
@return the priority
*/
- (int)queuePriority
{
return _queuePriority;
}
// We need to observe the "isFinished" key of our dependent operations so we can update our own "isReady" state
- (void)observeValueForKeyPath:(CPString)keyPath
ofObject:(id)object
change:(CPDictionary)change
context:(void)context
{
if (keyPath == @"isFinished")
{
[self _updateIsReadyState];
}
}
- (void)_updateIsReadyState
{
var newReady = YES;
if (_dependencies && [_dependencies count] > 0)
{
var i = 0;
for (i = 0; i < [_dependencies count]; i++)
{
if (![[_dependencies objectAtIndex:i] isFinished])
{
newReady = NO;
}
}
}
if (newReady != _ready)
{
[self willChangeValueForKey:@"isReady"];
_ready = newReady;
[self didChangeValueForKey:@"isReady"];
}
}
@end
Jump to Line
Something went wrong with that request. Please try again.