aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs21
-rw-r--r--src/ocr.rs39
2 files changed, 40 insertions, 20 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8c8bcc3..e90202d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,8 @@ use image::{DynamicImage, ImageFormat};
use std::cell::{Cell, RefCell};
use std::rc::Rc;
+use futures::channel::mpsc;
+use futures::prelude::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::*;
@@ -84,6 +86,8 @@ async fn do_boot() {
let history = Rc::new(RefCell::new(history::History::default()));
+ let (manual_update_tx, manual_update_rx) = mpsc::channel::<()>(5);
+
let video: HtmlVideoElement = document
.get_element_by_id("video")
.unwrap()
@@ -107,7 +111,9 @@ async fn do_boot() {
let width = width.clone();
let height = height.clone();
let target_marker = target_marker.clone();
+ let manual_update_tx = manual_update_tx.clone();
gloo::events::EventListener::new(&video, "click", move |event| {
+ let mut manual_update_tx = manual_update_tx.clone();
let video = also_video.clone();
let mouse_event: &MouseEvent = event.dyn_ref().unwrap();
let mouse_x = mouse_event.offset_x() as f64;
@@ -120,6 +126,7 @@ async fn do_boot() {
let real_y = mouse_y / fake_height * real_height - QUEUE_SIZE_HEIGHT as f64 / 2.0;
queue_position.replace((real_x.round() as u32, real_y.round() as u32));
update_target_marker(&target_marker, &width, &height, &video, &queue_position);
+ spawn_local(async move { manual_update_tx.send(()).await.unwrap() });
})
};
video_click_listener.forget();
@@ -146,7 +153,9 @@ async fn do_boot() {
let also_video = video.clone();
let canvas = canvas.clone();
let queue_position = queue_position.clone();
+ let manual_update_tx = manual_update_tx.clone();
gloo::events::EventListener::new(&video, "canplay", move |_event| {
+ let mut manual_update_tx = manual_update_tx.clone();
let video = also_video.clone();
let _ = video.play().unwrap();
if !streaming.get() {
@@ -156,16 +165,21 @@ async fn do_boot() {
canvas.set_attribute("height", &format!("{}", height.get()));
streaming.set(true);
update_target_marker(&target_marker, &width, &height, &video, &queue_position);
+ spawn_local(async move { manual_update_tx.send(()).await.unwrap() });
}
})
};
video_play_listener.forget();
- let update_interval = gloo::timers::callback::Interval::new(2_000, move || {
+ let update_stream = futures::stream_select!(
+ gloo::timers::future::IntervalStream::new(2_000),
+ manual_update_rx,
+ );
+ let update_future = update_stream.for_each(move |_| {
let history = history.clone();
let queue_position = queue_position.clone();
if !streaming.get() {
- return;
+ return futures::future::ready(());
}
let context = canvas.get_context("2d").unwrap().unwrap();
let context: CanvasRenderingContext2d = context.dyn_into().unwrap();
@@ -247,8 +261,9 @@ async fn do_boot() {
.unwrap(),
)
.unwrap();
+ futures::future::ready(())
});
- update_interval.forget();
+ spawn_local(update_future);
}
#[wasm_bindgen]
diff --git a/src/ocr.rs b/src/ocr.rs
index cde116f..14021cc 100644
--- a/src/ocr.rs
+++ b/src/ocr.rs
@@ -1,18 +1,27 @@
use image::{DynamicImage, GrayImage, ImageFormat};
use imageproc::template_matching::MatchTemplateMethod;
+use lazy_static::lazy_static;
-const REFERENCE_PNGS: [&[u8]; 10] = [
- include_bytes!("../data/0.png"),
- include_bytes!("../data/1.png"),
- include_bytes!("../data/2.png"),
- include_bytes!("../data/3.png"),
- include_bytes!("../data/4.png"),
- include_bytes!("../data/5.png"),
- include_bytes!("../data/6.png"),
- include_bytes!("../data/7.png"),
- include_bytes!("../data/8.png"),
- include_bytes!("../data/9.png"),
-];
+lazy_static! {
+ static ref REFERENCES: [GrayImage; 10] = {
+ let parse = |data: &[u8]| {
+ let png = image::load_from_memory_with_format(data, ImageFormat::Png).unwrap();
+ image::imageops::grayscale(&png)
+ };
+ [
+ parse(include_bytes!("../data/0.png")),
+ parse(include_bytes!("../data/1.png")),
+ parse(include_bytes!("../data/2.png")),
+ parse(include_bytes!("../data/3.png")),
+ parse(include_bytes!("../data/4.png")),
+ parse(include_bytes!("../data/5.png")),
+ parse(include_bytes!("../data/6.png")),
+ parse(include_bytes!("../data/7.png")),
+ parse(include_bytes!("../data/8.png")),
+ parse(include_bytes!("../data/9.png")),
+ ]
+ };
+}
fn x_matches(image: &GrayImage, template: &GrayImage) -> Vec<u32> {
let match_values = imageproc::template_matching::match_template(
@@ -31,11 +40,7 @@ pub fn ocr(image: DynamicImage) -> Option<u32> {
let grayscale_image = image::imageops::grayscale(&image);
let mut digit_x_positions: Vec<(u8, u32)> = (0..10)
.flat_map(|i| {
- let png_i =
- image::load_from_memory_with_format(REFERENCE_PNGS[i as usize], ImageFormat::Png)
- .unwrap();
- let grey_png_i = image::imageops::grayscale(&png_i);
- x_matches(&grayscale_image, &grey_png_i)
+ x_matches(&grayscale_image, &REFERENCES[i as usize])
.into_iter()
.map(move |x| (i, x))
})