summaryrefslogtreecommitdiff
path: root/engine/src/asset.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/asset.rs')
-rw-r--r--engine/src/asset.rs168
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,
}