1+ use super :: audio_handles:: output_markers:: { OutputDisabled , OutputEnabled } ;
2+ use super :: device:: Device ;
13use super :: errors:: AudioError ;
2- use rodio:: { OutputStream , OutputStreamHandle , source:: Source } ;
4+ use super :: output:: * ;
5+ use rodio:: { OutputStream , OutputStreamHandle , Sink , source:: Source , Decoder } ;
36use std:: collections:: HashMap ;
47use std:: fs:: File ;
58use std:: io:: { Cursor , Read } ;
69use std:: marker:: PhantomData ;
7- use crate :: audio:: audio_handles:: input_markers:: { InputDisabled , InputEnabled } ;
8- use crate :: audio:: audio_handles:: output_markers:: { OutputDisabled , OutputEnabled } ;
10+ use std:: path:: Path ;
911
10-
11- pub ( super ) mod output_markers {
12+ pub mod output_markers {
1213 use crate :: audio:: audio_handles:: input_markers:: InputDisabled ;
1314
14- pub ( super ) struct OutputDisabled ;
15+ pub struct OutputDisabled ;
1516 //pub(super) type OutDis=OutputDisabled;
16- pub ( super ) struct OutputEnabled ;
17+ pub struct OutputEnabled ;
1718 //pub(super) type OutEn=OutputEnabled;
1819}
19- pub ( super ) mod input_markers {
20- pub ( super ) struct InputEnabled ;
20+ pub mod input_markers {
21+ pub struct InputEnabled ;
2122 //pub(super) type InEn=InputEnabled;
22- pub ( super ) struct InputDisabled ;
23+ pub struct InputDisabled ;
2324 //pub(super) type InDis=InputDisabled;
2425}
2526
2627//statetype pattern, everything else than the impl combinations is basically ignored, so you could have a OutputHandle<String>, but it just does...nothing
2728//I thought this is better for the dev using this library since the type system helps them
2829//I think I can't really avoid a bit of shared code if I want to keep it straightforward...
29- pub ( super ) struct OutputHandler < O >
30- {
31- pub ( super ) output_handle : Option < OutputStreamHandle > ,
30+ pub struct OutputHandle < O > {
31+ pub ( super ) output_handle : Option < Sink > ,
32+ pub ( super ) device_name : Option < String > ,
3233 pub ( super ) loaded_files : HashMap < String , Cursor < Vec < u8 > > > ,
3334 _marker : PhantomData < O > ,
3435}
3536
36- impl Default for OutputHandler < OutputDisabled > {
37- fn default ( ) -> OutputHandler < OutputDisabled > {
38- OutputHandler {
37+ impl Default for OutputHandle < OutputDisabled > {
38+ fn default ( ) -> OutputHandle < OutputDisabled > {
39+ OutputHandle {
3940 output_handle : None ,
41+ device_name : None ,
4042 loaded_files : HashMap :: new ( ) ,
4143 _marker : PhantomData ,
4244 }
4345 }
4446}
4547
46- impl OutputHandler < OutputDisabled > {
48+ impl OutputHandle < OutputDisabled > {
49+ //NEVER set the handle to Some(_) here!!!
50+ fn new ( ) -> OutputHandle < OutputDisabled > {
51+ Default :: default ( )
52+ }
4753 fn load_file ( & mut self , path : & str , new_name : String ) -> Result < ( ) , AudioError > {
4854 //capacity: 50 Kilobytes, every sound effect has at least this size...
49- let mut buffer = Vec :: with_capacity ( 1024 * 50 ) ;
55+ let mut buffer = Vec :: with_capacity ( 1024 * 50 ) ;
5056 let mut file = File :: open ( path) ?;
5157 file. read_to_end ( & mut buffer) ?;
5258 let buffer = Cursor :: new ( buffer) ;
@@ -55,30 +61,49 @@ impl OutputHandler<OutputDisabled> {
5561 }
5662 fn unload_file ( & mut self , name : String ) -> Result < ( ) , AudioError > {
5763 if self . loaded_files . remove ( & name) . is_none ( ) {
58- Err ( AudioError :: FileNotLoaded )
59- } else {
60- Ok ( ( ) )
61- }
62- }
63- fn activate_output_default ( & mut self ) -> Result < ( ) , AudioError > {
64- if self . output_handle . is_none ( ) {
65- let ( _stream, stream_handle) = OutputStream :: ?;
66- self . output_handle = Some ( stream_handle) ;
64+ return Err ( AudioError :: FileNotLoaded ) ;
6765 }
6866 Ok ( ( ) )
6967 }
70- fn activate_output_from_device ( ) {
71- todo ! ( ) ;
68+
69+ //maybe one day I'll find a shorter name...
70+ pub fn activate_output_with_default_device ( self ) -> Result < OutputHandle < OutputEnabled > , AudioError > {
71+ //IDK what this was supposed to do yesterday, but I'll leave it here
72+ if self . output_handle . is_none ( ) { }
73+ //--
74+ let ( _stream, stream_handle) = OutputStream :: try_default ( ) ?;
75+ OutputHandle :: from ( self , stream_handle)
76+
77+ }
78+
79+ fn activate_output_with_device ( self , device : Device < Output > ) -> Result < OutputHandle < OutputEnabled > , AudioError > {
80+ let ( _stream, stream_handle) = OutputStream :: try_from_device ( & device. device ) ?;
81+ //self.output_handle = Some(Sink::try_new(&stream_handle)?);
82+ Ok ( OutputHandle :: from ( self , stream_handle) ?)
7283 }
7384}
7485
75- impl OutputHandler < OutputEnabled > {
76- fn new ( ) -> OutputHandler < OutputDisabled > {
77- Default :: default ( )
86+
87+
88+ //important!
89+ //NO get_device (but get_device_name) because it instanly gives an error if you try to use a device that just can't work for whatever reason
90+ //meaning you directly get an error
91+ impl OutputHandle < OutputEnabled > {
92+
93+ fn from ( handler : OutputHandle < OutputDisabled > , stream_handle : OutputStreamHandle ) -> Result < Self , AudioError > {
94+ Ok (
95+ Self {
96+ output_handle : Some ( Sink :: try_new ( & stream_handle) ?) ,
97+ device_name : handler. device_name ,
98+ loaded_files : handler. loaded_files ,
99+ _marker : PhantomData ,
100+ }
101+ )
78102 }
79- fn load_file ( & mut self , path : & str , new_name : String ) -> Result < ( ) , AudioError > {
103+
104+ pub fn load_file ( & mut self , path : & Path , new_name : String ) -> Result < ( ) , AudioError > {
80105 //capacity: 50 Kilobytes, every sound effect has at least this size...
81- let mut buffer = Vec :: with_capacity ( 1024 * 50 ) ;
106+ let mut buffer = Vec :: with_capacity ( 1024 * 50 ) ;
82107 let mut file = File :: open ( path) ?;
83108 file. read_to_end ( & mut buffer) ?;
84109 let buffer = Cursor :: new ( buffer) ;
@@ -92,14 +117,57 @@ impl OutputHandler<OutputEnabled> {
92117 Ok ( ( ) )
93118 }
94119 }
95-
120+
121+ /*fn get_available_devices() -> Result<Vec<Device<Output>>, AudioError> {
122+ rodio::Device::
123+ }*/
124+
125+ fn use_default_device ( & mut self ) -> Result < ( ) , AudioError > {
126+ let ( _stream, stream_handle) = OutputStream :: try_default ( ) ?;
127+ self . output_handle =Some ( Sink :: try_new ( & stream_handle) ?) ;
128+ Ok ( ( ) )
129+ }
130+ fn change_device ( & mut self , device : Device < Output > ) {
131+ todo ! ( ) ;
132+ }
133+
134+ fn get_device_name ( & self ) -> String {
135+ //ask the compiler why this works...
136+ <Option < String > as Clone >:: clone ( & self . device_name )
137+ . expect ( "Impossible error. Device<OutputEnabled> always has device_name ≠ None" )
138+ }
139+
96140 fn disable_output ( & mut self ) {
97141 self . output_handle = None ;
98- }
99- fn play ( & mut self ) {
142+ }
143+
144+ fn play_from_file ( & mut self /*...*/ , new_id : u32 ) {
100145 todo ! ( ) ;
101146 }
147+ pub fn play_loaded ( & mut self , name : String , new_id : u32 ) -> Result < ( ) , AudioError > {
148+ if dbg ! ( self . loaded_files. contains_key( & name) ) {
149+ let buffer=self . loaded_files . get ( & name)
150+ . expect ( "Impossible, just checked if it's there" )
151+ . to_owned ( ) ;
152+ self . output_handle . as_mut ( ) . expect ( "Impossible, thanks to the type system" )
153+ . append ( Decoder :: new ( buffer) ?) ;
154+ }
155+ Ok ( ( ) )
156+ }
157+
158+ //Result!!
159+ fn pause ( & mut self , id : u32 ) {
160+
161+ }
162+
163+ fn pause_all ( & mut self ) {
164+
165+ }
166+
167+ fn is_paused ( & self ) -> bool {
168+ self . output_handle . as_ref ( ) . expect ( "Impossible..." ) . is_paused ( )
169+ }
102170 //other play functions...
103171 //channels?
104172 //ids?
105- }
173+ }
0 commit comments