4个版本 (2个重大更新)
0.3.0 | 2024年3月23日 |
---|---|
0.2.0 | 2024年3月6日 |
0.1.1 | 2024年3月3日 |
0.1.0 | 2024年3月3日 |
在异步类别中排名644
每月下载量285次
45KB
947行代码(不包括注释)
screeeps异步
screeeps的tick感知异步运行时
入门指南
将 screeps-async
添加到您的 Cargo.toml
[dependencies]
screeps-async = "0.3.0"
重要:该项目处于早期阶段,alpha版本之间可能会进行重大、破坏性的更改。
将 #[screeps_async::main]
添加到主循环函数中,并开始孵化异步代码!
#[screeps_async::main] // must be before other attributes to work properly
#[wasm_bindgen(js_name = loop)]
pub fn game_loop() {
// Tick logic that spawns some tasks
screeps_async::spawn(async {
println!("Hello!");
});
}
each_tick!
宏
在同步的Screeps代码中,一个常见的模式是使用状态机并根据状态决定使用哪种逻辑。在使用异步编程时,你可以摆脱tick的束缚,可以编写一个跨越多个tick执行的单个函数。这允许你将状态机“展开”成一个从上到下执行的单一函数。在这种情况下,你可能仍然需要编写在每个tick循环直到下一步的代码(即重复调用move_to
)。
但是,在tick之间存储对RoomObjects的引用是不安全的,因为它们可能会被销毁/超出视野。解决这个问题的方法是存储
ObjectId
而不是它们,并在每个tick使用.resolve()
来解析它们。
可以使用each_tick!
宏来帮助减少每个tick循环和解析的样板代码。each_tick!
接受一个依赖项列表(通常是ObjectId
),并在每个tick对它们调用.resolve()
,使解析的值在提供的代码块中以与依赖项相同的名称可用(请参阅示例以获取详细信息)
async fn collect_and_upgrade(creep: ObjectId<Creep>, source: ObjectId<Source>, controller: ObjectId<StructureController>) {
// Collect until full
each_tick!(creep, source, {
if creep.store().get_free_capacity(Some(ResourceType::Energy)) == 0 {
return Some(());
}
if let Err(_) = creep.harvest(&source) {
let _ = creep.move_to(&source);
}
// Do this forever
None
}).await.expect("Creep or source is gone!");
each_tick!(creep, controller, {
if creep.store().get_used_capacity(Some(ResourceType::Energy)) == 0 {
return Some(());
}
if let Err(_) = creep.upgrade_controller(&controller) {
let _ = creep.move_to(&controller);
}
// Do this forever
None
}).await.expect("Creep or controller is gone!");
}
依赖项
约2.5–3.5MB
约67K SLoC