relm4/component/sync/
controller.rs

1// Copyright 2021-2022 Aaron Erhardt <aaron.erhardt@t-online.de>
2// Copyright 2022 System76 <info@system76.com>
3// SPDX-License-Identifier: MIT or Apache-2.0
4
5use std::cell::Ref;
6use std::fmt::{self, Debug};
7
8use crate::Sender;
9
10use super::{Component, StateWatcher};
11
12/// Shared behavior of component controller types.
13pub trait ComponentController<C: Component> {
14    /// Emits an input to the component.
15    fn emit(&self, event: C::Input) {
16        self.sender().send(event).unwrap();
17    }
18
19    /// Provides access to the component's sender.
20    fn sender(&self) -> &Sender<C::Input>;
21
22    /// Provides access to the state of a component.
23    fn state(&self) -> &StateWatcher<C>;
24
25    /// Returns a reference to the [`Component`].
26    fn model(&self) -> Ref<'_, C> {
27        let part_ref = self.state().get();
28        Ref::map(part_ref, |part| &part.model)
29    }
30
31    /// Returns a reference to the [`Component::Widgets`].
32    fn widgets(&self) -> Ref<'_, C::Widgets> {
33        let part_ref = self.state().get();
34        Ref::map(part_ref, |part| &part.widgets)
35    }
36
37    /// Returns the root widget of the component.
38    fn widget(&self) -> &C::Root;
39
40    /// Dropping this type will usually stop the runtime of the component.
41    /// With this method you can give the runtime a static lifetime.
42    /// In other words, dropping the controller or connector will not stop
43    /// the runtime anymore, instead it will run until the app is closed.
44    fn detach_runtime(&mut self);
45}
46
47/// Controls the component from afar.
48pub struct Controller<C: Component> {
49    /// The models and widgets maintained by the component.
50    pub(super) state: StateWatcher<C>,
51
52    /// The widget that this component manages.
53    pub(super) widget: C::Root,
54
55    /// Used for emitting events to the component.
56    pub(super) sender: Sender<C::Input>,
57}
58
59impl<C: Component> ComponentController<C> for Controller<C> {
60    fn sender(&self) -> &Sender<C::Input> {
61        &self.sender
62    }
63
64    fn state(&self) -> &StateWatcher<C> {
65        &self.state
66    }
67
68    fn widget(&self) -> &C::Root {
69        &self.widget
70    }
71
72    fn detach_runtime(&mut self) {
73        self.state.detach_runtime();
74    }
75}
76
77impl<C> Debug for Controller<C>
78where
79    C: Component + Debug,
80    C::Widgets: Debug,
81{
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        f.debug_struct("Controller")
84            .field("state", &self.state)
85            .field("widget", &self.widget)
86            .field("sender", &self.sender)
87            .finish()
88    }
89}