-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commands
should be a trait, and other Bevy-builtin SystemParams.
#3782
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
Comments
Wow. You guys are reacting blazingly fast! |
There's a Discord channel that tracks new Github issues ;) And this one is particularly interesting to me. |
This is what I'm currently doing to remove the boilerplate. pub fn run_once<Params, D>(systems: impl IntoIterator<Item = D>) -> World
where
D: IntoSystemDescriptor<Params>,
{
let mut stage = SystemStage::parallel();
for i in systems {
stage.add_system(i);
}
let mut world = World::new();
// Insert some dummy resources for use.
world.insert_resource(PlayerImage(Handle::default()));
stage.run(&mut world);
world
}
/// Queries the world. Returns an iterator. Different from World::query
/// which returns a [QueryState].
macro_rules! query {
($world: ident, $components: ty) => {
$world.query::<$components>().iter(&$world)
};
} |
So, I can definitely empathize with some of your frustrations around testing, and this issue is closely related to #2192. The inability to construct However, I suspect that you're not familiar with the absolutely wonderful For example: let mut input_system_state: SystemState<(
Option<ResMut<Input<GamepadButton>>>,
Option<ResMut<Input<KeyCode>>>,
Option<ResMut<Input<MouseButton>>>,
)> = SystemState::new(self);
let (mut maybe_gamepad, mut maybe_keyboard, mut maybe_mouse) =
input_system_state.get_mut(self); This is underdocumented though; I was actually just about to prepare a PR for it. |
This |
I'm pretty sure using |
Sure. It did not cost me much time to realize that it is almost impossible to mock system parameters without actually making them. |
What problem does this solve or what need does it fill?
Inversion-of-Control (IoC) frameworks should not be intrusive, or the code will be hard to test. Currently, quite a little functionality in Bevy are implemented directly as concrete structs. This makes unit tests with systems nearly impossible without bringing up a Bevy environment (
World
andStage
, at least). This also couples the gameplay code deeper with the existing implementation.What solution would you like?
We can introduce traits for structs such as
Commands
,Res
. Since Bevy supports generic functions, it is easy to switch to usingimpl Commands
. This costs us a little ergonomics, but we can still use the concrete one anyway if animpl
keyword means too much.What alternative(s) have you considered?
It is possible without an API change, by transforming structs such as
Commands
into sum types, i.e. one with the real logic, and one with mocking implementations. In tests, users can check actions performed upon the mocks. Overhead on dispatching is possible, but I guess it being neglectable thanks to modern CPU branch-prediction.The text was updated successfully, but these errors were encountered: