mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
Don't allocate memory for PixelRunner every time, ~4ns/pixel.
This commit is contained in:
parent
b9291ba212
commit
b24a004d1f
2 changed files with 18 additions and 9 deletions
|
@ -39,6 +39,7 @@ extern "C" fn init_particle_world_state(lua: *mut lua_State) -> c_int {
|
||||||
_world_ptr: world_pointer as *mut c_void,
|
_world_ptr: world_pointer as *mut c_void,
|
||||||
chunk_map_ptr: chunk_map_pointer as *mut c_void,
|
chunk_map_ptr: chunk_map_pointer as *mut c_void,
|
||||||
material_list_ptr: material_list_pointer as _,
|
material_list_ptr: material_list_pointer as _,
|
||||||
|
runner: Default::default(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
|
@ -52,8 +53,8 @@ extern "C" fn encode_area(lua: *mut lua_State) -> c_int {
|
||||||
let encoded_buffer = unsafe { LUA.lua_tointeger(lua, 5) } as *mut NoitaPixelRun;
|
let encoded_buffer = unsafe { LUA.lua_tointeger(lua, 5) } as *mut NoitaPixelRun;
|
||||||
|
|
||||||
STATE.with(|state| {
|
STATE.with(|state| {
|
||||||
let state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
let pws = state.particle_world_state.as_ref().unwrap();
|
let pws = state.particle_world_state.as_mut().unwrap();
|
||||||
let runs = unsafe { pws.encode_area(start_x, start_y, end_x, end_y, encoded_buffer) };
|
let runs = unsafe { pws.encode_area(start_x, start_y, end_x, end_y, encoded_buffer) };
|
||||||
unsafe { LUA.lua_pushinteger(lua, runs as isize) };
|
unsafe { LUA.lua_pushinteger(lua, runs as isize) };
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct PixelRun<Pixel> {
|
||||||
|
|
||||||
/// Copied from proxy.
|
/// Copied from proxy.
|
||||||
/// Converts a normal sequence of pixels to a run-length-encoded one.
|
/// Converts a normal sequence of pixels to a run-length-encoded one.
|
||||||
struct PixelRunner<Pixel> {
|
pub(crate) struct PixelRunner<Pixel> {
|
||||||
current_pixel: Option<Pixel>,
|
current_pixel: Option<Pixel>,
|
||||||
current_run_len: u32,
|
current_run_len: u32,
|
||||||
runs: Vec<PixelRun<Pixel>>,
|
runs: Vec<PixelRun<Pixel>>,
|
||||||
|
@ -64,14 +64,20 @@ impl<Pixel: Eq + Copy> PixelRunner<Pixel> {
|
||||||
self.current_run_len = 1;
|
self.current_run_len = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn build(mut self) -> Vec<PixelRun<Pixel>> {
|
fn build(&mut self) -> &[PixelRun<Pixel>] {
|
||||||
if self.current_run_len > 0 {
|
if self.current_run_len > 0 {
|
||||||
self.runs.push(PixelRun {
|
self.runs.push(PixelRun {
|
||||||
length: self.current_run_len,
|
length: self.current_run_len,
|
||||||
data: self.current_pixel.expect("has current pixel"),
|
data: self.current_pixel.expect("has current pixel"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.runs
|
&mut self.runs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.current_pixel = None;
|
||||||
|
self.current_run_len = 0;
|
||||||
|
self.runs.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +85,8 @@ pub(crate) struct ParticleWorldState {
|
||||||
pub(crate) _world_ptr: *mut c_void,
|
pub(crate) _world_ptr: *mut c_void,
|
||||||
pub(crate) chunk_map_ptr: *mut c_void,
|
pub(crate) chunk_map_ptr: *mut c_void,
|
||||||
pub(crate) material_list_ptr: *const c_void,
|
pub(crate) material_list_ptr: *const c_void,
|
||||||
|
|
||||||
|
pub(crate) runner: PixelRunner<RawPixel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParticleWorldState {
|
impl ParticleWorldState {
|
||||||
|
@ -115,14 +123,13 @@ impl ParticleWorldState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn encode_area(
|
pub(crate) unsafe fn encode_area(
|
||||||
&self,
|
&mut self,
|
||||||
start_x: i32,
|
start_x: i32,
|
||||||
start_y: i32,
|
start_y: i32,
|
||||||
end_x: i32,
|
end_x: i32,
|
||||||
end_y: i32,
|
end_y: i32,
|
||||||
pixel_runs: *mut NoitaPixelRun,
|
pixel_runs: *mut NoitaPixelRun,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let mut runner = PixelRunner::default();
|
|
||||||
for y in start_y..end_y {
|
for y in start_y..end_y {
|
||||||
for x in start_x..end_x {
|
for x in start_x..end_x {
|
||||||
let mut raw_pixel = RawPixel {
|
let mut raw_pixel = RawPixel {
|
||||||
|
@ -148,12 +155,12 @@ impl ParticleWorldState {
|
||||||
ntypes::CellType::Invalid => {}
|
ntypes::CellType::Invalid => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runner.put_pixel(raw_pixel);
|
self.runner.put_pixel(raw_pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pixel_runs = pixel_runs;
|
let mut pixel_runs = pixel_runs;
|
||||||
let built_runner = runner.build();
|
let built_runner = self.runner.build();
|
||||||
let runs = built_runner.len();
|
let runs = built_runner.len();
|
||||||
for run in built_runner {
|
for run in built_runner {
|
||||||
let noita_pixel_run = pixel_runs.as_mut().unwrap();
|
let noita_pixel_run = pixel_runs.as_mut().unwrap();
|
||||||
|
@ -162,6 +169,7 @@ impl ParticleWorldState {
|
||||||
noita_pixel_run.flags = run.data.flags;
|
noita_pixel_run.flags = run.data.flags;
|
||||||
pixel_runs = pixel_runs.offset(1);
|
pixel_runs = pixel_runs.offset(1);
|
||||||
}
|
}
|
||||||
|
self.runner.clear();
|
||||||
runs
|
runs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue