diff --git a/editor/src/asset/preview/cache.rs b/editor/src/asset/preview/cache.rs index 15e6ac530..a714fb9b5 100644 --- a/editor/src/asset/preview/cache.rs +++ b/editor/src/asset/preview/cache.rs @@ -25,13 +25,16 @@ use crate::{ }, fyrox::{ asset::untyped::UntypedResource, - core::{futures::executor::block_on, ok_or_continue, pool::Handle, Uuid}, + core::{futures::executor::block_on, parking_lot::Mutex, pool::Handle, Uuid}, engine::Engine, fxhash::FxHashMap, gui::{message::MessageDirection, UiNode}, }, }; -use std::sync::mpsc::Receiver; +use std::{ + collections::VecDeque, + sync::{mpsc::Receiver, Arc}, +}; pub struct IconRequest { pub widget_handle: Handle, @@ -40,75 +43,95 @@ pub struct IconRequest { } pub struct AssetPreviewCache { - receiver: Receiver, container: FxHashMap, throughput: usize, + queue: Arc>>, } impl AssetPreviewCache { pub fn new(receiver: Receiver, throughput: usize) -> Self { + let queue = Arc::new(Mutex::new(VecDeque::new())); + let queue2 = queue.clone(); + std::thread::spawn(move || { + for request in receiver.iter() { + let resource = request.resource.clone(); + if block_on(resource).is_ok() { + queue.lock().push_back(request); + } + } + }); + Self { - receiver, container: Default::default(), throughput, + queue: queue2, } } + fn preview_for( + &mut self, + resource: &UntypedResource, + generators: &mut AssetPreviewGeneratorsCollection, + force_update: bool, + generated_counter: &mut usize, + engine: &mut Engine, + ) -> Option { + let resource_uuid = resource.resource_uuid()?; + + if let (false, Some(cached_preview)) = (force_update, self.container.get(&resource_uuid)) { + return Some(cached_preview.clone()); + } else if let Some(generator) = resource + .type_uuid() + .and_then(|type_uuid| generators.map.get_mut(&type_uuid)) + { + if let Some(preview) = generator.generate_preview(resource, engine) { + *generated_counter += 1; + self.container.insert(resource_uuid, preview.clone()); + return Some(preview); + } else if let Some(icon) = generator.simple_icon(resource, &engine.resource_manager) { + let preview = AssetPreviewTexture { + texture: icon, + flip_y: false, + }; + self.container.insert(resource_uuid, preview.clone()); + return Some(preview); + } + } + + None + } + pub fn update( &mut self, generators: &mut AssetPreviewGeneratorsCollection, engine: &mut Engine, ) { - for request in self.receiver.try_iter().take(self.throughput) { + let mut generated = 0; + let queue = self.queue.clone(); + let mut queue = queue.lock(); + while let Some(request) = queue.pop_back() { let IconRequest { - widget_handle: asset_item, + widget_handle, resource, force_update, } = request; - let resource = ok_or_continue!(block_on(resource)); - - let preview = if let Some(resource_uuid) = resource.resource_uuid() { - if let (false, Some(cached_preview)) = - (force_update, self.container.get(&resource_uuid)) - { - Some(cached_preview.clone()) - } else if let Some(generator) = resource - .type_uuid() - .and_then(|type_uuid| generators.map.get_mut(&type_uuid)) - { - if let Some(preview) = generator.generate_preview(&resource, engine) { - self.container.insert(resource_uuid, preview.clone()); - Some(preview) - } else if let Some(icon) = - generator.simple_icon(&resource, &engine.resource_manager) - { - let preview = AssetPreviewTexture { - texture: icon, - flip_y: false, - }; - self.container.insert(resource_uuid, preview.clone()); - Some(preview) - } else { - None - } - } else { - None - } - } else { - None - }; - - if let Some(preview) = preview { + if let Some(preview) = + self.preview_for(&resource, generators, force_update, &mut generated, engine) + { let ui = engine.user_interfaces.first(); ui.send_message(AssetItemMessage::icon( - asset_item, + widget_handle, MessageDirection::ToWidget, Some(preview.texture), preview.flip_y, )); } + + if generated >= self.throughput { + break; + } } } }