Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Дмитрий Загорулькин от 04-12-2013, 15:09:24

Название: Обработка объекта (примитива) по событию его модификации.
Отправлено: Дмитрий Загорулькин от 04-12-2013, 15:09:24
Добрый день!
Есть необходимость пост-модификации объекта. То есть, пользователь редактирует объект, по окончании этого определяются его свойства. Проводится анализ. Если что-то не устраивает - объект автоматически корректируется.
Реализовал это так:
- подписался на событие модификации объекта базы данных (Autodesk.AutoCAD.DatabaseServices.Database.ObjectModified);
- обработчик события проверяет тип объекта и его характеристики, определяет необходимость пост-модификации;
- если объект нужно дообработать, вызываю его метод UpgradeOpen() и провожу необходимые изменения (без запуска дополнительной транзакции, т.к., как я понимаю, при модификации объекта она уже запущена системой).

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

Защита от этого с помощью try-catch помогает, но может есть более правильный подход для таких действий с объектами?
Название: Re: Обработка объекта (примитива) по событию его модификации.
Отправлено: Александр Ривилис от 04-12-2013, 15:27:27
Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
Название: Re: Обработка объекта (примитива) по событию его модификации.
Отправлено: xSAKABSx от 04-12-2013, 15:41:34
ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать
Название: Re: Обработка объекта (примитива) по событию его модификации.
Отправлено: Дмитрий Загорулькин от 04-12-2013, 15:51:23
Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
Если верить отладчику, то рекурсии не происходит. Была такая проблема, когда я запускал транзакцию в обработчике, Вы мне тогда на другом ресурсе подсказали, что я в рекурсию увожу этим. А если транзакцию не запускать, то повторного события модификации не происходит. Может быть, событие связано с запуском транзакции?
И задержек во времени при выполнении модификации нет никаких когда автокорректировка срабатывает.
Пока, наверное, оставлю так и понаблюдаю. Если будут проблемы - попробую тот вариант, что Вы предложили.
Название: Re: Обработка объекта (примитива) по событию его модификации.
Отправлено: Александр Ривилис от 05-12-2013, 01:35:28
- один раз было предупреждение "eWasOpenedForModify", почему - понять не успел, повторить не смог.
Наверное ты имел в виду eWasOpenForNotify

ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать
Это не поможет.