mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
This commit is contained in:
parent
cd8d85bd97
commit
b8e0ffc136
2 changed files with 70 additions and 22 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// Configuration
|
/// Configuration
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
|
/// Path of configuration entrypoint
|
||||||
|
pub path: PathBuf,
|
||||||
/// Name of configuration
|
/// Name of configuration
|
||||||
pub name: Option<Arc<str>>,
|
pub name: Option<Arc<str>>,
|
||||||
/// Description of configuration
|
/// Description of configuration
|
||||||
|
|
@ -14,20 +17,19 @@ pub struct Configuration {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
pub fn from_file (path: &impl AsRef<Path>, _watch: bool) -> Usually<Self> {
|
|
||||||
Self::from_source(String::from_utf8(std::fs::read(path.as_ref())?)?)
|
pub fn new (path: &impl AsRef<Path>, _watch: bool) -> Usually<Self> {
|
||||||
}
|
let text = read_and_leak(path.as_ref())?;
|
||||||
pub fn from_source (source: impl AsRef<str> + 'static) -> Usually<Self> {
|
let [name, info, view, keys] = Self::parse(TokenIter::from(text))?;
|
||||||
let source: Box<str> = source.as_ref().into();
|
|
||||||
let source: &'static str = Box::leak(source);
|
|
||||||
let [name, info, view, keys] = Self::parse(TokenIter::from(source.as_ref()))?;
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
path: path.as_ref().into(),
|
||||||
info: info.map(Self::parse_info).flatten(),
|
info: info.map(Self::parse_info).flatten(),
|
||||||
name: name.map(Self::parse_name).flatten(),
|
name: name.map(Self::parse_name).flatten(),
|
||||||
view: Self::parse_view(view)?,
|
view: Self::parse_view(view)?,
|
||||||
keys: Self::parse_keys(keys)?,
|
keys: Self::parse_keys(&path, keys)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse (iter: TokenIter) -> Usually<[Option<TokenIter>;4]> {
|
fn parse (iter: TokenIter) -> Usually<[Option<TokenIter>;4]> {
|
||||||
let mut name: Option<TokenIter> = None;
|
let mut name: Option<TokenIter> = None;
|
||||||
let mut info: Option<TokenIter> = None;
|
let mut info: Option<TokenIter> = None;
|
||||||
|
|
@ -59,6 +61,7 @@ impl Configuration {
|
||||||
}
|
}
|
||||||
Ok([name, info, view, keys])
|
Ok([name, info, view, keys])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_info (mut iter: TokenIter) -> Option<Arc<str>> {
|
fn parse_info (mut iter: TokenIter) -> Option<Arc<str>> {
|
||||||
iter.next().and_then(|x|if let Value::Str(x) = x.value {
|
iter.next().and_then(|x|if let Value::Str(x) = x.value {
|
||||||
Some(x.into())
|
Some(x.into())
|
||||||
|
|
@ -66,6 +69,7 @@ impl Configuration {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_name (mut iter: TokenIter) -> Option<Arc<str>> {
|
fn parse_name (mut iter: TokenIter) -> Option<Arc<str>> {
|
||||||
iter.next().and_then(|x|if let Value::Str(x) = x.value {
|
iter.next().and_then(|x|if let Value::Str(x) = x.value {
|
||||||
Some(x.into())
|
Some(x.into())
|
||||||
|
|
@ -73,6 +77,7 @@ impl Configuration {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_view (iter: Option<TokenIter>) -> Usually<TokenIter> {
|
fn parse_view (iter: Option<TokenIter>) -> Usually<TokenIter> {
|
||||||
if let Some(view) = iter {
|
if let Some(view) = iter {
|
||||||
Ok(view)
|
Ok(view)
|
||||||
|
|
@ -80,7 +85,8 @@ impl Configuration {
|
||||||
Err(format!("missing view definition").into())
|
Err(format!("missing view definition").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn parse_keys (iter: Option<TokenIter>)
|
|
||||||
|
fn parse_keys (base: &impl AsRef<Path>, iter: Option<TokenIter>)
|
||||||
-> Usually<InputMap<'static, Tek, TekCommand, TuiIn, TokenIter<'static>>>
|
-> Usually<InputMap<'static, Tek, TekCommand, TuiIn, TokenIter<'static>>>
|
||||||
{
|
{
|
||||||
if let Some(mut keys) = iter {
|
if let Some(mut keys) = iter {
|
||||||
|
|
@ -91,8 +97,39 @@ impl Configuration {
|
||||||
let next = exp.next();
|
let next = exp.next();
|
||||||
match next {
|
match next {
|
||||||
Some(Token { value: Value::Key(sym), .. }) => match sym {
|
Some(Token { value: Value::Key(sym), .. }) => match sym {
|
||||||
"layer" => { todo!() },
|
"layer" => {
|
||||||
"layer-if" => { todo!() },
|
let next = exp.next();
|
||||||
|
match next {
|
||||||
|
Some(Token { value: Value::Str(path), .. }) => {
|
||||||
|
map.add_layer(read_and_leak(path)?.into());
|
||||||
|
},
|
||||||
|
_ => return Err(
|
||||||
|
format!("(e4) unexpected non-string {next:?}").into()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
"layer-if" => {
|
||||||
|
let next = exp.next();
|
||||||
|
match next {
|
||||||
|
Some(Token { value: Value::Sym(sym), .. }) => {
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
_ => return Err(
|
||||||
|
format!("(e4) unexpected non-symbol {next:?}").into()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let next = exp.next();
|
||||||
|
match next {
|
||||||
|
Some(Token { value: Value::Str(path), .. }) => {
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
_ => return Err(
|
||||||
|
format!("(e4) unexpected non-symbol {next:?}").into()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
_ => return Err(
|
_ => return Err(
|
||||||
format!("(e3) unexpected symbol {sym:?}").into()
|
format!("(e3) unexpected symbol {sym:?}").into()
|
||||||
)
|
)
|
||||||
|
|
@ -112,4 +149,13 @@ impl Configuration {
|
||||||
return Err(format!("missing keys definition").into())
|
return Err(format!("missing keys definition").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_and_leak (path: impl AsRef<Path>) -> Usually<&'static str> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let text = String::from_utf8(std::fs::read(path)?)?;
|
||||||
|
let text: Box<str> = text.into();
|
||||||
|
let text: &'static str = Box::leak(text);
|
||||||
|
Ok(text)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,16 @@ impl Cli {
|
||||||
for (index, connect) in midi_tos.iter().enumerate() {
|
for (index, connect) in midi_tos.iter().enumerate() {
|
||||||
let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?;
|
let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?;
|
||||||
midi_outs.push(port);
|
midi_outs.push(port);
|
||||||
}
|
};
|
||||||
|
let config_path = match mode {
|
||||||
|
LaunchMode::Clock => "config/config_transport.edn",
|
||||||
|
LaunchMode::Sequencer => "config/config_sequencer.edn",
|
||||||
|
LaunchMode::Groovebox => "config/config_groovebox.edn",
|
||||||
|
LaunchMode::Arranger { .. } => "config/config_arranger.edn",
|
||||||
|
LaunchMode::Sampler => "config/config_sampler.edn",
|
||||||
|
_ => todo!("{mode:?}"),
|
||||||
|
};
|
||||||
|
let config = Configuration::new(&config_path, false)?;
|
||||||
let mut app = Tek {
|
let mut app = Tek {
|
||||||
jack: jack.clone(),
|
jack: jack.clone(),
|
||||||
color: ItemTheme::random(),
|
color: ItemTheme::random(),
|
||||||
|
|
@ -139,14 +148,7 @@ impl Cli {
|
||||||
},
|
},
|
||||||
scenes,
|
scenes,
|
||||||
selected: Selection::TrackClip { track: 0, scene: 0 },
|
selected: Selection::TrackClip { track: 0, scene: 0 },
|
||||||
config: Configuration::from_file(match mode {
|
config,
|
||||||
LaunchMode::Clock => &"config/config_transport.edn",
|
|
||||||
LaunchMode::Sequencer => &"config/config_sequencer.edn",
|
|
||||||
LaunchMode::Groovebox => &"config/config_groovebox.edn",
|
|
||||||
LaunchMode::Arranger { .. } => &"config/config_arranger.edn",
|
|
||||||
LaunchMode::Sampler => &"config/config_sampler.edn",
|
|
||||||
_ => todo!("{mode:?}"),
|
|
||||||
}, false)?,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode {
|
if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue