JackClient -> JackConnection

This commit is contained in:
🪞👃🪞 2024-12-29 15:32:39 +01:00
parent c3f9aa7549
commit 411d4bc91d
23 changed files with 55 additions and 51 deletions

View file

@ -38,7 +38,7 @@ impl ArrangerCli {
if let Some(name) = self.name.as_ref() { if let Some(name) = self.name.as_ref() {
client_name = name.clone(); client_name = name.clone();
} }
Tui::run(JackClient::new(client_name.as_str())?.activate_with(|jack|{ Tui::run(JackConnection::new(client_name.as_str())?.activate_with(|jack|{
let mut app = ArrangerTui::try_from(jack)?; let mut app = ArrangerTui::try_from(jack)?;
let jack = jack.read().unwrap(); let jack = jack.read().unwrap();
app.color = ItemPalette::random(); app.color = ItemPalette::random();
@ -50,7 +50,7 @@ impl ArrangerCli {
} }
} }
fn add_tracks (jack: &JackClient, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> { fn add_tracks (jack: &JackConnection, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> {
let n = cli.tracks; let n = cli.tracks;
let track_color_1 = ItemColor::random(); let track_color_1 = ItemColor::random();
let track_color_2 = ItemColor::random(); let track_color_2 = ItemColor::random();

View file

@ -33,7 +33,7 @@ pub struct GrooveboxCli {
} }
impl GrooveboxCli { impl GrooveboxCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_groovebox")?.activate_with(|jack|{ Tui::run(JackConnection::new("tek_groovebox")?.activate_with(|jack|{
let app = tek::GrooveboxTui::try_from(jack)?; let app = tek::GrooveboxTui::try_from(jack)?;
jack.read().unwrap().client().connect_ports(&app.player.midi_outs[0], &app.sampler.midi_in)?; jack.read().unwrap().client().connect_ports(&app.player.midi_outs[0], &app.sampler.midi_in)?;
jack.connect_midi_from(&app.player.midi_ins[0], &self.midi_from)?; jack.connect_midi_from(&app.player.midi_ins[0], &self.midi_from)?;
@ -44,11 +44,10 @@ impl GrooveboxCli {
jack.connect_audio_to(&app.sampler.audio_outs[0], &self.l_to)?; jack.connect_audio_to(&app.sampler.audio_outs[0], &self.l_to)?;
jack.connect_audio_to(&app.sampler.audio_outs[1], &self.r_to)?; jack.connect_audio_to(&app.sampler.audio_outs[1], &self.r_to)?;
if self.sync { if self.sync {
jack.read().unwrap().client().register_timebase_callback(false, |state|{ jack.read().unwrap().client().register_timebase_callback(false, |mut state|{
let ::jack::contrib::TimebaseInfo { state, new_pos, nframes, mut position } = state; app.clock().playhead.update_from_sample(state.position.frame() as f64);
app.clock().playhead.update_from_sample(position.frame() as f64); state.position.bbt = Some(app.clock().bbt());
position.bbt = Some(app.clock().bbt()); state.position
position
})? })?
} }
Ok(app) Ok(app)

View file

@ -8,7 +8,7 @@ pub fn main () -> Usually<()> { SamplerCli::parse().run() }
} }
impl SamplerCli { impl SamplerCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_sampler")?.activate_with(|x|{ Tui::run(JackConnection::new("tek_sampler")?.activate_with(|x|{
let sampler = tek::SamplerTui::try_from(x)?; let sampler = tek::SamplerTui::try_from(x)?;
Ok(sampler) Ok(sampler)
})?)?; })?)?;

View file

@ -25,7 +25,7 @@ pub struct SequencerCli {
impl SequencerCli { impl SequencerCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
let name = self.name.as_deref().unwrap_or("tek_sequencer"); let name = self.name.as_deref().unwrap_or("tek_sequencer");
Tui::run(JackClient::new(name)?.activate_with(|jack|{ Tui::run(JackConnection::new(name)?.activate_with(|jack|{
let mut app = SequencerTui::try_from(jack)?; let mut app = SequencerTui::try_from(jack)?;
let jack = jack.read().unwrap(); let jack = jack.read().unwrap();
let midi_in = jack.register_port("i", MidiIn::default())?; let midi_in = jack.register_port("i", MidiIn::default())?;

View file

@ -2,7 +2,7 @@ include!("./lib.rs");
/// Application entrypoint. /// Application entrypoint.
pub fn main () -> Usually<()> { pub fn main () -> Usually<()> {
Tui::run(JackClient::new("tek_transport")?.activate_with(|jack|{ Tui::run(JackConnection::new("tek_transport")?.activate_with(|jack|{
TransportTui::try_from(jack) TransportTui::try_from(jack)
})?)?; })?)?;
Ok(()) Ok(())

View file

@ -3,7 +3,7 @@
#[allow(unused_imports)] use tek::{*, jack::*}; #[allow(unused_imports)] use tek::{*, jack::*};
#[allow(unused)] #[allow(unused)]
fn connect_from (jack: &JackClient, input: &Port<MidiIn>, ports: &[String]) -> Usually<()> { fn connect_from (jack: &JackConnection, input: &Port<MidiIn>, ports: &[String]) -> Usually<()> {
for port in ports.iter() { for port in ports.iter() {
if let Some(port) = jack.port_by_name(port).as_ref() { if let Some(port) = jack.port_by_name(port).as_ref() {
jack.client().connect_ports(port, input)?; jack.client().connect_ports(port, input)?;
@ -15,7 +15,7 @@ fn connect_from (jack: &JackClient, input: &Port<MidiIn>, ports: &[String]) -> U
} }
#[allow(unused)] #[allow(unused)]
fn connect_to (jack: &JackClient, output: &Port<MidiOut>, ports: &[String]) -> Usually<()> { fn connect_to (jack: &JackConnection, output: &Port<MidiOut>, ports: &[String]) -> Usually<()> {
for port in ports.iter() { for port in ports.iter() {
if let Some(port) = jack.port_by_name(port).as_ref() { if let Some(port) = jack.port_by_name(port).as_ref() {
jack.client().connect_ports(output, port)?; jack.client().connect_ports(output, port)?;
@ -27,7 +27,7 @@ fn connect_to (jack: &JackClient, output: &Port<MidiOut>, ports: &[String]) -> U
} }
#[allow(unused)] #[allow(unused)]
fn connect_audio_from (jack: &JackClient, input: &Port<AudioIn>, ports: &[String]) -> Usually<()> { fn connect_audio_from (jack: &JackConnection, input: &Port<AudioIn>, ports: &[String]) -> Usually<()> {
for port in ports.iter() { for port in ports.iter() {
if let Some(port) = jack.port_by_name(port).as_ref() { if let Some(port) = jack.port_by_name(port).as_ref() {
jack.client().connect_ports(port, input)?; jack.client().connect_ports(port, input)?;
@ -39,7 +39,7 @@ fn connect_audio_from (jack: &JackClient, input: &Port<AudioIn>, ports: &[String
} }
#[allow(unused)] #[allow(unused)]
fn connect_audio_to (jack: &JackClient, output: &Port<AudioOut>, ports: &[String]) -> Usually<()> { fn connect_audio_to (jack: &JackConnection, output: &Port<AudioOut>, ports: &[String]) -> Usually<()> {
for port in ports.iter() { for port in ports.iter() {
if let Some(port) = jack.port_by_name(port).as_ref() { if let Some(port) = jack.port_by_name(port).as_ref() {
jack.client().connect_ports(output, port)?; jack.client().connect_ports(output, port)?;

View file

@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
impl MixerCli { impl MixerCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_mixer")?.activate_with(|jack|{ Tui::run(JackConnection::new("tek_mixer")?.activate_with(|jack|{
let mut mixer = Mixer::new(jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"))?; let mut mixer = Mixer::new(jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"))?;
for channel in 0..self.channels.unwrap_or(8) { for channel in 0..self.channels.unwrap_or(8) {
mixer.track_add(&format!("Track {}", channel + 1), 1)?; mixer.track_add(&format!("Track {}", channel + 1), 1)?;

View file

@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
impl PluginCli { impl PluginCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_plugin")?.activate_with(|jack|{ Tui::run(JackConnection::new("tek_plugin")?.activate_with(|jack|{
let mut plugin = Plugin::new_lv2( let mut plugin = Plugin::new_lv2(
jack, jack,
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"), self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),

View file

@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
impl SamplerCli { impl SamplerCli {
fn run (&self) -> Usually<()> { fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_sampler")?.activate_with(|jack|{ Tui::run(JackConnection::new("tek_sampler")?.activate_with(|jack|{
let mut plugin = Sampler::new( let mut plugin = Sampler::new(
jack, jack,
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"), self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),

View file

@ -10,7 +10,7 @@ mod arranger_h;
/// Root view for standalone `tek_arranger` /// Root view for standalone `tek_arranger`
pub struct ArrangerTui { pub struct ArrangerTui {
jack: Arc<RwLock<JackClient>>, jack: Arc<RwLock<JackConnection>>,
pub clock: ClockModel, pub clock: ClockModel,
pub phrases: PoolModel, pub phrases: PoolModel,
pub tracks: Vec<ArrangerTrack>, pub tracks: Vec<ArrangerTrack>,

View file

@ -33,7 +33,7 @@ pub trait FromEdn<C>: Sized {
} }
} }
from_edn!("sampler" => |jack: &Arc<RwLock<JackClient>>, args| -> crate::Sampler { from_edn!("sampler" => |jack: &Arc<RwLock<JackConnection>>, args| -> crate::Sampler {
let mut name = String::new(); let mut name = String::new();
let mut dir = String::new(); let mut dir = String::new();
let mut samples = BTreeMap::new(); let mut samples = BTreeMap::new();
@ -64,7 +64,7 @@ from_edn!("sampler" => |jack: &Arc<RwLock<JackClient>>, args| -> crate::Sampler
type MidiSample = (Option<u7>, Arc<RwLock<crate::Sample>>); type MidiSample = (Option<u7>, Arc<RwLock<crate::Sample>>);
from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackClient>>, &str), args| -> MidiSample { from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackConnection>>, &str), args| -> MidiSample {
let mut name = String::new(); let mut name = String::new();
let mut file = String::new(); let mut file = String::new();
let mut midi = None; let mut midi = None;
@ -97,7 +97,7 @@ from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackClient>>, &str), args| ->
})))) }))))
}); });
from_edn!("plugin/lv2" => |jack: &Arc<RwLock<JackClient>>, args| -> Plugin { from_edn!("plugin/lv2" => |jack: &Arc<RwLock<JackConnection>>, args| -> Plugin {
let mut name = String::new(); let mut name = String::new();
let mut path = String::new(); let mut path = String::new();
edn!(edn in args { edn!(edn in args {
@ -119,7 +119,7 @@ const SYM_GAIN: &str = ":gain";
const SYM_SAMPLER: &str = "sampler"; const SYM_SAMPLER: &str = "sampler";
const SYM_LV2: &str = "lv2"; const SYM_LV2: &str = "lv2";
from_edn!("mixer/track" => |jack: &Arc<RwLock<JackClient>>, args| -> MixerTrack { from_edn!("mixer/track" => |jack: &Arc<RwLock<JackConnection>>, args| -> MixerTrack {
let mut _gain = 0.0f64; let mut _gain = 0.0f64;
let mut track = MixerTrack { let mut track = MixerTrack {
name: String::new(), name: String::new(),

View file

@ -7,7 +7,7 @@ use PhraseCommand::*;
use PhrasePoolCommand::*; use PhrasePoolCommand::*;
pub struct GrooveboxTui { pub struct GrooveboxTui {
_jack: Arc<RwLock<JackClient>>, _jack: Arc<RwLock<JackConnection>>,
pub player: MidiPlayer, pub player: MidiPlayer,
pub pool: PoolModel, pub pool: PoolModel,

View file

@ -15,7 +15,7 @@ pub use self::activate::JackActivate;
pub mod client; pub mod client;
pub(crate) use self::client::*; pub(crate) use self::client::*;
pub use self::client::JackClient; pub use self::client::JackConnection;
pub mod jack_event; pub mod jack_event;
pub(crate) use self::jack_event::*; pub(crate) use self::jack_event::*;
@ -24,12 +24,12 @@ pub mod ports;
pub(crate) use self::ports::*; pub(crate) use self::ports::*;
pub use self::ports::RegisterPort; pub use self::ports::RegisterPort;
/// Implement [TryFrom<&Arc<RwLock<JackClient>>>]: create app state from wrapped JACK handle. /// Implement [TryFrom<&Arc<RwLock<JackConnection>>>]: create app state from wrapped JACK handle.
#[macro_export] macro_rules! from_jack { #[macro_export] macro_rules! from_jack {
(|$jack:ident|$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)? $cb:expr) => { (|$jack:ident|$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)? $cb:expr) => {
impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc<RwLock<JackClient>>> for $Struct $(<$($L),*$($T),*>)? { impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc<RwLock<JackConnection>>> for $Struct $(<$($L),*$($T),*>)? {
type Error = Box<dyn std::error::Error>; type Error = Box<dyn std::error::Error>;
fn try_from ($jack: &Arc<RwLock<JackClient>>) -> Usually<Self> { fn try_from ($jack: &Arc<RwLock<JackConnection>>) -> Usually<Self> {
Ok($cb) Ok($cb)
} }
} }

View file

@ -3,15 +3,15 @@ use crate::*;
pub trait JackActivate: Sized { pub trait JackActivate: Sized {
fn activate_with <T: Audio + 'static> ( fn activate_with <T: Audio + 'static> (
self, self,
init: impl FnOnce(&Arc<RwLock<JackClient>>)->Usually<T> init: impl FnOnce(&Arc<RwLock<JackConnection>>)->Usually<T>
) )
-> Usually<Arc<RwLock<T>>>; -> Usually<Arc<RwLock<T>>>;
} }
impl JackActivate for JackClient { impl JackActivate for JackConnection {
fn activate_with <T: Audio + 'static> ( fn activate_with <T: Audio + 'static> (
self, self,
init: impl FnOnce(&Arc<RwLock<JackClient>>)->Usually<T> init: impl FnOnce(&Arc<RwLock<JackConnection>>)->Usually<T>
) )
-> Usually<Arc<RwLock<T>>> -> Usually<Arc<RwLock<T>>>
{ {

View file

@ -4,7 +4,7 @@ pub type DynamicAudioHandler = ClosureProcessHandler<(), BoxedAudioHandler>;
pub type BoxedAudioHandler = Box<dyn FnMut(&Client, &ProcessScope) -> Control + Send>; pub type BoxedAudioHandler = Box<dyn FnMut(&Client, &ProcessScope) -> Control + Send>;
/// Wraps [Client] or [DynamicAsyncClient] in place. /// Wraps [Client] or [DynamicAsyncClient] in place.
#[derive(Debug)] #[derive(Debug)]
pub enum JackClient { pub enum JackConnection {
/// Before activation. /// Before activation.
Inactive(Client), Inactive(Client),
/// During activation. /// During activation.
@ -12,18 +12,19 @@ pub enum JackClient {
/// After activation. Must not be dropped for JACK thread to persist. /// After activation. Must not be dropped for JACK thread to persist.
Active(DynamicAsyncClient), Active(DynamicAsyncClient),
} }
from!(|jack: JackClient|Client = match jack { from!(|jack: JackConnection|Client = match jack {
JackClient::Inactive(client) => client, JackConnection::Inactive(client) => client,
JackClient::Activating => panic!("jack client still activating"), JackConnection::Activating => panic!("jack client still activating"),
JackClient::Active(_) => panic!("jack client already activated"), JackConnection::Active(_) => panic!("jack client already activated"),
}); });
impl JackClient { impl JackConnection {
pub fn new (name: &str) -> Usually<Self> { pub fn new (name: &str) -> Usually<Self> {
let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?; let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?;
Ok(Self::Inactive(client)) Ok(Self::Inactive(client))
} }
} }
impl AudioEngine for JackClient { impl AudioEngine for JackConnection {
/// Return the internal [Client] handle that lets you call the JACK API.
fn client(&self) -> &Client { fn client(&self) -> &Client {
match self { match self {
Self::Inactive(ref client) => client, Self::Inactive(ref client) => client,
@ -31,6 +32,10 @@ impl AudioEngine for JackClient {
Self::Active(ref client) => client.as_client(), Self::Active(ref client) => client.as_client(),
} }
} }
/// Bind a process callback to a `JackConnection::Inactive`,
/// turning it into a `JackConnection::Active`. Needs work.
/// Strange ownership situation between the callback and
/// the host object.
fn activate( fn activate(
self, self,
mut cb: impl FnMut(&Arc<RwLock<Self>>, &Client, &ProcessScope) -> Control + Send + 'static, mut cb: impl FnMut(&Arc<RwLock<Self>>, &Client, &ProcessScope) -> Control + Send + 'static,

View file

@ -11,7 +11,7 @@ pub trait RegisterPort {
fn connect_audio_to (&self, my_output: &Port<AudioOut>, ports: &[String]) -> Usually<()>; fn connect_audio_to (&self, my_output: &Port<AudioOut>, ports: &[String]) -> Usually<()>;
} }
impl RegisterPort for Arc<RwLock<JackClient>> { impl RegisterPort for Arc<RwLock<JackConnection>> {
fn midi_in (&self, name: &str) -> Usually<Port<MidiIn>> { fn midi_in (&self, name: &str) -> Usually<Port<MidiIn>> {
Ok(self.read().unwrap().client().register_port(name, MidiIn::default())?) Ok(self.read().unwrap().client().register_port(name, MidiIn::default())?)
} }

View file

@ -127,7 +127,7 @@ pub struct MidiPlayer {
pub note_buf: Vec<u8>, pub note_buf: Vec<u8>,
} }
impl MidiPlayer { impl MidiPlayer {
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> { pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
Ok(Self { Ok(Self {
clock: ClockModel::from(jack), clock: ClockModel::from(jack),
play_phrase: None, play_phrase: None,
@ -324,7 +324,7 @@ impl HasPlayPhrase for MidiPlayer {
///// Methods used primarily by the process callback ///// Methods used primarily by the process callback
//impl MIDIPlayer { //impl MIDIPlayer {
//pub fn new ( //pub fn new (
//jack: &Arc<RwLock<JackClient>>, //jack: &Arc<RwLock<JackConnection>>,
//clock: &Arc<Clock>, //clock: &Arc<Clock>,
//name: &str //name: &str
//) -> Usually<Self> { //) -> Usually<Self> {

View file

@ -3,7 +3,7 @@ use crate::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Mixer { pub struct Mixer {
/// JACK client handle (needs to not be dropped for standalone mode to work). /// JACK client handle (needs to not be dropped for standalone mode to work).
pub jack: Arc<RwLock<JackClient>>, pub jack: Arc<RwLock<JackConnection>>,
pub name: String, pub name: String,
pub tracks: Vec<MixerTrack>, pub tracks: Vec<MixerTrack>,
pub selected_track: usize, pub selected_track: usize,
@ -25,7 +25,7 @@ pub struct MixerTrack {
audio!(|self: Mixer, _client, _scope|Control::Continue); audio!(|self: Mixer, _client, _scope|Control::Continue);
impl Mixer { impl Mixer {
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> { pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
Ok(Self { Ok(Self {
jack: jack.clone(), jack: jack.clone(),
name: name.into(), name: name.into(),

View file

@ -7,7 +7,7 @@ pub use self::lv2::LV2Plugin;
#[derive(Debug)] #[derive(Debug)]
pub struct Plugin { pub struct Plugin {
/// JACK client handle (needs to not be dropped for standalone mode to work). /// JACK client handle (needs to not be dropped for standalone mode to work).
pub jack: Arc<RwLock<JackClient>>, pub jack: Arc<RwLock<JackConnection>>,
pub name: String, pub name: String,
pub path: Option<String>, pub path: Option<String>,
pub plugin: Option<PluginKind>, pub plugin: Option<PluginKind>,
@ -40,7 +40,7 @@ impl Debug for PluginKind {
} }
impl Plugin { impl Plugin {
pub fn new_lv2 ( pub fn new_lv2 (
jack: &Arc<RwLock<JackClient>>, jack: &Arc<RwLock<JackConnection>>,
name: &str, name: &str,
path: &str, path: &str,
) -> Usually<Self> { ) -> Usually<Self> {
@ -131,7 +131,7 @@ audio!(|self: PluginAudio, client, scope|{
impl Plugin { impl Plugin {
/// Create a plugin host device. /// Create a plugin host device.
pub fn new ( pub fn new (
jack: &Arc<RwLock<JackClient>>, jack: &Arc<RwLock<JackConnection>>,
name: &str, name: &str,
) -> Usually<Self> { ) -> Usually<Self> {
Ok(Self { Ok(Self {

View file

@ -35,7 +35,7 @@ pub use self::sample_viewer::SampleViewer;
/// The sampler plugin plays sounds. /// The sampler plugin plays sounds.
#[derive(Debug)] #[derive(Debug)]
pub struct Sampler { pub struct Sampler {
pub jack: Arc<RwLock<JackClient>>, pub jack: Arc<RwLock<JackConnection>>,
pub name: String, pub name: String,
pub mapped: [Option<Arc<RwLock<Sample>>>;128], pub mapped: [Option<Arc<RwLock<Sample>>>;128],
pub recording: Option<(usize, Arc<RwLock<Sample>>)>, pub recording: Option<(usize, Arc<RwLock<Sample>>)>,
@ -49,7 +49,7 @@ pub struct Sampler {
pub output_gain: f32 pub output_gain: f32
} }
impl Sampler { impl Sampler {
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> { pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
Ok(Self { Ok(Self {
midi_in: jack.midi_in(&format!("M/{name}"))?, midi_in: jack.midi_in(&format!("M/{name}"))?,
audio_ins: vec![ audio_ins: vec![

View file

@ -6,7 +6,7 @@ use PhraseCommand::*;
use PhrasePoolCommand::*; use PhrasePoolCommand::*;
/// Root view for standalone `tek_sequencer`. /// Root view for standalone `tek_sequencer`.
pub struct SequencerTui { pub struct SequencerTui {
_jack: Arc<RwLock<JackClient>>, _jack: Arc<RwLock<JackConnection>>,
pub transport: bool, pub transport: bool,
pub selectors: bool, pub selectors: bool,
pub clock: ClockModel, pub clock: ClockModel,

View file

@ -82,7 +82,7 @@ pub struct ClockModel {
pub chunk: Arc<AtomicUsize>, pub chunk: Arc<AtomicUsize>,
} }
from!(|jack: &Arc<RwLock<JackClient>>| ClockModel = { from!(|jack: &Arc<RwLock<JackConnection>>| ClockModel = {
let jack = jack.read().unwrap(); let jack = jack.read().unwrap();
let chunk = jack.client().buffer_size(); let chunk = jack.client().buffer_size();
let transport = jack.client().transport(); let transport = jack.client().transport();

View file

@ -5,7 +5,7 @@ use FocusCommand::{Next, Prev};
use KeyCode::{Enter, Left, Right, Char}; use KeyCode::{Enter, Left, Right, Char};
/// Transport clock app. /// Transport clock app.
pub struct TransportTui { pub struct TransportTui {
pub jack: Arc<RwLock<JackClient>>, pub jack: Arc<RwLock<JackConnection>>,
pub clock: ClockModel, pub clock: ClockModel,
pub size: Measure<Tui>, pub size: Measure<Tui>,
pub cursor: (usize, usize), pub cursor: (usize, usize),