more create component work, still crashes(i dont like component buffers type)

This commit is contained in:
bgkillas 2025-08-15 18:03:01 -04:00
parent 1919f38b09
commit fe386ac2ff
3 changed files with 111 additions and 38 deletions

View file

@ -51,6 +51,7 @@ pub struct GlobalsRef {
pub filenames: &'static StdVec<StdString>, pub filenames: &'static StdVec<StdString>,
pub inventory: &'static Inventory, pub inventory: &'static Inventory,
pub mods: &'static Mods, pub mods: &'static Mods,
pub max_component: &'static usize,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct GlobalsMut { pub struct GlobalsMut {
@ -67,6 +68,7 @@ pub struct GlobalsMut {
pub filenames: &'static mut StdVec<StdString>, pub filenames: &'static mut StdVec<StdString>,
pub inventory: &'static mut Inventory, pub inventory: &'static mut Inventory,
pub mods: &'static mut Mods, pub mods: &'static mut Mods,
pub max_component: &'static mut usize,
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -84,6 +86,7 @@ pub struct Globals {
pub filenames: *mut StdVec<StdString>, pub filenames: *mut StdVec<StdString>,
pub inventory: *mut Inventory, pub inventory: *mut Inventory,
pub mods: *mut Mods, pub mods: *mut Mods,
pub max_component: *mut usize,
} }
#[allow(clippy::mut_from_ref)] #[allow(clippy::mut_from_ref)]
impl Globals { impl Globals {
@ -132,6 +135,9 @@ impl Globals {
pub fn mods(&self) -> &'static Mods { pub fn mods(&self) -> &'static Mods {
unsafe { self.mods.as_ref().unwrap() } unsafe { self.mods.as_ref().unwrap() }
} }
pub fn max_component(&self) -> &'static usize {
unsafe { self.max_component.as_ref().unwrap() }
}
pub fn world_seed_mut(&self) -> &'static mut usize { pub fn world_seed_mut(&self) -> &'static mut usize {
unsafe { self.world_seed.as_mut().unwrap() } unsafe { self.world_seed.as_mut().unwrap() }
} }
@ -177,6 +183,9 @@ impl Globals {
pub fn mods_mut(&self) -> &'static mut Mods { pub fn mods_mut(&self) -> &'static mut Mods {
unsafe { self.mods.as_mut().unwrap() } unsafe { self.mods.as_mut().unwrap() }
} }
pub fn max_component_mut(&self) -> &'static mut usize {
unsafe { self.max_component.as_mut().unwrap() }
}
pub fn as_ref(&self) -> GlobalsRef { pub fn as_ref(&self) -> GlobalsRef {
GlobalsRef { GlobalsRef {
world_seed: self.world_seed(), world_seed: self.world_seed(),
@ -192,6 +201,7 @@ impl Globals {
filenames: self.filenames(), filenames: self.filenames(),
inventory: self.inventory(), inventory: self.inventory(),
mods: self.mods(), mods: self.mods(),
max_component: self.max_component(),
} }
} }
pub fn as_mut(&self) -> GlobalsMut { pub fn as_mut(&self) -> GlobalsMut {
@ -209,6 +219,7 @@ impl Globals {
filenames: self.filenames_mut(), filenames: self.filenames_mut(),
inventory: self.inventory_mut(), inventory: self.inventory_mut(),
mods: self.mods_mut(), mods: self.mods_mut(),
max_component: self.max_component_mut(),
} }
} }
pub fn new(lua: LuaState) -> Self { pub fn new(lua: LuaState) -> Self {
@ -230,6 +241,7 @@ impl Globals {
let filenames = 0x1207bd4 as *mut StdVec<StdString>; let filenames = 0x1207bd4 as *mut StdVec<StdString>;
let inventory = 0x12224f0 as *mut Inventory; let inventory = 0x12224f0 as *mut Inventory;
let mods = 0x1207e90 as *mut Mods; let mods = 0x1207e90 as *mut Mods;
let max_component = 0x1152ff0 as *mut usize;
Self { Self {
world_seed, world_seed,
new_game_count, new_game_count,
@ -244,6 +256,7 @@ impl Globals {
filenames, filenames,
inventory, inventory,
mods, mods,
max_component,
} }
} }
} }

View file

@ -1,6 +1,7 @@
use crate::noita::types::{ use crate::noita::types::{
BitSet, CString, Component, Entity, EntityManager, StdMap, StdString, StdVec, TagManager, BitSet, CString, Component, Entity, EntityManager, StdMap, StdString, StdVec, TagManager,
}; };
use std::ptr;
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct ComponentData { pub struct ComponentData {
@ -83,7 +84,12 @@ pub struct ComponentBuffer {
pub component_list: StdVec<*mut ComponentData>, pub component_list: StdVec<*mut ComponentData>,
} }
impl ComponentBuffer { impl ComponentBuffer {
pub fn create<C: Component>(&mut self, entry: usize, id: usize) -> &'static mut C { pub fn create<C: Component>(
&mut self,
entity: &mut Entity,
id: usize,
type_id: usize,
) -> &'static mut C {
let com = C::default(ComponentData { let com = C::default(ComponentData {
vtable: self vtable: self
.component_list .component_list
@ -91,14 +97,14 @@ impl ComponentBuffer {
.iter() .iter()
.find_map(|a| unsafe { a.as_ref().map(|a| a.vtable) }) .find_map(|a| unsafe { a.as_ref().map(|a| a.vtable) })
.unwrap(), .unwrap(),
local_id: 0, local_id: self.component_list.len(),
type_name: self type_name: self
.component_list .component_list
.as_ref() .as_ref()
.iter() .iter()
.find_map(|a| unsafe { a.as_ref().map(|a| CString(a.type_name.0)) }) .find_map(|a| unsafe { a.as_ref().map(|a| CString(a.type_name.0)) })
.unwrap(), .unwrap(),
type_id: 0, type_id,
id, id,
enabled: false, enabled: false,
unk2: [0; 3], unk2: [0; 3],
@ -109,16 +115,31 @@ impl ComponentBuffer {
let com = Box::leak(Box::new(com)); let com = Box::leak(Box::new(com));
let index = self.component_list.len(); let index = self.component_list.len();
self.component_list.push((com as *mut C).cast()); self.component_list.push((com as *mut C).cast());
while self.entity_entry.len() <= entry { if self.entities.len() > index {
self.entities[index] = entity;
} else {
while self.entities.len() < index {
self.entities.push(ptr::null_mut())
}
self.entities.push(entity);
}
while self.entity_entry.len() <= entity.entry {
self.entity_entry.push(self.end) self.entity_entry.push(self.end)
} }
let mut off = entry; let mut off;
while let Some(next) = self.next.get(off).copied() if let Some(e) = self.entity_entry.get(entity.entry).copied()
&& next != self.end && e != self.end
{ {
off = next off = e;
while let Some(next) = self.next.get(off).copied()
&& next != self.end
{
off = next;
}
} else {
off = self.next.len();
self.entity_entry[entity.entry] = off;
} }
self.entity_entry[entry] = off;
while self.next.len() <= off { while self.next.len() <= off {
self.next.push(self.end) self.next.push(self.end)
} }
@ -135,6 +156,7 @@ impl ComponentBuffer {
component_list: self.component_list.copy(), component_list: self.component_list.copy(),
off: *off, off: *off,
next: self.next.copy(), next: self.next.copy(),
prev: self.prev.copy(),
end: self.end, end: self.end,
} }
} else { } else {
@ -142,6 +164,7 @@ impl ComponentBuffer {
component_list: StdVec::null(), component_list: StdVec::null(),
off: 0, off: 0,
next: StdVec::null(), next: StdVec::null(),
prev: StdVec::null(),
end: 0, end: 0,
} }
} }
@ -152,6 +175,7 @@ impl ComponentBuffer {
component_list: self.component_list.copy(), component_list: self.component_list.copy(),
off: *off, off: *off,
next: self.next.copy(), next: self.next.copy(),
prev: self.prev.copy(),
end: self.end, end: self.end,
} }
} else { } else {
@ -159,6 +183,7 @@ impl ComponentBuffer {
component_list: StdVec::null(), component_list: StdVec::null(),
off: 0, off: 0,
next: StdVec::null(), next: StdVec::null(),
prev: StdVec::null(),
end: 0, end: 0,
} }
} }
@ -243,6 +268,7 @@ pub struct ComponentIter {
off: usize, off: usize,
end: usize, end: usize,
next: StdVec<usize>, next: StdVec<usize>,
prev: StdVec<usize>,
} }
impl Iterator for ComponentIter { impl Iterator for ComponentIter {
@ -258,12 +284,26 @@ impl Iterator for ComponentIter {
} }
} }
} }
impl DoubleEndedIterator for ComponentIter {
fn next_back(&mut self) -> Option<Self::Item> {
unsafe {
if self.off == self.end {
return None;
}
let com = self.component_list.get(self.off)?.as_ref();
self.off = *self.prev.get(self.off)?;
com
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct ComponentIterMut { pub struct ComponentIterMut {
component_list: StdVec<*mut ComponentData>, component_list: StdVec<*mut ComponentData>,
off: usize, off: usize,
end: usize, end: usize,
next: StdVec<usize>, next: StdVec<usize>,
prev: StdVec<usize>,
} }
impl Iterator for ComponentIterMut { impl Iterator for ComponentIterMut {
@ -279,6 +319,18 @@ impl Iterator for ComponentIterMut {
} }
} }
} }
impl DoubleEndedIterator for ComponentIterMut {
fn next_back(&mut self) -> Option<Self::Item> {
unsafe {
if self.off == self.end {
return None;
}
let com = self.component_list.get(self.off)?.as_mut();
self.off = *self.prev.get(self.off)?;
com
}
}
}
impl BitSet<8> { impl BitSet<8> {
pub fn get(&self, n: u8) -> bool { pub fn get(&self, n: u8) -> bool {
let out_index = n / 32; let out_index = n / 32;

View file

@ -176,8 +176,8 @@ impl EntityManager {
} }
pub fn iter_components<C: Component + 'static>( pub fn iter_components<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> impl Iterator<Item = &'static C> { ) -> impl Iterator<Item = &'static C> {
let index = component_type_manager let index = component_type_manager
.component_buffer_indices .component_buffer_indices
@ -192,8 +192,8 @@ impl EntityManager {
} }
pub fn iter_components_mut<C: Component + 'static>( pub fn iter_components_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> impl Iterator<Item = &'static mut C> { ) -> impl Iterator<Item = &'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -202,8 +202,8 @@ impl EntityManager {
} }
pub fn iter_enabled_components<C: Component + 'static>( pub fn iter_enabled_components<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> impl Iterator<Item = &'static C> { ) -> impl Iterator<Item = &'static C> {
component_type_manager component_type_manager
.get::<C>(self) .get::<C>(self)
@ -212,8 +212,8 @@ impl EntityManager {
} }
pub fn iter_enabled_components_mut<C: Component + 'static>( pub fn iter_enabled_components_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> impl Iterator<Item = &'static mut C> { ) -> impl Iterator<Item = &'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -222,8 +222,8 @@ impl EntityManager {
} }
pub fn iter_disabled_components<C: Component + 'static>( pub fn iter_disabled_components<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> impl Iterator<Item = &'static C> { ) -> impl Iterator<Item = &'static C> {
component_type_manager component_type_manager
.get::<C>(self) .get::<C>(self)
@ -232,8 +232,8 @@ impl EntityManager {
} }
pub fn iter_disabled_components_mut<C: Component + 'static>( pub fn iter_disabled_components_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> impl Iterator<Item = &'static mut C> { ) -> impl Iterator<Item = &'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -242,32 +242,40 @@ impl EntityManager {
} }
pub fn create_component<C: Component + 'static>( pub fn create_component<C: Component + 'static>(
&mut self, &mut self,
entry: usize, entity: &mut Entity,
component_type_manager: &'static mut ComponentTypeManager, max_component: &mut usize,
) -> &'static mut C { component_type_manager: &mut ComponentTypeManager,
let id = component_type_manager.next_id; ) -> &mut C {
component_type_manager.next_id += 1; let index = component_type_manager
let buffer = self.get_component_buffer_mut::<C>(component_type_manager); .component_buffer_indices
buffer.create::<C>(entry, id) .get(C::STD_NAME)
.copied()
.unwrap();
let mgr = self.component_buffers.get(index).unwrap();
let com = unsafe { mgr.as_mut() }
.unwrap()
.create::<C>(entity, *max_component, index);
*max_component += 1;
com
} }
pub fn get_component_buffer<C: Component + 'static>( pub fn get_component_buffer<'a, C: Component + 'static>(
&self, &self,
component_type_manager: &'static ComponentTypeManager, component_type_manager: &'a ComponentTypeManager,
) -> &'static ComponentBuffer { ) -> &'a ComponentBuffer {
//TODO this needs to deal with when it does not exist //TODO this needs to deal with when it does not exist
component_type_manager.get::<C>(self) component_type_manager.get::<C>(self)
} }
pub fn get_component_buffer_mut<C: Component + 'static>( pub fn get_component_buffer_mut<'a, C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &'static mut ComponentTypeManager, component_type_manager: &'a mut ComponentTypeManager,
) -> &'static mut ComponentBuffer { ) -> &'a mut ComponentBuffer {
//TODO this needs to deal with when it does not exist //TODO this needs to deal with when it does not exist
component_type_manager.get_mut::<C>(self) component_type_manager.get_mut::<C>(self)
} }
pub fn get_first_component<C: Component + 'static>( pub fn get_first_component<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> Option<&'static C> { ) -> Option<&'static C> {
component_type_manager component_type_manager
.get::<C>(self) .get::<C>(self)
@ -276,8 +284,8 @@ impl EntityManager {
} }
pub fn get_first_component_mut<C: Component + 'static>( pub fn get_first_component_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> Option<&'static mut C> { ) -> Option<&'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -286,8 +294,8 @@ impl EntityManager {
} }
pub fn get_first_enabled_component<C: Component + 'static>( pub fn get_first_enabled_component<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> Option<&'static C> { ) -> Option<&'static C> {
component_type_manager component_type_manager
.get::<C>(self) .get::<C>(self)
@ -296,8 +304,8 @@ impl EntityManager {
} }
pub fn get_first_enabled_component_mut<C: Component + 'static>( pub fn get_first_enabled_component_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> Option<&'static mut C> { ) -> Option<&'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -306,8 +314,8 @@ impl EntityManager {
} }
pub fn get_first_disabled_component<C: Component + 'static>( pub fn get_first_disabled_component<C: Component + 'static>(
&self, &self,
component_type_manager: &ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &ComponentTypeManager,
) -> Option<&'static C> { ) -> Option<&'static C> {
component_type_manager component_type_manager
.get::<C>(self) .get::<C>(self)
@ -316,8 +324,8 @@ impl EntityManager {
} }
pub fn get_first_disabled_component_mut<C: Component + 'static>( pub fn get_first_disabled_component_mut<C: Component + 'static>(
&mut self, &mut self,
component_type_manager: &mut ComponentTypeManager,
entry: usize, entry: usize,
component_type_manager: &mut ComponentTypeManager,
) -> Option<&'static mut C> { ) -> Option<&'static mut C> {
component_type_manager component_type_manager
.get_mut::<C>(self) .get_mut::<C>(self)
@ -355,10 +363,10 @@ impl EntityManager {
} }
pub fn iter_in_radius_with_tag( pub fn iter_in_radius_with_tag(
&self, &self,
tag_manager: &TagManager<u16>,
pos: Vec2, pos: Vec2,
radius: f32, radius: f32,
tag: &StdString, tag: &StdString,
tag_manager: &TagManager<u16>,
) -> impl Iterator<Item = &'static Entity> { ) -> impl Iterator<Item = &'static Entity> {
if let Some(tag) = tag_manager.tag_indices.get(tag).copied() if let Some(tag) = tag_manager.tag_indices.get(tag).copied()
&& let Some(ents) = self.entity_buckets.get(tag as usize) && let Some(ents) = self.entity_buckets.get(tag as usize)
@ -384,10 +392,10 @@ impl EntityManager {
} }
pub fn iter_in_radius_with_tag_mut( pub fn iter_in_radius_with_tag_mut(
&mut self, &mut self,
tag_manager: &TagManager<u16>,
pos: Vec2, pos: Vec2,
radius: f32, radius: f32,
tag: &StdString, tag: &StdString,
tag_manager: &TagManager<u16>,
) -> impl Iterator<Item = &'static mut Entity> { ) -> impl Iterator<Item = &'static mut Entity> {
if let Some(tag) = tag_manager.tag_indices.get(tag).copied() if let Some(tag) = tag_manager.tag_indices.get(tag).copied()
&& let Some(ents) = self.entity_buckets.get_mut(tag as usize) && let Some(ents) = self.entity_buckets.get_mut(tag as usize)
@ -415,9 +423,9 @@ impl EntityManager {
} }
pub fn get_closest_with_tag( pub fn get_closest_with_tag(
&self, &self,
tag_manager: &TagManager<u16>,
pos: Vec2, pos: Vec2,
tag: &StdString, tag: &StdString,
tag_manager: &TagManager<u16>,
) -> Option<&'static Entity> { ) -> Option<&'static Entity> {
tag_manager.tag_indices.get(tag).copied().and_then(|tag| { tag_manager.tag_indices.get(tag).copied().and_then(|tag| {
self.entity_buckets.get(tag as usize).and_then(|b| { self.entity_buckets.get(tag as usize).and_then(|b| {
@ -444,9 +452,9 @@ impl EntityManager {
} }
pub fn get_closest_with_tag_mut( pub fn get_closest_with_tag_mut(
&mut self, &mut self,
tag_manager: &TagManager<u16>,
pos: Vec2, pos: Vec2,
tag: &StdString, tag: &StdString,
tag_manager: &TagManager<u16>,
) -> Option<&'static mut Entity> { ) -> Option<&'static mut Entity> {
tag_manager.tag_indices.get(tag).copied().and_then(|tag| { tag_manager.tag_indices.get(tag).copied().and_then(|tag| {
self.entity_buckets.get_mut(tag as usize).and_then(|b| { self.entity_buckets.get_mut(tag as usize).and_then(|b| {