save/restore: Impl. de/serialize for SaveData
TODO: Unit tests for de/serialize. Actual saving/loading behavior.
This commit is contained in:
parent
74a9980ca1
commit
63730b90bd
1 changed files with 336 additions and 44 deletions
|
@ -920,7 +920,27 @@ impl ParticleSystem {
|
||||||
|
|
||||||
let particle_count: usize = self.particles.len();
|
let particle_count: usize = self.particles.len();
|
||||||
bytes.append(&mut particle_count.to_be_bytes().into());
|
bytes.append(&mut particle_count.to_be_bytes().into());
|
||||||
todo!();
|
|
||||||
|
for particle in self.particles.iter() {
|
||||||
|
bytes.append(&mut particle.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.extend(self.spawn_timer.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.spawn_time.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.lifetime.to_be_bytes().into_iter());
|
||||||
|
|
||||||
|
bytes.append(&mut self.host_rect.serialize());
|
||||||
|
|
||||||
|
bytes.append(&mut self.host_circle.serialize());
|
||||||
|
|
||||||
|
bytes.push(if self.is_rect { 1 } else { 0 });
|
||||||
|
|
||||||
|
bytes.append(&mut self.direction.serialize());
|
||||||
|
|
||||||
|
bytes.append(&mut self.color.serialize());
|
||||||
|
|
||||||
|
bytes.extend(self.opacity.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.vel_multiplier.to_be_bytes().into_iter());
|
||||||
|
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1105,11 @@ impl RotatingParticleSystem {
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
todo!();
|
bytes.append(&mut self.particle_system.serialize());
|
||||||
|
|
||||||
|
bytes.extend(self.r.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.velr.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.offset.to_be_bytes().into_iter());
|
||||||
|
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
@ -1269,7 +1293,7 @@ impl Planet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize(data: &[u8], offset: usize) -> Result<Planet, ()> {
|
pub fn deserialize(data: &[u8], offset: usize) -> Result<(Planet, usize), ()> {
|
||||||
let mut idx: usize = 0;
|
let mut idx: usize = 0;
|
||||||
let mut planet = Planet::new(Circle::new(0.0, 0.0, 1.0), Color::WHITE);
|
let mut planet = Planet::new(Circle::new(0.0, 0.0, 1.0), Color::WHITE);
|
||||||
|
|
||||||
|
@ -1285,8 +1309,38 @@ impl Planet {
|
||||||
planet.particle_system = psystem;
|
planet.particle_system = psystem;
|
||||||
idx += psystem_size;
|
idx += psystem_size;
|
||||||
|
|
||||||
todo!("deserialize rotatingparticlesystem");
|
if data.len() < offset + idx + std::mem::size_of::<usize>() {
|
||||||
Err(())
|
return Err(());
|
||||||
|
}
|
||||||
|
let moons_size = usize::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<usize>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<usize>();
|
||||||
|
for _ in 0..moons_size {
|
||||||
|
let (rpsystem, rps_size) = RotatingParticleSystem::deserialize(data, offset + idx)?;
|
||||||
|
planet.moons.push(rpsystem);
|
||||||
|
idx += rps_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((planet, idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.append(&mut self.circle.serialize());
|
||||||
|
bytes.append(&mut self.color.serialize());
|
||||||
|
bytes.append(&mut self.particle_system.serialize());
|
||||||
|
|
||||||
|
let moons_size = self.moons.len();
|
||||||
|
bytes.extend(moons_size.to_be_bytes().into_iter());
|
||||||
|
for i in 0..moons_size {
|
||||||
|
bytes.append(&mut self.moons[i].serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1298,6 +1352,17 @@ struct Star {
|
||||||
r: f32,
|
r: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Star {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
color: Color::default(),
|
||||||
|
particle_system: ParticleSystem::default(),
|
||||||
|
velr: 0.0,
|
||||||
|
r: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Star {
|
impl Star {
|
||||||
fn new(circle: Circle, color: Color, velr: f32, r: f32) -> Self {
|
fn new(circle: Circle, color: Color, velr: f32, r: f32) -> Self {
|
||||||
let mut star = Star {
|
let mut star = Star {
|
||||||
|
@ -1356,6 +1421,53 @@ impl Star {
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deserialize(data: &[u8], offset: usize) -> Result<(Star, usize), ()> {
|
||||||
|
let mut idx: usize = 0;
|
||||||
|
let mut star = Star::default();
|
||||||
|
|
||||||
|
let (color, color_size) = Color::deserialize(data, offset + idx)?;
|
||||||
|
star.color = color;
|
||||||
|
idx += color_size;
|
||||||
|
|
||||||
|
let (psystem, psystem_size) = ParticleSystem::deserialize(data, offset + idx)?;
|
||||||
|
star.particle_system = psystem;
|
||||||
|
idx += psystem_size;
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
star.velr = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
star.r = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
Ok((star, idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.append(&mut self.color.serialize());
|
||||||
|
bytes.append(&mut self.particle_system.serialize());
|
||||||
|
|
||||||
|
bytes.extend(self.velr.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.r.to_be_bytes().into_iter());
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -1377,6 +1489,23 @@ enum FishState {
|
||||||
Swim,
|
Swim,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Fish {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
pos: Vector::default(),
|
||||||
|
r: 0.0,
|
||||||
|
swim_time: 1.0,
|
||||||
|
swim_timer: 0.0,
|
||||||
|
swim_v: 0.0,
|
||||||
|
anim_timer: 0.0,
|
||||||
|
anim_time: 1.0,
|
||||||
|
color: Color::default(),
|
||||||
|
body_rect: Rectangle::default(),
|
||||||
|
tail_rect: Rectangle::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Fish {
|
impl Fish {
|
||||||
fn new(pos: Vector, r: f32, color: Color) -> Self {
|
fn new(pos: Vector, r: f32, color: Color) -> Self {
|
||||||
let anim_timer = rand::thread_rng().gen_range(0.8..1.0);
|
let anim_timer = rand::thread_rng().gen_range(0.8..1.0);
|
||||||
|
@ -1489,6 +1618,108 @@ impl Fish {
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deserialize(data: &[u8], offset: usize) -> Result<(Fish, usize), ()> {
|
||||||
|
let mut idx: usize = 0;
|
||||||
|
let mut fish = Fish::default();
|
||||||
|
|
||||||
|
let (pos, pos_size) = Vector::deserialize(data, offset + idx)?;
|
||||||
|
fish.pos = pos;
|
||||||
|
idx += pos_size;
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.r = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.swim_time = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.swim_timer = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.swim_v = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.anim_timer = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
if data.len() < offset + idx + std::mem::size_of::<f32>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
fish.anim_time = f32::from_be_bytes(
|
||||||
|
data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<f32>();
|
||||||
|
|
||||||
|
let (color, color_size) = Color::deserialize(data, offset + idx)?;
|
||||||
|
fish.color = color;
|
||||||
|
idx += color_size;
|
||||||
|
|
||||||
|
let (body_rect, body_rect_size) = Rectangle::deserialize(data, offset + idx)?;
|
||||||
|
fish.body_rect = body_rect;
|
||||||
|
idx += body_rect_size;
|
||||||
|
|
||||||
|
let (tail_rect, tail_rect_size) = Rectangle::deserialize(data, offset + idx)?;
|
||||||
|
fish.tail_rect = tail_rect;
|
||||||
|
idx += tail_rect_size;
|
||||||
|
|
||||||
|
Ok((fish, idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.append(&mut self.pos.serialize());
|
||||||
|
|
||||||
|
bytes.extend(self.r.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.swim_time.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.swim_timer.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.swim_v.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.anim_timer.to_be_bytes().into_iter());
|
||||||
|
bytes.extend(self.anim_time.to_be_bytes().into_iter());
|
||||||
|
|
||||||
|
bytes.append(&mut self.color.serialize());
|
||||||
|
bytes.append(&mut self.body_rect.serialize());
|
||||||
|
bytes.append(&mut self.tail_rect.serialize());
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -1501,57 +1732,118 @@ struct SaveData {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SAVE_DATA_IDENTIFIER: [u8; 4] = [0x53, 0x41, 0x56, 0x45];
|
const SAVE_DATA_IDENTIFIER: [u8; 4] = [0x53, 0x41, 0x56, 0x45];
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
enum SaveDataDeserializeState {
|
impl Default for SaveData {
|
||||||
GET_IDENTIFIER,
|
fn default() -> Self {
|
||||||
GET_PLANETS,
|
Self {
|
||||||
|
planets: Vec::new(),
|
||||||
|
stars: Vec::new(),
|
||||||
|
fishes: Vec::new(),
|
||||||
|
player: Rectangle::default(),
|
||||||
|
joining_particles: RotatingParticleSystem::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SaveData {
|
impl SaveData {
|
||||||
pub fn deserialize(data: &[u8]) -> Result<SaveData, ()> {
|
pub fn deserialize(data: &[u8]) -> Result<SaveData, ()> {
|
||||||
let mut idx: usize = 0;
|
let mut idx: usize = 0;
|
||||||
let mut save_data = SaveData {
|
let mut save_data = SaveData::default();
|
||||||
planets: Vec::new(),
|
|
||||||
stars: Vec::new(),
|
|
||||||
fishes: Vec::new(),
|
|
||||||
player: Rectangle::new(0.0, 0.0, 0.0, 0.0),
|
|
||||||
joining_particles: RotatingParticleSystem::new(
|
|
||||||
PP_GEN_RATE,
|
|
||||||
1.0,
|
|
||||||
Rectangle::new(400.0, 300.0, 16.0, 16.0),
|
|
||||||
Circle::new(100.0, 100.0, 32.0),
|
|
||||||
true,
|
|
||||||
Vector::new(0.0, 0.0),
|
|
||||||
Color::GREEN,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.1,
|
|
||||||
JOINING_FAR_DIST,
|
|
||||||
1.0,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let mut state = SaveDataDeserializeState::GET_IDENTIFIER;
|
|
||||||
|
|
||||||
while idx < data.len() {
|
if data.len() < idx + SAVE_DATA_IDENTIFIER.len() {
|
||||||
match state {
|
return Err(());
|
||||||
SaveDataDeserializeState::GET_IDENTIFIER => {
|
}
|
||||||
for i in 0..SAVE_DATA_IDENTIFIER.len() {
|
for i in 0..SAVE_DATA_IDENTIFIER.len() {
|
||||||
if data[idx + i] != SAVE_DATA_IDENTIFIER[i] {
|
if data[idx + i] != SAVE_DATA_IDENTIFIER[i] {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx += SAVE_DATA_IDENTIFIER.len();
|
idx += SAVE_DATA_IDENTIFIER.len();
|
||||||
state = SaveDataDeserializeState::GET_PLANETS;
|
|
||||||
}
|
if data.len() < idx + std::mem::size_of::<usize>() {
|
||||||
SaveDataDeserializeState::GET_PLANETS => todo!(),
|
return Err(());
|
||||||
}
|
}
|
||||||
|
let planets_size = usize::from_be_bytes(
|
||||||
|
data[idx..(idx + std::mem::size_of::<usize>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<usize>();
|
||||||
|
|
||||||
|
for _ in 0..planets_size {
|
||||||
|
let (planet, planet_size) = Planet::deserialize(data, idx)?;
|
||||||
|
save_data.planets.push(planet);
|
||||||
|
idx += planet_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(())
|
if data.len() < idx + std::mem::size_of::<usize>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
let stars_size = usize::from_be_bytes(
|
||||||
|
data[idx..(idx + std::mem::size_of::<usize>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<usize>();
|
||||||
|
|
||||||
|
for _ in 0..stars_size {
|
||||||
|
let (star, star_size) = Star::deserialize(data, idx)?;
|
||||||
|
save_data.stars.push(star);
|
||||||
|
idx += star_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.len() < idx + std::mem::size_of::<usize>() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
let fishes_size = usize::from_be_bytes(
|
||||||
|
data[idx..(idx + std::mem::size_of::<usize>())]
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| ())?,
|
||||||
|
);
|
||||||
|
idx += std::mem::size_of::<usize>();
|
||||||
|
|
||||||
|
for _ in 0..fishes_size {
|
||||||
|
let (fish, fish_size) = Fish::deserialize(data, idx)?;
|
||||||
|
save_data.fishes.push(fish);
|
||||||
|
idx += fish_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (p_rect, p_rect_size) = Rectangle::deserialize(data, idx)?;
|
||||||
|
save_data.player = p_rect;
|
||||||
|
idx += p_rect_size;
|
||||||
|
|
||||||
|
let (jp, jp_size) = RotatingParticleSystem::deserialize(data, idx)?;
|
||||||
|
save_data.joining_particles = jp;
|
||||||
|
idx += jp_size;
|
||||||
|
|
||||||
|
Ok(save_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
todo!();
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.extend(SAVE_DATA_IDENTIFIER.iter());
|
||||||
|
|
||||||
|
bytes.extend(self.planets.len().to_be_bytes().into_iter());
|
||||||
|
for planet in &self.planets {
|
||||||
|
bytes.append(&mut planet.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.extend(self.stars.len().to_be_bytes().into_iter());
|
||||||
|
for star in &self.stars {
|
||||||
|
bytes.append(&mut star.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.extend(self.fishes.len().to_be_bytes().into_iter());
|
||||||
|
for fish in &self.fishes {
|
||||||
|
bytes.append(&mut fish.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.append(&mut self.player.serialize());
|
||||||
|
|
||||||
|
bytes.append(&mut self.joining_particles.serialize());
|
||||||
|
|
||||||
|
bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue