summaryrefslogtreecommitdiff
path: root/ecs/src/util.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-03-17 22:08:45 +0100
committerHampusM <hampus@hampusmat.com>2025-03-17 23:08:53 +0100
commitee7c0cb713891ae480407f56823289f3fe3b9807 (patch)
tree8c0fa0bd98050ccd74ab0c9100d12c057bdea6cd /ecs/src/util.rs
parent64eddc633cea0f4bc5603cc2d4c4c6eafac5c177 (diff)
fix(ecs): correct oversights made in component storage rewrite
Diffstat (limited to 'ecs/src/util.rs')
-rw-r--r--ecs/src/util.rs132
1 files changed, 131 insertions, 1 deletions
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<Item>
+{
+ fn insert_at_partition_point_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_partition_point_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<'_>>>(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<'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, 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`