mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-27 13:54:11 +00:00

Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.82) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.82) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
105 lines
3.5 KiB
Rust
105 lines
3.5 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
use bevy::asset::io::{AssetReader, AssetSource, AssetSourceId};
|
|
use bevy::prelude::*;
|
|
use slint::SharedString;
|
|
|
|
fn map_err(err: reqwest::Error) -> bevy::asset::io::AssetReaderError {
|
|
match err.status().map(|s| s.as_u16()) {
|
|
Some(404) => bevy::asset::io::AssetReaderError::NotFound(
|
|
err.url().map(|u| u.path()).unwrap_or_default().into(),
|
|
),
|
|
Some(code) => bevy::asset::io::AssetReaderError::HttpError(code),
|
|
_ => bevy::asset::io::AssetReaderError::Io(
|
|
std::io::Error::new(std::io::ErrorKind::Unsupported, "Unknown error").into(),
|
|
),
|
|
}
|
|
}
|
|
|
|
async fn get(
|
|
url: impl reqwest::IntoUrl,
|
|
progress_channel: smol::channel::Sender<(SharedString, f32)>,
|
|
) -> Result<bevy::asset::io::VecReader, bevy::asset::io::AssetReaderError> {
|
|
use smol::stream::StreamExt;
|
|
|
|
let url = url.into_url().unwrap();
|
|
|
|
let response = reqwest::get(url.clone()).await.map_err(map_err)?;
|
|
|
|
let content_length = response.content_length();
|
|
|
|
let mut stream = response.bytes_stream();
|
|
|
|
let mut data = Vec::new();
|
|
|
|
let progress_url_str = SharedString::from(url.as_str());
|
|
|
|
let _ = progress_channel.send((progress_url_str.clone(), 0.)).await.ok();
|
|
|
|
while let Some(chunk) = stream.next().await {
|
|
let chunk_bytes = chunk.map_err(map_err)?;
|
|
data.extend(chunk_bytes);
|
|
let progress_percent = content_length
|
|
.map(|total_length| data.len() as f32 / total_length as f32)
|
|
.unwrap_or_default();
|
|
let _ = progress_channel.send((progress_url_str.clone(), progress_percent)).await.ok();
|
|
}
|
|
|
|
Ok(bevy::asset::io::VecReader::new(data))
|
|
}
|
|
|
|
struct WebAssetLoader(smol::channel::Sender<(SharedString, f32)>);
|
|
|
|
impl AssetReader for WebAssetLoader {
|
|
fn read<'a>(
|
|
&'a self,
|
|
path: &'a std::path::Path,
|
|
) -> impl bevy::asset::io::AssetReaderFuture<Value: bevy::asset::io::Reader + 'a> {
|
|
let url = reqwest::Url::parse(&format!("https://{}", path.to_string_lossy())).unwrap();
|
|
async_compat::Compat::new(get(url, self.0.clone()))
|
|
}
|
|
|
|
fn read_meta<'a>(
|
|
&'a self,
|
|
path: &'a std::path::Path,
|
|
) -> impl bevy::asset::io::AssetReaderFuture<Value: bevy::asset::io::Reader + 'a> {
|
|
std::future::ready(Result::<bevy::asset::io::VecReader, _>::Err(
|
|
bevy::asset::io::AssetReaderError::NotFound(path.into()),
|
|
))
|
|
}
|
|
|
|
fn read_directory<'a>(
|
|
&'a self,
|
|
path: &'a std::path::Path,
|
|
) -> impl bevy::tasks::ConditionalSendFuture<
|
|
Output = std::result::Result<
|
|
Box<bevy::asset::io::PathStream>,
|
|
bevy::asset::io::AssetReaderError,
|
|
>,
|
|
> {
|
|
return std::future::ready(Err(bevy::asset::io::AssetReaderError::NotFound(path.into())));
|
|
}
|
|
|
|
fn is_directory<'a>(
|
|
&'a self,
|
|
_path: &'a std::path::Path,
|
|
) -> impl bevy::tasks::ConditionalSendFuture<
|
|
Output = std::result::Result<bool, bevy::asset::io::AssetReaderError>,
|
|
> {
|
|
std::future::ready(Ok(false))
|
|
}
|
|
}
|
|
|
|
pub struct WebAssetReaderPlugin(pub smol::channel::Sender<(SharedString, f32)>);
|
|
|
|
impl Plugin for WebAssetReaderPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
let progress_channel = self.0.clone();
|
|
app.register_asset_source(
|
|
AssetSourceId::Name("https".into()),
|
|
AssetSource::build()
|
|
.with_reader(move || Box::new(WebAssetLoader(progress_channel.clone()))),
|
|
);
|
|
}
|
|
}
|