servo_media_derive/
lib.rs1#![recursion_limit = "128"]
6
7extern crate proc_macro;
8extern crate proc_macro2;
9extern crate syn;
10#[macro_use]
11extern crate quote;
12
13use proc_macro::TokenStream;
14
15#[proc_macro_derive(AudioScheduledSourceNode)]
16pub fn audio_scheduled_source_node(input: TokenStream) -> TokenStream {
17 let ast: syn::DeriveInput = syn::parse(input).unwrap();
18 let r#gen = impl_audio_scheduled_source_node(&ast);
19 r#gen.into()
20}
21
22fn impl_audio_scheduled_source_node(ast: &syn::DeriveInput) -> proc_macro2::TokenStream {
23 let name = &ast.ident;
24 quote! {
25 impl #name {
26 fn should_play_at(&mut self, tick: Tick) -> ShouldPlay {
27 let start = if let Some(start) = self.start_at {
28 start
29 } else {
30 return ShouldPlay::No;
31 };
32
33 let frame_end = tick + Tick::FRAMES_PER_BLOCK;
34 if tick < start {
35 if frame_end < start {
36 ShouldPlay::No
37 } else {
38 let delta_start = start - tick;
39 if let Some(stop) = self.stop_at {
40 if stop <= start {
41 self.maybe_trigger_onended_callback();
42 return ShouldPlay::No;
43 }
44 if stop > frame_end {
45 ShouldPlay::Between(delta_start, Tick::FRAMES_PER_BLOCK)
46 } else {
47 self.maybe_trigger_onended_callback();
48 ShouldPlay::Between(delta_start, stop - tick)
49 }
50 } else {
51 ShouldPlay::Between(delta_start, Tick::FRAMES_PER_BLOCK)
52 }
53 }
54 } else {
55 let stop = if let Some(stop) = self.stop_at {
56 stop
57 } else {
58 return ShouldPlay::Between(Tick(0), Tick::FRAMES_PER_BLOCK);
59 };
60 if stop > frame_end {
61 ShouldPlay::Between(Tick(0), Tick::FRAMES_PER_BLOCK)
62 } else if stop < tick {
63 self.maybe_trigger_onended_callback();
64 ShouldPlay::No
65 } else {
66 self.maybe_trigger_onended_callback();
67 ShouldPlay::Between(Tick(0), stop - tick)
68 }
69 }
70 }
71
72 fn start(&mut self, tick: Tick) -> bool {
73 if self.start_at.is_some() || self.stop_at.is_some() {
76 return false;
77 }
78 self.start_at = Some(tick);
79 true
80 }
81
82 fn stop(&mut self, tick: Tick) -> bool {
83 if self.start_at.is_none() {
85 return false;
86 }
87 self.stop_at = Some(tick);
90 true
91 }
92
93 fn maybe_trigger_onended_callback(&mut self) {
94 if self.start_at.is_none() {
96 return;
97 }
98 if let Some(cb) = self.onended_callback.take() {
99 cb.0()
100 }
101 }
102
103 fn handle_source_node_message(&mut self, message: AudioScheduledSourceNodeMessage, sample_rate: f32) {
104 match message {
105 AudioScheduledSourceNodeMessage::Start(when) => {
106 self.start(Tick::from_time(when, sample_rate));
107 }
108 AudioScheduledSourceNodeMessage::Stop(when) => {
109 self.stop(Tick::from_time(when, sample_rate));
110 }
111 AudioScheduledSourceNodeMessage::RegisterOnEndedCallback(callback) => {
112 self.onended_callback = Some(callback);
113 }
114 }
115 }
116 }
117 }
118}
119
120#[proc_macro_derive(AudioNodeCommon)]
121pub fn channel_info(input: TokenStream) -> TokenStream {
122 let ast: syn::DeriveInput = syn::parse(input).unwrap();
123 let name = &ast.ident;
124 let r#gen = quote! {
125 impl crate::node::AudioNodeCommon for #name {
126 fn channel_info(&self) -> &crate::node::ChannelInfo {
127 &self.channel_info
128 }
129
130 fn channel_info_mut(&mut self) -> &mut crate::node::ChannelInfo {
131 &mut self.channel_info
132 }
133 }
134 };
135 r#gen.into()
136}