Merge pull request #2237 from iced-rs/fix/mapped-subscription-id
Use `TypeId` to identify `subscription::Map`
This commit is contained in:
commit
8e76d53803
2 changed files with 30 additions and 9 deletions
|
|
@ -89,6 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- `size_hint` not being called from `element::Map`. [#2224](https://github.com/iced-rs/iced/pull/2224)
|
- `size_hint` not being called from `element::Map`. [#2224](https://github.com/iced-rs/iced/pull/2224)
|
||||||
- `size_hint` not being called from `element::Explain`. [#2225](https://github.com/iced-rs/iced/pull/2225)
|
- `size_hint` not being called from `element::Explain`. [#2225](https://github.com/iced-rs/iced/pull/2225)
|
||||||
- Slow touch scrolling for `TextEditor` widget. [#2140](https://github.com/iced-rs/iced/pull/2140)
|
- Slow touch scrolling for `TextEditor` widget. [#2140](https://github.com/iced-rs/iced/pull/2140)
|
||||||
|
- `Subscription::map` using unreliable function pointer hash to identify mappers. [#2237](https://github.com/iced-rs/iced/pull/2237)
|
||||||
|
|
||||||
Many thanks to...
|
Many thanks to...
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use crate::{BoxStream, MaybeSend};
|
||||||
|
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use futures::never::Never;
|
use futures::never::Never;
|
||||||
|
use std::any::TypeId;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
/// A stream of runtime events.
|
/// A stream of runtime events.
|
||||||
|
|
@ -88,17 +89,29 @@ impl<Message> Subscription<Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms the [`Subscription`] output with the given function.
|
/// Transforms the [`Subscription`] output with the given function.
|
||||||
pub fn map<A>(mut self, f: fn(Message) -> A) -> Subscription<A>
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// The closure provided must be a non-capturing closure. The method
|
||||||
|
/// will panic in debug mode otherwise.
|
||||||
|
pub fn map<F, A>(mut self, f: F) -> Subscription<A>
|
||||||
where
|
where
|
||||||
Message: 'static,
|
Message: 'static,
|
||||||
|
F: Fn(Message) -> A + MaybeSend + Clone + 'static,
|
||||||
A: 'static,
|
A: 'static,
|
||||||
{
|
{
|
||||||
|
debug_assert!(
|
||||||
|
std::mem::size_of::<F>() == 0,
|
||||||
|
"the closure {} provided in `Subscription::map` is capturing",
|
||||||
|
std::any::type_name::<F>(),
|
||||||
|
);
|
||||||
|
|
||||||
Subscription {
|
Subscription {
|
||||||
recipes: self
|
recipes: self
|
||||||
.recipes
|
.recipes
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|recipe| {
|
.map(move |recipe| {
|
||||||
Box::new(Map::new(recipe, f)) as Box<dyn Recipe<Output = A>>
|
Box::new(Map::new(recipe, f.clone()))
|
||||||
|
as Box<dyn Recipe<Output = A>>
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
|
|
@ -143,27 +156,34 @@ pub trait Recipe {
|
||||||
fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output>;
|
fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Map<A, B> {
|
struct Map<A, B, F>
|
||||||
|
where
|
||||||
|
F: Fn(A) -> B + 'static,
|
||||||
|
{
|
||||||
recipe: Box<dyn Recipe<Output = A>>,
|
recipe: Box<dyn Recipe<Output = A>>,
|
||||||
mapper: fn(A) -> B,
|
mapper: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Map<A, B> {
|
impl<A, B, F> Map<A, B, F>
|
||||||
fn new(recipe: Box<dyn Recipe<Output = A>>, mapper: fn(A) -> B) -> Self {
|
where
|
||||||
|
F: Fn(A) -> B + 'static,
|
||||||
|
{
|
||||||
|
fn new(recipe: Box<dyn Recipe<Output = A>>, mapper: F) -> Self {
|
||||||
Map { recipe, mapper }
|
Map { recipe, mapper }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Recipe for Map<A, B>
|
impl<A, B, F> Recipe for Map<A, B, F>
|
||||||
where
|
where
|
||||||
A: 'static,
|
A: 'static,
|
||||||
B: 'static,
|
B: 'static,
|
||||||
|
F: Fn(A) -> B + 'static + MaybeSend,
|
||||||
{
|
{
|
||||||
type Output = B;
|
type Output = B;
|
||||||
|
|
||||||
fn hash(&self, state: &mut Hasher) {
|
fn hash(&self, state: &mut Hasher) {
|
||||||
|
TypeId::of::<F>().hash(state);
|
||||||
self.recipe.hash(state);
|
self.recipe.hash(state);
|
||||||
self.mapper.hash(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output> {
|
fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue