Skip to content

Commit

Permalink
add tests, and...
Browse files Browse the repository at this point in the history
* rename `reset` → `remove`
* add function `remove_by_type`
* format code
  • Loading branch information
optozorax committed Apr 9, 2021
1 parent 5ee53f3 commit aa8c081
Show file tree
Hide file tree
Showing 10 changed files with 584 additions and 48 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions egui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ persistence = ["serde", "epaint/persistence", "ron"]
# Only needed if you plan to use the same egui::Context from multiple threads.
single_threaded = ["epaint/single_threaded"]
multi_threaded = ["epaint/multi_threaded"]

[dev-dependencies]
serde_json = "1"
131 changes: 125 additions & 6 deletions egui/src/any/any_map.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::any::element::{AnyMapElement, AnyMapTrait};
use std::hash::Hash;
use std::any::TypeId;
use std::collections::HashMap;
use std::hash::Hash;

/// Stores any object by `Key`.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -62,6 +62,19 @@ impl<Key: Hash + Eq> AnyMap<Key> {
pub fn insert<T: AnyMapTrait>(&mut self, key: Key, element: T) {
self.0.insert(key, AnyMapElement::new(element));
}

pub fn remove(&mut self, key: &Key) {
self.0.remove(key);
}

pub fn remove_by_type<T: AnyMapTrait>(&mut self) {
let key = TypeId::of::<T>();
self.0.retain(|_, v| v.type_id() != key);
}

pub fn clear(&mut self) {
self.0.clear();
}
}

impl<Key: Hash + Eq> AnyMap<Key> {
Expand All @@ -74,13 +87,119 @@ impl<Key: Hash + Eq> AnyMap<Key> {
pub fn count_all(&mut self) -> usize {
self.0.len()
}
}

pub fn reset<T: AnyMapTrait>(&mut self) {
let key = TypeId::of::<T>();
self.0.retain(|_, v| v.type_id() != key);
// ----------------------------------------------------------------------------

#[cfg(test)]
#[test]
fn basic_usage() {
#[derive(Debug, Clone, Eq, PartialEq, Default)]
struct State {
a: i32,
}

pub fn reset_all(&mut self) {
self.0.clear();
let mut map: AnyMap<i32> = Default::default();

assert!(map.get::<State>(&0).is_none());
map.insert(0, State { a: 42 });

assert_eq!(*map.get::<State>(&0).unwrap(), State { a: 42 });
assert!(map.get::<State>(&1).is_none());
map.get_mut::<State>(&0).unwrap().a = 43;
assert_eq!(*map.get::<State>(&0).unwrap(), State { a: 43 });

map.remove(&0);
assert!(map.get::<State>(&0).is_none());

assert_eq!(
*map.get_or_insert_with(0, || State { a: 55 }),
State { a: 55 }
);
map.remove(&0);
assert_eq!(
*map.get_mut_or_insert_with(0, || State { a: 56 }),
State { a: 56 }
);
map.remove(&0);
assert_eq!(*map.get_or_default::<State>(0), State { a: 0 });
map.remove(&0);
assert_eq!(*map.get_mut_or_default::<State>(0), State { a: 0 });
}

#[cfg(test)]
#[test]
fn different_type_same_id() {
#[derive(Debug, Clone, Eq, PartialEq, Default)]
struct State {
a: i32,
}

let mut map: AnyMap<i32> = Default::default();

map.insert(0, State { a: 42 });

assert_eq!(*map.get::<State>(&0).unwrap(), State { a: 42 });
assert!(map.get::<i32>(&0).is_none());

map.insert(0, 255i32);

assert_eq!(*map.get::<i32>(&0).unwrap(), 255);
assert!(map.get::<State>(&0).is_none());
}

#[cfg(test)]
#[test]
fn cloning() {
#[derive(Debug, Clone, Eq, PartialEq, Default)]
struct State {
a: i32,
}

let mut map: AnyMap<i32> = Default::default();

map.insert(0, State::default());
map.insert(10, 10i32);
map.insert(11, 11i32);

let cloned_map = map.clone();

map.insert(12, 12i32);
map.insert(1, State { a: 10 });

assert_eq!(*cloned_map.get::<State>(&0).unwrap(), State { a: 0 });
assert!(cloned_map.get::<State>(&1).is_none());
assert_eq!(*cloned_map.get::<i32>(&10).unwrap(), 10i32);
assert_eq!(*cloned_map.get::<i32>(&11).unwrap(), 11i32);
assert!(cloned_map.get::<i32>(&12).is_none());
}

#[cfg(test)]
#[test]
fn counting() {
#[derive(Debug, Clone, Eq, PartialEq, Default)]
struct State {
a: i32,
}

let mut map: AnyMap<i32> = Default::default();

map.insert(0, State::default());
map.insert(1, State { a: 10 });
map.insert(10, 10i32);
map.insert(11, 11i32);
map.insert(12, 12i32);

assert_eq!(map.count::<State>(), 2);
assert_eq!(map.count::<i32>(), 3);

map.remove_by_type::<State>();

assert_eq!(map.count::<State>(), 0);
assert_eq!(map.count::<i32>(), 3);

map.clear();

assert_eq!(map.count::<State>(), 0);
assert_eq!(map.count::<i32>(), 0);
}
6 changes: 3 additions & 3 deletions egui/src/any/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@
//! [`Memory`]: crate::Memory
//! [`Any`]: std::any::Any
mod type_map;
mod element;
mod any_map;
mod element;
mod type_map;

/// Same structs and traits, but also can be de/serialized under `persistence` feature.
pub mod serializable;

pub use self::{type_map::TypeMap, element::AnyMapTrait, any_map::AnyMap};
pub use self::{any_map::AnyMap, element::AnyMapTrait, type_map::TypeMap};
Loading

0 comments on commit aa8c081

Please sign in to comment.