Why isn't this #[watch] of a SharedState variable working? #617
-
I have an application with some global state: # global.rs
use relm4::SharedState;
use std::collections::BTreeMap;
pub(crate) static TEST_STATE: SharedState<BTreeMap<u32, &str>> = SharedState::new(); I reference this variable in the main component: # main.rs
use other_view::OtherView;
use rand::Rng;
use relm4::gtk;
use relm4::gtk::prelude::ButtonExt;
use relm4::gtk::prelude::OrientableExt;
use relm4::Component;
use relm4::ComponentController;
use relm4::ComponentParts;
use relm4::ComponentSender;
use relm4::Controller;
use relm4::RelmApp;
use relm4::RelmWidgetExt;
use relm4::SimpleComponent;
use std::ops::{Deref, DerefMut};
use crate::globals::TEST_STATE;
mod globals;
mod other_view;
#[derive(Debug)]
enum AppInMsg {
DummyMsg,
ModifyRequested,
}
#[derive(Debug)]
struct App {
other_view: Controller<OtherView>,
}
#[relm4::component]
impl SimpleComponent for App {
type Init = ();
type Input = AppInMsg;
type Output = ();
view! {
#[root]
gtk::ApplicationWindow {
gtk::Box {
set_margin_all: 50,
set_orientation: gtk::Orientation::Vertical,
gtk::Label {
#[watch]
set_text: &format!("Test state: {:?}", TEST_STATE.read().deref()),
},
model.other_view.widget(),
gtk::Button {
set_label: "Modify",
connect_clicked => AppInMsg::ModifyRequested,
}
}
}
}
fn init(
_: Self::Init,
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let other_view = OtherView::builder()
.launch(())
.forward(sender.input_sender(), |_| Self::Input::DummyMsg);
let model = App { other_view };
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
let mut rng = rand::thread_rng();
match message {
AppInMsg::DummyMsg => {}
AppInMsg::ModifyRequested => {
println!("New value is {:?}", *TEST_STATE.read());
(*TEST_STATE.write().deref_mut()).insert(rng.gen(), "test");
}
}
}
}
fn main() {
let app = RelmApp::new("com.example.test");
app.run::<App>(());
} As you can see the main window also contains a separate widget: # other_view.rs
use crate::globals::TEST_STATE;
use relm4::gtk;
use relm4::SimpleComponent;
use relm4::{ComponentParts, ComponentSender};
use std::ops::Deref;
#[derive(Debug)]
pub struct OtherView {}
#[relm4::component(pub)]
impl SimpleComponent for OtherView {
type Init = ();
type Input = ();
type Output = ();
view! {
#[root]
gtk::Label {
#[watch]
set_text: &format!("Other test state: {:?}", TEST_STATE.read().deref()),
}
}
fn init(
_: Self::Init,
root: &Self::Root,
_sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = OtherView {};
let widgets = view_output!();
ComponentParts { model, widgets }
}
} My question is: how come TEST_STATE's state changes propagate in |
Beta Was this translation helpful? Give feedback.
Answered by
AaronErhardt
Mar 12, 2024
Replies: 1 comment 1 reply
-
|
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
pieterdd
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
#[watch]
updates the property every time a components receives a message (input or command).SharedState
does not send a message to your component unless you subscribe, so the property isn't updated.