![](/img/trans.png)
[英]How does one use FLTK library using Bjarne's GUI's header file in his book Programming principles and practices?
[英]Global application state with FLTK library
我正在使用 fltk 庫編寫應用程序。 該應用程序的架構涉及一個全局 state,它存儲現在顯示哪個頁面(查看器)並存儲查看器數據。 有一些按鈕可以發送消息來更新和更改全局 state,指示現在顯示哪個查看器。
#[derive(Clone, Copy)]
enum Message {
Update
}
#[derive(Clone, Copy)]
struct GlobalState {
viewer: Viewer,
}
impl GlobalState {
fn set_viewer(&mut self, v: Viewer) {
self.viewer = v;
}
}
#[derive(Clone, Copy)]
enum Viewer {
Page1,
Page2
}
fn main() {
let mut gs = GlobalState {viewer: Viewer::Page1};
let app = app::App::default().with_scheme(app::Scheme::Gtk);
let (s, r) = app::channel::<Message>();
let mut wind = Window::default().with_size(800, 600);
left_side(&mut gs);
let mut col = Column::new(155,70,800 - 150,600 - 65,None);
s.send(Message::Update);
col.end();
wind.end();
wind.show();
while app.wait() {
if let Some(msg) = r.recv() {
match msg {
Message::Update => {
match gs.viewer {
Viewer::Page1 => {
col.clear();
let view = view_ohm();
col.add(&view);
},
Viewer::Page2 => {
col.clear();
let view = view_ohm();
col.add(&view);
},
_ => ()
}
}
_ => (),
}
}
}
}
fn left_side(gs: &mut GlobalState) {
let btn_width = 130;
let btn_height = 30;
let (s, r) = app::channel::<Message>();
let mut grp = Group::default().with_size(65, 600);
let mut col = Pack::default()
.with_size(btn_width, 600)
.center_of_parent()
.with_type(PackType::Vertical);
col.set_spacing(2);
let mut btn = Button::new(0, 0, btn_width, btn_height, "Page 1");
btn.emit(s, Message::Update);
btn.set_callback(|_| {
gs.set_viewer(Viewer::Page1)
});
let mut btn = Button::new(0, 0, btn_width, btn_height, "Page 2");
btn.emit(s, Message::Update);
btn.set_callback(|_| {
gs.set_viewer(Viewer::Page2)
});
col.end();
grp.end();
}
問題:
error[E0521]: borrowed data escapes outside of function
--> src/main.rs:89:5
|
74 | fn left_side(gs: &mut GlobalState) {
| -- - let's call the lifetime of this reference `'1`
| |
| `gs` is a reference that is only valid in the function body
...
89 | / btn.set_callback(|_| {
90 | | gs.set_viewer(Viewer::Page1)
91 | | });
| | ^
| | |
| |______`gs` escapes the function body here
| argument requires that `'1` must outlive `'static`
error[E0524]: two closures require unique access to `*gs` at the same time
--> src/main.rs:95:22
|
89 | btn.set_callback(|_| {
| - --- first closure is constructed here
| _____|
| |
90 | | gs.set_viewer(Viewer::Page1)
| | -- first borrow occurs due to use of `*gs` in closure
91 | | });
| |______- argument requires that `*gs` is borrowed for `'static`
...
95 | btn.set_callback(|_| {
| ^^^ second closure is constructed here
96 | gs.set_viewer(Viewer::Page2)
| -- second borrow occurs due to use of `*gs` in closure
我的應用程序架構有效還是有更好的架構? 該應用程序有多個頁面(一頁一個查看器),每個查看器都有自己的全局 state 和存儲在其中並處理這些數據的數據。
在全局 state 中存儲觀眾數據的最佳方式是什么?
此代碼將您的 GlobalState 包裝在Rc<RefCell<GlobalState>>
中:
#[derive(Clone, Copy)]
enum Message {
Update
}
#[derive(Clone, Copy)]
struct GlobalState {
viewer: Viewer,
}
impl GlobalState {
fn set_viewer(&mut self, v: Viewer) {
self.viewer = v;
}
}
#[derive(Clone, Copy)]
enum Viewer {
Page1,
Page2
}
fn main() {
let mut gs = Rc::new(RefCell::new(GlobalState {viewer: Viewer::Page1}));
let app = app::App::default().with_scheme(app::Scheme::Gtk);
let (s, r) = app::channel::<Message>();
let mut wind = Window::default().with_size(800, 600);
left_side(gs.clone());
let mut col = Column::new(155,70,800 - 150,600 - 65,None);
col.end();
wind.end();
wind.show();
while app.wait() {
if let Some(msg) = r.recv() {
match msg {
Message::Update => {
let gs = gs.borrow();
match gs.viewer {
Viewer::Page1 => {
col.clear();
let view = view_ohm();
col.add(&view);
},
Viewer::Page2 => {
col.clear();
let view = view_ohm();
col.add(&view);
},
_ => ()
}
}
_ => (),
}
}
}
}
fn left_side(gs: Rc<RefCell<GlobalState>>) {
let btn_width = 130;
let btn_height = 30;
let s = app::Sender::get();
let mut grp = Group::default().with_size(65, 600);
let mut col = Pack::default()
.with_size(btn_width, 600)
.center_of_parent()
.with_type(PackType::Vertical);
col.set_spacing(2);
let mut btn = Button::new(0, 0, btn_width, btn_height, "Page 1");
btn.set_callback({
let gs = gs.clone();
move |_| {
gs.borrow_mut().set_viewer(Viewer::Page1);
s.send(Message::Update);
}});
let mut btn = Button::new(0, 0, btn_width, btn_height, "Page 2");
btn.set_callback(move |_| {
gs.borrow_mut().set_viewer(Viewer::Page2);
s.send(Message::Update);
});
col.end();
grp.end();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.