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