Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрый секундомер 
:(
    Опции темы
MrDmitry
Дата 5.8.2014, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 556
Регистрация: 10.11.2006

Репутация: нет
Всего: нет



помогите написать очень быстрый секундомер. чтоб у например секунды бежали  в 10 или 100 раз быстрее реальных секунд и соотвественно менялись, минуты, часы, дни. Сейчас сделал так


Код

function zero(i:integer):string;
 begin
   if i<10 then
    result:='0'+inttostr(i)
   else
    result:=inttostr(i);
 end;


procedure TForm3.Button1Click(Sender: TObject);
begin
Timer1.Enabled:=true;
end;

procedure TForm3.Timer1Timer(Sender: TObject);
var
 sec, min, hour, day:integer;
begin
    if sec>=60 then
     begin
      sec:=0;
      inc(min);
       if min=60 then
        begin
         min:=0;
         inc(hour);
         if hour=24 then
          begin
           hour:=0;
           inc(day);
          end;
        end;
     end;
    sec_label.Caption:=zero(sec);
    min_label.Caption:=zero(min);
    hour_label.Caption:=zero(hour);
    day_label.Caption:=zero(day);
end;


интервал таймера выставлен на 1мс. но мне такой скорости мало )) 
PM MAIL   Вверх
drkot
Дата 5.8.2014, 01:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Во первых: никто не мешает приращивать время больше чем на одну секунду
Во вторых: 
Код

var
  dt: TDateTime;
...
  dt:= dt + OneSecond;
  secundomer. Caption:= DateTimeToStr(dt);
  
и как ни странно необходимость в эпическом наборе условий пропадает

В третьих: есть OnPaint в нем и надо рисовать

Добавлено через 7 минут и 34 секунды
Как по мне так идеально (без излишнего погружения в глубины) реализовать так:
Код


// например глобально  :crazy 
var
  start: TDateTime;

// инициализация
  start:= Now;

// ontimer
  caption:= DateTimeToStr(start + (Now - start) * 1000); // коэффициент ускорения

интервал таймера не стоит делать менее 50. а так 100мс в самый раз.


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Delvish
Дата 5.8.2014, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


oO
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 13.12.2006

Репутация: 1
Всего: 4



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

Код

TNewThread = class(TThread)
   private
   protected
     procedure Execute; override;
   end;

var
NewThread : TNewThread;
i : Cardinal = 0;

procedure TForm1.Button1Click(Sender: TObject);
begin
NewThread := TNewThread.Create(False);
NewThread.Priority := tpNormal;
end;

procedure TNewThread.Execute;
begin
  inherited;
while True do
  begin
  Form1.Label1.Caption := IntToStr(i);
  Sleep(10);
  Inc(i);
  end;
end;


PM MAIL   Вверх
drkot
Дата 5.8.2014, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(Delvish @  5.8.2014,  13:00 Найти цитируемый пост)
Вероятно, правильнее будет

не лезть в потоки если не имеете элементарных навыков работы с ними. 

Цитата(Delvish @  5.8.2014,  13:00 Найти цитируемый пост)
  Sleep(10);

А сколько кадров воспринимает глаз человека? А сколько кадров выдает монитор?
Откуда, Pi, такая любовь к малым числам? 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Alexeis
Дата 5.8.2014, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(drkot @  5.8.2014,  02:58 Найти цитируемый пост)
интервал таймера не стоит делать менее 50. а так 100мс в самый раз. 

  О_о откуда такие цифры? В принципе правильно сказали, если делается анимация, то не следует ее запускать чаще чем способен увидеть глаз. Т.е. 25 кадров в секунду, что ровняется 40мс. Дискретность системного таймера обычно ~ 15.6мс, поэтому при помощи него можно реально выдавать обновления с периодом ~31 мс т.е. 32 кадра в секунду (заводим например на 30мс). Если завести таймер на 40мс, то реально получим ~47 мс интервал, т.е. 21 кадр в сек. Тоже не плохо, хотя глаз может видеть изменения чаще. 
  Ну и как правильно сказали, что можно за 1 кадр менять величину секунд не на единицу, а на 2, на 3 или даже на число с плавающей точкой (округлять при выводе на экран).


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Delvish
Дата 5.8.2014, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


oO
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 13.12.2006

Репутация: 1
Всего: 4



Цитата(drkot @  5.8.2014,  15:14 Найти цитируемый пост)
не лезть в потоки если не имеете элементарных навыков работы с ними. 

Сударь, а более конкретно и по делу?
Задача не
Цитата(drkot @  5.8.2014,  02:58 Найти цитируемый пост)
start:= Now;

машину времени написать же. Насколько я понял из первого поста, человек хочет секундомер. 
Цитата(MrDmitry @  5.8.2014,  01:59 Найти цитируемый пост)
помогите написать очень быстрый секундомер

То бишь чтобы от отметки "ноль" циферки начали бежать вперед, быстро-быстро увеличиваясь. Поток не даст форме висеть, процессор не будет 25% ресурсов отдавать на таймер с задержкой 50 мс. Да и к тому же, sleep(10) не говорит о том, что цикл будет повторяться ровно каждые 10 мс - не забываем об отрисовке на канве формы label'а. Собственно, цифру я написал совершенно случайную, не нужно придираться smile
Т.о., я предложил не такой уж и плохой вариант, довольно близко стоящий к запросу топикстартера. Да и слово "вероятно", что я употребил, говорит о том, что я не считаю свои слова истиной в последней инстанции, не стОит так нападать smile

PM MAIL   Вверх
drkot
Дата 5.8.2014, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(Alexeis @  5.8.2014,  15:57 Найти цитируемый пост)
откуда такие цифры?

мягко говоря с потолка. сакрального смысла в них нет.
любой интервал таймера приведет к мерцанию, так как он в априори асинхронен с WM_PAINT .
Для локальной анимации вполне достаточно 5-10 кадров, отсюда интервал задержки 100мс.
Учитывая, что таймер инициирует перерисовку (в оригинальном коде целых четыре раза) то малые значения интервала приведут жуткому мерцанию. По факту изображение будет пропадать примерно в каждом втором кадре, а наличие 4-х объектов создаст эффект старых люминесцентных ламп smile


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Alexeis
Дата 5.8.2014, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
То бишь чтобы от отметки "ноль" циферки начали бежать вперед, быстро-быстро увеличиваясь. Поток не даст форме висеть, процессор не будет 25% ресурсов отдавать на таймер с задержкой 50 мс. 

  Если мы что-то делаем, то на то должны быть объективные причины. В чем необходимость создания потока? Разве задача требует тактирование интервалов менее 15мс? Глаз не различает интервалы менее 40мс, так какой будет толк от того что мы меняем счетчик 100500 раз в секунду? Я бы мог понять если б от этого таймера работала передача данных по сети или осуществлялось управление внешним устройством. А так задача сводиться к тому, чтобы осуществлять вывод на экран. Я бы вообще и тактировал счетчик именно отрисовкой очередного кадра. Засекал бы сколько прошло времени с предыдущего кадра умножал бы эту цифру на коэффициент ускорения времени и прибавлял к текущему времени, вот вам и ускоренное время безо всякого перерасхода ресурсов.

Добавлено @ 17:51
Цитата(drkot @  5.8.2014,  18:29 Найти цитируемый пост)
мягко говоря с потолка. сакрального смысла в них нет.
любой интервал таймера приведет к мерцанию, так как он в априори асинхронен с WM_PAINT .

  Неа. К мерцанию иногда приводит очистка фона, но она легко отключается если перехватывать WM_ERASEBKG . И кто сказал, чтобы обязаны рисовать в самом таймере? Мы в таймере просто вызываем функцию InvalidateRect для нижележащего окна. Она говорит винде, а ну-ка давай-ка перерисуйся. Винда говорит Yes sir! досрочно генерит сообщение WM_PAINT . По факту мы получаем WM_PAINT с частотой таймера. Вот в нем и рисуем. WM_PAINT априори синхронен со всем с чем должна быть синхронна отрисовка, поэтому все что мы нарисуем не будет мигать. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
drkot
Дата 5.8.2014, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
Сударь

Во первых, это моя песенка, так что попрошу без плагиата.
Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
более конкретно и по делу?

1. наверно Вас мама не учила, что надо прорисовку синхронизировать с основным потоком? 
2. глобальная переменная в потоке? 
3. ну и на последок inherited; смысл в вызове метода предка? конечно ничего критичного, но все же...
итого: идеальный пример "как провалить собеседование".
Так, что мне не понятен повод Вашего сарказма...

Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
человек хочет секундомер

человек хочет чтоб циферки быстрее бежали,  а уж подсунуть то можно любые...
Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
отметки "ноль" циферки

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

Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
процессор не будет 25% ресурсов отдавать на таймер с задержкой 50 мс.

таки, какой процессор?
таки, получается в системе может работать только 4-ре таймера?

Цитата(Delvish @  5.8.2014,  18:25 Найти цитируемый пост)
е стОит так нападать

ни каких нападений.
просто зачем лезть (давать совет лезть) в неведомые дебри... лучше решать задачу теми средствами которые знаешь, меньше шансов наломать дров... имхо


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
drkot
Дата 5.8.2014, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(Alexeis @  5.8.2014,  18:42 Найти цитируемый пост)
отключается если перехватывать WM_ERASEBKG

Вы абсолютно правы.
Цитата(Alexeis @  5.8.2014,  18:42 Найти цитируемый пост)
 синхронен

Могу ошибаться..., но когда TWinControl посылает CM_INVALIDATE, то он не проверяет пришел ли ответный WM_PAINT... таким образом приходят целые пакеты WM_PAINT, что приводит к многократному вызову (возможно асинхронному) перерисовки. А учитывая что при начале прорисовке ставится блокировка, а в конце она снимается. Будут моменты времени когда прорисовка еще ведется, а блокировка уже снята. Изображение выводится на монитор только с той части на которых нет блокировок. Вот и получается, что может быть выведена только часть (в данном случае фон). Конечно сумбурно получилось, но без листа бумаги объяснить тяжело...

Собственно для избежания этого и вызывают Synchronize()

Это сообщение отредактировал(а) drkot - 5.8.2014, 18:21


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
MrDmitry
Дата 5.8.2014, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 556
Регистрация: 10.11.2006

Репутация: нет
Всего: нет



Мне конечно льстит что тут развилась такая дискуссия на тему таймеров и секундомеров но задача более тривиальная. Мне нужно прогонять время с 0 до наступления события x. Должно это происходить на подобие, как   это происходит, в игре симс. Нажата кнопка плей время идет в обычном режиме, нажали ускорение, время бежит еще быстрее, нажали еще ускорение, время бежит очень и очень быстро. Визуально время нужно отображать только в лейблах, без всяких от рисовок циферблатов и т.д. Как я написал в 1 посте, я поставил параметр interval компонента timer на 1, все работает так как нужно, за исключением того что мне нужно чтоб время секундомера бежало быстрее чем 1мс. 
PM MAIL   Вверх
MrDmitry
Дата 5.8.2014, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 556
Регистрация: 10.11.2006

Репутация: нет
Всего: нет



Цитата(Delvish @  5.8.2014,  12:00 Найти цитируемый пост)
  Form1.Label1.Caption := IntToStr(i);


спасибо, в принципе меня ваш код устраивает. ))  Хотя наверное использование потока для быстрого секундомера не лучший вариант, но все же это работает )
PM MAIL   Вверх
drkot
Дата 5.8.2014, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(MrDmitry @  5.8.2014,  22:50 Найти цитируемый пост)
в принципе меня ваш код устраивает

Собственно потом будут ругать дядю Билла что система жутко тормозит и глючит...

MrDmitry, Вы хоть на загрузку процессора посмотрите... У вас же все ресурсы направлены на рисование какой то мелкой метки, Вы действительно считаете что это правильно?

PS: да... сложно на рунете жить стало... 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
MrDmitry
Дата 5.8.2014, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 556
Регистрация: 10.11.2006

Репутация: нет
Всего: нет



Цитата(drkot @ 5.8.2014,  22:05)
Цитата(MrDmitry @  5.8.2014,  22:50 Найти цитируемый пост)
в принципе меня ваш код устраивает

Собственно потом будут ругать дядю Билла что система жутко тормозит и глючит...

MrDmitry, Вы хоть на загрузку процессора посмотрите... У вас же все ресурсы направлены на рисование какой то мелкой метки, Вы действительно считаете что это правильно?

PS: да... сложно на рунете жить стало... 

Может я не туда смотрю? Нажал старт, открыл диспетчер задача, загрузка процессора не изменилась. напротив моей программы цп 0
PM MAIL   Вверх
drkot
Дата 6.8.2014, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Да, как ни странно CPU не потребляет...
Но зато больше 30 секунд не работает... Достаточно спровоцировать перерисовку других окон (например закладки переключать) и сие чудо техники падает. Причины озвучены ранее... Хотя думал, что они не будут столь систематически появляться.


В приложении весьма не хитрая иллюстрация разницы между подходами.
Думаю будет понятно без объяснений.

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  Project1.rar 563,92 Kb


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0679 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.