/
TWLAsyncOperation.m
73 lines (63 loc) · 2 KB
/
TWLAsyncOperation.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// TWLAsyncOperation.m
// Tomorrowland
//
// Created by Lily Ballard on 8/18/20.
// Copyright © 2020 Lily Ballard. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
#import "TWLAsyncOperation+Private.h"
#import <stdatomic.h>
@implementation TWLAsyncOperation {
atomic_ulong _state;
}
- (TWLAsyncOperationState)state {
return atomic_load_explicit(&_state, memory_order_relaxed);
}
- (void)setState:(TWLAsyncOperationState)state {
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
atomic_store_explicit(&_state, state, memory_order_relaxed);
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}
- (void)start {
if (self.state != TWLAsyncOperationStateInitial) {
// Attempted to call -start after it's already been started.
return;
}
self.state = TWLAsyncOperationStateExecuting;
[self main];
}
- (void)main {
// This should be overridden. If it does get invoked, just mark ourselves as finished.
NSAssert(self.state == TWLAsyncOperationStateExecuting, @"-[TWLAsyncOperation main] invoked while the operation was not executing.");
self.state = TWLAsyncOperationStateFinished;
}
- (BOOL)isExecuting {
switch (self.state) {
case TWLAsyncOperationStateInitial:
case TWLAsyncOperationStateFinished:
return NO;
case TWLAsyncOperationStateExecuting:
return YES;
}
}
- (BOOL)isFinished {
switch (self.state) {
case TWLAsyncOperationStateInitial:
case TWLAsyncOperationStateExecuting:
return NO;
case TWLAsyncOperationStateFinished:
return YES;
}
}
- (BOOL)isAsynchronous {
return YES;
}
@end