我认为这里的问题是我们在view(..)内部使用该函数作为回调来绘制图形。因此,最低限度的设置如下所示:
fn main() {
nannou::sketch(view);
}
fn view(app: &App, frame: Frame) -> Frame {
// Draw stuff
}
但是你想传递数据,那么我们需要使用Model这样的:
fn main() {
nannou::app(model).update(update).run();
}
struct Model {
my_data: MyData,
}
fn model(app: &App) -> Model {
app
.new_window()
.with_dimensions(720, 720)
.view(view)
.build()
.unwrap();
let my_data = MyData::new();
Model { my_data }
}
fn update(_app: &App, _model: &mut Model, _update: Update) {}
fn view(app: &App, model: &Model, frame: Frame) -> Frame {
// Draw stuff
}
请注意,当这样设置时,视图函数具有不同的签名。它包括一个Model您可以将自己的数据放入其中。当您想在函数中更新它时它是不可变的,但如果需要update(),您可以解决这个问题。RefCell
我通常做的是从model()函数中启动我的其他线程,然后使用通道中的通道Model与nannou循环进行通信,例如:
fn model(app: &App) -> Model {
let (talk_to_nannou, data_from_my_thread) = mpsc::channel();
thread::spawn(|| {
//All the stuff I want to do
talk_to_nannou.send("Hey");
});
Model {
data_from_my_thread,
};
}
fn view(app: &App, model: &Model, frame: Frame) -> Frame {
if let Some(msg) = model.data_from_my_thread.try_recv() {
dbg!(msg);
}
}
如果您将它添加到这样的现有应用程序中,您可以用不同的方式来思考它:
fn main() {
// My awesome app that has heaps of cool stuff
thread::spawn(|| {
nannou::app(model).update(update).run();
});
// Do more stuff in my cool app
}
struct Model {
my_data: MyData,
}
fn model(app: &App) -> Model {
app.new_window()
.with_dimensions(720, 720)
.view(view)
.build()
.unwrap();
let my_data = MyData::new();
Model { my_data }
}
fn update(_app: &App, _model: &mut Model, _update: Update) {}
fn view(app: &App, model: &Model, frame: Frame) -> Frame {
// Draw stuff
}
然后你可以把所有的nannou东西塞进一个模块中,但这取决于你想如何安排事情。唯一的事情是,nannou 需要运行其内部循环来完成所有工作,但很高兴能在另一个线程上。
查看示例和指南以获取更多信息