1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <EXTaskManager/EXTaskExecutionRequest.h>
4
5@interface EXTaskExecutionRequest ()
6
7@property (nonatomic, strong, nullable) NSMutableSet<id<EXTaskInterface>> *tasks;
8@property (nonatomic, strong, nullable) NSMutableArray<id> *results;
9@property (nonatomic, assign) int tasksCount;
10
11@end
12
13
14@implementation EXTaskExecutionRequest
15
16- (instancetype)initWithCallback:(void(^)(NSArray *results))callback
17{
18  if (self = [super init]) {
19    _callback = callback;
20    _tasks = [NSMutableSet new];
21    _results = [NSMutableArray new];
22  }
23  return self;
24}
25
26- (void)addTask:(nonnull id<EXTaskInterface>)task
27{
28  [_tasks addObject:task];
29}
30
31- (void)task:(nonnull id<EXTaskInterface>)task didFinishWithResult:(id)result
32{
33  [_tasks removeObject:task];
34  [_results addObject:result];
35  [self maybeEvaluate];
36}
37
38- (BOOL)isIncludingTask:(nullable id<EXTaskInterface>)task
39{
40  return task && [_tasks containsObject:task];
41}
42
43- (void)maybeEvaluate
44{
45  if ([_tasks count] == 0) {
46    [self _maybeExecuteCallback];
47  }
48}
49
50# pragma mark - helpers
51
52- (void)_maybeExecuteCallback
53{
54  if (_callback) {
55    // Make a strong pointer to self before executing a callback as the request may be deallocated there,
56    // due to this fact `_callback = nil;` was crashing on older versions of iOS (below 12.0).
57    __strong EXTaskExecutionRequest *strongSelf = self;
58
59    _callback(_results);
60    _callback = nil;
61    _tasks = nil;
62    _results = nil;
63    strongSelf = nil;
64  }
65}
66
67@end
68