@@ -57,7 +57,7 @@ public class TaskConfiguration
5757 }
5858}
5959
60- public class Task < Progress, Value, Error> : Printable
60+ public class Task < Progress, Value, Error> : Cancellable , Printable
6161{
6262 public typealias ProgressTuple = ( oldProgress: Progress ? , newProgress: Progress )
6363 public typealias ErrorInfo = ( error: Error ? , isCancelled: Bool )
@@ -213,7 +213,8 @@ public class Task<Progress, Value, Error>: Printable
213213 internal func setup( #weakified: Bool, paused: Bool, _initClosure: _InitClosure)
214214 {
215215// #if DEBUG
216- // println("[init] \(self.name)")
216+ // let addr = String(format: "%p", unsafeAddressOf(self))
217+ // NSLog("[init] \(self.name) \(addr)")
217218// #endif
218219
219220 self . _initClosure = _initClosure
@@ -287,7 +288,8 @@ public class Task<Progress, Value, Error>: Printable
287288 deinit
288289 {
289290// #if DEBUG
290- // println("[deinit] \(self.name)")
291+ // let addr = String(format: "%p", unsafeAddressOf(self))
292+ // NSLog("[deinit] \(self.name) \(addr)")
291293// #endif
292294
293295 // cancel in case machine is still running
@@ -355,14 +357,19 @@ public class Task<Progress, Value, Error>: Printable
355357 ///
356358 public func progress( progressClosure: ProgressTuple -> Void ) -> Task
357359 {
358- var token : HandlerToken ? = nil
359- return self . progress ( & token , progressClosure)
360+ var dummyCanceller : Canceller ? = nil
361+ return self . progress ( & dummyCanceller , progressClosure)
360362 }
361363
362- public func progress( inout token : HandlerToken ? , _ progressClosure: ProgressTuple -> Void ) -> Task
364+ public func progress< C : Canceller > ( inout canceller : C ? , _ progressClosure: ProgressTuple -> Void ) -> Task
363365 {
366+ var token : _HandlerToken ? = nil
364367 self . _machine. addProgressTupleHandler ( & token, progressClosure)
365368
369+ canceller = C { [ weak self] in
370+ self ? . _machine. removeProgressTupleHandler ( token)
371+ }
372+
366373 return self
367374 }
368375
@@ -373,13 +380,13 @@ public class Task<Progress, Value, Error>: Printable
373380 ///
374381 public func then< Value2> ( thenClosure: ( Value ? , ErrorInfo ? ) -> Value2 ) -> Task < Progress , Value2 , Error >
375382 {
376- var token : HandlerToken ? = nil
377- return self . then ( & token , thenClosure)
383+ var dummyCanceller : Canceller ? = nil
384+ return self . then ( & dummyCanceller , thenClosure)
378385 }
379386
380- public func then< Value2> ( inout token : HandlerToken ? , _ thenClosure: ( Value ? , ErrorInfo ? ) -> Value2 ) -> Task < Progress , Value2 , Error >
387+ public func then< Value2, C : Canceller > ( inout canceller : C ? , _ thenClosure: ( Value ? , ErrorInfo ? ) -> Value2 ) -> Task < Progress , Value2 , Error >
381388 {
382- return self . then ( & token ) { ( value: Value ? , errorInfo: ErrorInfo ? ) -> Task < Progress , Value2 , Error > in
389+ return self . then ( & canceller ) { ( value: Value ? , errorInfo: ErrorInfo ? ) -> Task < Progress , Value2 , Error > in
383390 return Task < Progress , Value2 , Error > ( value: thenClosure ( value, errorInfo) )
384391 }
385392 }
@@ -391,13 +398,13 @@ public class Task<Progress, Value, Error>: Printable
391398 ///
392399 public func then< Progress2, Value2> ( thenClosure: ( Value ? , ErrorInfo ? ) -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
393400 {
394- var token : HandlerToken ? = nil
395- return self . then ( & token , thenClosure)
401+ var dummyCanceller : Canceller ? = nil
402+ return self . then ( & dummyCanceller , thenClosure)
396403 }
397404
398- public func then< Progress2, Value2> ( inout token : HandlerToken ? , _ thenClosure: ( Value ? , ErrorInfo ? ) -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
405+ public func then< Progress2, Value2, C : Canceller > ( inout canceller : C ? , _ thenClosure: ( Value ? , ErrorInfo ? ) -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
399406 {
400- return Task < Progress2 , Value2 , Error > { [ unowned self] newMachine, progress, fulfill, _reject, configure in
407+ return Task < Progress2 , Value2 , Error > { [ unowned self, weak canceller ] newMachine, progress, fulfill, _reject, configure in
401408
402409 //
403410 // NOTE:
@@ -408,7 +415,7 @@ public class Task<Progress, Value, Error>: Printable
408415 //
409416 let selfMachine = self . _machine
410417
411- self . _then ( & token ) {
418+ self . _then ( & canceller ) {
412419 let innerTask = thenClosure ( selfMachine. value, selfMachine. errorInfo)
413420 _bindInnerTask ( innerTask, newMachine, progress, fulfill, _reject, configure)
414421 }
@@ -417,13 +424,18 @@ public class Task<Progress, Value, Error>: Printable
417424 }
418425
419426 /// invokes `completionHandler` "now" or "in the future"
420- private func _then( inout token : HandlerToken ? , _ completionHandler: Void -> Void )
427+ private func _then< C : Canceller > ( inout canceller : C ? , _ completionHandler: Void -> Void )
421428 {
422429 switch self . state {
423430 case . Fulfilled, . Rejected, . Cancelled:
424431 completionHandler ( )
425432 default :
433+ var token : _HandlerToken ? = nil
426434 self . _machine. addCompletionHandler ( & token, completionHandler)
435+
436+ canceller = C { [ weak self] in
437+ self ? . _machine. removeCompletionHandler ( token)
438+ }
427439 }
428440 }
429441
@@ -434,13 +446,13 @@ public class Task<Progress, Value, Error>: Printable
434446 ///
435447 public func success< Value2> ( successClosure: Value -> Value2 ) -> Task < Progress , Value2 , Error >
436448 {
437- var token : HandlerToken ? = nil
438- return self . success ( & token , successClosure)
449+ var dummyCanceller : Canceller ? = nil
450+ return self . success ( & dummyCanceller , successClosure)
439451 }
440452
441- public func success< Value2> ( inout token : HandlerToken ? , _ successClosure: Value -> Value2 ) -> Task < Progress , Value2 , Error >
453+ public func success< Value2, C : Canceller > ( inout canceller : C ? , _ successClosure: Value -> Value2 ) -> Task < Progress , Value2 , Error >
442454 {
443- return self . success ( & token ) { ( value: Value ) -> Task < Progress , Value2 , Error > in
455+ return self . success ( & canceller ) { ( value: Value ) -> Task < Progress , Value2 , Error > in
444456 return Task < Progress , Value2 , Error > ( value: successClosure ( value) )
445457 }
446458 }
@@ -452,18 +464,18 @@ public class Task<Progress, Value, Error>: Printable
452464 ///
453465 public func success< Progress2, Value2> ( successClosure: Value -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
454466 {
455- var token : HandlerToken ? = nil
456- return self . success ( & token , successClosure)
467+ var dummyCanceller : Canceller ? = nil
468+ return self . success ( & dummyCanceller , successClosure)
457469 }
458470
459- public func success< Progress2, Value2> ( inout token : HandlerToken ? , _ successClosure: Value -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
471+ public func success< Progress2, Value2, C : Canceller > ( inout canceller : C ? , _ successClosure: Value -> Task < Progress2 , Value2 , Error > ) -> Task < Progress2 , Value2 , Error >
460472 {
461473 return Task < Progress2 , Value2 , Error > { [ unowned self] newMachine, progress, fulfill, _reject, configure in
462474
463475 let selfMachine = self . _machine
464476
465477 // NOTE: using `self._then()` + `selfMachine` instead of `self.then()` will reduce Task allocation
466- self . _then ( & token ) {
478+ self . _then ( & canceller ) {
467479 if let value = selfMachine. value {
468480 let innerTask = successClosure ( value)
469481 _bindInnerTask ( innerTask, newMachine, progress, fulfill, _reject, configure)
@@ -484,13 +496,13 @@ public class Task<Progress, Value, Error>: Printable
484496 ///
485497 public func failure( failureClosure: ErrorInfo -> Value ) -> Task
486498 {
487- var token : HandlerToken ? = nil
488- return self . failure ( & token , failureClosure)
499+ var dummyCanceller : Canceller ? = nil
500+ return self . failure ( & dummyCanceller , failureClosure)
489501 }
490502
491- public func failure( inout token : HandlerToken ? , _ failureClosure: ErrorInfo -> Value ) -> Task
503+ public func failure< C : Canceller > ( inout canceller : C ? , _ failureClosure: ErrorInfo -> Value ) -> Task
492504 {
493- return self . failure ( & token ) { ( errorInfo: ErrorInfo ) -> Task in
505+ return self . failure ( & canceller ) { ( errorInfo: ErrorInfo ) -> Task in
494506 return Task ( value: failureClosure ( errorInfo) )
495507 }
496508 }
@@ -503,17 +515,17 @@ public class Task<Progress, Value, Error>: Printable
503515 ///
504516 public func failure< Progress2> ( failureClosure: ErrorInfo -> Task < Progress2 , Value , Error > ) -> Task < Progress2 , Value , Error >
505517 {
506- var token : HandlerToken ? = nil
507- return self . failure ( & token , failureClosure)
518+ var dummyCanceller : Canceller ? = nil
519+ return self . failure ( & dummyCanceller , failureClosure)
508520 }
509521
510- public func failure< Progress2> ( inout token : HandlerToken ? , _ failureClosure: ErrorInfo -> Task < Progress2 , Value , Error > ) -> Task < Progress2 , Value , Error >
522+ public func failure< Progress2, C : Canceller > ( inout canceller : C ? , _ failureClosure: ErrorInfo -> Task < Progress2 , Value , Error > ) -> Task < Progress2 , Value , Error >
511523 {
512524 return Task < Progress2 , Value , Error > { [ unowned self] newMachine, progress, fulfill, _reject, configure in
513525
514526 let selfMachine = self . _machine
515527
516- self . _then ( & token ) {
528+ self . _then ( & canceller ) {
517529 if let value = selfMachine. value {
518530 fulfill ( value)
519531 }
@@ -536,27 +548,25 @@ public class Task<Progress, Value, Error>: Printable
536548 return self . _machine. handleResume ( )
537549 }
538550
539- public func cancel( error: Error ? = nil ) -> Bool
551+ //
552+ // NOTE:
553+ // To conform to `Cancellable`, this method is needed in replace of:
554+ // - `public func cancel(error: Error? = nil) -> Bool`
555+ // - `public func cancel(_ error: Error? = nil) -> Bool` (segfault in Swift 1.2)
556+ //
557+ public func cancel( ) -> Bool
540558 {
541- return self . _cancel ( error : error )
559+ return self . cancel ( nil )
542560 }
543561
544- internal func _cancel ( error: Error ? = nil ) -> Bool
562+ public func cancel ( error: Error ? ) -> Bool
545563 {
546- return self . _machine. handleCancel ( error: error)
547- }
548-
549- // MARK: Remove Handlers
550-
551- public func removeProgress( handlerToken: HandlerToken )
552- {
553- return self . _machine. removeProgressTupleHandler ( handlerToken)
564+ return self . _cancel ( error: error)
554565 }
555566
556- /// NOTE: `task.removeThen(token)` will force `let task2 = task.then(&token)` to deinit immediately and tries cancellation if it is still running.
557- public func removeThen( handlerToken: HandlerToken )
567+ internal func _cancel( error: Error ? = nil ) -> Bool
558568 {
559- return self . _machine. removeCompletionHandler ( handlerToken )
569+ return self . _machine. handleCancel ( error : error )
560570 }
561571
562572}
0 commit comments