-
-
Save makleso6/2dd10723eaeb86346aa0d38036304a5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import notify | |
import Combine | |
enum Notify {} | |
extension Notify { | |
struct Status: Error { | |
let rawValue: UInt32 | |
init(_ rawValue: UInt32) { | |
self.rawValue = rawValue | |
} | |
func ok() throws { | |
guard rawValue == NOTIFY_STATUS_OK else { throw self } | |
} | |
} | |
} | |
extension Notify { | |
struct Token { | |
typealias State = UInt64 | |
typealias RawValue = Int32 | |
var rawValue: RawValue = NOTIFY_TOKEN_INVALID | |
init(_ rawValue: RawValue) { | |
self.rawValue = rawValue | |
} | |
init(dispatch name: String, queue: DispatchQueue = .main, handler: @escaping notify_handler_t) throws { | |
try Status(notify_register_dispatch(name, &rawValue, queue, handler)).ok() | |
} | |
init(check name: String) throws { | |
try Status(notify_register_check(name, &rawValue)).ok() | |
} | |
func state() throws -> State { | |
var state: State = 0 | |
try Status(notify_get_state(rawValue, &state)).ok() | |
return state | |
} | |
func cancel() throws { | |
try Status(notify_cancel(rawValue)).ok() | |
} | |
} | |
} | |
extension Notify { | |
class Listener { | |
private class Helper { | |
let name: String | |
var token: Token? | |
let publisher = PassthroughSubject<UInt64, Status>() | |
init(name: String) { | |
self.name = name | |
} | |
func subscribe() { | |
do { | |
token = try Token(dispatch: name) { [publisher] token in | |
do { | |
publisher.send(try Token(token).state()) | |
} catch { | |
publisher.send(completion: .failure(error as! Status)) | |
} | |
} | |
} catch { | |
publisher.send(completion: .failure(error as! Status)) | |
} | |
} | |
func cancel() { | |
try? token?.cancel() | |
} | |
func value() throws -> UInt64 { | |
try Token(check: name).state() | |
} | |
} | |
private let helper: Helper | |
init(name: String) { | |
helper = Helper(name: name) | |
} | |
func value() throws -> UInt64 { | |
try helper.value() | |
} | |
lazy var publisher: AnyPublisher<UInt64, Status> = { | |
helper.publisher | |
.handleEvents(receiveSubscription: { [helper] sub in | |
helper.subscribe() | |
}, receiveCancel: helper.cancel) | |
.share() | |
.eraseToAnyPublisher() | |
}() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment