mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-14 08:01:14 +01:00
Change static callback vec to local
This commit is contained in:
parent
4e36637e19
commit
1680acc5e9
5 changed files with 184 additions and 90 deletions
|
@ -2,9 +2,6 @@ use pinnacle_api::prelude::*;
|
||||||
use pinnacle_api::*;
|
use pinnacle_api::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// let mut num = 5;
|
|
||||||
// let test = &mut num;
|
|
||||||
|
|
||||||
pinnacle_api::connect().unwrap();
|
pinnacle_api::connect().unwrap();
|
||||||
|
|
||||||
let mod_key = Modifier::Ctrl;
|
let mod_key = Modifier::Ctrl;
|
||||||
|
@ -13,65 +10,97 @@ fn main() {
|
||||||
|
|
||||||
process::set_env("MOZ_ENABLE_WAYLAND", "1");
|
process::set_env("MOZ_ENABLE_WAYLAND", "1");
|
||||||
|
|
||||||
input::mousebind(&[mod_key], MouseButton::Left, MouseEdge::Press, move || {
|
let mut callback_vec = CallbackVec::new();
|
||||||
window::begin_move(MouseButton::Left);
|
|
||||||
});
|
input::mousebind(
|
||||||
|
&[mod_key],
|
||||||
|
MouseButton::Left,
|
||||||
|
MouseEdge::Press,
|
||||||
|
move |_| {
|
||||||
|
window::begin_move(MouseButton::Left);
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
input::mousebind(
|
input::mousebind(
|
||||||
&[mod_key],
|
&[mod_key],
|
||||||
MouseButton::Right,
|
MouseButton::Right,
|
||||||
MouseEdge::Press,
|
MouseEdge::Press,
|
||||||
move || {
|
move |_| {
|
||||||
window::begin_resize(MouseButton::Right);
|
window::begin_resize(MouseButton::Right);
|
||||||
},
|
},
|
||||||
|
&mut callback_vec,
|
||||||
);
|
);
|
||||||
|
|
||||||
input::keybind(&[mod_key, Modifier::Alt], 'q', pinnacle::quit);
|
input::keybind(
|
||||||
|
&[mod_key, Modifier::Alt],
|
||||||
|
'q',
|
||||||
|
|_| pinnacle::quit(),
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
input::keybind(&[mod_key, Modifier::Alt], 'c', move || {
|
input::keybind(
|
||||||
if let Some(window) = window::get_focused() {
|
&[mod_key, Modifier::Alt],
|
||||||
window.close();
|
'c',
|
||||||
}
|
move |_| {
|
||||||
});
|
if let Some(window) = window::get_focused() {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
input::keybind(&[mod_key], xkbcommon::xkb::keysyms::KEY_Return, move || {
|
input::keybind(
|
||||||
process::spawn(vec![terminal]).unwrap();
|
&[mod_key],
|
||||||
});
|
xkbcommon::xkb::keysyms::KEY_Return,
|
||||||
|
move |_| {
|
||||||
|
process::spawn(vec![terminal]).unwrap();
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
input::keybind(
|
input::keybind(
|
||||||
&[mod_key, Modifier::Alt],
|
&[mod_key, Modifier::Alt],
|
||||||
xkbcommon::xkb::keysyms::KEY_space,
|
xkbcommon::xkb::keysyms::KEY_space,
|
||||||
move || {
|
move |_| {
|
||||||
if let Some(window) = window::get_focused() {
|
if let Some(window) = window::get_focused() {
|
||||||
window.toggle_floating();
|
window.toggle_floating();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
&mut callback_vec,
|
||||||
);
|
);
|
||||||
|
|
||||||
input::keybind(&[mod_key], 'f', move || {
|
input::keybind(
|
||||||
if let Some(window) = window::get_focused() {
|
&[mod_key],
|
||||||
window.toggle_fullscreen();
|
'f',
|
||||||
}
|
move |_| {
|
||||||
});
|
if let Some(window) = window::get_focused() {
|
||||||
|
window.toggle_fullscreen();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
input::keybind(&[mod_key], 'm', move || {
|
input::keybind(
|
||||||
if let Some(window) = window::get_focused() {
|
&[mod_key],
|
||||||
window.toggle_maximized();
|
'm',
|
||||||
}
|
move |_| {
|
||||||
});
|
if let Some(window) = window::get_focused() {
|
||||||
|
window.toggle_maximized();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
|
|
||||||
let tags = ["1", "2", "3", "4", "5"];
|
let tags = ["1", "2", "3", "4", "5"];
|
||||||
|
|
||||||
output::connect_for_all(move |output| {
|
output::connect_for_all(
|
||||||
tag::add(&output, tags.as_slice());
|
move |output, _| {
|
||||||
tag::get("1", Some(&output)).unwrap().toggle();
|
tag::add(&output, tags.as_slice());
|
||||||
});
|
tag::get("1", Some(&output)).unwrap().toggle();
|
||||||
|
},
|
||||||
// let mut num = 5;
|
&mut callback_vec,
|
||||||
//
|
);
|
||||||
// input::keybind(&[mod_key], 'm', || {
|
|
||||||
// num += 1;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let layout_cycler = tag.layout_cycler(&[
|
// let layout_cycler = tag.layout_cycler(&[
|
||||||
// Layout::MasterStack,
|
// Layout::MasterStack,
|
||||||
|
@ -89,38 +118,46 @@ fn main() {
|
||||||
|
|
||||||
for tag_name in tags.iter().map(|t| t.to_string()) {
|
for tag_name in tags.iter().map(|t| t.to_string()) {
|
||||||
let t = tag_name.clone();
|
let t = tag_name.clone();
|
||||||
input::keybind(&[mod_key], tag_name.chars().next().unwrap(), move || {
|
input::keybind(
|
||||||
tag::get(&t, None).unwrap().switch_to();
|
&[mod_key],
|
||||||
});
|
tag_name.chars().next().unwrap(),
|
||||||
|
move |_| {
|
||||||
|
tag::get(&t, None).unwrap().switch_to();
|
||||||
|
},
|
||||||
|
&mut callback_vec,
|
||||||
|
);
|
||||||
let t = tag_name.clone();
|
let t = tag_name.clone();
|
||||||
input::keybind(
|
input::keybind(
|
||||||
&[mod_key, Modifier::Shift],
|
&[mod_key, Modifier::Shift],
|
||||||
tag_name.chars().next().unwrap(),
|
tag_name.chars().next().unwrap(),
|
||||||
move || {
|
move |_| {
|
||||||
tag::get(&t, None).unwrap().toggle();
|
tag::get(&t, None).unwrap().toggle();
|
||||||
},
|
},
|
||||||
|
&mut callback_vec,
|
||||||
);
|
);
|
||||||
let t = tag_name.clone();
|
let t = tag_name.clone();
|
||||||
input::keybind(
|
input::keybind(
|
||||||
&[mod_key, Modifier::Alt],
|
&[mod_key, Modifier::Alt],
|
||||||
tag_name.chars().next().unwrap(),
|
tag_name.chars().next().unwrap(),
|
||||||
move || {
|
move |_| {
|
||||||
if let Some(window) = window::get_focused() {
|
if let Some(window) = window::get_focused() {
|
||||||
window.move_to_tag(&tag::get(&t, None).unwrap());
|
window.move_to_tag(&tag::get(&t, None).unwrap());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
&mut callback_vec,
|
||||||
);
|
);
|
||||||
let t = tag_name.clone();
|
let t = tag_name.clone();
|
||||||
input::keybind(
|
input::keybind(
|
||||||
&[mod_key, Modifier::Shift, Modifier::Alt],
|
&[mod_key, Modifier::Shift, Modifier::Alt],
|
||||||
tag_name.chars().next().unwrap(),
|
tag_name.chars().next().unwrap(),
|
||||||
move || {
|
move |_| {
|
||||||
if let Some(window) = window::get_focused() {
|
if let Some(window) = window::get_focused() {
|
||||||
window.toggle_tag(&tag::get(&t, None).unwrap());
|
window.toggle_tag(&tag::get(&t, None).unwrap());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
&mut callback_vec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinnacle_api::listen();
|
pinnacle_api::listen(callback_vec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use xkbcommon::xkb::Keysym;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
msg::{Args, CallbackId, KeyIntOrString, Msg},
|
msg::{Args, CallbackId, KeyIntOrString, Msg},
|
||||||
send_msg, CALLBACK_VEC,
|
send_msg, CallbackVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Set a keybind.
|
/// Set a keybind.
|
||||||
|
@ -18,17 +18,22 @@ use crate::{
|
||||||
/// - [`char`]: A character of the key you want. This can be `a`, `~`, `@`, and so on.
|
/// - [`char`]: A character of the key you want. This can be `a`, `~`, `@`, and so on.
|
||||||
/// - [`u32`]: The key in numeric form. You can use the keys defined in [`xkbcommon::xkb::keysyms`] for this.
|
/// - [`u32`]: The key in numeric form. You can use the keys defined in [`xkbcommon::xkb::keysyms`] for this.
|
||||||
/// - [`Keysym`]: The key in `Keysym` form, from [xkbcommon::xkb::Keysym].
|
/// - [`Keysym`]: The key in `Keysym` form, from [xkbcommon::xkb::Keysym].
|
||||||
pub fn keybind<F>(modifiers: &[Modifier], key: impl Into<KeyIntOrString>, mut action: F)
|
///
|
||||||
where
|
/// `action` takes in a `&mut `[`CallbackVec`] for use in the closure.
|
||||||
F: FnMut() + Send + 'static,
|
pub fn keybind<'a, F>(
|
||||||
|
modifiers: &[Modifier],
|
||||||
|
key: impl Into<KeyIntOrString>,
|
||||||
|
mut action: F,
|
||||||
|
callback_vec: &mut CallbackVec<'a>,
|
||||||
|
) where
|
||||||
|
F: FnMut(&mut CallbackVec) + 'a,
|
||||||
{
|
{
|
||||||
let args_callback = move |_: Option<Args>| {
|
let args_callback = move |_: Option<Args>, callback_vec: &mut CallbackVec<'_>| {
|
||||||
action();
|
action(callback_vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
let len = callback_vec.callbacks.len();
|
||||||
let len = callback_vec.len();
|
callback_vec.callbacks.push(Box::new(args_callback));
|
||||||
callback_vec.push(Box::new(args_callback));
|
|
||||||
|
|
||||||
let key = key.into();
|
let key = key.into();
|
||||||
|
|
||||||
|
@ -45,17 +50,23 @@ where
|
||||||
///
|
///
|
||||||
/// The mousebind can happen either on button press or release, so you must
|
/// The mousebind can happen either on button press or release, so you must
|
||||||
/// specify which edge you desire.
|
/// specify which edge you desire.
|
||||||
pub fn mousebind<F>(modifiers: &[Modifier], button: MouseButton, edge: MouseEdge, mut action: F)
|
///
|
||||||
where
|
/// `action` takes in a `&mut `[`CallbackVec`] for use in the closure.
|
||||||
F: FnMut() + Send + 'static,
|
pub fn mousebind<'a, F>(
|
||||||
|
modifiers: &[Modifier],
|
||||||
|
button: MouseButton,
|
||||||
|
edge: MouseEdge,
|
||||||
|
mut action: F,
|
||||||
|
callback_vec: &mut CallbackVec<'a>,
|
||||||
|
) where
|
||||||
|
F: FnMut(&mut CallbackVec) + 'a,
|
||||||
{
|
{
|
||||||
let args_callback = move |_: Option<Args>| {
|
let args_callback = move |_: Option<Args>, callback_vec: &mut CallbackVec<'_>| {
|
||||||
action();
|
action(callback_vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
let len = callback_vec.callbacks.len();
|
||||||
let len = callback_vec.len();
|
callback_vec.callbacks.push(Box::new(args_callback));
|
||||||
callback_vec.push(Box::new(args_callback));
|
|
||||||
|
|
||||||
let msg = Msg::SetMousebind {
|
let msg = Msg::SetMousebind {
|
||||||
modifiers: modifiers.to_vec(),
|
modifiers: modifiers.to_vec(),
|
||||||
|
|
|
@ -46,8 +46,6 @@ use msg::{Args, CallbackId, IncomingMsg, Msg, Request, RequestResponse};
|
||||||
use crate::msg::RequestId;
|
use crate::msg::RequestId;
|
||||||
|
|
||||||
static STREAM: OnceLock<Mutex<UnixStream>> = OnceLock::new();
|
static STREAM: OnceLock<Mutex<UnixStream>> = OnceLock::new();
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
static CALLBACK_VEC: Mutex<Vec<Box<dyn FnMut(Option<Args>) + Send>>> = Mutex::new(Vec::new());
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref UNREAD_CALLBACK_MSGS: Mutex<HashMap<CallbackId, IncomingMsg>> = Mutex::new(HashMap::new());
|
static ref UNREAD_CALLBACK_MSGS: Mutex<HashMap<CallbackId, IncomingMsg>> = Mutex::new(HashMap::new());
|
||||||
static ref UNREAD_REQUEST_MSGS: Mutex<HashMap<RequestId, IncomingMsg>> = Mutex::new(HashMap::new());
|
static ref UNREAD_REQUEST_MSGS: Mutex<HashMap<RequestId, IncomingMsg>> = Mutex::new(HashMap::new());
|
||||||
|
@ -157,7 +155,7 @@ pub fn connect() -> anyhow::Result<()> {
|
||||||
/// Begin listening for messages coming from Pinnacle.
|
/// Begin listening for messages coming from Pinnacle.
|
||||||
///
|
///
|
||||||
/// This needs to be called at the very end of your `setup` function.
|
/// This needs to be called at the very end of your `setup` function.
|
||||||
pub fn listen() -> Infallible {
|
pub fn listen(mut callback_vec: CallbackVec) -> Infallible {
|
||||||
loop {
|
loop {
|
||||||
let mut unread_callback_msgs = UNREAD_CALLBACK_MSGS.lock().unwrap();
|
let mut unread_callback_msgs = UNREAD_CALLBACK_MSGS.lock().unwrap();
|
||||||
|
|
||||||
|
@ -168,11 +166,18 @@ pub fn listen() -> Infallible {
|
||||||
let IncomingMsg::CallCallback { callback_id, args } = entry.remove() else {
|
let IncomingMsg::CallCallback { callback_id, args } = entry.remove() else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
|
||||||
let Some(callback) = callback_vec.get_mut(callback_id.0 as usize) else {
|
// Take the callback out and replace it with a dummy callback
|
||||||
unreachable!();
|
// to allow callback_vec to be used mutably below.
|
||||||
};
|
let mut callback = std::mem::replace(
|
||||||
callback(args);
|
&mut callback_vec.callbacks[callback_id.0 as usize],
|
||||||
|
Box::new(|_, _| {}),
|
||||||
|
);
|
||||||
|
|
||||||
|
callback(args, &mut callback_vec);
|
||||||
|
|
||||||
|
// Put it back.
|
||||||
|
callback_vec.callbacks[callback_id.0 as usize] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
let incoming_msg = read_msg(None);
|
let incoming_msg = read_msg(None);
|
||||||
|
@ -181,11 +186,43 @@ pub fn listen() -> Infallible {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
let mut callback = std::mem::replace(
|
||||||
let Some(callback) = callback_vec.get_mut(callback_id.0 as usize) else {
|
&mut callback_vec.callbacks[callback_id.0 as usize],
|
||||||
unreachable!();
|
Box::new(|_, _| {}),
|
||||||
};
|
);
|
||||||
|
|
||||||
callback(args);
|
callback(args, &mut callback_vec);
|
||||||
|
|
||||||
|
callback_vec.callbacks[callback_id.0 as usize] = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A wrapper around a vector that holds all of your callbacks.
|
||||||
|
///
|
||||||
|
/// You will need to create this before you can start calling config functions
|
||||||
|
/// that require callbacks.
|
||||||
|
///
|
||||||
|
/// Because your callbacks can capture things, we need a non-static way to hold them.
|
||||||
|
/// That's where this struct comes in.
|
||||||
|
///
|
||||||
|
/// Every function that needs you to provide a callback will also need you to
|
||||||
|
/// provide a `&mut CallbackVec`. This will insert the callback for use in [`listen`].
|
||||||
|
///
|
||||||
|
/// Additionally, all callbacks will also take in `&mut CallbackVec`. This is so you can
|
||||||
|
/// call functions that need it inside of other callbacks.
|
||||||
|
///
|
||||||
|
/// At the end of your config, you will need to call [`listen`] to begin listening for
|
||||||
|
/// messages from Pinnacle that will call your callbacks. Here, you must in pass your
|
||||||
|
/// `CallbackVec`.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CallbackVec<'a> {
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
pub(crate) callbacks: Vec<Box<dyn FnMut(Option<Args>, &mut CallbackVec) + 'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CallbackVec<'a> {
|
||||||
|
/// Create a new, empty `CallbackVec`.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
msg::{Args, CallbackId, Msg, Request, RequestResponse},
|
msg::{Args, CallbackId, Msg, Request, RequestResponse},
|
||||||
request, send_msg,
|
request, send_msg,
|
||||||
tag::TagHandle,
|
tag::TagHandle,
|
||||||
CALLBACK_VEC,
|
CallbackVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A unique identifier for an output.
|
/// A unique identifier for an output.
|
||||||
|
@ -58,6 +58,10 @@ pub fn get_focused() -> Option<OutputHandle> {
|
||||||
/// When called, `connect_for_all` will run `func` with all currently connected outputs.
|
/// When called, `connect_for_all` will run `func` with all currently connected outputs.
|
||||||
/// If a new output is connected, `func` will also be called with it.
|
/// If a new output is connected, `func` will also be called with it.
|
||||||
///
|
///
|
||||||
|
/// `func` takes in two parameters:
|
||||||
|
/// - `0`: An [`OutputHandle`] you can act on.
|
||||||
|
/// - `1`: A `&mut `[`CallbackVec`] for use in the closure.
|
||||||
|
///
|
||||||
/// This will *not* be called if it has already been called for a given connector.
|
/// This will *not* be called if it has already been called for a given connector.
|
||||||
/// This means turning your monitor off and on or unplugging and replugging it *to the same port*
|
/// This means turning your monitor off and on or unplugging and replugging it *to the same port*
|
||||||
/// won't trigger `func`. Plugging it in to a new port *will* trigger `func`.
|
/// won't trigger `func`. Plugging it in to a new port *will* trigger `func`.
|
||||||
|
@ -66,19 +70,18 @@ pub fn get_focused() -> Option<OutputHandle> {
|
||||||
/// Please note: this function will be run *after* Pinnacle processes your entire config.
|
/// Please note: this function will be run *after* Pinnacle processes your entire config.
|
||||||
/// For example, if you define tags in `func` but toggle them directly after `connect_for_all`,
|
/// For example, if you define tags in `func` but toggle them directly after `connect_for_all`,
|
||||||
/// nothing will happen as the tags haven't been added yet.
|
/// nothing will happen as the tags haven't been added yet.
|
||||||
pub fn connect_for_all<F>(mut func: F)
|
pub fn connect_for_all<'a, F>(mut func: F, callback_vec: &mut CallbackVec<'a>)
|
||||||
where
|
where
|
||||||
F: FnMut(OutputHandle) + Send + 'static,
|
F: FnMut(OutputHandle, &mut CallbackVec) + 'a,
|
||||||
{
|
{
|
||||||
let args_callback = move |args: Option<Args>| {
|
let args_callback = move |args: Option<Args>, callback_vec: &mut CallbackVec<'_>| {
|
||||||
if let Some(Args::ConnectForAllOutputs { output_name }) = args {
|
if let Some(Args::ConnectForAllOutputs { output_name }) = args {
|
||||||
func(OutputHandle(OutputName(output_name)));
|
func(OutputHandle(OutputName(output_name)), callback_vec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
let len = callback_vec.callbacks.len();
|
||||||
let len = callback_vec.len();
|
callback_vec.callbacks.push(Box::new(args_callback));
|
||||||
callback_vec.push(Box::new(args_callback));
|
|
||||||
|
|
||||||
let msg = Msg::ConnectForAllOutputs {
|
let msg = Msg::ConnectForAllOutputs {
|
||||||
callback_id: CallbackId(len as u32),
|
callback_id: CallbackId(len as u32),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
msg::{Args, CallbackId, Msg},
|
msg::{Args, CallbackId, Msg},
|
||||||
send_msg, CALLBACK_VEC,
|
send_msg, CallbackVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Spawn a process.
|
/// Spawn a process.
|
||||||
|
@ -26,11 +26,18 @@ pub fn spawn(command: Vec<&str>) -> anyhow::Result<()> {
|
||||||
/// - `1`: The process's stderr printed this line.
|
/// - `1`: The process's stderr printed this line.
|
||||||
/// - `2`: The process exited with this code.
|
/// - `2`: The process exited with this code.
|
||||||
/// - `3`: The process exited with this message.
|
/// - `3`: The process exited with this message.
|
||||||
pub fn spawn_with_callback<F>(command: Vec<&str>, mut callback: F) -> anyhow::Result<()>
|
/// - `4`: A `&mut `[`CallbackVec`] for use inside the closure.
|
||||||
|
///
|
||||||
|
/// You must also pass in a mutable reference to a [`CallbackVec`] in order to store your callback.
|
||||||
|
pub fn spawn_with_callback<'a, F>(
|
||||||
|
command: Vec<&str>,
|
||||||
|
mut callback: F,
|
||||||
|
callback_vec: &mut CallbackVec<'a>,
|
||||||
|
) -> anyhow::Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(Option<String>, Option<String>, Option<i32>, Option<String>) + Send + 'static,
|
F: FnMut(Option<String>, Option<String>, Option<i32>, Option<String>, &mut CallbackVec) + 'a,
|
||||||
{
|
{
|
||||||
let args_callback = move |args: Option<Args>| {
|
let args_callback = move |args: Option<Args>, callback_vec: &mut CallbackVec<'_>| {
|
||||||
if let Some(Args::Spawn {
|
if let Some(Args::Spawn {
|
||||||
stdout,
|
stdout,
|
||||||
stderr,
|
stderr,
|
||||||
|
@ -38,13 +45,12 @@ where
|
||||||
exit_msg,
|
exit_msg,
|
||||||
}) = args
|
}) = args
|
||||||
{
|
{
|
||||||
callback(stdout, stderr, exit_code, exit_msg);
|
callback(stdout, stderr, exit_code, exit_msg, callback_vec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut callback_vec = CALLBACK_VEC.lock().unwrap();
|
let len = callback_vec.callbacks.len();
|
||||||
let len = callback_vec.len();
|
callback_vec.callbacks.push(Box::new(args_callback));
|
||||||
callback_vec.push(Box::new(args_callback));
|
|
||||||
|
|
||||||
let msg = Msg::Spawn {
|
let msg = Msg::Spawn {
|
||||||
command: command.into_iter().map(|s| s.to_string()).collect(),
|
command: command.into_iter().map(|s| s.to_string()).collect(),
|
||||||
|
|
Loading…
Reference in a new issue