1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
//! Module for [`MonotonicMap`].
use super::clear::Clear;
/// A map-like interface which in reality only stores one value at a time.
///
/// The keys must be monotonically increasing (i.e. timestamps). For Hydroflow, this allows state
/// to be stored which resets each tick by using the tick counter as the key. In the generic `Map`
/// case it can be swapped out for a true map to allow processing of multiple ticks of data at
/// once.
#[derive(Clone, Debug)]
pub struct MonotonicMap<K, V>
where
K: PartialOrd,
{
key: Option<K>,
val: V,
}
impl<K, V> Default for MonotonicMap<K, V>
where
K: PartialOrd,
V: Default,
{
fn default() -> Self {
Self {
key: None,
val: Default::default(),
}
}
}
impl<K, V> MonotonicMap<K, V>
where
K: PartialOrd,
{
/// Creates a new `MonotonicMap` initialized with the given value. The
/// vaue will be `Clear`ed before it is accessed.
pub fn new_init(val: V) -> Self {
Self { key: None, val }
}
/// Inserts the value using the function if new `key` is strictly later than the current key.
pub fn get_mut_with(&mut self, key: K, init: impl FnOnce() -> V) -> &mut V {
if self.key.as_ref().map_or(true, |old_key| old_key < &key) {
self.key = Some(key);
self.val = (init)();
}
&mut self.val
}
// /// Returns the value for the monotonically increasing key, or `None` if
// /// the key has already passed.
// pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
// if self
// .key
// .as_ref()
// .map_or(true, |old_key| old_key <= &key)
// {
// self.key = Some(key);
// Some(&mut self.val)
// } else {
// None
// }
// }
}
impl<K, V> MonotonicMap<K, V>
where
K: PartialOrd,
V: Default,
{
/// Gets a mutable reference to the inner value. If `key` is strictly later than the existing
/// key, the value will be reset to `Default::default`.
pub fn get_mut_default(&mut self, key: K) -> &mut V {
self.get_mut_with(key, Default::default)
}
}
impl<K, V> MonotonicMap<K, V>
where
K: PartialOrd,
V: Clear,
{
/// Gets a mutable reference to the inner value. If `key` is strictly later than the existing
/// key, the value will be cleared via the [`Clear`] trait.
pub fn get_mut_clear(&mut self, key: K) -> &mut V {
if self.key.as_ref().map_or(true, |old_key| old_key < &key) {
self.key = Some(key);
self.val.clear();
}
&mut self.val
}
}