Skip to main content

loam_runtime/
stores.rs

1use crate::entity::{Entity, SceneId};
2use crate::relation::Relation;
3use crate::store::{Owner, Store};
4
5/// The application's storage contract; only `Session` calls its lifetime hooks.
6pub trait Stores: Send + 'static {
7    type Snapshot: Send + 'static;
8
9    fn bind(&mut self, scene: SceneId, owner: Owner);
10
11    fn boundary(&mut self, owner: Owner);
12
13    fn release(&mut self, entity: Entity, owner: Owner);
14
15    fn snapshot(&self) -> Self::Snapshot;
16
17    fn restore(&mut self, from: &Self::Snapshot, scene: SceneId, owner: Owner);
18}
19
20pub trait HasStore<T>: Stores {
21    fn store(&self) -> &Store<T>;
22
23    fn store_mut(&mut self) -> &mut Store<T>;
24}
25
26pub trait HasRelation<T>: Stores {
27    fn relation(&self) -> &Relation<T>;
28
29    fn relation_mut(&mut self) -> &mut Relation<T>;
30}
31
32#[doc(hidden)]
33#[macro_export]
34macro_rules! __stores_field {
35    (Store, $name:ident, $field:ident, $row:ty) => {
36        impl $crate::HasStore<$row> for $name {
37            fn store(&self) -> &$crate::Store<$row> {
38                &self.$field
39            }
40
41            fn store_mut(&mut self) -> &mut $crate::Store<$row> {
42                &mut self.$field
43            }
44        }
45    };
46    (Relation, $name:ident, $field:ident, $row:ty) => {
47        impl $crate::HasRelation<$row> for $name {
48            fn relation(&self) -> &$crate::Relation<$row> {
49                &self.$field
50            }
51
52            fn relation_mut(&mut self) -> &mut $crate::Relation<$row> {
53                &mut self.$field
54            }
55        }
56    };
57    (Value, $name:ident, $field:ident, $row:ty) => {};
58}
59
60/// Declares the store struct and implements `Stores`; its snapshot type is `<A as Stores>::Snapshot`.
61#[macro_export]
62macro_rules! stores {
63    (
64        $(#[$attr:meta])*
65        $vis:vis struct $name:ident {
66            $( $field:ident : $kind:ident < $row:ty > ),* $(,)?
67        }
68    ) => {
69        $(#[$attr])*
70        $vis struct $name {
71            $( pub $field : $crate::$kind<$row>, )*
72        }
73
74        const _: () = {
75            pub struct Snapshot {
76                $( pub $field : <$crate::$kind<$row> as $crate::StoreField>::Snapshot, )*
77            }
78
79            impl $crate::Stores for $name {
80                type Snapshot = Snapshot;
81
82                fn bind(&mut self, _scene: $crate::SceneId, _owner: $crate::Owner) {
83                    $( $crate::StoreField::bind(&mut self.$field, _scene, _owner); )*
84                }
85
86                fn boundary(&mut self, _owner: $crate::Owner) {
87                    $( $crate::StoreField::boundary(&mut self.$field, _owner); )*
88                }
89
90                fn release(&mut self, _entity: $crate::Entity, _owner: $crate::Owner) {
91                    $( $crate::StoreField::release(&mut self.$field, _entity, _owner); )*
92                }
93
94                fn snapshot(&self) -> Snapshot {
95                    Snapshot {
96                        $( $field : $crate::StoreField::snapshot(&self.$field), )*
97                    }
98                }
99
100                fn restore(
101                    &mut self,
102                    _from: &Snapshot,
103                    _scene: $crate::SceneId,
104                    _owner: $crate::Owner,
105                ) {
106                    $( $crate::StoreField::restore(&mut self.$field, &_from.$field, _scene, _owner); )*
107                }
108            }
109
110            $( $crate::__stores_field!($kind, $name, $field, $row); )*
111        };
112    };
113}