Как правильно ссылаться на тот же код как зависимость зависимости? - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть игрушечный проект, использующий игровой движок Amethyst .Я пытаюсь написать свой собственный System для сбора пользовательского ввода, аналогично FlyMovementSystem и ArcBallRotationSystem, которые они реализовали здесь .

Кажется, правильный путьсобирать движения мыши можно с помощью EventChannel<Event>, где Event происходит из ящика winit, от которого зависит Аметист, но не реэкспортирует.

Что такое "правильный" способсослаться на тот же winit::Event, что и Amethyst?

  • Должен ли я добавить winit в мой Cargo.toml файл?Если да, то каков рекомендуемый способ указать версию?(Есть ли какое-либо ключевое слово, которое я могу использовать вместо определенного номера версии, чтобы позволить мне «наследовать» зависимость от Amethyst?)
  • Действительно ли не рекомендуется ссылаться на суб-зависимости?Если так, что я должен делать вместо этого?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Я оставляю ответ @ Shepmaster как принятый, так как он отвечает на общий вопрос, на который я рассчитывал.Но благодаря мягкому толчку от @trentcl, в случае, если кто-то нашел этот вопрос специально для его отношения к Аметисту, вот что я в итоге сделал.

Не пытайтесь получить winit::Events вall.

Когда вы присоединяете InputBundle<AX, AC> к своим GameData, он устанавливает InputSystem<AX, AC>, который повторно публикует winit::Events в форме InputEvent<AC>.

Это достигается путем установки EventChannel<InputEvent<AC>> в качестве ресурса, к которому вы можете получить доступ через тип Read в системе ECS.Каналы событий и их использование объясняются в Книге Аметистов .

С тех пор я переключился на другой подход для обработки моего пользовательского ввода, но вот примерно так это выглядело (примечание: Amethyst чуть позже 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());
    }
}
0 голосов
/ 18 февраля 2019

На данный момент нет отличного решения этой проблемы.Лучший обходной путь - добавить прямую зависимость к той же версии транзитивной зависимости:

[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 в актуальном состоянии.Я настоятельно рекомендую добавить комментарий, указывающий, почему вы выбрали конкретную версию.

Если ящик очень сложно использовать без использования базовой зависимости, я также рекомендую вам подать проблему сродительский ящик, чтобы просить, чтобы они реэкспортировали то, что нужно.Хорошим примером этого является ящик Tokio, который реэкспортирует большие куски ящика с фьючерсами .


По аналогии с вашей идеей, Я предложил иметь способ использовать ту же версию в качестве зависимости.Вместо этого команда Cargo решила добавить различие между публичными и частными зависимостями .Хотя это будет лучшим решением с инженерной точки зрения, очень мало было сделано для его реализации.

См. Также:

...