Skip to main content

pebble/assets/
upload.rs

1use crate::assets::deps::Dependencies;
2
3/// Declares the processed form of a source asset type.
4///
5/// Implement this alongside [`Asset<B>`] for every source type that is
6/// uploaded to a backend. Used as the storage bound for
7/// [`Assets<T>`](crate::assets::storage::Assets) — the struct that holds
8/// both `T` (source) and `T::Processed` (uploaded result) per entry.
9///
10/// Kept separate from `Asset<B>` so that `Assets<T>` does not need to know
11/// the backend type `B`.
12pub trait AssetSource: 'static + Send + Sync {
13    /// The uploaded (GPU/processed) form produced by [`Asset::upload`].
14    type Processed: 'static + Send + Sync;
15}
16
17/// Describes how a source asset of type `Self` is converted into its
18/// processed form [`Self::Processed`](AssetSource::Processed), using a
19/// backend `B`.
20///
21/// `B` is intentionally generic — it is not restricted to GPU backends:
22/// - **CPU → GPU**: `B` is your graphics backend (e.g. a wgpu device).
23/// - **CPU → CPU**: set `B = ()` for pure data transforms.
24/// - **Audio / other**: `B` is your audio device or any other service.
25///
26/// # Associated types
27/// - `Processed` (via [`AssetSource`]) — the result stored alongside the
28///   source in [`Assets<Self>`](crate::assets::storage::Assets).
29/// - `Deps` — zero or more additional resources required during the
30///   conversion (see [`Dependencies`]). Use `()` when there are none.
31///
32/// # Upload lifecycle
33/// [`AssetPlugin`](crate::assets::plugin::AssetPlugin) drains the dirty
34/// queue from `Assets<Self>` each tick and calls [`upload`] for every
35/// pending entry. Returning `None` re-queues the handle for the next tick,
36/// allowing conversions to wait on sub-resources that may not be ready yet.
37pub trait Asset<B>: AssetSource {
38    /// Resources (beyond `B` itself) required to perform the conversion.
39    /// Use `()` when there are no extra dependencies.
40    type Deps<'a>: Dependencies<'a>;
41
42    /// Convert `self` (the source) into its processed form using `backend`
43    /// and `deps`.
44    ///
45    /// Return `None` to defer the conversion to the next tick (e.g. a
46    /// required sub-resource is not yet available).
47    fn upload<'a>(&self, backend: &B, deps: &Self::Deps<'a>) -> Option<Self::Processed>;
48}