Crate assets_manager
source ·Expand description
Conveniently load, store and cache external resources.
This crate aims at providing a filesystem abstraction to easily load external resources. It was originally thought for games, but can, of course, be used in other contexts.
The structure AssetCache is the entry point of the crate.
§Cargo features
hot-reloading: Add hot-reloading.macros: Add support for derivingAssettrait.
§Additional sources
These features enable to read assets from other sources than the file
system. They are defined in the source module.
embedded: Embed assets files directly in your binary.zip: Read asset from zip archives. Note that no decompression method is enabled by default, but you can do so with the following features:zip-bzip2: Enablebzip2decompression.zip-deflate: Enableflate2decompression.
tar: Read assets from TAR archives.
§Additional formats
These features add support for asset formats. There is one feature per format.
- Serialisation formats (with
serdecrate):bincode,json,msgpack,ron,toml,yaml. - Image formats (with
imagecrate):bmp,jpeg,pngwebp. - 3D formats (with
gltfcrate):gltf.
§External crates support
Support of some other crates is done in external crates:
§Internal features
These features change inner data structures implementations.
parking_lot: Useparking_lot’s synchronization primitives.ahash: Use a faster hashing algorithm (enabled by default).
§Basic example
If the file assets/common/position.ron contains this:
Point(
x: 5,
y: -6,
)
Then you can load it this way (with feature ron enabled):
use assets_manager::{Asset, AssetCache, loader};
use serde::Deserialize;
// The struct you want to load
#[derive(Deserialize)]
struct Point {
x: i32,
y: i32,
}
// Specify how you want the structure to be loaded
impl Asset for Point {
// The extension of the files to look into
const EXTENSION: &'static str = "ron";
// The serialization format
type Loader = loader::RonLoader;
}
// Create a new cache to load assets under the "./assets" folder
let cache = AssetCache::new("assets")?;
// Get a handle on the asset
// This will load the file `./assets/common/position.ron`
let handle = cache.load::<Point>("common.position")?;
// Lock the asset for reading
// Any number of read locks can exist at the same time,
// but none can exist when the asset is reloaded
let point = handle.read();
// The asset is now ready to be used
assert_eq!(point.x, 5);
assert_eq!(point.y, -6);
// Loading the same asset retreives it from the cache
let other_handle = cache.load("common.position")?;
assert!(std::ptr::eq(handle, other_handle));§Hot-reloading
Hot-reloading is a major feature of assets_manager: when a file is added,
modified or deleted, the values of all loaded assets that depend on this
file are automatically and transparently updated.
To use hot-reloading, see AssetCache::hot_reload.
See the asset module for a precise description of how assets interact
with hot-reloading.
§Ownership model
You will notice that you cannot get owned Handles, only references whose
lifetime are tied to that of the AssetCache from which there was loaded.
This may be seen as a weakness, as 'static data is generally easier to
work with, but it is actually a clever use of Rust ownership system.
As when you borrow an &str from a String, an &Handle guarantees
that the underlying asset is stored in the cache. This is especially useful
with hot-reloading: all &Handle are guaranteed to be reloaded when
possible, so two handles on the same asset always have the same value. This
would not be possible if Handles were always 'static.
Note that this also means that you need a mutable reference to a cache to remove assets from it.
§Getting owned data
Working with owned data is far easier: you don’t have to care about lifetimes, it can easily be sent to other threads, etc. This section gives a few techniques to work with the fact that caches give references to their assets.
Note that none of these proposals is compulsory to use this crate: you can
work with non-'static data, or invent your own techniques.
§Getting a &'static AssetCache
Because the lifetime of a Handle reference is tied to that of the &AssetCache,
this makes possible to get &'static Handles. Moreover, it enables you to
call AssetCache::enhance_hot_reloading, which is easier to work with
than the default solution.
You get easily get a &'static AssetCache, with the once_cell crate or
std::sync::OnceLock, but you can also do it by leaking a Box.
Note that using this technique prevents you from removing assets from the cache, so you have to keep them in memory for the duration of the program. This also creates global state, which you might want to avoid.
§Cloning assets
Assets being 'static themselves, cloning them is a good way to opt out of
the lifetime of the cache. If cloning the asset itself is too expensive, you
can take advantage of the fact that Arc<T> is an asset if T is too and
that cloning an Arc is a rather cheap operation.
Not that this usually does not work wery well with hot-reloading.
§Storing Strings
Strings are 'static and easy to work with, and you can use them to load
an asset from the cache, which is a cheap operation if the asset is already
stored in it. If you want to ensure that no heavy operation is used, you
can do so with AssetCache::get_cached.
If you have to clone them a lot, you may consider changing your String
into an Arc<str> or a SharedString which is cheaper to clone.
This is the technique internally used by assets_manager to store
directories.
Re-exports§
Modules§
- Values loadable from a cache.
- Tools to implement hot-reloading.
- Generic asset loading definition
- Bytes sources to load assets from.
Structs§
- A non-generic version of
AssetCache. - The main structure of this crate, used to cache assets.
- RAII guard used to keep a read lock on an asset and release it when dropped.
- A
ReloadIdthat can be shared between threads. - Stores ids in a directory containing assets of type
T - The error type which is used when loading an asset.
- A handle on an asset.
- Single-threaded version of
AssetCache. - Once
Init Cell utilsA thread-safe cell which can be written to only once. - Stores ids in a recursive directory containing assets of type
T - An id to know when an asset is reloaded.
- A watcher that can tell when an asset is reloaded.
- Bytes that can easily be shared.
- A string that can easily be shared.
- A untyped handle on an asset.
Traits§
- Used to get an
AnyCachefrom a type.
Type Aliases§
- A boxed error