summaryrefslogtreecommitdiff
path: root/ecs/src/util.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-05-21 17:55:20 +0200
committerHampusM <hampus@hampusmat.com>2026-05-21 17:55:20 +0200
commit8022e8998290b067b8aa0cb9cba8ba410826bdab (patch)
tree7171e79ce530e03079046ee8fd12167160c45480 /ecs/src/util.rs
parent412cee02c252f91bcf0b70a3f5cc5fca6d2b4c62 (diff)
chore: rename ecs* crates to engine-ecs*
Diffstat (limited to 'ecs/src/util.rs')
-rw-r--r--ecs/src/util.rs415
1 files changed, 0 insertions, 415 deletions
diff --git a/ecs/src/util.rs b/ecs/src/util.rs
deleted file mode 100644
index 27e9748..0000000
--- a/ecs/src/util.rs
+++ /dev/null
@@ -1,415 +0,0 @@
-use std::hash::Hash;
-use std::mem::transmute;
-use std::ops::{BitAnd, Deref};
-
-use hashbrown::HashMap;
-
-pub(crate) mod array_vec;
-
-pub trait VecExt<Item>
-{
- fn insert_at_part_pt_by_key<Key>(
- &mut self,
- item: Item,
- func: impl FnMut(&Item) -> &Key,
- ) where
- Key: Ord;
-}
-
-impl<Item> VecExt<Item> for Vec<Item>
-{
- fn insert_at_part_pt_by_key<Key>(
- &mut self,
- item: Item,
- mut func: impl FnMut(&Item) -> &Key,
- ) where
- Key: Ord,
- {
- let key = func(&item);
-
- let insert_index = self.partition_point(|other_item| func(other_item) <= key);
-
- self.insert(insert_index, item);
- }
-}
-
-pub trait StreamingIterator
-{
- type Item<'a>
- where
- Self: 'a;
-
- fn streaming_next(&mut self) -> Option<Self::Item<'_>>;
-
- fn streaming_map<NewItem, Func>(self, func: Func) -> StreamingMap<Self, Func>
- where
- Self: Sized,
- Func: FnMut(Self::Item<'_>) -> NewItem,
- {
- StreamingMap { iter: self, func }
- }
-
- fn streaming_find<'this, Predicate>(
- &'this mut self,
- mut predicate: Predicate,
- ) -> Option<Self::Item<'this>>
- where
- Self: Sized,
- Predicate: FnMut(&Self::Item<'this>) -> bool,
- {
- while let Some(item) = unsafe {
- transmute::<Option<Self::Item<'_>>, Option<Self::Item<'_>>>(
- self.streaming_next(),
- )
- } {
- if predicate(&item) {
- return Some(item);
- }
- }
-
- None
- }
-}
-
-pub struct StreamingMap<Iter, Func>
-{
- iter: Iter,
- func: Func,
-}
-
-impl<Iter, Func, Item> StreamingIterator for StreamingMap<Iter, Func>
-where
- Iter: StreamingIterator,
- Func: FnMut(Iter::Item<'_>) -> Item,
-{
- type Item<'a>
- = Item
- where
- Iter: 'a,
- Func: 'a;
-
- fn streaming_next(&mut self) -> Option<Self::Item<'_>>
- {
- Some((self.func)(self.iter.streaming_next()?))
- }
-}
-
-#[derive(Debug)]
-pub enum BorrowedOrOwned<'a, Value>
-{
- Borrowned(&'a Value),
- Owned(Value),
-}
-
-impl<Value> Deref for BorrowedOrOwned<'_, Value>
-{
- type Target = Value;
-
- fn deref(&self) -> &Self::Target
- {
- match self {
- Self::Borrowned(value) => value,
- Self::Owned(value) => value,
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub enum Either<A, B>
-{
- A(A),
- B(B),
-}
-
-impl<A, B> Iterator for Either<A, B>
-where
- A: Iterator,
- B: Iterator<Item = A::Item>,
-{
- type Item = A::Item;
-
- fn next(&mut self) -> Option<Self::Item>
- {
- match self {
- Self::A(a) => a.next(),
- Self::B(b) => b.next(),
- }
- }
-}
-
-pub trait HashMapExt<Key, Value>
-{
- /// Returns true if the keys are a subset of another [`HashMap`]'s keys, i.e., `other`
- /// contains at least all the keys in `self`.
- fn keys_is_subset(&self, other: &Self) -> bool;
-
- /// Returns true if the keys are a superset of another [`HashMap`]'s keys, i.e.,
- /// `self` contains at least all the keys in `other`.
- fn keys_is_superset(&self, other: &Self) -> bool;
-}
-
-impl<Key, Value> HashMapExt<Key, Value> for HashMap<Key, Value>
-where
- Key: Eq + Hash,
-{
- fn keys_is_subset(&self, other: &Self) -> bool
- {
- if self.len() <= other.len() {
- self.keys().all(|key| other.contains_key(key))
- } else {
- false
- }
- }
-
- fn keys_is_superset(&self, other: &Self) -> bool
- {
- other.keys_is_subset(self)
- }
-}
-
-pub trait Array<Item>:
- AsRef<[Item]>
- + AsMut<[Item]>
- + IntoIterator<Item = Item>
- + Into<Vec<Item>>
- + Sortable<Item = Item>
- + sealed::Sealed
-{
-}
-
-impl<Item, const CNT: usize> Array<Item> for [Item; CNT] {}
-
-impl<Item, const CNT: usize> sealed::Sealed for [Item; CNT] {}
-
-pub trait Sortable
-{
- type Item;
-
- fn sort_by_key_b<Key, Func>(&mut self, func: Func)
- where
- Func: FnMut(&Self::Item) -> Key,
- Key: Ord;
-}
-
-impl<Item> Sortable for [Item]
-{
- type Item = Item;
-
- fn sort_by_key_b<Key, Func>(&mut self, func: Func)
- where
- Func: FnMut(&Self::Item) -> Key,
- Key: Ord,
- {
- self.sort_by_key(func);
- }
-}
-
-impl<Item, const LENGTH: usize> Sortable for [Item; LENGTH]
-{
- type Item = Item;
-
- fn sort_by_key_b<Key, Func>(&mut self, func: Func)
- where
- Func: FnMut(&Self::Item) -> Key,
- Key: Ord,
- {
- self.sort_by_key(func);
- }
-}
-
-impl<Item> Sortable for Vec<Item>
-{
- type Item = Item;
-
- fn sort_by_key_b<Key, Func>(&mut self, func: Func)
- where
- Func: FnMut(&Self::Item) -> Key,
- Key: Ord,
- {
- self.sort_by_key(func);
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct BitMask<Value>
-{
- mask: Value,
-}
-
-impl BitMask<u64>
-{
- #[must_use]
- pub const fn new(mask: u64) -> Self
- {
- Self { mask }
- }
-
- #[must_use]
- pub const fn value(self) -> u64
- {
- self.mask
- }
-
- /// Prepares a bitfield value in the range of bits specified by this `BitMask`.
- #[must_use]
- pub const fn field_prep(self, field_value: u64) -> u64
- {
- debug_assert!(field_value < 1 << self.mask.count_ones());
-
- ((field_value) << self.mask.trailing_zeros()) & (self.mask)
- }
-}
-
-impl BitAnd<u64> for BitMask<u64>
-{
- type Output = u64;
-
- fn bitand(self, rhs: u64) -> Self::Output
- {
- self.mask & rhs
- }
-}
-
-pub trait NumberExt: Sized
-{
- /// Returns a range of bits (field) specified by the provided [`BitMask`].
- #[must_use]
- fn field_get(self, field_mask: BitMask<Self>) -> Self;
-}
-
-impl NumberExt for u64
-{
- fn field_get(self, field_mask: BitMask<Self>) -> Self
- {
- (field_mask & self) >> field_mask.value().trailing_zeros()
- }
-}
-
-macro_rules! gen_mask_64 {
- ($low: literal..=$high: literal) => {
- const {
- if $high <= $low {
- panic!("High bit index cannot be less than or equal to low bit index");
- }
-
- (((!0u64) - (1u64 << ($low)) + 1)
- & (!0u64 >> (u64::BITS as u64 - 1 - ($high))))
- }
- };
-}
-
-pub(crate) use gen_mask_64;
-
-macro_rules! impl_multiple {
- (
- $type: ident,
- ($(
- impl$(<$($generic: tt$(: $bound: ident)?),*>)?
- _<$($lt_param: lifetime),*><$($type_param: ty),*>
- $(($($extra_cb_arg: expr),*))?
- ),*)
- cb=(
- type_params=($($ty_param_matcher: ident),*)
- $(, $($extra_matcher: ident),+)?
- ) => {
- $($item_tt: tt)*
- }
- ) => {
- const _: () = {
- $crate::util::impl_multiple!(
- @(make_gen_item_macro)
- _gen_multiple_impl_item,
- ($($ty_param_matcher),*),
- ($($($extra_matcher),+)?),
- ($($item_tt)*)
- );
-
- $(
- impl $(<$($generic$(: $bound)?,)*>)? $type<$($lt_param,)* $($type_param),*>
- {
- _gen_multiple_impl_item!(
- type_params=($($type_param),*),
- $($($extra_cb_arg),*)?
- );
- }
- )*
- };
- };
-
- (
- @(make_gen_item_macro)
- $name: ident,
- ($($ty_param_matcher: ident),*),
- ($($extra_matcher: ident),*),
- ($($transcriber: tt)*)
- ) => {
- $crate::util::impl_multiple!(
- @(make_gen_item_macro)
- ($),
- $name,
- ($($ty_param_matcher),*),
- ($($extra_matcher),*),
- ($($transcriber)*)
- );
- };
-
- (
- @(make_gen_item_macro)
- ($dollar: tt),
- $name: ident,
- ($($ty_param_matcher: ident),*),
- ($($extra_matcher: ident),*),
- ($($transcriber: tt)*)
- ) => {
- $crate::util::impl_multiple!(
- @(make_gen_item_macro)
- $name,
- (
- type_params=($($dollar$ty_param_matcher: ty),*),
- $($dollar$extra_matcher: expr),*
- ) => {
- $($transcriber)*
- }
- );
- };
-
- (@(make_gen_item_macro) $name: ident, $($rule: tt)*) => {
- macro_rules! $name {
- $($rule)*
- }
- };
-}
-
-pub(crate) use impl_multiple;
-
-mod sealed
-{
- pub trait Sealed {}
-}
-
-#[cfg(test)]
-mod tests
-{
-
- use super::BitMask;
- use crate::util::NumberExt;
-
- #[test]
- fn field_get_works()
- {
- assert_eq!(0b11011u64.field_get(BitMask::new(0b11100)), 0b00110);
- }
-
- #[test]
- fn bitmask_field_prep_works()
- {
- assert_eq!(BitMask::new(0b11000).field_prep(3), 0b11000);
- }
-
- #[test]
- #[should_panic]
- fn bitmask_field_prep_too_large_value_panics()
- {
- let _ = BitMask::new(0b001110).field_prep(9);
- }
-}