1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

make fixedbitset require generic const exprs again :3

This commit is contained in:
mat 2025-05-30 12:59:08 -13:45
parent cfdd8e690f
commit a64c650504
18 changed files with 78 additions and 61 deletions

View file

@ -256,7 +256,7 @@ impl<S> CommandDispatcher<S> {
return Err(BuiltInError::DispatcherUnknownCommand.create_with_context(&parse.reader));
};
flat_context.execute_all(original.source().clone(), self.consumer.as_ref())
flat_context.execute_all(original.source.clone(), self.consumer.as_ref())
}
pub fn get_all_usage(

View file

@ -10,7 +10,7 @@ use crate::{
/// A built `CommandContextBuilder`.
pub struct CommandContext<S> {
pub(super) source: Arc<S>,
pub source: Arc<S>,
pub(super) input: String,
pub(super) arguments: HashMap<String, ParsedArgument>,
pub(super) command: Command<S>,
@ -93,10 +93,6 @@ impl<S> CommandContext<S> {
&self.command
}
pub fn source(&self) -> &Arc<S> {
&self.source
}
pub fn argument(&self, name: &str) -> Option<&dyn Any> {
let argument = self.arguments.get(name);
argument.map(|a| a.result.as_ref())

View file

@ -131,7 +131,7 @@ impl DispatchStorage {
///
/// Spawns an entity with the [`SpawnedEntity`] component.
fn command_spawn_entity(context: &CommandContext<WorldAccessor>) -> i32 {
context.source().lock().spawn(SpawnedEntity);
context.source.lock().spawn(SpawnedEntity);
0
}
@ -143,7 +143,7 @@ impl DispatchStorage {
let num = get_integer(context, "entities").unwrap();
for _ in 0..num {
context.source().lock().spawn(SpawnedEntity);
context.source.lock().spawn(SpawnedEntity);
}
0

View file

@ -127,23 +127,27 @@ impl From<Vec<u8>> for BitSet {
/// A list of bits with a known fixed size.
///
/// The `N` is the number of bytes reserved for the bitset. You're encouraged to
/// use it like `FixedBitSet<{ 20_usize.div_ceil(8) }>` if you need 20 bits.
///
/// TODO: this should be changed back to bits once this is resolved:
/// <https://github.com/rust-lang/rust/issues/133199#issuecomment-2531645526>
/// use it like `FixedBitSet<20>` if you need 20 bits.
///
/// Note that this is primarily meant for fast serialization and deserialization
/// for Minecraft, if you don't need that you should use the `fixedbitset` crate
/// since it's approximately 20% faster (since it stores the data as usizes
/// instead of u8s).
/// for Minecraft. An alternative that would be ~20% faster for accessing data
/// could store it interally as `usize`s instead of `u8`s.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FixedBitSet<const N: usize> {
data: [u8; N],
pub struct FixedBitSet<const N: usize>
where
[u8; bits_to_bytes(N)]: Sized,
{
data: [u8; bits_to_bytes(N)],
}
impl<const N: usize> FixedBitSet<N> {
pub fn new() -> Self {
FixedBitSet { data: [0; N] }
impl<const N: usize> FixedBitSet<N>
where
[u8; bits_to_bytes(N)]: Sized,
{
pub const fn new() -> Self {
FixedBitSet {
data: [0; bits_to_bytes(N)],
}
}
#[inline]
@ -157,29 +161,42 @@ impl<const N: usize> FixedBitSet<N> {
}
}
impl<const N: usize> AzaleaRead for FixedBitSet<N> {
impl<const N: usize> AzaleaRead for FixedBitSet<N>
where
[u8; bits_to_bytes(N)]: Sized,
{
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let mut data = [0; N];
for item in data.iter_mut().take(N) {
let mut data = [0; bits_to_bytes(N)];
for item in data.iter_mut().take(bits_to_bytes(N)) {
*item = u8::azalea_read(buf)?;
}
Ok(FixedBitSet { data })
}
}
impl<const N: usize> AzaleaWrite for FixedBitSet<N> {
impl<const N: usize> AzaleaWrite for FixedBitSet<N>
where
[u8; bits_to_bytes(N)]: Sized,
{
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
for i in 0..N {
for i in 0..bits_to_bytes(N) {
self.data[i].azalea_write(buf)?;
}
Ok(())
}
}
impl<const N: usize> Default for FixedBitSet<N> {
impl<const N: usize> Default for FixedBitSet<N>
where
[u8; bits_to_bytes(N)]: Sized,
{
fn default() -> Self {
Self::new()
}
}
pub const fn bits_to_bytes(n: usize) -> usize {
n.div_ceil(8)
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,3 +1,5 @@
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![doc = include_str!("../README.md")]
pub mod aabb;

View file

@ -97,7 +97,7 @@ impl Default for ModelCustomization {
impl AzaleaRead for ModelCustomization {
fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
let set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<7>::azalea_read(buf)?;
Ok(Self {
cape: set.index(0),
jacket: set.index(1),
@ -112,7 +112,7 @@ impl AzaleaRead for ModelCustomization {
impl AzaleaWrite for ModelCustomization {
fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<7>::new();
if self.cape {
set.set(0);
}

View file

@ -32,7 +32,7 @@ pub struct RelativeMovements {
impl AzaleaRead for RelativeMovements {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
// yes minecraft seriously wastes that many bits, smh
let set = FixedBitSet::<{ 32_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<32>::azalea_read(buf)?;
Ok(RelativeMovements {
x: set.index(0),
y: set.index(1),
@ -49,7 +49,7 @@ impl AzaleaRead for RelativeMovements {
impl AzaleaWrite for RelativeMovements {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut set = FixedBitSet::<{ 32_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<32>::new();
let mut set_bit = |index: usize, value: bool| {
if value {
set.set(index);

View file

@ -36,7 +36,7 @@ impl AzaleaRead for Operation {
_ => {
return Err(BufReadError::UnexpectedEnumVariant {
id: operation_id as i32,
})
});
}
})
}
@ -116,7 +116,7 @@ pub struct Properties {
impl AzaleaRead for Properties {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<3>::azalea_read(buf)?;
Ok(Self {
darken_screen: set.index(0),
play_music: set.index(1),
@ -127,7 +127,7 @@ impl AzaleaRead for Properties {
impl AzaleaWrite for Properties {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<3>::new();
if self.darken_screen {
set.set(0);
}

View file

@ -46,7 +46,7 @@ impl<T: PartialEq> PartialEq for BrigadierNumber<T> {
impl<T: AzaleaRead> AzaleaRead for BrigadierNumber<T> {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let flags = FixedBitSet::<{ 2_usize.div_ceil(8) }>::azalea_read(buf)?;
let flags = FixedBitSet::<2>::azalea_read(buf)?;
let min = if flags.index(0) {
Some(T::azalea_read(buf)?)
} else {
@ -62,7 +62,7 @@ impl<T: AzaleaRead> AzaleaRead for BrigadierNumber<T> {
}
impl<T: AzaleaWrite> AzaleaWrite for BrigadierNumber<T> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut flags = FixedBitSet::<{ 2_usize.div_ceil(8) }>::new();
let mut flags = FixedBitSet::<2>::new();
if self.min.is_some() {
flags.set(0);
}
@ -158,7 +158,7 @@ pub struct EntityParser {
}
impl AzaleaRead for EntityParser {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let flags = FixedBitSet::<{ 2_usize.div_ceil(8) }>::azalea_read(buf)?;
let flags = FixedBitSet::<2>::azalea_read(buf)?;
Ok(EntityParser {
single: flags.index(0),
players_only: flags.index(1),
@ -167,7 +167,7 @@ impl AzaleaRead for EntityParser {
}
impl AzaleaWrite for EntityParser {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut flags = FixedBitSet::<{ 2_usize.div_ceil(8) }>::new();
let mut flags = FixedBitSet::<2>::new();
if self.single {
flags.set(0);
}
@ -182,9 +182,11 @@ impl AzaleaWrite for EntityParser {
// TODO: BrigadierNodeStub should have more stuff
impl AzaleaRead for BrigadierNodeStub {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let flags = FixedBitSet::<{ 8_usize.div_ceil(8) }>::azalea_read(buf)?;
let flags = FixedBitSet::<8>::azalea_read(buf)?;
if flags.index(5) || flags.index(6) || flags.index(7) {
warn!("The flags from a Brigadier node are over 31. This is a bug, BrigadierParser probably needs updating.",);
warn!(
"The flags from a Brigadier node are over 31. This is a bug, BrigadierParser probably needs updating.",
);
}
let node_type = u8::from(flags.index(0)) + (u8::from(flags.index(1)) * 2);
@ -241,7 +243,7 @@ impl AzaleaRead for BrigadierNodeStub {
impl AzaleaWrite for BrigadierNodeStub {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut flags = FixedBitSet::<{ 4_usize.div_ceil(8) }>::new();
let mut flags = FixedBitSet::<4>::new();
if self.is_executable {
flags.set(2);
}

View file

@ -23,7 +23,7 @@ pub struct PlayerAbilitiesFlags {
impl AzaleaRead for PlayerAbilitiesFlags {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 4_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<4>::azalea_read(buf)?;
Ok(PlayerAbilitiesFlags {
invulnerable: set.index(0),
flying: set.index(1),
@ -35,7 +35,7 @@ impl AzaleaRead for PlayerAbilitiesFlags {
impl AzaleaWrite for PlayerAbilitiesFlags {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 4_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<4>::new();
if self.invulnerable {
set.set(0);
}

View file

@ -183,7 +183,7 @@ pub struct ActionEnumSet {
impl AzaleaRead for ActionEnumSet {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<7>::azalea_read(buf)?;
Ok(ActionEnumSet {
add_player: set.index(0),
initialize_chat: set.index(1),
@ -199,7 +199,7 @@ impl AzaleaRead for ActionEnumSet {
impl AzaleaWrite for ActionEnumSet {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<7>::new();
if self.add_player {
set.set(0);
}

View file

@ -14,7 +14,7 @@ pub struct ClientboundStopSound {
impl AzaleaRead for ClientboundStopSound {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 2_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<2>::azalea_read(buf)?;
let source = if set.index(0) {
Some(SoundSource::azalea_read(buf)?)
} else {
@ -32,7 +32,7 @@ impl AzaleaRead for ClientboundStopSound {
impl AzaleaWrite for ClientboundStopSound {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 2_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<2>::new();
if self.source.is_some() {
set.set(0);
}

View file

@ -17,6 +17,6 @@ pub struct ServerboundChat {
pub struct LastSeenMessagesUpdate {
#[var]
pub offset: u32,
pub acknowledged: FixedBitSet<{ 20_usize.div_ceil(8) }>,
pub acknowledged: FixedBitSet<20>,
pub checksum: u8,
}

View file

@ -13,7 +13,7 @@ pub struct ServerboundPlayerAbilities {
impl AzaleaRead for ServerboundPlayerAbilities {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 2_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<2>::azalea_read(buf)?;
Ok(Self {
is_flying: set.index(1),
})
@ -22,7 +22,7 @@ impl AzaleaRead for ServerboundPlayerAbilities {
impl AzaleaWrite for ServerboundPlayerAbilities {
fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 2_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<2>::new();
if self.is_flying {
set.set(1);
}

View file

@ -18,7 +18,7 @@ pub struct ServerboundPlayerInput {
impl AzaleaRead for ServerboundPlayerInput {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<7>::azalea_read(buf)?;
Ok(Self {
forward: set.index(0),
backward: set.index(1),
@ -33,7 +33,7 @@ impl AzaleaRead for ServerboundPlayerInput {
impl AzaleaWrite for ServerboundPlayerInput {
fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<7>::new();
if self.forward {
set.set(0);
}

View file

@ -30,7 +30,7 @@ impl AzaleaRead for ServerboundSetCommandBlock {
let command = String::azalea_read(buf)?;
let mode = Mode::azalea_read(buf)?;
let set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<3>::azalea_read(buf)?;
Ok(Self {
pos,
command,
@ -48,7 +48,7 @@ impl AzaleaWrite for ServerboundSetCommandBlock {
self.command.azalea_write(buf)?;
self.mode.azalea_write(buf)?;
let mut set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<3>::new();
if self.track_output {
set.set(0);
}

View file

@ -73,7 +73,7 @@ pub struct Flags {
impl AzaleaRead for Flags {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::azalea_read(buf)?;
let set = FixedBitSet::<3>::azalea_read(buf)?;
Ok(Self {
ignore_entities: set.index(0),
show_air: set.index(1),
@ -84,7 +84,7 @@ impl AzaleaRead for Flags {
impl AzaleaWrite for Flags {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::new();
let mut set = FixedBitSet::<3>::new();
if self.ignore_entities {
set.set(0);
}

View file

@ -82,11 +82,11 @@ impl CachedSections {
pub struct CachedSection {
pub pos: ChunkSectionPos,
/// Blocks that we can fully pass through (like air).
pub passable_bitset: FixedBitSet<{ 4096_usize.div_ceil(8) }>,
pub passable_bitset: FixedBitSet<4096>,
/// Blocks that we can stand on and do parkour from.
pub solid_bitset: FixedBitSet<{ 4096_usize.div_ceil(8) }>,
pub solid_bitset: FixedBitSet<4096>,
/// Blocks that we can stand on but might not be able to parkour from.
pub standable_bitset: FixedBitSet<{ 4096_usize.div_ceil(8) }>,
pub standable_bitset: FixedBitSet<4096>,
}
impl CachedWorld {
@ -195,9 +195,9 @@ impl CachedWorld {
fn calculate_bitsets_for_section(&self, section_pos: ChunkSectionPos) -> Option<CachedSection> {
self.with_section(section_pos, |section| {
let mut passable_bitset = FixedBitSet::<{ 4096_usize.div_ceil(8) }>::new();
let mut solid_bitset = FixedBitSet::<{ 4096_usize.div_ceil(8) }>::new();
let mut standable_bitset = FixedBitSet::<{ 4096_usize.div_ceil(8) }>::new();
let mut passable_bitset = FixedBitSet::<4096>::new();
let mut solid_bitset = FixedBitSet::<4096>::new();
let mut standable_bitset = FixedBitSet::<4096>::new();
for i in 0..4096 {
let block_state = section.get_at_index(i);
if is_block_state_passable(block_state) {