Цепочка событий на основе времени (множественность нажатий кнопок)JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Цепочка событий на основе времени (множественность нажатий кнопок)

Сообщение Anonymous »

У меня есть программа, которая создает поток событий кнопок/осей геймпада.
Я хочу иметь возможность распознавать кратность щелчков.
На последнем этапе есть Конвейер Flux:

Код: Выделить всё

        final Flux buttonStream = stateStream.getButtonFlux()
.mapNotNull(GamepadIntrospector::introspect)
.filter(Predicate.not(List::isEmpty))
.map(EventMapper::translateButtonTimed)
.filter(notFizzy)
;
в котором EventMapper::translateButtonTimed — это компонент с состоянием, который может определить, повторялось ли нажатие кнопки в течение заранее настроенного периода времени и, следовательно, продолжалось и увеличивалось ли количество повторений. Следовательно, когда я быстро нажму кнопку 3 раза, я получу:

Код: Выделить всё

01:08:09.696 [pool-1-thread-1] INFO org.asmus.Main -- QualifiedEType(type=A, pressType=CLICK)
01:08:09.873 [pool-1-thread-1] INFO org.asmus.Main -- QualifiedEType(type=A, pressType=DOUBLE)
01:08:10.016 [pool-1-thread-1] INFO org.asmus.Main -- QualifiedEType(type=A, pressType=TRIPLE)
Это означает, что тройной щелчок был правильно распознан для кнопки «A».
Что мне нужно, чтобы этот конвейер решил, так это иметь только последнее событие на выходе.
Мне не нужна выборка временных интервалов, которая начиналась бы при запуске программы, чтобы выполнить выборку и получить последнюю за этот промежуток времени; Думаю, это можно сделать так:

Код: Выделить всё

        final Flux buttonStream = stateStream.getButtonFlux()
.mapNotNull(GamepadIntrospector::introspect)
.filter(Predicate.not(List::isEmpty))
.map(EventMapper::translateButtonTimed)
.filter(notFizzy)
.bufferTimeout(3, Duration.ofMillis(300))
.map(e -> e.size() == 1 ?
e.getFirst() : e.getLast())
;
это работает, но случается, что я вижу «двойное» после «тройного», а также я не хочу, чтобы каждое событие на выходе было выбрано с интервалом 300 мс. Ощущение медленной реакции.
Я бы хотел, чтобы этот конвейер ждал некоторое время, скажем, 80 мс, после получения первого события, и если больше ничего не происходит, он генерирует событие (оно кратность уже будет установлена ​​вышеупомянутым компонентом картографа); если в течение этого временного диапазона поступает дополнительный, он излучает последний из этой цепочки и так далее.
Поэтому после трехкратного нажатия кнопки «A» я хочу получить только

Код: Выделить всё

01:08:10.016 [pool-1-thread-1] INFO org.asmus.Main -- QualifiedEType(type=A, pressType=TRIPLE)
но без буферизации всех 300 мс. Первые два щелчка могут происходить через 20 мс + 20 мс, а последние — в течение этих 80 мс, так что после последнего нажатия физической кнопки ей придется ждать только 80 мс, прежде чем выдать это событие.
Кроме того, эта цепочка должна учитывать тип кнопки, поэтому время QualifiedEType(type=A, pressType=...) не может мешать QualifiedEType(type=X, pressType=...)
Как это можно сделать? В идеале была бы какая-нибудь умная цепочка операторов Flux, но подойдет все что угодно...
io.projectreactor:reactor-core:3.6.5
Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/793 ... ltiplicity
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»