Commit graph

25 commits

Author SHA1 Message Date
Matthew Taylor
50a44417ba Derive AsBindGroup Improvements: Better errors, more options, update examples (#5364)
# Objective

- Provide better compile-time errors and diagnostics.
- Add more options to allow more textures types and sampler types.
- Update array_texture example to use upgraded AsBindGroup derive macro.

## Solution

Split out the parsing of the inner struct/field attributes (the inside part of a `#[foo(...)]` attribute) for better clarity

Parse the binding index for all inner attributes, as it is part of all attributes (`#[foo(0, ...)`), then allow each attribute implementer to parse the rest of the attribute metadata as needed. This should make it very trivial to extend/change if needed in the future.

Replaced invocations of `panic!` with the `syn::Error` type, providing fine-grained errors that retains span information. This provides much nicer compile-time errors, and even better IDE errors.

![image](https://user-images.githubusercontent.com/7478134/179452241-6d85d440-4b67-44da-80a7-9d47e8c88b8a.png)

Updated the array_texture example to demonstrate the new changes.

## New AsBindGroup attribute options


### `#[texture(u32, ...)]`
Where `...` is an optional list of arguments.
| Arguments    	| Values                                                         	| Default |
|--------------	|----------------------------------------------------------------	| ----------- |
| dimension = "..."    	| `"1d"`, `"2d"`, `"2d_array"`, `"3d"`, `"cube"`, `"cube_array"` 	|    `"2d"`    |
| sample_type = "..."  	| `"float"`, `"depth"`, `"s_int"` or `"u_int"`                   	|    `"float"`    |
| filterable = ...   	| `true`, `false`                                                	|    `true`     |
| multisampled = ... 	| `true`, `false`                                                	|    `false` |
| visibility(...) 	| `all`, `none`, or a list-combination of `vertex`, `fragment`, `compute` |   `vertex`, `fragment`   |

Example: `#[texture(0, dimension = "2d_array", visibility(vertex, fragment))]`


### `#[sampler(u32, ...)]`
Where `...` is an optional list of arguments.
| Arguments 	| Values                                            	| Default |
|-----------	|---------------------------------------------------	| ----------- |
| sampler_type = "..."   	| `"filtering"`, `"non_filtering"`, `"comparison"`. 	|  `"filtering"`  |
| visibility(...) 	| `all`, `none`, or a list-combination of `vertex`, `fragment`, `compute` |   `vertex`, `fragment`   |

Example: `#[sampler(0, sampler_type = "filtering", visibility(vertex, fragment)]`

## Changelog

- Added more options to `#[texture(...)]` and `#[sampler(...)]` attributes, supporting more kinds of materials. See above for details.
- Upgraded IDE and compile-time error messages.
- Updated array_texture example using the new options.
2022-07-19 22:05:43 +00:00
JoJoJet
44e9cd4bfc Add attribute to ignore fields of derived labels (#5366)
# Objective

Fixes #5362 

## Solution

Add the attribute `#[label(ignore_fields)]` for `*Label` types.

```rust
#[derive(SystemLabel)]
pub enum MyLabel {
    One,

    // Previously this was not allowed since labels cannot contain data.
    #[system_label(ignore_fields)]
    Two(PhantomData<usize>),
}
```

## Notes

This label makes it possible for equality to behave differently depending on whether or not you are treating the type as a label. For example:

```rust
#[derive(SystemLabel, PartialEq, Eq)]
#[system_label(ignore_fields)]
pub struct Foo(usize);
```

If you compare it as a label, it will ignore the wrapped fields as the user requested. But if you compare it as a `Foo`, the derive will incorrectly compare the inner fields. I see a few solutions

1. Do nothing. This is technically intended behavior, but I think we should do our best to prevent footguns.
2. Generate impls of `PartialEq` and `Eq` along with the `#[derive(Label)]` macros. This is a breaking change as it requires all users to remove these derives from their types.
3. Only allow `PhantomData` to be used with `ignore_fields` -- seems needlessly prescriptive.

---

## Changelog

* Added the `ignore_fields` attribute to the derive macros for `*Label` types.
* Added an example showing off different forms of the derive macro.

<!--
## Migration Guide

> This section is optional. If there are no breaking changes, you can delete this section.

- If this PR is a breaking change (relative to the last release of Bevy), describe how a user might need to migrate their code to support these changes
- Simply adding new functionality is not a breaking change.
- Fixing behavior that was definitely a bug, rather than a questionable design choice is not a breaking change.
-->
2022-07-19 05:21:19 +00:00
JoJoJet
c43295af80 Simplify design for *Labels (#4957)
# Objective

- Closes #4954 
- Reduce the complexity of the `{System, App, *}Label` APIs.

## Solution

For the sake of brevity I will only refer to `SystemLabel`, but everything applies to all of the other label types as well.

- Add `SystemLabelId`, a lightweight, `copy` struct.
- Convert custom types into `SystemLabelId` using the trait `SystemLabel`.

## Changelog

- String literals implement `SystemLabel` for now, but this should be changed with #4409 .

## Migration Guide

- Any previous use of `Box<dyn SystemLabel>` should be replaced with `SystemLabelId`.
- `AsSystemLabel` trait has been modified.
    - No more output generics.
    - Method `as_system_label` now returns `SystemLabelId`, removing an unnecessary level of indirection.
- If you *need* a label that is determined at runtime, you can use `Box::leak`. Not recommended.

## Questions for later

* Should we generate a `Debug` impl along with `#[derive(*Label)]`?
* Should we rename `as_str()`?
* Should we remove the extra derives (such as `Hash`) from builtin `*Label` types?
* Should we automatically derive types like `Clone, Copy, PartialEq, Eq`?
* More-ergonomic comparisons between `Label` and `LabelId`.
* Move `Dyn{Eq, Hash,Clone}` somewhere else.
* Some API to make interning dynamic labels easier.
* Optimize string representation
    * Empty string for unit structs -- no debug info but faster comparisons
    * Don't show enum types -- same tradeoffs as asbove.
2022-07-14 18:23:01 +00:00
MrGVSV
3d8d922566 bevy_reflect_derive: Tidying up the code (#4712)
# Objective

The `bevy_reflect_derive` crate is not the cleanest or easiest to follow/maintain. The `lib.rs` file is especially difficult with over 1000 lines of code written in a confusing order. This is just a result of growth within the crate and it would be nice to clean it up for future work.

## Solution

Split `bevy_reflect_derive` into many more submodules. The submodules include:

* `container_attributes` - Code relating to container attributes
* `derive_data` - Code relating to reflection-based derive metadata
* `field_attributes` - Code relating to field attributes
* `impls` - Code containing actual reflection implementations
* `reflect_value` - Code relating to reflection-based value metadata
* `registration` - Code relating to type registration
* `utility` - General-purpose utility functions

This leaves the `lib.rs` file to contain only the public macros, making it much easier to digest (and fewer than 200 lines).

By breaking up the code into smaller modules, we make it easier for future contributors to find the code they're looking for or identify which module best fits their own additions.

### Metadata Structs

This cleanup also adds two big metadata structs: `ReflectFieldAttr` and `ReflectDeriveData`. The former is used to store all attributes for a struct field (if any). The latter is used to store all metadata for struct-based derive inputs.

Both significantly reduce code duplication and make editing these macros much simpler. The tradeoff is that we may collect more metadata than needed. However, this is usually a small thing (such as checking for attributes when they're not really needed or creating a `ReflectFieldAttr` for every field regardless of whether they actually have an attribute).

We could try to remove these tradeoffs and squeeze some more performance out, but doing so might come at the cost of developer experience. Personally, I think it's much nicer to create a `ReflectFieldAttr` for every field since it means I don't have to do two `Option` checks. Others may disagree, though, and so we can discuss changing this either in this PR or in a future one.

### Out of Scope

_Some_ documentation has been added or improved, but ultimately good docs are probably best saved for a dedicated PR.

## 🔍 Focus Points (for reviewers)

I know it's a lot to sift through, so here is a list of **key points for reviewers**:

- The following files contain code that was mostly just relocated:
  - `reflect_value.rs`
  - `registration.rs`
- `container_attributes.rs` was also mostly moved but features some general cleanup (reducing nesting, removing hardcoded strings, etc.) and lots of doc comments
- Most impl logic was moved from `lib.rs` to `impls.rs`, but they have been significantly modified to use the new `ReflectDeriveData` metadata struct in order to reduce duplication.
- `derive_data.rs` and `field_attributes.rs` contain almost entirely new code and should probably be given the most attention.
- Likewise, `from_reflect.rs` saw major changes using `ReflectDeriveData` so it should also be given focus.
- There was no change to the `lib.rs` exports so the end-user API should be the same.

## Prior Work

This task was initially tackled by @NathanSWard in #2377 (which was closed in favor of this PR), so hats off to them for beating me to the punch by nearly a year!

---

## Changelog

* **[INTERNAL]** Split `bevy_reflect_derive` into smaller submodules
* **[INTERNAL]** Add `ReflectFieldAttr`
* **[INTERNAL]** Add `ReflectDeriveData`
* Add `BevyManifest::get_path_direct()` method (`bevy_macro_utils`)


Co-authored-by: MrGVSV <49806985+MrGVSV@users.noreply.github.com>
2022-05-12 19:43:23 +00:00
bjorn3
ddce22b614 Decouple some dependencies (#3886)
# Objective

Reduce from scratch build time.

## Solution

Reduce the size of the critical path by removing dependencies between crates where not necessary. For `cargo check --no-default-features` this reduced build time from ~51s to ~45s. For some commits I am not completely sure if the tradeoff between build time reduction and convenience caused by the commit is acceptable. If not, I can drop them.
2022-04-27 19:08:11 +00:00
bjorn3
ec30822517 Misc dependency improvements (#4545)
A couple more uncontroversial changes extracted from #3886.

* Enable full feature of syn
  
   It is necessary for the ItemFn and ItemTrait type. Currently it is indirectly
   enabled through the tracing dependency of bevy_utils, but this may no
   longer be the case in the future.
* Remove unused function from bevy_macro_utils
2022-04-25 13:16:27 +00:00
Yutao Yuan
8d67832dfa Bump Bevy to 0.8.0-dev (#4505)
# Objective

We should bump our version to 0.8.0-dev after releasing 0.7.0, according to our release checklist.

## Solution

Do it.
2022-04-17 23:04:52 +00:00
Carter Anderson
83c6ffb73c release 0.7.0 (#4487) 2022-04-15 18:05:37 +00:00
Alice Cecile
7ce3ae43e3 Bump Bevy to 0.7.0-dev (#4230)
# Objective

- The [dev docs](https://dev-docs.bevyengine.org/bevy/index.html#) show version 0.6.0, which is actively misleading.

[Image of the problem](https://cdn.discordapp.com/attachments/695741366520512563/953513612943704114/Screenshot_20220316-154100_Firefox-01.jpeg)

Noticed by @ickk, fix proposed by @mockersf.

## Solution

- Bump the version across all Bevy crates to 0.7.0 dev.
- Set a reminder in the Release Checklist to remember to do this each release.
2022-03-19 03:54:15 +00:00
danieleades
d8974e7c3d small and mostly pointless refactoring (#2934)
What is says on the tin.

This has got more to do with making `clippy` slightly more *quiet* than it does with changing anything that might greatly impact readability or performance.

that said, deriving `Default` for a couple of structs is a nice easy win
2022-02-13 22:33:55 +00:00
Ted Driggs
8e1f660e1d Don't panic in macro shape validation (#3647)
# Objective
Emitting compile errors produces cleaner messages than panicking in a proc-macro.

## Solution
- Replace match-with-panic code with call to new `bevy_macro_utils::get_named_struct_fields` function
- Replace one use of match-with-panic for enums with inline match

_Aside:_ I'm also the maintainer of [`darling`](https://docs.rs/darling), a crate which provides a serde-like API for parsing macro inputs. I avoided using it here because it seemed like overkill, but if there are plans to add lots more attributes/macros then that might be a good way of offloading macro error handling.
2022-01-15 22:14:43 +00:00
Carter Anderson
2ee38cb9e0 Release 0.6.0 (#3587) 2022-01-08 10:18:22 +00:00
Michael Nett
1a2646ecc4 Use fully-qualified type names in proc macro. (#3544)
Modifies the code emitted by `derive_label` to use fully-qualified type
names (e.g. `std::boxed::Box` instead of `Box`).

# Objective

- Using unqualified types here causes errors when the proc macro is used in contexts that locally define types with conflicting names (e.g. a local definition of `Box`).

## Solution

- Fully qualify standard types emitted by the proc macro code.
2022-01-04 19:49:37 +00:00
François
79d36e7c28 Prepare crevice for vendored release (#3394)
# Objective

- Our crevice is still called "crevice", which we can't use for a release
- Users would need to use our "crevice" directly to be able to use the derive macro

## Solution

- Rename crevice to bevy_crevice, and crevice-derive to bevy-crevice-derive
- Re-export it from bevy_render, and use it from bevy_render everywhere
- Fix derive macro to work either from bevy_render, from bevy_crevice, or from bevy

## Remaining

- It is currently re-exported as `bevy::render::bevy_crevice`, is it the path we want?
- After a brief suggestion to Cart, I changed the version to follow Bevy version instead of crevice, do we want that?
- Crevice README.md need to be updated
- in the `Cargo.toml`, there are a few things to change. How do we want to change them? How do we keep attributions to original Crevice?
```
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
documentation = "https://docs.rs/crevice"
homepage = "https://github.com/LPGhatguy/crevice"
repository = "https://github.com/LPGhatguy/crevice"
```


Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-12-23 22:49:12 +00:00
Jonathan Cornaz
1b8453d9a0 Fix path used by macro not considering that we can use a sub-crate (#3178)
# Problem

Let's say I am writting a simple bevy plugin, and I want to depend on `bevy_ecs` crate instead of depending on the full `bevy`. 

So I write the following:

*Cargo.toml*:
```toml
[dependencies]
bevy_ecs = { git = "https://github.com/bevyengine/bevy.git", rev = "94db0176fecfac7e7e9763f2dc7458a54c105886" }
```

*lib.rs*:
```rust
use bevy_ecs::prelude::*;

#[derive(Debug, Default, Component)
pub struct MyFancyComponent;
```

So far, so good. Everything works. But let's say I want to write some examples for using my plugin. And for theses I'd like to use the `bevy` crate, so that I can write complete examples (rendering stuff, etc.) that are simple and look like what the consumer of my plugin will do (`use bevy::prelude::*` and `DefaultPlugins`)

So I amend my *Cargo.toml*:
```toml
[dependencies]
bevy_ecs = { git = "https://github.com/bevyengine/bevy.git", rev = "94db0176fecfac7e7e9763f2dc7458a54c105886" }

[dev-dependencies]
bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "94db0176fecfac7e7e9763f2dc7458a54c105886", default-features = false }
```

And that  leads to a complilation error 

```
error[E0433]: failed to resolve: use of undeclared crate or module `bevy`
```

Basically, because `bevy` is in the `dev-dependencies`, the macro (of the production code) decides to use the `bevy::ecs` path instead of `bevy_ecs`. But `bevy` is not available there.

## Solution

This PR fixes the problem. I amend the macro utility responsible of finding the path of a module.

If we try to find a path, we first test if this correspond to a crate that the user directly depend on. (Like, if we search for `bevy_ecs`, we first check if there is a `bevy_ecs` dependency). If yes, we can depend on that directly. Otherwise, we proceed with the existing logic (testing `bevy` and `bevy_internal`)
2021-11-29 23:10:31 +00:00
Carter Anderson
8009af3879 Merge New Renderer 2021-11-22 23:57:42 -08:00
Yoh Deadfall
ffde86efa0 Update to edition 2021 on master (#3028)
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.
2021-10-27 00:12:14 +00:00
François
2f4bcc5bf7 Update for edition 2021 (#2997)
# Objective

- update for Edition 2021

## Solution

- remove the `resolver = "2"`
- update for https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html by adding a few ` `
2021-10-25 18:00:13 +00:00
Paweł Grabarz
07ed1d053e Implement and require #[derive(Component)] on all component structs (#2254)
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>
2021-10-03 19:23:44 +00:00
Jakob Hellermann
b9e0241071 update cargo-manifest (#2859)
On older versions, people with `edition = 2021` would get this error:

![grafik](https://user-images.githubusercontent.com/22177966/134387678-28ece4d4-8af6-48de-beb8-973356c3b9f0.png)
2021-09-22 22:11:54 +00:00
Zicklag
e290a7e29c Implement Sub-App Labels (#2695)
This is a rather simple but wide change, and it involves adding a new `bevy_app_macros` crate. Let me know if there is a better way to do any of this!

---

# Objective

- Allow adding and accessing sub-apps by using a label instead of an index

## Solution

- Migrate the bevy label implementation and derive code to the `bevy_utils` and `bevy_macro_utils` crates and then add a new `SubAppLabel` trait to the `bevy_app` crate that is used when adding or getting a sub-app from an app.
2021-08-24 00:31:21 +00:00
Carter Anderson
a89a954a17 Not me ... us (#2654)
I don't see much of a reason at this point to boost my name over anyone elses. We are all Bevy Contributors.
2021-08-15 20:08:52 +00:00
Carter Anderson
e167a1d9cf Relicense Bevy under the dual MIT or Apache-2.0 license (#2509)
This relicenses Bevy under the dual MIT or Apache-2.0 license. For rationale, see #2373.

* Changes the LICENSE file to describe the dual license. Moved the MIT license to docs/LICENSE-MIT. Added the Apache-2.0 license to docs/LICENSE-APACHE. I opted for this approach over dumping both license files at the root (the more common approach) for a number of reasons:
  * Github links to the "first" license file (LICENSE-APACHE) in its license links (you can see this in the wgpu and rust-analyzer repos). People clicking these links might erroneously think that the apache license is the only option. Rust and Amethyst both use COPYRIGHT or COPYING files to solve this problem, but this creates more file noise (if you do everything at the root) and the naming feels way less intuitive. 
  * People have a reflex to look for a LICENSE file. By providing a single license file at the root, we make it easy for them to understand our licensing approach. 
  * I like keeping the root clean and noise free
  * There is precedent for putting the apache and mit license text in sub folders (amethyst) 
* Removed the `Copyright (c) 2020 Carter Anderson` copyright notice from the MIT license. I don't care about this attribution, it might make license compliance more difficult in some cases, and it didn't properly attribute other contributors. We shoudn't replace it with something like "Copyright (c) 2021 Bevy Contributors" because "Bevy Contributors" is not a legal entity. Instead, we just won't include the copyright line (which has precedent ... Rust also uses this approach).
* Updates crates to use the new "MIT OR Apache-2.0" license value
* Removes the old legion-transform license file from bevy_transform. bevy_transform has been its own, fully custom implementation for a long time and that license no longer applies.
* Added a License section to the main readme
* Updated our Bevy Plugin licensing guidelines.

As a follow-up we should update the website to properly describe the new license.

Closes #2373
2021-07-23 21:11:51 +00:00
bjorn3
ebd10681ac Remove unused deps (#2455)
# Objective

Reduce compilation time

# Solution

Remove unused dependencies. While this PR doesn't remove any crates from `Cargo.lock`, it may unlock more build parallelism.
2021-07-14 20:52:50 +00:00
Yoh Deadfall
653c10371e Use bevy_reflect as path in case of no direct references (#1875)
Fixes #1844


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-05-19 19:03:36 +00:00