Skip to main content

mimium_scheduler/
lib.rs

1//! Scheduler plugin for mimium.
2//!
3//! This plugin provides a simple synchronous event scheduler which is used by
4//! the runtime to execute scheduled tasks at sample boundaries.
5//!
6//! The scheduler communicates with the audio worker through a lock-free channel.
7//! `schedule_at` enqueues tasks from the main thread, and the audio worker
8//! dequeues and executes them at the correct sample time.
9//!
10//! All VM interaction goes through [`RuntimeHandle`](mimium_lang::runtime::ffi::RuntimeHandle)
11//! rather than accessing `Machine` directly, making the scheduler compatible
12//! with both the native VM and the WASM backend.
13
14use mimium_lang::plugin::{SysPluginSignature, SystemPlugin, SystemPluginAudioWorker};
15use mimium_lang::{function, numeric, plugin::SystemPluginFnType, types::Type, unit};
16
17mod scheduler;
18#[cfg(not(target_arch = "wasm32"))]
19mod wasm_handle;
20
21pub use scheduler::SimpleScheduler;
22#[cfg(not(target_arch = "wasm32"))]
23pub use wasm_handle::WasmSchedulerHandle;
24
25impl SystemPlugin for SimpleScheduler {
26    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
27        self
28    }
29
30    fn generate_audioworker(&mut self) -> Option<Box<dyn SystemPluginAudioWorker>> {
31        Some(Box::new(self.take_audio_worker().unwrap()))
32    }
33
34    fn gen_interfaces(&self) -> Vec<SysPluginSignature> {
35        let fun: SystemPluginFnType<Self> = Self::schedule_at;
36        let schedule_fn = SysPluginSignature::new(
37            "_mimium_schedule_at",
38            fun,
39            function!(vec![numeric!(), function!(vec![], unit!())], unit!()),
40        );
41        vec![schedule_fn]
42    }
43
44    #[cfg(not(target_arch = "wasm32"))]
45    fn freeze_audio_handle(&mut self) -> Option<Box<dyn std::any::Any + Send>> {
46        Some(Box::new(self.take_or_create_wasm_handle()))
47    }
48
49    #[cfg(not(target_arch = "wasm32"))]
50    fn freeze_for_wasm(&mut self) -> Option<mimium_lang::runtime::wasm::WasmPluginFnMap> {
51        let handle = self.take_or_create_wasm_handle();
52        Some(handle.into_wasm_plugin_fn_map())
53    }
54
55    #[cfg(not(target_arch = "wasm32"))]
56    fn generate_wasm_audioworker(
57        &mut self,
58    ) -> Option<Box<dyn mimium_lang::runtime::wasm::WasmSystemPluginAudioWorker>> {
59        Some(Box::new(self.take_or_create_wasm_handle()))
60    }
61}
62
63/// Return a [`SystemPlugin`] with the default synchronous scheduler.
64pub fn get_default_scheduler_plugin() -> impl SystemPlugin {
65    SimpleScheduler::default()
66}