lundi 2 mars 2020

Right way to implement world of entities

I'm looking for the right way to implement a world for my game. The world holds and updates every entity but some entities may modify the world back. I've tried to use RefCell but I got an error in Entity::update method:

use std::cell::RefCell;
use std::rc::Rc;

struct World {
    entities: Vec<Entity>,
}

impl World {
    fn update(&mut self) {
        for entity in self.entities.iter_mut() {
            entity.update();
        }

        println!("World has been updated");
    }

    fn influence(&mut self) {
        println!("World has been influenced");
    }
}

struct Entity {
    world: Rc<RefCell<World>>,
}

impl Entity {
    fn update(&mut self) {
        self.world.borrow_mut().influence(); // ERROR GOES HERE
        println!("Entity has been updated");
    }
}

fn main() {
    let world = Rc::new(RefCell::new(World {
        entities: Vec::new(),
    }));
    world.borrow_mut().entities.push(Entity {
        world: world.clone(),
    });
    world.borrow_mut().entities.push(Entity {
        world: world.clone(),
    });
    world.borrow_mut().entities.push(Entity {
        world: world.clone(),
    });
    world.borrow_mut().update();
    world.borrow_mut().update();
}
thread 'main' panicked at 'already borrowed: BorrowMutError', src/libcore/result.rs:1188:5

What is the right way to implement this kind of world?

Similar question was Passing mutable self reference to method of owned object but I need more complex logic since an entity may modify the world or other entities. I even plan to hold generic traits so that some entities will have different logic.

I know why I got this error, my question is more about design-pattern.

Aucun commentaire:

Enregistrer un commentaire