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/