OberonCore
https://forum.oberoncore.ru/

Аналог процедуры Delay()
https://forum.oberoncore.ru/viewtopic.php?f=81&t=3861
Страница 1 из 1

Автор:  Александр Иноземцев [ Вторник, 28 Февраль, 2012 20:36 ]
Заголовок сообщения:  Аналог процедуры Delay()

Я хочу в исполнителе сделать задержку на x миллисекунд между выполнением команд. Как в Pascal процедура Delay().
Подскажите пожалуйста как проще реализовать это.

Автор:  Info21 [ Вторник, 28 Февраль, 2012 23:22 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Александр Иноземцев писал(а):
Я хочу в исполнителе сделать задержку на x миллисекунд между выполнением команд. Как в Pascal процедура Delay().
Подскажите пожалуйста как проще реализовать это.
Через Services.Action

Автор:  Пётр Кушнир [ Среда, 29 Февраль, 2012 01:16 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Код:
IMPORT Services;

TYPE
  DelayAction = POINTER TO RECORD (Services.Action) END;

PROCEDURE (da: DelayAction) Do;
BEGIN
 (* наш код
если нужно продолжить, выполняем здесь
Services.DoLater(Services.Ticks()+timeout);*)
END Do;

PROCEDURE DoLater(timeout: INTEGER);
VAR da: DelayAction;
BEGIN
NEW(da); Services.DoLater(da, Services.Ticks()+timeout); (* это важно, именно Ticks()+таймаут, то есть, через таймаут от текущего момента *)
END DoLater;

Автор:  Trurl [ Среда, 29 Февраль, 2012 07:41 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Товарищи, вы название форума не забыли прочитать? ;)

Автор:  Илья Ермаков [ Среда, 29 Февраль, 2012 08:26 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Насколько я помню, в Дельфе Delay блокирует выполнение? Т.е. это просто обёртка над WinApi.Sleep?

Автор:  Александр Иноземцев [ Среда, 29 Февраль, 2012 08:49 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

В данном случае я бы хотел написать аналог Sleep(). Т.е. задержка перед выполнением следующей команды. Однако моих скромных познаний в КП не хватает для этого.

Опишу подробнее: Имется набор процедур Исполнителя. Часть из них изменяют положение Исполнителя (перемещение, поворот). Я хочу в конце таких процедур ставить процедуру задержки, чтобы можно было рассмотреть процесс, а не конечный результат (процедура задержки должна иметь параметр).

Автор:  Евгений Темиргалеев [ Среда, 29 Февраль, 2012 09:04 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Вызывайте WinApi.Sleep напрямую.

Если не хотите выходить за пределы библиотеки ББ, используйте Services.Action --- задержка будет не после, а перед выполнением команды --- команда ожидает заданное число миллисекунд, потом выполняется.

Автор:  Trurl [ Среда, 29 Февраль, 2012 11:55 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Евгений Темиргалеев писал(а):
Вызывайте WinApi.Sleep напрямую.

Задержка то будет, но картинка обновится только после завершения программы.

Автор:  igor [ Среда, 29 Февраль, 2012 12:11 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Trurl писал(а):
Задержка то будет, но картинка обновится только после завершения программы.
После завершения программы никакой картинки уже не будет. Или я не в теме?

Автор:  Александр Иноземцев [ Среда, 29 Февраль, 2012 13:52 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Евгений Темиргалеев писал(а):
Вызывайте WinApi.Sleep напрямую.

Если не хотите выходить за пределы библиотеки ББ, используйте Services.Action --- задержка будет не после, а перед выполнением команды --- команда ожидает заданное число миллисекунд, потом выполняется.


1. А как быть если ББ запущен из Linux? (по поводу WInApi)

2. Я с трудом разгребаю Views, поэтому буду очень благодарен за ссылку на примеры по модулю Services, а конкретно, по данному вопросу.

Автор:  Евгений Темиргалеев [ Среда, 29 Февраль, 2012 14:37 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

1) Вы скорее всего пользуетесь виндовым ББ под wine, который реализует WinApi. Но, как заметил Trurl, этот вариант не годится.
2) viewtopic.php?p=71073#p71073
Код:
MODULE PrivDelay;
   IMPORT Services, Dialog;

   TYPE
      DelayAction = POINTER TO RECORD (Services.Action)
         cmd: ARRAY 256 OF CHAR
      END;

   PROCEDURE (da: DelayAction) Do;
      VAR res: INTEGER;
   BEGIN
      Dialog.Call(da.cmd, "", res)
   END Do;

   PROCEDURE Exec* (IN cmd: ARRAY OF CHAR; timeout: INTEGER);
   VAR da: DelayAction;
   BEGIN
      NEW(da); da.cmd := cmd$;
      Services.DoLater(da, Services.Ticks()+timeout); (* это важно, именно Ticks()+таймаут, то есть, через таймаут от текущего момента *)
   END Exec;

END PrivDelay.

^Q "PrivDelay.Exec('Log.Int(1);Log.Ln', 1000)"

Автор:  Александр Иноземцев [ Среда, 29 Февраль, 2012 17:25 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Спасибо.
А если вызов идет не через коммандер, то так пойдет PrivDelay.Exec('', 1000)?
Вот пример фрагмента:
Код:
...
PROCEDURE ШагВперед;
BEGIN
  DrawPlace(vx, vy); (* удаляем изображение Исполнителя на старой позиции *)
  vx := vx + dx;
  vy := vy + dy;
  DrawVoyager(vx, vy); (* отрисовываем Исполнителя на новой позиции *)
  Views.Update( область, Views.keepFrames );
  PrivDelay.Exec('', 1000)
END;

Автор:  Евгений Темиргалеев [ Среда, 29 Февраль, 2012 18:24 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

PrivDelay.Exec(cmd, t) регистрирует экшен, который через t мс выполнит команду cmd. Экшены выполняются "в фоне".

PROCEDURE ШагВперед;
BEGIN
...
PrivDelay.Exec('', 1000)
END;

ШагВперед будет сам по себе работать, на каждое его исполнение будет регистрироваться по экшену, которые в фоне, через секунду ничего делать не будут.

Вам надо что-то типа Exec('ШагВперёд', 1000)

Автор:  Александр Иноземцев [ Среда, 29 Февраль, 2012 21:05 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Евгений Темиргалеев писал(а):
...
Вам надо что-то типа Exec('ШагВперёд', 1000)

Большое спасибо. Что-то такое я предполагал, когда внимательнее посмотрел на предложенный вариант. Не хотел даблпостить.
Именно такой вариант подойдет, т.к. ШагВперед это процедура отрисовки. Анализ до и после действия производится отдельно.

Автор:  Kubanych [ Среда, 25 Июль, 2012 07:56 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Евгений Темиргалеев писал(а):
Вызывайте WinApi.Sleep напрямую.

Код:
PROCEDURE Test* ();
VAR i:INTEGER;
BEGIN
   i:=0;
   WHILE i<20  DO
      WinApi.Sleep(1000);
      Log.Real(ObxRandom.Uniform());
      Log.Ln;

      led0:=~led0;
      led1:=~led1;
      led2:=~led2;
      led3:=~led3;

      Dialog.UpdateBool(led0);   
      Dialog.UpdateBool(led1);   
      Dialog.UpdateBool(led2);   
      Dialog.UpdateBool(led3);   
      
      INC(i)
   END;
END Test;
   

Иногда срабатывает нормально (чекбоксы мигают, как LED),
иногда после 5-6 миганий система затормаживается и потом
все результаты сразу выводятся на печать.

Причина- в многозадачности операционной системы?
Как можно лечить?

Автор:  Kubanych [ Среда, 25 Июль, 2012 08:04 ]
Заголовок сообщения:  Re: Аналог процедуры Delay()

Kubanych писал(а):
Причина- в многозадачности операционной системы?
Как можно лечить?


Лечится тестированием на многоядерном процессоре.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/