OberonCore
https://forum.oberoncore.ru/

Обход Store'ов из одного Domain'а
https://forum.oberoncore.ru/viewtopic.php?f=23&t=3309
Страница 1 из 2

Автор:  Info21 [ Воскресенье, 27 Февраль, 2011 14:52 ]
Заголовок сообщения:  Обход Store'ов из одного Domain'а

Выделено: viewtopic.php?p=60750#p60750
См. также: viewtopic.php?f=23&t=2876
viewtopic.php?f=23&t=1669


Иван Кузьмицкий писал(а):
у меня ещё нет отчётливого видения Stores.
Главное, знать, куда там смотреть.
А смотреть нужно в Ex|Internalize и просто выабстрагировать оттуда механизм обхода узлов составной структуры данных, позволяющий не заходить в уже обойденные узлы.

Например, чтобы каждый узел (Store) что-то от себя напечатал в Рабочий журнал, но ровно один раз.
Или создать простой список всех узлов структуры (например, чтобы иметь их упорядоченность по какому-то критерию).

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

С итератором командовать парадом будет тот, кто вызывает итератор.
С сообщениями -- обрабатывать сообщения будут сами узлы.
Во втором случае проще скрыть реальную природу узлов. Зато список создать проще, видимо, с итератором.

Автор:  Иван Кузьмицкий [ Среда, 02 Март, 2011 11:16 ]
Заголовок сообщения:  Ошибка в документации к Stores?

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

Цитата:
Inspecting a store set

A store set cannot be inspected programmatically beyond what is offered by procedure Joined. However, the debugger allows to iterate over all stores in a store set. The stores which belong to the same store set are linked in a circular list. As soon as a domain object is associated to the set, the links are set to NIL and each store in the set refers to the new domain object. To iterate over a store set the debugger has to be called before the store set is bound. Then, the stores can be iterated with the store's next field. Listing 2 shows a simple procedure which generates an empty text view and then opens the debugger. Following the next fields of the view v, you see that the following seven stores are joined in one set: TextModels.Model, TextModels.Attributes, TextRulers.Ruler, TextRulers.Style, TextRulers.Attributes, TextViews.View and TextControllers.Controller.


Но ведь ни Views.Views, ни его предок Stores.Store не имеют поля next! И описанный способ обхода хранилищ не относится к текущему положению дел. Может, это какой-то старый кусок, относящийся ко временам, когда поле next существовало?

Видимо, имеется в виду поле dlink. Но тут ещё проблема - если поступить так, как описано в документации (откомпилировав и запустив пример Test), то мы не сможем уйти дальше первого dlink, так как его поле dlink = NIL.

Автор:  Александр Ильин [ Среда, 02 Март, 2011 11:36 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Действительно, неувязка. Раньше, видимо, производилась связь в циклический список, а теперь просто создаётся домен, у которого поле initialized = FALSE. Таким образом, итерация по элементам домена невозможна.

Автор:  Info21 [ Среда, 02 Март, 2011 12:17 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Александр Ильин писал(а):
итерация по элементам домена невозможна.
Интересно.

Что это дает?
Ведь инициализацию домена у Store всё равно надо явно делать, там и можно сделать подцепление.
Экономия нескольких слов?

Автор:  Александр Ильин [ Среда, 02 Март, 2011 12:40 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Я эту часть системы плохо знаю. Но почему-то у меня вертится предположение, что политика "все указывают на домен, но домен ни на кого не указывает" может быть необходима с точки зрения сборки мусора.

Операция "подцепления" к домену есть (Stores.Join), а "отцепления" - нету.

Автор:  Info21 [ Среда, 02 Март, 2011 14:51 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Александр Ильин писал(а):
предположение, что политика "все указывают на домен, но домен ни на кого не указывает" может быть необходима с точки зрения сборки мусора.

Операция "подцепления" к домену есть (Stores.Join), а "отцепления" - нету.
Я имел в виду подцепление к какому-нибудь циклическому списку.

Про сборку мусора -- возможно.
Но надо бы додумать.

Автор:  Иван Кузьмицкий [ Среда, 02 Март, 2011 16:27 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

В порядке осмысления.

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

Автор:  Александр Ильин [ Среда, 02 Март, 2011 16:38 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Info21 писал(а):
Александр Ильин писал(а):
Операция "подцепления" к домену есть (Stores.Join), а "отцепления" - нету.
Я имел в виду подцепление к какому-нибудь циклическому списку.
Если в документ забросили вьюшку, а потом удалили вместе с куском текста, то при удалении её надо "отцепить" - хоть от циклического списка, хоть от какого. А операции такой нету. Если нет отцепления, то будет она в этом циклическом списке висеть до закрытия документа, а так - помрёт при очистке буфера Undo (Stores.Domain.sequencer), что, кстати, делается при сохранении документа на диск.

Автор:  Info21 [ Среда, 02 Март, 2011 21:17 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Александр Ильин писал(а):
Info21 писал(а):
Александр Ильин писал(а):
Операция "подцепления" к домену есть (Stores.Join), а "отцепления" - нету.
Я имел в виду подцепление к какому-нибудь циклическому списку.
Если в документ забросили вьюшку, а потом удалили вместе с куском текста, то при удалении её надо "отцепить" - хоть от циклического списка, хоть от какого. А операции такой нету.
Мне сначала показалось, что это можно сделать в FINALIZE.
Но теперь мне кажется, что нет.
Сейчас не соображу...

Автор:  Евгений Темиргалеев [ Четверг, 03 Март, 2011 09:32 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Если вьюшка в списке, сборка мусора до неё не доберётся, FINALIZE не вызовется...

Тут два варианта. Либо Оминк не успел доработать концепцию, либо наоборот, они этот этап уже прошли. Например, тоже хотели универсальное средтсво для обхода сторов домена. Но оказалось, что ограничения, которые вносит его внедрение не окупают результат. а? Например, нехилое усложнение распространяется на все "вышележащие" компоненты.

Автор:  Иван Кузьмицкий [ Четверг, 03 Март, 2011 10:16 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

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

В итоге остаётся только один системный канал для передачи сообщений - деревья фреймов. Модели контейнеров уже частность.

Автор:  Евгений Темиргалеев [ Четверг, 03 Март, 2011 11:14 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Системный-то он системный, т.е. каркасный. Но тоже частность. Т.к. предназначен только для трансляции визуальных изменений состояния модели на эти самые фреймы.

Но никак не на работу с самой моделью.

А для работы с моделью, пока у нас только исходный метод: отталкиваться от конкретной задачи, когда структура связей известна. И соответственно, своими силами, организовывать обход....

Может тут стоит собирать опытный материал --- по конкретным задачам? Глядя на него, может выявится общая методика, как это делать в типовых случаях. А дальше, может, и до общей реализации дело дойдёт.? Или хотя бы до спец. каркаса под схожий набор задач.

Автор:  Иван Кузьмицкий [ Четверг, 03 Март, 2011 11:30 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Евгений Темиргалеев писал(а):
Системный-то он системный, т.е. каркасный. Но тоже частность. Т.к. предназначен только для трансляции визуальных изменений состояния модели на эти самые фреймы.
Полностью согласен.

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

А каркасное сообщение моделей между собой не предусмотрено ни концептуально, ни в рамках ББ как реализации.

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

Автор:  Александр Ильин [ Четверг, 03 Март, 2011 11:37 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

Насколько я понимаю, идея домена не предполагает знания обо всех объектах, в него входящих. Это механизм персистентности (сохранения на диск того, что должно сохраниться), а не динамического оповещения, в котором может витать куча временного мусора, тот же буфер Undo. Для обхода актуального состояния дерева модель должна предоставлять собственные средства - Reader.ReadView. Далее по всем прочитанным вьюхам рассылайте сообщения и вообще что хотите с ними делайте.

Да, неизвестные заранее типы контейнеров так не обойдёшь. Тут можно ввести дополнительный уровень абстракции (Reader, от которого будет унаследован TextModels.Reader). Не знаю, надо ли.

Автор:  Евгений Темиргалеев [ Четверг, 03 Март, 2011 16:45 ]
Заголовок сообщения:  Re: Ошибка в документации к Stores?

размышление в тему: viewtopic.php?f=23&t=288

Автор:  Сергей Губанов [ Суббота, 05 Март, 2011 00:22 ]
Заголовок сообщения:  Re: Что это за сообщение - Views.UpdateCachesMsg?

Info21 писал(а):
Основной вопрос: какой тут выбрать механизм для внешнего представления такого обхода: итератор (навроде прохода по вложенным вьюшкам в контейнере) -- или рассылка сообщений.
Я на работе в программу прошлым летом встроил обход всех объектов. Понадобилось для контроля над утечками памяти. Теперь всегда знаю сколько в памяти объектов какого типа есть, скорость их создания и удаления.

Написал модуль Diagnostics. Там абстрактный указательный тип Diagnostics.Object. У него переопределяемая процедура без параметров Traverse. Она экспортируется только для реализации. Ещё экспортируется просто процедура Diagnostics.TraverseThis(obj: Diagnostics.Object). В переопределённой процедуре Diagnostics.Object.Traverse() надо вызвать процедуру Diagnostics.TraverseThis(obj) для каждого диагностируемого объекта видимого из данного. У каждого Diagnostics.Object есть счётчик эпох обхода (целое число). Новый обход инициируется вызовом процедуры Diagnostics.TraverseRoot(root: Diagnostics.Object). Она увеличивает глобальный счётчик обходов на единицу, записывает его в root, ставит root в глобальную очередь. Затем, пока эта очередь не пуста вытаскивает из неё объекты и вызывает у них виртуальную Traverse. В ней вызываются Diagnostics.TraverseThis(obj) они сравнивают счётчик эпох обхода с текущим значением, если равен, значит этот объект уже был в пройден, иначе добавляем в очередь обхода.

Diagnostics.TraverseRoot глобально лочится и проверяет на повторное вхождение чтоб в один момент времени был активен только один обход.

Если нужно выполнить какое-то обобщённое действие, единственное что нужно, так это добавить в процедуру Traverse аргумент - "визитёртку". Мне он не нужен был.

Автор:  Иван Кузьмицкий [ Суббота, 05 Март, 2011 08:15 ]
Заголовок сообщения:  Re: Что это за сообщение - Views.UpdateCachesMsg?

Сергей, не могли бы Вы пару слов сказать про эпохи? Ну так, в общем. Это ведь та самая era, да?

Автор:  Info21 [ Суббота, 05 Март, 2011 10:59 ]
Заголовок сообщения:  Re: Обход Store'ов из одного Domain'а

Коллеги, кто помнит, где было про то, как Store'ы в домене друг друга не знают (кажется, Александр Сергеевич высказывался), сообщите модераторам, чтобы перенести сюда.

Автор:  Александр Ильин [ Суббота, 05 Март, 2011 12:18 ]
Заголовок сообщения:  Re: Обход Store'ов из одного Domain'а

Info21 писал(а):
Коллеги, кто помнит, где было про то, как Store'ы в домене друг друга не знают (кажется, Александр Сергеевич высказывался), сообщите модераторам, чтобы перенести сюда.
В этой теме: viewtopic.php?f=16&t=3296
модератор: перенесено

Автор:  Сергей Губанов [ Суббота, 05 Март, 2011 12:37 ]
Заголовок сообщения:  Re: Что это за сообщение - Views.UpdateCachesMsg?

Иван Кузьмицкий писал(а):
Сергей, не могли бы Вы пару слов сказать про эпохи? Ну так, в общем. Это ведь та самая era, да?
Не совсем та самая (я на C#), но так же целое число.

Папа всех диагностируемых объектов (поле nextDiagnosticsObject - для временного образования очереди (точнее стэка) во время обхода):
Код:
public static partial class Diagnostics
{
   public abstract class Object
   {
      internal readonly Type diagnosticsType;
      internal int currentDiagnosticsEra;
      internal Object nextDiagnosticsObject;

      public Type DiagnosticsType { get { return this.diagnosticsType; } }

      public Object ()
      {
         lock (synchRoot)
         {
            this.diagnosticsType = ...
         }
      }

      protected internal virtual void Traverse ()
      {
      }
   }
}
Принципиальная схема механизма:
Код:
public static partial class Diagnostics
{
   private static readonly object synchRoot = new object();
   private static int traverseEra;
   private static Object traverseFirst;
   private static System.Threading.Thread traverseThread;

   public static void Traverse (Object obj)
   {
      if ((obj != null) && (obj.currentDiagnosticsEra != traverseEra) && (traverseThread == System.Threading.Thread.CurrentThread))
      {
         obj.currentDiagnosticsEra = traverseEra;
         obj.nextDiagnosticsObject = traverseFirst;
         traverseFirst = obj;
      }
   }

   public static void TraverseRoot (Object root)
   {
      ...
      traverseEra++;
      if (traverseEra == 0) { traverseEra = 1; }
      root.currentDiagnosticsEra = traverseEra;
      traverseFirst = root;
      traverseThread = System.Threading.Thread.CurrentThread;
      while (traverseFirst != null)
      {
         Object obj = traverseFirst;
         traverseFirst = traverseFirst.nextDiagnosticsObject;
         obj.nextDiagnosticsObject = null;
         obj.Traverse();
         ...
      }
      ...
   }
}
Пример:
Код:
public class Node: Diagnostics.Object
{
   private Node left;
   private Node right;
                  
   protected override void Traverse ()
   {
      Diagnostics.Traverse(this.left);
      Diagnostics.Traverse(this.right);
   }
}

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