Default/Swappable systems, is it possible? #2769
-
On my quest for making bevy_dolly, an extension of h3r2tic's ergonomic dolly crate implemented in bevy. I want to create an equally ergonomic plugin for Bevy. However, I've hit a snag, I'm not sure what I want is possible so here goes: I want to somehow tie a boxed system to a struct so that it can impl a plugin specified behavior, but still, allow the user to create their own Params for the system. This would allow for systems to be swapped, just as with RunCriteria, but the user who implements the plugin has more flexibility and extensibility. I've tried to see if SystemParam could do this, but I've hit snags there as well due to I wanted it to be generic as possible, but QuerySets and QueryFilter don't seem to be supported by SystemParam. I recognize that my goal might not come across in text, so I've provided a loose example of how I imagine it could look like: use bevy::{ecs::system::BoxedSystem, prelude::*};
//Lib.rs (Plugin)
pub struct SwapSystem {
pub current_index: usize,
pub systems: Vec<BoxedSystem>,
}
pub trait NextIndex {
fn next_wrap(&self) -> usize;
}
impl NextIndex for SwapSystem {
fn next_wrap(&self) -> usize {
if self.current_index + 1 > self.systems.len() - 1 {
0
} else {
self.current_index + 1
}
}
}
impl Default for SwapSystem {
fn default() -> Self {
Self {
systems: vec![HelloBevy::system(), HelloWorld::system()],
current_index: 0,
}
}
}
pub trait SwapableSystem {
fn system() -> BoxedSystem;
fn sys() -> ();
}
struct HelloBevy;
impl SwapableSystem for HelloBevy {
fn system() -> BoxedSystem {
Box::new(Self::sys.system())
}
fn sys() -> () {
print!("Hello Bevy!");
}
}
struct HelloWorld;
impl SwapableSystem for HelloWorld {
fn system() -> BoxedSystem {
Box::new(Self::sys.system())
}
fn sys() -> () {
print!("Hello World!");
}
}
//Implementation (Example)
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.insert_resource(SwapSystem {
systems: vec![HelloMe::system(), HelloWorld::system()],
..Default::default()
})
.add_system(swap_system.system())
.add_system(update.system())
.run();
}
struct HelloMe;
impl SwapableSystem for HelloMe {
fn system() -> BoxedSystem {
Box::new(Self::sys.system())
}
fn sys() -> () {
print!("Hello Me!");
}
}
fn swap_system(
keys: Res<Input<KeyCode>>,
swap: ResMut<SwapSystem>,
){
if keys.just_pressed(KeyCode::E) {
swap.next_wrap();
}
}
fn update(swap: ResMut<SwapSystem>) {
swap.systems[swap.current_index].run(input, world); //Notice compile error: input & world is not found in this scope
} Even though you might not have a solution, any pointers, suggestions, are appreciated and are very welcomed. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
dolly achieves what I want without relying on bevy 🎉 |
Beta Was this translation helpful? Give feedback.
dolly achieves what I want without relying on bevy 🎉