diff options
| author | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
| commit | f285f82072b491b1f3cc92db8e08485f26779d5a (patch) | |
| tree | bf6c6c61cdfb3a12550e55966c8552957ade9e71 /engine/src/asset.rs | |
| parent | 0546d575c11d3668d0f95933697ae4f670fe2a55 (diff) | |
Diffstat (limited to 'engine/src/asset.rs')
| -rw-r--r-- | engine/src/asset.rs | 168 |
1 files changed, 149 insertions, 19 deletions
diff --git a/engine/src/asset.rs b/engine/src/asset.rs index e78b6d8..b089b73 100644 --- a/engine/src/asset.rs +++ b/engine/src/asset.rs @@ -15,12 +15,24 @@ use std::sync::mpsc::{ channel as mpsc_channel, }; -use ecs::Sole; -use ecs::phase::PRE_UPDATE as PRE_UPDATE_PHASE; +use ecs::pair::{ChildOf, Pair}; +use ecs::phase::{PRE_UPDATE as PRE_UPDATE_PHASE, Phase}; use ecs::sole::Single; +use ecs::{Sole, declare_entity}; use crate::work_queue::{Work, WorkQueue}; +declare_entity!( + pub HANDLE_ASSETS_PHASE, + ( + Phase, + Pair::builder() + .relation::<ChildOf>() + .target_id(*PRE_UPDATE_PHASE) + .build() + ) +); + /// Asset label. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Label<'a> @@ -125,6 +137,7 @@ pub struct Assets import_work_queue: WorkQueue<ImportWorkUserData>, import_work_msg_receiver: MpscReceiver<ImportWorkMessage>, import_work_msg_sender: MpscSender<ImportWorkMessage>, + events: Events, } impl Assets @@ -142,6 +155,7 @@ impl Assets import_work_queue: WorkQueue::new(), import_work_msg_receiver, import_work_msg_sender, + events: Events::default(), } } @@ -173,13 +187,15 @@ impl Assets where 'this: 'handle, { - let LookupEntry::Occupied(asset_index) = - *self.asset_lookup.borrow().get(&handle.id.label_hash)? + let asset_lookup = self.asset_lookup.borrow(); + + let LookupEntry::Occupied(asset_index, _) = + asset_lookup.get(&handle.id.label_hash)? else { return None; }; - let stored_asset = self.assets.get(asset_index).expect("Not possible"); + let stored_asset = self.assets.get(*asset_index).expect("Not possible"); let Some(asset) = stored_asset.strong.downcast_ref::<Asset>() else { tracing::error!("Wrong asset type"); @@ -189,6 +205,68 @@ impl Assets Some(asset) } + #[tracing::instrument(skip_all, fields(asset_type=type_name::<Asset>()))] + pub fn get_handle_to_loaded<'label, Asset: 'static + Send + Sync>( + &self, + label: impl Into<Label<'label>>, + ) -> Option<Handle<Asset>> + { + let label = label.into(); + + let label_hash = LabelHash::new(&label); + + let asset_lookup = self.asset_lookup.borrow(); + + let LookupEntry::Occupied(asset_index, _) = asset_lookup.get(&label_hash)? else { + return None; + }; + + let stored_asset = self.assets.get(*asset_index).expect("Not possible"); + + if stored_asset.strong.downcast_ref::<Asset>().is_none() { + tracing::error!("Wrong asset type"); + return None; + }; + + Some(Handle::new(label_hash)) + } + + pub fn is_loaded_and_has_type<Asset: 'static + Send + Sync>( + &self, + handle: &Handle<Asset>, + ) -> bool + { + let asset_lookup = self.asset_lookup.borrow(); + + let Some(LookupEntry::Occupied(asset_index, _)) = + asset_lookup.get(&handle.id.label_hash) + else { + return false; + }; + + let stored_asset = self.assets.get(*asset_index).expect("Not possible"); + + stored_asset.strong.downcast_ref::<Asset>().is_some() + } + + pub fn get_label<Asset: 'static + Send + Sync>( + &self, + handle: &Handle<Asset>, + ) -> Option<LabelOwned> + { + let lookup_entry = self + .asset_lookup + .borrow() + .get(&handle.id.label_hash)? + .clone(); + + let LookupEntry::Occupied(_, label) = lookup_entry else { + return None; + }; + + Some(label) + } + #[tracing::instrument(skip(self))] pub fn load<'i, Asset: 'static + Send + Sync>( &self, @@ -216,9 +294,9 @@ impl Assets return Handle::new(label_hash); }; - match *lookup_entry { - LookupEntry::Occupied(asset_index) => { - let stored_asset = self.assets.get(asset_index).expect("Not possible"); + match lookup_entry { + LookupEntry::Occupied(asset_index, _) => { + let stored_asset = self.assets.get(*asset_index).expect("Not possible"); if stored_asset.strong.downcast_ref::<Asset>().is_none() { tracing::error!("Wrong asset type {}", type_name::<Asset>()); @@ -261,9 +339,9 @@ impl Assets return Handle::new(label_hash); }; - match *lookup_entry { - LookupEntry::Occupied(asset_index) => { - let stored_asset = self.assets.get(asset_index).expect("Not possible"); + match lookup_entry { + LookupEntry::Occupied(asset_index, _) => { + let stored_asset = self.assets.get(*asset_index).expect("Not possible"); if stored_asset.strong.downcast_ref::<Asset>().is_none() { tracing::error!( @@ -323,7 +401,7 @@ impl Assets if matches!( self.asset_lookup.get_mut().get(&label_hash), - Some(LookupEntry::Occupied(_)) + Some(LookupEntry::Occupied(_, _)) ) { tracing::error!("Asset already exists"); @@ -338,11 +416,15 @@ impl Assets self.asset_lookup .get_mut() - .insert(label_hash, LookupEntry::Occupied(index)); + .insert(label_hash, LookupEntry::Occupied(index, label.to_owned())); if label.name.is_some() { - let parent_asset_label_hash = - LabelHash::new(&Label { path: label.path, name: None }); + let parent_asset_label = Label { + path: label.path.as_ref().into(), + name: None, + }; + + let parent_asset_label_hash = LabelHash::new(&parent_asset_label); if matches!( self.asset_lookup.get_mut().get(&parent_asset_label_hash), @@ -360,14 +442,26 @@ impl Assets self.asset_lookup.get_mut().insert( parent_asset_label_hash, - LookupEntry::Occupied(self.assets.len() - 1), + LookupEntry::Occupied( + self.assets.len() - 1, + parent_asset_label.to_owned(), + ), ); } } + self.events + .curr_tick_events + .push(Event::Stored(Id { label_hash }, label.to_owned())); + Handle::new(label_hash) } + pub fn events(&self) -> &Events + { + &self.events + } + fn is_pending(asset_lookup: &HashMap<LabelHash, LookupEntry>, label: &Label) -> bool { if label.name.is_some() { @@ -587,6 +681,11 @@ pub struct Handle<Asset: 'static> impl<Asset: 'static> Handle<Asset> { + pub fn from_id(id: Id) -> Self + { + Self { id, _pd: PhantomData } + } + pub fn id(&self) -> Id { self.id @@ -616,6 +715,29 @@ pub struct Id label_hash: LabelHash, } +#[derive(Debug, Default)] +pub struct Events +{ + curr_tick_events: Vec<Event>, + last_tick_events: Vec<Event>, +} + +impl Events +{ + pub fn last_tick_events(&self) -> impl Iterator<Item = &Event> + { + self.last_tick_events.iter() + } +} + +/// Asset event. +#[derive(Debug)] +pub enum Event +{ + /// Asset stored. + Stored(Id, LabelOwned), +} + #[derive(Debug, thiserror::Error)] enum ImporterError { @@ -718,12 +840,20 @@ impl ecs::extension::Extension for Extension { let _ = collector.add_sole(self.assets); - collector.add_system(*PRE_UPDATE_PHASE, add_received_assets); + collector.add_declared_entity(&HANDLE_ASSETS_PHASE); + + collector.add_system(*HANDLE_ASSETS_PHASE, add_received_assets); } } fn add_received_assets(mut assets: Single<Assets>) { + let Events { curr_tick_events, last_tick_events } = &mut assets.events; + + std::mem::swap(last_tick_events, curr_tick_events); + + curr_tick_events.clear(); + while let Some(import_work_msg) = assets.import_work_msg_receiver.try_recv().ok() { match import_work_msg { ImportWorkMessage::Store { do_store, label, asset } => { @@ -770,10 +900,10 @@ enum ImportWorkMessage }, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] enum LookupEntry { - Occupied(usize), + Occupied(usize, LabelOwned), Pending, } |
