model_context.rs

  1use crate::{
  2    AppContext, Context, Effect, EntityId, EventEmitter, Handle, Reference, Subscription,
  3    WeakHandle,
  4};
  5use std::marker::PhantomData;
  6
  7pub struct ModelContext<'a, T> {
  8    app: Reference<'a, AppContext>,
  9    entity_type: PhantomData<T>,
 10    entity_id: EntityId,
 11}
 12
 13impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
 14    pub(crate) fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self {
 15        Self {
 16            app: Reference::Mutable(app),
 17            entity_type: PhantomData,
 18            entity_id,
 19        }
 20    }
 21
 22    // todo!
 23    // fn update<R>(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R {
 24    //     let mut entity = self
 25    //         .app
 26    //         .entities
 27    //         .get_mut(self.entity_id)
 28    //         .unwrap()
 29    //         .take()
 30    //         .unwrap();
 31    //     let result = update(entity.downcast_mut::<T>().unwrap(), self);
 32    //     self.app
 33    //         .entities
 34    //         .get_mut(self.entity_id)
 35    //         .unwrap()
 36    //         .replace(entity);
 37    //     result
 38    // }
 39
 40    pub fn handle(&self) -> WeakHandle<T> {
 41        self.app.entities.weak_handle(self.entity_id)
 42    }
 43
 44    pub fn observe<E: Send + Sync + 'static>(
 45        &mut self,
 46        handle: &Handle<E>,
 47        on_notify: impl Fn(&mut T, Handle<E>, &mut ModelContext<'_, T>) + Send + Sync + 'static,
 48    ) -> Subscription {
 49        let this = self.handle();
 50        let handle = handle.downgrade();
 51        self.app.observers.insert(
 52            handle.id,
 53            Box::new(move |cx| {
 54                if let Some((this, handle)) = this.upgrade(cx).zip(handle.upgrade(cx)) {
 55                    this.update(cx, |this, cx| on_notify(this, handle, cx));
 56                    true
 57                } else {
 58                    false
 59                }
 60            }),
 61        )
 62    }
 63
 64    pub fn subscribe<E: EventEmitter + Send + Sync + 'static>(
 65        &mut self,
 66        handle: &Handle<E>,
 67        on_event: impl Fn(&mut T, Handle<E>, &E::Event, &mut ModelContext<'_, T>)
 68            + Send
 69            + Sync
 70            + 'static,
 71    ) -> Subscription {
 72        let this = self.handle();
 73        let handle = handle.downgrade();
 74        self.app.event_handlers.insert(
 75            handle.id,
 76            Box::new(move |event, cx| {
 77                let event = event.downcast_ref().expect("invalid event type");
 78                if let Some((this, handle)) = this.upgrade(cx).zip(handle.upgrade(cx)) {
 79                    this.update(cx, |this, cx| on_event(this, handle, event, cx));
 80                    true
 81                } else {
 82                    false
 83                }
 84            }),
 85        )
 86    }
 87
 88    pub fn notify(&mut self) {
 89        self.app
 90            .pending_effects
 91            .push_back(Effect::Notify(self.entity_id));
 92    }
 93}
 94
 95impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> {
 96    pub fn emit(&mut self, event: T::Event) {
 97        self.app.pending_effects.push_back(Effect::Emit {
 98            entity_id: self.entity_id,
 99            event: Box::new(event),
100        });
101    }
102}
103
104impl<'a, T: 'static> Context for ModelContext<'a, T> {
105    type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
106    type Result<U> = U;
107
108    fn entity<U: Send + Sync + 'static>(
109        &mut self,
110        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
111    ) -> Handle<U> {
112        self.app.entity(build_entity)
113    }
114
115    fn update_entity<U: Send + Sync + 'static, R>(
116        &mut self,
117        handle: &Handle<U>,
118        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
119    ) -> R {
120        self.app.update_entity(handle, update)
121    }
122}