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 fn get(&mut self, id: ComponentBlueprintId) -> Option<(ComponentKind, Box<dyn AnyComponent>, Box<dyn State>)> {
66 match self.0.get_mut(id) {
67 Some(component) => match component {
68 ComponentType::Component(comp, state) => Some((ComponentKind::Instance, comp.take()?, state.take()?)),
69 ComponentType::Prototype(proto, state) => Some((ComponentKind::Prototype, proto(), state())),
70 },
71 None => panic!(),
72 }
73 }
74
75 pub fn return_component(
81 &mut self,
82 id: ComponentBlueprintId,
83 current_component: Box<dyn AnyComponent>,
84 current_state: Box<dyn State>,
85 ) {
86 match self.0.get_mut(id) {
87 Some(component) => match component {
88 ComponentType::Component(comp, state) => {
89 *comp = Some(current_component);
90 *state = Some(current_state);
91 }
92 ComponentType::Prototype(..) => {
93 }
95 },
96 None => panic!(),
97 }
98 }
99}
100
101#[derive(Debug)]
102pub struct ComponentId<T>(pub(crate) ComponentBlueprintId, pub(crate) PhantomData<T>);
103
104impl<T> From<ComponentBlueprintId> for ComponentId<T> {
105 fn from(value: ComponentBlueprintId) -> Self {
106 Self(value, PhantomData)
107 }
108}
109
110impl<T> Clone for ComponentId<T> {
111 fn clone(&self) -> Self {
112 *self
113 }
114}
115
116impl<T> Copy for ComponentId<T> {}
117
118pub struct ViewMessage {
119 pub(super) payload: Box<dyn Any + Send + Sync>,
120 pub(super) recipient: ComponentBlueprintId,
121}
122
123impl ViewMessage {
124 pub fn recipient(&self) -> ComponentBlueprintId {
125 self.recipient
126 }
127
128 pub fn payload(self) -> Box<dyn Any + Send + Sync> {
129 self.payload
130 }
131}
132
133#[derive(Debug, Clone)]
134pub struct Emitter(pub(crate) flume::Sender<ViewMessage>);
135
136impl From<flume::Sender<ViewMessage>> for Emitter {
137 fn from(value: flume::Sender<ViewMessage>) -> Self {
138 Self(value)
139 }
140}
141
142impl Emitter {
143 pub fn emit<T: 'static + Send + Sync>(
144 &self,
145 component_id: ComponentId<T>,
146 value: T,
147 ) -> Result<(), SendError<ViewMessage>> {
148 let msg = ViewMessage {
149 payload: Box::new(value),
150 recipient: component_id.0,
151 };
152 self.0.send(msg)
153 }
154
155 pub async fn emit_async<T: 'static + Send + Sync>(
156 &self,
157 component_id: ComponentId<T>,
158 value: T,
159 ) -> Result<(), SendError<ViewMessage>> {
160 let msg = ViewMessage {
161 payload: Box::new(value),
162 recipient: component_id.0,
163 };
164 self.0.send_async(msg).await
165 }
166}
167
168pub struct Context<'frame, 'bp, T> {
169 inner: AnyComponentContext<'frame, 'bp>,
170 _p: PhantomData<T>,
171}
172
173impl<'frame, 'bp, T: 'static> Context<'frame, 'bp, T> {
174 pub fn new(inner: AnyComponentContext<'frame, 'bp>) -> Self {
175 Self { inner, _p: PhantomData }
176 }
177
178 pub fn publish<D: 'static>(&mut self, ident: &str, data: D) {
185 let Some(parent) = self.parent else { return };
187
188 let Some(ident_id) = self.inner.strings.lookup(ident) else { return };
189
190 let ids = self.assoc_functions.iter().find(|assoc| assoc.internal == ident_id);
191
192 let Some(assoc_event_map) = ids else { return };
193
194 self.inner.assoc_events.push(
195 self.state_id,
196 parent,
197 *assoc_event_map,
198 self.ident_id,
199 self.sender_id,
200 data,
201 );
202 }
203
204 pub fn attribute(&self, key: &str) -> Option<&ValueKind<'_>> {
206 self.attributes.get(key)
207 }
208
209 pub fn emit<M: 'static + Send + Sync>(&self, recipient: ComponentId<M>, value: M) {
211 self.emitter
212 .emit(recipient, value)
213 .expect("this will not fail unless the runtime is droped")
214 }
215}
216
217impl<'frame, 'bp, T> Deref for Context<'frame, 'bp, T> {
218 type Target = AnyComponentContext<'frame, 'bp>;
219
220 fn deref(&self) -> &Self::Target {
221 &self.inner
222 }
223}
224
225impl<'frame, 'bp, T> DerefMut for Context<'frame, 'bp, T> {
226 fn deref_mut(&mut self) -> &mut Self::Target {
227 &mut self.inner
228 }
229}
230
231pub struct AnyComponentContext<'frame, 'bp> {
232 parent: Option<Parent>,
233 ident_id: StringId,
234 sender_id: WidgetId,
235 state_id: StateId,
236 assoc_functions: &'frame [AssocEventMapping],
237 assoc_events: &'frame mut AssociatedEvents,
238 pub attributes: &'frame mut Attributes<'bp>,
239 state: Option<&'frame mut StateValue<Box<dyn State>>>,
240 pub emitter: &'frame Emitter,
241 pub viewport: &'frame Viewport,
242 pub strings: &'frame Strings,
243 pub components: &'frame mut DeferredComponents,
244 stop_runtime: &'frame mut bool,
245}
246
247impl<'frame, 'bp> AnyComponentContext<'frame, 'bp> {
248 pub fn new(
249 parent: Option<Parent>,
250 ident_id: StringId,
251 sender_id: WidgetId,
252 state_id: StateId,
253 assoc_functions: &'frame [AssocEventMapping],
254 assoc_events: &'frame mut AssociatedEvents,
255 components: &'frame mut DeferredComponents,
256 attributes: &'frame mut Attributes<'bp>,
257 state: Option<&'frame mut StateValue<Box<dyn State>>>,
258 emitter: &'frame Emitter,
259 viewport: &'frame Viewport,
260 stop_runtime: &'frame mut bool,
261 strings: &'frame Strings,
262 ) -> Self {
263 Self {
264 parent,
265 ident_id,
266 sender_id,
267 state_id,
268 assoc_functions,
269 assoc_events,
270 attributes,
271 components,
272 state,
273 emitter,
274 viewport,
275 strings,
276 stop_runtime,
277 }
278 }
279
280 pub fn parent(&self) -> Option<Parent> {
281 self.parent
282 }
283
284 pub fn stop_runtime(&mut self) {
285 *self.stop_runtime = true;
286 }
287}
288
289pub struct AssociatedEvent {
290 pub state: StateId,
291 pub parent: Parent,
292 pub sender: StringId,
293 pub sender_id: WidgetId,
294 event_map: AssocEventMapping,
295 data: Box<dyn Any>,
296}
297
298impl AssociatedEvent {
299 pub fn to_event<'a>(
300 &'a self,
301 internal: &'a str,
302 external: &'a str,
303 sender: &'a str,
304 sender_id: WidgetId,
305 ) -> UserEvent<'a> {
306 UserEvent {
307 external_ident: external,
308 internal_ident: internal,
309 data: &*self.data,
310 sender,
311 sender_id,
312 stop_propagation: false,
313 }
314 }
315
316 pub fn external(&self) -> StringId {
317 self.event_map.external
318 }
319
320 pub fn internal(&self) -> StringId {
321 self.event_map.internal
322 }
323}
324
325#[derive(Debug, Copy, Clone)]
326pub struct UserEvent<'a> {
327 pub sender: &'a str,
328 pub sender_id: WidgetId,
329 pub external_ident: &'a str,
330 pub internal_ident: &'a str,
331 data: &'a dyn Any,
332 stop_propagation: bool,
333}
334
335impl<'a> UserEvent<'a> {
336 pub fn stop_propagation(&mut self) {
337 self.stop_propagation = true;
338 }
339
340 pub fn name(&self) -> &str {
341 self.external_ident
342 }
343
344 pub fn data<T: 'static>(&self) -> &'a T {
350 match self.data.downcast_ref() {
351 Some(data) => data,
352 None => panic!("invalid type when casting event data"),
353 }
354 }
355
356 pub fn data_checked<T: 'static>(&self) -> Option<&'a T> {
358 self.data.downcast_ref()
359 }
360
361 pub fn should_stop_propagation(&self) -> bool {
362 self.stop_propagation
363 }
364}
365
366pub struct AssociatedEvents {
370 inner: Vec<AssociatedEvent>,
371}
372
373impl AssociatedEvents {
374 pub fn new() -> Self {
375 Self { inner: vec![] }
376 }
377
378 fn push<T: 'static>(
379 &mut self,
380 state: StateId,
381 parent: Parent,
382 assoc_event_map: AssocEventMapping,
383 sender: StringId,
384 sender_id: WidgetId,
385 data: T,
386 ) {
387 self.inner.push(AssociatedEvent {
388 state,
389 parent,
390 sender,
391 sender_id,
392 event_map: assoc_event_map,
393 data: Box::new(data),
394 })
395 }
396
397 pub fn next(&mut self) -> Option<AssociatedEvent> {
398 self.inner.pop()
399 }
400}
401
402pub trait Component: 'static {
403 type State: State;
404 type Message;
405
406 const TICKS: bool = true;
407
408 #[allow(unused_variables, unused_mut)]
409 fn on_key(
410 &mut self,
411 key: KeyEvent,
412 state: &mut Self::State,
413 mut children: Children<'_, '_>,
414 mut context: Context<'_, '_, Self::State>,
415 ) {
416 }
417
418 #[allow(unused_variables, unused_mut)]
419 fn on_mount(
420 &mut self,
421 state: &mut Self::State,
422 mut children: Children<'_, '_>,
423 mut context: Context<'_, '_, Self::State>,
424 ) {
425 }
426
427 #[allow(unused_variables, unused_mut)]
428 fn on_unmount(
429 &mut self,
430 state: &mut Self::State,
431 mut children: Children<'_, '_>,
432 mut context: Context<'_, '_, Self::State>,
433 ) {
434 }
435
436 #[allow(unused_variables, unused_mut)]
437 fn on_blur(
438 &mut self,
439 state: &mut Self::State,
440 mut children: Children<'_, '_>,
441 mut context: Context<'_, '_, Self::State>,
442 ) {
443 }
444
445 #[allow(unused_variables, unused_mut)]
446 fn on_focus(
447 &mut self,
448 state: &mut Self::State,
449 mut children: Children<'_, '_>,
450 mut context: Context<'_, '_, Self::State>,
451 ) {
452 }
453
454 #[allow(unused_variables, unused_mut)]
455 fn on_mouse(
456 &mut self,
457 mouse: MouseEvent,
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_tick(
466 &mut self,
467 state: &mut Self::State,
468 mut children: Children<'_, '_>,
469 context: Context<'_, '_, Self::State>,
470 dt: Duration,
471 ) {
472 }
473
474 #[allow(unused_variables, unused_mut)]
475 fn on_message(
476 &mut self,
477 message: Self::Message,
478 state: &mut Self::State,
479 mut children: Children<'_, '_>,
480 mut context: Context<'_, '_, Self::State>,
481 ) {
482 }
483
484 #[allow(unused_variables, unused_mut)]
485 fn on_resize(
486 &mut self,
487 state: &mut Self::State,
488 mut children: Children<'_, '_>,
489 mut context: Context<'_, '_, Self::State>,
490 ) {
491 }
492
493 #[allow(unused_variables, unused_mut)]
494 fn on_event(
495 &mut self,
496 event: &mut UserEvent<'_>,
497 state: &mut Self::State,
498 mut children: Children<'_, '_>,
499 mut context: Context<'_, '_, Self::State>,
500 ) {
501 }
502
503 fn accept_focus(&self) -> bool {
504 true
505 }
506}
507
508impl Component for () {
509 type Message = ();
510 type State = ();
511
512 const TICKS: bool = false;
513
514 fn accept_focus(&self) -> bool {
515 false
516 }
517}
518
519#[derive(Debug)]
520pub enum ComponentKind {
521 Instance,
522 Prototype,
523}
524
525pub trait AnyComponent {
526 fn any_event(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, ev: Event) -> Event;
527
528 fn any_message(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, message: Box<dyn Any>);
529
530 fn any_tick(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>, dt: Duration);
531
532 fn any_focus(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
533
534 fn any_blur(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
535
536 fn any_resize(&mut self, children: Children<'_, '_>, ctx: AnyComponentContext<'_, '_>);
537
538 fn any_component_event(
539 &mut self,
540 children: Children<'_, '_>,
541 ctx: AnyComponentContext<'_, '_>,
542 value: &mut UserEvent<'_>,
543 );
544
545 fn any_accept_focus(&self) -> bool;
546
547 fn any_ticks(&self) -> bool;
548}
549
550impl<T> AnyComponent for T
551where
552 T: Component,
553 T: 'static,
554{
555 fn any_event(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, event: Event) -> Event {
556 let mut state = ctx
557 .state
558 .take()
559 .map(|s| s.to_mut_cast::<T::State>())
560 .expect("components always have a state");
561 let context = Context::<T::State>::new(ctx);
562 match event {
563 Event::Blur | Event::Focus => (), Event::Key(ev) => self.on_key(ev, &mut *state, children, context),
565 Event::Mouse(ev) => self.on_mouse(ev, &mut *state, children, context),
566 Event::Tick(dt) => self.on_tick(&mut *state, children, context, dt),
567 Event::Resize(_) => self.on_resize(&mut *state, children, context),
568 Event::Mount => self.on_mount(&mut *state, children, context),
569 Event::Unmount => self.on_unmount(&mut *state, children, context),
570 Event::Noop | Event::Stop => (),
571 }
572 event
573 }
574
575 fn any_accept_focus(&self) -> bool {
576 self.accept_focus()
577 }
578
579 fn any_ticks(&self) -> bool {
580 T::TICKS
581 }
582
583 fn any_message(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, message: Box<dyn Any>) {
584 let mut state = ctx
585 .state
586 .take()
587 .map(|s| s.to_mut_cast::<T::State>())
588 .expect("components always have a state");
589 let Ok(message) = message.downcast::<T::Message>() else { return };
590 let context = Context::<T::State>::new(ctx);
591 self.on_message(*message, &mut *state, children, context);
592 }
593
594 fn any_focus(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
595 let mut state = ctx
596 .state
597 .take()
598 .map(|s| s.to_mut_cast::<T::State>())
599 .expect("components always have a state");
600 let context = Context::<T::State>::new(ctx);
601 self.on_focus(&mut *state, children, context);
602 }
603
604 fn any_blur(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
605 let mut state = ctx
606 .state
607 .take()
608 .map(|s| s.to_mut_cast::<T::State>())
609 .expect("components always have a state");
610 let context = Context::<T::State>::new(ctx);
611 self.on_blur(&mut *state, children, context);
612 }
613
614 fn any_tick(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>, dt: Duration) {
615 let mut state = ctx
616 .state
617 .take()
618 .map(|s| s.to_mut_cast::<T::State>())
619 .expect("components always have a state");
620 let context = Context::<T::State>::new(ctx);
621 self.on_tick(&mut *state, children, context, dt);
622 }
623
624 fn any_resize(&mut self, children: Children<'_, '_>, mut ctx: AnyComponentContext<'_, '_>) {
625 let mut state = ctx
626 .state
627 .take()
628 .map(|s| s.to_mut_cast::<T::State>())
629 .expect("components always have a state");
630 let context = Context::<T::State>::new(ctx);
631 self.on_resize(&mut *state, children, context);
632 }
633
634 fn any_component_event(
635 &mut self,
636 children: Children<'_, '_>,
637 mut ctx: AnyComponentContext<'_, '_>,
638 event: &mut UserEvent<'_>,
639 ) {
640 let mut state = ctx
641 .state
642 .take()
643 .map(|s| s.to_mut_cast::<T::State>())
644 .expect("components always have a state");
645
646 let context = Context::<T::State>::new(ctx);
647
648 self.on_event(event, &mut *state, children, context);
649 }
650}
651
652impl std::fmt::Debug for dyn AnyComponent {
653 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
654 write!(f, "<dyn AnyComponent>")
655 }
656}