From 24f49927f5acc962c6b8135a2eb5a39c58d6be33 Mon Sep 17 00:00:00 2001 From: Kent Ross Date: Sat, 6 Apr 2024 17:39:41 -0700 Subject: [PATCH 1/2] add bilrost --- Cargo.toml | 2 + benches/bench.rs | 14 + src/bench_bilrost.rs | 106 +++++++ src/datasets/log/mod.rs | 8 + src/datasets/mesh/mod.rs | 4 + .../minecraft_savedata_bilrost.rs | 261 ++++++++++++++++++ src/datasets/minecraft_savedata/mod.rs | 14 + src/datasets/mk48/mk48_bilrost.rs | 218 +++++++++++++++ src/datasets/mk48/mod.rs | 14 + src/lib.rs | 2 + 10 files changed, 643 insertions(+) create mode 100644 src/bench_bilrost.rs create mode 100644 src/datasets/minecraft_savedata/minecraft_savedata_bilrost.rs create mode 100644 src/datasets/mk48/mk48_bilrost.rs diff --git a/Cargo.toml b/Cargo.toml index 4631011..a893561 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ alkahest = { version = "0.1.5", optional = true, features = [ "nightly", ] } bebop = { version = "2.4.9", optional = true } +bilrost = { version = "0.1005.1", optional = true } bincode1 = { package = "bincode", version = "1.3.3", optional = true } # Can't call it bincode2 because of a current issue of bincode2 bincode = { package = "bincode", version = "2.0.0-rc", optional = true } @@ -99,6 +100,7 @@ default = [ "abomonation_derive", "alkahest", # "bebop", + "bilrost", "bincode1", "bincode", "bitcode", diff --git a/benches/bench.rs b/benches/bench.rs index 46f412a..67612b3 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -5,6 +5,8 @@ use rand_pcg::Lcg64Xsh32; use rust_serialization_benchmark::bench_abomonation; #[cfg(feature = "alkahest")] use rust_serialization_benchmark::bench_alkahest; +#[cfg(feature = "bilrost")] +use rust_serialization_benchmark::bench_bilrost; #[cfg(feature = "bincode")] use rust_serialization_benchmark::bench_bincode; #[cfg(feature = "bincode1")] @@ -97,6 +99,9 @@ fn bench_log(c: &mut Criterion) { } }); + #[cfg(feature = "bilrost")] + bench_bilrost::bench(BENCH, c, &data); + #[cfg(feature = "bincode1")] bench_bincode1::bench(BENCH, c, &data); @@ -271,6 +276,9 @@ fn bench_mesh(c: &mut Criterion) { } }); + #[cfg(feature = "bilrost")] + bench_bilrost::bench(BENCH, c, &data); + #[cfg(feature = "bincode1")] bench_bincode1::bench(BENCH, c, &data); @@ -429,6 +437,9 @@ fn bench_minecraft_savedata(c: &mut Criterion) { } }); + #[cfg(feature = "bilrost")] + bench_bilrost::bench(BENCH, c, &data); + #[cfg(feature = "bincode1")] bench_bincode1::bench(BENCH, c, &data); @@ -591,6 +602,9 @@ fn bench_mk48(c: &mut Criterion) { } }); + #[cfg(feature = "bilrost")] + bench_bilrost::bench(BENCH, c, &data); + #[cfg(feature = "bincode1")] bench_bincode1::bench(BENCH, c, &data); diff --git a/src/bench_bilrost.rs b/src/bench_bilrost.rs new file mode 100644 index 0000000..5b29df6 --- /dev/null +++ b/src/bench_bilrost.rs @@ -0,0 +1,106 @@ +use bilrost::buf::ReverseBuffer; +use bilrost::bytes::BufMut; +use bilrost::Message; +use criterion::{black_box, Criterion}; +use std::borrow::Borrow; + +pub trait ToBilrost: Sized { + type Message: Message + Into; + type Serializable<'a>: Borrow + where + Self: 'a; + + fn to_bilrost(&self) -> Self::Serializable<'_>; + + fn is_already_bilrost() -> bool { + false // provided: false + } +} + +impl ToBilrost for T +where + T: Clone + Message, +{ + type Message = Self; + type Serializable<'a> = &'a Self + where + Self: 'a; + + fn to_bilrost(&self) -> &Self { + self + } + + fn is_already_bilrost() -> bool { + true // true for this covering impl only + } +} + +pub fn bench(name: &'static str, c: &mut Criterion, data: &T) +where + T: ToBilrost + PartialEq, +{ + const BUFFER_LEN: usize = 10_000_000; + + let mut group = c.benchmark_group(format!("{}/bilrost", name)); + + let mut serialize_buffer = Vec::with_capacity(BUFFER_LEN); + let mut prepend_buffer = ReverseBuffer::with_capacity(BUFFER_LEN); + + if !T::is_already_bilrost() { + group.bench_function("serialize (populate + encode)", |b| { + b.iter(|| { + black_box(&mut serialize_buffer).clear(); + data.to_bilrost() + .borrow() + .encode(&mut serialize_buffer) + .unwrap(); + black_box(()); + }) + }); + group.bench_function("serialize (populate + prepend)", |b| { + b.iter(|| { + black_box(&mut prepend_buffer).clear(); + data.to_bilrost().borrow().prepend(&mut prepend_buffer); + black_box(()); + }) + }); + } + + let message = data.to_bilrost(); + group.bench_function("serialize (only encode)", |b| { + b.iter(|| { + black_box(&mut serialize_buffer).clear(); + message.borrow().encode(&mut serialize_buffer).unwrap(); + black_box(()); + }) + }); + + let message = data.to_bilrost(); + group.bench_function("serialize (only prepend)", |b| { + b.iter(|| { + black_box(&mut prepend_buffer).clear(); + message.borrow().prepend(&mut prepend_buffer); + black_box(()); + }) + }); + + let mut deserialize_buffer = Vec::new(); + message.borrow().encode(&mut deserialize_buffer).unwrap(); + let mut prepended_data = Vec::new(); + prepended_data.put(message.borrow().encode_fast()); + // Because there are no unordered collections in the benchmarked types, we can assert that the + // prepended encoding path emits precisely the same bytes as the forward-encoded one. + assert_eq!(prepended_data, deserialize_buffer); + + group.bench_function("deserialize", |b| { + b.iter(|| { + black_box(::decode(black_box(&deserialize_buffer).as_slice()).unwrap()); + }) + }); + + crate::bench_size(name, "bilrost", deserialize_buffer.as_slice()); + + assert!(::decode(&*deserialize_buffer).unwrap().into() == *data); + + group.finish(); +} diff --git a/src/datasets/log/mod.rs b/src/datasets/log/mod.rs index bcff439..faa2ea7 100644 --- a/src/datasets/log/mod.rs +++ b/src/datasets/log/mod.rs @@ -32,6 +32,7 @@ use crate::Generate; #[derive(Clone, Copy, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -59,9 +60,13 @@ use crate::Generate; #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] pub struct Address { + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub x0: u8, + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub x1: u8, + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub x2: u8, + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub x3: u8, } @@ -141,6 +146,7 @@ impl alkahest::Pack
for Address { #[derive(Clone, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -365,6 +371,7 @@ impl alkahest::Pack for &'_ Log { #[derive(Clone, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -391,6 +398,7 @@ impl alkahest::Pack for &'_ Log { #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] pub struct Logs { + #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub logs: Vec, } diff --git a/src/datasets/mesh/mod.rs b/src/datasets/mesh/mod.rs index 4659887..8922647 100644 --- a/src/datasets/mesh/mod.rs +++ b/src/datasets/mesh/mod.rs @@ -30,6 +30,7 @@ use crate::Generate; #[derive(Clone, Copy, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -133,6 +134,7 @@ impl alkahest::Pack for Vector3 { #[derive(Clone, Copy, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -248,6 +250,7 @@ impl alkahest::Pack for &'_ Triangle { #[derive(Clone, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -274,6 +277,7 @@ impl alkahest::Pack for &'_ Triangle { #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] pub struct Mesh { + #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub triangles: Vec, } diff --git a/src/datasets/minecraft_savedata/minecraft_savedata_bilrost.rs b/src/datasets/minecraft_savedata/minecraft_savedata_bilrost.rs new file mode 100644 index 0000000..6a33e4b --- /dev/null +++ b/src/datasets/minecraft_savedata/minecraft_savedata_bilrost.rs @@ -0,0 +1,261 @@ +//! The bilrost implementation for the minecraft savedata types is customized purely to support the +//! UUID type and the (f64, f64, f64) native tuple type. If those were changed no conversion would +//! be necessary. + +use bilrost::Message; + +use crate::bench_bilrost::ToBilrost; + +#[derive(Clone, PartialEq, Message)] +pub struct Vector3d(pub f64, pub f64, pub f64); + +impl From<(f64, f64, f64)> for Vector3d { + fn from(value: (f64, f64, f64)) -> Self { + Self(value.0, value.1, value.2) + } +} + +impl From for (f64, f64, f64) { + fn from(value: Vector3d) -> Self { + (value.0, value.1, value.2) + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Vector2f(pub f32, pub f32); + +impl From<(f32, f32)> for Vector2f { + fn from(value: (f32, f32)) -> Self { + Self(value.0, value.1) + } +} + +impl From for (f32, f32) { + fn from(value: Vector2f) -> Self { + (value.0, value.1) + } +} + +/// Bilrost has its own Entity +#[derive(Clone, PartialEq, Message)] +pub struct Entity { + pub id: String, + pub pos: Vector3d, + pub motion: Vector3d, + pub rotation: Vector2f, + pub fall_distance: f32, + pub fire: u16, + pub air: u16, + pub on_ground: bool, + pub no_gravity: bool, + pub invulnerable: bool, + pub portal_cooldown: i32, + #[bilrost(encoding(packed < fixed >))] + pub uuid: Vec, + pub custom_name: Option, + pub custom_name_visible: bool, + pub silent: bool, + pub glowing: bool, +} + +impl ToBilrost for super::Entity { + type Message = Entity; + type Serializable<'a> = Entity; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Entity { + id: self.id.clone(), + pos: self.pos.into(), + motion: self.motion.into(), + rotation: self.rotation.into(), + fall_distance: self.fall_distance, + fire: self.fire, + air: self.air, + on_ground: self.on_ground, + no_gravity: self.no_gravity, + invulnerable: self.invulnerable, + portal_cooldown: self.portal_cooldown, + uuid: self.uuid.into(), + custom_name: self.custom_name.clone(), + custom_name_visible: self.custom_name_visible, + silent: self.silent, + glowing: self.glowing, + } + } +} + +impl From for super::Entity { + fn from(value: Entity) -> Self { + Self { + id: value.id, + pos: value.pos.into(), + motion: value.motion.into(), + rotation: value.rotation.into(), + fall_distance: value.fall_distance, + fire: value.fire, + air: value.air, + on_ground: value.on_ground, + no_gravity: value.no_gravity, + invulnerable: value.invulnerable, + portal_cooldown: value.portal_cooldown, + uuid: value.uuid.as_slice().try_into().unwrap(), + custom_name: value.custom_name, + custom_name_visible: value.custom_name_visible, + silent: value.silent, + glowing: value.glowing, + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Vehicle { + #[bilrost(encoding(packed < fixed >))] + pub uuid: Vec, + pub entity: Entity, +} + +#[derive(Clone, PartialEq, Message)] +pub struct Player { + pub game_type: Option, + pub previous_game_type: Option, + pub score: i64, + pub dimension: String, + pub selected_item_slot: u32, + pub selected_item: super::Item, + pub spawn_dimension: Option, + pub spawn_x: i64, + pub spawn_y: i64, + pub spawn_z: i64, + pub spawn_forced: Option, + pub sleep_timer: u16, + pub food_exhaustion_level: f32, + pub food_saturation_level: f32, + pub food_tick_timer: u32, + pub xp_level: u32, + pub xp_p: f32, + pub xp_total: i32, + pub xp_seed: i32, + #[bilrost(encoding(packed))] + pub inventory: Vec, + #[bilrost(encoding(packed))] + pub ender_items: Vec, + pub abilities: super::Abilities, + pub entered_nether_position: Option, + pub root_vehicle: Option, + pub shoulder_entity_left: Option, + pub shoulder_entity_right: Option, + pub seen_credits: bool, + pub recipe_book: super::RecipeBook, +} + +impl ToBilrost for super::Player { + type Message = Player; + type Serializable<'a> = Player; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Player { + game_type: Some(self.game_type), + previous_game_type: Some(self.previous_game_type), + score: self.score, + dimension: self.dimension.clone(), + selected_item_slot: self.selected_item_slot, + selected_item: self.selected_item.clone(), + spawn_dimension: self.spawn_dimension.clone(), + spawn_x: self.spawn_x, + spawn_y: self.spawn_y, + spawn_z: self.spawn_z, + spawn_forced: self.spawn_forced, + sleep_timer: self.sleep_timer, + food_exhaustion_level: self.food_exhaustion_level, + food_saturation_level: self.food_saturation_level, + food_tick_timer: self.food_tick_timer, + xp_level: self.xp_level, + xp_p: self.xp_p, + xp_total: self.xp_total, + xp_seed: self.xp_seed, + inventory: self.inventory.clone(), + ender_items: self.ender_items.clone(), + abilities: self.abilities, + entered_nether_position: self.entered_nether_position.map(Into::into), + root_vehicle: self.root_vehicle.as_ref().map(|(uuid, entity)| Vehicle { + uuid: uuid.into(), + entity: entity.to_bilrost(), + }), + shoulder_entity_left: self + .shoulder_entity_left + .as_ref() + .map(ToBilrost::to_bilrost), + shoulder_entity_right: self + .shoulder_entity_right + .as_ref() + .map(ToBilrost::to_bilrost), + seen_credits: self.seen_credits, + recipe_book: self.recipe_book.clone(), + } + } +} + +impl From for super::Player { + fn from(value: Player) -> Self { + Self { + game_type: value.game_type.unwrap(), + previous_game_type: value.previous_game_type.unwrap(), + score: value.score, + dimension: value.dimension, + selected_item_slot: value.selected_item_slot, + selected_item: value.selected_item, + spawn_dimension: value.spawn_dimension, + spawn_x: value.spawn_x, + spawn_y: value.spawn_y, + spawn_z: value.spawn_z, + spawn_forced: value.spawn_forced, + sleep_timer: value.sleep_timer, + food_exhaustion_level: value.food_exhaustion_level, + food_saturation_level: value.food_saturation_level, + food_tick_timer: value.food_tick_timer, + xp_level: value.xp_level, + xp_p: value.xp_p, + xp_total: value.xp_total, + xp_seed: value.xp_seed, + inventory: value.inventory, + ender_items: value.ender_items, + abilities: value.abilities, + entered_nether_position: value.entered_nether_position.map(Into::into), + root_vehicle: value.root_vehicle.map(|vehicle| { + ( + vehicle.uuid.as_slice().try_into().unwrap(), + vehicle.entity.into(), + ) + }), + shoulder_entity_left: value.shoulder_entity_left.map(Into::into), + shoulder_entity_right: value.shoulder_entity_right.map(Into::into), + seen_credits: value.seen_credits, + recipe_book: value.recipe_book, + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Players { + #[bilrost(encoding(packed))] + pub players: Vec, +} + +impl ToBilrost for super::Players { + type Message = Players; + type Serializable<'a> = Players; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Players { + players: self.players.iter().map(ToBilrost::to_bilrost).collect(), + } + } +} + +impl From for super::Players { + fn from(value: Players) -> Self { + Self { + players: value.players.into_iter().map(Into::into).collect(), + } + } +} diff --git a/src/datasets/minecraft_savedata/mod.rs b/src/datasets/minecraft_savedata/mod.rs index 7b394a3..962775f 100644 --- a/src/datasets/minecraft_savedata/mod.rs +++ b/src/datasets/minecraft_savedata/mod.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "bilrost")] +pub mod minecraft_savedata_bilrost; #[cfg(feature = "capnp")] pub mod minecraft_savedata_capnp; #[cfg(feature = "flatbuffers")] @@ -32,6 +34,7 @@ use crate::{generate_vec, Generate}; #[derive(Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Enumeration))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -60,9 +63,13 @@ use crate::{generate_vec, Generate}; #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] #[repr(u8)] pub enum GameType { + #[cfg_attr(feature = "bilrost", bilrost(0))] Survival, + #[cfg_attr(feature = "bilrost", bilrost(1))] Creative, + #[cfg_attr(feature = "bilrost", bilrost(2))] Adventure, + #[cfg_attr(feature = "bilrost", bilrost(3))] Spectator, } @@ -144,6 +151,7 @@ impl alkahest::Pack for GameType { #[derive(Clone, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -170,7 +178,9 @@ impl alkahest::Pack for GameType { #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] pub struct Item { + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub count: i8, + #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub slot: u8, pub id: String, } @@ -277,6 +287,7 @@ impl alkahest::Pack for &'_ Item { #[derive(Clone, Copy, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -719,6 +730,7 @@ impl alkahest::Pack for &'_ Entity { #[derive(Clone, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -745,7 +757,9 @@ impl alkahest::Pack for &'_ Entity { #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] pub struct RecipeBook { + #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub recipes: Vec, + #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub to_be_displayed: Vec, pub is_filtering_craftable: bool, pub is_gui_open: bool, diff --git a/src/datasets/mk48/mk48_bilrost.rs b/src/datasets/mk48/mk48_bilrost.rs new file mode 100644 index 0000000..1019a6a --- /dev/null +++ b/src/datasets/mk48/mk48_bilrost.rs @@ -0,0 +1,218 @@ +//! The bilrost implementation for the MK48 data types, as for minecraft_savedata, is customized +//! purely to support the fields which have native tuple types like (i8, i8) and (f32, f32). If +//! those were changed no conversion would be necessary. + +use crate::bench_bilrost::ToBilrost; +use bilrost::Message; + +#[derive(Clone, PartialEq, Message)] +pub struct Vector2f(pub f32, pub f32); + +impl From<(f32, f32)> for Vector2f { + fn from(value: (f32, f32)) -> Self { + Self(value.0, value.1) + } +} + +impl From for (f32, f32) { + fn from(value: Vector2f) -> Self { + (value.0, value.1) + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Transform { + #[bilrost(encoding(varint))] + pub altitude: i8, + pub angle: u16, + pub position: Vector2f, + pub velocity: i16, +} + +impl ToBilrost for super::Transform { + type Message = Transform; + type Serializable<'a> = Transform; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Transform { + altitude: self.altitude, + angle: self.angle, + position: self.position.into(), + velocity: self.velocity, + } + } +} + +impl From for super::Transform { + fn from(value: Transform) -> Self { + Self { + altitude: value.altitude, + angle: value.angle, + position: value.position.into(), + velocity: value.velocity, + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Contact { + #[bilrost(encoding(varint))] + pub damage: u8, + pub entity_id: u32, + pub entity_type: Option, + pub guidance: super::Guidance, + pub player_id: Option, + #[bilrost(encoding(packed))] + pub reloads: Vec, + pub transform: Transform, + #[bilrost(encoding(packed))] + pub turret_angles: Vec, +} + +impl ToBilrost for super::Contact { + type Message = Contact; + type Serializable<'a> = Contact; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Contact { + damage: self.damage, + entity_id: self.entity_id, + entity_type: self.entity_type, + guidance: self.guidance, + player_id: self.player_id, + reloads: self.reloads.clone(), + transform: self.transform.to_bilrost(), + turret_angles: self.turret_angles.clone(), + } + } +} + +impl From for super::Contact { + fn from(value: Contact) -> Self { + Self { + damage: value.damage, + entity_id: value.entity_id, + entity_type: value.entity_type, + guidance: value.guidance, + player_id: value.player_id, + reloads: value.reloads, + transform: value.transform.into(), + turret_angles: value.turret_angles, + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct ChunkId { + #[bilrost(encoding(varint))] + pub x: i8, + #[bilrost(encoding(varint))] + pub y: i8, +} + +impl From<(i8, i8)> for ChunkId { + fn from(value: (i8, i8)) -> Self { + Self { + x: value.0, + y: value.1, + } + } +} + +impl From for (i8, i8) { + fn from(value: ChunkId) -> Self { + (value.x, value.y) + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct TerrainUpdate { + pub chunk_id: ChunkId, + #[bilrost(encoding(plainbytes))] + pub data: Vec, +} + +impl ToBilrost for super::TerrainUpdate { + type Message = TerrainUpdate; + type Serializable<'a> = TerrainUpdate; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + TerrainUpdate { + chunk_id: self.chunk_id.into(), + data: self.data.clone(), + } + } +} + +impl From for super::TerrainUpdate { + fn from(value: TerrainUpdate) -> Self { + Self { + chunk_id: value.chunk_id.into(), + data: value.data, + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Update { + #[bilrost(encoding(packed))] + pub contacts: Vec, + pub score: u32, + pub world_radius: f32, + #[bilrost(encoding(packed))] + pub terrain_updates: Vec, +} + +impl ToBilrost for super::Update { + type Message = Update; + type Serializable<'a> = Update; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Update { + contacts: self.contacts.iter().map(ToBilrost::to_bilrost).collect(), + score: self.score, + world_radius: self.world_radius, + terrain_updates: self + .terrain_updates + .iter() + .map(ToBilrost::to_bilrost) + .collect(), + } + } +} + +impl From for super::Update { + fn from(value: Update) -> Self { + Self { + contacts: value.contacts.into_iter().map(Into::into).collect(), + score: value.score, + world_radius: value.world_radius, + terrain_updates: value.terrain_updates.into_iter().map(Into::into).collect(), + } + } +} + +#[derive(Clone, PartialEq, Message)] +pub struct Updates { + #[bilrost(encoding(packed))] + pub updates: Vec, +} + +impl ToBilrost for super::Updates { + type Message = Updates; + type Serializable<'a> = Updates; + + fn to_bilrost(&self) -> Self::Serializable<'_> { + Updates { + updates: self.updates.iter().map(ToBilrost::to_bilrost).collect(), + } + } +} + +impl From for super::Updates { + fn from(value: Updates) -> Self { + Self { + updates: value.updates.into_iter().map(Into::into).collect(), + } + } +} diff --git a/src/datasets/mk48/mod.rs b/src/datasets/mk48/mod.rs index b3e9cfe..bc78061 100644 --- a/src/datasets/mk48/mod.rs +++ b/src/datasets/mk48/mod.rs @@ -1,5 +1,7 @@ #[cfg(feature = "bebop")] pub mod mk48_bebop; +#[cfg(feature = "bilrost")] +pub mod mk48_bilrost; #[cfg(any(feature = "capnp", feature = "prost"))] pub mod mk48_capnp; #[cfg(feature = "flatbuffers")] @@ -34,6 +36,7 @@ use crate::{generate_vec, Generate}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Enumeration))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( @@ -62,15 +65,25 @@ use crate::{generate_vec, Generate}; #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] #[repr(u8)] pub enum EntityType { + #[cfg_attr(feature = "bilrost", bilrost(0))] ArleighBurke, + #[cfg_attr(feature = "bilrost", bilrost(1))] Bismarck, + #[cfg_attr(feature = "bilrost", bilrost(2))] Clemenceau, + #[cfg_attr(feature = "bilrost", bilrost(3))] Fletcher, + #[cfg_attr(feature = "bilrost", bilrost(4))] G5, + #[cfg_attr(feature = "bilrost", bilrost(5))] Iowa, + #[cfg_attr(feature = "bilrost", bilrost(6))] Kolkata, + #[cfg_attr(feature = "bilrost", bilrost(7))] Osa, + #[cfg_attr(feature = "bilrost", bilrost(8))] Yasen, + #[cfg_attr(feature = "bilrost", bilrost(9))] Zubr, } @@ -402,6 +415,7 @@ impl alkahest::Pack for Transform { #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "abomonation", derive(abomonation_derive::Abomonation))] +#[cfg_attr(feature = "bilrost", derive(bilrost::Message))] #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))] #[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))] #[cfg_attr( diff --git a/src/lib.rs b/src/lib.rs index 76ac15f..4564bce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,8 @@ pub mod bench_abomonation; #[cfg(feature = "alkahest")] pub mod bench_alkahest; +#[cfg(feature = "bilrost")] +pub mod bench_bilrost; #[cfg(feature = "bincode")] pub mod bench_bincode; #[cfg(feature = "bincode1")] From 20affc1d2543363da126f3f1f29dd4f389d69769 Mon Sep 17 00:00:00 2001 From: Kent Ross Date: Sat, 6 Apr 2024 20:16:13 -0700 Subject: [PATCH 2/2] regenerate prost files --- src/datasets/log/prost.log.rs | 1 + src/datasets/mesh/prost.mesh.rs | 1 + src/datasets/minecraft_savedata/prost.minecraft_savedata.rs | 1 + src/datasets/mk48/prost.mk48.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/src/datasets/log/prost.log.rs b/src/datasets/log/prost.log.rs index ef407ea..230b8fa 100644 --- a/src/datasets/log/prost.log.rs +++ b/src/datasets/log/prost.log.rs @@ -1,3 +1,4 @@ +// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Address { diff --git a/src/datasets/mesh/prost.mesh.rs b/src/datasets/mesh/prost.mesh.rs index 4aa6134..2633158 100644 --- a/src/datasets/mesh/prost.mesh.rs +++ b/src/datasets/mesh/prost.mesh.rs @@ -1,3 +1,4 @@ +// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Vector3 { diff --git a/src/datasets/minecraft_savedata/prost.minecraft_savedata.rs b/src/datasets/minecraft_savedata/prost.minecraft_savedata.rs index be7ce73..57dba36 100644 --- a/src/datasets/minecraft_savedata/prost.minecraft_savedata.rs +++ b/src/datasets/minecraft_savedata/prost.minecraft_savedata.rs @@ -1,3 +1,4 @@ +// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Item { diff --git a/src/datasets/mk48/prost.mk48.rs b/src/datasets/mk48/prost.mk48.rs index dccb9ce..4873d32 100644 --- a/src/datasets/mk48/prost.mk48.rs +++ b/src/datasets/mk48/prost.mk48.rs @@ -1,3 +1,4 @@ +// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Vector2f {