Created
June 29, 2023 00:05
-
-
Save storoj/bc5c0d24dde6b5bb0b5f7fe2706c61e9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
Usage: