LINUX.ORG.RU

Как хандлить ввод по уму

 , , , ,


2

2

Мне не нравится что одни события нужно обрабатывать внутри SDL_PoolEvent() например SDL_MOUSEWHEEL, а другие можно после обновления пула узнать через SDL_MouseState(),SDL_KeyboarState() Но в цикле пула например мышку мы не можем обрабатывать как нажатую постоянно если нет иных эвентов, но можем вне цикла узнавая через State. Как то оно некрасиво, сначала попытался налабать обёрток что бы избавится от цикла эвентов забирая последние события, но тогда происходят скачки если была большая очередь событий, затем я попробовал вообще всё впихнуть в цикл пула, но тогда приходится спавнить треды что бы продолжать обрабатывать мышку если она нажата, но затёр этот ад по итогу.

Вот типичная ситуация из Corange

Свободная камера должна быть вне эвент цикла иначе не реализовать плавное движение https://github.com/orangeduck/Corange/blob/master/src/entities/camera.c#L77 Орбитальная же камера должна находится в евент цикле для корректной работы https://github.com/orangeduck/Corange/blob/master/src/entities/camera.c#L44

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

Deleted

не хочется обрабатывать одно событие в одном месте и его же, но по другому в другом

Схренали? У тебя так и так должен быть объект (структура) хранящий актуальное состояние нажатых и отжатых клавиш, колёс и кликов. Вот с него и надо брать инфу при обновлении мира.

происходят скачки если была большая очередь событий

А не надо никакой очереди накапливать. Если в данный момент времени при обновлении мира прыжок нажат, значит мы прыгаем (учесть макс высоту прыжка), если отжат, значит вниз летим. Или, если это «турбо» кнопка, то стрелять пока её не отожмут, иначе стрельнуть один раз, даже если в следующую итерацию обновления мира она всё еще нажата.

плавное движение

Позиции объектов мира запрашиваются в момент отрисовки. И какие они там — не важно, ведь они уже посчитаны. Т.е.:

0) Обновляем объект состояния ввода.

1) Обновляем мир, с учетом состояния ввода, смещаем/модифицируем/удаляем/создаём объекты (их св-ва).

2) Отрисовываем состояние мира.

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

Хмммм, надо подумать,голова уже не варит, наверное я логически неверно подошёл к вопросу, а кода нагородил за день уже тонну... Щас спать лягу, а завтра либо соглашусь с тобой продумав всё ещё раз, либо буду возникать ибо я уже наспотыкался так что психанув карандашик сломал... бедный карандашик... )).

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Для каждой итерации обновления мира нужно запоминать сколько времени длилось это (предыдущее) обновление. Если у тебя там движущийся объект, то, расстояние, которое он должен пройти, рассчитывается с этим (предыдущим) временем. А отображение состояния (то, что видит пользак) вызывается только когда мир перестроен. Это и есть «просадка фпс» когда мир большой, объектов много, а показываем только после того, как обновили. Вот, сколько раз в секунду ты успел обновить и показать мир, такой фпс твой код и выдаёт.

Ещё можно для мощного железа и маленького мира делать ограничение на максимальный фпс и тем самым вставлять usleep() в цикл обновления и отображения, если комп считает слишком быстро.

Иди спи короче ))

deep-purple ★★★★★ ()
Последнее исправление: deep-purple (всего исправлений: 1)

эстетически не хочется обрабатывать одно событие в одном месте и его же, но по другому в другом, как пример это нажатие мышки в режимах эвент нажатия и станус нажатия

Пересматривай свою эстетику, это абсолютно нормально. Состояние доступно для прямого инспектирования, плюс его изменение дополнительно доступно в виде событий.

тогда происходят скачки если была большая очередь событий

Как ты этого добиваешься? 1 FPS с обработкой ввода каждый 60-й кадр?

slovazap ★★★★★ ()

Короче без учёта порядка очереди эвентов мне никак, городить огород лишний не к чему по итогу нужно хандлить по обычному события внутри цикла обрабатывая в порядке появления,состояния самые актуальные полученные напрямую, а не через цикл эвентов для обработки в любой части дерева кода и и сохранённые события которые существуют и сохраняются только внутри одного фрейма,то есть событие нажатия клавиши или движения мышки пожно получить вне цикла эвентов, но только если это событие произошло в отрезке времени фрейма и того у любого события 3 состояния, 1событие действия/2состояние вне зависимости от события/3событие области видимости фрейма. 2 и 3 актуальны всегда для любой части кода. Это я так мысли в слух. Конечно для тех кому не важна очередь событий могут сделать всё чище и красивее. GG HF

UDP: Ах да в реализации SDL_PoolEvent который на самом деле SDL_PoolEventWait стоит SDL_Delay(10), а я весь исплевался пока понимал откуда эти милисекунды берутся.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)