Inferno Programmer's Guide / Руководство программиста по ОС Inferno: Chapter 3 - Limbo Programming

← →
Английский оригинал Перевод на русский

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

Взаимодействие с внешними функциями

j1m 30.04.09 в 10:48

0

Следующий пример состоит из трех файлов. Главная программа пороождает новый поток с внешней функцией (из загруженного модуля) и испольует механизм каналов для взаимодействия в потоками.

j1m 30.04.09 в 11:04

0

chanx2a.b:
1 implement command;
2
3 include "sys.m";
4 include "draw.m";
5 include "chanx.m";
6
7 sys: sys;
8 print: import sys;
9 ex: chanx;
10 sc: chan of int;
11 re: chan of int;
12
13 Command: module {
14 init: fn(ctxt: ref Draw->context, argv: list of string);
15 };
16
17 init(ctxt: ref Draw->context, argv: list of string) {
18 sys = load sys Sys->PATH;
19 ex = load chanx "./chanx2b.dis";
20 sc = chan of int;
21 re = chan of int; 22
23 for (i:=l; i<=5; i++) {
24 spawn cx->func(sc, re);
25 print("%2d\n", i);
26 sc<- = i;
27 func(<-rc);
28 }
29 }
30
31 func(i: int) {
32 print("%6d\n", i);
33 }

j1m 30.04.09 в 11:05

0

chanx2b.m (интерфейс модуля для chanx2b.b):

j1m 30.04.09 в 11:07

0

1 chanx: module {
2 func: fn(sc: chan of int, re: chan of int);
3 };

j1m 30.04.09 в 11:07

0

chanx2b.b

j1m 30.04.09 в 11:07

0

1 implement chanx;
2
3 include "sys.m";
4 include "draw.m";
5 include "chanx.m";
6
7 sys: sys;
8 print: import sys;
9
10 func(sc: chan of int, re: cha
11 sys = load sys Sys->PATH;
12 i: int;
13 i = <-sc;
14 print("%4d\n", i);
15 rc<- = i;
16 }

j1m 30.04.09 в 11:07

0

Пример событийного пользовательского интерфейса
Этот пример демонстрирует использование оператора alt. В событийной модели графического окружения Limbo/Tk, каналы используются для отправки команд от графических элементов (виджетов). Использование оператора alt дает возможность программам откликаться на команды от различных событий. (Подробную информацию о графическом программировании в Limbo смотри в разделе Графическое Программирование на странице 3-43.)
Хотя Листинг 3-13 длинне большинства других примеров, использование оператоа alt начинается со строки 50.

Листинг 3-13 wmaltx.b
1 implement wmAltx;
2
3 include "sys.m";
4 include "draw.m";
5 include "tk.m";
6 include"wmlib.m";
7
8 sys: sys;
9 draw: Draw;
10 Display, image: import draw;
11 tk: Tk;
12 wmlib: wmlib;
13
14 WmAltx: module {
15 init: fn(ctxt: ref Draw->context, argv: list of string);
16 };
17
18 win_cfg := array[] of {
19 "frame .ft",
20 "text .ft.t -yscrollcommand {.ft.s set} -width 40w -height 15h",
21 "scrollbar .ft.s -command {.ft.t yview}",
22 "focus .ft.t",
23 "pack .ft.s -side right -fill y",
24 "frame .fb.a -bd 2 -relief sunken",
25 "pack .ft.t -side left -fill y",
26 "button .fb.a.b -height 2h -text {Button 1} -command {send cmd 1}",
27 "pack .fb.a.b -padx 1 -pady 1",
28 "button .fb.c -height 2h -text {Button 2} -command {send cmd 2}",
29 "button .fb.q -height 2h -text {Quit} -command {send cmd Q}",
30 "frame .fb",
31 "pack .fb.a .fb.c .fb.q -padx 5 -pady 5 -side left",
32 "pack .ft .fb",
33 "pack propagate . 0",
34 "update",
35 };
36 init(ctxt: ref Draw->context, argv: list of string) {
37 sys = load sys Sys->PATH;
38 draw = load Draw Draw->PATH;
39 tk = load Tk Tk->PATH;
40 wmlib = load wmlib Wm"lib->PATH; 41
42 wm~lib->init();
43
44 (win, menubut) := wm~lib->tit1ebar(ctxt.screen, "-x 5 -y 5", "wmAltx", 0);
45
46 cmd := chan of string;
47 tk->namechan(win, cmd, "cmd");
48 wm~lib->tkcmds(win, win_cfg); 49
50 for(;;) alt {
51 menu := <-menubut =>
52 if(menu[0] == 'e') {
53 tk->cmd(win, ".ft.t insert end '"+"close button pressed.\n");
54 tk->cmd(win, "update");
55 wm~lib->dia~log(win, "warning -fg red",
"close Button", "close Button pressed!", 0, "close"::nil);
56 exit;
57 }
58 wm~lib->tit1ect1 (win, menu);
59 s := <-cmd =>
60 case s[0] {
61 '1' =>
62 tk->cmd(win, ".ft.t insert end '"+"Button 1 pressed.\n");
63 tk->cmd(win, "update");
64 break;
65 '2' =>
66 tk->cmd(win, ".ft.t insert end '"+ "Button 2 pressed.\n");
67 tk->cmd(win, "update");
68 break;
69 'Q' =>
70 tk->ctnd(win, ".ft.t insert end '" + "Quit button pressed.\n");
71 tk->cmd(win, "update");
72 wm~lib->dia~log(win, "info", "Quit Button", "Quit button pressed!", 0, "Quit": :ni"l);
73 exit;
74 }
75 }
76 }

rapidfx 14.05.09 в 04:28

0

Выполнение оператора alt начинается со строки 50. Там происходит выбор между двумя каналами: menubut и cmd. Канал menubut ипользуется для уведомления приложения о событиях связанных с заголовком окна (titlebar), таких как перемещение и закрытие. Канал cmd уведомляет приложение о событиях от других виджетов, таких как кнопки расположенные внизу, Кнопка 1, Кнопка 2, и Выход.

rapidfx 14.05.09 в 04:36

0

Графика

j1m 30.04.09 в 10:49

0

Средства работы с графикой не встроены в язык Limbo, вместо этого они вынесены в специальные модули: Draw, Prefab и Limbo/Tk.
* Модуль Draw (draw.m) обеспечивает базовую функциональность для работы с растровой графикой и окнами. Модули Prefab и Limbo/Tk пользуются его услугами для создания более высокоуровневых интерфейсов.
* Модуль Prefab (prefab.m) предоставляет набор функций, предназначенных для использования приложениями интерактивного телевидения. Он включает поддержку инфрокрасных устройств ввода.
* Модули Limbo/Tk (tk.m и wmlib.m) предоставляют функции для создания интерактивных настольных приложений.

j1m 30.04.09 в 17:44

0

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

j1m 01.05.09 в 11:51

0

Модуль Draw

j1m 30.04.09 в 10:50

0

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

j1m 01.05.09 в 12:13

0

Концепция и Терминология

j1m 30.04.09 в 10:50

0

Мдуль Draw предоставляет низкоуровневые средства работы с графикой, поэтому его функции и данные находятся на более низком уровне, чем в большинтсве графических API. Поэтому он имеет несколько концепций и терминов, с которыми лучше познакомиться сразу.

j1m 01.05.09 в 12:18

0

Графический контекст (Context)

j1m 30.04.09 в 10:51

0

Как мы уже говорили в этой главе, графический контекст (Context), который захватывает программа через аргумент функции init(), определен в модуле Draw. Аргумент Context содержит ссылку на грфические ресурсы.
Два важных элемента графического контекста - display и screen.

j1m 01.05.09 в 13:12

0

Display

j1m 30.04.09 в 10:51

0

Объект display типа Draw->Display представляет физический экран, соответствующий одиночному подключению к устройству draw (/dev/draw).
Кроме изображения самого экрана, тип Display так же хранит сслыки на закадровые изображения, шрифты и т.п. Содержимое этих изображений хранится в устройстве display (???), а не в клиенте, что влияет на то, как они выделяются и используются.
Ресурсы для объект типа Display должны быть выделены с помощью его же функций (методов). Если объект Display будет создат стандартными средствами языка Limbo, его поведение будет неправильным и может привести к ошибкам исполнения.

j1m 01.05.09 в 13:33

0

Screen

j1m 30.04.09 в 10:51

0

Объект screen типа Draw->Screen используется для управления набором окон в изображении. Screens, and hence windows, may be built recursively upon windows for subwindowing or even on off-screen images.
Ресурсы для объекта типа Screen должны быть выделены с помощью его же функций (методов).

j1m 01.05.09 в 13:49

0

Объект screen типа Draw->Screen используется для управления набором окон в изображении, и обычно не т необходимости в его отображении. Screen'ы и следовательно и окна, могут создаваться рекурсивно в окнах для для дочерних окон/под-окон , или даже для закадровых изображений.
Ресурсы для объекта типа Screen должны быть выделены с помощью его же функций (методов).

rapidfx 14.05.09 в 09:23

0

Пиксели

j1m 30.04.09 в 10:52

0

Изображения представляют собой прямоугольный регион в целочисленной плоскости с элементом изображения (пиксель) на каждой точке сетки. Значение пикселя - это целое число, длиной 1, 2, 4 или 8 бит на пиксель. Все пиксели одного изображения имеют одинаковый размер (или глубину). Некторые операции позволяют объединить изображения с разной глубиной, например для выполнения маскирования (masking).
Когда изображение будет показано, значение каждого пикселя определит цвет экрана. Для цветных дисплеев Inferno использует фиксированную карту цветов для каждой глуюины экрана. and the application is responsible for mapping its desired colors to the values available. Предусмотрены функции для конвертирования троек красный, зеленый, синий (RGB) в значения пикселей.

j1m 02.05.09 в 09:28

0

Point

j1m 30.04.09 в 10:52

0

Тип Point определяет координаты. Графическая плоскость определена на целочисленной решетке, каждая (x, y) координата которой идентифицирует верхний левый угол соответствующего пикселя. Начало плоскости, (0,0) находится в верхнем левом углу экрана; координаты x и y возрастают в право и вниз.

j1m 04.05.09 в 19:33

0

Rect

j1m 30.04.09 в 10:52

0

Тип Rect определяет прямоугольный регион плоскости. Он содержит два поля типа Point (min и max) и указывает на регион, определенный пикселями с координатами большими или равными min и меньшими чем max, как x, так и y. Это полу-открытое свойство позволяет прямоугольникам, совместно использующим край, иметь одинаковые координаты на краю.

j1m 05.05.09 в 07:57

0

Image

j1m 30.04.09 в 10:52

0

Тип Image предоставляет базовые действия над группами пикселей. Через несколько простых действий тип Image предоставляет строительные блоки для Display, Screen и Font.
Объекты типа Image должны быть выделены с помощью их собственных методов.
Изображение занимает прямоугольник Image.r графической плоскости. Второй прямоугольник Image.clipr определяет "clipping region" изображения.
Обычно "clipping rectangle" равен прямоугольнику базового изображения, но они могут различаться. Например, "clipping region" сделать меньше и поместить в центр базового изображения чтобы обозначить защищенную рамку.

j1m 05.05.09 в 08:09

0

Глубина пикселей в Image записана как логарифм, записанный в Image. 1 depth (???). Пиксели, глубиной 1, 2, 4 или 8 бит соответствуют значениям 1 depth 0, 1, 2 или 3.
Изображение может быть маркировано для репликации. // FIXME

j1m 08.05.09 в 06:07

0

Font

j1m 30.04.09 в 10:52

0

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

j1m 13.05.09 в 10:41

0

Pointer

j1m 30.04.09 в 10:52

0

Тип Pointer сообщает информацию о состоянии устройств-указателей, таких как мыши и трекболы.

j1m 01.05.09 в 13:56

0

Возвращаемые значения

j1m 30.04.09 в 10:53

0

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

j1m 01.05.09 в 14:09

0

Освобождение графических объектов

j1m 30.04.09 в 10:53

0

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

j1m 01.05.09 в 14:14

0

Пример

j1m 30.04.09 в 10:53

0

Далее приведен исходный код версии программы Greet, которая иллюстрирует использования модуля Draw:

j1m 01.05.09 в 14:15

0

drawgreet.b:
1 implement DrawGreet;
2
3 include "sys.m";
4 include "draw.m";
5
6 sys: sys;
7 draw: Draw;
8 Display, Font, Rect, Point, image, screen: import draw;
9 display: ref Display;
10 disp, img: ref image;
11 font: Font;
12
13 DrawGreet : module {
14 init: fn(ctxt: ref Draw->context, argv: list of string);
15 };
16
17 init(ctxt: ref Draw->context, argv: list of string) {
18 sys = load sys Sys->PATH;
19 draw = load Draw Draw->PATH;
20
21 display = Display.allocate(nil);
22 disp = display.image;
23 spawn refresh(display);
24 white := display.color(Draw->white); # Предопределенный цвет
25 yellow := display.color(Draw->Yellow); # Предопределенный цвет
26 black := display.color(Draw->Black) ; # Предопределенный цвет
27 ones := display.ones; # Пиксельная маска
28 font = Font.open(display, "/fonts/lucidasans/uni code.9x24.font");
29
30 if ((tl argv) != nil)
31 str := "Hello, " + (hd(tl argv)) + "!";
32 else
33 str = "Hello, world!";
34
35 strctr := (font.width(str) / 2);
36
37 img := display.open("/icons/logon.bit") ;
38 imgxctr := img.r.max.x / 2;
39
40 dispctr := disp.r.max.x / 2;
41
42 disp.draw(disp.r, white, ones, (0,0));
43 disp.draw(disp.r, img, ones, (-(dispctr-imgxctr),-10));
44 disp.text(((dispctr - strctr), img.r.max.y+20), black, (0,0), font, str);
45 sys->sleep(10000);
46 disp.draw(disp.r, white, ones, (0,0));
47 }
48
49 refresh(disp1ay: ref Display) {
50 display.startrefresh();
51 }

j1m 30.04.09 в 17:49

0

Седьмая строка объявляет хэндл к модулю Draw, а строка 8 импортирует структуры данных Draw в текущее пространство имен. В частности это типы Display, Image и Font.
Тип Display олицетворяет физический экран, представленный устройством draw, смонтированным в /dev/draw. Строка 21 выделяет ресурсы для объекта display используя функцию Display.allocate().

j1m 13.05.09 в 10:51

0

Тип Image предоставляет базовые операции над группами пикселей и строительные блоки для более высокоуровневых объектов вроде изображний (графические файлы), окон и шрифтов. Строка 22 присваивает видимое содержимое (холст Draw) переменной disp. Строка 37 открывает файл изображения logon.bit, расположенный в каталоге /icons и присваивает его переменной img.

j1m 13.05.09 в 11:01

0

Тип Font определяет внешний вид символов, отображаемых с помощью функции Image.font(). Шрифты считываются из файлов, которые описывают их размер, стиль и часть Unicode-символов, которые они содержат. Строка 27 открывает файл шрифта unicode.9x24.font, расположенный в каталоге /fonts/lucidasans, и присваивает его переменной font.

j1m 13.05.09 в 11:06

0

Строка 23 обновляет экран используя рекомендованную технику порождения отдельного потока для локальной функции refresh() (строки 49-51), которая вызывает функцию Display.startrefresh() модуля Draw.

j1m 13.05.09 в 11:08

0

Строка 42 заполняет область экрана (прямоугольник, определенный в disp.r) белым цветом. Строка 43 отрисовывает изображение img на экране. Строка 44 рисует текст str используя шрифт font. Строка 45 делает паузу перед тем как экран будет очищен в строке 46.

j1m 13.05.09 в 11:11

0

После компиляции этой программы, вы можете запустить ее из консоли Inferno (не из графического окна командного инерпретатора):

% drawgreet inferno

j1m 13.05.09 в 11:13

0

//Тут рисунок со страницы 121

j1m 30.04.09 в 10:53

0

Модуль Prefab

j1m 30.04.09 в 10:53

0
Минутку...

← Предыдущая страница

Следующая страница →