1use std::marker::PhantomData;
2
3use abi_stable::{
4 StableAbi, sabi_trait,
5 sabi_trait::TD_Opaque,
6 std_types::{RBox, ROption, RResult, RStr, RString, RVec},
7};
8
9use crate::{
10 event::{Args, Event, EventFilter, ItemEffect, Message},
11 host::Context,
12 payload::PayloadBox,
13 types::{
14 DesktopSettings, DisplayStyle, Node, QuickSettingsTile, RenderableSettings, SpotlightResult,
15 },
16};
17
18pub trait Component: Send + 'static {
19 fn new(ctx: &Context<'_>) -> Self;
20 fn events(&self) -> RVec<EventFilter> {
21 RVec::new()
22 }
23 fn foreground_services(&self) -> RVec<RString> {
24 RVec::new()
25 }
26 fn watch(&mut self, _ctx: &Context<'_>) {}
27 fn update(&mut self, _ctx: &Context<'_>, _event: &Event) -> ItemEffect {
28 ItemEffect::None
29 }
30 fn check_view(&self, _ctx: &Context<'_>) -> bool {
31 true
32 }
33 fn hoverable() -> bool {
34 true
35 }
36 fn stop(&mut self, _ctx: &Context<'_>) {}
37 fn view(&self, ctx: &Context<'_>) -> Node;
38}
39
40#[sabi_trait]
41pub trait ComponentObject: Send + 'static {
42 fn events(&self) -> RVec<EventFilter>;
43 fn foreground_services(&self) -> RVec<RString>;
44 fn watch(&mut self, ctx: &Context<'_>);
45 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect;
46 fn check_view(&self, ctx: &Context<'_>) -> bool;
47 fn stop(&mut self, ctx: &Context<'_>);
48 fn view(&self, ctx: &Context<'_>) -> Node;
49}
50
51pub type ComponentObjectBox = ComponentObject_TO<RBox<()>>;
52
53#[sabi_trait]
54pub trait ComponentFactory: Send + Sync + 'static {
55 fn create(&self, ctx: &Context<'_>) -> ComponentObjectBox;
56 fn hoverable(&self) -> bool;
57}
58
59pub type ComponentFactoryBox = ComponentFactory_TO<RBox<()>>;
60
61struct ComponentAdapter<T>(T);
62
63impl<T: Component> ComponentObject for ComponentAdapter<T> {
64 fn events(&self) -> RVec<EventFilter> {
65 self.0.events()
66 }
67
68 fn foreground_services(&self) -> RVec<RString> {
69 self.0.foreground_services()
70 }
71
72 fn watch(&mut self, ctx: &Context<'_>) {
73 self.0.watch(ctx);
74 }
75
76 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect {
77 self.0.update(ctx, event)
78 }
79
80 fn check_view(&self, ctx: &Context<'_>) -> bool {
81 self.0.check_view(ctx)
82 }
83
84 fn stop(&mut self, ctx: &Context<'_>) {
85 self.0.stop(ctx);
86 }
87
88 fn view(&self, ctx: &Context<'_>) -> Node {
89 self.0.view(ctx)
90 }
91}
92
93struct ComponentFactoryImpl<T>(PhantomData<fn() -> T>);
94
95impl<T: Component> ComponentFactory for ComponentFactoryImpl<T> {
96 fn create(&self, ctx: &Context<'_>) -> ComponentObjectBox {
97 ComponentObjectBox::from_value(ComponentAdapter(T::new(ctx)), TD_Opaque)
98 }
99
100 fn hoverable(&self) -> bool {
101 T::hoverable()
102 }
103}
104
105pub fn component_factory<T: Component>() -> ComponentFactoryBox {
106 ComponentFactoryBox::from_value(ComponentFactoryImpl::<T>(PhantomData), TD_Opaque)
107}
108
109pub trait Renderable: Send + 'static {
110 fn new(ctx: &Context<'_>) -> Self;
111 fn settings(&self) -> RenderableSettings {
112 RenderableSettings::default()
113 }
114 fn events(&self) -> RVec<EventFilter> {
115 RVec::new()
116 }
117 fn initialize(&mut self, _ctx: &Context<'_>) {}
118 fn update(&mut self, _ctx: &Context<'_>) -> ItemEffect {
119 ItemEffect::None
120 }
121 fn on_event(&mut self, _ctx: &Context<'_>, _event: &Event) -> ItemEffect {
122 ItemEffect::None
123 }
124 fn handle_message(&mut self, _ctx: &Context<'_>, _message: &Message) -> ItemEffect {
125 ItemEffect::None
126 }
127 fn view(&self, ctx: &Context<'_>) -> Node;
128}
129
130#[sabi_trait]
131pub trait RenderableObject: Send + 'static {
132 fn settings(&self) -> RenderableSettings;
133 fn events(&self) -> RVec<EventFilter>;
134 fn initialize(&mut self, ctx: &Context<'_>);
135 fn update(&mut self, ctx: &Context<'_>) -> ItemEffect;
136 fn on_event(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect;
137 fn handle_message(&mut self, ctx: &Context<'_>, message: &Message) -> ItemEffect;
138 fn view(&self, ctx: &Context<'_>) -> Node;
139}
140
141pub type RenderableObjectBox = RenderableObject_TO<RBox<()>>;
142
143#[sabi_trait]
144pub trait RenderableFactory: Send + Sync + 'static {
145 fn create(&self, ctx: &Context<'_>) -> RenderableObjectBox;
146}
147
148pub type RenderableFactoryBox = RenderableFactory_TO<RBox<()>>;
149
150struct RenderableAdapter<T>(T);
151
152impl<T: Renderable> RenderableObject for RenderableAdapter<T> {
153 fn settings(&self) -> RenderableSettings {
154 self.0.settings()
155 }
156
157 fn events(&self) -> RVec<EventFilter> {
158 self.0.events()
159 }
160
161 fn initialize(&mut self, ctx: &Context<'_>) {
162 self.0.initialize(ctx);
163 }
164
165 fn update(&mut self, ctx: &Context<'_>) -> ItemEffect {
166 self.0.update(ctx)
167 }
168
169 fn on_event(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect {
170 self.0.on_event(ctx, event)
171 }
172
173 fn handle_message(&mut self, ctx: &Context<'_>, message: &Message) -> ItemEffect {
174 self.0.handle_message(ctx, message)
175 }
176
177 fn view(&self, ctx: &Context<'_>) -> Node {
178 self.0.view(ctx)
179 }
180}
181
182struct RenderableFactoryImpl<T>(PhantomData<fn() -> T>);
183
184impl<T: Renderable> RenderableFactory for RenderableFactoryImpl<T> {
185 fn create(&self, ctx: &Context<'_>) -> RenderableObjectBox {
186 RenderableObjectBox::from_value(RenderableAdapter(T::new(ctx)), TD_Opaque)
187 }
188}
189
190pub fn renderable_factory<T: Renderable>() -> RenderableFactoryBox {
191 RenderableFactoryBox::from_value(RenderableFactoryImpl::<T>(PhantomData), TD_Opaque)
192}
193
194pub trait Payload: Send + 'static {
195 fn new(ctx: &Context<'_>) -> Self;
196 fn invoke(&mut self, ctx: &Context<'_>, args: &Args, payload: ROption<&PayloadBox>);
197}
198
199#[sabi_trait]
200pub trait PayloadObject: Send + 'static {
201 fn invoke(&mut self, ctx: &Context<'_>, args: &Args, payload: ROption<&PayloadBox>);
202}
203
204pub type PayloadObjectBox = PayloadObject_TO<RBox<()>>;
205
206#[sabi_trait]
207pub trait PayloadFactory: Send + Sync + 'static {
208 fn create(&self, ctx: &Context<'_>) -> PayloadObjectBox;
209}
210
211pub type PayloadFactoryBox = PayloadFactory_TO<RBox<()>>;
212
213struct PayloadAdapter<T>(T);
214
215impl<T: Payload> PayloadObject for PayloadAdapter<T> {
216 fn invoke(&mut self, ctx: &Context<'_>, args: &Args, payload: ROption<&PayloadBox>) {
217 self.0.invoke(ctx, args, payload);
218 }
219}
220
221struct PayloadFactoryImpl<T>(PhantomData<fn() -> T>);
222
223impl<T: Payload> PayloadFactory for PayloadFactoryImpl<T> {
224 fn create(&self, ctx: &Context<'_>) -> PayloadObjectBox {
225 PayloadObjectBox::from_value(PayloadAdapter(T::new(ctx)), TD_Opaque)
226 }
227}
228
229pub fn payload_factory<T: Payload>() -> PayloadFactoryBox {
230 PayloadFactoryBox::from_value(PayloadFactoryImpl::<T>(PhantomData), TD_Opaque)
231}
232
233pub trait DesktopItem: Send + 'static {
234 fn new(ctx: &Context<'_>) -> Self;
235 fn settings(&self) -> DesktopSettings;
236 fn events(&self) -> RVec<EventFilter> {
237 RVec::new()
238 }
239 fn initialize(&mut self, _ctx: &Context<'_>) {}
240 fn update(&mut self, _ctx: &Context<'_>, _event: &Event) -> ItemEffect {
241 ItemEffect::None
242 }
243 fn view(&self, ctx: &Context<'_>) -> Node;
244 fn handle_message(&mut self, _ctx: &Context<'_>, _message: &Message) -> ItemEffect {
245 ItemEffect::None
246 }
247}
248
249#[sabi_trait]
250pub trait DesktopItemObject: Send + 'static {
251 fn settings(&self) -> DesktopSettings;
252 fn events(&self) -> RVec<EventFilter>;
253 fn initialize(&mut self, ctx: &Context<'_>);
254 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect;
255 fn view(&self, ctx: &Context<'_>) -> Node;
256 fn handle_message(&mut self, ctx: &Context<'_>, message: &Message) -> ItemEffect;
257}
258
259pub type DesktopItemObjectBox = DesktopItemObject_TO<RBox<()>>;
260
261#[sabi_trait]
262pub trait DesktopItemFactory: Send + Sync + 'static {
263 fn create(&self, ctx: &Context<'_>) -> DesktopItemObjectBox;
264}
265
266pub type DesktopItemFactoryBox = DesktopItemFactory_TO<RBox<()>>;
267
268struct DesktopItemAdapter<T>(T);
269
270impl<T: DesktopItem> DesktopItemObject for DesktopItemAdapter<T> {
271 fn settings(&self) -> DesktopSettings {
272 self.0.settings()
273 }
274
275 fn events(&self) -> RVec<EventFilter> {
276 self.0.events()
277 }
278
279 fn initialize(&mut self, ctx: &Context<'_>) {
280 self.0.initialize(ctx);
281 }
282
283 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> ItemEffect {
284 self.0.update(ctx, event)
285 }
286
287 fn view(&self, ctx: &Context<'_>) -> Node {
288 self.0.view(ctx)
289 }
290
291 fn handle_message(&mut self, ctx: &Context<'_>, message: &Message) -> ItemEffect {
292 self.0.handle_message(ctx, message)
293 }
294}
295
296struct DesktopItemFactoryImpl<T>(PhantomData<fn() -> T>);
297
298impl<T: DesktopItem> DesktopItemFactory for DesktopItemFactoryImpl<T> {
299 fn create(&self, ctx: &Context<'_>) -> DesktopItemObjectBox {
300 DesktopItemObjectBox::from_value(DesktopItemAdapter(T::new(ctx)), TD_Opaque)
301 }
302}
303
304pub fn desktop_item_factory<T: DesktopItem>() -> DesktopItemFactoryBox {
305 DesktopItemFactoryBox::from_value(DesktopItemFactoryImpl::<T>(PhantomData), TD_Opaque)
306}
307
308#[repr(C)]
309#[derive(StableAbi)]
310pub struct DeployedItem {
311 pub id: RString,
312 pub item: DesktopItemObjectBox,
313}
314
315impl DeployedItem {
316 pub fn new<T: DesktopItem>(ctx: &Context<'_>, id: impl Into<RString>) -> Self {
317 Self {
318 id: id.into(),
319 item: desktop_item_factory::<T>().create(ctx),
320 }
321 }
322}
323
324#[repr(C)]
325#[derive(StableAbi)]
326pub enum DeployResult {
327 None,
328 Deploy(RVec<DeployedItem>),
329 Destroy(RString),
330 Many(RVec<DeployResult>),
331}
332
333pub trait DeployableDesktopItem: Send + 'static {
334 fn new(ctx: &Context<'_>) -> Self;
335 fn events(&self) -> RVec<EventFilter> {
336 RVec::new()
337 }
338 fn deploy(&mut self, _ctx: &Context<'_>, _event: &Event) -> DeployResult {
339 DeployResult::None
340 }
341}
342
343#[sabi_trait]
344pub trait DeployableDesktopItemObject: Send + 'static {
345 fn events(&self) -> RVec<EventFilter>;
346 fn deploy(&mut self, ctx: &Context<'_>, event: &Event) -> DeployResult;
347}
348
349pub type DeployableDesktopItemObjectBox = DeployableDesktopItemObject_TO<RBox<()>>;
350
351#[sabi_trait]
352pub trait DeployableDesktopItemFactory: Send + Sync + 'static {
353 fn create(&self, ctx: &Context<'_>) -> DeployableDesktopItemObjectBox;
354}
355
356pub type DeployableDesktopItemFactoryBox = DeployableDesktopItemFactory_TO<RBox<()>>;
357
358struct DeployableDesktopItemAdapter<T>(T);
359
360impl<T: DeployableDesktopItem> DeployableDesktopItemObject for DeployableDesktopItemAdapter<T> {
361 fn events(&self) -> RVec<EventFilter> {
362 self.0.events()
363 }
364
365 fn deploy(&mut self, ctx: &Context<'_>, event: &Event) -> DeployResult {
366 self.0.deploy(ctx, event)
367 }
368}
369
370struct DeployableDesktopItemFactoryImpl<T>(PhantomData<fn() -> T>);
371
372impl<T: DeployableDesktopItem> DeployableDesktopItemFactory
373 for DeployableDesktopItemFactoryImpl<T>
374{
375 fn create(&self, ctx: &Context<'_>) -> DeployableDesktopItemObjectBox {
376 DeployableDesktopItemObjectBox::from_value(DeployableDesktopItemAdapter(T::new(ctx)), TD_Opaque)
377 }
378}
379
380pub fn deployable_desktop_item_factory<T: DeployableDesktopItem>() -> DeployableDesktopItemFactoryBox
381{
382 DeployableDesktopItemFactoryBox::from_value(
383 DeployableDesktopItemFactoryImpl::<T>(PhantomData),
384 TD_Opaque,
385 )
386}
387
388#[repr(C)]
389#[derive(StableAbi, Clone, Debug)]
390pub enum CompositorCommand {
391 FocusWorkspace(i32),
392 FocusWindow(u64),
393 CloseWindow(u64),
394 KillWindow(u64),
395 FocusMonitor(RString),
396 Custom(PayloadBox),
397}
398
399pub trait Compositor: Send + 'static {
400 fn new(ctx: &Context<'_>) -> Self;
401 fn is_active(&self) -> bool {
402 false
403 }
404 fn initialize(&mut self, _ctx: &Context<'_>) {}
405 fn update_state(&mut self, _ctx: &Context<'_>) {}
406 fn send_command(&mut self, _ctx: &Context<'_>, _command: &CompositorCommand) {}
407}
408
409#[sabi_trait]
410pub trait CompositorObject: Send + 'static {
411 fn is_active(&self) -> bool;
412 fn initialize(&mut self, ctx: &Context<'_>);
413 fn update_state(&mut self, ctx: &Context<'_>);
414 fn send_command(&mut self, ctx: &Context<'_>, command: &CompositorCommand);
415}
416
417pub type CompositorObjectBox = CompositorObject_TO<RBox<()>>;
418
419#[sabi_trait]
420pub trait CompositorFactory: Send + Sync + 'static {
421 fn create(&self, ctx: &Context<'_>) -> CompositorObjectBox;
422}
423
424pub type CompositorFactoryBox = CompositorFactory_TO<RBox<()>>;
425
426struct CompositorAdapter<T>(T);
427
428impl<T: Compositor> CompositorObject for CompositorAdapter<T> {
429 fn is_active(&self) -> bool {
430 self.0.is_active()
431 }
432
433 fn initialize(&mut self, ctx: &Context<'_>) {
434 self.0.initialize(ctx);
435 }
436
437 fn update_state(&mut self, ctx: &Context<'_>) {
438 self.0.update_state(ctx);
439 }
440
441 fn send_command(&mut self, ctx: &Context<'_>, command: &CompositorCommand) {
442 self.0.send_command(ctx, command);
443 }
444}
445
446struct CompositorFactoryImpl<T>(PhantomData<fn() -> T>);
447
448impl<T: Compositor> CompositorFactory for CompositorFactoryImpl<T> {
449 fn create(&self, ctx: &Context<'_>) -> CompositorObjectBox {
450 CompositorObjectBox::from_value(CompositorAdapter(T::new(ctx)), TD_Opaque)
451 }
452}
453
454pub fn compositor_factory<T: Compositor>() -> CompositorFactoryBox {
455 CompositorFactoryBox::from_value(CompositorFactoryImpl::<T>(PhantomData), TD_Opaque)
456}
457
458pub trait Spotlight: Send + 'static {
459 fn new(ctx: &Context<'_>) -> Self;
460 fn generate(&mut self, _ctx: &Context<'_>, _query: &str) -> Vec<SpotlightResult> {
461 Vec::new()
462 }
463 fn activate(&mut self, _ctx: &Context<'_>, _index: usize) {}
464 fn trigger_check(&self, _ctx: &Context<'_>, _query: &str) -> bool {
465 false
466 }
467 fn allows_triggers() -> bool {
468 false
469 }
470 fn display_styles() -> &'static [DisplayStyle] {
471 &[DisplayStyle::List]
472 }
473}
474
475#[sabi_trait]
476pub trait SpotlightObject: Send + 'static {
477 fn generate(&mut self, ctx: &Context<'_>, query: RStr<'_>) -> RVec<SpotlightResult>;
478 fn activate(&mut self, ctx: &Context<'_>, index: usize);
479 fn trigger_check(&self, ctx: &Context<'_>, query: RStr<'_>) -> bool;
480 fn allows_triggers(&self) -> bool;
481 fn display_styles(&self) -> u32;
482}
483
484pub type SpotlightObjectBox = SpotlightObject_TO<RBox<()>>;
485
486#[sabi_trait]
487pub trait SpotlightFactory: Send + Sync + 'static {
488 fn create(&self, ctx: &Context<'_>) -> SpotlightObjectBox;
489}
490
491pub type SpotlightFactoryBox = SpotlightFactory_TO<RBox<()>>;
492
493struct SpotlightAdapter<T>(T);
494
495impl<T: Spotlight> SpotlightObject for SpotlightAdapter<T> {
496 fn generate(&mut self, ctx: &Context<'_>, query: RStr<'_>) -> RVec<SpotlightResult> {
497 self.0.generate(ctx, &query).into()
498 }
499
500 fn activate(&mut self, ctx: &Context<'_>, index: usize) {
501 self.0.activate(ctx, index);
502 }
503
504 fn trigger_check(&self, ctx: &Context<'_>, query: RStr<'_>) -> bool {
505 self.0.trigger_check(ctx, &query)
506 }
507
508 fn allows_triggers(&self) -> bool {
509 T::allows_triggers()
510 }
511
512 fn display_styles(&self) -> u32 {
513 T::display_styles()
514 .iter()
515 .fold(0, |bits, style| bits | style.bit())
516 }
517}
518
519struct SpotlightFactoryImpl<T>(PhantomData<fn() -> T>);
520
521impl<T: Spotlight> SpotlightFactory for SpotlightFactoryImpl<T> {
522 fn create(&self, ctx: &Context<'_>) -> SpotlightObjectBox {
523 SpotlightObjectBox::from_value(SpotlightAdapter(T::new(ctx)), TD_Opaque)
524 }
525}
526
527pub fn spotlight_factory<T: Spotlight>() -> SpotlightFactoryBox {
528 SpotlightFactoryBox::from_value(SpotlightFactoryImpl::<T>(PhantomData), TD_Opaque)
529}
530
531pub trait QuickSettings: Send + 'static {
532 fn new(ctx: &Context<'_>) -> Self;
533 fn tiles(&self, _ctx: &Context<'_>) -> Vec<QuickSettingsTile> {
534 Vec::new()
535 }
536 fn children(&self, _ctx: &Context<'_>, _id: &str) -> Vec<QuickSettingsTile> {
537 Vec::new()
538 }
539}
540
541#[sabi_trait]
542pub trait QuickSettingsObject: Send + 'static {
543 fn tiles(&self, ctx: &Context<'_>) -> RVec<QuickSettingsTile>;
544 fn children(&self, ctx: &Context<'_>, id: RStr<'_>) -> RVec<QuickSettingsTile>;
545}
546
547pub type QuickSettingsObjectBox = QuickSettingsObject_TO<RBox<()>>;
548
549#[sabi_trait]
550pub trait QuickSettingsFactory: Send + Sync + 'static {
551 fn create(&self, ctx: &Context<'_>) -> QuickSettingsObjectBox;
552}
553
554pub type QuickSettingsFactoryBox = QuickSettingsFactory_TO<RBox<()>>;
555
556struct QuickSettingsAdapter<T>(T);
557
558impl<T: QuickSettings> QuickSettingsObject for QuickSettingsAdapter<T> {
559 fn tiles(&self, ctx: &Context<'_>) -> RVec<QuickSettingsTile> {
560 self.0.tiles(ctx).into()
561 }
562
563 fn children(&self, ctx: &Context<'_>, id: RStr<'_>) -> RVec<QuickSettingsTile> {
564 self.0.children(ctx, &id).into()
565 }
566}
567
568struct QuickSettingsFactoryImpl<T>(PhantomData<fn() -> T>);
569
570impl<T: QuickSettings> QuickSettingsFactory for QuickSettingsFactoryImpl<T> {
571 fn create(&self, ctx: &Context<'_>) -> QuickSettingsObjectBox {
572 QuickSettingsObjectBox::from_value(QuickSettingsAdapter(T::new(ctx)), TD_Opaque)
573 }
574}
575
576pub fn quick_settings_factory<T: QuickSettings>() -> QuickSettingsFactoryBox {
577 QuickSettingsFactoryBox::from_value(QuickSettingsFactoryImpl::<T>(PhantomData), TD_Opaque)
578}
579
580#[sabi_trait]
581pub trait ConfigParser: Send + Sync + 'static {
582 fn parse(
583 &self,
584 block: abi_stable::std_types::ROption<RStr<'_>>,
585 ) -> RResult<(), abi_stable::std_types::RString>;
586}
587
588pub type ConfigParserBox = ConfigParser_TO<RBox<()>>;
589
590pub trait Service: Send + 'static {
591 fn new(ctx: &Context<'_>) -> Self;
592 fn run(&mut self, ctx: &crate::host::ServiceContext<'_>);
593}
594
595#[sabi_trait]
596pub trait ServiceObject: Send + 'static {
597 fn run(&mut self, ctx: &crate::host::ServiceContext<'_>);
598}
599
600pub type ServiceObjectBox = ServiceObject_TO<RBox<()>>;
601
602#[sabi_trait]
603pub trait ServiceFactory: Send + Sync + 'static {
604 fn create(&self, ctx: &Context<'_>) -> ServiceObjectBox;
605}
606
607pub type ServiceFactoryBox = ServiceFactory_TO<RBox<()>>;
608
609struct ServiceAdapter<T>(T);
610
611impl<T: Service> ServiceObject for ServiceAdapter<T> {
612 fn run(&mut self, ctx: &crate::host::ServiceContext<'_>) {
613 self.0.run(ctx);
614 }
615}
616
617struct ServiceFactoryImpl<T>(PhantomData<fn() -> T>);
618
619impl<T: Service> ServiceFactory for ServiceFactoryImpl<T> {
620 fn create(&self, ctx: &Context<'_>) -> ServiceObjectBox {
621 ServiceObjectBox::from_value(ServiceAdapter(T::new(ctx)), TD_Opaque)
622 }
623}
624
625pub fn service_factory<T: Service>() -> ServiceFactoryBox {
626 ServiceFactoryBox::from_value(ServiceFactoryImpl::<T>(PhantomData), TD_Opaque)
627}
628
629pub trait ForegroundService: Send + 'static {
630 fn new(ctx: &Context<'_>) -> Self;
631 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> bool;
632}
633
634#[sabi_trait]
635pub trait ForegroundServiceObject: Send + 'static {
636 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> bool;
637}
638
639pub type ForegroundServiceObjectBox = ForegroundServiceObject_TO<RBox<()>>;
640
641#[sabi_trait]
642pub trait ForegroundServiceFactory: Send + Sync + 'static {
643 fn create(&self, ctx: &Context<'_>) -> ForegroundServiceObjectBox;
644}
645
646pub type ForegroundServiceFactoryBox = ForegroundServiceFactory_TO<RBox<()>>;
647
648struct ForegroundServiceAdapter<T>(T);
649
650impl<T: ForegroundService> ForegroundServiceObject for ForegroundServiceAdapter<T> {
651 fn update(&mut self, ctx: &Context<'_>, event: &Event) -> bool {
652 self.0.update(ctx, event)
653 }
654}
655
656struct ForegroundServiceFactoryImpl<T>(PhantomData<fn() -> T>);
657
658impl<T: ForegroundService> ForegroundServiceFactory for ForegroundServiceFactoryImpl<T> {
659 fn create(&self, ctx: &Context<'_>) -> ForegroundServiceObjectBox {
660 ForegroundServiceObjectBox::from_value(ForegroundServiceAdapter(T::new(ctx)), TD_Opaque)
661 }
662}
663
664pub fn foreground_service_factory<T: ForegroundService>() -> ForegroundServiceFactoryBox {
665 ForegroundServiceFactoryBox::from_value(ForegroundServiceFactoryImpl::<T>(PhantomData), TD_Opaque)
666}