mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
create component is only borked not crash
This commit is contained in:
parent
49f6999bc4
commit
448ddcaeab
4 changed files with 128 additions and 43 deletions
|
@ -156,6 +156,9 @@ impl Ord for StdString {
|
|||
pub struct CString(pub *const u8);
|
||||
impl Display for CString {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
if self.0.is_null() {
|
||||
return write!(f, "");
|
||||
}
|
||||
let mut string = String::new();
|
||||
unsafe {
|
||||
let mut ptr = self.0;
|
||||
|
@ -212,7 +215,11 @@ impl<T> IndexMut<usize> for StdVec<T> {
|
|||
}
|
||||
impl<T> AsRef<[T]> for StdVec<T> {
|
||||
fn as_ref(&self) -> &[T] {
|
||||
unsafe { slice::from_raw_parts(self.start, self.len()) }
|
||||
if self.start.is_null() {
|
||||
&[]
|
||||
} else {
|
||||
unsafe { slice::from_raw_parts(self.start, self.len()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> AsMut<[T]> for StdVec<T> {
|
||||
|
@ -326,10 +333,10 @@ impl<T> StdVec<T> {
|
|||
}
|
||||
}
|
||||
pub fn last(&self) -> Option<&T> {
|
||||
unsafe { self.end.as_ref() }
|
||||
unsafe { self.end.sub(1).as_ref() }
|
||||
}
|
||||
pub fn last_mut(&mut self) -> Option<&mut T> {
|
||||
unsafe { self.end.as_mut() }
|
||||
unsafe { self.end.sub(1).as_mut() }
|
||||
}
|
||||
pub fn insert(&mut self, index: usize, value: T) {
|
||||
self.alloc(1);
|
||||
|
@ -365,12 +372,34 @@ pub struct StdMapNode<K, V> {
|
|||
pub key: K,
|
||||
pub value: V,
|
||||
}
|
||||
impl<K: Default, V: Default> Default for StdMapNode<K, V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
left: ptr::null_mut(),
|
||||
parent: ptr::null_mut(),
|
||||
right: ptr::null_mut(),
|
||||
color: false,
|
||||
end: false,
|
||||
unk: [0, 0],
|
||||
key: Default::default(),
|
||||
value: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct StdMap<K, V> {
|
||||
pub root: *mut StdMapNode<K, V>,
|
||||
pub len: usize,
|
||||
}
|
||||
impl<K: Default, V: Default> Default for StdMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
root: Box::leak(Box::new(StdMapNode::default())),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<K: Debug + 'static, V: Debug + 'static> Debug for StdMap<K, V> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("StdMap")
|
||||
|
|
|
@ -21,7 +21,7 @@ impl Default for ComponentData {
|
|||
Self {
|
||||
vtable: &ComponentVTable {},
|
||||
local_id: 0,
|
||||
type_name: CString(std::ptr::null()),
|
||||
type_name: CString(ptr::null()),
|
||||
type_id: 0,
|
||||
id: 0,
|
||||
enabled: false,
|
||||
|
@ -43,7 +43,7 @@ pub struct ComponentManagerVTable {
|
|||
//TODO should be a union
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ComponentTypeManager {
|
||||
pub next_id: usize,
|
||||
pub component_buffer_indices: StdMap<StdString, usize>,
|
||||
|
@ -73,16 +73,59 @@ impl ComponentTypeManager {
|
|||
}
|
||||
#[test]
|
||||
fn test_com_create() {
|
||||
let com_buffer = ComponentBuffer {
|
||||
vtable: &ComponentManagerVTable {},
|
||||
end: usize::MAX,
|
||||
unk: [0, 0],
|
||||
entity_entry: StdVec::new(),
|
||||
entities: StdVec::new(),
|
||||
prev: StdVec::new(),
|
||||
next: StdVec::new(),
|
||||
component_list: StdVec::new(),
|
||||
};
|
||||
let mut em = EntityManager::default();
|
||||
let cm = &mut ComponentTypeManager::default();
|
||||
let id = &mut 0;
|
||||
{
|
||||
let mut com_buffer = ComponentBuffer::default();
|
||||
let com = &mut com_buffer as *mut _;
|
||||
em.component_buffers.push(com);
|
||||
let mut node = crate::noita::types::StdMapNode::default();
|
||||
node.key = StdString::from_str("WalletComponent");
|
||||
node.value = 0usize;
|
||||
unsafe { cm.component_buffer_indices.root.as_mut().unwrap() }.parent = &mut node as *mut _;
|
||||
}
|
||||
let ent = em.create();
|
||||
{
|
||||
em.create_component::<crate::noita::types::WalletComponent>(ent, id, cm);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
);
|
||||
em.create_component::<crate::noita::types::WalletComponent>(ent, id, cm);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
);
|
||||
em.create_component::<crate::noita::types::WalletComponent>(ent, id, cm);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
);
|
||||
em.create_component::<crate::noita::types::WalletComponent>(ent, id, cm);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
);
|
||||
}
|
||||
let mut coms = em.iter_components::<crate::noita::types::WalletComponent>(ent.entry, cm);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
.component_list
|
||||
);
|
||||
println!(
|
||||
"{:?}",
|
||||
em.get_component_buffer::<crate::noita::types::WalletComponent>(cm)
|
||||
.component_list
|
||||
.get(0)
|
||||
);
|
||||
println!("{:?}", coms.next());
|
||||
println!("{:?}", coms.next());
|
||||
println!("{:?}", coms.next());
|
||||
println!("{:?}", coms.next());
|
||||
println!("{:?}", coms.next());
|
||||
println!("{:?}", coms.next());
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
|
@ -96,6 +139,20 @@ pub struct ComponentBuffer {
|
|||
pub next: StdVec<usize>,
|
||||
pub component_list: StdVec<*mut ComponentData>,
|
||||
}
|
||||
impl Default for ComponentBuffer {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
vtable: &ComponentManagerVTable {},
|
||||
end: (-1isize).cast_unsigned(),
|
||||
unk: [0, 0],
|
||||
entity_entry: Default::default(),
|
||||
entities: Default::default(),
|
||||
prev: Default::default(),
|
||||
next: Default::default(),
|
||||
component_list: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ComponentBuffer {
|
||||
pub fn create<C: Component>(
|
||||
&mut self,
|
||||
|
@ -103,21 +160,20 @@ impl ComponentBuffer {
|
|||
id: usize,
|
||||
type_id: usize,
|
||||
) -> &'static mut C {
|
||||
crate::print!("{id} {type_id} {}", entity.entry);
|
||||
let com = C::default(ComponentData {
|
||||
vtable: self
|
||||
.component_list
|
||||
.as_ref()
|
||||
.iter()
|
||||
.find_map(|a| unsafe { a.as_ref().map(|a| a.vtable) })
|
||||
.unwrap(),
|
||||
.unwrap_or(&ComponentVTable {}),
|
||||
local_id: self.component_list.len(),
|
||||
type_name: self
|
||||
.component_list
|
||||
.as_ref()
|
||||
.iter()
|
||||
.find_map(|a| unsafe { a.as_ref().map(|a| CString(a.type_name.0)) })
|
||||
.unwrap(),
|
||||
.unwrap_or(CString(ptr::null_mut())),
|
||||
type_id,
|
||||
id,
|
||||
enabled: false,
|
||||
|
@ -128,14 +184,6 @@ impl ComponentBuffer {
|
|||
});
|
||||
let com = Box::leak(Box::new(com));
|
||||
let index = self.component_list.len();
|
||||
crate::print!(
|
||||
"{index} {} {} {} {} {:?}",
|
||||
self.component_list.len(),
|
||||
self.entities.len(),
|
||||
self.next.len(),
|
||||
self.prev.len(),
|
||||
self.next
|
||||
);
|
||||
self.component_list.push((com as *mut C).cast());
|
||||
if self.entities.len() > index {
|
||||
self.entities[index] = entity;
|
||||
|
@ -145,43 +193,39 @@ impl ComponentBuffer {
|
|||
}
|
||||
self.entities.push(entity);
|
||||
}
|
||||
crate::print!("a");
|
||||
while self.entity_entry.len() <= entity.entry {
|
||||
self.entity_entry.push(self.end)
|
||||
}
|
||||
let mut off;
|
||||
let mut last = self.end;
|
||||
if let Some(e) = self.entity_entry.get(entity.entry).copied()
|
||||
&& e != self.end
|
||||
{
|
||||
off = e;
|
||||
crate::print!("b");
|
||||
while let Some(next) = self.next.get(off).copied()
|
||||
&& next != self.end
|
||||
{
|
||||
while let Some(next) = self.next.get(off).copied() {
|
||||
last = off;
|
||||
if next == self.end {
|
||||
break;
|
||||
}
|
||||
off = next;
|
||||
}
|
||||
crate::print!("c");
|
||||
while self.next.len() <= index {
|
||||
self.next.push(self.end)
|
||||
}
|
||||
self.next[off] = index;
|
||||
while self.prev.len() <= index {
|
||||
self.prev.push(self.end)
|
||||
}
|
||||
self.prev[index] = last;
|
||||
} else {
|
||||
off = index;
|
||||
self.entity_entry[entity.entry] = off;
|
||||
crate::print!("c");
|
||||
while self.next.len() <= index {
|
||||
self.next.push(self.end)
|
||||
}
|
||||
self.next[off] = self.end;
|
||||
}
|
||||
crate::print!("d");
|
||||
while self.prev.len() <= index {
|
||||
self.prev.push(self.end)
|
||||
}
|
||||
crate::print!("{off}");
|
||||
self.prev[index] = off;
|
||||
crate::print!("e");
|
||||
unsafe { std::mem::transmute(self.component_list.last_mut().unwrap()) }
|
||||
com
|
||||
}
|
||||
pub fn iter_components(&self, entry: usize) -> ComponentIter {
|
||||
if let Some(off) = self.entity_entry.get(entry) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::noita::types::*;
|
||||
pub trait Component {
|
||||
pub trait Component: Debug {
|
||||
fn default(base: ComponentData) -> Self;
|
||||
const NAME: &'static str;
|
||||
const STD_NAME: &'static StdString = &StdString::from_str(Self::NAME);
|
||||
|
|
|
@ -76,8 +76,8 @@ impl EntityManager {
|
|||
}
|
||||
pub fn get_entities_with_tag(
|
||||
&self,
|
||||
tag_manager: &TagManager<u16>,
|
||||
tag: &StdString,
|
||||
tag_manager: &TagManager<u16>,
|
||||
) -> impl DoubleEndedIterator<Item = &'static Entity> {
|
||||
let n = *tag_manager.tag_indices.get(tag).unwrap();
|
||||
self.entity_buckets
|
||||
|
@ -743,6 +743,18 @@ pub struct EntityManager {
|
|||
pub entity_buckets: StdVec<StdVec<*mut Entity>>,
|
||||
pub component_buffers: StdVec<*mut ComponentBuffer>,
|
||||
}
|
||||
impl Default for EntityManager {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
vtable: &EntityManagerVTable {},
|
||||
max_entity_id: 0,
|
||||
free_ids: Default::default(),
|
||||
entities: Default::default(),
|
||||
entity_buckets: Default::default(),
|
||||
component_buffers: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct EntityManagerVTable {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue