我有一个使用Amethyst game engine的玩具项目。我正在尝试编写自己的System
来收集用户输入,类似于他们已经实现here的FlyMovementSystem
和ArcBallRotationSystem
。
收集鼠标移动的正确方法似乎是通过EventChannel<Event>
,其中Event
来自winit
板条箱,紫水晶依赖该板条箱,但不会重新导出
引用与紫水晶相同的winit::Event
的“正确”方法是什么?
winit
添加到我的Cargo.toml
文件中吗?如果是这样,建议的指定版本的方法是什么? (是否可以使用某些关键字代替特定的版本号,以使我“继承” Amethyst的依赖项?)答案 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());
}
}