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

Download history 16/week @ 2024-03-30 1/week @ 2024-05-25

每月下载量285

MIT协议

45KB
947行代码(不包括注释)

screeeps异步

screeeps的tick感知异步运行时

Crates.io CI docs.rs version badge

入门指南

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