Метки начала и конца отмены
Почитав про транзакции в .NET, задумался: а если в лиспе сделать вложенные метки начала / конца отмены? А заодно и доказать утвержение в статье Ошибка отмены в AutoCAD о нежелательности вложенных отмен.
Отлично, попробуем. ACAD2016x64Eng, все обновления. Создаем несложный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object))) (defun t1 () (vla-startundomark adoc) (entmakex (list (cons 0 "LINE") (cons 10 '(0. 0. 0.)) (cons 11 '(10. 0. 0.)) (cons 62 1))) (t2) (entmakex (list (cons 0 "LINE") (cons 10 '(0. 20. 0.)) (cons 11 '(10. 20. 0.)) (cons 62 3))) (vla-endundomark adoc) (princ) ) ;_ end of defun (defun t2 () (vla-startundomark adoc) (entmakex (list (cons 0 "LINE") (cons 10 '(0. 10. 0.)) (cons 11 '(10. 10. 0.)) (cons 62 2))) (vla-endundomark adoc) (princ) ) ;_ end of defun |
Естественно, вызываем (t1). Естественно, создается три отрезка. А что будет при нажатии Ctrl+Z? Теоретически отмениться должно сразу все: у нас получается одна "внешняя" отмена (сформирована в t1), и одна "внутренняя", или "вложенная" (сделана в t2):
1. | Начало t1 | |
2. | Начало t2 | |
3. | Конец t2 | |
4. | Конец t1 |
При отмене выполненных действий, казалось бы, должна сработать отмена, сделанная только в t1 (все действия, описанные между шагами 1 и 4). Но, к сожалению, это не так: отменяется все, что описано между последними метками начала и конца, т.е. между шагами 2 и 4. При этом метка начала отмены все еще болтается в памяти.
При этом метод установки метки отмены (командный или vla-) не играет никакой роли, ситуация не меняется.
Поэтому при написании кодов не стоит злоупотреблять метками отмены, проставляемыми бессистемно.