0

我正在尝试制作一个粘贴在样板代码中的宏,然后我想使用它粘贴的变量。Rust 的宏观卫生正在防止这种情况发生;我该如何关闭它?

我知道有一些方法可以解决它,通过将所有变量传递给宏,但这会使宏无用......我发现了一个名为 unhygienic 的箱子,它说它就是这样做的,但我无法得到它工作。

这就是它应该如何工作的方式。这是您可以在 Java 或 JavaScript 中使用处理(绘图/图形框架)的方式(这将显示一辆移动的汽车(在一个Car类中定义)和一个矩形:

// You need to add a library or use the pde to be able to make this work though

let car;

setup() {
    createCanvas(500, 100);
    frameRate(60);
    car = new Car();
}

draw() {
    car.move();
    car.show();

    // this draws a rectangle at a certain place
    rect(100, 200, 200, 100)
}

setup是你在主循环之前所做的draw一切,也是你在循环内所做的一切。这就是我希望它在 Rust 中的样子(绝对不需要,只是为了美观):

//does all the boilerplate opengl setup. 
setup!{
    // setting my variables and settings
}

// // adds a loop around the code in it and keeps up the framerate etc
draw!{
    // do my updating and drawing commands
}
4

1 回答 1

1

尝试使用特征!这显示了如何实现此功能的大致轮廓:

操场

// Library:
mod library {
    pub trait Program {
        fn setup(ctx: &mut Context) -> Self;
        fn draw(&mut self, ctx: &mut Context);
    }

    pub struct Context;

    impl Context {
        pub fn create_canvas(&mut self, width: usize, height: usize) {
            // ...
        }

        pub fn frame_rate(&mut self, fps: usize) {
            // ...
        }

        pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize) {
            // ...
        }
    }

    pub fn run_program<P: Program>() {
        let ctx = Context;
        let program = P::setup(&mut ctx);

        loop {
            program.draw(&mut ctx);
        }
    }
}

// User:
use library::{Context, Program};

struct Car;

impl Car {
    // `move` is a reserved keyword
    fn move_pos(&mut self, ctx: &mut Context) {
        // ...
    }

    fn show(&mut self, ctx: &mut Context) {
        // ...
    }
}

struct MyProgram {
    car: Car,
}

impl Program for MyProgram {
    fn setup(ctx: &mut Context) -> Self {
        ctx.create_canvas(500, 100);
        ctx.frame_rate(60);

        Self { car: Car }
    }

    fn draw(&mut self, ctx: &mut Context) {
        self.car.move_pos(ctx);
        self.car.show(ctx);

        // this draws a rectangle at a certain place
        ctx.rect(100, 200, 200, 100)
    }
}

fn main() {
    library::run_program::<MyProgram>();
}

我知道到处走动有点麻烦ctx,但这是值得的,因为您不必担心使用 a Rc<RefCell<...>>(多线程可能会变得更加复杂)以确保对共享上下文的唯一访问通过缓慢的、运行时检查的内存管理。您可以同时运行多个程序,每个程序都有自己的上下文,并且您知道在任何给定时间,最多有一个函数正在写入上下文。

于 2020-08-17T17:18:57.630 回答