use crate::capture::{Capture, ScreenshotsCapture};
use crate::frame::Frame;
use crate::matcher::{Match, Matcher, RgbMatcher};
use crate::template::Template;
use crate::Result;
#[cfg(all(windows, feature = "capture-dxgi"))]
use crate::Error;
#[cfg(feature = "match-corr")]
use crate::matcher_corr::CorrMatcher;
pub enum CaptureKind {
Screenshots,
#[cfg(all(windows, feature = "capture-gdi"))]
Gdi,
#[cfg(all(windows, feature = "capture-dxgi"))]
Dxgi,
#[cfg(all(windows, any(feature = "capture-gdi", feature = "capture-dxgi")))]
Auto,
}
pub enum MatchKind {
Rgb { tolerance: i32 },
#[cfg(feature = "match-corr")]
Corr,
}
pub struct Finder {
capture: Box<dyn Capture>,
matcher: Box<dyn Matcher>,
}
impl Finder {
pub fn builder() -> FinderBuilder {
FinderBuilder { capture: None, matcher: None }
}
pub fn find_on_screen(&mut self, tpl: &Template) -> Result<Option<Match>> {
let frame = self.capture.grab()?;
Ok(self.find_in_frame(&frame, tpl))
}
pub fn find_in_frame(&self, frame: &Frame, tpl: &Template) -> Option<Match> {
self.matcher.find(frame, tpl)
}
}
pub struct FinderBuilder {
capture: Option<CaptureKind>,
matcher: Option<MatchKind>,
}
impl FinderBuilder {
pub fn capture(mut self, k: CaptureKind) -> Self {
self.capture = Some(k);
self
}
pub fn matcher(mut self, k: MatchKind) -> Self {
self.matcher = Some(k);
self
}
pub fn build(self) -> Result<Finder> {
let capture: Box<dyn Capture> = match self.capture.unwrap_or(CaptureKind::Screenshots) {
CaptureKind::Screenshots => Box::new(ScreenshotsCapture::primary()?),
#[cfg(all(windows, feature = "capture-gdi"))]
CaptureKind::Gdi => Box::new(crate::capture_gdi::GdiCapture::new_primary()),
#[cfg(all(windows, feature = "capture-dxgi"))]
CaptureKind::Dxgi => Box::new(
crate::capture_dxgi::DxgiCapture::new_primary()
.ok_or_else(|| Error::Capture("DXGI desktop duplication unavailable".into()))?,
),
#[cfg(all(windows, any(feature = "capture-gdi", feature = "capture-dxgi")))]
CaptureKind::Auto => auto_capture()?,
};
let matcher: Box<dyn Matcher> =
match self.matcher.unwrap_or(MatchKind::Rgb { tolerance: 25 }) {
MatchKind::Rgb { tolerance } => Box::new(RgbMatcher::new(tolerance)),
#[cfg(feature = "match-corr")]
MatchKind::Corr => Box::new(CorrMatcher::new()),
};
Ok(Finder { capture, matcher })
}
}
#[cfg(all(windows, any(feature = "capture-gdi", feature = "capture-dxgi")))]
fn auto_capture() -> Result<Box<dyn Capture>> {
#[cfg(feature = "capture-dxgi")]
if let Some(c) = crate::capture_dxgi::DxgiCapture::new_primary() {
return Ok(Box::new(c));
}
#[cfg(feature = "capture-gdi")]
{
return Ok(Box::new(crate::capture_gdi::GdiCapture::new_primary()));
}
#[allow(unreachable_code)]
Ok(Box::new(ScreenshotsCapture::primary()?))
}