Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stageless #47

Merged
merged 8 commits into from
May 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ jobs:
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev
if: runner.os == 'linux'
- name: Build & run tests for all feature combinations
run: cargo hack test --feature-powerset --group-features "2d","3d"
run: cargo hack test --feature-powerset --group-features "2d","3d","dynamic_assets" --group-features "stageless","progress_tracking_stageless" --clean-per-run -p bevy_asset_loader
- name: Build & run tests for derive package
run: cargo hack test --feature-powerset --group-features "2d","3d" --clean-per-run -p bevy_asset_loader_derive
lint:
runs-on: ubuntu-latest
steps:
Expand Down
88 changes: 77 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ The plugin supports different paths for asset collections to be loaded. The most

Asset configurations, like their file path or tile dimensions for sprite sheets, can be resolved at compile time (through derive macro attributes), or at run time (see ["Dynamic assets"](#dynamic-assets)). The second allows managing asset configurations as assets. This means you can keep a list of your asset files and their properties in asset files (at the moment only `ron` files are supported).

*The `main` branch and the latest release support Bevy version `0.7` (see [version table](#compatible-bevy-versions)). If you like living on the edge, take a look at the `bevy_main` branch, which tries to stay close to Bevy's development.*
Asset loader also supports `iyes_loopless` states via [`stageless`](#stageless) feature.

_The `main` branch and the latest release support Bevy version `0.7` (see [version table](#compatible-bevy-versions)). If you like living on the edge, take a look at the `bevy_main` branch, which tries to stay close to Bevy's development._

## How to use

Expand Down Expand Up @@ -76,7 +78,7 @@ use bevy_asset_loader::AssetCollection;
#[derive(AssetCollection)]
struct ImageAssets {
#[asset(key = "player")]
player: Handle<Image>,
player: Handle<Image>,
#[asset(key = "tree")]
tree: Handle<Image>,
}
Expand All @@ -100,6 +102,7 @@ Loading dynamic assets from such a ron file requires the feature `dynamic_assets
### Loading a folder as asset

You can load all assets in a folder and keep them in an `AssetCollection` as a vector of untyped handles.

```rust
use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;
Expand All @@ -114,6 +117,7 @@ struct MyAssets {
Just like Bevy's `load_folder`, this will also recursively load sub folders.

If all assets in the folder have the same type you can load the folder as `Vec<Handle<T>>`. Just set `typed` in the `folder` attribute and adapt the type of the asset collection field.

```rust
use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;
Expand All @@ -128,6 +132,7 @@ struct MyAssets {
### Loading standard materials

You can directly load standard materials if you enable the feature `render`. For a complete example please take a look at [standard_material.rs](/bevy_asset_loader/examples/standard_material.rs).

```rust
use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;
Expand All @@ -141,6 +146,7 @@ struct MyAssets {
```

This is also supported as a dynamic asset:

```ron
({
"image.tree": StandardMaterial (
Expand All @@ -152,6 +158,7 @@ This is also supported as a dynamic asset:
### Loading texture atlases

You can directly load texture atlases from sprite sheets if you enable the feature `render`. For a complete example please take a look at [atlas_from_grid.rs](/bevy_asset_loader/examples/atlas_from_grid.rs).

```rust
use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;
Expand All @@ -165,6 +172,7 @@ struct MyAssets {
```

This is also supported as a dynamic asset:

```ron
({
"image.player": TextureAtlas (
Expand Down Expand Up @@ -193,9 +201,11 @@ With the feature `progress_tracking`, you can integrate with [`iyes_progress`][i

See [`progress_tracking`](/bevy_asset_loader/examples/progress_tracking.rs) for a complete example.

When using `stageless` feature, you need to add `progress_tracking_stageless` feature in addition to `progress_tracking`.

### A note on system ordering

The loading state runs in a single exclusive system `at_start`. This means that any parallel system in the loading state will always run after all asset handles have been checked for their status. You can thus read the current progress in each frame in a parallel system without worrying about frame lag.
The loading state runs in a single exclusive system `at_start`. This means that any parallel system in the loading state will always run after all asset handles have been checked for their status. You can thus read the current progress in each frame in a parallel system without worrying about frame lag.

## Usage without a loading state

Expand All @@ -222,25 +232,81 @@ struct MyAssets {
}
```

## Stageless

Asset loader supports Stageless RFC via `iyes_loopless`. It can be enabled with `stageless` feature.

Note that currently you must initialize loopless state before you initialize `AssetLoader`. This is a limitation due to the way `iyes_loopless` works.

When using with `progress_tracking`, remember to enable `progress_tracking_stageless` feature too.

```rust no_run
use bevy::prelude::*;
use bevy_asset_loader::{AssetCollection, AssetLoader};
use iyes_loopless::prelude::*;

/// This example shows how to use `iyes_loopless` with `bevy_asset_loader`
fn main() {
let mut app = App::new();
app.add_loopless_state(MyStates::AssetLoading);
AssetLoader::new(MyStates::AssetLoading)
.continue_to_state(MyStates::Next)
.with_collection::<ImageAssets>()
.with_collection::<AudioAssets>()
.build(&mut app);
app
.add_plugins(DefaultPlugins)
.add_enter_system(MyStates::Next, use_my_assets)
.run();
}

#[derive(AssetCollection)]
struct AudioAssets {
#[asset(path = "audio/background.ogg")]
background: Handle<AudioSource>,
}

#[derive(AssetCollection)]
struct ImageAssets {
#[asset(path = "images/player.png")]
player: Handle<Image>,
#[asset(path = "images/tree.png")]
tree: Handle<Image>,
#[asset(path = "images", folder)]
_images: Vec<HandleUntyped>,
}


fn use_my_assets(_image_assets: Res<ImageAssets>, _audio_assets: Res<AudioAssets>) {
// do something using the asset handles from the resources
}

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
enum MyStates {
AssetLoading,
Next,
}
```

## Compatible Bevy versions

The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tracks the `main` branch of Bevy.

Compatibility of `bevy_asset_loader` versions:
| `bevy_asset_loader` | `bevy` |
| :-- | :-- |
| `0.10` | `0.7` |
| `0.8` - `0.9` | `0.6` |
| `0.1` - `0.7` | `0.5` |
| `main` | `0.7` |
| `bevy_main` | `main` |
| :-- | :-- |
| `0.10` | `0.7` |
| `0.8` - `0.9` | `0.6` |
| `0.1` - `0.7` | `0.5` |
| `main` | `0.7` |
| `bevy_main` | `main` |

## License

Licensed under either of

* Apache License, Version 2.0, ([LICENSE-APACHE](/LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](/LICENSE-MIT) or https://opensource.org/licenses/MIT)
- Apache License, Version 2.0, ([LICENSE-APACHE](/LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](/LICENSE-MIT) or https://opensource.org/licenses/MIT)

at your option.

Expand Down
31 changes: 22 additions & 9 deletions bevy_asset_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@ categories = ["game-development"]
readme = "../README.md"

[features]
# This feature adds support for bevy's TextureAtlas assets
2d = [
"bevy/bevy_sprite",
"bevy_asset_loader_derive/2d",
]
2d = ["bevy/bevy_sprite", "bevy_asset_loader_derive/2d"]
# This feature adds support for bevy's StandardMaterial assets
3d = [
"bevy/bevy_pbr",
"bevy_asset_loader_derive/3d",
]
3d = ["bevy/bevy_pbr", "bevy_asset_loader_derive/3d"]
dynamic_assets = ["bevy_asset_ron", "serde"]
progress_tracking = ["iyes_progress"]
progress_tracking_stageless = ["iyes_progress/iyes_loopless"]
stageless = ["iyes_loopless"]

[dependencies]
Expand Down Expand Up @@ -85,3 +79,22 @@ required-features = ["progress_tracking"]
name = "stageless"
path = "examples/stageless.rs"
required-features = ["stageless"]

[[example]]
name = "stageless_dynamic_asset"
path = "examples/stageless_dynamic_asset.rs"
required-features = ["stageless"]

[[example]]
name = "stageless_progress"
path = "examples/stageless_progress.rs"
required-features = [
"progress_tracking_stageless",
"stageless",
"progress_tracking"
]

[[example]]
name = "stageless_dynamic_ron"
path = "examples/stageless_dynamic_ron.rs"
required-features = ["2d", "dynamic_assets", "stageless"]
31 changes: 22 additions & 9 deletions bevy_asset_loader/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@

These examples are simple Bevy Apps illustrating the capabilities of `bevy_asset_loader`. Run the examples with `cargo run --example <example>`.

| Example | Description |
|--------------------------------------------------|-------------------------------------------------------------------------|
| [`two_collections.rs`](two_collections.rs) | Load multiple asset collections |
| [`dynamic_asset.rs`](dynamic_asset.rs) | Load an image asset from a path resolved at run time |
| [`dynamic_asset_ron.rs`](dynamic_asset_ron.rs) | Load dynamic assets from a `.ron` file |
| [`atlas_from_grid.rs`](atlas_from_grid.rs) | Loading a texture atlas from a sprite sheet |
| [`standard_material.rs`](standard_material.rs) | Loading a standard material from a png file |
| [`init_resource.rs`](init_resource.rs) | Inserting a `FromWorld` resource when all asset collections are loaded |
| [`no_loading_state.rs`](no_loading_state.rs) | How to use asset collections without a loading state |
| Example | Description |
| ---------------------------------------------- | ---------------------------------------------------------------------- |
| [`two_collections.rs`](two_collections.rs) | Load multiple asset collections |
| [`dynamic_asset.rs`](dynamic_asset.rs) | Load an image asset from a path resolved at run time |
| [`dynamic_asset_ron.rs`](dynamic_asset_ron.rs) | Load dynamic assets from a `.ron` file |
| [`atlas_from_grid.rs`](atlas_from_grid.rs) | Loading a texture atlas from a sprite sheet |
| [`standard_material.rs`](standard_material.rs) | Loading a standard material from a png file |
| [`init_resource.rs`](init_resource.rs) | Inserting a `FromWorld` resource when all asset collections are loaded |
| [`no_loading_state.rs`](no_loading_state.rs) | How to use asset collections without a loading state |

## Examples for stageless

The following examples use `iyes_loopless`, which implements ideas from Bevy's [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45). All examples require the `stageless` feature.
Note that progress tracking needs `progress_tracking_stageless` feature together with `progress_tracking`.

| Example | Description |
| ---------------------------------------------------------- | ------------------------------------------------ |
| [`stageless.rs](stageless.rs) | Basic example |
| [`stageless_dynamic_asset.rs`](stageless_dynamic_asset.rs) | Load an image asset from a path resolved runtime |
| [`stageless_progress.rs`](stageless_progress.rs) | Stageless with progress tracking |
| [`stageless_dynamic_ron.rs](stageless_dynamic_ron.rs) | Stageless with ron loading |

## Credits

The examples include third party assets:

Background audio: [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/) by [Jay_You](https://freesound.org/people/Jay_You/sounds/460432/)
Expand Down
14 changes: 8 additions & 6 deletions bevy_asset_loader/examples/stageless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ const PLAYER_SPEED: f32 = 5.;
/// This example shows how to use `iyes_loopless` with `bevy_asset_loader`
fn main() {
let mut app = App::new();
app.add_loopless_state(MyStates::AssetLoading);
AssetLoader::new(MyStates::AssetLoading)
.continue_to_state(MyStates::Next)
.with_collection::<ImageAssets>()
.with_collection::<AudioAssets>()
.build(&mut app);
app.add_loopless_state(MyStates::AssetLoading)
.insert_resource(Msaa { samples: 1 })
app.insert_resource(Msaa { samples: 1 })
.add_plugins(DefaultPlugins)
.add_enter_system(MyStates::Next, spawn_player_and_tree)
.add_enter_system(MyStates::Next, play_background_audio)
.add_system_set(
SystemSet::on_enter(MyStates::Next)
.with_system(spawn_player_and_tree)
.with_system(play_background_audio),
ConditionSet::new()
.run_in_state(MyStates::Next)
.with_system(move_player)
.into(),
)
.add_system_set(SystemSet::on_update(MyStates::Next).with_system(move_player))
.run();
}

Expand Down