Skip to main content

widgetkit_runtime/
context.rs

1use crate::{internal::RuntimeServices, scheduler::Scheduler, tasks::Tasks, widget::Widget};
2use std::{marker::PhantomData, ptr::NonNull};
3use widgetkit_core::{InstanceId, Size, WidgetId};
4
5pub struct MountCtx<W>
6where
7    W: Widget,
8{
9    widget_id: WidgetId,
10    instance_id: InstanceId,
11    _marker: PhantomData<fn() -> W>,
12}
13
14impl<W> MountCtx<W>
15where
16    W: Widget,
17{
18    pub(crate) fn new(widget_id: WidgetId, instance_id: InstanceId) -> Self {
19        Self {
20            widget_id,
21            instance_id,
22            _marker: PhantomData,
23        }
24    }
25
26    pub fn widget_id(&self) -> WidgetId {
27        self.widget_id
28    }
29
30    pub fn instance_id(&self) -> InstanceId {
31        self.instance_id
32    }
33}
34
35pub struct StartCtx<W>
36where
37    W: Widget,
38{
39    widget_id: WidgetId,
40    instance_id: InstanceId,
41    services: NonNull<RuntimeServices<W::Message>>,
42    _marker: PhantomData<fn() -> W>,
43}
44
45impl<W> StartCtx<W>
46where
47    W: Widget,
48{
49    pub(crate) fn new(
50        widget_id: WidgetId,
51        instance_id: InstanceId,
52        services: NonNull<RuntimeServices<W::Message>>,
53    ) -> Self {
54        Self {
55            widget_id,
56            instance_id,
57            services,
58            _marker: PhantomData,
59        }
60    }
61
62    pub fn widget_id(&self) -> WidgetId {
63        self.widget_id
64    }
65
66    pub fn instance_id(&self) -> InstanceId {
67        self.instance_id
68    }
69
70    pub fn post(&mut self, message: W::Message) {
71        let services = self.services_mut();
72        let _ = services.dispatcher.post_message(message);
73    }
74
75    /// Marks the current frame dirty and wakes the host if this is the first pending redraw.
76    ///
77    /// Repeated calls before the host consumes the pending frame are coalesced into one redraw.
78    pub fn request_render(&mut self) {
79        let services = self.services_mut();
80        if services.request_render() {
81            services.dispatcher.wake.wake();
82        }
83    }
84
85    /// Returns the scheduler owned by the current widget instance.
86    /// All timers created here are cleared when the instance stops or is disposed.
87    pub fn scheduler(&mut self) -> Scheduler<'_, W::Message> {
88        let services = self.services_mut();
89        Scheduler::new(&mut services.scheduler, services.dispatcher.clone())
90    }
91
92    /// Returns the task backend owned by the current widget instance.
93    /// All tasks created here are canceled when the instance stops or is disposed.
94    pub fn tasks(&mut self) -> Tasks<'_, W::Message> {
95        let services = self.services_mut();
96        Tasks::new(services.tasks.as_mut())
97    }
98
99    fn services_mut(&mut self) -> &mut RuntimeServices<W::Message> {
100        unsafe { self.services.as_mut() }
101    }
102}
103
104pub struct UpdateCtx<W>
105where
106    W: Widget,
107{
108    widget_id: WidgetId,
109    instance_id: InstanceId,
110    services: NonNull<RuntimeServices<W::Message>>,
111    _marker: PhantomData<fn() -> W>,
112}
113
114impl<W> UpdateCtx<W>
115where
116    W: Widget,
117{
118    pub(crate) fn new(
119        widget_id: WidgetId,
120        instance_id: InstanceId,
121        services: NonNull<RuntimeServices<W::Message>>,
122    ) -> Self {
123        Self {
124            widget_id,
125            instance_id,
126            services,
127            _marker: PhantomData,
128        }
129    }
130
131    pub fn widget_id(&self) -> WidgetId {
132        self.widget_id
133    }
134
135    pub fn instance_id(&self) -> InstanceId {
136        self.instance_id
137    }
138
139    pub fn post(&mut self, message: W::Message) {
140        let services = self.services_mut();
141        let _ = services.dispatcher.post_message(message);
142    }
143
144    /// Marks the current frame dirty and wakes the host if this is the first pending redraw.
145    ///
146    /// Repeated calls before the host consumes the pending frame are coalesced into one redraw.
147    pub fn request_render(&mut self) {
148        let services = self.services_mut();
149        if services.request_render() {
150            services.dispatcher.wake.wake();
151        }
152    }
153
154    /// Returns the scheduler owned by the current widget instance.
155    /// All timers created here are cleared when the instance stops or is disposed.
156    pub fn scheduler(&mut self) -> Scheduler<'_, W::Message> {
157        let services = self.services_mut();
158        Scheduler::new(&mut services.scheduler, services.dispatcher.clone())
159    }
160
161    /// Returns the task backend owned by the current widget instance.
162    /// All tasks created here are canceled when the instance stops or is disposed.
163    pub fn tasks(&mut self) -> Tasks<'_, W::Message> {
164        let services = self.services_mut();
165        Tasks::new(services.tasks.as_mut())
166    }
167
168    fn services_mut(&mut self) -> &mut RuntimeServices<W::Message> {
169        unsafe { self.services.as_mut() }
170    }
171}
172
173pub struct RenderCtx<W>
174where
175    W: Widget,
176{
177    widget_id: WidgetId,
178    instance_id: InstanceId,
179    surface_size: Size,
180    _marker: PhantomData<fn() -> W>,
181}
182
183impl<W> RenderCtx<W>
184where
185    W: Widget,
186{
187    pub(crate) fn new(widget_id: WidgetId, instance_id: InstanceId, surface_size: Size) -> Self {
188        Self {
189            widget_id,
190            instance_id,
191            surface_size,
192            _marker: PhantomData,
193        }
194    }
195
196    pub fn widget_id(&self) -> WidgetId {
197        self.widget_id
198    }
199
200    pub fn instance_id(&self) -> InstanceId {
201        self.instance_id
202    }
203
204    pub fn surface_size(&self) -> Size {
205        self.surface_size
206    }
207}
208
209pub struct StopCtx<W>
210where
211    W: Widget,
212{
213    widget_id: WidgetId,
214    instance_id: InstanceId,
215    services: NonNull<RuntimeServices<W::Message>>,
216    _marker: PhantomData<fn() -> W>,
217}
218
219impl<W> StopCtx<W>
220where
221    W: Widget,
222{
223    pub(crate) fn new(
224        widget_id: WidgetId,
225        instance_id: InstanceId,
226        services: NonNull<RuntimeServices<W::Message>>,
227    ) -> Self {
228        Self {
229            widget_id,
230            instance_id,
231            services,
232            _marker: PhantomData,
233        }
234    }
235
236    pub fn widget_id(&self) -> WidgetId {
237        self.widget_id
238    }
239
240    pub fn instance_id(&self) -> InstanceId {
241        self.instance_id
242    }
243
244    /// Returns the scheduler owned by the current widget instance.
245    /// All timers created here are cleared when the instance stops or is disposed.
246    pub fn scheduler(&mut self) -> Scheduler<'_, W::Message> {
247        let services = self.services_mut();
248        Scheduler::new(&mut services.scheduler, services.dispatcher.clone())
249    }
250
251    /// Returns the task backend owned by the current widget instance.
252    /// All tasks created here are canceled when the instance stops or is disposed.
253    pub fn tasks(&mut self) -> Tasks<'_, W::Message> {
254        let services = self.services_mut();
255        Tasks::new(services.tasks.as_mut())
256    }
257
258    fn services_mut(&mut self) -> &mut RuntimeServices<W::Message> {
259        unsafe { self.services.as_mut() }
260    }
261}
262
263pub struct DisposeCtx<W>
264where
265    W: Widget,
266{
267    widget_id: WidgetId,
268    instance_id: InstanceId,
269    _marker: PhantomData<fn() -> W>,
270}
271
272impl<W> DisposeCtx<W>
273where
274    W: Widget,
275{
276    pub(crate) fn new(widget_id: WidgetId, instance_id: InstanceId) -> Self {
277        Self {
278            widget_id,
279            instance_id,
280            _marker: PhantomData,
281        }
282    }
283
284    pub fn widget_id(&self) -> WidgetId {
285        self.widget_id
286    }
287
288    pub fn instance_id(&self) -> InstanceId {
289        self.instance_id
290    }
291}