2023-01-02 16:00:42 -05:00
|
|
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
2022-03-08 09:40:34 -05:00
|
|
|
|
|
|
|
use deno_core::anyhow::Error;
|
2022-03-14 13:44:15 -04:00
|
|
|
use deno_core::op;
|
2022-03-08 09:40:34 -05:00
|
|
|
use deno_core::Extension;
|
|
|
|
use deno_core::JsRuntime;
|
|
|
|
use deno_core::OpState;
|
|
|
|
use deno_core::RuntimeOptions;
|
|
|
|
use futures::channel::mpsc;
|
|
|
|
use futures::stream::StreamExt;
|
|
|
|
use std::task::Poll;
|
|
|
|
|
2022-03-14 13:44:15 -04:00
|
|
|
// This is a hack to make the `#[op]` macro work with
|
|
|
|
// deno_core examples.
|
|
|
|
// You can remove this:
|
|
|
|
use deno_core::*;
|
|
|
|
|
2022-03-08 09:40:34 -05:00
|
|
|
type Task = Box<dyn FnOnce()>;
|
|
|
|
|
|
|
|
fn main() {
|
2023-01-08 17:48:46 -05:00
|
|
|
let my_ext = Extension::builder("my_ext")
|
2022-03-14 13:44:15 -04:00
|
|
|
.ops(vec![op_schedule_task::decl()])
|
2022-06-28 05:23:36 -04:00
|
|
|
.event_loop_middleware(|state_rc, cx| {
|
|
|
|
let mut state = state_rc.borrow_mut();
|
2022-03-08 09:40:34 -05:00
|
|
|
let recv = state.borrow_mut::<mpsc::UnboundedReceiver<Task>>();
|
|
|
|
let mut ref_loop = false;
|
|
|
|
while let Poll::Ready(Some(call)) = recv.poll_next_unpin(cx) {
|
|
|
|
call();
|
|
|
|
ref_loop = true; // `call` can callback into runtime and schedule new callbacks :-)
|
|
|
|
}
|
|
|
|
ref_loop
|
|
|
|
})
|
|
|
|
.state(move |state| {
|
|
|
|
let (tx, rx) = mpsc::unbounded::<Task>();
|
|
|
|
state.put(tx);
|
|
|
|
state.put(rx);
|
|
|
|
})
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// Initialize a runtime instance
|
|
|
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
|
|
|
extensions: vec![my_ext],
|
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
|
|
|
.enable_all()
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let future = async move {
|
|
|
|
// Schedule 10 tasks.
|
|
|
|
js_runtime
|
2023-04-04 08:46:31 -04:00
|
|
|
.execute_script_static(
|
2022-08-11 09:56:56 -04:00
|
|
|
"<usage>",
|
|
|
|
r#"for (let i = 1; i <= 10; i++) Deno.core.ops.op_schedule_task(i);"#,
|
|
|
|
)
|
|
|
|
.unwrap();
|
2022-03-08 09:40:34 -05:00
|
|
|
js_runtime.run_event_loop(false).await
|
|
|
|
};
|
|
|
|
runtime.block_on(future).unwrap();
|
|
|
|
}
|
|
|
|
|
2022-03-14 13:44:15 -04:00
|
|
|
#[op]
|
2022-03-14 18:38:53 -04:00
|
|
|
fn op_schedule_task(state: &mut OpState, i: u8) -> Result<(), Error> {
|
2022-03-08 09:40:34 -05:00
|
|
|
let tx = state.borrow_mut::<mpsc::UnboundedSender<Task>>();
|
2023-01-27 10:43:16 -05:00
|
|
|
tx.unbounded_send(Box::new(move || println!("Hello, world! x{i}")))
|
2022-03-08 09:40:34 -05:00
|
|
|
.expect("unbounded_send failed");
|
|
|
|
Ok(())
|
|
|
|
}
|