hydrate_loader/
lib.rs

1pub mod artifact_storage;
2mod disk_io;
3pub mod loader;
4pub mod storage;
5
6pub use crate::artifact_storage::{ArtifactStorageSet, DynArtifactLoader};
7use crate::disk_io::DiskArtifactIO;
8use crate::loader::Loader;
9use crossbeam_channel::{Receiver, Sender};
10use hydrate_base::handle::RefOp;
11use hydrate_base::{ArtifactId, StringHash};
12use std::path::PathBuf;
13use type_uuid::TypeUuid;
14
15mod artifact_type_id;
16pub use artifact_type_id::ArtifactTypeId;
17
18use crate::storage::IndirectIdentifier;
19pub use hydrate_base::handle::Handle;
20
21pub fn process_ref_ops(
22    loader: &Loader,
23    rx: &Receiver<RefOp>,
24) {
25    while let Ok(ref_op) = rx.try_recv() {
26        match ref_op {
27            RefOp::Decrease(handle) => loader.remove_engine_ref(handle),
28            RefOp::Increase(handle) => {
29                loader.add_engine_ref_by_handle(handle);
30            }
31        }
32    }
33}
34
35pub struct ArtifactManager {
36    artifact_storage: ArtifactStorageSet,
37    loader: Loader,
38    ref_op_tx: Sender<RefOp>,
39    ref_op_rx: Receiver<RefOp>,
40}
41
42impl ArtifactManager {
43    pub fn new(build_data_root_path: PathBuf) -> Result<Self, String> {
44        let (ref_op_tx, ref_op_rx) = crossbeam_channel::unbounded();
45        let (loader_events_tx, loader_events_rx) = crossbeam_channel::unbounded();
46
47        let artifact_io = DiskArtifactIO::new(build_data_root_path, loader_events_tx.clone())?;
48        let loader = Loader::new(Box::new(artifact_io), loader_events_tx, loader_events_rx);
49        let artifact_storage = ArtifactStorageSet::new(ref_op_tx.clone());
50
51        let mut loader = ArtifactManager {
52            artifact_storage,
53            loader,
54            ref_op_tx,
55            ref_op_rx,
56        };
57
58        loader.update();
59
60        Ok(loader)
61    }
62
63    pub fn loader(&self) -> &Loader {
64        &self.loader
65    }
66
67    pub fn storage(&self) -> &ArtifactStorageSet {
68        &self.artifact_storage
69    }
70
71    pub fn add_storage<T>(&mut self)
72    where
73        T: TypeUuid + for<'a> serde::Deserialize<'a> + 'static + Send,
74    {
75        self.artifact_storage.add_storage::<T>();
76    }
77
78    pub fn add_storage_with_loader<ArtifactDataT, ArtifactT, LoaderT>(
79        &mut self,
80        loader: Box<LoaderT>,
81    ) where
82        ArtifactDataT: TypeUuid + for<'a> serde::Deserialize<'a> + 'static,
83        ArtifactT: TypeUuid + 'static + Send,
84        LoaderT: DynArtifactLoader<ArtifactT> + 'static,
85    {
86        self.artifact_storage
87            .add_storage_with_loader::<ArtifactDataT, ArtifactT, LoaderT>(loader);
88    }
89
90    pub fn load_artifact<T: TypeUuid + 'static + Send>(
91        &self,
92        artifact_id: ArtifactId,
93    ) -> Handle<T> {
94        let data_type_uuid = self
95            .storage()
96            .artifact_to_data_type_uuid::<T>()
97            .expect("Called load_artifact with unregistered asset type");
98        let load_handle = self
99            .loader
100            .add_engine_ref_indirect(IndirectIdentifier::ArtifactId(artifact_id, data_type_uuid));
101        Handle::<T>::new(self.ref_op_tx.clone(), load_handle)
102    }
103
104    pub fn load_artifact_symbol_name<T: TypeUuid + 'static + Send>(
105        &self,
106        symbol_name: &'static str,
107    ) -> Handle<T> {
108        self.load_artifact_symbol_string_hash(StringHash::from_static_str(symbol_name))
109    }
110
111    pub fn load_artifact_symbol_string_hash<T: TypeUuid + 'static + Send>(
112        &self,
113        symbol: StringHash,
114    ) -> Handle<T> {
115        let data_type_uuid = self
116            .storage()
117            .artifact_to_data_type_uuid::<T>()
118            .expect("Called load_artifact with unregistered asset type");
119
120        let load_handle = self
121            .loader
122            .add_engine_ref_indirect(IndirectIdentifier::SymbolWithType(symbol, data_type_uuid));
123        Handle::<T>::new(self.ref_op_tx.clone(), load_handle)
124    }
125
126    pub fn update(&mut self) {
127        process_ref_ops(&self.loader, &self.ref_op_rx);
128        self.loader.update(&mut self.artifact_storage);
129    }
130}