2 releases
0.1.1 | Mar 4, 2024 |
---|---|
0.1.0 | Mar 14, 2023 |
#553 in Data structures
Used in 3 crates
(via moongraph)
22KB
395 lines
broomdog ๐งน๐
broomdog
is a Rust library providing a map of type-erased values with indefinite loanership semantics.
what is a type map?
broomdog
's type map is a map of std::any::TypeId
keys to type-erased values.
There may be at most one value for each key, which means the map stores singleton values of different types.
why another type map library?
broomdog
provides the usual map-like API, and then some.
Notably broomdog
provides "indefinite loanership".
wtf is indefinite loanership?
It's a wordsmush that roughly means you can borrow a value from the map without a lifetime.
wtf is a loaned value?
A loaned value is a smart pointer to a value that you can deref
or deref_mut
.
You may only have one exclusive (write) loan of any one type at a time, but you may have as many non-exclusive (read) loans of the same type as you like. You may also have multiple exclusive loans of different types at the same time.
After an exclusive loan is dropped you may make another exclusive loan of the same type, or multiple non-exclusive loans of that type.
This allows you to make multiple loans of different types at the same time, without map borrow conflicts - so long as you don't try to share an exclusive loan of the same type at the same time.
Furthermore, broomdog
has nice descriptive errors with the names of the types (more even, if compiled with debug_assertions
).
uses
Type erased maps have many uses, but broomdog
was built to facilitate the following:
- singleton resource storage layer for
apecs
's system schedule runner (apecs
is an ECS library) - singleton resource storage layer for
renderling
's render node schedule runner (part of the render graph)
It works particularly well with dagga
, which is a DAG scheduler. In fact, dagga
and broomdog
are joined in moongraph
with some nice helpers to form a DAG scheduling, resource managment and execution library.
Together it's possible to define and run an extensible system of functions that share mutable resources, some of which may run in parallel.
why (the heck) did you name it broomdog
-
"broomdog" is the name of the part broom / part dog character in Alice in Wonderland that erases the path as it walks along it.
-
I think names should be funny.
-
It's my library, oh well ๐.
example
use broomdog::{TypeMap, TypeKey};
let mut map = TypeMap::default();
assert!(map.insert_value(0usize).unwrap().is_none());
assert!(map.insert_value(0.0f32).unwrap().is_none());
assert!(map.insert_value("hello").unwrap().is_none());
{
let num_usize = map.get_value_mut::<usize>().unwrap().unwrap();
*num_usize += 666;
}
assert_eq!(666, *map.get_value::<usize>().unwrap().unwrap());
assert_eq!("hello", *map.get_value::<&str>().unwrap().unwrap());
{
let loan = map.loan(TypeKey::new::<usize>()).unwrap().unwrap();
assert_eq!(666, *loan.downcast_ref::<usize>().unwrap());
let loan2 = map.loan(TypeKey::new::<usize>()).unwrap().unwrap();
assert_eq!(666, *loan2.downcast_ref::<usize>().unwrap());
let mut loan_mut = map.loan_mut(TypeKey::new::<&str>()).unwrap().unwrap();
let word = loan_mut.downcast_mut::<&str>().unwrap();
assert_eq!("hello", *word);
*word = "goodbye";
}
map.unify().unwrap();
Dependencies
~0.4โ1MB
~21K SLoC