When using methods with callbacks, it is common to create a block for the sole purpose of passing it to that callback. For example, in Winit we do:
unsafe {
center.addObserverForName_object_queue_usingBlock(
Some(name),
None,
None,
&RcBlock::new(move |notification| {
// ...
}),
)
}
It's a lot more rare to re-use the block, or choose a different kind of storage (like global_block!) for it, because the performance of that usually doesn't matter. It might be nice if we could avoid the &RcBlock::new(...), and simply pass the closure to the method?
I wouldn't want to just change the signature to impl Fn(&NSNotification), because that would mean we would always have to allocate a new block even if one isn't needed (and that goes against the spirit of this project).
One way to implement this would be to add a trait to convert from impl Fn(T) -> R to &Block<dyn Fn(T) -> R>:
pub trait Blockable<F: ?Sized> {
type Storage: AsRef<Block<F>>;
fn to_storage(self) -> Self::Storage;
}
impl<T, R, Closure: Fn(T) -> R> Blockable<dyn Fn(T) -> R> for Closure {
type Storage = RcBlock<dyn Fn(T) -> R>;
fn to_storage(self) -> Self::Storage {
RcBlock::new(self)
}
}
impl<T, R> Blockable<dyn Fn(T) -> R> for &Block<dyn Fn(T) -> R> {
type Storage = Self;
fn to_storage(self) -> Self::Storage {
self
}
}
// Similar for `RcBlock` and `&RcBlock` probably.
I'm yet unsure if this is worth it?
It would also conflict with rust-lang/rust#29625, we wouldn't be able to implement Fn for Block if that becomes possible in the future.
When using methods with callbacks, it is common to create a block for the sole purpose of passing it to that callback. For example, in Winit we do:
It's a lot more rare to re-use the block, or choose a different kind of storage (like
global_block!) for it, because the performance of that usually doesn't matter. It might be nice if we could avoid the&RcBlock::new(...), and simply pass the closure to the method?I wouldn't want to just change the signature to
impl Fn(&NSNotification), because that would mean we would always have to allocate a new block even if one isn't needed (and that goes against the spirit of this project).One way to implement this would be to add a trait to convert from
impl Fn(T) -> Rto&Block<dyn Fn(T) -> R>:I'm yet unsure if this is worth it?
It would also conflict with rust-lang/rust#29625, we wouldn't be able to implement
FnforBlockif that becomes possible in the future.