2个版本
0.1.1 | 2024年3月4日 |
---|---|
0.1.0 | 2023年3月14日 |
#378 in 数据结构
在3个crate中使用(通过moongraph)
22KB
395 行
brushdog 🧹🐕
brushdog
是一个Rust库,提供了一种类型擦除值的映射,具有不确定借用权的语义。
什么是类型映射?
brushdog
的类型映射是一个 std::any::TypeId
键到类型擦除值的映射。每个键最多有一个值,这意味着映射存储了不同类型的单例值。
为什么还需要另一个类型映射库?
brushdog
提供了常规的映射API,还有一些其他的功能。值得注意的是,brushdog
提供了“不确定借用权”。
什么是不确定借用权?
这是一个大概意味着你可以不用寿命就可以从映射中借用值的词语混合体。
什么是借用值?
借用值是一个指向值的智能指针,你可以对其进行 deref
或 deref_mut
。
你一次只能有一个特定类型的独占(写入)借用,但你可以有任意多个相同类型的非独占(读取)借用。你也可以同时有 多个不同类型的独占借用。
在独占借用释放后,你可以再次为同一类型的值创建独占借用,或者为该类型创建多个非独占借用。
这允许你在不发生映射借用冲突的情况下同时创建不同类型的多个借用——只要你不尝试在同时共享同一类型的独占借用。
此外,brushdog
具有带有类型名称的漂亮描述性错误(如果使用 debug_assertions
编译,则更好)。
用途
类型擦除映射有很多用途,但 brushdog
是为了方便以下用途而构建的
- 为
apecs
的系统调度运行器提供单例资源存储层(apecs
是一个ECS库) - 为
renderling
的渲染节点调度运行器提供单例资源存储层(是渲染图的一部分)
它与dagga
配合得非常好,后者是一个DAG调度器。实际上,dagga
和broomdog
在moongraph
中被联合使用,并附带一些有用的助手来形成一个DAG调度、资源管理和执行库。
结合起来,可以定义并运行一个可扩展的函数系统,这些函数共享可变资源,其中一些可以并行运行。
你为什么(见鬼)把它命名为broomdog
-
“broomdog”是《爱丽丝梦游仙境》中那个既是扫帚又是狗的角色的名字,它在行走时会擦除路径。
-
我认为名字应该有趣。
-
这是我的库,哦好吧 😏。
示例
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();
依赖关系
~0.5–1MB
~22K SLoC