1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::*;
use extend_lifetime::extend_lifetime;
use std::cell::{Ref, RefCell};
use std::rc::Rc;

pub struct PerArchetype<T> {
    cell: RefCell<BorrowedPerArchetype<T>>,
}

pub struct BorrowedPerArchetype<T> {
    version: Version,
    value: T,
}

impl<T> BorrowedPerArchetype<T> {
    pub fn new(value: T) -> Self {
        Self {
            value,
            version: Version(0),
        }
    }
}

impl<T: 'static> BorrowedStorage for BorrowedPerArchetype<T> {
    type Item = &'static T;
    type Batch = &'static T;
    #[inline(always)]
    fn read(&self, _index: usize) -> Option<Self::Item> {
        // See also 0a427633-4da0-4729-bae6-45d77542261c
        unsafe { extend_lifetime(Some(&self.value)) }
    }
    fn read_batch(&self) -> Self::Batch {
        // See also 0a427633-4da0-4729-bae6-45d77542261c
        unsafe { extend_lifetime(&self.value) }
    }
    #[inline(always)]
    fn version(&self) -> Version {
        self.version
    }
}

impl<T> PerArchetype<T> {
    pub fn new(value: T) -> Self {
        let cell = RefCell::new(BorrowedPerArchetype::new(value));
        Self { cell }
    }
}

impl<T: 'static> AnyStorage for PerArchetype<T> {}

impl<T: 'static> ReadableStorage for PerArchetype<T> {
    type Read = Rc<Self>;
    fn get(_world_storage: &Components, archetype_storage: &Components) -> Option<Self::Read> {
        archetype_storage.get_storage::<Self>()
    }
}

impl<T: 'static> RefLike for PerArchetype<T> {
    type Borrowed = Ref<'static, BorrowedPerArchetype<T>>;
    fn borrow(&self) -> Self::Borrowed {
        // See also 0a427633-4da0-4729-bae6-45d77542261c
        unsafe { extend_lifetime(self.cell.borrow()) }
    }
}

impl<T: Component<Storage = PerArchetype<T>>> ArchetypeInitializerFromComponentStorage
    for PerArchetype<T>
{
    type Component = T;
    fn initialize(component: T, archetype: &mut Archetype) {
        let storage = Self::new(component); // FIXME Version
        archetype.add_component::<T>(storage);
    }
}

impl<T: Component<Storage = PerArchetype<T>> + Eq> ArchetypeFilterFromComponentStorage
    for PerArchetype<T>
{
    type Component = T;
    fn includes(component: &T, archetype: &Archetype) -> bool {
        let storage = archetype.get_storage::<Self>();
        if let Some(storage) = storage {
            &storage.borrow().value == component
        } else {
            false
        }
    }
}

impl<T: Component<Storage = PerArchetype<T>>> EntityWriterFromComponentStorage for PerArchetype<T> {
    type Component = T;
    #[inline]
    fn write(_component: T, _archetype: &mut Archetype, _index: usize) {}
}