Files
phbar/Sources/phbarEvents/PHEventRecognizer.swift
T
2026-07-11 23:49:25 +02:00

55 lines
2.3 KiB
Swift

import Foundation
/// The contract every phbar event recognizer conforms to.
///
/// phbar ships a set of built-in recognizers (volume, network, appearance,
/// power, mpd) compiled into the host. External recognizers are loaded at
/// runtime as shared libraries from `~/.config/phbar/events/<name>/` and conform
/// to this same protocol, so the host drives built-in and external recognizers
/// through one shape.
///
/// Conform an `NSObject` subclass and export a zero-argument factory via
/// `@_cdecl(PHEventCreateSymbol)`:
///
/// ```swift
/// import phbarEvents
///
/// @objc(MyVolumeRecognizer)
/// final class MyVolumeRecognizer: NSObject, PHEventRecognizer {
/// func start(notify: @escaping () -> Void) { /* observe, call notify() */ }
/// func stop() { /* tear down */ }
/// }
///
/// @_cdecl("phbar_event_create")
/// public func phbar_event_create() -> AnyObject { MyVolumeRecognizer() }
/// ```
///
/// `notify` may be invoked from any thread; the host marshals each firing onto
/// the main actor, so a recognizer that receives callbacks on a background queue
/// (CoreAudio, Network, IOKit) may call it directly without hopping.
@objc public protocol PHEventRecognizer: AnyObject {
/// Begin observing. `notify` must be retained for as long as the recognizer
/// is started and is invoked whenever the observed state changes.
/// Idempotent: calling `start` while already started is a no-op.
func start(notify: @escaping () -> Void)
/// Stop observing and release system resources. Idempotent.
func stop()
}
/// The C entry point every external event library must export.
///
/// Returns a retained instance of an `NSObject` subclass conforming to
/// `PHEventRecognizer`. Authors declare it with `@_cdecl(PHEventCreateSymbol)`.
public typealias PHEventCreate = @convention(c) () -> AnyObject
/// The `dlsym` symbol the host looks up in an external event library when the
/// manifest omits one (`"phbar_event_create"`).
public let PHEventCreateSymbol = "phbar_event_create"
/// Bumped whenever `PHEventRecognizer` changes in a source-incompatible way.
/// External libraries declare the version they target in their manifest
/// (`apiVersion`); the host refuses to load a mismatched library. Omitting the
/// field skips the check (treat the library as unversioned).
public let PHEventAPIVersion = 1