fix: Don't rely on image handle not being dropped

It now causes a memory leak, though. :/
This commit is contained in:
Liam Murphy 2021-03-21 15:34:20 +11:00
parent e9d122b1aa
commit 99c56b9bff
No known key found for this signature in database
GPG key ID: 792DFA5B236BDF05

View file

@ -76,14 +76,21 @@ impl<Message> Widget<Message> for Image {
use dodrio::builder::*; use dodrio::builder::*;
use dodrio::bumpalo::collections::String; use dodrio::bumpalo::collections::String;
let src = String::from_str_in( let src = match self.handle.data.as_ref() {
match self.handle.data.as_ref() { Data::Path(path) => {
Data::Path(path) => path.to_str().unwrap_or(""), String::from_str_in(path.to_str().unwrap_or(""), bump)
Data::ObjectUrl(url) => &url, .into_bump_str()
}, }
bump, Data::Bytes(bytes) => bump.alloc(
) Url::create_object_url_with_blob(
.into_bump_str(); &Blob::new_with_u8_array_sequence(&Array::of1(
&Uint8Array::from(bytes.as_slice()),
))
.unwrap(),
)
.unwrap(),
),
};
let alt = String::from_str_in(&self.alt, bump).into_bump_str(); let alt = String::from_str_in(&self.alt, bump).into_bump_str();
@ -129,23 +136,10 @@ impl Handle {
/// Creates an image [`Handle`] containing the image data directly. /// Creates an image [`Handle`] containing the image data directly.
/// ///
/// NOTE: this unnecessarily takes ownership of the data to be compaticle with `iced_native`. /// This is useful if you already have your image loaded in-memory, maybe
/// If you're only using `iced_web`, you should use `from_slice` instead. /// because you downloaded or generated it procedurally.
pub fn from_memory(bytes: Vec<u8>) -> Handle { pub fn from_memory(bytes: Vec<u8>) -> Handle {
Handle::from_slice(bytes.as_slice()) Self::from_data(Data::Bytes(bytes))
}
/// Creates an image [`Handle`] containing the image data directly.
pub fn from_slice(bytes: &[u8]) -> Handle {
// This copies the memory twice (once in Uint8Array::from and once in Blob::new),
// but unsafe code is needed not to do that and #[forbid(unsafe_code)] is on.
let blob = Blob::new_with_u8_array_sequence(&Array::of1(
&Uint8Array::from(bytes),
))
.unwrap();
Self::from_data(Data::ObjectUrl(
Url::create_object_url_with_blob(&blob).unwrap(),
))
} }
fn from_data(data: Data) -> Handle { fn from_data(data: Data) -> Handle {
@ -187,24 +181,15 @@ pub enum Data {
/// A remote image /// A remote image
Path(PathBuf), Path(PathBuf),
/// An Object URL pointing to some image data. /// In-memory data
ObjectUrl(String), Bytes(Vec<u8>),
} }
impl std::fmt::Debug for Data { impl std::fmt::Debug for Data {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Data::Path(path) => write!(f, "Path({:?})", path), Data::Path(path) => write!(f, "Path({:?})", path),
Data::ObjectUrl(url) => write!(f, "ObjectUrl({:?})", url), Data::Bytes(_) => write!(f, "Bytes(...)"),
}
}
}
impl Drop for Data {
fn drop(&mut self) {
match self {
Data::ObjectUrl(url) => Url::revoke_object_url(&url).unwrap(),
_ => {}
} }
} }
} }