From ee7c0cb713891ae480407f56823289f3fe3b9807 Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 17 Mar 2025 22:08:45 +0100 Subject: fix(ecs): correct oversights made in component storage rewrite --- ecs/src/util.rs | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) (limited to 'ecs/src/util.rs') diff --git a/ecs/src/util.rs b/ecs/src/util.rs index 71021cd..fbd33fa 100644 --- a/ecs/src/util.rs +++ b/ecs/src/util.rs @@ -1,8 +1,138 @@ use std::hash::Hash; -use std::ops::BitAnd; +use std::mem::transmute; +use std::ops::{BitAnd, Deref}; use hashbrown::HashMap; +pub trait VecExt +{ + fn insert_at_partition_point_by_key( + &mut self, + item: Item, + func: impl FnMut(&Item) -> Key, + ) where + Key: Ord; +} + +impl VecExt for Vec +{ + fn insert_at_partition_point_by_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>; + + fn streaming_map(self, func: Func) -> StreamingMap + where + Self: Sized, + Func: FnMut(Self::Item<'_>) -> NewItem, + { + StreamingMap { iter: self, func } + } + + fn streaming_find<'this, Predicate>( + &'this mut self, + mut predicate: Predicate, + ) -> Option> + where + Self: Sized, + Predicate: FnMut(&Self::Item<'this>) -> bool, + { + while let Some(item) = + unsafe { transmute::<_, Option>>(self.streaming_next()) } + { + if predicate(&item) { + return Some(item); + } + } + + None + } +} + +pub struct StreamingMap +{ + iter: Iter, + func: Func, +} + +impl StreamingIterator for StreamingMap +where + Iter: StreamingIterator, + Func: FnMut(Iter::Item<'_>) -> Item, +{ + type Item<'a> + = Item + where + Iter: 'a, + Func: 'a; + + fn streaming_next(&mut self) -> Option> + { + Some((self.func)(self.iter.streaming_next()?)) + } +} + +#[derive(Debug)] +pub enum BorrowedOrOwned<'a, Value> +{ + Borrowned(&'a Value), + Owned(Value), +} + +impl<'a, Value> Deref for BorrowedOrOwned<'a, 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(A), + B(B), +} + +impl Iterator for Either +where + A: Iterator, + B: Iterator, +{ + type Item = A::Item; + + fn next(&mut self) -> Option + { + match self { + Self::A(a) => a.next(), + Self::B(b) => b.next(), + } + } +} + pub trait HashMapExt { /// Returns true if the keys are a subset of another [`HashMap`]'s keys, i.e., `other` -- cgit v1.2.3-18-g5258