首页 > 解决方案 > 借用 GameMaster (self) 到 GameState

问题描述

我对 Rust 还很陌生,我一直在尝试使用ggez 制作一个简单的游戏。

现在,通常在 C++ 或 C# 中,我会围绕一个“主”类的实例来构建我的游戏,该实例负责设置、帧限制、窗口创建、事件处理等,以及由主类持有的“状态”类. 在创建状态类(类似于game_master*)时,我会传递一个指向主类的指针,以便状态类可以访问主类的资源。

在 Rust 中我不能通过 a&mut self因为状态可能比引用更长寿。

pub fn new(_ctx: &mut Context) -> GameMaster {
    let game = GameMaster {
        state: None,
        pending_state: None
    };

    game.state = Some(Box::new(TestState::new_with_master(&mut game))) <----- NOPE
    game
}

我认为这可以通过生命周期来解决,但我还没有找到一种方法让生命周期与特征一起工作。在每个函数调用中将 master 作为引用传递也不起作用,因为一次只能保存一个可变引用。

fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
    if self.state.is_some() {
        (*self.state.as_mut().unwrap()).update(ctx, &mut self) <----- NOPE
    } 
    else {
        Ok(())
    }
}

在 Rust 中没有好的方法可以做到这一点吗?

标签: rustgame-engine2d-gamesgame-development

解决方案


不久前我有一个类似的问题,但我认为唯一的选择是:

  1. Rc<RefCell<>>到处使用。Weak如果您需要对这些对象进行垃圾收集,请记住还要使用或添加特殊的销毁方法,因为它们相互引用。

  2. 使用原始指针和不安全的代码。问题在于,如果使用不安全的尊重,RefCell除了生命周期检查之外,您还会丢失可变性检查(确保一次只存在一个可变引用)。


推荐阅读