1use std::any;
4use std::fmt;
5use std::ops::Deref;
6use std::sync::{Arc, Weak};
7
8extern crate stable_deref_trait;
9use stable_deref_trait::CloneStableDeref;
10
11use dashmap::DashMap;
12use downcast_rs::{Downcast, DowncastSync};
13use parking_lot::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
14
15use super::{ComponentManager, Entity};
16use crate::snowflake::Snowflake;
17use crate::util::Result;
18
19rental! {
20 pub mod handle_ref {
21 use super::*;
23
24 #[rental(debug, clone, deref_suffix, covariant, map_suffix = "T")]
33 pub struct HandleReadRef<H: CloneStableDeref + Deref + 'static, T: 'static> {
34 head: H,
35 suffix: RwLockReadGuard<'head, T>,
36 }
37
38 #[rental(debug, clone, deref_mut_suffix, covariant, map_suffix = "T")]
47 pub struct HandleWriteRef<H: CloneStableDeref + Deref + 'static, T: 'static> {
48 head: H,
49 suffix: RwLockWriteGuard<'head, T>,
50 }
51 }
52}
53
54pub use handle_ref::{HandleReadRef, HandleWriteRef};
55
56pub type StoreReference<T> = Arc<RwLock<T>>;
57type WeakStoreReference<T> = Weak<RwLock<T>>;
58pub type ReadReference<T> = HandleReadRef<StoreReference<T>, T>;
59pub type WriteReference<T> = HandleWriteRef<StoreReference<T>, T>;
60
61pub fn read_store_reference<T: 'static>(head: StoreReference<T>) -> ReadReference<T> {
63 HandleReadRef::new(head, |s| s.read())
64}
65
66pub fn write_store_reference<T: 'static>(head: StoreReference<T>) -> WriteReference<T> {
68 HandleWriteRef::new(head, |s| s.write())
69}
70
71pub trait SharedStore<T, U>
74where
75 T: Entity + 'static,
76 U: EntityBackend<T> + Sync + Send + 'static,
77{
78 fn get_store<'a>(&'a self) -> &'a Store<T, U>;
79}
80
81pub struct StoreHandle<T>
89where
90 T: Entity + 'static,
91{
92 backend: Arc<dyn EntityBackend<T> + Sync + Send + 'static>,
93 id: Snowflake,
94 object: Option<T>,
95}
96
97impl<T> StoreHandle<T>
98where
99 T: Entity + 'static,
100{
101 fn new<U>(backend: Arc<U>, id: Snowflake, object: Option<T>) -> StoreHandle<T>
102 where
103 U: EntityBackend<T> + Sync + Send + 'static,
104 {
105 StoreHandle {
106 backend,
107 id,
108 object,
109 }
110 }
111
112 pub fn get(&self) -> Option<&T> {
114 self.object.as_ref()
115 }
116
117 pub fn get_mut(&mut self) -> Option<&mut T> {
119 self.object.as_mut()
120 }
121
122 pub fn replace(&mut self, object: T) -> Option<T> {
124 self.object.replace(object)
125 }
126
127 pub fn id(&self) -> Snowflake {
129 self.id
130 }
131
132 pub fn exists(&self) -> bool {
134 self.object.is_some()
135 }
136
137 pub fn store(&self) -> Result<()> {
139 match &self.object {
140 None => self.backend.delete(self.id),
141 Some(obj) => self.backend.store(self.id, &obj),
142 }
143 }
144
145 pub fn delete(&mut self) -> Result<()> {
148 if let Some(obj) = &mut self.object {
149 obj.clear_components()?;
150 }
151
152 self.object = None;
153 self.backend.delete(self.id)
154 }
155
156 fn set_object(&mut self, object: Option<T>) {
157 self.object = object;
158 }
159}
160
161impl<T> Drop for StoreHandle<T>
162where
163 T: Entity + 'static,
164{
165 fn drop(&mut self) {
166 if let Some(entity) = &self.object {
167 if entity.dirty() {
168 let _e = self.backend.store(self.id, &entity);
170 }
171 }
172 }
173}
174
175#[doc(hidden)]
176#[derive(Clone)]
177pub struct StoredHandleData<T>
178where
179 T: Entity + 'static,
180{
181 initializer: Arc<Once>,
182 handle: WeakStoreReference<StoreHandle<T>>,
183}
184
185#[doc(hidden)]
187#[derive(Clone)]
188pub struct HandleData<T>
189where
190 T: Entity + 'static,
191{
192 initializer: Arc<Once>,
193 handle: StoreReference<StoreHandle<T>>,
194}
195
196pub struct Store<T, U>
205where
206 T: Entity + 'static,
207 U: EntityBackend<T> + Sync + Send + 'static,
208{
209 backend: Arc<U>,
210 refs: DashMap<Snowflake, StoredHandleData<T>>,
211}
212
213impl<T, U> Store<T, U>
214where
215 T: Entity + 'static,
216 U: EntityBackend<T> + Sync + Send + 'static,
217{
218 pub fn new(backend: Arc<U>) -> Store<T, U> {
220 Store {
221 backend,
222 refs: DashMap::new(),
223 }
224 }
225
226 fn get_handle(&self, id: Snowflake) -> HandleData<T> {
229 let mut entry = self.refs.entry(id).or_insert_with(|| StoredHandleData {
230 initializer: Arc::new(Once::new()),
231 handle: Weak::new(),
232 });
233
234 if let Some(strong) = entry.handle.upgrade() {
235 HandleData {
236 initializer: entry.initializer.clone(),
237 handle: strong,
238 }
239 } else {
240 let handle: StoreHandle<T> = StoreHandle::new(self.backend.clone(), id, None);
241 let initializer = Arc::new(Once::new());
242 let strong = Arc::new(RwLock::new(handle));
243
244 entry.handle = Arc::downgrade(&strong);
245 entry.initializer = initializer.clone();
246
247 HandleData {
248 initializer,
249 handle: strong,
250 }
251 }
252 }
253
254 fn initialize_handle(
258 &self,
259 id: Snowflake,
260 cm: Arc<ComponentManager<T>>,
261 handle_data: HandleData<T>,
262 ) -> Result<HandleData<T>> {
263 let mut res: Result<()> = Result::Ok(());
264
265 handle_data.initializer.call_once(|| {
266 let mut write_handle = handle_data.handle.write();
267 match self.backend.load(id, cm) {
268 Err(e) => {
269 res = Err(e);
270 write_handle.set_object(None);
271 }
272 Ok(data) => {
273 write_handle.set_object(data);
274 }
275 };
276 });
277
278 match res {
279 Err(e) => Err(e),
280 Ok(_v) => Ok(handle_data),
281 }
282 }
283
284 pub fn load_handle(
285 &self,
286 id: Snowflake,
287 cm: Arc<ComponentManager<T>>,
288 ) -> Result<StoreReference<StoreHandle<T>>> {
289 let handle_data = self.initialize_handle(id, cm, self.get_handle(id))?;
290 Ok(handle_data.handle.clone())
291 }
292
293 pub fn load(
301 &self,
302 id: Snowflake,
303 cm: Arc<ComponentManager<T>>,
304 ) -> Result<ReadReference<StoreHandle<T>>> {
305 let handle_data = self.initialize_handle(id, cm, self.get_handle(id))?;
306 Ok(read_store_reference(handle_data.handle))
307 }
308
309 pub fn load_mut(
317 &self,
318 id: Snowflake,
319 cm: Arc<ComponentManager<T>>,
320 ) -> Result<WriteReference<StoreHandle<T>>> {
321 let handle_data = self.initialize_handle(id, cm, self.get_handle(id))?;
322 Ok(write_store_reference(handle_data.handle))
323 }
324
325 pub fn store(&self, object: T) -> Result<()> {
328 let id = object.id();
329 let handle_data = self.get_handle(id);
330
331 let mut object: Option<T> = Some(object);
337 let mut initializer_result: Option<Result<()>> = None;
338
339 handle_data.initializer.call_once(|| {
340 let mut handle = handle_data.handle.write();
341 handle.set_object(object.take());
342 initializer_result = Some(handle.store());
343 });
344
345 if let Some(obj) = object {
346 let mut handle = handle_data.handle.write();
347 handle.set_object(Some(obj));
348 handle.store()
349 } else {
350 initializer_result.unwrap()
354 }
355 }
356
357 pub fn insert(&self, object: T) -> WriteReference<StoreHandle<T>> {
362 let id = object.id();
363 let handle_data = self.get_handle(id);
364
365 let mut object: Option<T> = Some(object);
371 let mut initializer_result: Option<WriteReference<StoreHandle<T>>> = None;
372
373 handle_data.initializer.call_once(|| {
374 let mut handle = write_store_reference(handle_data.handle.clone());
375 handle.set_object(object.take());
376 initializer_result = Some(handle);
377 });
378
379 if let Some(obj) = object {
380 let mut ret = write_store_reference(handle_data.handle.clone());
381 ret.set_object(Some(obj));
382 ret
383 } else {
384 initializer_result.unwrap()
388 }
389 }
390
391 pub fn delete(&self, id: Snowflake, cm: Arc<ComponentManager<T>>) -> Result<()> {
400 let mut handle = self.load_mut(id, cm)?;
401 handle.delete()
402 }
403
404 pub fn exists(&self, id: Snowflake) -> Result<bool> {
406 let handle_data = self.get_handle(id);
407
408 if handle_data.initializer.state().done() {
409 let read_lock = handle_data.handle.read();
410 Ok(read_lock.exists())
411 } else {
412 self.backend.exists(id)
413 }
414 }
415
416 pub fn keys(&self, page: u64, limit: u64) -> Result<Vec<Snowflake>> {
418 self.backend.keys(page, limit)
419 }
420}
421
422#[doc(hidden)]
429pub struct EntityStoreDowncastHelper<T: Entity + 'static>(pub Box<dyn EntityStore<T> + 'static>);
430
431#[doc(hidden)]
436pub trait EntityStoreDowncast: Downcast + Send + Sync + 'static {}
437downcast_rs::impl_downcast!(EntityStoreDowncast);
438
439impl<T: Entity + 'static> EntityStoreDowncast for EntityStoreDowncastHelper<T> {}
440
441pub trait EntityStore<T>: DowncastSync
451where
452 T: Entity + 'static,
453{
454 fn load(
455 &self,
456 id: Snowflake,
457 cm: Arc<ComponentManager<T>>,
458 ) -> Result<ReadReference<StoreHandle<T>>>;
459
460 fn load_mut(
461 &self,
462 id: Snowflake,
463 cm: Arc<ComponentManager<T>>,
464 ) -> Result<WriteReference<StoreHandle<T>>>;
465
466 fn store(&self, object: T) -> Result<()>;
467 fn insert(&self, object: T) -> WriteReference<StoreHandle<T>>;
468 fn delete(&self, id: Snowflake, cm: Arc<ComponentManager<T>>) -> Result<()>;
469 fn exists(&self, id: Snowflake) -> Result<bool>;
470 fn keys(&self, page: u64, limit: u64) -> Result<Vec<Snowflake>>;
471}
472
473downcast_rs::impl_downcast!(sync EntityStore<T> where T: Entity + 'static);
474
475impl<T, U> EntityStore<T> for Store<T, U>
476where
477 T: Entity + 'static,
478 U: EntityBackend<T> + Sync + Send + 'static,
479{
480 fn load(
481 &self,
482 id: Snowflake,
483 cm: Arc<ComponentManager<T>>,
484 ) -> Result<ReadReference<StoreHandle<T>>> {
485 self.load(id, cm)
486 }
487
488 fn load_mut(
489 &self,
490 id: Snowflake,
491 cm: Arc<ComponentManager<T>>,
492 ) -> Result<WriteReference<StoreHandle<T>>> {
493 self.load_mut(id, cm)
494 }
495
496 fn store(&self, object: T) -> Result<()> {
497 self.store(object)
498 }
499
500 fn insert(&self, object: T) -> WriteReference<StoreHandle<T>> {
501 self.insert(object)
502 }
503
504 fn delete(&self, id: Snowflake, cm: Arc<ComponentManager<T>>) -> Result<()> {
505 self.delete(id, cm)
506 }
507
508 fn exists(&self, id: Snowflake) -> Result<bool> {
509 self.exists(id)
510 }
511
512 fn keys(&self, page: u64, limit: u64) -> Result<Vec<Snowflake>> {
513 self.keys(page, limit)
514 }
515}
516
517impl<T, U> fmt::Debug for Store<T, U>
518where
519 T: Entity + 'static,
520 U: EntityBackend<T> + Sync + Send + 'static,
521{
522 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523 write!(
524 f,
525 "Store<{}, {}> {{ {} keys }}",
526 any::type_name::<T>(),
527 any::type_name::<U>(),
528 self.refs.len()
529 )
530 }
531}
532
533pub trait EntityBackend<T: Entity + 'static> {
539 fn load(&self, id: Snowflake, cm: Arc<ComponentManager<T>>) -> Result<Option<T>>;
542
543 fn exists(&self, id: Snowflake) -> Result<bool>;
545
546 fn store(&self, id: Snowflake, object: &T) -> Result<()>;
548
549 fn delete(&self, id: Snowflake) -> Result<()>;
551
552 fn keys(&self, page: u64, limit: u64) -> Result<Vec<Snowflake>>;
554}
555
556#[cfg(test)]
557mod tests {
558 use super::*;
559
560 use std::any::TypeId;
561 use std::collections::{HashMap, HashSet};
562 use std::sync::{mpsc, Arc, Barrier, RwLock};
563 use std::thread;
564
565 use dashmap::DashMap;
566
567 use crate::ecs::Component;
568 use crate::snowflake::SnowflakeGenerator;
569
570 struct MockStoredData {
571 id: Snowflake,
572 field_a: String,
573 field_b: u64,
574 cm: Arc<ComponentManager<MockStoredData>>,
575 components_attached: HashSet<TypeId>,
576 component_preloads: DashMap<TypeId, Box<dyn Component<Self> + Send + Sync + 'static>>,
577 dirty: bool,
578 }
579
580 impl MockStoredData {
581 fn new(
582 id: Snowflake,
583 field_a: String,
584 field_b: u64,
585 cm: Arc<ComponentManager<MockStoredData>>,
586 ) -> MockStoredData {
587 MockStoredData {
588 id,
589 field_a,
590 field_b,
591 cm,
592 components_attached: HashSet::new(),
593 component_preloads: DashMap::new(),
594 dirty: false,
595 }
596 }
597
598 fn id<'a>(&'a self) -> &'a Snowflake {
599 &self.id
600 }
601 }
602
603 impl Entity for MockStoredData {
604 fn new(
605 id: Snowflake,
606 cm: Arc<ComponentManager<Self>>,
607 _components: HashSet<TypeId>,
608 ) -> Self {
609 MockStoredData::new(id, String::from(""), 0, cm)
610 }
611
612 fn id(&self) -> Snowflake {
613 self.id
614 }
615
616 fn component_manager(&self) -> &ComponentManager<MockStoredData> {
617 &self.cm
618 }
619
620 fn components_attached(&self) -> &HashSet<TypeId> {
621 &self.components_attached
622 }
623
624 fn components_attached_mut(&mut self) -> &mut HashSet<TypeId> {
625 &mut self.components_attached
626 }
627
628 fn preloaded_components(
629 &self,
630 ) -> &DashMap<TypeId, Box<dyn Component<Self> + Send + Sync + 'static>> {
631 &self.component_preloads
632 }
633
634 fn dirty(&self) -> bool {
635 self.dirty
636 }
637
638 fn dirty_mut(&mut self) -> &mut bool {
639 &mut self.dirty
640 }
641 }
642
643 impl Clone for MockStoredData {
644 fn clone(&self) -> Self {
645 Self {
646 id: self.id,
647 dirty: self.dirty,
648 cm: self.cm.clone(),
649 components_attached: self.components_attached.clone(),
650 component_preloads: DashMap::new(),
651 field_a: self.field_a.clone(),
652 field_b: self.field_b,
653 }
654 }
655 }
656
657 struct MockEntityBackend {
658 data: RwLock<HashMap<Snowflake, MockStoredData>>,
659 remove_on_load: bool,
660 }
661
662 impl MockEntityBackend {
663 fn new() -> MockEntityBackend {
664 MockEntityBackend {
665 data: RwLock::new(HashMap::new()),
666 remove_on_load: false,
667 }
668 }
669
670 fn set_remove_on_load(&mut self, flag: bool) {
671 self.remove_on_load = flag;
672 }
673 }
674 impl EntityBackend<MockStoredData> for MockEntityBackend {
675 fn exists(&self, id: Snowflake) -> Result<bool> {
676 let map = self.data.read().unwrap();
677 Ok(map.contains_key(&id))
678 }
679
680 fn load(
681 &self,
682 id: Snowflake,
683 _cm: Arc<ComponentManager<MockStoredData>>,
684 ) -> Result<Option<MockStoredData>> {
685 if !self.remove_on_load {
686 let map = self.data.read().unwrap();
687 Ok(map.get(&id).map(|pl| pl.clone()))
688 } else {
689 let mut map = self.data.write().unwrap();
690 let res = Ok(map.get(&id).map(|pl| pl.clone()));
691 map.remove(&id);
692 res
693 }
694 }
695
696 fn store(&self, id: Snowflake, data: &MockStoredData) -> Result<()> {
697 let mut map = self.data.write().unwrap();
698 map.insert(id, data.clone());
699
700 Ok(())
701 }
702
703 fn delete(&self, id: Snowflake) -> Result<()> {
704 let mut map = self.data.write().unwrap();
705 map.remove(&id);
706
707 Ok(())
708 }
709
710 fn keys(&self, page: u64, limit: u64) -> Result<Vec<Snowflake>> {
711 let ids: Vec<Snowflake>;
712 let start_index = page * limit;
713
714 let data = self.data.read().unwrap();
715 ids = data
716 .keys()
717 .skip(start_index as usize)
718 .take(limit as usize)
719 .map(|x| *x)
720 .collect();
721
722 Ok(ids)
723 }
724 }
725
726 type MockStore = Store<MockStoredData, MockEntityBackend>;
727
728 #[test]
729 fn test_exists() {
730 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
731 let backend = Arc::new(MockEntityBackend::new());
732 let data = MockStoredData::new(
733 snowflake_gen.generate(),
734 "foo".to_owned(),
735 1,
736 Arc::new(ComponentManager::new()),
737 );
738
739 backend.store(*data.id(), &data).unwrap();
740 let store = MockStore::new(backend);
741
742 let id2 = snowflake_gen.generate();
743 assert!(store.exists(*data.id()).unwrap());
744 assert!(!store.exists(id2).unwrap());
745 }
746
747 #[test]
748 fn test_load_nonexistent() {
749 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
750 let backend = Arc::new(MockEntityBackend::new());
751 let store = MockStore::new(backend);
752 let handle = store
753 .load(snowflake_gen.generate(), Arc::new(ComponentManager::new()))
754 .unwrap();
755
756 assert!(!handle.exists());
757 }
758
759 #[test]
760 fn test_load() {
761 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
762 let backend = Arc::new(MockEntityBackend::new());
763 let data = MockStoredData::new(
764 snowflake_gen.generate(),
765 "foo".to_owned(),
766 1,
767 Arc::new(ComponentManager::new()),
768 );
769
770 backend.store(*data.id(), &data).unwrap();
771 let store = MockStore::new(backend);
772
773 let handle = store
774 .load(*data.id(), Arc::new(ComponentManager::new()))
775 .unwrap();
776
777 assert!(handle.exists());
778 let data_copy = handle.get().unwrap();
779
780 assert_eq!(*data.id(), *data_copy.id());
781 assert_eq!(data.field_a, data_copy.field_a);
782 assert_eq!(data.field_b, data_copy.field_b);
783 }
784
785 #[test]
786 fn test_concurrent_load() {
787 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
789 let backend = Arc::new(MockEntityBackend::new());
790 let id = snowflake_gen.generate();
791 let data = MockStoredData::new(id, "foo".to_owned(), 1, Arc::new(ComponentManager::new()));
792 backend.store(id, &data).unwrap();
793
794 let store = Arc::new(MockStore::new(backend));
798 let mut threads = Vec::with_capacity(9);
799 let barrier = Arc::new(Barrier::new(10));
800
801 for _ in 0..9 {
802 let b_clone = barrier.clone();
803 let s_clone = store.clone();
804
805 let handle = thread::spawn(move || {
806 b_clone.wait();
807 let wrapper = s_clone.get_handle(id);
808 wrapper
809 });
810
811 threads.push(handle);
812 }
813
814 barrier.wait();
815 let our_wrapper = store.get_handle(id);
816
817 for thread in threads {
818 let their_wrapper = thread.join().unwrap();
822 assert!(Arc::ptr_eq(&our_wrapper.handle, &their_wrapper.handle));
823 }
824 }
825
826 #[test]
827 fn test_concurrent_access() {
828 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
830 let mut backend = MockEntityBackend::new();
831 let id = snowflake_gen.generate();
832 let data = MockStoredData::new(id, "foo".to_owned(), 1, Arc::new(ComponentManager::new()));
833
834 backend.set_remove_on_load(true);
836 backend.store(id, &data).unwrap();
837
838 let store = Arc::new(MockStore::new(Arc::new(backend)));
844 let barrier = Arc::new(Barrier::new(10));
845 let mut threads = Vec::with_capacity(9);
846 let (tx, rx) = mpsc::channel();
847
848 for _ in 0..9 {
849 let b_clone = barrier.clone();
850 let s_clone = store.clone();
851 let tx_clone = tx.clone();
852
853 let handle = thread::spawn(move || {
854 b_clone.wait();
855 let handle = s_clone.load(id, Arc::new(ComponentManager::new())).unwrap();
856 let data = handle.get().unwrap();
857
858 tx_clone
859 .send((data.id, data.field_a.clone(), data.field_b))
860 .unwrap();
861
862 b_clone.wait();
865 assert_eq!(data.id, id);
866 });
867
868 threads.push(handle);
869 }
870
871 {
874 barrier.wait();
875 let handle = store.load(id, Arc::new(ComponentManager::new())).unwrap();
876 let data = handle.get().unwrap();
877
878 for _ in 0..9 {
880 let their_data = rx.recv().unwrap();
881
882 assert_eq!(data.id, their_data.0);
883 assert_eq!(data.field_a, their_data.1);
884 assert_eq!(data.field_b, their_data.2);
885 }
886 }
887
888 barrier.wait();
892 for thread in threads {
893 thread.join().unwrap();
894 }
895
896 let handle = store.load(id, Arc::new(ComponentManager::new())).unwrap();
900 let data = handle.get();
901 assert!(data.is_none());
902 }
903
904 #[test]
905 fn test_multiple_single_thread_access() {
906 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
908 let backend = MockEntityBackend::new();
909 let id = snowflake_gen.generate();
910 let data = MockStoredData::new(id, "foo".to_owned(), 1, Arc::new(ComponentManager::new()));
911 backend.store(id, &data).unwrap();
912
913 let store = MockStore::new(Arc::new(backend));
914
915 let handle_1 = store.load(id, Arc::new(ComponentManager::new())).unwrap();
922 let data_1 = handle_1.get().unwrap();
923
924 let handle_2 = store.load(id, Arc::new(ComponentManager::new())).unwrap();
925 let data_2 = handle_2.get().unwrap();
926
927 assert_eq!(data_1.id, data_2.id);
928 assert_eq!(data_1.field_a, data_2.field_a);
929 assert_eq!(data_1.field_b, data_2.field_b);
930
931 assert_eq!(data_1.id, data.id);
932 assert_eq!(data_1.field_a, data.field_a);
933 assert_eq!(data_1.field_b, data.field_b);
934 }
935
936 #[test]
937 fn test_store() {
938 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
939 let id = snowflake_gen.generate();
940 let cm = Arc::new(ComponentManager::new());
941 let data = MockStoredData::new(id, "foo".to_owned(), 1, cm.clone());
942
943 let backend = Arc::new(MockEntityBackend::new());
944 let store = MockStore::new(backend);
945
946 {
947 let mut handle = store.load_mut(*data.id(), cm.clone()).unwrap();
948 assert!(!handle.exists());
949
950 handle.replace(data.clone());
951 handle.store().unwrap();
952 }
953
954 let handle = store.load(*data.id(), cm).unwrap();
955 let data_copy = handle.get().unwrap();
956
957 assert_eq!(*data_copy.id(), id);
958 assert_eq!(data.field_a, data_copy.field_a);
959 assert_eq!(data.field_b, data_copy.field_b);
960 }
961
962 #[test]
963 fn test_handle_drop() {
964 use super::ComponentManager;
965 use crate::local_storage::LocalComponentStorage;
966 use crate::Component;
967
968 #[derive(Clone)]
969 struct TestComponent(u64);
970 impl Component<MockStoredData> for TestComponent {};
971
972 let backend = Arc::new(MockEntityBackend::new());
973 let store = MockStore::new(backend);
974 let mut cm: ComponentManager<MockStoredData> = ComponentManager::new();
975
976 cm.register_component(
977 "TestComponent",
978 LocalComponentStorage::<MockStoredData, TestComponent>::new(),
979 )
980 .unwrap();
981
982 let cm = Arc::new(cm);
983
984 let mut snowflake_gen = SnowflakeGenerator::new(0, 0);
985 let id = snowflake_gen.generate();
986
987 {
988 let data = MockStoredData::new(id, "foo".to_owned(), 1, cm.clone());
989
990 let mut handle = store.insert(data);
991 let data = handle.get_mut().unwrap();
992
993 data.set_component(TestComponent(50)).unwrap();
994 }
995
996 let handle = store.load(id, cm.clone()).unwrap();
997 let data = handle.get().unwrap();
998 let component: TestComponent = data.get_component().unwrap().unwrap();
999
1000 assert_eq!(component.0, 50);
1001 }
1002}