mirror of
https://github.com/bevyengine/bevy.git
synced 2026-07-01 08:12:51 -04:00
create-pull-request/patch
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a3fa0c2c8f |
Rename Preferences to Settings in the appropriate places (#24613)
# Objective `bevy_settings` currently conflates "settings" and "preferences" in a number of places. The name of the framework itself is Bevy Settings, so anything that drives general "settings" behaviors should use "settings" terminology. For example, `PreferencesPlugin` should be `SettingsPlugin` because it handles _all_ `SettingsGroup` types (regardless of their "scope" such as "preferences.toml"). ## Solution Use "settings" instead of "preferences" in the appropriate places. I've also removed the custom `ExitAfterSave` commands in the examples as they are unnecessary. This should land in 0.19 because we haven't published this API yet and getting naming right is important. --------- Co-authored-by: Dave Waggoner <waggoner.dave@gmail.com> Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |
||
|
|
e626337b00 |
Use the shorthand functions to construct Val in examples (#24096)
This is my first bevy PR, please tell me if I'm doing anything wrong. # Objective Contribute to #22695. Showcase the preferred coding style in all examples. ## Solution Replace Val:: constructors with the more ergonomic shorthand functions. Change their float literals to integer literals if they are integral. Exceptions: - const contexts (the shorthand functions are not const) - inside bsn! macros (these are new and presumably know what they are doing) - in testbed (these are not really examples) - Val::ZERO (no helper function) ## Testing Ran the changed examples before and after, except the library example `widgets` where I just checked that it still builds. ## Context There was PR #22765 that fixed the same thing but only in the UI examples. --------- Co-authored-by: ickshonpe <david.curthoys@googlemail.com> |
||
|
|
4b09a461e9 |
Simplify Command error handling traits (#23432)
# Objective
I have working `Command` reflection for my game:
```rust
#[derive(Clone)]
pub struct ReflectCommand {
pub apply: fn(&mut World, &dyn PartialReflect, &TypeRegistry),
}
impl ReflectCommand {
pub fn apply(&self, world: &mut World, command: &dyn PartialReflect, registry: &TypeRegistry) {
(self.apply)(world, command, registry);
}
}
impl<C: Command<Result> + Reflect + TypePath> FromType<C> for ReflectCommand {
fn from_type() -> Self {
ReflectCommand {
apply: |world, command, registry| {
let command = from_reflect_with_fallback::<C>(command, world, registry);
command.apply(world);
},
}
}
}
```
However, I am currently only allowed to support a single output type
across *all* command types (which I've chosen to be `Result` for the
time being). This is because, by virtue of `Out` being a generic
parameter, `Command` *can* be implemented multiple times for the same
type, but with different output types. In order for my command
reflection logic to support command types with *any* output type, I need
the ability to guarantee that `Command` will only be implemented once
for some `FooCommand`.
That's why `Out` should be changed into an associated type.
## Solution
- Turned the `Out` generic parameter into an associated type on both
`Command` and `EntityCommand`.
- Bounded `Command::Out` associated type with a new `CommandOutput`
trait.
- This replaces the functionality of the now removed `HandleError`
trait, and allows us to add its functions directly on the `Command`
trait.
- Also bounded `EntityCommand::Out` associated type with the new
`CommandOutput` trait.
- This replaces the functionality of the now removed `CommandWithEntity`
trait, and allows us to add its functions directly on the
`EntityCommand` trait.
Additionally, the new `CommandOutput` trait gives a place for bevy users
to hook into error handling logic with their own types! It also comes
with `diagnostic::on_unimplemented` diagnostics!
## Testing
Maybe TODO: Current tests appear green but should we add tests for the
new `CommandOutput` trait?
|
||
|
|
53050f90e2 |
New bevy_settings crate (#23034)
Yet another attempt at implementing bevy preferences. This version uses bevy_reflect serialization to convert resources from toml values into Rust types and vice versa. This is based on the feedback that I got from the earlier attempt in #22770 To indicate that a resource type should be loaded as preferences, you'll need to add the `SettingsGroup` annotation: ```rust #[derive(Resource, SettingsGroup, Reflect, Default)] #[reflect(Resource, SettingsGroup, Default)] struct Counter { count: i32, } ``` This will produce a TOML file that looks like this: ```toml [counter] count = 3 ``` ## Theory of Operation The `PreferencesPlugin` scans the type registry for all resource types that impl `SettingsGroup` and `Default`. Derive attributes can be used to write the resource to a different file (or different key in browser local storage). `PreferencesPlugin` should be added before other plugins. This ensures that any other plugins can have access to the settings data during initialization. The loader checks to see if the resource already exists; if so, it uses that resource instance and patches the toml values into it, preserving any defaults that have been set. If the resource does not exist, it constructs a new one via `ReflectDefault` before applying the toml properties. (There was a suggestion of using `FromWorld` instead of `Default`. This is worth considering, although there may be issues with calling `FromWorld` so early in the app initialization lifecycle, before most resources have been created.) On `wasm` platforms, this uses browser local storage rather than the filesystem to store preferences. On platforms which have neither, preferences are not supported (although it's possible that some platform-specific settings storage could be implemented). ## Note on terminology I've tried to consistently use the term "preferences" rather than "settings" or "config" because those are broader terms. For example, the `xorg.conf` file, commonly used to configure an XWindows display, is technically a "settings" file, but it is not "preferences". However, for end users it's perfectly permissible to use the word "Settings" in menus and navigation elements since that is the term most commonly used in software today. ## Open Issues ### Syncing with non-resources Some important settings are not stored in resources: one of the most common things that users will want to preserve is the window position and size, which exist on the window entity. It's not possible, under my design, to store arbitrary entities as preferences, so in order for the window properties to be saved they will have to be copied to a resource before being serialized. We probably don't want to be continually copying the window size every time the window is dragged or moved, so we'll need some way to know when serialization is about to happen. I'm thinking that possibly some global event could be triggered just before serialization, and the handlers could use this event to make last-minute patches to resources. ## Saving If Changed Because saving involves i/o, we want to only save when preferences have actually changed. This involves two discrete checks: * Whether a save operation needs to be done at all * Which files need to be saved The reason for these two steps is that even checking which files need to be saved is non-trivial and probably should not be done every frame. Rather than check the `is_changed()` field of every preference resource every frame, the code currently relies on the user to issue an explicit `Command` whenever they change a preferences property. This gets especially tricky if the settings to be saved aren't actually in a resource, like the aforementioned window position. There are two forms of the command: `SavePreferences` and `SavePreferencesSync`. The former, which uses an i/o task, is the preferred approach, unless the app is about to exit, in which case the sync version is preferred. Once we know that a save will take place, a second pass can be used to check the timestamp on every resource: if any resource has a tick value later than the last time the file was either loaded or saved, then we know that file is out of date. Also some properties can change at high frequency - for example, dragging the master volume slider changes the volume every frame. For this reason, we will generally want to put in a delay / debounce logic to batch updated together (not present in this PR). However, this delay means that if the user adjusts the setting and then immediately terminates the app, the setting won't be recorded. (There is no chance of the file being corrupted, as it uses standard practices for ensuring file integrity.) Unfortunately, on some platforms, depending on how the user chooses to quit (Command-Q on Mac) there's no opportunity to listen for the `AppExit` event. For this reason, it's best to use a "belt and suspenders" approach which listens for both `AppExit` and autosave timer events. Fixes #23172 Fixes #13311 --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |