OberonCore
https://forum.oberoncore.ru/

Что может означать этот трап?
https://forum.oberoncore.ru/viewtopic.php?f=24&t=2645
Страница 1 из 2

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 00:42 ]
Заголовок сообщения:  Что может означать этот трап?

Это я что-то неправильно делаю, но что именно, понять не могу.

Суть вот в чём.

На форме лежит отображение, у которого в методе Restore производится проверка изменения размеров этой формы (форма берётся через Views.HostOf). Если размеры изменились, то берём модель формы и пропорционально меняем размеры всех внедрённых на форму отображений.

И вся эта музыка вполне себе работает. Только иногда выскакивает вот это:

Цитата:
TRAP 22 (precondition violated)

Views.RestoreRoot [00002C54H]
.b INTEGER 4104540
.col INTEGER 16777215
.gb INTEGER 2534633
.gl INTEGER 43425
.gr INTEGER 2191803
.gt INTEGER 72000
.l INTEGER 74041
.port Ports.Port NIL
.r INTEGER 728091
.rd Ports.Rider NIL
.root Views.RootFrame [01AA0F70H]
.t INTEGER 3875940
.tl Views.TLS NIL
.u INTEGER 9525
Views.ValidateRoot [0000300DH]
.f Views.Frame [01A20CE0H]
.i INTEGER 3
.n INTEGER 9
.rgn Views.Region [01D176A0H]
.root Views.RootFrame [01AA0F70H]
.v Views.View [01D08FE0H]
Windows.Window.Update [00000175H]
.w Windows.Window [01D19040H]
Windows.RestoreSequencer [00001CBBH]
.seq Sequencers.Sequencer [01D19910H]
.w Windows.Window [01D19040H]
Windows.Directory.Update [000007C4H]
.d Windows.Directory [01A65630H]
.u Windows.Window [01D19040H]
.w Windows.Window NIL
HostMenus.Loop [00003CC0H]
.done BOOLEAN FALSE
.f SET {0..5}
.n INTEGER 2
.res INTEGER 0
.w HostWindows.Window NIL
Kernel.TrapHandler [000039BDH]
.context POINTER [629A58F9H]
.dispCont INTEGER 29033072
.estFrame POINTER [629A5D55H]
.excpRec POINTER [0022FC94H]


Куда копать, что бы это значило? Отложенное действие (даже с задержкой в одну секунду) не помогает - всё равно этот же трап, ведущий в

Цитата:
PROCEDURE RestoreRoot* (root: RootFrame; l, t, r, b: INTEGER);
VAR port: Ports.Port; rd: Ports.Rider;
u, gl, gt, gr, gb: INTEGER; col: Ports.Color;
tl: TLS;
BEGIN
ASSERT(root # NIL, 20); ASSERT(root.state = open, 21);
ASSERT(root.update.n = 0, 22); << вот здесь и трапает
...

Автор:  Илья Ермаков [ Воскресенье, 16 Май, 2010 08:04 ]
Заголовок сообщения:  Re: Что может означать этот трап?

-- Подобная интересная гадость с фреймами была когда-то в Lab-е, где рабочие области в текст вставлялись... Проявлялось нерегулярно. Разобраться руки не дошли, а потом Лаб был закрыт.

А если всё это делать не в Restore, а периодически по Action? (не только отложенно размер менять).
И на код бы точный глянуть.

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 09:48 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Илья, спасибо за ответ!

Выкладываю исходники модуля SternResize (вместе с сопутствующими). Смотрите в процедуре
Код:
PROCEDURE Resize (VAR v: View; w1, h1, w2, h2: INTEGER; s: SET);


Насчёт полностью отложенной операции обновления... Попробую что-нибудь, ради эксперимента.

Вложения:
Stern.zip [18.07 КБ]
Скачиваний: 483

Автор:  Info21 [ Воскресенье, 16 Май, 2010 11:46 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Иван Кузьмицкий писал(а):
Это я что-то неправильно делаю, но что именно, понять не могу.
...
На форме лежит отображение, у которого в методе Restore производится проверка изменения размеров этой формы (форма берётся через Views.HostOf). ...
Вообще-то Views.HostOf явно помечена в документации как не предназначенная для прикладного программиста.
Это игры с огнём, и результат вполне закономерен.

Если это попытка выйти за ограничения Form, то надо поискать регулярный способ.

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 12:17 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Да, конечно, я знаю, что Views.HostOf для внутреннего употребления.

Для чего мне это понадобилось?

Есть надобность подгонять размеры внедрённых отображений под размер формы. Размер формы меняется пользователем (тема viewtopic.php?f=24&t=2622&p=47045#p47045 сюда же).

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

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

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

Поэтому напрашивается такое решение: внедрить особый элемент прямо на форму, которую надо контролировать. Это как бы очевидно, и интерфейс получается интуитивно понятный.

Но как этому элементу следить за размерами своего хоста-формы? Легально - никак. Идеология контейнеров не предполагает подобной активности от внедрённых отображений (регулирование только на уровне предпочтений, а это значит, что нужна обработка сообщений на уровне каждого контрола, что влечёт за собой кучу дополнительных костылей в виде обёрток отображений).

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

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 13:06 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Сделал немного по-другому.

При изменении размера окна, в окно посылается модельное сообщение:
Код:
   PROCEDURE ResizeCallBack* (w, h: INTEGER);
      VAR wnd: Windows.Window; msg: ResizeMsg;
   BEGIN
      wnd := Windows.dir.First();
      IF wnd # NIL THEN
         wnd.BroadcastModelMsg(msg)
      END
   END ResizeCallBack;


Отображение получает это сообщение и создаёт отложенное действие (поставил задержку в 1 секунду):
Код:
   PROCEDURE (v: View) HandleModelMsg (VAR msg: Models.Message);
      VAR a: ResizeAction;
   BEGIN
      WITH msg: ResizeMsg DO
         NEW(a); a.v := v; Services.DoLater(a, Services.Ticks() + 1000);
      ELSE
      END
   END HandleModelMsg;


Когда действие срабатывает, то отображение проверяет изменения размеров и ресайзит контролы. Трап всё равно выскакивает (Опять же, не всегда и не везде).

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 13:47 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Опытным путём поймал место трапа.

Трап проявляется именно на этой форме.

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

Кнопка самая что ни на есть стандартная! Если её сдвинуть в сторону от закладок, то наползания нет и трапа нет.

Самое интересное, что я стёр эту кнопку, потом разместил новую (привязал процедуры со старой), и трап пропал!

Может быть, дело в закладках TabViews. Может быть, дело в порядке размещения отображений на форме (ресайз отработал по кнопке, она наползла на закладки и, как раз в этот момент ББ решает обновить фреймы, - получайте трап). Пока не знаю. Но медицинский факт зафиксирован.

Вложения:
Глюк ресайза с кнопкой Закрыть.png
Глюк ресайза с кнопкой Закрыть.png [ 19.55 КБ | Просмотров: 15304 ]

Автор:  Info21 [ Воскресенье, 16 Май, 2010 14:14 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Тема важная, все понять не успел, но вот это:
Иван Кузьмицкий писал(а):
Обёртывать форму своей обёрткой, значит лишиться стандартной поддержки каркаса.
-- мне кажется, неверное утверждение.
Своя вьюха над стандартной формой, вьюха помнит о вложенных кнопках -- и они про нее могут знать, эта вьюха, по сути, отвечает на их запросы,
а все сигналы к форме форвардуются настоящей форме, которая ничего не подозревает.
Нельзя ли как-то так? Любопытно.

Иван Кузьмицкий писал(а):
Кроме этого, уже разработано немалое количество диалогов на базе стандартных форм, и заменять их на какие-то особые - дело неблагодарное.
Подразумевается замена всей подсистемы Form? Похоже, тут тоже неверное неявное предположение, что это неизбежно.

Но да, корень проблемы тут в том, что в Form не предусмотрены подобные взаимодействия. Мне любопытно, можно ли обойти эти ограничения уже заложенными в ББ "композиционными" средствами.

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 14:19 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Info21 писал(а):
Своя вьюха над стандартной формой, вьюха помнит о вложенных кнопках -- и они про нее могут знать, эта вьюха, по сути, отвечает на их запросы,
а все сигналы к форме форвардуются настоящей форме, которая ничего не подозревает.
Нельзя ли как-то так? Любопытно.


Я с этого и начинал. Сделал обёртку формы. Но форму обернуть невозможно без потери связи с каркасом (контейнер плотно "впаян" в механизмы ББ). Контролы оборачивать тоже нельзя, потеряется управляемость.

Info21 писал(а):
Подразумевается замена всей подсистемы Form? Похоже, тут тоже неверное неявное предположение, что это неизбежно.

Это предлагал и Е.Темиргалеев, кстати: viewtopic.php?p=47018#p47018, и я даже чуть не встал на этот путь.

Автор:  Info21 [ Воскресенье, 16 Май, 2010 18:37 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Иван Кузьмицкий писал(а):
форму обернуть невозможно без потери связи с каркасом (контейнер плотно "впаян" в механизмы ББ).
Есть уверенность, что это неверно. То есть, что можно все связи сохранить.

Хотя такая полноценная обертка будет громоздкой (не ощущаю, насколько именно).

Автор:  Иван Кузьмицкий [ Воскресенье, 16 Май, 2010 19:46 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Info21 писал(а):
Иван Кузьмицкий писал(а):
форму обернуть невозможно без потери связи с каркасом (контейнер плотно "впаян" в механизмы ББ).
Есть уверенность, что это неверно. То есть, что можно все связи сохранить.

Хотя такая полноценная обертка будет громоздкой (не ощущаю, насколько именно).


К примеру, я сделал обёртку типа Views.View для формы, обернул ею стандартную FormViews.View, сохранил в документ и теперь хочу открыть моё отображение в режиме маски: StdCmds.OpenAuxDialog. А получится фигвам, потому что стандартная установка режима маски выглядит так:

Код:
   PROCEDURE ThisMask (param: ARRAY OF CHAR): Views.View;
      VAR v: Views.View; c: Containers.Controller;
   BEGIN
      v := ThisDialog(param);
      IF v # NIL THEN
         WITH v: Containers.View DO
            c := v.ThisController();
            IF c # NIL THEN
               c.SetOpts(c.opts - {Containers.noFocus} + {Containers.noCaret, Containers.noSelection})
            ELSE Dialog.ShowMsg("#System:NotEditable")
            END
         ELSE Dialog.ShowMsg("#System:ContainerExpected")
         END
      END;
      RETURN v
   END ThisMask;


Опции контроллера срабатывают только для Containers.View. Таким образом, моя обёртка сработала как экран и я теперь не могу пользоваться стандартной поддержкой каркаса. Значит, мне надо делать обёртку-контейнер. Ради отлова одного-единственного сообщения как-то не хочется :)

Автор:  Info21 [ Воскресенье, 16 Май, 2010 21:16 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Иван Кузьмицкий писал(а):
Значит, мне надо делать обёртку-контейнер.
То есть надо что-то генерализовать, выходит.

Интересно, а если бы весь интерфейс контейнера был бы реализован через мессиджи, наверное, то данная ситуация разрулилась бы гораздо проще?

Еще: почему бы просто не сделать свою процедуру открытия в режиме маски?

Автор:  Иван Кузьмицкий [ Понедельник, 17 Май, 2010 09:34 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Info21 писал(а):
Интересно, а если бы весь интерфейс контейнера был бы реализован через мессиджи, наверное, то данная ситуация разрулилась бы гораздо проще?


Я тоже об этом крепко думал. Да, в этом случае, возможностей для расширения стандартных конструкций было бы куда больше.
Ещё возникла идея - обработчик сообщений делать инсталлируемым. Чтобы обёртывать не всю, скажем, форму, а только вклинить свой обработчик.

Info21 писал(а):
Еще: почему бы просто не сделать свою процедуру открытия в режиме маски?

Уже есть такая. Скопипастили к себе HostCmds, HostWindows и StdCmds, чтобы создавать окна с некоторой дополнительной функциональностью.

Автор:  Илья Ермаков [ Понедельник, 17 Май, 2010 17:43 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Иван Кузьмицкий писал(а):
Ещё возникла идея - обработчик сообщений делать инсталлируемым. Чтобы обёртывать не всю, скажем, форму, а только вклинить свой обработчик.


Дык... Он и есть отдельный - контроллер! Можно вклинить свой контроллер, а внутри пусть он что надо переадресует к стандартному.

Можно перед открытием конкретной формы подменить FormControllers.dir - и вуаля, форма откроется с Вашим контроллером (который внутри себя создаст стандартный).

Автор:  Иван Кузьмицкий [ Понедельник, 17 Май, 2010 20:13 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Ну да, FormControllers.Controller как раз абстрактный, плюс сам по себе небольшой. Единственное, что смущает - обработчики сообщений у него финальные.

Автор:  Илья Ермаков [ Понедельник, 17 Май, 2010 20:19 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Почему финальные? EXTENSIBLE, вроде как.

Автор:  Info21 [ Понедельник, 17 Май, 2010 21:09 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Что же, всё-таки нашелся способ?

Промблемка интересная, надо бы понять.

Автор:  Иван Кузьмицкий [ Понедельник, 17 Май, 2010 21:21 ]
Заголовок сообщения:  Re: Что может означать этот трап?

А, точно, это я не туда второпях глянул, на обработчики контейнерного View, а вот у контейнерного контроллера обработчики расширяемые, то что надо.

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

Автор:  Иван Кузьмицкий [ Понедельник, 17 Май, 2010 21:41 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Продолжая эксперименты, отчётливо увидел, что трап возникает как раз в момент наползания одного контрола на другой. Уже увеличенный контрол (Field) наползает на другой (TabViews), ещё старого размера.

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

Стало быть, ББ в момент моего ресайза начинает обновлять вьюхи. Как-то это надо блокировать, что ли...

Автор:  Иван Горячев [ Вторник, 18 Май, 2010 03:57 ]
Заголовок сообщения:  Re: Что может означать этот трап?

Илья Ермаков писал(а):
Можно перед открытием конкретной формы подменить FormControllers.dir - и вуаля, форма откроется с Вашим контроллером (который внутри себя создаст стандартный).


Нет! В этом вся и фишка - при загрузке Stores директории не используются - вызывается напрямую Kernel.NewRec с указанным финальным типом! То есть ExternalizeAs имеется, а вот обратно - звиняйте.

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