Hi all
In my bevy game, I have multiple menus, which work correctly using the mouse. I would like to use keyboard also. For this, I created a trait to manage keyboard navigation :
pub trait ButtonNav<T> {
fn up(&self, current: T) -> Option<T>;
fn down(&self, current: T) -> Option<T>;
}
// As most of the menu are simple one (a 2 vertical buttons for example),
// I impl this trait for slices :
impl<T> ButtonNav<T> for [T]
where
T: PartialEq + Clone,
{
fn up(&self, current: T) -> Option<T> {
let i = self.iter().position(|v| *v == current)?;
self.get(i.saturating_sub(1)).cloned()
}
fn down(&self, current: T) -> Option<T> {
let i = self.iter().position(|v| *v == current)?;
self.get(i + 1).cloned()
}
}
// In bevy, resources must be stored in specific type, so I will do someting like
// struct MyMenu([MyButton])
// I would like MyMenu to impl the ButtonNav trait,
// For this, I give the contract that the MyMenu deref to ButtonNav trait
impl<S, T, N> ButtonNav<T> for S
where
S: std::ops::Deref<Target = N>,
N: ButtonNav<T>,
{
fn up(&self, current: T) -> Option<T> {
(**self).up(current)
}
fn down(&self, current: T) -> Option<T> {
(**self).down(current)
}
}
OK, Let's try
#[derive(Clone, Copy, PartialEq)]
enum MenuButtonAction {
PlayGame,
ExitApplication,
}
struct MainMenuButtonNav([MenuButtonAction; 2]);
impl Default for MainMenuButtonNav {
fn default() -> Self {
MainMenuButtonNav([
MenuButtonAction::PlayGame,
MenuButtonAction::ExitApplication,
])
}
}
impl std::ops::Deref for MainMenuButtonNav {
type Target = [MenuButtonAction];
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let nav = MainMenuButtonNav::default();
button_keyboard_nav(nav, MenuButtonAction::PlayGame);
// let container = MyStructContainer(MyStruct { i: 5 });
// do_func(container, 8);
// println!("Hello, world!");
}
fn button_keyboard_nav<T, N>(nav: N, current: T)
where
T: PartialEq + Clone,
N: ButtonNav<T>,
{
let _new = nav.down(current);
}
I get the followinf error :
error[E0277]: the size for values of type `[MenuButtonAction]` cannot be known at compilation time
--> src/main.rs:31:25
|
31 | button_keyboard_nav(nav, MenuButtonAction::PlayGame);
| ------------------- ^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `std::marker::Sized` is not implemented for `[MenuButtonAction]`, which is required by `MainMenuButtonNav: nav::ButtonNav<_>`
= help: the trait `nav::ButtonNav<T>` is implemented for `[T]`
note: required for `MainMenuButtonNav` to implement `nav::ButtonNav<MenuButtonAction>`
--> src\nav.rs:21:15
|
21 | impl<S, T, N> ButtonNav<T> for S
| - ^^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `button_keyboard_nav`
--> src/main.rs:40:8
|
37 | fn button_keyboard_nav<T, N>(nav: N, current: T)
| ------------------- required by a bound in this function
...
40 | N: ButtonNav<T>,
| ^^^^^^^^^^^^ required by this bound in `button_keyboard_nav`
I don't understand what does that mean...
Any help ?