mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
Use FxHash
This commit is contained in:
parent
5419556f88
commit
4050fe5c0d
7 changed files with 36 additions and 17 deletions
7
noita-proxy/Cargo.lock
generated
7
noita-proxy/Cargo.lock
generated
|
@ -1820,6 +1820,7 @@ dependencies = [
|
||||||
"poll-promise",
|
"poll-promise",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rustc-hash",
|
||||||
"self-replace",
|
"self-replace",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -2491,6 +2492,12 @@ version = "0.1.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.34"
|
version = "0.38.34"
|
||||||
|
|
|
@ -33,6 +33,7 @@ image = { version = "0.25.1", default_features = false, features = ["png"] }
|
||||||
egui_extras = { version = "*", features = ["all_loaders"] }
|
egui_extras = { version = "*", features = ["all_loaders"] }
|
||||||
bytemuck = { version = "1.16.0", features = ["derive"] }
|
bytemuck = { version = "1.16.0", features = ["derive"] }
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
|
rustc-hash = "1.1.0"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fs::File, io::BufWriter};
|
use std::{fs::File, io::BufWriter};
|
||||||
|
use world_model::WorldModel;
|
||||||
|
|
||||||
pub use world_model::encoding::NoitaWorldUpdate;
|
pub use world_model::encoding::NoitaWorldUpdate;
|
||||||
|
|
||||||
|
@ -12,22 +13,25 @@ pub enum WorldUpdateKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WorldManager {
|
pub struct WorldManager {
|
||||||
pub(crate) writer: BufWriter<File>,
|
// pub(crate) writer: BufWriter<File>,
|
||||||
|
model: WorldModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldManager {
|
impl WorldManager {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
writer: BufWriter::new(File::create("worldlog.bin").unwrap()),
|
// writer: BufWriter::new(File::create("worldlog.bin").unwrap()),
|
||||||
|
model: WorldModel::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_update(&mut self, update: NoitaWorldUpdate) {
|
pub fn add_update(&mut self, update: NoitaWorldUpdate) {
|
||||||
bincode::serialize_into(&mut self.writer, &WorldUpdateKind::Update(update)).unwrap();
|
// bincode::serialize_into(&mut self.writer, &WorldUpdateKind::Update(update)).unwrap();
|
||||||
|
self.model.apply_noita_update(&update);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_end(&mut self) {
|
pub fn add_end(&mut self) {
|
||||||
bincode::serialize_into(&mut self.writer, &WorldUpdateKind::End).unwrap();
|
// bincode::serialize_into(&mut self.writer, &WorldUpdateKind::End).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +47,8 @@ mod test {
|
||||||
let mut model = WorldModel::new();
|
let mut model = WorldModel::new();
|
||||||
let mut model2 = WorldModel::new();
|
let mut model2 = WorldModel::new();
|
||||||
let mut entry_id = 0;
|
let mut entry_id = 0;
|
||||||
|
let mut deltas_size = 0;
|
||||||
|
|
||||||
while let Ok(entry) = bincode::deserialize_from::<_, WorldUpdateKind>(&mut file)
|
while let Ok(entry) = bincode::deserialize_from::<_, WorldUpdateKind>(&mut file)
|
||||||
.inspect_err(|e| println!("{}", e))
|
.inspect_err(|e| println!("{}", e))
|
||||||
{
|
{
|
||||||
|
@ -59,7 +65,7 @@ mod test {
|
||||||
entry.header.w as u32 + 1,
|
entry.header.w as u32 + 1,
|
||||||
entry.header.h as u32 + 1,
|
entry.header.h as u32 + 1,
|
||||||
);
|
);
|
||||||
// TODO
|
|
||||||
assert_eq!(entry, new_update);
|
assert_eq!(entry, new_update);
|
||||||
}
|
}
|
||||||
WorldUpdateKind::End => {
|
WorldUpdateKind::End => {
|
||||||
|
@ -70,6 +76,7 @@ mod test {
|
||||||
img.save(format!("/tmp/img_{}.png", entry_id)).unwrap();
|
img.save(format!("/tmp/img_{}.png", entry_id)).unwrap();
|
||||||
}
|
}
|
||||||
let deltas = model.get_all_deltas();
|
let deltas = model.get_all_deltas();
|
||||||
|
deltas_size += lz4_flex::compress_prepend_size(&bitcode::encode(&deltas)).len();
|
||||||
|
|
||||||
model.reset_change_tracking();
|
model.reset_change_tracking();
|
||||||
model2.apply_all_deltas(&deltas);
|
model2.apply_all_deltas(&deltas);
|
||||||
|
@ -84,6 +91,7 @@ mod test {
|
||||||
let img = model2.gen_image(x, y, 2048 * 2, 2048 * 2);
|
let img = model2.gen_image(x, y, 2048 * 2, 2048 * 2);
|
||||||
img.save(format!("/tmp/img_model2.png")).unwrap();
|
img.save(format!("/tmp/img_model2.png")).unwrap();
|
||||||
|
|
||||||
|
println!("Deltas: {} bytes", deltas_size)
|
||||||
// let mut mats = model.mats.iter().copied().collect::<Vec<_>>();
|
// let mut mats = model.mats.iter().copied().collect::<Vec<_>>();
|
||||||
// mats.sort();
|
// mats.sort();
|
||||||
// for mat in mats {
|
// for mat in mats {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
use bitcode::{Decode, Encode};
|
||||||
use chunk::{Chunk, Pixel, PixelFlags};
|
use chunk::{Chunk, Pixel, PixelFlags};
|
||||||
use encoding::{NoitaWorldUpdate, PixelRun, PixelRunner};
|
use encoding::{NoitaWorldUpdate, PixelRun, PixelRunner};
|
||||||
use image::{Rgb, RgbImage};
|
use image::{Rgb, RgbImage};
|
||||||
use std::collections::{HashMap, HashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
mod chunk;
|
mod chunk;
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
@ -11,8 +13,8 @@ const CHUNK_SIZE: usize = 256;
|
||||||
type ChunkCoord = (i32, i32);
|
type ChunkCoord = (i32, i32);
|
||||||
|
|
||||||
pub struct WorldModel {
|
pub struct WorldModel {
|
||||||
chunks: HashMap<ChunkCoord, Chunk>,
|
chunks: FxHashMap<ChunkCoord, Chunk>,
|
||||||
pub mats: HashSet<u16>,
|
pub mats: FxHashSet<u16>,
|
||||||
palette: MatPalette,
|
palette: MatPalette,
|
||||||
changed_chunks: HashSet<ChunkCoord>,
|
changed_chunks: HashSet<ChunkCoord>,
|
||||||
}
|
}
|
||||||
|
@ -21,7 +23,7 @@ struct MatPalette {
|
||||||
colors: Vec<Rgb<u8>>,
|
colors: Vec<Rgb<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct ChunkDelta {
|
pub struct ChunkDelta {
|
||||||
runs: Vec<PixelRun<Option<Pixel>>>,
|
runs: Vec<PixelRun<Option<Pixel>>>,
|
||||||
chunk_coord: (i32, i32),
|
chunk_coord: (i32, i32),
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
use bitcode::{Decode, Encode};
|
||||||
|
|
||||||
use super::{encoding::RawPixel, CHUNK_SIZE};
|
use super::{encoding::RawPixel, CHUNK_SIZE};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Encode, Decode)]
|
||||||
pub enum PixelFlags {
|
pub enum PixelFlags {
|
||||||
#[default]
|
#[default]
|
||||||
Unknown,
|
Unknown,
|
||||||
|
@ -8,7 +10,7 @@ pub enum PixelFlags {
|
||||||
Fluid,
|
Fluid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Encode, Decode)]
|
||||||
pub struct Pixel {
|
pub struct Pixel {
|
||||||
pub flags: PixelFlags,
|
pub flags: PixelFlags,
|
||||||
pub material: u16,
|
pub material: u16,
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
use bitcode::{Decode, Encode};
|
||||||
use bytemuck::{bytes_of, pod_read_unaligned, AnyBitPattern, NoUninit};
|
use bytemuck::{bytes_of, pod_read_unaligned, AnyBitPattern, NoUninit};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
use super::chunk::Pixel;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, AnyBitPattern, NoUninit, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, AnyBitPattern, NoUninit, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub(crate) struct Header {
|
pub(crate) struct Header {
|
||||||
|
@ -28,7 +27,7 @@ pub(crate) struct RawPixel {
|
||||||
|
|
||||||
/// Stores a run of pixels.
|
/// Stores a run of pixels.
|
||||||
/// Not specific to Noita side - length is an actual length
|
/// Not specific to Noita side - length is an actual length
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Encode, Decode)]
|
||||||
pub struct PixelRun<Pixel> {
|
pub struct PixelRun<Pixel> {
|
||||||
pub length: u32,
|
pub length: u32,
|
||||||
pub data: Pixel,
|
pub data: Pixel,
|
||||||
|
|
|
@ -45,7 +45,7 @@ function world_sync.on_world_update_host()
|
||||||
end_y = end_y + 2
|
end_y = end_y + 2
|
||||||
|
|
||||||
local rectangle = rect.Rectangle(start_x, start_y, end_x, end_y)
|
local rectangle = rect.Rectangle(start_x, start_y, end_x, end_y)
|
||||||
-- rect_optimiser:submit(rectangle)
|
rect_optimiser:submit(rectangle)
|
||||||
end
|
end
|
||||||
for i = 0, tonumber(thread_impl.world_update_params_count) - 1 do
|
for i = 0, tonumber(thread_impl.world_update_params_count) - 1 do
|
||||||
local wup = thread_impl.world_update_params.begin[i]
|
local wup = thread_impl.world_update_params.begin[i]
|
||||||
|
@ -55,7 +55,7 @@ function world_sync.on_world_update_host()
|
||||||
local end_y = wup.update_region.bottom_right.y
|
local end_y = wup.update_region.bottom_right.y
|
||||||
|
|
||||||
local rectangle = rect.Rectangle(start_x, start_y, end_x, end_y)
|
local rectangle = rect.Rectangle(start_x, start_y, end_x, end_y)
|
||||||
-- rect_optimiser:submit(rectangle)
|
rect_optimiser:submit(rectangle)
|
||||||
end
|
end
|
||||||
|
|
||||||
local px, py = EntityGetTransform(ctx.my_player.entity)
|
local px, py = EntityGetTransform(ctx.my_player.entity)
|
||||||
|
@ -74,7 +74,7 @@ function world_sync.on_world_update_host()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if GameGetFrameNum() % 1 == 0 then
|
if GameGetFrameNum() % 10 == 0 then
|
||||||
rect_optimiser:scan()
|
rect_optimiser:scan()
|
||||||
|
|
||||||
for crect in rect.parts(rect_optimiser:iterate(), 256) do
|
for crect in rect.parts(rect_optimiser:iterate(), 256) do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue