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