Книга: Язык программирования Euphoria. Справочное руководство

от S до T

от S до T

save_bitmap

Синтаксис:

include image.e

i = save_bitmap(s, st)

Описание:

Создаёт bitmap-файл (.bmp) из 2-х элементного ряда s. Ряд st является именем .bmp-файла. s[1] является палитрой:

{{r,g,b}, {r,g,b}, ..., {r,g,b}}

Каждая из величин r, g, или b должна быть в диапазоне от 0 до 255. s[2] является двумерным рядом рядов, содержащих пиксельно-графическое изображение. Ряды, содержащиеся в s[2], должны все иметь одинаковую длину. s имеет тот же самый формат, что и величина, выдаваемая функцией read_bitmap().

Индикатор результата операции i может принимать одно из следующих значений:

global constant BMP_SUCCESS = 0,-- успех операции
BMP_OPEN_FAILED = 1,-- файл не открылся на запись
BMP_INVALID_MODE = 4 -- неверный графический формат

-- или неверный аргумент

Комментарии:

Если вы использовали get_all_palette() для получения палитры перед вызовом этой функции, вы должны умножить величины интенсивностей на 4 перед вызовом save_bitmap().

Вы можете использовать save_image(), чтобы получить двумерный ряд для s[2], содержащий изображение.

Функция save_bitmap() вырабатывает файлы биткарт с 2, 4, 16, или 256 цветами, так что все они могут быть затем прочитаны с помощью read_bitmap(). Программа Paintbrush из пакета Windows и некоторые другие графические редакторы не поддерживают 4-х цветные биткарты.

Пример:

paletteData = get_all_palette() * 4
code = save_bitmap({paletteData, imageData},
"c:examplea1.bmp")

См. также:

save_image, read_bitmap, save_screen, get_all_palette

save_image

Платформа:

DOS32

Синтаксис:

include image.e

s3 = save_image(s1, s2)

Описание:

Переписывает в ряд прямоугольное изображение с пиксельно-графического экрана. Результатом является двумерный ряд рядов, содержащий данные обо всех пикселах изображения. Вы можете затем снова вывести это изображение с использованием процедуры display_image(). Ряд s1 является 2-х элементным рядом {x1,y1}, задающим координаты верхнего левого угла изображения, s2 задаёт {x2,y2} - координаты правого нижнего угла.

Пример:

s = save_image({0,0}, {50,50})
display_image({100,200}, s)
display_image({300,400}, s)
-- записывает в ряд квадратный участок размером 51x51 из верхнего левого угла экрана,
-- а затем выводит его в позиции {100,200} и в позиции {300,400}

См. также:

display_image, save_text_image

save_screen

Платформа:

DOS32

Синтаксис:

include image.e

i = save_screen(x1, st)

Описание:

Сохраняет весь экран или прямоугольную область экрана в файле типа Windows bitmap - .bmp-файле. Чтобы записать в файл весь экран, подайте в функцию 0 для x1. Чтобы записать прямоугольную область экрана, x1 должен быть рядом двух рядов: {{topLeftXPixel, topLeftYPixel}, {bottomRightXPixel, bottomRightYPixel}}, где {topLeftXPixel, topLeftYPixel} равно {Xверхний левый, Yверхний левый}, а {bottomRightXPixel, bottomRightYPixel} равно {Xнижний правый, Yнижний правый}

Ряд st - имя вашего .bmp-файла, в который будет записана биткарта.

Индикатор результата операции i может принимать одно из следующих значений:

global constant BMP_SUCCESS = 0,-- успех операции
BMP_OPEN_FAILED = 1,-- файл не открылся на запись
BMP_INVALID_MODE = 4 -- неверный графический формат

-- или неверный аргумент

Комментарии:

save_screen() вырабатывает биткарты с 2, 4, 16, или 256 цветами, которые могут быть прочитаны с помощью read_bitmap(). Программа Paintbrush из пакета Windows и некоторые другие графические редакторы не поддерживают 4-х цветные биткарты.

save_screen() работает только в пиксельно-графических режимах, но не в текстовых.

Пример 1:

-- записывается весь экран:
code = save_screen(0, "c:examplea1.bmp")

Пример 2:

-- записывается часть экрана:
err = save_screen({{0,0},{200, 15}}, "b1.bmp")

См. также:

save_image, read_bitmap, save_bitmap

save_text_image

Синтаксис:

include image.e

s3 = save_text_image(s1, s2)

Описание:

Записывает в ряд прямоугольную область экрана в текстовом режиме. Результатом будет ряд рядов, содержащий символы ASCII и их атрибуты с экрана. Вы сможете затем перевывести этот текст с помощью процедуры display_text_image(). s1 является двухэлементным рядом вида {строка1, колонка1}, в котором определена позиция (знакоместо) верхнего левого символа. s2 - ряд вида {строка2, колонка2}, определяющий позицию (знакоместо) правого нижнего символа.

Комментарии:

Поскольку сохраняются и атрибуты, вы будете получать правильные цвета фона, символов и другие свойства для каждого символа при перевыводе сохранённого текста.

Под DOS32 байт атрибута состоит из двух 4-битных полей, в которых содержится информация о цвете фона и символа для каждого знакоместа. Старшие 4 бита определяют цвет фона, а младшие 4 бита дают цвет символа на этом фоне.

Эта подпрограмма работает только в текстовых режимах.

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

Под DOS32, если вы применяете чередование видеостраниц, имейте в виду, что данная функция производит чтение с текущей активной страницы.

Пример:

Если на двух верхних строках экрана имеется:

Hello

World

и вы исполните:

s = save_text_image({1,1}, {2,5})

тогда s будет иметь вид:

{"H-e-l-l-o-",
"W-o-r-l-d-"}
символ '-' здесь обозначает некие байты атрибутов.

См. также:

display_text_image, save_image, set_active_page, get_screen_char

scroll

Синтаксис:

include graphics.e

scroll(i1, i2, i3)

Описание:

Прокручивает участок текста на экране вверх (если i1 положительное) или вниз (если i1 отрицательное) на i1 строк. Участок текста - это последовательность строк на экране от i2 (верхняя строка) до i3 (нижняя строка) включительно. Сверху или снизу будут появляться новые пустые строки.

Комментарии:

Вы могли бы выполнять прокручивание экрана, используя серии вызовов puts(), но scroll() работает намного быстрее.

Позиция курсора после прокрутки не определена.

Пример программы:

bined.ex

См. также:

clear_screen, text_rows

seek

Синтаксис:

include file.e

i1 = seek(fn, a1)

Описание:

Переход на позицию байта с номером a1 в файле fn или в конец файла, если a1 равно -1. Для каждого из открытых файлов у системы имеется информация о текущей байтовой позиции, которая обновляется в результате выполнения на файле операций ввода/вывода. Начальная позиция равна 0 для файлов, открытых на чтение, запись или обновление. Начальная позиция равна концу файла для файлов, открытых на добавление. Величина i1, выдаваемая функцией seek(), равна 0, если переход в заданную позицию завершился успешно, и не равна 0, если переходу что-то помешало. Возможен переход за границу имеющегося файла, в некоторую позицию за его концом. Если вы перешли за конец файла и записываете данные, в зазор между имевшимся концом файла и вашими новыми данными будут вставлены неопределённые байты.

Комментарии:

После перехода в заданную позицию и чтения (записи) последовательности байтов вам может потребоваться новый явный вызов seek() непосредственно перед переключением на запись (чтение) байтов, даже если позиция в файле уже была именно та, которая вам необходима.

Эта функция обычно используется с файлами, открытыми в двоичном режиме. В текстовом режиме DOS преобразует CR LF в LF на входе, и LF в CR LF на выходе, что может вызывать великую путаницу, когда вы пытаетесь подсчитывать байты.

Пример:

include file.e
integer fn
fn = open("mydata", "rb")
-- читает и отображает первую строку файла 3 раза:
for i = 1 to 3 do
puts(1, gets(fn))
if seek(fn, 0) then
puts(1, "перемотка не сработала!n")
end if
end for

См. также:

where, open

sequence

Синтаксис:

i = sequence(x)

Описание:

Выдаёт 1, если x является рядом, иначе выдаёт 0.

Комментарии:

Основное назначение команды - определение переменных типа ряд. Но вы можете вызывать её как обычную функцию, чтобы проверить, является ли объект действительно рядом.

Пример 1:

sequence s
s = {1,2,3}

Пример 2:

if sequence(x) then
sum = 0
for i = 1 to length(x) do
sum = sum + x[i]
end for
else
-- x должен быть атомом
sum = x
end if

См. также:

atom, object, integer, atoms and sequences

set_active_page

Платформа:

DOS32

Синтаксис:

include image.e

set_active_page(i)

Описание:

Выбирает видеостраницу номер i для всех выводов на экран.

Комментарии:

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

Функция video_config() сообщит вам, как много видео страниц доступно в текущем графическом режиме на вашей видеоплате.

По умолчанию активная страница и отображаемая страница обе имеют номер 0.

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

Пример:

include image.e
-- активная и отображаемая страницы сначала обе имеют номер 0
puts(1, "nЭто страница 0n")
set_active_page(1) -- экранный вывод теперь пойдёт на страницу 1
clear_screen()
puts(1, "nТеперь мы перешли на страницу 1n")
if getc(0) then -- ожидание нажатия клавиши
end if
set_display_page(1) -- "Теперь мы ..." становится видимым
if getc(0) then -- ожидание нажатия клавиши
end if
set_display_page(0) -- "Это ..." становится видимым снова
set_active_page(0)

См. также:

get_active_page, set_display_page, video_config

set_display_page

Платформа:

DOS32

Синтаксис:

include image.e

set_display_page(i)

Описание:

Делает видеостраницу номер i отображаемой на экране.

Комментарии:

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

Функция video_config() сообщит вам, сколько видеостраниц доступно в текущем видеорежиме на вашей видеоплате.

По умолчанию в качестве и активной, и отображаемой страницы используется видеостраница под номером 0.

Эта процедура работает под DOS или в полноэкранном окне DOS. В окнах, занимающих часть экрана, вы не можете манипулировать номерами видеостраниц.

Пример:

See set_active_page() example.

См. также:

get_display_page, set_active_page, video_config

set_rand

Синтаксис:

include machine.e

set_rand(i1)

Описание:

Устанавливает генератор случайных чисел в определённое состояние, i1, так что вы будете получать одинаковые серии квазислучайных чисел при последовательных запусках своей программы с вызовами rand().

Комментарии:

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

Пример:

sequence s, t
s = repeat(0, 3)
t = s
set_rand(12345)
s[1] = rand(10)
s[2] = rand(100)
s[3] = rand(1000)
set_rand(12345) -- та же величина для set_rand()
t[1] = rand(10) -- те же аргументы для rand(), что и ранее
t[2] = rand(100)
t[3] = rand(1000)
-- в этой точке s и t будут идентичными

См. также:

rand

set_vector

Платформа:

DOS32

Синтаксис:

include machine.e

set_vector(i, s)

Описание:

Устанавливает s в качестве нового адреса для обработчика прерывания номер i. Ряд s должен содержать дальний адрес защищённого режима в форме: {16-битный сегмент, 32-битное смещение}.

Комментарии:

Перед вызовом set_vector() вы должны разместить машинный код подпрограммы обработчика прерывания в памяти по адресу s.

16-битный сегмент может быть сегментом кода, используемым Euphoria. Чтобы получить значение для этого сегмента, см. demodos32hardint.ex. Смещение может быть 32-битной величиной, выдаваемой функцией allocate(). Euphoria исполняется в защищённом режиме с сегментами кода и данных, расположенными в одной и той же физической памяти, но с различными режимами доступа.

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

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

Вы должны заблокировать память, занимаемую вашим обработчиком, чтобы быть уверенным, что он никогда не будет перенесен на диск при использовании виртуальной памяти. См. lock_memory().

Настоятельно рекомендуем изучить работу файла demodos32hardint.ex, прежде чем пытаться устанавливать собственный обработчик прерывания.

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

Вы можете вызвать set_vector() с дальним адресом, выданным get_vector(), если возникла необходимость восстановить исходный оригинальный обработчик.

Пример:

set_vector(#1C, {code_segment, my_handler_address})

Пример программы:

demodos32hardint.ex

См. также:

get_vector, lock_memory, allocate

sin

Синтаксис:

x2 = sin(x1)

Описание:

Выдаёт синус x1, где x1 выражено в радианах.

Комментарии:

Данная функция может быть применена к атому или ко всем элементам ряда.

Пример:

sin_x = sin({.5, .9, .11})
-- sin_x равен {.479, .783, .110}

См. также:

cos, tan

sleep

Синтаксис:

include misc.e

sleep(i)

Описание:

Приостанавливает исполнение программы на i секунд.

Комментарии:

Под WIN32 и Linux/FreeBSD операционная система будет приостанавливать вашу программу и отдавать управление другим запущенным программам. Под DOS32 ваша программа будет исполнять занятый цикл в течение i секунд, во время которых другие программы могут выполняться, но на конкурентной основе за обладание процессором.

При работе в режиме многозадачности приостанавливается вся программа, а не только текущая задача. Чтобы приостановить текущую задачу, вы можете вызвать task_schedule(task_self(), {i, i}), а затем исполнить task_yield().

Пример:

puts(1, "Остановка на 15 секунд ...n")
sleep(15)

puts(1, "Остановка закончена.n")

См. также:

lock_file, abort, time

sort

Синтаксис:

include sort.e

s2 = sort(s1)

Описание:

Сортирует ряд s1 в порядке возрастания, используя быстрый алгоритм сортировки. Элементы s1 могут быть любой смесью атомов или рядов. Атомы идут перед рядами, а ряды сортируются в "алфавитном" порядке, так, что сначала сортировка выполняется по первым элементам (полям), затем, если первые эквивалентны, по вторым и т.д. Выдаёт отсортированный ряд.

Пример 1:

x = 0 & sort({7,5,3,8}) & 0
-- x становится равным {0, 3, 5, 7, 8, 0}

Пример 2:

y = sort({"Smith", "Jones", "Doe", 5.5, 4, 6})
-- y равно {4, 5.5, 6, "Doe", "Jones", "Smith"}

Пример 3:

database = sort({{"Smith", 95.0, 29},
{"Jones", 77.2, 31},
{"Clinton", 88.7, 44}})
-- 3 "записи" в базе данных будут отсортированы по первому "полю",
-- т.е. по имени. Там, где первые поля (элементы) эквивалентны,
-- сортировка будет производиться по второму полю и т.д.
-- после сортировки база данных примет вид:
{{"Clinton", 88.7, 44},
{"Jones", 77.2, 31},
{"Smith", 95.0, 29}}

См. также:

custom_sort, compare, match, find

sound

Платформа:

DOS32

Синтаксис:

include graphics.e

sound(i)

Описание:

Включает системный громкоговоритель (звукоизлучатель) PC на частоте i Гц. Если подать аргумент i, равный 0, громкоговоритель будет выключен.

Комментарии:

Под WIN32 и Linux/FreeBSD звуки этой процедурой не генерируются.

Пример:

sound(1000) -- включается непрерывный высокий тон частотой 1000 Гц

sprint

Синтаксис:

include misc.e

s = sprint(x)

Описание:

Выдаёт представление x как символьной строки. Это точно то же самое, что и print(fn, x), но вывод производится не в файл и не на устройство (экран), а в ряд. x может быть любым объектом Euphoria. The representation of x as a string of characters is returned. This is exactly the same as print(fn, x), except that the output is returned as a sequence of characters, rather than being sent to a file or device. x can be any Euphoria object.

Комментарии:

Атомы, содержащиеся в x, будут выведены максимум с 10 значащими цифрами, как и при помощи print().

Пример 1:

s = sprint(12345)
-- s равно "12345"

Пример 2:

s = sprint({10,20,30}+5)
-- s равно "{15,25,35}"

См. также:

print, sprintf, value, get

sprintf

Синтаксис:

s = sprintf(st, x)

Описание:

Эта функция делает точно то же самое, что и printf(), но вывод производится не в файл и не на устройство (экран), а в ряд. Ряд st является строкой формата, x - величина или ряд, подлежащие форматированию. printf(fn, st, x) является эквивалентом для puts(fn, sprintf(st, x)).

Комментарии:

Некоторые типовые применения sprintf():

1. Преобразование чисел в строки.

2. Создание строк для подачи в system().

3. Создание форматированных сообщений об ошибках, которые могут быть поданы в обработчик общих сообщений об ошибках.

Пример:

s = sprintf("%08d", 12345)
-- s равно "00012345"

См. также:

printf, value, sprint, get, system

sqrt

Синтаксис:

x2 = sqrt(x1)

Описание:

Выдаёт квадратный корень x1.

Комментарии:

Данная функция может быть применена к атому или ко всем элементам ряда.

Попытка извлечь квадратный корень из отрицательного числа вызовет аварийное завершение вашей программы с сообщением об ошибке времени исполнения.

Пример:

r = sqrt(16)
-- r равно 4

См. также:

log, power

system

Синтаксис:

system(st, i)

Описание:

Подаёт командную строку st в интерпретатор команд операционной системы для немедленного исполнения. Аргумент i необходим для указания способа возвращения из дочерней программы, запущенной командой system():

Когда i равно 0, предыдущий графический режим восстанавливается и экран очищается.

Когда i равно 1, выдаётся звуковой сигнал и программа ждет нажатия пользователя на клавишу, прежде чем восстановить предыдущий графический режим.

Когда i равно 2, графический режим не восстанавливается и экран не очищается.

Комментарии:

i = 2 должно использоваться, только когда известно, что команда, выполняемая system(), не будет изменять графический режим.

Вы можете использовать Euphoria как мощнейший "пакетный" (.bat) язык, задавая нужные вам вызовы system() и system_exec().

system() запускает новую копию интерпретатора команд DOS или Linux/FreeBSD.

system() позволяет вам использовать из командной строки перенаправление стандартных входа и выхода, задавая его в строке st.

Под DOS32 программа Euphoria стартует без использования расширенной памяти, но после старта начинает её использовать. Если для исполнения программы расширенной памяти перестанет хватать, программа начнёт занимать остатки стандартной памяти. При исчерпании и стандартной памяти начнётся использование виртуальной памяти, т.е. пересылка кода и данных на диск. Команда DOS, запущенная на исполнение с помощью system(), прервётся, если для её исполнения окажется недостаточно стандартной памяти. Чтобы избежать подобных ситуаций, вы можете зарезервировать некоторый объём стандартной (нижней) памяти, выполнив команду:

SET CAUSEWAY=LOWMEM:xxx

где xxx есть число K (килобайт) стандартной памяти, отводимой в резерв DOS. Резервирование должно быть выполнено до запуска вашей программы. Вы можете производить резервирование из вашего файла autoexec.bat или из .bat-файла, запускающего вашу программу. Например:

SET CAUSEWAY=LOWMEM:80

ex myprog.ex

По данной команде будет зарезервировано 80K стандартной памяти, которых достаточно для исполнения простых команд DOS вроде COPY, MOVE, MKDIR и т.п., если вы их потом подадите из своей программы myprog.ex.

Пример 1:

system("copy temp.txt a:temp.bak", 2)
-- не забывайте писать двойную косую черту в вашей команде, чтобы в DOS
-- передавалась штатная одинарная

Пример 2:

system("ex testmyprog.ex outdata", 2)
-- исполняется myprog, при этом её стандартные вход и выход
-- перенаправлены

См. также:

system_exec, dir, current_dir, getenv, command_line

system_exec

Синтаксис:

i1 = system_exec(st, i2)

Описание:

Пытается выполнить команду, заданную в строке st. Ряд st должен содержать команду запуска исполняемой программы, возможно, с некоторыми параметрами командной строки. Если программа может исполняться, в i1 будет записан код возврата из программы после её завершения. Если запуск программы невозможен, функция system_exec() выдаёт -1. В i2 должен быть указан код, дающий способ действий с текущим графическим режимом после завершения программы, вызванной system_exec(). Эти коды имеют те же самые значения, что и для функции system():

Когда i2 равно 0, восстанавливается предыдущий графический режим и экран очищается.

Когда i2 равно 1, подаётся звуковой сигнал, программа ждёт нажатия на клавишу перед восстановлением предыдущего графического режима.

Когда i2 равно 2, графический режим не восстанавливается и экран не очищается.

Комментарии:

Под DOS32 или WIN32 system_exec() запускает только .exe и .com программы. Для запуска пакетных файлов .bat или встроенных команд DOS следует пользоваться system() - некоторые команды DOS, такие как DEL и т.п., не являются отдельными программами, фактически они встроены в командный интерпретатор операционной системы.

Под DOS32 и WIN32 system_exec() не позволяет осуществлять перенаправление стандартных входа и выхода в командной строке st. Не разрешается также забирать в кавычки строки, которые содержат пробелы в именах каталогов и файлов.

Коды возврата из программ DOS или Windows обычно находятся в пределах от 0 до 255, 0 соответствует "нормальному завершению".

Вы можете запускать и дочерние программы Euphoria с использованием функции system_exec(). Программы Euphoria могут выдавать код возврата по команде abort().

system_exec() не запускает новую копию командного интерпретатора DOS.

Пример 1:

integer exit_code
exit_code = system_exec("xcopy temp1.dat temp2.dat", 2)
if exit_code = -1 then
puts(2, "n не могу запустить xcopy.exen")
elsif exit_code = 0 then
puts(2, "n успешное выполнение xcopyn")
else
printf(2, "n отказ xcopy с кодом ошибки %dn", exit_code)
end if

Пример 2:

-- исполняет myprog с двумя именами файлов в качестве аргументов
if system_exec("ex testmyprog.ex indata outdata", 2) then
puts(2, "отказ!n")
end if

См. также:

system, abort

tan

Синтаксис:

x2 = tan(x1)

Описание:

Выдаёт тангенс x1, когда x1 выражен в радианах.

Комментарии:

Данная функция может быть применена к атому или ко всем элементам ряда.

Пример:

t = tan(1.0)
-- t равно 1.55741

См. также:

sin, cos, arctan

task_clock_start

Синтаксис:

task_clock_start()

Описание:

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

Комментарии:

Команды task_clock_stop() и task_clock_start() предназначены для приостановки и возобновления выполнения задач реального времени.

Вызов task_clock_start() корректирует плановое время всех задач реального времени на тот промежуток времени, который прошёл с момента вызова task_clock_stop(). Это позволяет игре, модели или другой программе продолжаться плавно за счёт того, что часы диспетчера задач оказываются развязанными от общесистемных часов.

Задачи общего времени при этом не затрагиваются.

Пример:

-- приостановить игру, пока игрок отвечает на телефонный звонок
task_clock_stop()
while get_key() = -1 do
end while

task_clock_start()

См. также:

task_clock_stop, task_schedule, task_yield, task_suspend

task_clock_stop

Синтаксис:

task_clock_stop()

Описание:

Останавливает часы диспетчера, ответственные за выполнение плана задач реального времени. Выполнение плана возобновится по команде task_clock_start(). Задачи общего времени могут продолжать выполняться. Текущая задача также может продолжать выполняться, но если это задача реального времени, управление от неё будет передано диспетчеру.

Комментарии:

Вызывайте task_clock_stop(), когда вам необходимо, чтобы диспетчер задач приостановил выполнение задач реального времени. Например, когда вы хотите временно остановить игру или программную модель, чтобы затем, после некоторого перерыва, продолжить её исполнение из точки остановки.

Функция time() этой командой не затрагивается, команда действует только в отношении часов диспетчера многозадачности Euphoria.

См. также:

task_clock_start, task_schedule, task_yield, task_suspend

task_create

Синтаксис:

a2 = task_create(i1, s)

Описание:

Оформляет заданную процедуру как новую задачу для передачи её диспетчеру многозадачности. Аргумент i1 представляет собой номер процедуры Euphoria, составляющей новую задачу. Ряд s - это список аргументов, которые будут поданы в процедуру-задачу, когда начнётся её исполнение. Выдаваемый результат, a2, является номером задачи, под которым она будет фигурировать в системе многозадачности Euphoria.

Комментарии:

Функция task_create() позволяет оформить новую задачу, но не запускает её на исполнение.

Каждая из задач имеет свой набор частных переменных и свой собственный стек вызова. Глобальные и местные переменные действуют для всех задач.

При обнаружении ошибки во время исполнения, отчёт будет включать информацию по всем задачам, с ошибочной задачей, идущей в списке первой.

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

Задача не может иметь в основе функцию, так как нет возможности использования результата, выдаваемого функцией.

Каждая задача имеет уникальный номер. Функция task_create() никогда не выдаёт повторный номер задачи, как это было ранее. Номера задач являются атомами с величиной вплоть до наибольшей доступной целочисленной величины (15 цифр).

Пример:

mytask = task_create(routine_id("myproc"), {5, 9, "ABC"})

См. также:

task_schedule, task_yield, task_suspend, task_self

task_list

Синтаксис:

s = task_list()

Описание:

Выдаёт ряд, содержащий номера всех активных или приостановленных задач.

Комментарии:

Эта функция позволяет вам определить, какие задачи существуют в данный момент. Номера задач, которые были прекращены, в ряд не включаются. Вы можете уточнить состояние конкретной задачи, подав её номер в функцию task_status().

Пример:

sequence tasks
tasks = task_list()
for i = 1 to length(tasks) do
if task_status(tasks[i]) 0 then
printf(1, "задача %d активнаn", tasks[i])
end if
end for

См. также:

task_status, task_create, task_schedule, task_yield, task_suspend

task_schedule

Синтаксис:

task_schedule(a, x)

Описание:

Включает задачу номер a в план диспетчера, задаваемый аргументом x. Аргумент a должен быть получен как результат из функции task_create(). Если x является положительным атомом, это означает, что задача a является задачей общего времени и диспетчер должен x раз подряд обеспечить её выполнение, прежде чем перейти к другим задачам. Если x является рядом, это должен быть двухэлементный ряд {min, max}, в котором оба элемента больше нуля или равны нулю, а min и max дают минимальное и максимальное время, в секундах, которое необходимо выждать перед исполнением задачи реального времени a. Величины min и max также устанавливают временной интервал между последовательными запусками задачи a, если он не будет изменён повторным вызовом task_schedule() или task_suspend().

Комментарии:

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

Задачи реального времени имеют более высокий приоритет. Задачи общего времени выполняются, когда нет задач реального времени, готовых к выполнению. Задача может переключаться между режимами выполнения реального и общего времени. Это всё зависит от последнего вызова task_schedule() для данной задачи. Диспетчер никогда не запустит задачу реального времени до открытия её временного окна (величина min), и он пытается не допустить пропуска временного окна (величина max).

Чтобы повысить точность временных рамок, вы можете задать одну и ту же величину для min и для max. Тем не менее, задавая некоторый промежуток, вы добавляете диспетчеру гибкости. Это позволяет ему выполнять план задач более эффективно, избегая непродуктивных задержек. Когда диспетчеру требуется задержка, он вызывает sleep(), если задержка не слишком короткая. Использование sleep() позволяет операционной системе выполнять другие программы.

Величины min и max могут быть дробными. Если величина min меньше, чем разрешение часов диспетчера (в настоящее время 0.01 секунды под Windows и Linux/FreeBSD, и 0.55 секунды под DOS, если не вызывалась tick_rate()), точное диспетчирование не может быть выполнено, но диспетчер будет пытаться запустить задачу несколько раз подряд, чтобы приблизиться к заданному плану. Например, если вы задали время min равным 0.002 секунды, диспетчер будет пытаться запустить вашу задачу .01/.002 = 5 раз подряд, прежде чем ждать следующего тика часов через .01 секунды. Во время следующих 0.01 секунды он будет выполнять вашу задачу ещё (до) следующих 5 раз и так далее, считая, что ваша задача может быть завершена 5 раз за один тик его часов.

Для задач общего времени увеличение аргумента x будет увеличивать процент времени процессора, отдаваемого для выбранной задачи, при уменьшении этого процента для других задач общего времени. При этом эффективность программы в целом возрастёт, так как каждое переключение задач само по себе требует некоторого небольщого времени. Вызов task_yield(), когда та же самая задача продолжает выполняться, занимает меньше времени. Тем не менее, данный приём не всегда применим, так как может блокировать выполнение других задач общего времени на длительные периоды времени. Имейте в виду, что задачи реального времени всегда имеют приоритет перед любым task_yield(), если достигнуто время их активации.

По старту программы исполняется единственная задача. Её номер равен 0, и изначально это задача общего времени, которой разрешен 1 запуск на task_yield(). Другие задачи не могут выполняться, пока задача номер 0 не выполнит task_yield().

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

Если диспетчер не находит активных задач, т.е. в программе не осталось задач, которые следует поставить вновь на выполнение (в плане нет даже задачи номер 0), он останавливает программу с кодом окончания 0, наподобие abort(0).

Пример:

-- Задача t1 будет выполнена до 10 раз подряд, прежде чем
-- другим задачам общего времени будет отдано управление. Если управление
-- требуется задаче реального времени, t1 потеряет управление в её пользу.
task_schedule(t1, 10)
-- Задача t2 будет выполняться некоторое время между 4-ой и 5-ой секундами,
-- наступившими после текущего момента. Если не изменить план для t2, она будет
-- запускаться через каждые 4..5 секунд и в дальнейшем.
task_schedule(t2, {4, 5})

См. также:

task_create, task_yield, task_suspend, task_suspend

task_self

Синтаксис:

a = task_self()

Описание:

Выдаёт номер текущей задачи.

Комментарии:

Этот номер может понадобиться, если в задаче возникла необходимость перепланировать, приостановить или прекратить саму себя.

Пример:

-- перепланировать себя
task_schedule(task_self(), {5.9, 6.0})

См. также:

task_create, task_schedule, task_yield, task_suspend

task_status

Синтаксис:

i2 = task_status(a)

Описание:

Выдаёт код состояния задачи. Значения кода могут быть 1 (активна), 0 (приостановлена) и -1 (задача не существует).

Комментарии:

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

Величина кода состояния -1 показывает, что задача никогда не существовала либо задача завершилась естественным путём, либо была прекращена.

Пример:

integer s
s = task_status(tid)
if s = 1 then
puts(1, "АКТИВНАn")
elsif s = 0 then
puts(1, "ПРИОСТАНОВЛЕНАn")
else
puts(1, "НЕ СУЩЕСТВУЕТn")
end if

См. также:

task_list, task_create, task_schedule, task_suspend

task_suspend

Синтаксис:

task_suspend(a)

Описание:

Приостанавливает выполнение задачи номер a.

Комментарии:

Подача команды приостанавливает выполнение задачи номер a. Задача a не будет в дальнейшем выполняться, если для неё не будет снова подана команда task_schedule(). Номер a - это номер, который выдаёт функция task_create().

Любая задача может приостанавливать любую другую задачу. Если задача приостанавливает саму себя, остановка начнётся по вызову task_yield().

Пример:

-- приотановить задачу 15
task_suspend(15)
-- приостановить текущую задачу
task_suspend(task_self())

См. также:

task_create, task_schedule, task_self, task_yield

task_yield

Синтаксис:

task_yield()

Описание:

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

Комментарии:

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

Задача может иметь вызовы task_yield() во многих различных местах её кода, и на любой глубине вызова подпрограмм.

Диспетчер будет использовать текущую величину {min, max} или оставшееся текущее число последовательных вызовов, определяя, когда следует вернуться к текущей задаче.

Когда управление возвращается в задачу, её выполнение продолжается с команды, которая следует за task_yield(). Стек вызова и все частные переменные останутся теми, какими они были перед вызовом task_yield(). Глобальные и местные переменные могут измениться при выполнении других задач.

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

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

Пример:

-- Из игры Language war.
-- Эта небольшая задача имитирует расходование запасов энергии
-- на корабле Euphoria и на его челноке.
-- Задача представляется "вечной" в бесконечном цикле,
-- но на самом деле это задача реального времени, которая вызывается
-- с периодом 1.7 - 1.8 секунды на протяжении всей игры.
-- Каждый раз при её вызове расходуется 3 или 13 единиц энергии.
global procedure task_life()
-- независимая задача: вычитание из запасов энергии
while TRUE do
if shuttle then
p_energy(-3)
else
p_energy(-13)
end if
task_yield()
end while
end procedure

См. также:

task_create, task_schedule, task_suspend task_suspend

text_color

Синтаксис:

include graphics.e

text_color(i)

Описание:

Устанавливает цвет символов текста. Увеличив i на 16, в некоторых графических режимах можно получить мерцающий текст заданного i цвета. См. в graphics.e список возможных цветов.

Комментарии:

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

Когда ваша программа завершается, последний цвет, выбранный вами для текста и выводившийся на экран, сохраняется в действии. Поэтому вам может понадобиться напечатать что-то, можно просто 'n', в белом цвете (WHITE), чтобы восстановить белый цвет текста операционной системы, особенно, если курсор находится в нижней строке экрана в готовности к прокрутке вверх.

Пример:

text_color(BRIGHT_BLUE)

См. также:

bk_color

text_rows

Платформа:

DOS32, WIN32

Синтаксис:

include graphics.e

i2 = text_rows(i1)

Описание:

Устанавливает число строк на экране в текстовом режиме, если заданное значение i1 возможно. i2 принимает значение действительного нового числа строк.

Комментарии:

Число строк 25, 28, 43 и 50 поддерживается большинством видеоплат.

См. также:

graphics_mode

tick_rate

Платформа:

DOS32

Синтаксис:

include machine.e

tick_rate(a)

Описание:

Задаёт число прерываний в секунду от таймера. Тем самым устанавливается точность библиотечной функции time() и частота дискретизации при профилировании времени.

Комментарии:

tick_rate() игнорируется под WIN32 и Linux/FreeBSD. Дискретность счёта времени под WIN32 всегда равна 100 прерываниям в секунду.

На PC прерывания от таймера идут обычно с частотой 18.2 прерываний в секунду. tick_rate() позволяет вам увеличить эту частоту, но не уменьшить её.

tick_rate(0) восстановит нормальную частоту 18.2. Euphoria восстанавливает нормальную частоту автоматически при завершении вашей программы, даже при аварийной остановке по обнаруженной ошибке.

Когда программа исполняется в окне DOS с частотой таймера иной, чем 18.2, функция time() не будет убегать вперед, если данное окно не является активным окном.

С частотой таймера, отличающейся от 18.2, функция time() под DOS занимает примерно 1/100 от обычного времени её исполнения. Под Windows и FreeBSD функция time() всегда исполняется очень быстро.

До тех пор, пока ex.exe исполняется, система будет поддерживать правильное время дня. Но если произойдет отказ ex.exe (т.е. вы увидите сообщение об ошибке "CauseWay..."), когда частота таймера установлена высокая, вам (или вашему пользователю) может потребоваться перезапуск машины, чтобы восстановить правильную исходную частоту. Если не сделать этого, системное время будет быстро опережать реальное. Эта проблема не свойственна Windows 95/98/NT и имеет место только под DOS или Windows 3.1. Но вы всегда можете вернуться к правильному времени, поддерживаемому батарейными часами вашей машины, перезагрузив машину.

Пример:

tick_rate(100)
-- time() идёт с шагом .01 секунды
-- вместо обычных .055 секунды

См. также:

time, time profiling

time

Синтаксис:

a = time()

Описание:

Выдаёт число секунд, прошедших от некоторого фиксированного момента в прошлом.

Комментарии:

Если вам нужно измерить, например, сколько времени ушло на выполнение какого-то участка кода вашей программы, найдите разность между двумя отсчетами time(), взятыми в начале и в конце данного участка кода.

Разрешение под DOS32 обычно около 0.05 секунды. Под WIN32 и Linux/FreeBSD разрешение около 0.01 секунды.

Под DOS32 вы можете улучшить разрешение, вызвав процедуру tick_rate() с необходимым параметром.

Под DOS32 период времени, который вы можете так измерить, ограничен 24 часами. После этого величина, выдаваемая time() будет переустановлена и начнётся новый счёт. Если, тем не менее, вы вызывали tick_rate(), и частота часов была выше обычной 18.2/сек, результат time() будет оставаться правильным намного дольше, так как в этом случае Euphoria обрабатывает прерывания от часов прямо и накапливает отсчёты в более ёмкой переменной, 32-битной.

Эмуляция DOS под Windows XP не вполне совершенна. Когда вы производите профилирование времени (with profile_time), функция time() может иметь погрешность до нескольких процентов. Эта проблема не имеет места под Windows ME/98/95.

На некоторых машинах функция time() может выдавать отрицательное число. Тем не менее, вы можете использовать разность отсчётов от time(), чтобы измерять истекшее время.

Пример:

constant ITERATIONS = 1000000
integer p
atom t0, loop_overhead
t0 = time()
for i = 1 to ITERATIONS do
-- время пустого цикла
end for
loop_overhead = time() - t0
t0 = time()
for i = 1 to ITERATIONS do
p = power(2, 20)
end for
? (time() - t0 - loop_overhead)/ITERATIONS
-- вычисление времени (в секундах) одного возведения в степень

См. также:

date, tick_rate

trace

Синтаксис:

with trace

trace(i)

Описание:

Если i равно 1 или 2, включается полноэкранная интерактивная трассировка/отладка исполнения команд программой. Если i равно 3, включается трассировка команд в файл протокола с именем ctrace.out. Если i равно 0, трассировка выключается. Когда i равно 1, отображение на экране трассировки цветное. Когда i равно 2, трассировка отображается в монохромном режиме. Трассироваться будут только те подпрограммы, которые были откомпилированны с метакомандой "with trace". Процедура trace() не будет давать эффекта, если вызвана вне участка вашей программы, на котором действует команда "with trace".

См. Часть I - 3.1 Отладка и профилирование, чтобы уяснить детали по вопросам трассировки и отладки.

Комментарии:

Используйте trace(2), если цветное отображение на вашей системе затруднено.

Все формы trace() поддерживаются интерпретатором.

Транслятором с Euphoria на Си поддерживается только trace(3).

Пример:

if x then
-- да, этот участок требует отладки...
trace(1)
-- и т.д.
...
end if

См. также:

profile, debugging and profiling

...

Оглавление книги


Генерация: 0.108. Запросов К БД/Cache: 0 / 1
поделиться
Вверх Вниз