Skip to content

Commit 288a626

Browse files
committed
Add pause and resume API's to Loop
On some scenarios, it's useful to "pause" the `Loop` so that we stop processing events for some reason (e.g. to stop a `Loop` backed Service). Following the same reasoning, it becomes necessary to have a "resume" mechanism so that the Loop starts processing events again. Given `Loop` now starts automatically and `stop` is designed as a tear down mechanism to be used on dealloc and dispose all observations, some new API's are required so that we can unplug/replug feedbacks to achieve the above mentioned pause/resume behavior. ## Changes - Create new `plugFeedbacks` and `unplugFeedbacks` API's in `Floodgate`, which establish and dispose feedbacks observations, respectively. Floodgate now retains the feedbacks passed in on `bootstrap` to use them on `plugFeedbacks`. - Add `pause` and `resume` API's to `LoopBoxBase`. - Implement `pause` and `resume` API's in `RootLoopBox`, which unplug and plug the feedbacks on the `Floodgate`, respectively. - Implement `pause` and `resume` API's in `ScopedLoopBox`, which forward the calls to their root, respectively.
1 parent cbf1238 commit 288a626

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

Loop/Floodgate.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ final class Floodgate<State, Event>: FeedbackEventConsumer<Event> {
3434

3535
private let queue = Atomic(QueueState())
3636
private let reducer: (inout State, Event) -> Void
37-
private let feedbackDisposables = CompositeDisposable()
37+
private var feedbacks: [Loop<State, Event>.Feedback] = []
38+
private var feedbackDisposables = CompositeDisposable()
3839

3940
init(state: State, reducer: @escaping (inout State, Event) -> Void) {
4041
self.state = state
@@ -46,6 +47,12 @@ final class Floodgate<State, Event>: FeedbackEventConsumer<Event> {
4647
}
4748

4849
func bootstrap(with feedbacks: [Loop<State, Event>.Feedback]) {
50+
self.feedbacks = feedbacks
51+
52+
plugFeedbacks()
53+
}
54+
55+
func plugFeedbacks() {
4956
for feedback in feedbacks {
5057
// Pass `producer` which has replay-1 semantic.
5158
feedbackDisposables += feedback.events(
@@ -60,6 +67,11 @@ final class Floodgate<State, Event>: FeedbackEventConsumer<Event> {
6067
}
6168
}
6269

70+
func unplugFeedbacks() {
71+
feedbackDisposables.dispose()
72+
feedbackDisposables = CompositeDisposable()
73+
}
74+
6375
override func process(_ event: Event, for token: Token) {
6476
enqueue(event, for: token)
6577

Loop/LoopBox.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ internal class ScopedLoopBox<RootState, RootEvent, ScopedState, ScopedEvent>: Lo
4444
event: { [eventTransform] in eventTransform(event($0)) }
4545
)
4646
}
47+
48+
override func pause() {
49+
root.pause()
50+
}
51+
52+
override func resume() {
53+
root.resume()
54+
}
4755
}
4856

4957
internal class RootLoopBox<State, Event>: LoopBoxBase<State, Event> {
@@ -83,6 +91,14 @@ internal class RootLoopBox<State, Event>: LoopBoxBase<State, Event> {
8391
ScopedLoopBox(root: self, value: scope, event: event)
8492
}
8593

94+
override func pause() {
95+
floodgate.unplugFeedbacks()
96+
}
97+
98+
override func resume() {
99+
floodgate.plugFeedbacks()
100+
}
101+
86102
func start(with feedbacks: [Loop<State, Event>.Feedback]) {
87103
floodgate.bootstrap(with: feedbacks + [input.feedback])
88104
}
@@ -115,6 +131,10 @@ internal class LoopBoxBase<State, Event> {
115131
) -> LoopBoxBase<S, E> {
116132
subclassMustImplement()
117133
}
134+
135+
func pause() { subclassMustImplement() }
136+
137+
func resume() { subclassMustImplement() }
118138
}
119139

120140
@inline(never)

Loop/Public/Loop.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ public final class Loop<State, Event> {
6969
box: box.scoped(to: { $0 }, event: { _ in fatalError() })
7070
)
7171
}
72+
73+
public func pause() {
74+
box.pause()
75+
}
76+
77+
public func resume() {
78+
box.resume()
79+
}
7280
}
7381

7482
extension Loop {

0 commit comments

Comments
 (0)