1use std::any::Any;
2use std::marker::PhantomData;
3use std::ops::{Deref, DerefMut};
4use std::time::Duration;
5
6use anathema_state::{State, StateId, Value as StateValue};
7use anathema_store::slab::Slab;
8use anathema_templates::strings::{StringId, Strings};
9use anathema_templates::{AssocEventMapping, ComponentBlueprintId};
10use anathema_value_resolver::{Attributes, ValueKind};
11use deferred::DeferredComponents;
12use flume::SendError;
13
14use self::events::{Event, KeyEvent, MouseEvent};
15use crate::WidgetId;
16use crate::layout::Viewport;
17use crate::query::Children;
18use crate::widget::Parent;
19
20pub mod deferred;
21pub mod events;
22
23pub type ComponentFn = dyn Fn() -> Box<dyn AnyComponent>;
24pub type StateFn = dyn FnMut() -> Box<dyn State>;
25
26enum ComponentType {
27 Component(Option<Box<dyn AnyComponent>>, Option<Box<dyn State>>),
28 Prototype(Box<ComponentFn>, Box<StateFn>),
29}
30
31pub struct ComponentRegistry(Slab<ComponentBlueprintId, ComponentType>);
34
35impl ComponentRegistry {
36 pub fn new() -> Self {
37 Self(Slab::empty())
38 }
39
40 pub fn add_component<S: State>(&mut self, id: ComponentBlueprintId, component: impl Component + 'static, state: S) {
44 let comp_type = ComponentType::Component(Some(Box::new(component)), Some(Box::new(state)));
45 self.0.insert_at(id, comp_type);
46 }
47
48 pub fn add_prototype<FC, FS, C, S>(&mut self, id: ComponentBlueprintId, proto: FC, mut state: FS)
49 where
50 FC: 'static + Fn() -> C,
51 FS: 'static + FnMut() -> S,
52 C: Component + 'static,
53 S: State + 'static,
54 {
55 let comp_type =
56 ComponentType::Prototype(Box::new(move || Box::new(proto())), Box::new(move || Box::new(state())));
57
58 self.0.insert_at(id, comp_type);
59 }
60
61 pub(super) fn get(
66 &mut self,
67 id: ComponentBlueprintId,
68 ) -> Option<(ComponentKind, Box<dyn AnyComponent>, Box<dyn State>)> {
69 match self.0.get_mut(id) {
70 Some(component) => match component {
71 ComponentType::Component(comp, state) => Some((ComponentKind::Instance, comp.take()?, state.take()?)),
72 ComponentType::Prototype(proto, state) => Some((ComponentKind::Prototype, proto(), state())),
73 },
74 None => panic!(),
75 }
76 }
77
78 pub fn return_component(
84 &mut self,
85 id: ComponentBlueprintId,
86 current_component: Box<dyn AnyComponent>,
87 current_state: Box<dyn State>,
88 ) {
89 match self.0.get_mut(id) {
90 Some(component) => match component {
91 ComponentType::Component(comp, state) => {
92 *comp = Some(current_component);
93 *state = Some(current_state);
94 }
95 ComponentType::Prototype(..) => {
96 }
98 },
99 None => panic!(),
100 }
101 }
102}
103
104#[derive(Debug)]
105pub struct ComponentId<T>(pub(crate) ComponentBlueprintId, pub(crate) PhantomData<T>);
106
107impl<T> From<ComponentBlueprintId> for ComponentId<T> {
108 fn from(value: ComponentBlueprintId) -> Self {
109 Self(value, PhantomData)
110 }
111}
112
113impl<T> Clone for ComponentId<T> {
114 fn clone(&self) -> Self {
115 *self
116 }
117}
118
119impl<T> Copy for ComponentId<T> {}
120
121pub struct ViewMessage {
122 pub(super) payload: Box<dyn Any + Send + Sync>,
123 pub(super) recipient: Recipient,
124}
125
126impl ViewMessage {
127 pub fn recipient(&self) -> Recipient {
128 self.recipient
129 }
130
131 pub fn payload(self) -> Box<dyn Any + Send + Sync> {
132 self.payload
133 }
134}
135
136#[derive(Debug, Copy, Clone)]
137pub enum Recipient {
138 ComponentId(ComponentBlueprintId),
139 WidgetId(WidgetId),
140}
141
142#[derive(Debug, Clone)]
143pub struct Emitter(pub(crate) flume::Sender<ViewMessage>);
144
145impl From<flume::Sender<ViewMessage>> for Emitter {
146 fn from(value: flume::Sender<ViewMessage>) -> Self {
147 Self(value)
148 }
149}
150
151pub type MessageReceiver = flume::Receiver<ViewMessage>;
152
153impl Emitter {
154 pub fn new() -> (Self, MessageReceiver) {
155 let (tx, rx) = flume::unbounded();
156 (Self(tx), rx)
157 }
158
159 pub fn emit<T: 'static + Send + Sync>(
161 &self,
162 component_id: ComponentId<T>,
163 value: T,
164 ) -> Result<(), SendError<ViewMessage>> {
165 let msg = ViewMessage {
166 payload: Box::new(value),
167 recipient: Recipient::ComponentId(component_id.0),
168 };
169 self.0.send(msg)
170 }
171
172 pub async fn emit_async<T: 'static + Send + Sync>(
174 &self,
175 component_id: ComponentId<T>,
176 value: T,
177 ) -> Result<(), SendError<ViewMessage>> {
178 let msg = ViewMessage {
179 payload: Box::new(value),
180 recipient: Recipient::ComponentId(component_id.0),
181 };
182 self.0.send_async(msg).await
183 }
184
185 pub fn try_emit<T: 'static + Send + Sync>(
189 &self,
190 widget_id: WidgetId,
191 value: T,
192 ) -> Result<(), SendError<ViewMessage>> {
193 let msg = ViewMessage {
194 payload: Box::new(value),
195 recipient: Recipient::WidgetId(widget_id),
196 };
197 self.0.send(msg)
198 }
199
200 pub async fn try_emit_async<T: 'static + Send + Sync>(
202 &self,
203 widget_id: WidgetId,
204 value: T,
205 ) -> Result<(), SendError<ViewMessage>> {
206 let msg = ViewMessage {
207 payload: Box::new(value),
208 recipient: Recipient::WidgetId(widget_id),
209 };
210 self.0.send_async(msg).await
211 }
212}
213
214pub struct Context<'frame, 'bp, T> {
215 inner: AnyComponentContext<'frame, 'bp>,
216 _p: PhantomData<T>,
217}
218
219impl<'frame, 'bp, T: 'static> Context<'frame, 'bp, T> {
220 pub fn new(inner: AnyComponentContext<'frame, 'bp>) -> Self {
221 Self { inner, _p: PhantomData }
222 }
223
224 pub fn publish<D: 'static>(&mut self, ident: &str, data: D) {
231 let Some(parent) = self.parent else { return };
233
234 let Some(ident_id) = self.inner.strings.lookup(ident) else { return };
235
236 let ids = self.assoc_functions.iter().find(|assoc| assoc.internal == ident_id);
237
238 let Some(assoc_event_map) = ids else { return };
239
240 self.inner.assoc_events.push(
241 self.state_id,
242 parent,
243 *assoc_event_map,
244 self.ident_id,
245 self.widget_id,
246 data,
247 );
248 }
249
250 pub fn attribute(&self, key: &str) -> Option<&ValueKind<'_>> {
252 self.attributes.get(key)
253 }
254
255 pub fn emit<M: 'static + Send + Sync>(&self, recipient: ComponentId<M>, value: M) {
257 self.emitter
258 .emit(recipient, value)
259 .expect("this will not fail unless the runtime is dropped")
260 }
261}
262
263impl<'frame, 'bp, T> Deref for Context<'frame, 'bp, T> {
264 type Target = AnyComponentContext<'frame, 'bp>;
265
266 fn deref(&self) -> &Self::Target {
267 &self.inner
268 }
269}
270
271impl<'frame, 'bp, T> DerefMut for Context<'frame, 'bp, T> {
272 fn deref_mut(&mut self) -> &mut Self::Target {
273 &mut self.inner
274 }
275}
276
277pub struct AnyComponentContext<'frame, 'bp> {
278 parent: Option<Parent>,
279 ident_id: StringId,
280 pub widget_id: WidgetId,
281 state_id: StateId,
282 assoc_functions: &'frame [AssocEventMapping],
283 assoc_events: &'frame mut AssociatedEvents,
284 pub attributes: &'frame mut Attributes<'bp>,
285 state: Option<&'frame mut StateValue<Box<dyn State>>>,
286 pub emitter: &'frame Emitter,
287 pub viewport: &'frame Viewport,
288 pub strings: &'frame Strings,
289 pub components: &'frame mut DeferredComponents,
290 stop_runtime: &'frame mut bool,
291}
292
293impl<'frame, 'bp> AnyComponentContext<'frame, 'bp> {
294 pub fn new(
295 parent: Option<Parent>,
296 ident_id: StringId,
297 sender_id: WidgetId,
298 state_id: StateId,
299 assoc_functions: &'frame [AssocEventMapping],
300 assoc_events: &'frame mut AssociatedEvents,
301 components: &'frame mut DeferredComponents,
302 attributes: &'frame mut Attributes<'bp>,
303 state: Option<&'frame mut StateValue<Box<dyn State>>>,
304 emitter: &'frame Emitter,
305 viewport: &'frame Viewport,
306 stop_runtime: &'frame mut bool,
307 strings: &'frame Strings,
308 ) -> Self {
309 Self {
310 parent,
311 ident_id,
312 widget_id: sender_id,
313 state_id,
314 assoc_functions,
315 assoc_events,
316 attributes,
317 components,
318 state,
319 emitter,
320 viewport,
321 strings,
322 stop_runtime,
323 }
324 }
325
326 pub fn parent(&self) -> Option<Parent> {
327 self.parent
328 }
329
330 pub fn stop_runtime(&mut self) {
331 *self.stop_runtime = true;
332 }
333}
334
335pub struct AssociatedEvent {
336 pub state: StateId,
337 pub parent: Parent,
338 pub sender: StringId,
339 pub sender_id: WidgetId,
340 event_map: AssocEventMapping,
341 data: Box<dyn Any>,
342}
343
344impl AssociatedEvent {
345 pub fn to_event<'a>(
346 &'a self,
347 internal: &'a str,
348 external: &'a str,
349 sender: &'a str,
350 sender_id: WidgetId,
351 ) -> UserEvent<'a> {
352 UserEvent {
353 external_ident: external,
354 internal_ident: internal,
355 data: &*self.data,
356 sender,
357 sender_id,
358 stop_propagation: false,
359 }
360 }
361
362 pub fn external(&self) -> StringId {
363 self.event_map.external
364 }
365
366 pub fn internal(&self) -> StringId {
367 self.event_map.internal
368 }
369}
370
371#[derive(Debug, Copy, Clone)]
372pub struct UserEvent<'a> {
373 pub sender: &'a str,
374 pub sender_id: WidgetId,
375 pub external_ident: &'a str,
376 pub internal_ident: &'a str,
377 data: &'a dyn Any,
378 stop_propagation: bool,
379}
380
381impl<'a> UserEvent<'a> {
382 pub fn stop_propagation(&mut self) {
383 self.stop_propagation = true;
384 }
385
386 pub fn name(&self) -> &str {
387 self.external_ident
388 }
389
390 pub fn data<T: 'static>(&self) -> &'a T {
396 match self.data.downcast_ref() {
397 Some(data) => data,
398 None => panic!("invalid type when casting event data"),
399 }
400 }
401
402 pub fn data_checked<T: 'static>(&self) -> Option<&'a T> {
404 self.data.downcast_ref()
405 }
406
407 pub fn should_stop_propagation(&self) -> bool {
408 self.stop_propagation
409 }
410}
411
412pub struct AssociatedEvents {
416 inner: Vec<AssociatedEvent>,
417}
418
419impl AssociatedEvents {
420 pub fn new() -> Self {
421 Self { inner: vec![] }
422 }
423
424 fn push<T: 'static>(
425 &mut self,
426 state: StateId,
427 parent: Parent,
428 assoc_event_map: AssocEventMapping,
429 sender: StringId,
430 sender_id: WidgetId,
431 data: T,
432 ) {
433 self.inner.push(AssociatedEvent {
434 state,
435 parent,
436 sender,
437 sender_id,
438 event_map: assoc_event_map,
439 data: Box::new(data),
440 })
441 }
442
443 pub fn next(&mut self) -> Option<AssociatedEvent> {
444 self.inner.pop()
445 }
446}
447
448pub trait Component: 'static {
449 type State: State;
450 type Message;
451
452 const TICKS: bool = true;
453
454 #[allow(unused_variables, unused_mut)]
455 fn on_key(
456 &mut self,
457 key: KeyEvent,
458 state: &mut Self::State,
459 mut children: Children<'_, '_>,
460 mut context: Context<'_, '_, Self::State>,
461 ) {
462 }
463
464 #[allow(unused_variables, unused_mut)]
465 fn on_mount(
466 &mut self,
467 state: &mut Self::State,
468 mut children: Children<'_, '_>,
469 mut context: Context<'_, '_, Self::State>,
470 ) {
471 }
472
473 #[allow(unused_variables, unused_mut)]
474 fn on_unmount(
475 &mut self,
476 state: &mut Self::State,
477 mut children: Children<'_, '_>,
478 mut context: Context<'_, '_, Self::State>,
479 ) {
480 }
481
482 #[allow(unused_variables, unused_mut)]
483 fn on_blur(
484 &mut self,
485 state: &mut Self::State,
486 mut children: Children<'_, '_>,
487 mut context: Context<'_, '_, Self::State>,
488 ) {
489 }
490
491 #[allow(unused_variables, unused_mut)]
492 fn on_focus(
493 &mut self,
494 state: &mut Self::State,
495 mut children: Children<'_, '_>,
496 mut context: Context<'_, '_, Self::State>,
497 ) {
498 }
499
500 #[allow(unused_variables, unused_mut)]
501 fn on_mouse(
502 &mut self,
503 mouse: MouseEvent,
504 state: &mut Self::State,
505 mut children: Children<'_, '_>,
506 mut context: Context<'_, '_, Self::State>,
507 ) {
508 }
509
510 #[allow(unused_variables, unused_mut)]
511 fn on_tick(
512 &mut self,
513 state: &mut Self::State,
514 mut children: Children<'_, '_>,
515 context: Context<'_, '_, Self::State>,
516 dt: Duration,
517 ) {
518 }
519
520 #[allow(unused_variables, unused_mut)]
521 fn on_message(
522 &mut self,
523 message: Self::Message,
524 state: &mut Self::State,
525 mut children: Children<'_, '_>,
526 mut context: Context<'_, '_, Self::State>,
527 ) {
528 }
529
530 #[allow(unused_variables, unused_mut)]
531 fn on_resize(
532 &mut self,
533 state: &mut Self::State,
534 mut children: Children<'_, '_>,
535 mut context: Context<'_, '_, Self::State>,
536 ) {
537 }
538
539 #[allow(unused_variables, unused_mut)]
540 fn on_event(
541 &mut self,
542 event: &mut UserEvent<'_>,
543 state: &mut Self::State,
544 mut children: Children<'_, '_>,
545 mut context: Context<'_, '_, Self::State>,
546 ) {
547 }
548
549 fn accept_focus(&self) -> bool {
550 true
551 }
552}
553
554impl Component for () {
555 type Message = ();
556 type State = ();
557
558 const TICKS: bool = false;
559
560 fn accept_focus(&self) -> bool {
561 false
562 }
563}
564
565#[derive(Debug)]
566pub enum ComponentKind {
567 Instance,
568 Prototype,
569}
570
571pub trait AnyComponent {
572 fn any_event(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, ev: Event) -> Event;
573
574 fn any_message(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, message: Box<dyn Any>);
575
576 fn any_tick(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, dt: Duration);
577
578 fn any_focus(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
579
580 fn any_blur(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
581
582 fn any_resize(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
583
584 fn any_component_event(
585 &mut self,
586 children: Children<'_, '_>,
587 ctx: AnyComponentContext<'_, '_>,
588 value: &mut UserEvent<'_>,
589 );
590
591 fn any_accept_focus(&self) -> bool;
592
593 fn any_ticks(&self) -> bool;
594}
595
596impl<T> AnyComponent for T
597where
598 T: Component,
599 T: 'static,
600{
601 fn any_event(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, event: Event) -> Event {
602 let mut state = ctx
603 .state
604 .take()
605 .map(|s| s.to_mut_cast::<T::State>())
606 .expect("components always have a state");
607 let context = Context::<T::State>::new(ctx);
608 match event {
609 Event::Blur | Event::Focus => (), Event::Key(ev) => self.on_key(ev, &mut *state, children, context),
611 Event::Mouse(ev) => self.on_mouse(ev, &mut *state, children, context),
612 Event::Tick(dt) => self.on_tick(&mut *state, children, context, dt),
613 Event::Resize(_) => self.on_resize(&mut *state, children, context),
614 Event::Mount => self.on_mount(&mut *state, children, context),
615 Event::Unmount => self.on_unmount(&mut *state, children, context),
616 Event::Noop | Event::Stop => (),
617 }
618 event
619 }
620
621 fn any_accept_focus(&self) -> bool {
622 self.accept_focus()
623 }
624
625 fn any_ticks(&self) -> bool {
626 T::TICKS
627 }
628
629 fn any_message(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, message: Box<dyn Any>) {
630 let mut state = ctx
631 .state
632 .take()
633 .map(|s| s.to_mut_cast::<T::State>())
634 .expect("components always have a state");
635 let Ok(message) = message.downcast::<T::Message>() else { return };
636 let context = Context::<T::State>::new(ctx);
637 self.on_message(*message, &mut *state, children, context);
638 }
639
640 fn any_focus(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
641 let mut state = ctx
642 .state
643 .take()
644 .map(|s| s.to_mut_cast::<T::State>())
645 .expect("components always have a state");
646 let context = Context::<T::State>::new(ctx);
647 self.on_focus(&mut *state, children, context);
648 }
649
650 fn any_blur(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
651 let mut state = ctx
652 .state
653 .take()
654 .map(|s| s.to_mut_cast::<T::State>())
655 .expect("components always have a state");
656 let context = Context::<T::State>::new(ctx);
657 self.on_blur(&mut *state, children, context);
658 }
659
660 fn any_tick(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, dt: Duration) {
661 let mut state = ctx
662 .state
663 .take()
664 .map(|s| s.to_mut_cast::<T::State>())
665 .expect("components always have a state");
666 let context = Context::<T::State>::new(ctx);
667 self.on_tick(&mut *state, children, context, dt);
668 }
669
670 fn any_resize(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
671 let mut state = ctx
672 .state
673 .take()
674 .map(|s| s.to_mut_cast::<T::State>())
675 .expect("components always have a state");
676 let context = Context::<T::State>::new(ctx);
677 self.on_resize(&mut *state, children, context);
678 }
679
680 fn any_component_event(
681 &mut self,
682 children: Children<'_, '_>,
683 mut ctx: AnyComponentContext<'_, '_>,
684 event: &mut UserEvent<'_>,
685 ) {
686 let mut state = ctx
687 .state
688 .take()
689 .map(|s| s.to_mut_cast::<T::State>())
690 .expect("components always have a state");
691
692 let context = Context::<T::State>::new(ctx);
693
694 self.on_event(event, &mut *state, children, context);
695 }
696}
697
698impl std::fmt::Debug for dyn AnyComponent {
699 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
700 write!(f, "<dyn AnyComponent>")
701 }
702}