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
use crate::descriptors::archetype_descriptor::ArchetypeDescriptor;
use crate::*;
use alloc::alloc::{alloc, Layout};
use core::mem::{align_of, size_of};
use crate::constants::DEFAULT_ARCHETYPE_ALLOCATION_SIZE;
mod data_access;
#[cfg(test)]
mod tests;
#[derive(Debug)]
pub struct Archetype {
descriptor: ArchetypeDescriptor,
pointers: [*mut u8; MAX_COMPONENTS_PER_ENTITY],
entity_associations: *mut Entity,
entity_count: u32,
capacity: u32,
}
unsafe impl Send for Archetype {}
unsafe impl Sync for Archetype {}
impl Archetype {
#[allow(dead_code)]
pub fn new(archetype_descriptor: &ArchetypeDescriptor) -> Archetype {
assert!(archetype_descriptor.is_valid());
Self::with_capacity(
archetype_descriptor,
DEFAULT_ARCHETYPE_ALLOCATION_SIZE as u32,
)
}
pub fn with_capacity(archetype_descriptor: &ArchetypeDescriptor, capacity: u32) -> Archetype {
assert!(archetype_descriptor.is_valid());
let mut archetype = Self {
descriptor: archetype_descriptor.clone(),
pointers: [core::ptr::null_mut(); MAX_COMPONENTS_PER_ENTITY],
entity_associations: core::ptr::null_mut(),
entity_count: 0,
capacity: 0,
};
if capacity > 0 && capacity <= MAX_ENTITIES_PER_ARCHETYPE {
unsafe {
let layout = Layout::from_size_align_unchecked(
size_of::<Entity>() * capacity as usize,
align_of::<Entity>(),
);
archetype.entity_associations = alloc(layout) as *mut Entity;
assert_ne!(archetype.entity_associations, core::ptr::null_mut());
for (index, component) in archetype.descriptor.components().iter().enumerate() {
let layout = Layout::from_size_align_unchecked(
component.size as usize * capacity as usize,
component.align as usize,
);
archetype.pointers[index] = alloc(layout);
assert_ne!(archetype.pointers[index], core::ptr::null_mut());
}
archetype.capacity = capacity;
}
}
archetype
}
pub fn descriptor(&self) -> &ArchetypeDescriptor {
&self.descriptor
}
}
impl Drop for Archetype {
fn drop(&mut self) {
if self.capacity == 0 {
return;
}
unsafe {
self.drop_entities();
self.dealloc();
}
}
}