Обработка объекта (примитива) по событию его модификации.

Автор Тема: Обработка объекта (примитива) по событию его модификации.  (Прочитано 6989 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Добрый день!
Есть необходимость пост-модификации объекта. То есть, пользователь редактирует объект, по окончании этого определяются его свойства. Проводится анализ. Если что-то не устраивает - объект автоматически корректируется.
Реализовал это так:
- подписался на событие модификации объекта базы данных (Autodesk.AutoCAD.DatabaseServices.Database.ObjectModified);
- обработчик события проверяет тип объекта и его характеристики, определяет необходимость пост-модификации;
- если объект нужно дообработать, вызываю его метод UpgradeOpen() и провожу необходимые изменения (без запуска дополнительной транзакции, т.к., как я понимаю, при модификации объекта она уже запущена системой).

Это работает как надо, но есть смущающие моменты:
- если отменять действия вызовом стандартной команды UNDO, то возникает исключение из-за того, что "eWasOpenedForUndo".
- один раз было предупреждение "eWasOpenedForModify", почему - понять не успел, повторить не смог.

Защита от этого с помощью try-catch помогает, но может есть более правильный подход для таких действий с объектами?

Отмечено как Решение Дмитрий Загорулькин 25-01-2019, 15:23:19

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн xSAKABSx

  • ADN Club
  • Сообщений: 36
  • Карма: 1
ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
Если верить отладчику, то рекурсии не происходит. Была такая проблема, когда я запускал транзакцию в обработчике, Вы мне тогда на другом ресурсе подсказали, что я в рекурсию увожу этим. А если транзакцию не запускать, то повторного события модификации не происходит. Может быть, событие связано с запуском транзакции?
И задержек во времени при выполнении модификации нет никаких когда автокорректировка срабатывает.
Пока, наверное, оставлю так и понаблюдаю. Если будут проблемы - попробую тот вариант, что Вы предложили.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
- один раз было предупреждение "eWasOpenedForModify", почему - понять не успел, повторить не смог.
Наверное ты имел в виду eWasOpenForNotify

ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать
Это не поможет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение