mardi 7 novembre 2023

How to implement abstract class like functionality in Rust?

I recently learned Rust, and for my first larger scale practical project I'm making a terminal based game with crossterm. Now, I come from the OOP world of Java and C++, so I'm having some trouble adjusting to Rust.

If I was making this in a OOP language, I would have a GameWorld abstract class that would define different "worlds", such as the lobby, metaworld, dungeons, and the menu. The GameWorld would have methods such as draw() and tick().

Then, for each of those worlds I would then define a subclass, so I would have DungeonWorld and MenuWorld, etc...

However in Rust, my original idea was to define a World trait. Then I could define structs for each world and have them implement World. But that requires major use of Box<dyn World> which seems to be discouraged by the community and slow to execute.

In theory, what I would like is to be able to define different impl blocks for each instance of a World struct.

This is a stripped down version of what I currently have.

let game = game::get_game();
loop {
    let result = if event::poll(std::time::Duration::from_millis(1000 / TICK_SPEED))
        .expect("Error checking input")
    {
        game.current_world.update(Some(event::read().expect("Error reading input.")))
    } else {
        game.current_world.update(None)
    };

    if !result {
        break;
    }
    game.curent_world.draw();
}
////////////
pub trait World {
     fn draw(&self);
     fn update(&self, event: Option<Event>);
}
////////////
struct Game {
    current_world: Box<dyn World>,
}

struct MenuWorld {}
impl World for MenuWorld {
    fn draw(&self) {}
    fn update(&self, event: Option<Event>) {}
}

pub fn get_game() -> Game {
    Game {
        current_world: Box::new(MenuWorld {})
    }
}

Aucun commentaire:

Enregistrer un commentaire