# Objective
- New clippy lints with rust 1.57 are failing
## Solution
- Fixed clippy lints following suggestions
- I ignored clippy in old renderer because there was many and it will be removed soon
Objective
During work on #3009 I've found that not all jobs use actions-rs, and therefore, an previous version of Rust is used for them. So while compilation and other stuff can pass, checking markup and Android build may fail with compilation errors.
Solution
This PR adds `action-rs` for any job running cargo, and updates the edition to 2021.
# Objective
The current TODO comment is out of date
## Solution
I switched up the comment
Co-authored-by: William Batista <45850508+billyb2@users.noreply.github.com>
# Objective
The update to wgpu 0.11 broke CI for android. This was due to a confusion between `bevy::render::ShaderStage` and `wgpu::ShaderStage`.
## Solution
Revert the incorrect change
Upgrades both the old and new renderer to wgpu 0.11 (and naga 0.7). This builds on @zicklag's work here #2556.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This implements the most minimal variant of #1843 - a derive for marker trait. This is a prerequisite to more complicated features like statically defined storage type or opt-out component reflection.
In order to make component struct's purpose explicit and avoid misuse, it must be annotated with `#[derive(Component)]` (manual impl is discouraged for compatibility). Right now this is just a marker trait, but in the future it might be expanded. Making this change early allows us to make further changes later without breaking backward compatibility for derive macro users.
This already prevents a lot of issues, like using bundles in `insert` calls. Primitive types are no longer valid components as well. This can be easily worked around by adding newtype wrappers and deriving `Component` for them.
One funny example of prevented bad code (from our own tests) is when an newtype struct or enum variant is used. Previously, it was possible to write `insert(Newtype)` instead of `insert(Newtype(value))`. That code compiled, because function pointers (in this case newtype struct constructor) implement `Send + Sync + 'static`, so we allowed them to be used as components. This is no longer the case and such invalid code will trigger a compile error.
Co-authored-by: = <=>
Co-authored-by: TheRawMeatball <therawmeatball@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This updates the `pipelined-rendering` branch to use the latest `bevy_ecs` from `main`. This accomplishes a couple of goals:
1. prepares for upcoming `custom-shaders` branch changes, which were what drove many of the recent bevy_ecs changes on `main`
2. prepares for the soon-to-happen merge of `pipelined-rendering` into `main`. By including bevy_ecs changes now, we make that merge simpler / easier to review.
I split this up into 3 commits:
1. **add upstream bevy_ecs**: please don't bother reviewing this content. it has already received thorough review on `main` and is a literal copy/paste of the relevant folders (the old folders were deleted so the directories are literally exactly the same as `main`).
2. **support manual buffer application in stages**: this is used to enable the Extract step. we've already reviewed this once on the `pipelined-rendering` branch, but its worth looking at one more time in the new context of (1).
3. **support manual archetype updates in QueryState**: same situation as (2).
# Objective
- Make it easy to use HexColorError with `thiserror`, i.e. converting it into other error types.
Makes this possible:
```rust
#[derive(Debug, thiserror::Error)]
pub enum LdtkError {
#[error("An error occured while deserializing")]
Json(#[from] serde_json::Error),
#[error("An error occured while parsing a color")]
HexColor(#[from] bevy::render::color::HexColorError),
}
```
## Solution
- Derive thiserror::Error the same way we do elsewhere (see query.rs for instance)
# Objective
Enable using exact World lifetimes during read-only access . This is motivated by the new renderer's need to allow read-only world-only queries to outlive the query itself (but still be constrained by the world lifetime).
For example:
115b170d1f/pipelined/bevy_pbr2/src/render/mod.rs (L774)
## Solution
Split out SystemParam state and world lifetimes and pipe those lifetimes up to read-only Query ops (and add into_inner for Res). According to every safety test I've run so far (except one), this is safe (see the temporary safety test commit). Note that changing the mutable variants to the new lifetimes would allow aliased mutable pointers (try doing that to see how it affects the temporary safety tests).
The new state lifetime on SystemParam does make `#[derive(SystemParam)]` more cumbersome (the current impl requires PhantomData if you don't use both lifetimes). We can make this better by detecting whether or not a lifetime is used in the derive and adjusting accordingly, but that should probably be done in its own pr.
## Why is this a draft?
The new lifetimes break QuerySet safety in one very specific case (see the query_set system in system_safety_test). We need to solve this before we can use the lifetimes given.
This is due to the fact that QuerySet is just a wrapper over Query, which now relies on world lifetimes instead of `&self` lifetimes to prevent aliasing (but in systems, each Query has its own implied lifetime, not a centralized world lifetime). I believe the fix is to rewrite QuerySet to have its own World lifetime (and own the internal reference). This will complicate the impl a bit, but I think it is doable. I'm curious if anyone else has better ideas.
Personally, I think these new lifetimes need to happen. We've gotta have a way to directly tie read-only World queries to the World lifetime. The new renderer is the first place this has come up, but I doubt it will be the last. Worst case scenario we can come up with a second `WorldLifetimeQuery<Q, F = ()>` parameter to enable these read-only scenarios, but I'd rather not add another type to the type zoo.
# Objective
- Provides more useful error messages when using unsupported shader features.
## Solution Fixes#869
- Provided a error message as follows (adding name, set and binding):
```
Unsupported shader bind type CombinedImageSampler (name noiseVol0, set 0, binding 9)
```
# Objective
- Remove all the `.system()` possible.
- Check for remaining missing cases.
## Solution
- Remove all `.system()`, fix compile errors
- 32 calls to `.system()` remains, mostly internals, the few others should be removed after #2446
This is extracted out of eb8f973646476b4a4926ba644a77e2b3a5772159 and includes some additional changes to remove all references to AppBuilder and fix examples that still used App::build() instead of App::new(). In addition I didn't extract the sub app feature as it isn't ready yet.
You can use `git diff --diff-filter=M eb8f973646476b4a4926ba644a77e2b3a5772159` to find all differences in this PR. The `--diff-filtered=M` filters all files added in the original commit but not in this commit away.
Co-Authored-By: Carter Anderson <mcanders1@gmail.com>
# Objective
Fixes how the layer bit is unset in the RenderLayers bit mask when calling the `without` method.
## Solution
Unsets the layer bit using `&=` and the inverse of the layer bit mask.
# Objective
- CI jobs are starting to fail due to `clippy::bool-assert-comparison` and `clippy::single_component_path_imports` being triggered.
## Solution
- Fix all uses where `asset_eq!(<condition>, <bool>)` could be replace by `assert!`
- Move the `#[allow()]` for `single_component_path_imports` to `#![allow()]` at the start of the files.
fixes#2169
Instead of having custom methods with reduced visibility, implement `From<image::DynamicImage> for Texture` and `TryFrom<Texture> for image::DynamicImage`
Since `visible_entities_system` already checks `Visiblie::is_visible` for each entity and requires it to be `true`, there's no reason to verify visibility in `PassNode::prepare` which consumes entities produced by the system.
When implementing `AssetLoader ` you need to specify which File extensions are supported by that loader.
Currently, Bevy always says it supports extensions that actually require activating a Feature beforehand.
This PR adds cf attributes, so Bevy only tries to load those Extensions whose Features were activated.
This prevents Bevy from Panicking and reports such a warning:
```
Jun 02 23:05:57.139 WARN bevy_asset::asset_server: no `AssetLoader` found for the following extension: ogg
```
This also fixes the Bug, that the `png Feature had to be activated even if you wanted to load a different image format.
Fixes#640
`ResMut`, `Mut` and `ReflectMut` all share very similar code for change detection.
This PR is a first pass at refactoring these implementation and removing a lot of the duplicated code.
Note, this introduces a new trait `ChangeDetectable`.
Please feel free to comment away and let me know what you think!
This gets rid of multiple unsafe blocks that we had to maintain ourselves, and instead depends on library that's commonly used and supported by the ecosystem. We also get support for glam types for free.
There is still some things to clear up with the `Bytes` trait, but that is a bit more substantial change and can be done separately. Also there are already separate efforts to use `crevice` crate, so I've just added that as a TODO.
There's what might be considered a proper bug in `PipelineCompiler::compile_pipeline()`, where it overwrites the `step_mode` for the passed in `VertexBufferLayout` with `InputStepMode::Vertex`. Due to this some ugly workarounds are needed to do any kind of instancing.
In the somewhat longer term, `PipelineCompiler::compile_pipeline()` should probably also handle a `Vec<VertexBufferLayout>`, but that would be a (slightly) larger PR, rather than a bugfix. And I'd love to have this fix in sooner than we can deal with a bigger PR.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Required by #1429,
- Adds the `Ushort4` vertex attribute for joint indices
- `Mesh::ATTRIBUTE_JOINT_WEIGHT` and `Mesh::ATTRIBUTE_JOINT_INDEX` to import vertex attributes related to skinning from GLTF
- impl `Default` for `Mesh` a empty triangle mesh is created (needed by reflect)
- impl `Reflect` for `Mesh` all attributes are ignored (needed by the animation system)
Changes to get Bevy to compile with wgpu master.
With this, on a Mac:
* 2d examples look fine
* ~~3d examples crash with an error specific to metal about a compilation error~~
* 3d examples work fine after enabling feature `wgpu/cross`
Feature `wgpu/cross` seems to be needed only on some platforms, not sure how to know which. It was introduced in https://github.com/gfx-rs/wgpu-rs/pull/826
Fixes#2037 (and then some)
Problem:
- `TypeUuid`, `RenderResource`, and `Bytes` derive macros did not properly handle generic structs.
Solution:
- Rework the derive macro implementations to handle the generics.
If a mesh without any vertex attributes is rendered (for example, one that only has indices), bevy will crash since the mesh still creates a vertex buffer even though it's empty. Later code assumes that there is vertex data, causing an index-out-of-bounds panic. This PR fixes the issue by adding a check that there is any vertex data before creating a vertex buffer.
I ran into this issue while rendering a tilemap without any vertex attributes (only indices).
Stack trace:
```
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', C:\Dev\Games\bevy\crates\bevy_render\src\render_graph\nodes\pass_node.rs:346:9
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/bb491ed23937aef876622e4beb68ae95938b3bf9\/library\std\src\panicking.rs:493
1: core::panicking::panic_fmt
at /rustc/bb491ed23937aef876622e4beb68ae95938b3bf9\/library\core\src\panicking.rs:92
2: core::panicking::panic_bounds_check
at /rustc/bb491ed23937aef876622e4beb68ae95938b3bf9\/library\core\src\panicking.rs:69
3: core::slice::index::{{impl}}::index<core::option::Option<tuple<bevy_render::renderer::render_resource::buffer::BufferId, u64>>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\slice\index.rs:184
4: core::slice::index::{{impl}}::index<core::option::Option<tuple<bevy_render::renderer::render_resource::buffer::BufferId, u64>>,usize>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\slice\index.rs:15
5: alloc::vec::{{impl}}::index<core::option::Option<tuple<bevy_render::renderer::render_resource::buffer::BufferId, u64>>,usize,alloc::alloc::Global>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\vec\mod.rs:2386
6: bevy_render::render_graph::nodes::pass_node::DrawState::is_vertex_buffer_set
at C:\Dev\Games\bevy\crates\bevy_render\src\render_graph\nodes\pass_node.rs:346
7: bevy_render::render_graph::nodes::pass_node::{{impl}}::update::{{closure}}<bevy_render::render_graph::base::MainPass*>
at C:\Dev\Games\bevy\crates\bevy_render\src\render_graph\nodes\pass_node.rs:285
8: bevy_wgpu::renderer::wgpu_render_context::{{impl}}::begin_pass
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\renderer\wgpu_render_context.rs:196
9: bevy_render::render_graph::nodes::pass_node::{{impl}}::update<bevy_render::render_graph::base::MainPass*>
at C:\Dev\Games\bevy\crates\bevy_render\src\render_graph\nodes\pass_node.rs:244
10: bevy_wgpu::renderer::wgpu_render_graph_executor::WgpuRenderGraphExecutor::execute
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\renderer\wgpu_render_graph_executor.rs:75
11: bevy_wgpu::wgpu_renderer::{{impl}}::run_graph::{{closure}}
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\wgpu_renderer.rs:115
12: bevy_ecs::world::World::resource_scope<bevy_render::render_graph::graph::RenderGraph,tuple<>,closure-0>
at C:\Dev\Games\bevy\crates\bevy_ecs\src\world\mod.rs:715
13: bevy_wgpu::wgpu_renderer::WgpuRenderer::run_graph
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\wgpu_renderer.rs:104
14: bevy_wgpu::wgpu_renderer::WgpuRenderer::update
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\wgpu_renderer.rs:121
15: bevy_wgpu::get_wgpu_render_system::{{closure}}
at C:\Dev\Games\bevy\crates\bevy_wgpu\src\lib.rs:112
16: alloc::boxed::{{impl}}::call_mut<tuple<mut bevy_ecs::world::World*>,FnMut<tuple<mut bevy_ecs::world::World*>>,alloc::alloc::Global>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1553
17: bevy_ecs::system::exclusive_system::{{impl}}::run
at C:\Dev\Games\bevy\crates\bevy_ecs\src\system\exclusive_system.rs:41
18: bevy_ecs::schedule::stage::{{impl}}::run
at C:\Dev\Games\bevy\crates\bevy_ecs\src\schedule\stage.rs:812
19: bevy_ecs::schedule::Schedule::run_once
at C:\Dev\Games\bevy\crates\bevy_ecs\src\schedule\mod.rs:201
20: bevy_ecs::schedule::{{impl}}::run
at C:\Dev\Games\bevy\crates\bevy_ecs\src\schedule\mod.rs:219
21: bevy_app::app::App::update
at C:\Dev\Games\bevy\crates\bevy_app\src\app.rs:58
22: bevy_winit::winit_runner_with::{{closure}}
at C:\Dev\Games\bevy\crates\bevy_winit\src\lib.rs:485
23: winit::platform_impl::platform::event_loop::{{impl}}::run_return::{{closure}}<tuple<>,closure-1>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:203
24: alloc::boxed::{{impl}}::call_mut<tuple<winit::event::Event<tuple<>>, mut winit::event_loop::ControlFlow*>,FnMut<tuple<winit::event::Event<tuple<>>, mut winit::event_loop::ControlFlow*>>,alloc::alloc::Global>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1553
25: winit::platform_impl::platform::event_loop:🏃:{{impl}}::call_event_handler::{{closure}}<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:245
26: std::panic::{{impl}}::call_once<tuple<>,closure-0>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:344
27: std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure-0>,tuple<>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379
28: hashbrown::set::HashSet<mut winapi::shared::windef::HWND__*, std::collections:#️⃣:map::RandomState, alloc::alloc::Global>::iter<mut winapi::shared::windef::HWND__*,std::collections:#️⃣:map::RandomState,alloc::alloc::Global>
29: std::panicking::try<tuple<>,std::panic::AssertUnwindSafe<closure-0>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343
30: std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure-0>,tuple<>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431
31: winit::platform_impl::platform::event_loop:🏃:EventLoopRunner<tuple<>>::catch_unwind<tuple<>,tuple<>,closure-0>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:152
32: winit::platform_impl::platform::event_loop:🏃:EventLoopRunner<tuple<>>::call_event_handler<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:239
33: winit::platform_impl::platform::event_loop:🏃:EventLoopRunner<tuple<>>::move_state_to<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:341
34: winit::platform_impl::platform::event_loop:🏃:EventLoopRunner<tuple<>>::main_events_cleared<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:227
35: winit::platform_impl::platform::event_loop::flush_paint_messages<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:676
36: winit::platform_impl::platform::event_loop::thread_event_target_callback::{{closure}}<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:1967
37: std::panic::{{impl}}::call_once<isize,closure-0>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:344
38: std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure-0>,isize>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379
39: hashbrown::set::HashSet<mut winapi::shared::windef::HWND__*, std::collections:#️⃣:map::RandomState, alloc::alloc::Global>::iter<mut winapi::shared::windef::HWND__*,std::collections:#️⃣:map::RandomState,alloc::alloc::Global>
40: std::panicking::try<isize,std::panic::AssertUnwindSafe<closure-0>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343
41: std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure-0>,isize>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431
42: winit::platform_impl::platform::event_loop:🏃:EventLoopRunner<tuple<>>::catch_unwind<tuple<>,isize,closure-0>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:152
43: winit::platform_impl::platform::event_loop::thread_event_target_callback<tuple<>>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:2151
44: DefSubclassProc
45: DefSubclassProc
46: CallWindowProcW
47: DispatchMessageW
48: SendMessageTimeoutW
49: KiUserCallbackDispatcher
50: NtUserDispatchMessage
51: DispatchMessageW
52: winit::platform_impl::platform::event_loop::EventLoop<tuple<>>::run_return<tuple<>,closure-1>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:218
53: winit::platform_impl::platform::event_loop::EventLoop<tuple<>>::run<tuple<>,closure-1>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:188
54: winit::event_loop::EventLoop<tuple<>>::run<tuple<>,closure-1>
at C:\Users\tehpe\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\event_loop.rs:154
55: bevy_winit::run<closure-1>
at C:\Dev\Games\bevy\crates\bevy_winit\src\lib.rs:171
56: bevy_winit::winit_runner_with
at C:\Dev\Games\bevy\crates\bevy_winit\src\lib.rs:493
57: bevy_winit::winit_runner
at C:\Dev\Games\bevy\crates\bevy_winit\src\lib.rs:211
58: core::ops::function::Fn::call<fn(bevy_app::app::App),tuple<bevy_app::app::App>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:70
59: alloc::boxed::{{impl}}::call<tuple<bevy_app::app::App>,Fn<tuple<bevy_app::app::App>>,alloc::alloc::Global>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1560
60: bevy_app::app::App::run
at C:\Dev\Games\bevy\crates\bevy_app\src\app.rs:68
61: bevy_app::app_builder::AppBuilder::run
at C:\Dev\Games\bevy\crates\bevy_app\src\app_builder.rs:54
62: game_main::main
at .\crates\game_main\src\main.rs:23
63: core::ops::function::FnOnce::call_once<fn(),tuple<>>
at C:\Users\tehpe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Apr 27 21:51:01.026 ERROR gpu_descriptor::allocator: `DescriptorAllocator` is dropped while some descriptor sets were not deallocated
error: process didn't exit successfully: `target/cargo\debug\game_main.exe` (exit code: 0xc000041d)
```
There are cases where we want an enum variant name. Right now the only way to do that with rust's std is to derive Debug, but this will also print out the variant's fields. This creates the unfortunate situation where we need to manually write out each variant's string name (ex: in #1963), which is both boilerplate-ey and error-prone. Crates such as `strum` exist for this reason, but it includes a lot of code and complexity that we don't need.
This adds a dead-simple `EnumVariantMeta` derive that exposes `enum_variant_index` and `enum_variant_name` functions. This allows us to make cases like #1963 much cleaner (see the second commit). We might also be able to reuse this logic for `bevy_reflect` enum derives.
In bevy_webgl2, the `RenderResourceContext` is created after startup as it needs to first wait for an event from js side:
f31e5d49de/src/lib.rs (L117)
remove `panic` introduced in #1965 and log as a `warn` instead
This implementations allows you
convert std::vec::Vec<T> to VertexAttributeValues::T and back.
# Examples
```rust
use std::convert::TryInto;
use bevy_render::mesh::VertexAttributeValues;
// creating vector of values
let before = vec![[0_u32; 4]; 10];
let values = VertexAttributeValues::from(before.clone());
let after: Vec<[u32; 4]> = values.try_into().unwrap();
assert_eq!(before, after);
```
Co-authored-by: aloucks <aloucks@cofront.net>
Co-authored-by: simens_green <34134129+simensgreen@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Allows render resources to move data to the heap by boxing them. I did this as a workaround to #1892, but it seems like it'd be useful regardless. If not, feel free to close this PR.