4个版本
0.1.3 | 2024年3月23日 |
---|---|
0.1.2 | 2024年3月6日 |
0.1.1 | 2024年3月3日 |
0.1.0 | 2024年3月3日 |
#1874 in 过程宏
每月下载量271次
用于 screeps-async
7KB
59 行
Screeps Async
Screeps的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!");
});
}
每个tick宏
在同步的Screeps代码中,一种常见的模式是使用状态机并根据状态决定要使用哪种逻辑。在异步编程中,您可以摆脱tick的束缚,自由地编写一个跨越tick执行的单个函数。这允许您将状态机“展开”为单个函数,从上到下执行。在这种情况下,您可能仍然需要编写在每次tick循环中移动的代码(即重复调用move_to
)。
然而,由于RoomObjects可能会被销毁/消失在视野之外,所以不能在tick之间存储对它们的引用。解决这个问题的方法是存储
ObjectId,并在每个tick中调用
.resolve()
来解析它们。
可以使用 each_tick!
宏来帮助减少循环和每次迭代调用 .resolve()
的冗余代码。 each_tick!
接受一系列依赖项(通常是 ObjectId
),并在每次迭代中调用这些依赖项上的 .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!");
}
依赖项
~260–700KB
~17K SLoC