Struct bevy::asset::LoadContext

pub struct LoadContext<'a> { /* private fields */ }
Expand description

A context that provides access to assets in AssetLoaders, tracks dependencies, and collects asset load state. Any asset state accessed by LoadContext will be tracked and stored for use in dependency events and asset preprocessing.

Implementations§

§

impl<'a> LoadContext<'a>

pub fn begin_labeled_asset(&self) -> LoadContext<'_>

Begins a new labeled asset load. Use the returned LoadContext to load dependencies for the new asset and call LoadContext::finish to finalize the asset load. When finished, make sure you call LoadContext::add_labeled_asset to add the results back to the parent context. Prefer LoadContext::labeled_asset_scope when possible, which will automatically add the labeled LoadContext back to the parent context. LoadContext::begin_labeled_asset exists largely to enable parallel asset loading.

See AssetPath for more on labeled assets.

let mut handles = Vec::new();
for i in 0..2 {
    let mut labeled = load_context.begin_labeled_asset();
    handles.push(std::thread::spawn(move || {
        (i.to_string(), labeled.finish(Image::default(), None))
    }));
}
for handle in handles {
    let (label, loaded_asset) = handle.join().unwrap();
    load_context.add_loaded_labeled_asset(label, loaded_asset);
}

pub fn labeled_asset_scope<A>( &mut self, label: String, load: impl FnOnce(&mut LoadContext<'_>) -> A ) -> Handle<A>
where A: Asset,

Creates a new LoadContext for the given label. The load function is responsible for loading an Asset of type A. load will be called immediately and the result will be used to finalize the LoadContext, resulting in a new LoadedAsset, which is registered under the label label.

This exists to remove the need to manually call LoadContext::begin_labeled_asset and then manually register the result with LoadContext::add_labeled_asset.

See AssetPath for more on labeled assets.

pub fn add_labeled_asset<A>(&mut self, label: String, asset: A) -> Handle<A>
where A: Asset,

This will add the given asset as a “labeled Asset” with the label label.

§Warning

This will not assign dependencies to the given asset. If adding an asset with dependencies generated from calls such as LoadContext::load, use LoadContext::labeled_asset_scope or LoadContext::begin_labeled_asset to generate a new LoadContext to track the dependencies for the labeled asset.

See AssetPath for more on labeled assets.

pub fn add_loaded_labeled_asset<A>( &mut self, label: impl Into<CowArc<'static, str>>, loaded_asset: LoadedAsset<A> ) -> Handle<A>
where A: Asset,

Add a LoadedAsset that is a “labeled sub asset” of the root path of this load context. This can be used in combination with LoadContext::begin_labeled_asset to parallelize sub asset loading.

See AssetPath for more on labeled assets.

pub fn has_labeled_asset<'b>(&self, label: impl Into<CowArc<'b, str>>) -> bool

Returns true if an asset with the label label exists in this context.

See AssetPath for more on labeled assets.

pub fn finish<A>( self, value: A, meta: Option<Box<dyn AssetMetaDyn>> ) -> LoadedAsset<A>
where A: Asset,

“Finishes” this context by populating the final Asset value (and the erased AssetMeta value, if it exists). The relevant asset metadata collected in this context will be stored in the returned LoadedAsset.

pub fn path(&self) -> &Path

Gets the source path for this load context.

Examples found in repository?
examples/asset/asset_decompression.rs (line 49)
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    async fn load<'a>(
        &'a self,
        reader: &'a mut Reader<'_>,
        _settings: &'a (),
        load_context: &'a mut LoadContext<'_>,
    ) -> Result<Self::Asset, Self::Error> {
        let compressed_path = load_context.path();
        let file_name = compressed_path
            .file_name()
            .ok_or(GzAssetLoaderError::IndeterminateFilePath)?
            .to_string_lossy();
        let uncompressed_file_name = file_name
            .strip_suffix(".gz")
            .ok_or(GzAssetLoaderError::IndeterminateFilePath)?;
        let contained_path = compressed_path.join(uncompressed_file_name);

        let mut bytes_compressed = Vec::new();

        reader.read_to_end(&mut bytes_compressed).await?;

        let mut decoder = GzDecoder::new(bytes_compressed.as_slice());

        let mut bytes_uncompressed = Vec::new();

        decoder.read_to_end(&mut bytes_uncompressed)?;

        // Now that we have decompressed the asset, let's pass it back to the
        // context to continue loading

        let mut reader = VecReader::new(bytes_uncompressed);

        let uncompressed = load_context
            .loader()
            .direct()
            .with_reader(&mut reader)
            .untyped()
            .load(contained_path)
            .await?;

        Ok(GzAsset { uncompressed })
    }

pub fn asset_path(&self) -> &AssetPath<'static>

Gets the source asset path for this load context.

pub async fn read_asset_bytes<'b, 'c>( &'b mut self, path: impl Into<AssetPath<'c>> ) -> Result<Vec<u8>, ReadAssetBytesError>

Reads the asset at the given path and returns its bytes

pub fn get_label_handle<'b, A>( &mut self, label: impl Into<CowArc<'b, str>> ) -> Handle<A>
where A: Asset,

Returns a handle to an asset of type A with the label label. This LoadContext must produce an asset of the given type and the given label or the dependencies of this asset will never be considered “fully loaded”. However you can call this method before or after adding the labeled asset.

pub fn loader(&mut self) -> NestedLoader<'a, '_>

Create a builder for loading nested assets in this context.

Examples found in repository?
examples/asset/processing/asset_processing.rs (line 150)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    async fn load<'a>(
        &'a self,
        reader: &'a mut Reader<'_>,
        _settings: &'a Self::Settings,
        load_context: &'a mut LoadContext<'_>,
    ) -> Result<CoolText, Self::Error> {
        let mut bytes = Vec::new();
        reader.read_to_end(&mut bytes).await?;
        let ron: CoolTextRon = ron::de::from_bytes(&bytes)?;
        let mut base_text = ron.text;
        for embedded in ron.embedded_dependencies {
            let loaded = load_context
                .loader()
                .direct()
                .load::<Text>(&embedded)
                .await?;
            base_text.push_str(&loaded.get().0);
        }
        for (path, settings_override) in ron.dependencies_with_settings {
            let loaded = load_context
                .loader()
                .with_settings(move |settings| {
                    *settings = settings_override.clone();
                })
                .direct()
                .load::<Text>(&path)
                .await?;
            base_text.push_str(&loaded.get().0);
        }
        Ok(CoolText {
            text: base_text,
            dependencies: ron
                .dependencies
                .iter()
                .map(|p| load_context.load(p))
                .collect(),
        })
    }
More examples
Hide additional examples
examples/asset/asset_decompression.rs (line 75)
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    async fn load<'a>(
        &'a self,
        reader: &'a mut Reader<'_>,
        _settings: &'a (),
        load_context: &'a mut LoadContext<'_>,
    ) -> Result<Self::Asset, Self::Error> {
        let compressed_path = load_context.path();
        let file_name = compressed_path
            .file_name()
            .ok_or(GzAssetLoaderError::IndeterminateFilePath)?
            .to_string_lossy();
        let uncompressed_file_name = file_name
            .strip_suffix(".gz")
            .ok_or(GzAssetLoaderError::IndeterminateFilePath)?;
        let contained_path = compressed_path.join(uncompressed_file_name);

        let mut bytes_compressed = Vec::new();

        reader.read_to_end(&mut bytes_compressed).await?;

        let mut decoder = GzDecoder::new(bytes_compressed.as_slice());

        let mut bytes_uncompressed = Vec::new();

        decoder.read_to_end(&mut bytes_uncompressed)?;

        // Now that we have decompressed the asset, let's pass it back to the
        // context to continue loading

        let mut reader = VecReader::new(bytes_uncompressed);

        let uncompressed = load_context
            .loader()
            .direct()
            .with_reader(&mut reader)
            .untyped()
            .load(contained_path)
            .await?;

        Ok(GzAsset { uncompressed })
    }

pub fn load<'b, A>(&mut self, path: impl Into<AssetPath<'b>>) -> Handle<A>
where A: Asset,

Retrieves a handle for the asset at the given path and adds that path as a dependency of the asset. If the current context is a normal AssetServer::load, an actual asset load will be kicked off immediately, which ensures the load happens as soon as possible. “Normal loads” kicked from within a normal Bevy App will generally configure the context to kick off loads immediately. If the current context is configured to not load dependencies automatically (ex: AssetProcessor), a load will not be kicked off automatically. It is then the calling context’s responsibility to begin a load if necessary.

If you need to override asset settings, asset type, or load directly, please see LoadContext::loader.

Examples found in repository?
examples/asset/processing/asset_processing.rs (line 172)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    async fn load<'a>(
        &'a self,
        reader: &'a mut Reader<'_>,
        _settings: &'a Self::Settings,
        load_context: &'a mut LoadContext<'_>,
    ) -> Result<CoolText, Self::Error> {
        let mut bytes = Vec::new();
        reader.read_to_end(&mut bytes).await?;
        let ron: CoolTextRon = ron::de::from_bytes(&bytes)?;
        let mut base_text = ron.text;
        for embedded in ron.embedded_dependencies {
            let loaded = load_context
                .loader()
                .direct()
                .load::<Text>(&embedded)
                .await?;
            base_text.push_str(&loaded.get().0);
        }
        for (path, settings_override) in ron.dependencies_with_settings {
            let loaded = load_context
                .loader()
                .with_settings(move |settings| {
                    *settings = settings_override.clone();
                })
                .direct()
                .load::<Text>(&path)
                .await?;
            base_text.push_str(&loaded.get().0);
        }
        Ok(CoolText {
            text: base_text,
            dependencies: ron
                .dependencies
                .iter()
                .map(|p| load_context.load(p))
                .collect(),
        })
    }

Auto Trait Implementations§

§

impl<'a> Freeze for LoadContext<'a>

§

impl<'a> !RefUnwindSafe for LoadContext<'a>

§

impl<'a> Send for LoadContext<'a>

§

impl<'a> Sync for LoadContext<'a>

§

impl<'a> Unpin for LoadContext<'a>

§

impl<'a> !UnwindSafe for LoadContext<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<T> ConditionalSend for T
where T: Send,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Settings for T
where T: 'static + Send + Sync,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,