Skip to content
This repository has been archived by the owner on Mar 9, 2023. It is now read-only.

Web Workers #211

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion osm-tags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#![warn(unreachable_pub)]
#![deny(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(unused_crate_dependencies)]
// #![warn(unused_crate_dependencies)] // https://github.com/rust-lang/rust/issues/57274
#![warn(unused_lifetimes)]
#![warn(unused_qualifications)]
// Clippy
Expand Down
3 changes: 2 additions & 1 deletion osm2lanes-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ edition = "2021"

[dependencies]
console_log = { version = "0.2", optional = true, features = ["color"] }
console_error_panic_hook = "0.1"
geo = { version = "0.20" }
gloo-utils = "0.1"
gloo-timers = "0.2"
leaflet = { git = "https://github.com/droogmic/leaflet-rs", branch = "polyline_get_bounds" }
log = "0.4"
osm-tags = { path = "../osm-tags" }
Expand All @@ -32,6 +32,7 @@ syntect = { version = "5.0", default-features = false, features = [
wasm-bindgen = "0.2"
wee_alloc = { version = "0.4", optional = true }
yew = "0.19"
yew-agent = "0.1"

[dependencies.web-sys]
version = "0.3"
Expand Down
6 changes: 5 additions & 1 deletion osm2lanes-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
crossorigin></script>
<link rel="stylesheet" href="//unpkg.com/leaflet-gesture-handling/dist/leaflet-gesture-handling.min.css"
type="text/css" />
type="text/css">
<script src="https://unpkg.com/leaflet-gesture-handling"></script>

<!-- Web Workers -->
<link data-trunk rel="rust" href="Cargo.toml" data-bin="app" data-type="main" />
<link data-trunk rel="rust" href="Cargo.toml" data-bin="worker" data-type="worker" />
</head>

</html>
38 changes: 38 additions & 0 deletions osm2lanes-web/src/agent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use osm2lanes::test::{get_tests, TestCase};
use serde::{Deserialize, Serialize};
use yew_agent::{Agent, AgentLink, HandlerId, Public};

pub struct ExampleLoader {
link: AgentLink<Self>,
}

#[derive(Serialize, Deserialize)]
pub struct ExampleLoaderOutput(pub Vec<TestCase>);

impl Agent for ExampleLoader {
type Input = ();
type Message = ();
type Output = ExampleLoaderOutput;
type Reach = Public<Self>;

fn create(link: AgentLink<Self>) -> Self {
Self { link }
}

fn update(&mut self, _msg: Self::Message) {
// no messaging
}

fn handle_input(&mut self, _msg: Self::Input, id: HandlerId) {
let tests = get_tests();
let examples = tests
.into_iter()
.filter(|t| t.example().is_some())
.collect();
self.link.respond(id, ExampleLoaderOutput(examples));
}

fn name_of_resource() -> &'static str {
"worker.js"
}
}
8 changes: 8 additions & 0 deletions osm2lanes-web/src/bin/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use osm2lanes_web::App;

fn main() {
console_error_panic_hook::set_once();
console_log::init_with_level(log::Level::Debug).expect("logging failed");
log::trace!("Initializing yew...");
yew::start_app::<App>();
}
7 changes: 7 additions & 0 deletions osm2lanes-web/src/bin/worker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use osm2lanes_web::agent::ExampleLoader;
use yew_agent::Threaded;

fn main() {
console_error_panic_hook::set_once();
ExampleLoader::register();
}
47 changes: 28 additions & 19 deletions osm2lanes-web/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ use std::cell::RefCell;
use std::collections::BTreeMap;
use std::rc::Rc;

use gloo_timers::callback::Timeout;
use osm2lanes::locale::{Country, DrivingSide, Locale};
use osm2lanes::test::{get_tests, TestCase};
use osm2lanes::test::TestCase;
use web_sys::{Event, FocusEvent, HtmlInputElement, HtmlSelectElement, KeyboardEvent, MouseEvent};
use yew::{html, Callback, Component, Context, Html, NodeRef, Properties, TargetCast};
use yew_agent::{Bridge, Bridged};

use crate::agent::{ExampleLoader, ExampleLoaderOutput};
use crate::{Msg as AppMsg, State};

pub(crate) enum Msg {
/// Pass the message to the parent
Up(Box<AppMsg>),
FirstLazy,
/// Worker's response with examples
WorkerMsg(ExampleLoaderOutput),
/// Select example given name
Example(String),
}

Expand All @@ -28,8 +32,8 @@ pub(crate) struct Props {
pub(crate) state: Rc<RefCell<State>>,
}

#[derive(Default)]
pub(crate) struct Control {
_worker: Box<dyn Bridge<ExampleLoader>>,
textarea_input_ref: NodeRef,
textarea_output_ref: NodeRef,
example: Option<String>,
Expand All @@ -40,16 +44,31 @@ impl Component for Control {
type Properties = Props;
type Message = Msg;

fn create(_ctx: &Context<Self>) -> Self {
Self::default()
fn create(ctx: &Context<Self>) -> Self {
let cb = {
let link = ctx.link().clone();
link.callback(Self::Message::WorkerMsg)
};
let mut worker = ExampleLoader::bridge(cb);

// Trigger worker
worker.send(());

Self {
_worker: worker,
textarea_input_ref: Default::default(),
textarea_output_ref: Default::default(),
example: Default::default(),
examples: Default::default(),
}
}

fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Up(msg) => ctx.props().callback_msg.emit(*msg),
Msg::FirstLazy => {
let tests = get_tests();
let examples: BTreeMap<_, _> = tests
Msg::WorkerMsg(examples) => {
let examples: BTreeMap<String, TestCase> = examples
.0
.into_iter()
.filter_map(|t| {
let example_name = t.example().map(std::borrow::ToOwned::to_owned);
Expand Down Expand Up @@ -256,14 +275,4 @@ impl Component for Control {
</>
}
}

fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
if first_render {
let handle = {
let link = ctx.link().clone();
Timeout::new(1, move || link.send_message(Msg::FirstLazy))
};
handle.forget();
}
}
}
10 changes: 3 additions & 7 deletions osm2lanes-web/src/main.rs → osm2lanes-web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![warn(unreachable_pub)]
#![deny(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(unused_crate_dependencies)]
// #![warn(unused_crate_dependencies)] // https://github.com/rust-lang/rust/issues/57274
#![warn(unused_lifetimes)]
#![warn(unused_qualifications)]
// Clippy
Expand Down Expand Up @@ -57,6 +57,8 @@ use syntect::parsing::SyntaxSet;
use web_sys::HtmlInputElement;
use yew::prelude::*;

pub mod agent;

mod control;
use control::Control;

Expand Down Expand Up @@ -361,9 +363,3 @@ impl App {
}
}
}

fn main() {
console_log::init_with_level(log::Level::Debug).expect("logging failed");
log::trace!("Initializing yew...");
yew::start_app::<App>();
}
1 change: 1 addition & 0 deletions osm2lanes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ tests = ["serde_yaml"]

[dev-dependencies]
assert-json-diff = "2.0"
bincode = "1.3"
criterion = { version = "0.3", features = ["html_reports"] }
env_logger = "0.9"
osm2lanes = { path = ".", features = ["tests"] }
Expand Down
2 changes: 1 addition & 1 deletion osm2lanes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#![warn(unreachable_pub)]
#![deny(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(unused_crate_dependencies)]
// #![warn(unused_crate_dependencies)] // https://github.com/rust-lang/rust/issues/57274
#![warn(unused_lifetimes)]
#![warn(unused_qualifications)]
// Clippy
Expand Down
32 changes: 28 additions & 4 deletions osm2lanes/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use serde::Deserialize;
use serde::{Deserialize, Serialize};

use crate::locale::DrivingSide;
use crate::road::{Lane, Road};
use crate::tag::{Highway, HighwayType, Tags};

#[derive(Clone, Deserialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum RustTesting {
Enabled(bool),
Expand All @@ -14,7 +14,7 @@ pub enum RustTesting {
},
}

#[derive(Clone, Deserialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Expected {
Road(Road),
Expand All @@ -23,7 +23,7 @@ pub enum Expected {
}

#[allow(clippy::module_name_repetitions)]
#[derive(Clone, Deserialize)]
#[derive(Clone, Serialize, Deserialize)]
pub struct TestCase {
// Metadata
/// The OSM way unique identifier
Expand Down Expand Up @@ -406,6 +406,30 @@ mod tests {
});
}

#[test]
fn test_bincode() {
env_logger_init();
let tests = get_tests();
for test in &tests {
bincode::serialize(&test.tags).expect("can't serialize tags");
match &test.expected {
Expected::Road(expected_road) => {
bincode::serialize(&expected_road.lanes)
.expect("can't serialize expected road lanes");
bincode::serialize(&expected_road.highway)
.expect("can't serialize expected road highway");
bincode::serialize(expected_road).expect("can't serialize expected road");
},
Expected::Output(expected_output) => {
bincode::serialize(expected_output).expect("can't serialize expected output");
},
}
bincode::serialize(&test.expected).expect("can't serialize expected");
bincode::serialize(test).expect("can't serialize test case");
}
bincode::serialize(&tests).expect("can't serialize test cases");
}

#[test]
fn test_from_data() {
env_logger_init();
Expand Down