From 22aa9abb139f21bf35b8b0bdb6beee929f75c139 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Thu, 5 Sep 2024 09:42:23 -0400 Subject: [PATCH] Clarify relationships between saving, loading, reading and writing --- crates/bevy_asset/src/io/mod.rs | 10 ++++++++-- crates/bevy_asset/src/lib.rs | 25 +++++++++++++++++++++++++ crates/bevy_asset/src/loader.rs | 5 +++++ crates/bevy_asset/src/saver.rs | 5 +++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/crates/bevy_asset/src/io/mod.rs b/crates/bevy_asset/src/io/mod.rs index dbe559d5f2..9814fc19df 100644 --- a/crates/bevy_asset/src/io/mod.rs +++ b/crates/bevy_asset/src/io/mod.rs @@ -130,7 +130,10 @@ where /// API, where asset bytes and asset metadata bytes are both stored and accessible for a given /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetReader`] instead. /// -/// Also see [`AssetWriter`]. +/// This trait defines asset-agnostic mechanisms to interact with a storage system. +/// For the per-asset-type saving/loading logic, see [`AssetSaver`](crate::saver::AssetSaver) and [`AssetLoader`](crate::loader::AssetLoader). +/// +/// For a mirrored version of this trait that can write assets to storage, see [`AssetWriter`]. pub trait AssetReader: Send + Sync + 'static { /// Returns a future to load the full file data at the provided path. /// @@ -261,7 +264,10 @@ pub enum AssetWriterError { /// API, where asset bytes and asset metadata bytes are both stored and accessible for a given /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetWriter`] instead. /// -/// Also see [`AssetReader`]. +/// This trait defines asset-agnostic mechanisms to interact with a storage system. +/// For the per-asset-type saving/loading logic, see [`AssetSaver`](crate::saver::AssetSaver) and [`AssetLoader`](crate::loader::AssetLoader). +/// +/// For a mirrored version of this trait that can read assets from storage, see [`AssetReader`]. pub trait AssetWriter: Send + Sync + 'static { /// Writes the full asset bytes at the provided path. fn write<'a>( diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 8c4a218e0c..c547f627c3 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -44,6 +44,31 @@ //! This is because the assets were removed from memory while they were still in use. //! You were probably too aggressive with the use of weak handles: think through the lifetime of your assets carefully! //! As soon as an asset is loaded, you must ensure that at least one strong handle is held to it until all matching entities are out of sight of the player. +//! +//! # Custom asset types +//! +//! While Bevy comes with implementations for a large number of common game-oriented asset types (often behind off-by-default feature flags!), +//! implementing a custom asset type can be useful when dealing with unusual, game-specific, or proprietary formats. +//! +//! Defining a new asset type is as simple as implementing the [`Asset`] trait. +//! This requires [`TypePath`] for metadata about the asset type, +//! and [`VisitAssetDependencies`] to track asset dependencies. +//! In simple cases, you can derive [`Asset`] and [`Reflect`] and be done with it: the required supertraits will be implemented for you. +//! +//! With a new asset type in place, we now need to figure out how to load it. +//! While [`AssetReader`](io::AssetReader) describes strategies to read assets from various sources, +//! [`AssetLoader`] is the trait that actually turns those into your desired format. +//! Generally, only) [`AssetLoader`] needs to be implemented for custom assets, as the [`AssetReader`](io::AssetReader) implementations are provided by Bevy. +//! +//! However, [`AssetLoader`] shouldn't be implemented for your asset type directly: instead, this is implemented for a "loader" type +//! that can store complex intermediate state, while your asset type is used as the [`AssetLoader::Asset`] associated type. +//! As the trait documentation explains, this allows various [`AssetLoader::Settings`] to be used to configure the loader. +//! +//! After the loader is implemented, it needs to be registered with the [`AssetServer`] using [`App::register_asset_loader`](AssetApp::register_asset_loader). +//! Once your asset type is loaded, you can use it in your game like any other asset type! +//! +//! If you want to save your assets back to disk, you should implement [`AssetSaver`](saver::AssetSaver) as well. +//! This trait mirrors [`AssetLoader`] in structure, and works in tandem with [`AssetWriter`](io::AssetWriter), which mirrors [`AssetReader`](io::AssetReader). // FIXME(3492): remove once docs are ready #![allow(missing_docs)] diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index f0dce3593d..4d8ade8b48 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -20,6 +20,11 @@ use thiserror::Error; /// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`] /// should be loaded. +/// +/// This trait defines asset-specific logic to convert serialized data into Rust types. +/// For asset-agnostic mechanisms to interact with a storage system, see [`AssetSaver`](crate::saver::AssetSaver) and [`AssetLoader`](crate::loader::AssetLoader). +/// +/// For a mirrored version of this trait that can save assets, see [`AssetSaver`](crate::saver::AssetSaver). pub trait AssetLoader: Send + Sync + 'static { /// The top level [`Asset`] loaded by this [`AssetLoader`]. type Asset: Asset; diff --git a/crates/bevy_asset/src/saver.rs b/crates/bevy_asset/src/saver.rs index 4d5925dc54..fbcbee525f 100644 --- a/crates/bevy_asset/src/saver.rs +++ b/crates/bevy_asset/src/saver.rs @@ -8,6 +8,11 @@ use std::{borrow::Borrow, hash::Hash, ops::Deref}; /// Saves an [`Asset`] of a given [`AssetSaver::Asset`] type. [`AssetSaver::OutputLoader`] will then be used to load the saved asset /// in the final deployed application. The saver should produce asset bytes in a format that [`AssetSaver::OutputLoader`] can read. +/// +/// This trait defines asset-specific logic to convert Rust types into serializable data. +/// For asset-agnostic mechanisms to interact with a storage system, see [`AssetSaver`](crate::saver::AssetSaver) and [`AssetLoader`](crate::loader::AssetLoader). +/// +/// For a mirrored version of this trait that can load assets, see [`AssetLoader`](crate::loader::AssetLoader). pub trait AssetSaver: Send + Sync + 'static { /// The top level [`Asset`] saved by this [`AssetSaver`]. type Asset: Asset;