Skip to content

Commit

Permalink
Update to 0.14.0 (#537)
Browse files Browse the repository at this point in the history
* Update to 0.14.0-rc.2

* [12997](bevyengine/bevy#12997): rename `multi-threaded` to `multi_threaded`

* RenderAssets<Image> is now RenderAssets<GpuImage>

Implemented in [12827](bevyengine/bevy#12827)

* FloatOrd is now in bevy_math

implemented in [12732](bevyengine/bevy#12732)

* convert Transparent2d::dynamic_offset to extra_index

[12889](bevyengine/bevy#12889) Gpu Frustum Culling removed the dynamic_offset of Transparent2d and it became `extra_index` with the special value `PhaseItemExtraIndex::NONE`, which indicates the `None` that was here previously

* RenderPhase<Transparent2d> -> ViewSortedRenderPhases<Transparent2d>

[12453](https://github.com/StarArawn/bevy_ecs_tilemap/pull/bevyengine/bevy#12453): Render phases are now binned or sorted.

Following the changes in the `mesh2d_manual` [example](https://github.com/bevyengine/bevy/blob/ecdd1624f302c5f71aaed95b0984cbbecf8880b7/examples/2d/mesh2d_manual.rs#L357-L358): use the `ViewSortedRenderPhases` resource.

* get_sub_app_mut is now an Option

in [9202](https://github.com/StarArawn/bevy_ecs_tilemap/pull/bevyengine/bevy/pull/9202) SubApp access has changed

* GpuImage::size f32 -> u32 via UVec2

[11698](bevyengine/bevy#11698) changed `GpuImage::size` to `UVec2`.

Right above this, `Extent3d` does the same thing, so I'm taking a small leap and assuming can `as`.

* GpuMesh::primitive_topology -> key_bits/BaseMeshPipeline

[12791](bevyengine/bevy#12791) the `primitive_topology` field on `GpuMesh` was removed in favor of `key_bits` which can be constructed using `BaseMeshPipeline::from_primitive_topology`

* RenderChunk2d::prepare requires &mut MeshVertexBufferLayouts now

[12216](bevyengine/bevy#12216) introduced an argument `&mut MeshVertexBufferLayouts` to `get_mesh_vertex_buffer_layout`, which bevy_ecs_tilemap calls in `RenderChunk2d::prepare`

* into_linear_f32 -> color.0.linear().to_f32_array(),

[12163](bevyengine/bevy#12163) bevy_color was created and Color handling has changed. Specifically Color::as_linear_rgba_f32 has been removed.

LinearRgba is now its own type that can be accessed via [`linear()`](https://docs.rs/bevy/0.14.0-rc.2/bevy/color/enum.Color.html#method.linear) and then converted.

* Must specify type of VisibleEntities when accessing

[12582](bevyengine/bevy#12582) divided `VisibleEntities` into separate lists. So now we have to specify which kind of entity we want. I think we want the Mesh here, and I think we can get rid of the `.index` calls on Entity since Entity [already compares bits](https://docs.rs/bevy_ecs/0.14.0-rc.2/src/bevy_ecs/entity/mod.rs.html#173) for optimized codegen purposes. Waiting to do that until the other changes are in though so as to not change functionality until post-upgrade.

* app.world access is functions now

- [9202](bevyengine/bevy#9202) changed world access to functions. [relevent line](https://github.com/bevyengine/bevy/pull/9202/files#diff-b2fba3a0c86e496085ce7f0e3f1de5960cb754c7d215ed0f087aa556e529f97fR640)
- This also surfaced [12655](bevyengine/bevy#12655) which removed `Into<AssetId<T>>` for `Handle<T>`. using a reference or .id() is the solution here.

* We don't need `World::cell`, and it doesn't exist anymore

In [12551](bevyengine/bevy#12551) `WorldCell` was removed.

...but it turns out we don't need it or its replacement anyway.

* examples error out unless this bevy bug is addressed with these features being added

bevyengine/bevy#13728

* check_visibility is required for the entity that is renderable

As a result of [12582](bevyengine/bevy#12582) `check_visibility` must be implemented for the "renderable" tilemap entities. Doing this is trivial by taking advantage of the
existing `check_visibility` type arguments, which accept a [`QF: QueryFilter + 'static`](https://docs.rs/bevy/0.14.0-rc.2/bevy/render/view/fn.check_visibility.html).

The same `QueryFilter`` is used when checking `VisibleEntities`. I've chosen `With<TilemapRenderSettings` because presumably if the entity doesn't have a `TilemapRenderSettings` then it will not be rendering, but this could be as sophisticated or simple as we want.

For example `WithLight` is currently implemented as

```rust
pub type WithLight = Or<(With<PointLight>, With<SpotLight>, With<DirectionalLight>)>;
```

* view.view_proj -> view.clip_from_world

[13289](bevyengine/bevy#13489) introduced matrix naming changes, including `view_proj` which becomes `clip_from_world`

* color changes to make tests runnable

* clippy fix

* Update Cargo.toml

Co-authored-by: Rob Parrett <robparrett@gmail.com>

* Update Cargo.toml

Co-authored-by: Rob Parrett <robparrett@gmail.com>

* final clippy fixes

* Update Cargo.toml

Co-authored-by: Rob Parrett <robparrett@gmail.com>

* Simplify async loading in ldtk/tiled helpers

See Bevy #12550

* remove second allow lint

* rc.3 bump

* bump version for major release

* remove unused features

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
  • Loading branch information
ChristopherBiscardi and rparrett authored Jul 5, 2024
1 parent e4f3cc6 commit aee4779
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 172 deletions.
14 changes: 8 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bevy_ecs_tilemap"
description = "A tilemap rendering plugin for bevy which is more ECS friendly by having an entity per tile."
version = "0.12.0"
version = "0.14.0"
authors = ["John Mitchell"]
homepage = "https://github.com/StarArawn/bevy_ecs_tilemap"
repository = "https://github.com/StarArawn/bevy_ecs_tilemap"
Expand All @@ -16,7 +16,7 @@ render = []
serde = ["dep:serde"]

[dependencies]
bevy = { version = "0.13", default-features = false, features = [
bevy = { version = "0.14.0", default-features = false, features = [
"bevy_core_pipeline",
"bevy_render",
"bevy_asset",
Expand All @@ -35,7 +35,7 @@ tiled = { version = "0.11.0", default-features = false }
thiserror = { version = "1.0" }

[dev-dependencies.bevy]
version = "0.13"
version = "0.14.0"
default-features = false
features = [
"bevy_core_pipeline",
Expand All @@ -47,11 +47,12 @@ features = [
"bevy_text",
"bevy_sprite",
#"file_watcher",
"multi-threaded",
"multi_threaded",
"webgl2",
]

[target.'cfg(unix)'.dev-dependencies.bevy]
version = "0.13"
version = "0.14.0"
default-features = false
features = [
"bevy_core_pipeline",
Expand All @@ -63,7 +64,8 @@ features = [
"x11",
"bevy_text",
"bevy_sprite",
"multi-threaded",
"multi_threaded",
"webgl2",
]


Expand Down
8 changes: 4 additions & 4 deletions examples/colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
TileTextureIndex(5),
TilePos { x: 0, y: 0 },
quadrant_size,
Color::rgba(1.0, 0.0, 0.0, 1.0),
Color::srgba(1.0, 0.0, 0.0, 1.0),
tilemap_id,
&mut commands,
&mut tile_storage,
Expand All @@ -42,7 +42,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
y: 0,
},
quadrant_size,
Color::rgba(0.0, 1.0, 0.0, 1.0),
Color::srgba(0.0, 1.0, 0.0, 1.0),
tilemap_id,
&mut commands,
&mut tile_storage,
Expand All @@ -55,7 +55,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
y: QUADRANT_SIDE_LENGTH,
},
quadrant_size,
Color::rgba(0.0, 0.0, 1.0, 1.0),
Color::srgba(0.0, 0.0, 1.0, 1.0),
tilemap_id,
&mut commands,
&mut tile_storage,
Expand All @@ -68,7 +68,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
y: QUADRANT_SIDE_LENGTH,
},
quadrant_size,
Color::rgba(1.0, 1.0, 0.0, 1.0),
Color::srgba(1.0, 1.0, 0.0, 1.0),
tilemap_id,
&mut commands,
&mut tile_storage,
Expand Down
69 changes: 33 additions & 36 deletions examples/helpers/ldtk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use bevy::{
use bevy::{
asset::{AssetLoader, AssetPath, LoadContext},
prelude::*,
utils::BoxedFuture,
};
use bevy_ecs_tilemap::map::TilemapType;

Expand Down Expand Up @@ -62,45 +61,43 @@ impl AssetLoader for LdtkLoader {
type Settings = ();
type Error = LdtkAssetLoaderError;

fn load<'a>(
async fn load<'a>(
&'a self,
reader: &'a mut Reader,
reader: &'a mut Reader<'_>,
_settings: &'a Self::Settings,
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<LdtkMap, Self::Error>> {
Box::pin(async move {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;

let project: ldtk_rust::Project = serde_json::from_slice(&bytes).map_err(|e| {
std::io::Error::new(
ErrorKind::Other,
format!("Could not read contents of Ldtk map: {e}"),
)
})?;
let dependencies: Vec<(i64, AssetPath)> = project
.defs
.tilesets
.iter()
.filter_map(|tileset| {
tileset.rel_path.as_ref().map(|rel_path| {
(
tileset.uid,
load_context.path().parent().unwrap().join(rel_path).into(),
)
})
load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;

let project: ldtk_rust::Project = serde_json::from_slice(&bytes).map_err(|e| {
std::io::Error::new(
ErrorKind::Other,
format!("Could not read contents of Ldtk map: {e}"),
)
})?;
let dependencies: Vec<(i64, AssetPath)> = project
.defs
.tilesets
.iter()
.filter_map(|tileset| {
tileset.rel_path.as_ref().map(|rel_path| {
(
tileset.uid,
load_context.path().parent().unwrap().join(rel_path).into(),
)
})
.collect();
})
.collect();

let ldtk_map = LdtkMap {
project,
tilesets: dependencies
.iter()
.map(|dep| (dep.0, load_context.load(dep.1.clone())))
.collect(),
};
Ok(ldtk_map)
})
let ldtk_map = LdtkMap {
project,
tilesets: dependencies
.iter()
.map(|dep| (dep.0, load_context.load(dep.1.clone())))
.collect(),
};
Ok(ldtk_map)
}

fn extensions(&self) -> &[&str] {
Expand Down
149 changes: 73 additions & 76 deletions examples/helpers/tiled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use bevy::{
Res, Transform, Update,
},
reflect::TypePath,
utils::{BoxedFuture, HashMap},
utils::HashMap,
};
use bevy_ecs_tilemap::prelude::*;

Expand Down Expand Up @@ -104,90 +104,87 @@ impl AssetLoader for TiledLoader {
type Settings = ();
type Error = TiledAssetLoaderError;

fn load<'a>(
async fn load<'a>(
&'a self,
reader: &'a mut Reader,
reader: &'a mut Reader<'_>,
_settings: &'a Self::Settings,
load_context: &'a mut bevy::asset::LoadContext,
) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
Box::pin(async move {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;

let mut loader = tiled::Loader::with_cache_and_reader(
tiled::DefaultResourceCache::new(),
BytesResourceReader::new(&bytes),
);
let map = loader.load_tmx_map(load_context.path()).map_err(|e| {
std::io::Error::new(ErrorKind::Other, format!("Could not load TMX map: {e}"))
})?;

let mut tilemap_textures = HashMap::default();
#[cfg(not(feature = "atlas"))]
let mut tile_image_offsets = HashMap::default();

for (tileset_index, tileset) in map.tilesets().iter().enumerate() {
let tilemap_texture = match &tileset.image {
None => {
#[cfg(feature = "atlas")]
{
log::info!("Skipping image collection tileset '{}' which is incompatible with atlas feature", tileset.name);
continue;
}
load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;

let mut loader = tiled::Loader::with_cache_and_reader(
tiled::DefaultResourceCache::new(),
BytesResourceReader::new(&bytes),
);
let map = loader.load_tmx_map(load_context.path()).map_err(|e| {
std::io::Error::new(ErrorKind::Other, format!("Could not load TMX map: {e}"))
})?;

let mut tilemap_textures = HashMap::default();
#[cfg(not(feature = "atlas"))]
let mut tile_image_offsets = HashMap::default();

for (tileset_index, tileset) in map.tilesets().iter().enumerate() {
let tilemap_texture = match &tileset.image {
None => {
#[cfg(feature = "atlas")]
{
log::info!("Skipping image collection tileset '{}' which is incompatible with atlas feature", tileset.name);
continue;
}

#[cfg(not(feature = "atlas"))]
{
let mut tile_images: Vec<Handle<Image>> = Vec::new();
for (tile_id, tile) in tileset.tiles() {
if let Some(img) = &tile.image {
// The load context path is the TMX file itself. If the file is at the root of the
// assets/ directory structure then the tmx_dir will be empty, which is fine.
let tmx_dir = load_context
.path()
.parent()
.expect("The asset load context was empty.");
let tile_path = tmx_dir.join(&img.source);
let asset_path = AssetPath::from(tile_path);
log::info!("Loading tile image from {asset_path:?} as image ({tileset_index}, {tile_id})");
let texture: Handle<Image> =
load_context.load(asset_path.clone());
tile_image_offsets
.insert((tileset_index, tile_id), tile_images.len() as u32);
tile_images.push(texture.clone());
}
#[cfg(not(feature = "atlas"))]
{
let mut tile_images: Vec<Handle<Image>> = Vec::new();
for (tile_id, tile) in tileset.tiles() {
if let Some(img) = &tile.image {
// The load context path is the TMX file itself. If the file is at the root of the
// assets/ directory structure then the tmx_dir will be empty, which is fine.
let tmx_dir = load_context
.path()
.parent()
.expect("The asset load context was empty.");
let tile_path = tmx_dir.join(&img.source);
let asset_path = AssetPath::from(tile_path);
log::info!("Loading tile image from {asset_path:?} as image ({tileset_index}, {tile_id})");
let texture: Handle<Image> = load_context.load(asset_path.clone());
tile_image_offsets
.insert((tileset_index, tile_id), tile_images.len() as u32);
tile_images.push(texture.clone());
}

TilemapTexture::Vector(tile_images)
}

TilemapTexture::Vector(tile_images)
}
Some(img) => {
// The load context path is the TMX file itself. If the file is at the root of the
// assets/ directory structure then the tmx_dir will be empty, which is fine.
let tmx_dir = load_context
.path()
.parent()
.expect("The asset load context was empty.");
let tile_path = tmx_dir.join(&img.source);
let asset_path = AssetPath::from(tile_path);
let texture: Handle<Image> = load_context.load(asset_path.clone());

TilemapTexture::Single(texture.clone())
}
};
}
Some(img) => {
// The load context path is the TMX file itself. If the file is at the root of the
// assets/ directory structure then the tmx_dir will be empty, which is fine.
let tmx_dir = load_context
.path()
.parent()
.expect("The asset load context was empty.");
let tile_path = tmx_dir.join(&img.source);
let asset_path = AssetPath::from(tile_path);
let texture: Handle<Image> = load_context.load(asset_path.clone());

TilemapTexture::Single(texture.clone())
}
};

tilemap_textures.insert(tileset_index, tilemap_texture);
}
tilemap_textures.insert(tileset_index, tilemap_texture);
}

let asset_map = TiledMap {
map,
tilemap_textures,
#[cfg(not(feature = "atlas"))]
tile_image_offsets,
};
let asset_map = TiledMap {
map,
tilemap_textures,
#[cfg(not(feature = "atlas"))]
tile_image_offsets,
};

log::info!("Loaded map: {}", load_context.path().display());
Ok(asset_map)
})
log::info!("Loaded map: {}", load_context.path().display());
Ok(asset_map)
}

fn extensions(&self) -> &[&str] {
Expand Down
8 changes: 4 additions & 4 deletions examples/hex_neighbors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bevy::math::Vec4Swizzles;
use bevy::prelude::*;
use bevy::{color::palettes, math::Vec4Swizzles};
use bevy_ecs_tilemap::helpers::hex_grid::neighbors::{HexDirection, HexNeighbors};
use bevy_ecs_tilemap::prelude::*;
mod helpers;
Expand Down Expand Up @@ -315,7 +315,7 @@ fn hover_highlight_tile_label(
if let Ok(label) = tile_label_q.get(tile_entity) {
if let Ok(mut tile_text) = text_q.get_mut(label.0) {
for section in tile_text.sections.iter_mut() {
section.style.color = Color::RED;
section.style.color = palettes::tailwind::RED_600.into();
}
commands.entity(tile_entity).insert(Hovered);
}
Expand Down Expand Up @@ -371,7 +371,7 @@ fn highlight_neighbor_label(
if let Ok(label) = tile_label_q.get(tile_entity) {
if let Ok(mut tile_text) = text_q.get_mut(label.0) {
for section in tile_text.sections.iter_mut() {
section.style.color = Color::BLUE;
section.style.color = palettes::tailwind::BLUE_600.into();
}
commands.entity(tile_entity).insert(NeighborHighlight);
}
Expand Down Expand Up @@ -412,7 +412,7 @@ fn highlight_neighbor_label(
if let Ok(label) = tile_label_q.get(tile_entity) {
if let Ok(mut tile_text) = text_q.get_mut(label.0) {
for section in tile_text.sections.iter_mut() {
section.style.color = Color::GREEN;
section.style.color = palettes::tailwind::GREEN_600.into();
}
commands.entity(tile_entity).insert(NeighborHighlight);
}
Expand Down
Loading

0 comments on commit aee4779

Please sign in to comment.