Russian Qt Forum
Ноябрь 23, 2024, 21:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Интерактивное (почти) управление  (Прочитано 13831 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Апрель 14, 2016, 07:51 »

Добрый день

Есть 3 параметра (QLineEdit'ы со спиннерами): скорость (или газ), поворот и сдвиг. Есть фиксированное число кадров, на каждом параметры могут иметь разные значения. Параметры рулят объектами, напр больше скорость - объект движется быстрее. По существу все как в игре, поэтому логично запустить анимацию (т.е. показывать кадр за кадром) и сделать упр-е клавишами (напр стрелками).

Но есть одно обстоятельство: в отличие от игры время смены кадра может быть любым в зависимости от сложности сцены. Где-то и вытянет 30fps, а где-то только 5 а то и меньше. Это нормально, там тонны расчетов (а не только рисование).

Как сделать упр-е от клавиш удобным, чтобы не было эффектов "залипания" (как у крутой игры на дохлой машине)? 

Спасибо
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Апрель 15, 2016, 17:45 »

В играх в основном берется фиксированный fps и уже исходя из реального времени расчета кадров некоторые кадры могут скипаться.
Да, картика станет дерганой, но общий fps не пострадает.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Апрель 16, 2016, 09:25 »

В играх в основном берется фиксированный fps и уже исходя из реального времени расчета кадров некоторые кадры могут скипаться.
Да, картика станет дерганой, но общий fps не пострадает.
Обычно (и не только в играх) это называется "drop frames". Здесь никаких пропусков нет, проблема такая

- юзер нажал на клавишу (напр хочет увеличить скорость движения) - но ничего не происходит, значение QLineEdit не меняется, обновление геометрии может быть слишком долгим. Юзер еще давит - опять ничего. Наконец "просралось", дело дошло до событий, и выяснилось что надавил значение куда больше чем думал.

А хотелось бы так: QLineEdit обновляется при нажатии на клавишу и/или спыннер, юзер видит что установил. Он понимает что новое значение скорости будет задействовано на след кадрах, это нормально.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Апрель 17, 2016, 02:49 »

Хм... а почему обработка событий зависит от вычисления геометрии?
Есть поток, который занят гуем и событиями, но геометрия то в другом (надеюсь) считается?
Откуда указанный эффект возникает?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Апрель 17, 2016, 09:08 »

Хм... а почему обработка событий зависит от вычисления геометрии?
Есть поток, который занят гуем и событиями, но геометрия то в другом (надеюсь) считается?
Не надейтесь, сейчас все в главной нитке. Кода настолько много что хз кто может тормозить - могут все. Напр рисование многочисленных окон (в том числе и с OpenGL) запросто может оказаться узким местом, но это должно быть в главной нитке. По поводу др операций..

Пример: рисование требует текстур (картинок), причем их набор может быть всяким-разным в зависимости от многих установок. Др словами нужно подгружать/выгружать картинки с диска. Сейчас это делается перед началом каждого рисования. Да, формально эта трудоемкая операция загрузки UI-независима и "может быть вынесена в др поток". Ну а зачем? Ведь "иметь свободное UI" я все равно не могу. Как только выйду в событийный цикл - нарвусь на событие требующее др рисования, и что тогда делать с текущим?

Стандартная реакция типа
Цитировать
Фу, как неграмотно грузить картинки в paintEvent! Кривой дизайн! Нужно все картинки заранее загрузить и.т.п.
Ну конечно не в paintEvent, c OpenGL можно рисовать когда угодно. А главное - расклад картинок  может измениться в 100 местах, отследить все - проще застрелиться. Поэтому логично грузить их когда они действительно нужны, на фазе подготовки рисования.
 
Вообще рекомендация "вынести в др поток" слишком популярна и дается к месту и не к месту  Улыбающийся
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Апрель 17, 2016, 12:20 »

Ну, в данном случае классическая рекомендация, как я вижу, будет к месту.  Выносить и еще раз выносить.
У нас тоже был 3д плоттер, который рендерился в основном потоке. Тормозил безбожно.
Пришлось порезать на потоки, после чего проблема тормозов ушла раз и навсегда.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 17, 2016, 12:31 »

Ну, в данном случае классическая рекомендация, как я вижу, будет к месту.  Выносить и еще раз выносить.
Ну почему Вы всегда говорите банальность - и только банальность? Улыбающийся В предыдущем посте я описал проблемы "выноса", прочитайте, потом (может) "я вижу".
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Апрель 18, 2016, 10:45 »

Если "тормозит хз что, я не знаю что, но тормозит же", то профайлер в помощь.
Определите, что тормозит, и дальше по ситуации.
Или там настолько все плохо, что уже не поддается распознаванию?
Картинки, как минимум, тоже можно раскидать по потокам, или частично закэшировать.
Банально? Да. Но ведь и задача пока тоже выглядит банальной.
Есть еще что то, о чем мы " пока не знаем"?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #8 : Апрель 18, 2016, 14:26 »

"Наконец "просралось", дело дошло до событий, и выяснилось что надавил значение куда больше чем думал."
Ну собственно тут и ответ.
до тех пор пока не просралось, виджеты управления блокируем и показываем некий индикатор занятости.
Записан

Юра.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Апрель 18, 2016, 15:36 »

Или там настолько все плохо, что уже не поддается распознаванию?
Почему "плохо"? Как только объем приложения превышает некоторый предел - никто (включая автора) уже не представляет все подробности. Я всего лишь один из авторов, навскидку вспомню пяток-десяток операций - уже хорошо. Это нормально, человеческие возможности ограничены.

Определите, что тормозит, и дальше по ситуации.
А Вы уверены что это правильный подход? Для той или иной сцены(данных) узкие места могут быть совершенно разными. Ну хорошо, допустим нашли какое-то, но "вынос в поток" не имеет смысла. Почему - давайте еще разжую

"Вынос тела" имеет смысл если UI переживет его временное отсутствие. Напр галерея иконок может грузиться довольно долго, тогда написать пока "Loading", и диалог все же открыть. Но такая возможность есть далеко не всегда, напр объекты в окнах должны рисоваться с текстурами, на них надписи не сделать. И. как уже говорилось, UI не должно конфликтовать с фоновой загрузкой.

Ну и что неясно, и зачем упорно лепить одну-единственную рекомендацию из букваря? Улыбающийся

Ну собственно тут и ответ.
до тех пор пока не просралось, виджеты управления блокируем и показываем некий индикатор занятости.
Так этот индикатор и будет все время "занят" т.к. время схватывания событий ничтожно по сравнению с выполнением рабочих операций

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Апрель 18, 2016, 17:10 »

Запустить нитку - наблюдателя которая по таймеру подсматривает события клавы. Когда нужное событие обнаружено - отрисовать QLineEdit (с измененным значением) в QPixMap и шлепнуть его на экран. С добрым старым КвыкДроу это было совершенно реально, можно даже было лочить пыксели на время копирования. Сейчас нет конечно, да и с "подсматриванием" в Qt большие проблемы  Плачущий

Не, конечно легко повторять "UI только в главной нитке" - ну а если вот НАДО? И вообще - что собсно имеется ввиду? Qt вызовы "not thread-safe" или ОС? Если только первое - обойти можно.
Записан
Bepec
Гость
« Ответ #11 : Апрель 18, 2016, 19:43 »

По сути опять у Igors коллапс идей в мини черную дырку.
1) изменение spinbox/lineEdit с отложенным выполнением. (подробнее в п.3)
2) ускорение расчётов/отрисовки - не имеет решения, ибо "ну и пусть тормозит внутри, я хочу ускорить ничего не меняя" © Igors.
3) разделение органов управления и расчёта. Решается добавлением промежуточной переменной - той, которая рассчитывается "сейчас". Как только расчёт завершён для "сейчас", происходит сравнение с спинбоксом, если есть изменение - начало нового расчёта с изменением переменной "сейчас". Обе переменные видны пользователю, устанавливаемая пользователем в виде edit, текущая в виде label.

А все вместе эти проблемы нерешаемы.
« Последнее редактирование: Апрель 18, 2016, 21:56 от Bepec » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #12 : Апрель 18, 2016, 22:34 »

"Наконец "просралось", дело дошло до событий, и выяснилось что надавил значение куда больше чем думал."
Ну собственно тут и ответ.
до тех пор пока не просралось, виджеты управления блокируем и показываем некий индикатор занятости.

Ну в общем почти. Только блокировать надо лишь при изменении значения. А при следующей отрисовке разблокировать.
Тогда по идее нельзя будет много раз поменять значение в пределах одного кадра.
Но все это полумеры и основной проблемы не решают. ..
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Апрель 19, 2016, 00:03 »

Но все это полумеры и основной проблемы не решает..
А какую собственно вы хотите решить проблему? Отзывчивость GUI? Улыбающийся
Ну так она решается предложенным вами методом. По другому гуй нормально разгрузить не получиться.
Как-то вы сами за сомневались в решении, которое сами же решили использовать. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Апрель 19, 2016, 10:01 »

Напомню задачу (как я ее вижу)
А хотелось бы так: QLineEdit обновляется при нажатии на клавишу и/или спыннер, юзер видит что установил. Он понимает что новое значение скорости будет задействовано на след кадрах, это нормально.
Т.е. нужно обеспечить feedback, простую реакцию на действия пользователя. Как уже неоднократно упоминалось, это совсем не значит что "UI свободно" (т.е. принимает события в штатном режиме), напротив, обработка других событий не должна начинаться до окончания расчетов и рисования.

Тогда по идее нельзя будет много раз поменять значение в пределах одного кадра.
Непонимающий Наоборот, пусть меняет много раз если успевает - это желательно
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.108 секунд. Запросов: 23.