Some refactoring

This commit is contained in:
IQuant 2024-06-04 14:34:57 +03:00
parent e95d0ca7a8
commit 81b35d342a
4 changed files with 97 additions and 75 deletions

View file

@ -9,7 +9,7 @@ use std::{
time::Duration,
};
use tracing::debug;
use world::{RunLengthUpdate, WorldManager};
use world::{NoitaWorldUpdate, WorldManager};
use tangled::Reliability;
use tracing::{error, info, warn};
@ -360,7 +360,7 @@ impl NetManager {
match key {
// world frame
0 => {
let update = RunLengthUpdate::load(data);
let update = NoitaWorldUpdate::load(data);
state.world.add_update(update);
}
// world end

View file

@ -1,81 +1,18 @@
use std::{fs::File, io::BufWriter, mem::size_of};
use bytemuck::{pod_read_unaligned, AnyBitPattern};
use serde::{Deserialize, Serialize};
use std::{fs::File, io::BufWriter};
pub use world_model::noita_encoding::NoitaWorldUpdate;
pub mod world_model;
#[derive(Debug, Clone, Copy, AnyBitPattern, Serialize, Deserialize)]
#[repr(C)]
struct Header {
x: i32,
y: i32,
w: u8,
h: u8,
run_count: u16,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct RunLengthUpdate {
header: Header,
runs: Vec<PixelRun>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
struct PixelRun {
length: u16,
material: i16,
flags: u8,
}
struct ByteParser<'a> {
data: &'a [u8],
pub enum WorldUpdateKind {
Update(NoitaWorldUpdate),
End,
}
pub struct WorldManager {
writer: BufWriter<File>,
}
impl<'a> ByteParser<'a> {
fn new(data: &'a [u8]) -> Self {
Self { data }
}
fn next<T: AnyBitPattern>(&mut self) -> T {
let size = size_of::<T>();
let sli = &self.data[..size];
self.data = &self.data[size..];
pod_read_unaligned(sli)
}
fn next_run(&mut self) -> PixelRun {
PixelRun {
length: self.next(),
material: self.next(),
flags: self.next(),
}
}
}
impl RunLengthUpdate {
pub fn load(data: &[u8]) -> Self {
let mut parser = ByteParser::new(data);
let header: Header = parser.next();
let mut runs = Vec::with_capacity(header.run_count.into());
for _ in 0..header.run_count {
runs.push(parser.next_run());
}
Self { header, runs }
}
}
#[derive(Debug, Serialize, Deserialize)]
pub enum WorldUpdateKind {
Update(RunLengthUpdate),
End,
pub(crate) writer: BufWriter<File>,
}
impl WorldManager {
@ -85,7 +22,7 @@ impl WorldManager {
}
}
pub fn add_update(&mut self, update: RunLengthUpdate) {
pub fn add_update(&mut self, update: NoitaWorldUpdate) {
bincode::serialize_into(&mut self.writer, &WorldUpdateKind::Update(update)).unwrap();
}

View file

@ -1,9 +1,10 @@
use super::RunLengthUpdate;
use chunk::{Chunk, Pixel, PixelFlags};
use image::{Rgb, RgbImage};
use noita_encoding::NoitaWorldUpdate;
use std::collections::{HashMap, HashSet};
mod chunk;
pub mod noita_encoding;
const CHUNK_SIZE: usize = 256;
@ -75,7 +76,7 @@ impl WorldModel {
}
}
pub fn apply_noita_update(&mut self, update: &RunLengthUpdate) {
pub fn apply_noita_update(&mut self, update: &NoitaWorldUpdate) {
let header = &update.header;
let runs = &update.runs;

View file

@ -0,0 +1,84 @@
use bytemuck::{bytes_of, pod_read_unaligned, AnyBitPattern, NoUninit};
use serde::{Deserialize, Serialize};
use std::mem::size_of;
#[derive(Debug, Clone, Copy, AnyBitPattern, NoUninit, Serialize, Deserialize)]
#[repr(C)]
pub(crate) struct Header {
pub x: i32,
pub y: i32,
pub w: u8,
pub h: u8,
pub run_count: u16,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct NoitaWorldUpdate {
pub(crate) header: Header,
pub(crate) runs: Vec<PixelRun>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub(crate) struct PixelRun {
pub(crate) length: u16,
pub(crate) material: i16,
pub(crate) flags: u8,
}
struct ByteParser<'a> {
data: &'a [u8],
}
impl<'a> ByteParser<'a> {
fn new(data: &'a [u8]) -> Self {
Self { data }
}
fn next<T: AnyBitPattern>(&mut self) -> T {
let size = size_of::<T>();
let sli = &self.data[..size];
self.data = &self.data[size..];
pod_read_unaligned(sli)
}
fn next_run(&mut self) -> PixelRun {
PixelRun {
length: self.next(),
material: self.next(),
flags: self.next(),
}
}
}
impl NoitaWorldUpdate {
pub fn load(data: &[u8]) -> Self {
let mut parser = ByteParser::new(data);
let header: Header = parser.next();
let mut runs = Vec::with_capacity(header.run_count.into());
for _ in 0..header.run_count {
runs.push(parser.next_run());
}
assert!(parser.data.is_empty());
Self { header, runs }
}
pub fn save(&self) -> Vec<u8> {
let header = Header {
run_count: self.runs.len() as u16,
..self.header
};
let mut buf = Vec::new();
buf.extend_from_slice(bytes_of(&header));
for run in &self.runs {
buf.extend_from_slice(bytes_of(&run.length));
buf.extend_from_slice(bytes_of(&run.material));
buf.extend_from_slice(bytes_of(&run.flags));
}
buf
}
}