2

我正在尝试使用 SFML 和 Rust 编写一个简单的游戏,但事实证明借用检查器是我在这段旅程中最大的敌人。

在很多情况下 SFML 需要引用另一个对象。在下面的代码中,我需要对 Font 的引用,否则 Text 不会向用户显示任何内容。

问题是,我已经尝试了很多东西,而引用本身的寿命却不够长。如果我在 draw 方法上创建 Text 对象,它显然可以工作,但我想避免在应用程序的主循环中创建东西。

这是我应该看看不安全操作的情况吗?是否有满足我需求的 Rc、RefCell、Box 等的组合?

如果可能的话,请尝试向我解释我应该做什么以及我目前的心态有什么问题。

extern crate sfml;

use sfml::system::{ Clock, Vector2f };
use sfml::graphics::{ Color, Font, RenderTarget, RenderWindow, Text, Transformable };

pub struct FpsMeter<'a> {
    position: Vector2f,
    clock:    Clock,
    value:    f32,

    text:     Text<'a>
}

impl<'a> FpsMeter<'a> {
    pub fn new() -> Self {
        let font = match Font::new_from_file("assets/sansation.ttf") {
            Some(fnt) => fnt,
            None      => panic!("Cannot open resource: sansation.ttf"),
        };

        let mut text = Text::new_init(
            &format!("FPS: {}", 0),
            &font,
            20  
        ).expect("Could not create text");

        FpsMeter {
            position: Vector2f::new(0., 0.),
            clock:    Clock::new(),
            value:    0.,

            text: text,
        }
    }

    pub fn set_position2f(&mut self, x: f32, y: f32) {
        self.position.x = x;
        self.position.y = y;
    }

    pub fn restart(&mut self) {
        self.value = 1. / self.clock.restart().as_seconds();
    }

    pub fn draw(&mut self, window: &mut RenderWindow) {
        self.text.set_position(&self.position);
        self.text.set_color(&Color::white());

        window.draw(&self.text);
    }
}
4

1 回答 1

2

我不熟悉 rust-sfml,所以我可能误读了您的问题,但它应该看起来像这样。您有一个Fontand Text(您无法控制,它们是由库为您构建的),其中Text包含对Font. 简化:

struct Font;
struct Text<'a> { font: &'a Font }

然后你有一个FpsMeter(你可以控制的)有一个Text字段。再次简化:

struct FpsMeter<'a> {
    text: Text<'a>
}

现在,如果是这种情况,我认为您不能在创建的相同方法中创建Text(或至少) ,因为对构造函数的堆栈框架的引用无法转义。您需要将预先构建的内容传递给您的构造函数。例如:FontFpsMeterFontText

impl<'a> FpsMeter<'a> {
    fn new(txt: Text<'a>) -> FpsMeter<'a> {
        FpsMeter { text: txt }
    } 
}

或者可能:

impl<'a> FpsMeter<'a> {
    fn new(fnt: &'a Font) -> FpsMeter<'a> {
        FpsMeter { text: Text { font: fnt } }
    } 
}

操场上的玩具示例

于 2016-01-07T16:24:17.890 回答