visual-cortex 0.1.0

Watch screen regions and receive typed events over async streams when patterns match: OCR, template matching, and pixel conditions on live captures.
Documentation
use std::sync::Arc;
use std::time::SystemTime;

use visual_cortex_vision::DetectorOutput;

/// An event emitted by a watcher.
#[derive(Debug, Clone)]
pub struct Event {
    pub watcher: Arc<str>,
    pub timestamp: SystemTime,
    pub kind: EventKind,
}

#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum EventKind {
    /// Every-match mode: the detector matched this tick.
    Matched { output: DetectorOutput },
    /// Change mode (default): the detector's output transitioned.
    /// `old` is `None` on the first evaluation.
    Changed {
        old: Option<DetectorOutput>,
        new: DetectorOutput,
    },
    /// Threshold mode: the predicate flipped.
    ThresholdCrossed {
        value: f64,
        direction: ThresholdDirection,
    },
    /// Template mode: the best match score rose to or above the threshold.
    TemplateAppeared { score: f32 },
    /// Template mode: the best match score fell below the threshold.
    TemplateVanished,
    /// The detector failed repeatedly; the watcher keeps running.
    WatcherDegraded { consecutive_errors: u32 },
    /// The capture target disappeared (e.g. the watched window closed).
    /// Session-wide: delivered to every subscriber. Watchers stay registered;
    /// a `TargetReattached` follows if the target comes back.
    TargetLost,
    /// A previously lost capture target is available again. Session-wide.
    TargetReattached,
}

impl EventKind {
    /// Session-wide events that every subscriber should see, regardless of the
    /// watcher names their stream filters on.
    pub fn is_session_level(&self) -> bool {
        matches!(self, EventKind::TargetLost | EventKind::TargetReattached)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThresholdDirection {
    /// The predicate became true.
    Entered,
    /// The predicate became false.
    Exited,
}