![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
помогите написать очень быстрый секундомер. чтоб у например секунды бежали в 10 или 100 раз быстрее реальных секунд и соотвественно менялись, минуты, часы, дни. Сейчас сделал так
интервал таймера выставлен на 1мс. но мне такой скорости мало )) |
|||
|
||||
| drkot |
|
||||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
Во первых: никто не мешает приращивать время больше чем на одну секунду
Во вторых:
и как ни странно необходимость в эпическом наборе условий пропадает В третьих: есть OnPaint в нем и надо рисовать Добавлено через 7 минут и 34 секунды Как по мне так идеально (без излишнего погружения в глубины) реализовать так:
интервал таймера не стоит делать менее 50. а так 100мс в самый раз. -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
||||
|
|||||
| Delvish |
|
|||
![]() oO ![]() Профиль Группа: Участник Сообщений: 136 Регистрация: 13.12.2006 Репутация: 1 Всего: 4 |
Вероятно, правильнее будет использовать поток, в котором гонять цикл. Примитивный код:
|
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
не лезть в потоки если не имеете элементарных навыков работы с ними. А сколько кадров воспринимает глаз человека? А сколько кадров выдает монитор? Откуда, Pi, такая любовь к малым числам? -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
О_о откуда такие цифры? В принципе правильно сказали, если делается анимация, то не следует ее запускать чаще чем способен увидеть глаз. Т.е. 25 кадров в секунду, что ровняется 40мс. Дискретность системного таймера обычно ~ 15.6мс, поэтому при помощи него можно реально выдавать обновления с периодом ~31 мс т.е. 32 кадра в секунду (заводим например на 30мс). Если завести таймер на 40мс, то реально получим ~47 мс интервал, т.е. 21 кадр в сек. Тоже не плохо, хотя глаз может видеть изменения чаще. Ну и как правильно сказали, что можно за 1 кадр менять величину секунд не на единицу, а на 2, на 3 или даже на число с плавающей точкой (округлять при выводе на экран). -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Delvish |
|
|||
![]() oO ![]() Профиль Группа: Участник Сообщений: 136 Регистрация: 13.12.2006 Репутация: 1 Всего: 4 |
Сударь, а более конкретно и по делу? Задача не машину времени написать же. Насколько я понял из первого поста, человек хочет секундомер. То бишь чтобы от отметки "ноль" циферки начали бежать вперед, быстро-быстро увеличиваясь. Поток не даст форме висеть, процессор не будет 25% ресурсов отдавать на таймер с задержкой 50 мс. Да и к тому же, sleep(10) не говорит о том, что цикл будет повторяться ровно каждые 10 мс - не забываем об отрисовке на канве формы label'а. Собственно, цифру я написал совершенно случайную, не нужно придираться Т.о., я предложил не такой уж и плохой вариант, довольно близко стоящий к запросу топикстартера. Да и слово "вероятно", что я употребил, говорит о том, что я не считаю свои слова истиной в последней инстанции, не стОит так нападать |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
мягко говоря с потолка. сакрального смысла в них нет. любой интервал таймера приведет к мерцанию, так как он в априори асинхронен с WM_PAINT . Для локальной анимации вполне достаточно 5-10 кадров, отсюда интервал задержки 100мс. Учитывая, что таймер инициирует перерисовку (в оригинальном коде целых четыре раза) то малые значения интервала приведут жуткому мерцанию. По факту изображение будет пропадать примерно в каждом втором кадре, а наличие 4-х объектов создаст эффект старых люминесцентных ламп -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Если мы что-то делаем, то на то должны быть объективные причины. В чем необходимость создания потока? Разве задача требует тактирование интервалов менее 15мс? Глаз не различает интервалы менее 40мс, так какой будет толк от того что мы меняем счетчик 100500 раз в секунду? Я бы мог понять если б от этого таймера работала передача данных по сети или осуществлялось управление внешним устройством. А так задача сводиться к тому, чтобы осуществлять вывод на экран. Я бы вообще и тактировал счетчик именно отрисовкой очередного кадра. Засекал бы сколько прошло времени с предыдущего кадра умножал бы эту цифру на коэффициент ускорения времени и прибавлял к текущему времени, вот вам и ускоренное время безо всякого перерасхода ресурсов. Добавлено @ 17:51
Неа. К мерцанию иногда приводит очистка фона, но она легко отключается если перехватывать WM_ERASEBKG . И кто сказал, чтобы обязаны рисовать в самом таймере? Мы в таймере просто вызываем функцию InvalidateRect для нижележащего окна. Она говорит винде, а ну-ка давай-ка перерисуйся. Винда говорит Yes sir! досрочно генерит сообщение WM_PAINT . По факту мы получаем WM_PAINT с частотой таймера. Вот в нем и рисуем. WM_PAINT априори синхронен со всем с чем должна быть синхронна отрисовка, поэтому все что мы нарисуем не будет мигать. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
Во первых, это моя песенка, так что попрошу без плагиата. 1. наверно Вас мама не учила, что надо прорисовку синхронизировать с основным потоком? 2. глобальная переменная в потоке? 3. ну и на последок inherited; смысл в вызове метода предка? конечно ничего критичного, но все же... итого: идеальный пример "как провалить собеседование". Так, что мне не понятен повод Вашего сарказма... человек хочет чтоб циферки быстрее бежали, а уж подсунуть то можно любые... надеюсь что тут общаются люди как минимум с уверенной тройкой по математике за 6-й класс, думаю этого вполне достаточно, чтобы получить озвученный эффект.
таки, какой процессор? таки, получается в системе может работать только 4-ре таймера? ни каких нападений. просто зачем лезть (давать совет лезть) в неведомые дебри... лучше решать задачу теми средствами которые знаешь, меньше шансов наломать дров... имхо -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
Вы абсолютно правы. Могу ошибаться..., но когда TWinControl посылает CM_INVALIDATE, то он не проверяет пришел ли ответный WM_PAINT... таким образом приходят целые пакеты WM_PAINT, что приводит к многократному вызову (возможно асинхронному) перерисовки. А учитывая что при начале прорисовке ставится блокировка, а в конце она снимается. Будут моменты времени когда прорисовка еще ведется, а блокировка уже снята. Изображение выводится на монитор только с той части на которых нет блокировок. Вот и получается, что может быть выведена только часть (в данном случае фон). Конечно сумбурно получилось, но без листа бумаги объяснить тяжело... Собственно для избежания этого и вызывают Synchronize() Это сообщение отредактировал(а) drkot - 5.8.2014, 18:21 -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Мне конечно льстит что тут развилась такая дискуссия на тему таймеров и секундомеров но задача более тривиальная. Мне нужно прогонять время с 0 до наступления события x. Должно это происходить на подобие, как это происходит, в игре симс. Нажата кнопка плей время идет в обычном режиме, нажали ускорение, время бежит еще быстрее, нажали еще ускорение, время бежит очень и очень быстро. Визуально время нужно отображать только в лейблах, без всяких от рисовок циферблатов и т.д. Как я написал в 1 посте, я поставил параметр interval компонента timer на 1, все работает так как нужно, за исключением того что мне нужно чтоб время секундомера бежало быстрее чем 1мс.
|
|||
|
||||
| MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
||||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
Собственно потом будут ругать дядю Билла что система жутко тормозит и глючит... MrDmitry, Вы хоть на загрузку процессора посмотрите... У вас же все ресурсы направлены на рисование какой то мелкой метки, Вы действительно считаете что это правильно? PS: да... сложно на рунете жить стало... -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Может я не туда смотрю? Нажал старт, открыл диспетчер задача, загрузка процессора не изменилась. напротив моей программы цп 0 |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
Да, как ни странно CPU не потребляет...
Но зато больше 30 секунд не работает... Достаточно спровоцировать перерисовку других окон (например закладки переключать) и сие чудо техники падает. Причины озвучены ранее... Хотя думал, что они не будут столь систематически появляться. В приложении весьма не хитрая иллюстрация разницы между подходами. Думаю будет понятно без объяснений. Присоединённый файл ( Кол-во скачиваний: 1 )
Project1.rar 563,92 Kb-------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
вариант хороший и может даже лучший, но весь вопрос "как?" Стену нужно строить так, чтоб подпирать... или как говаривали классики "главное леса не убирайте пока обои не поклеите"... Это сообщение отредактировал(а) drkot - 6.8.2014, 01:25 -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
| Delvish |
|
|||
![]() oO ![]() Профиль Группа: Участник Сообщений: 136 Регистрация: 13.12.2006 Репутация: 1 Всего: 4 |
Не сударь, так мусье ...Помнится, когда я был курсе на 4м и изучал предмет Автоматика, был дико поражен тем, КАК можно задачу за 2й класс по математике, где из двух труб вода наливается в бассейн, а из третьей выливается, извратить до ужасного вида дифференциальных уравнений второго порядка. Так и тут, простую задачу чуть ли не через ассемблерные вставки решаем |
|||
|
||||
| PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
2) разрешение таймера по дефолту 15.6 ms, так что твоя "1" (и любое число до 15 включительно) на самом деле = 15.6 3) ускорять нет смысла, т.к. длительность 1 кадра при стандартной развертке 60 кадров в секунду = 1000ms/60 = 16.666 ms, а больше 60 кадров ты хоть как не сможешь на экране увидеть (хоть скоростной киносъемкой его снимай) Это сообщение отредактировал(а) PointerToNil - 6.8.2014, 13:50 |
|||
|
||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: 5 Всего: 8 |
гыы... простых задач не бывает. VCL это мало динамичное средство, так как вся работа по "принуждению" вынесена в ядро, а программист пишет только бизнес логику. Для самых тяжелых компонентов сделала возможность на время изменения отключить перерисовку. Отсюда вывод: динамичная перерисовка в VCL возможна только при перекрытии в наследнике. решение с потоком может выглядеть следующим образом: поток в цикле вызывает Invalidate для компонента и ждет на waitforobject(ивент) // ивент с автосбросом также можно добавить небольшой sleep которые определит частоту перерисовки функция перерисовки (например в TPaintBox) вычисляет значение таймера рисует значение таймера дергает ивент в результате никакого мерцания + быстрая перерисовка чтобы создать эффект "размытости" можно рисовать старое значение в виде тени (более светлым) тогда при низкой скорости обновления (5-10 кадров) можно достичь ощущения "размытости" Добавлено через 1 минуту и 34 секунды PointerToNil, о вот и капитан очевидность -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |