trying own signal handler impl
This commit is contained in:
parent
3f6909128d
commit
40db5b1b18
2 changed files with 90 additions and 0 deletions
|
@ -19,6 +19,9 @@ pub mod subsonic_vala;
|
|||
|
||||
mod playbin2;
|
||||
|
||||
mod signal;
|
||||
pub use signal::{Signal, SignalHandler};
|
||||
|
||||
use gettextrs::{bind_textdomain_codeset, bindtextdomain, setlocale, textdomain, LocaleCategory};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{gio, glib};
|
||||
|
|
87
src/signal.rs
Normal file
87
src/signal.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Signal<T> {
|
||||
handlers: RefCell<Vec<Box<dyn FnMut(T) -> bool>>>,
|
||||
just_connected: RefCell<Vec<Box<dyn FnMut(T) -> bool>>>,
|
||||
}
|
||||
|
||||
pub struct SignalHandler(Weak<Cell<bool>>);
|
||||
|
||||
impl SignalHandler {
|
||||
pub fn disconnect(self) -> bool {
|
||||
match self.0.upgrade() {
|
||||
None => false,
|
||||
Some(cell) => {
|
||||
cell.set(true);
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Signal<T> {
|
||||
fn connect_impl(&self, f: impl FnMut(T) -> bool + 'static) {
|
||||
self.just_connected.borrow_mut().push(Box::new(f));
|
||||
}
|
||||
|
||||
pub fn connect(&self, mut f: impl FnMut(T) -> bool + 'static) -> SignalHandler {
|
||||
let disconnect = Rc::new(Cell::new(false));
|
||||
let disconnect_weak = Rc::downgrade(&disconnect);
|
||||
|
||||
self.connect_impl(move |t| match disconnect.get() {
|
||||
false => false,
|
||||
true => {
|
||||
f(t);
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
SignalHandler(disconnect_weak)
|
||||
}
|
||||
|
||||
pub fn connect_listener<L: 'static>(
|
||||
&self,
|
||||
listener: &Rc<L>,
|
||||
mut f: impl FnMut(Rc<L>, T) -> bool + 'static,
|
||||
) -> SignalHandler {
|
||||
let listener = Rc::downgrade(listener);
|
||||
|
||||
self.connect(move |t| match listener.upgrade() {
|
||||
None => false,
|
||||
Some(listener) => f(listener, t),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Signal<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
pub fn emit(&self, t: T) {
|
||||
let mut handlers = self
|
||||
.handlers
|
||||
.try_borrow_mut()
|
||||
.expect("tried to re-emit signal during emission");
|
||||
handlers.append(self.just_connected.borrow_mut().as_mut());
|
||||
|
||||
let mut i = 0;
|
||||
let mut skip = 0;
|
||||
loop {
|
||||
if handlers[i + skip](t.clone()) {
|
||||
i += 1;
|
||||
} else {
|
||||
skip += 1;
|
||||
}
|
||||
|
||||
if i + skip == handlers.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
handlers.swap(i, i + skip);
|
||||
}
|
||||
|
||||
handlers.truncate(i);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue