https://github.com/schell/broomdog
๐งน๐ Rust library providing a map of type-erased values with indefinite loanership semantics
https://github.com/schell/broomdog
Last synced: about 2 months ago
JSON representation
๐งน๐ Rust library providing a map of type-erased values with indefinite loanership semantics
- Host: GitHub
- URL: https://github.com/schell/broomdog
- Owner: schell
- Created: 2023-03-14T22:21:18.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-15T18:17:52.000Z (8 months ago)
- Last Synced: 2025-02-27T11:05:07.505Z (2 months ago)
- Language: Rust
- Size: 17.6 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 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`](https://github.com/schell/apecs)'s system schedule runner (`apecs` is an ECS library)
* singleton resource storage layer for [`renderling`](https://github.com/schell/renderling)'s render node schedule runner (part of the render graph)It works particularly well with [`dagga`](https://github.com/schell/dagga), which is a DAG scheduler. In fact, `dagga` and `broomdog` are joined in [`moongraph`](https://github.com/schell/moongraph) with some nice helpers to form a DAG scheduling, resource management 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
```rust
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::().unwrap().unwrap();
*num_usize += 666;
}
assert_eq!(666, *map.get_value::().unwrap().unwrap());
assert_eq!("hello", *map.get_value::<&str>().unwrap().unwrap());{
let loan = map.loan(TypeKey::new::()).unwrap().unwrap();
assert_eq!(666, *loan.downcast_ref::().unwrap());
let loan2 = map.loan(TypeKey::new::()).unwrap().unwrap();
assert_eq!(666, *loan2.downcast_ref::().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();
```