Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pause and resume API's to Loop #17

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Loop/Public/FeedbackLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,17 @@ extension Loop {
}
}

public func autoconnect(followingChangesIn predicate: @escaping (State) -> Bool) -> Feedback {
return Feedback { state, consumer in
self.events(
state
.skipRepeats { predicate($0.0) == predicate($1.0) }
.flatMap(.latest) { predicate($0.0) ? state.filter { predicate($0.0) } : .empty },
consumer
)
}
}

Comment on lines +456 to +466
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I managed to come up with, and it appears to be working. However I am not convinced this is the best approach... 🙈

More specifically, I had to add that filter on the inner state to avoid the "disconnect-triggering" state from being processed before the inner chain is replaced.

Any ideas to make this tidier and/or more idiomatic?

public static func combine(_ feedbacks: Loop<State, Event>.Feedback...) -> Feedback {
return Feedback { state, consumer in
feedbacks.map { feedback in
Expand Down
35 changes: 35 additions & 0 deletions LoopTests/FeedbackVariantTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,39 @@ class FeedbackVariantTests: XCTestCase {
loop.send("world")
expect(hasCancelled) == true
}

func test_autoconnect_disposes_and_restores_flows_according_to_predicate() {

let loop = Loop<String, String>(
initial: "",
reducer: { content, string in
content = string
},
feedbacks: [
Loop<String, String>.Feedback
.init(
lensing: { $0.hasPrefix("hello") ? $0 : nil },
effects: { SignalProducer(value: $0.uppercased()) }
)
.autoconnect(followingChangesIn: { $0.contains("disconnect") == false })
]
)

expect(loop.box._current) == ""

// This should trigger an uppercased event
loop.send("hello1")
expect(loop.box._current) == "HELLO1"

loop.send("hello2")
expect(loop.box._current) == "HELLO2"

// This should lead to feedabck "disconnection", which in turn should cancel and disable the uppercasing effect.
loop.send("hello disconnect")
expect(loop.box._current) == "hello disconnect"

// This should lead feedback "connection", which in turn should reestablish the uppercasing effect.
loop.send("hello3")
expect(loop.box._current) == "HELLO3"
}
}