OberonCore https://forum.oberoncore.ru/ |
|
Пример ObxTwins в BlackBox https://forum.oberoncore.ru/viewtopic.php?f=29&t=6784 |
Страница 1 из 1 |
Автор: | Александр К [ Понедельник, 05 Июль, 2021 05:12 ] |
Заголовок сообщения: | Пример ObxTwins в BlackBox |
В примере ObxTwins есть процедура RecalcLayout: Код: PROCEDURE RecalcLayout (v: View); VAR w, h, sep: INTEGER; c: Context; BEGIN v.context.GetSize(w, h); sep := h DIV 3; (* separate the two views at 1/3 of the container's height *) c := v.top; c.l := border; c.t := border; c.r := w - border; c.b := sep - border; c := v.bottom; c.l := border; c.t := sep + border; c.r := w - border; c.b := h - border END RecalcLayout; Как данные из этой процедуры передаются во внешний мир, ведь она не использует глобальных переменных, ни возврата данных (RETURN), ни передачи по ссылке в своей сигнатуре? Почему использование переменной c без выделения памяти NEW(c) не вызывает ошибки, тогда как тип Context объявлен как указатель? |
Автор: | Иван Денисов [ Понедельник, 05 Июль, 2021 05:47 ] |
Заголовок сообщения: | Re: Пример ObxTwins в BlackBox |
Сначала вычисляются размеры контекста, куда вставлено большое отображение. Код: v.context.GetSize(w, h); И дальше эти данные w, h используются для вычисления размеров встроенных отображений. Данные передаются напрямую в их контексты. Для удобства сначала их указатели сохраняются в локальную переменную Код: c := v.top; а потом идут обращения по этому указателю Код: c.l := border; c.t := border; c.r := w - border; c.b := sep - border; NEW не требуется, так как работа идёт с уже существующими объектами в памяти. |
Автор: | Александр К [ Понедельник, 05 Июль, 2021 15:30 ] |
Заголовок сообщения: | Re: Пример ObxTwins в BlackBox |
Почему тогда это не работает: Код: IMPORT StdLog; ?
TYPE Field = POINTER TO RECORD i: INTEGER; END; MyC = POINTER TO RECORD top: Field; END; PROCEDURE Sea (m: MyC); VAR c: Field; BEGIN m.top := c; c.i := 1024; END Sea; PROCEDURE Start*; VAR v: MyC; BEGIN NEW (v); NEW (v.top); Sea (v); StdLog.Ln; StdLog.Int (v.top.i) END Start; |
Автор: | Иван Денисов [ Понедельник, 05 Июль, 2021 15:53 ] |
Заголовок сообщения: | Re: Пример ObxTwins в BlackBox |
В примере ObxTweens то контекст создаётся в NewContext до вызова RecalcLayout Код: PROCEDURE NewContext (v: Views.View; base: View): Context; VAR c: Context; BEGIN NEW(c); c.view := v; c.base := base; v.InitContext(c); Stores.Join(v, base); RETURN c END NewContext; Код: PROCEDURE NewTwin* (top, bottom: Views.View): Views.View; VAR v: View; BEGIN NEW(v); v.top := NewContext(top, v); v.bottom := NewContext(bottom, v); NEW(v.ident); Stores.Join(v, v.ident); v.focus := v.bottom; RETURN v END NewTwin; А у вас в примере top типа Field нигде не создаётся, поэтому и не работает. |
Автор: | adimetrius [ Вторник, 06 Июль, 2021 10:09 ] |
Заголовок сообщения: | Re: Пример ObxTwins в BlackBox |
Поле .top как раз инициализируется: NEW(v.top) Но в процедуре Sea объявлена переменная VAR c: Field Ее начальное значение - NIL, оно гарантируется языком. Затем m.top := c; (* теперь m.top = NIL *) c.i := 1024; (* теперь аварийный останов: разыменование пустого указателя, т.к. c = NIL *) Я не уверен, но, возможно, вы хотели написать c := m.top а написали m.top := c Тогда по окончании работы процедуры Sea будет справедливо m.top.i = 1024 (И, кстати, это называется постусловием процедуры Sea) |
Автор: | Иван Денисов [ Вторник, 13 Июль, 2021 10:34 ] |
Заголовок сообщения: | Re: Пример ObxTwins в BlackBox |
Да, мой ответ - неверный. Спасибо, Антон |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |