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

Update to Bevy 0.10 #106

Merged
merged 11 commits into from
Mar 10, 2023
32 changes: 2 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +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 feature combinations
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d","standard_dynamic_assets" --exclude-features "progress_tracking","stageless","progress_tracking_stageless" -p bevy_asset_loader
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d","standard_dynamic_assets" --exclude-features "progress_tracking" -p bevy_asset_loader
- name: Build & run tests for derive package
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d" -p bevy_asset_loader_derive
stageless-tests:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-build-stable-stageless-${{ hashFiles('**/Cargo.toml') }}
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: taiki-e/install-action@v1
with:
tool: cargo-hack
- name: Install alsa and udev
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 feature combinations
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d","standard_dynamic_assets" --features "stageless","progress_tracking","progress_tracking_stageless" -p bevy_asset_loader
progress-tracking-test:
strategy:
matrix:
Expand Down Expand Up @@ -90,7 +62,7 @@ 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 feature combinations
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d","standard_dynamic_assets" --exclude-features "stageless","progress_tracking_stageless" --features "progress_tracking" -p bevy_asset_loader
run: cargo hack test --keep-going --feature-powerset --group-features "2d","3d","standard_dynamic_assets" --features "progress_tracking" -p bevy_asset_loader
lint:
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Changelog

## v0.15.0
- Option to load folders as maps of path to handle (resolves [#32](https://github.com/NiklasEi/bevy_asset_loader/issues/32))
- Changed the default file ending for standard dynamic asset files from `.assets` to `.assets.ron`
- Fix: multiple calls of `with_dynamic_collections` (resolves [#99](https://github.com/NiklasEi/bevy_asset_loader/issues/99))
- Update to Bevy `0.10`
- Removed features `stageless` and `progress_tracking_stageless`

## v0.14.1
- Make sure that the `RonAssetPlugin` for `StandardDynamicAssetCollection` is only added once
Expand Down
85 changes: 22 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ This [Bevy][bevy] plugin reduces boilerplate for handling game assets. The crate

In most cases you will want to load your asset collections during loading states (think loading screens). During such a state, all assets are loaded and their loading process is observed. Only when asset collections can be build with fully loaded asset handles, the collections are inserted as resources. If you do not want to use a loading state, asset collections can still result in cleaner code and improved maintainability (see the ["usage without a loading state"](#usage-without-a-loading-state) section).

_`bevy_asset_loader` supports `iyes_loopless` states with the [`stageless`](#stageless-support) feature._

_The `main` branch and the latest release support Bevy version `0.9` (see [version table](#compatible-bevy-versions))_
_The `main` branch and the latest release support Bevy version `0.10` (see [version table](#compatible-bevy-versions))_

## Loading states

Expand All @@ -20,14 +18,18 @@ A loading state is responsible for managing the loading process during a configu
If your `LoadingState` is set up, you can start your game logic from the next state and use the asset collections as resources in your systems. The loading state guarantees that all handles in your collections are fully loaded by the time the next state starts.

```rust ignore
app.add_loading_state(
LoadingState::new(GameState::Loading)
.continue_to_state(GameState::Next)
.with_collection::<MyAssets>()
)
app
.add_state::<GameState>()
.add_loading_state(
LoadingState::new(GameState::Loading)
.continue_to_state(GameState::Next)
)
.add_collection_to_loading_state::<_, MyAssets>(GameState::Loading)
```

*Note that you can configure the same loading state in multiple places (e.g. in different plugins). All collections added anywhere in your application will be considered.*
Your Bevy state needs to be added to the application before you can add a loading state.

You can add collections to a loading state in multiple places (e.g. in different plugins). All collections added anywhere in your application will be loaded. Important is, that the loading state itself is added to the application before you try to add any collections to it.

## Compile time vs. Run time (dynamic) assets

Expand All @@ -42,14 +44,14 @@ use bevy_asset_loader::prelude::*;

fn main() {
App::new()
.add_state::<GameState>()
.add_loading_state(
LoadingState::new(GameState::AssetLoading)
.continue_to_state(GameState::Next)
.with_collection::<MyAssets>()
)
.add_state(GameState::AssetLoading)
.add_collection_to_loading_state::<_, MyAssets>(GameState::AssetLoading)
.add_plugins(DefaultPlugins)
.add_system_set(SystemSet::on_enter(GameState::Next).with_system(use_my_assets))
.add_system(use_my_assets.in_schedule(OnEnter(GameState::Next)))
.run();
}

Expand All @@ -65,8 +67,9 @@ fn use_my_assets(_my_assets: Res<MyAssets>) {
// do something using the asset handles from the resource
}

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum GameState {
#[default]
AssetLoading,
Next,
}
Expand Down Expand Up @@ -354,21 +357,19 @@ Any field in an asset collection without any attribute is required to implement

## Initializing FromWorld resources

In situations where you would like to prepare other resources based on your loaded asset collections you can use `LoadingState::init_resource` to initialize `FromWorld` resources. See [init_resource.rs](/bevy_asset_loader/examples/init_resource.rs) for an example that loads two images and then combines their pixel data into a third image.
In situations where you would like to prepare other resources based on your loaded asset collections you can use `App::init_resource_after_loading_state` to initialize `FromWorld` resources. See [init_resource.rs](/bevy_asset_loader/examples/init_resource.rs) for an example that loads two images and then combines their pixel data into a third image.

`LoadingState::init_resource` does the same as Bevy's `App::init_resource`, but at a different point in time. While Bevy inserts your resources at the very beginning, `bevy_asset_loader` will initialize them only after your loaded asset collections are inserted. That means you can use your asset collections in the `FromWorld` implementation.
`App::init_resource_after_loading_state` does the same as Bevy's `App::init_resource`, but at a different point in time. While Bevy inserts your resources at the very beginning, `bevy_asset_loader` will initialize them only after your loaded asset collections are inserted. That means you can use your asset collections in the `FromWorld` implementation.

## Progress tracking

With the feature `progress_tracking`, you can integrate with [`iyes_progress`][iyes_progress] to track asset loading during a loading state. This, for example, enables progress bars.

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 base set between `CoreSet::StateTransitions` and `CoreSet::Update`. This means that systems running in `CoreSet::Update` can already see the reported progress of all tracked asset collections for the current frame.

## Failure state

Expand Down Expand Up @@ -401,62 +402,20 @@ struct MyAssets {
}
```

## Stageless support

`bevy_asset_loader` can integrate with `iyes_loopless`, which implements ideas from Bevy's [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45). The integration can be enabled with the `stageless` feature.

Currently, you must initialize the `iyes_loopless` state before you initialize your `AssetLoader`. This is a limitation due to the way `iyes_loopless` works. The following is a minimal example of integrating `bevy_asset_loader` with `iyes_loopless`:

```rust no_run
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
use iyes_loopless::prelude::*;

fn main() {
App::new()
.add_loopless_state(MyStates::AssetLoading)
.add_loading_state(
LoadingState::new(MyStates::AssetLoading)
.continue_to_state(MyStates::Next)
.with_collection::<AudioAssets>()
)
.add_plugins(DefaultPlugins)
.add_enter_system(MyStates::Next, use_my_assets)
.run();
}

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

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

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

When using stageless with the `progress_tracking` feature, remember to also enable the `progress_tracking_stageless` feature. See [the stageless examples](/bevy_asset_loader/examples/README.md#examples-for-stageless) for different use cases with `iyes_loopless` integration.

## Compatible Bevy versions

The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tries to track the `main` branch of Bevy (PRs updating the tracked commit are welcome).

Compatibility of `bevy_asset_loader` versions:
| `bevy_asset_loader` | `bevy` |
| :-- | :-- |
| :-- | :-- |
| `0.15` | `0.10` |
| `0.14` | `0.9` |
| `0.12` - `0.13` | `0.8` |
| `0.10` - `0.11` | `0.7` |
| `0.8` - `0.9` | `0.6` |
| `0.1` - `0.7` | `0.5` |
| `main` | `0.8` |
| `main` | `0.10` |
| `bevy_main` | `main` |

## License
Expand Down
59 changes: 8 additions & 51 deletions bevy_asset_loader/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_asset_loader"
version = "0.14.1"
version = "0.15.0"
authors = ["Niklas Eicker <git@nikl.me>"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand All @@ -18,25 +18,21 @@ readme = "README.md"
3d = ["bevy/bevy_pbr", "bevy/bevy_render", "bevy_asset_loader_derive/3d"]
standard_dynamic_assets = ["bevy_common_assets", "serde"]
progress_tracking = ["iyes_progress"]
progress_tracking_stageless = ["iyes_progress/iyes_loopless"]
stageless = ["iyes_loopless"]

[dependencies]
bevy = { version = "0.9", default-features = false, features = ["bevy_asset"] }
bevy_asset_loader_derive = { version = "=0.14.0", path = "../bevy_asset_loader_derive" }
bevy = { version = "0.10", default-features = false, features = ["bevy_asset"] }
bevy_asset_loader_derive = { version = "=0.15.0", path = "../bevy_asset_loader_derive" }
anyhow = "1"

bevy_common_assets = { version = "0.4", features = ["ron"], optional = true }
bevy_common_assets = { version = "0.5.0", features = ["ron"], optional = true }
serde = { version = "1", optional = true }
iyes_progress = { version = "0.7", optional = true }
iyes_loopless = { version = "0.9", optional = true }
iyes_progress = { version = "0.8", optional = true }

[dev-dependencies]
bevy = { version = "0.9", features = ["vorbis"] }
bevy = { version = "0.10", features = ["vorbis"] }
anyhow = "1"
iyes_progress = { version = "0.7" }
iyes_loopless = { version = "0.9" }
bevy_common_assets = { version = "0.4", features = ["ron"] }
iyes_progress = { version = "0.8" }
bevy_common_assets = { version = "0.5.0", features = ["ron"] }
serde = { version = "1" }
trybuild = { version = "1.0" }

Expand Down Expand Up @@ -85,45 +81,6 @@ required-features = ["progress_tracking", "2d"]
name = "failure_state"
path = "examples/failure_state.rs"

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

[[example]]
name = "stageless_full_collection"
path = "examples/stageless_full_collection.rs"
required-features = ["stageless", "2d", "3d"]

[[example]]
name = "stageless_full_dynamic_collection"
path = "examples/stageless_full_dynamic_collection.rs"
required-features = ["stageless", "2d", "3d", "standard_dynamic_assets"]

[[example]]
name = "stageless_manual_dynamic_asset"
path = "examples/stageless_manual_dynamic_asset.rs"
required-features = ["stageless", "standard_dynamic_assets"]

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

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

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

[[example]]
name = "full_collection"
path = "examples/full_collection.rs"
Expand Down
30 changes: 7 additions & 23 deletions bevy_asset_loader/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,18 @@ with `cargo run --example <example>`.

| Example | Description |
|------------------------------------------------------------|--------------------------------------------------------------------------|
| [`atlas_from_grid.rs`](atlas_from_grid.rs) | Loading a texture atlas from a sprite sheet |
| [`custom_dynamic_assets.rs`](custom_dynamic_assets.rs) | Define and use your own dynamic assets |
| [`dynamic_asset.rs`](dynamic_asset.rs) | Load dynamic assets from a `.ron` file |
| [`failure_state.rs`](failure_state.rs) | Sets up a failure state |
| [`full_collection.rs`](full_collection.rs) | A complete asset collection with all supported non-dynamic field types |
| [`full_dynamic_collection.rs`](full_dynamic_collection.rs) | A complete asset collection with all supported dynamic asset field types |
| [`two_collections.rs`](two_collections.rs) | Load multiple asset collections |
| [`manual_dynamic_asset.rs`](manual_dynamic_asset.rs) | Load an image asset from a path resolved at run time |
| [`dynamic_asset.rs`](dynamic_asset.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 |
| [`manual_dynamic_asset.rs`](manual_dynamic_asset.rs) | Load an image asset from a path resolved at run time |
| [`no_loading_state.rs`](no_loading_state.rs) | How to use asset collections without a loading state |
| [`custom_dynamic_assets.rs`](custom_dynamic_assets.rs) | Define and use your own dynamic assets |
| [`progress_tracking.rs`](progress_tracking.rs) | How to set up progress tracking using `iyes_progress` |
| [`failure_state.rs`](failure_state.rs) | Sets up a failure 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_manual_dynamic_asset.rs`](stageless_manual_dynamic_asset.rs) | Load an image asset from a path resolved runtime |
| [`stageless_full_collection.rs`](stageless_full_collection.rs) | A complete asset collection with all supported non-dynamic field types |
| [`stageless_full_dynamic_collection.rs`](stageless_full_dynamic_collection.rs) | A complete asset collection with all supported dynamic asset field types |
| [`stageless_progress.rs`](stageless_progress.rs) | Stageless with progress tracking |
| [`stageless_dynamic_asset.rs`](stageless_dynamic_asset.rs) | Stageless with ron loading |
| [`stageless_failure_state.rs`](stageless_failure_state.rs) | Sets up a failure state |
| [`standard_material.rs`](standard_material.rs) | Loading a standard material from a png file |
| [`two_collections.rs`](two_collections.rs) | Load multiple asset collections |

## Credits

Expand Down
Loading