如何正确引用相同的代码作为依赖项的依赖项?

时间:2019-02-18 19:52:09

标签: rust rust-cargo

我有一个使用Amethyst game engine的玩具项目。我正在尝试编写自己的System来收集用户输入,类似于他们已经实现hereFlyMovementSystemArcBallRotationSystem

收集鼠标移动的正确方法似乎是通过EventChannel<Event>,其中Event来自winit板条箱,紫水晶依赖该板条箱,但不会重新导出

引用与紫水晶相同的winit::Event的“正确”方法是什么?

  • 我应该将winit添加到我的Cargo.toml文件中吗?如果是这样,建议的指定版本的方法是什么? (是否可以使用某些关键字代替特定的版本号,以使我“继承” Amethyst的依赖项?)
  • 实际上不鼓励引用子依赖项吗?如果是这样,我应该怎么做?

2 个答案:

答案 0 :(得分:4)

当前没有很好的解决方案。最好的解决方法是在传递依赖的相同版本上添加直接依赖:

[dependencies]
foo = "0.1" 
bar = "0.2" # `foo` depends on bar 0.2 and we need to keep these in sync

您可以使用cargo tree之类的工具来手动识别foo所需的版本,并使Cargo.toml保持最新。我强烈建议添加一条注释,指明为什么选择特定版本。

如果在不同时使用基础依赖项的情况下很难使用该条板箱,我还建议您向父条板箱提出问题,以要求它们重新导出所需的文件。一个很好的例子是re-exports large chunks of the futures crate的Tokio板条箱。


类似于您的想法,I proposed可以使用相同版本的依赖项。相反,货运团队选择添加public and private dependencies的区别。从工程的角度来看,虽然这将是一个更好的解决方案,但在实现方面进展甚微。

另请参阅:

答案 1 :(得分:1)

我离开了@Shepmaster的答案,因为它回答了我要解决的一般问题。但是由于@trentcl的大力推动,以防万一有人发现这个问题专门针对与紫水晶的关系,这就是我最后要做的事情。

完全不要获取winit::Events

当您将InputBundle<AX, AC>附加到GameData时,它会设置一个InputSystem<AX, AC>,并以winit::Events的形式重新发布InputEvent<AC>

它通过将EventChannel<InputEvent<AC>>设置为资源来执行此操作,您可以通过ECS系统中的Read类型进行访问。 in the Amethyst Book说明了EventChannel及其用法。

此后,我已经切换到其他方法来处理用户输入,但是大致如下所示(请注意:Amethyst a little after v0.10.0):

pub struct MouseMovementSystem {
    reader: Option<ReaderId<InputEvent<()>>>, // AC = () 
}

impl<'s> System<'s> for MouseMovementSystem {
    type SystemData = (
        Read<'s, EventChannel<InputEvent<()>>>,
        /* and others */
    }

    fn run(&mut self, (events, /* and others */): Self::SystemData) {
        let foo = events.read(self.reader.as_mut().unwrap())
            .yadda_yadda(/* ... */); // event processing logic
        do_stuff(foo);
    }

    fn setup(&mut self, res: &mut Resources) {
        use amethyst::core::specs::prelude::SystemData;
        Self::SystemData::setup(res);
        self.reader = Some(res.fetch_mut::<EventChannel<InputEvent<()>>>().register_reader());
    }
}