OGNLZ5CUNFD7X43S4VTMCCEMJA2R76O35XACIR7AUBHPGME27E3AC EEO6C4YSWFW3JOZ3JH6K7X4TKAUTVJD53CQNYZHI2QY6REGEXUCAC L6RIUKGLJZLAOKFGUDTZKBPP4HUBPEZAKHJEQHO34WFF62AB2ZIQC X5EMQBC4BFNJOOHS2QMF4UB4QH6JKSALK6RXLK6B7SP6MNYSAP6QC O5P6HCPWGMGJBFJEMC3SYQJ5OEW2AQV4KEJCMRVTTS3K6M45Z3BAC GHIHJCWBCGFZI4AG66L7WG4WKJ467DXFBRBNLT4ZULSN7ZVBJI6AC PAOLWMH7TLJLNAWBJBWP7KB7YGDFUPASMTFU33KZ3QW5JXJMPXCAC HTDZ53HWD4X3DSFZX7MMC7DPFJNHQPGBVLJD2S325SQRRVIQ3CLAC GROTV3H2V6BHU5CA7WSLVYDCWAR7GHUP5JV2QOGPLJ6N3553T4MAC FPNW5ZHTGO2UDPGVOKZYX2BYZRMKAB3NEAFVSIXRVYNSWCUPBWFQC 6YVIIRYC6FQP7ET7AMJHG4XCIDI4KIJMOKUDAUMVBLYFEULRDQEAC BYFMGWJ5ZPXZTCIFDHP66KK7JTEKT2NO7HR2XY7T5WRAAG3L5WYQC DKGUNP6LG3DJ35VMHU42K3VJO5JJ5UVYI4PLM72HO5ZNAQ4P366AC NS7EOR3SRISITX6SBHBOJIYTINDN2ZBL2QY64H6FNJJ3I2I3PYGQC pub async fn new<S: assets_manager::source::Source>(window: Window,assets: &AssetCache<S>,) -> color_eyre::Result<Self> {let size = {let actual_size = window.inner_size();if actual_size.width == 0 || actual_size.height == 0 {// Assume we are actually in-built height and notifylet assumed_size = PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT);window.set_min_inner_size(Some(assumed_size));assumed_size} else {// It's fineactual_size}};let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {backends: wgpu::Backends::all(),..Default::default()});
async fn acknoledge_surface(&mut self,surface: &wgpu::Surface<'static>,) -> color_eyre::Result<()> {if self.adapter_state.as_ref().is_some_and(|ads| ads.adapter.is_surface_supported(surface)){// Conserve work: we've already made a perfectly good adapter that supports the surface we want to draw toreturn Ok(());}
let surface_caps = surface.get_capabilities(&adapter);
pub async fn create_surface<S: assets_manager::source::Source>(&mut self,assets: &AssetCache<S>,) -> color_eyre::Result<()> {let surface = self.instance.create_surface(self.window.clone())?;self.acknoledge_surface(&surface).await?;let Some(adapter_state) = self.adapter_state.as_ref() else {unreachable!("adapter_state should have been created by `Screen::acknowledge_surface`");};let surface_caps = surface.get_capabilities(&adapter_state.adapter);
let world_atlas = glyphon::TextAtlas::new(&device, &queue, world_texture_format);let camera_atlas = glyphon::TextAtlas::new(&device, &queue, surface_format);let world_renderer =middleware::WorldRenderer::new(&device, config.format, world_texture_format, assets)?;
let world_atlas = glyphon::TextAtlas::new(&adapter_state.device,&adapter_state.queue,world_texture_format,);let camera_atlas =glyphon::TextAtlas::new(&adapter_state.device, &adapter_state.queue, surface_format);let world_renderer = middleware::WorldRenderer::new(&adapter_state.device,config.format,world_texture_format,assets,)?;
world_renderer,});Ok(())}pub async fn new(window: Window) -> color_eyre::Result<Self> {let size = {let actual_size = window.inner_size();if actual_size.width == 0 || actual_size.height == 0 {// Assume we are actually in-built height and notifylet assumed_size = PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT);window.set_min_inner_size(Some(assumed_size));assumed_size} else {// It's fineactual_size}};let window = Arc::new(window);let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {backends: wgpu::Backends::all(),..Default::default()});let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {power_preference: wgpu::PowerPreference::default(),compatible_surface: None,force_fallback_adapter: false,}).await;let adapter_state = if let Some(adapter) = adapter {let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {required_features: wgpu::Features::empty(), //wgpu::Features::all_webgpu_mask(),required_limits: if cfg!(target_arch = "wasm32") {if cfg!(feature = "webgpu") {wgpu::Limits::downlevel_defaults()} else if cfg!(feature = "webgl") {wgpu::Limits::downlevel_webgl2_defaults()} else {unreachable!("for `web` feature, you must also enable a backend feature: `webgpu`, `webgl`")}} else {wgpu::Limits::default()},label: None,},None,).await?;Some(AdapterState {adapter,device,queue,})} else {None};Ok(Self {instance,size,window,adapter_state,surface_state: None,
self.size = new_size;self.config.width = new_size.width;self.config.height = new_size.height;self.surface.configure(&self.device, &self.config);
if let Some((surface_state, adapter_state)) =self.surface_state.as_mut().zip(self.adapter_state.as_ref()){self.size = new_size;surface_state.config.width = new_size.width;surface_state.config.height = new_size.height;surface_state.surface.configure(&adapter_state.device, &surface_state.config);}
match self.config.present_mode {wgpu::PresentMode::AutoVsync => true,wgpu::PresentMode::AutoNoVsync => false,_ => unreachable!(),
if let Some(state) = self.surface_state.as_ref() {match state.config.present_mode {wgpu::PresentMode::AutoVsync => true,wgpu::PresentMode::AutoNoVsync => false,_ => unreachable!(),}} else {false
let pm = if vsync {wgpu::PresentMode::AutoVsync} else {wgpu::PresentMode::AutoNoVsync};self.config.present_mode = pm;self.surface.configure(&self.device, &self.config);
if let Some((surface_state, adapter_state)) =self.surface_state.as_mut().zip(self.adapter_state.as_ref()){let pm = if vsync {wgpu::PresentMode::AutoVsync} else {wgpu::PresentMode::AutoNoVsync};surface_state.config.present_mode = pm;surface_state.surface.configure(&adapter_state.device, &surface_state.config);}
let output = self.surface.get_current_texture()?;
let Some((surface_state, adapter_state)) =self.surface_state.as_mut().zip(self.adapter_state.as_ref())else {// Return early, as surface has not been initializedreturn Ok(());};let output = surface_state.surface.get_current_texture()?;
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {label: Some("Render Encoder"),});
let mut encoder =adapter_state.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {label: Some("Render Encoder"),});
}// Poor man's executor for winit's poor man's asynctype TaskId = usize;struct PollTask(TaskId);struct WinitExecutor<E> {// a better implementation should use a vec of options here.tasks: HashMap<TaskId, Pin<Box<dyn Future<Output = Result<(), E>>>>>,event_loop_proxy: EventLoopProxy<PollTask>,
impl<E> WinitExecutor<E> {/// Create a new `WinitExecutor`, driven by the given event loop.pub fn new(event_loop_proxy: EventLoopProxy<PollTask>) -> Self {Self {tasks: HashMap::new(),event_loop_proxy,}}fn next_task_id(&self) -> TaskId {static NEXT_TASK_ID: std::sync::atomic::AtomicUsize =std::sync::atomic::AtomicUsize::new(0);NEXT_TASK_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed)}/// Spawn a task.////// This immediately pools the task once, and then schedules it to be/// polled again if needed, using a `UserEvent::PollTask` event.pub fn spawn(&mut self, task: impl Future<Output = Result<(), E>> + 'static) {let task = Box::pin(task);let task_id = self.next_task_id();self.tasks.insert(task_id, task);self.poll(task_id);}
/// Poll a task.////// Should be called when the event loop receives a `UserEvent::PollTask`.pub fn poll(&mut self, task_id: TaskId) -> Option<Result<(), E>> {// this wake only need to work once, I believe, so we could use some type of "oneshot box"// instead of a mutex?let winit_proxy = Mutex::new(self.event_loop_proxy.clone());let waker = waker_fn::waker_fn(move || {let _ = winit_proxy.lock().unwrap().send_event(PollTask(task_id));});let task = self.tasks.get_mut(&task_id).unwrap().as_mut();match task.poll(&mut Context::from_waker(&waker)) {Poll::Ready(res) => {_ = self.tasks.remove(&task_id);Some(res)}Poll::Pending => None,}}}
Event::Resumed => {// Actually create the surface (and panic if we fail...)winit_executor.spawn({let game = game.clone();async move { game.lock().unwrap().create_surface().await }});}Event::UserEvent(PollTask(tid)) => {if let Some(res) = winit_executor.poll(tid) {// the stuff here shouldn't failres.unwrap();}}
desktop = ["egui-winit/clipboard", "egui-winit/links", "egui-winit/wayland","egui-winit/x11", "wgpu/dx12", "wgpu/metal", "wgpu/webgpu", "wgpu/wgsl","tracing-subscriber/env-filter", "dep:pollster"]
desktop = ["egui-winit/default", "wgpu/default", "tracing-subscriber/env-filter", "dep:pollster"]
name = "loom"version = "0.5.6"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"dependencies = ["cfg-if","generator","pin-utils","scoped-tls","tracing","tracing-subscriber",][[package]]