vl-cmdf, command, command-s и возвращаемые значения
Насколько я помню, в 2015 версии прошло такое очень интересное обновление.
Забудем про порядок выполнения command / command-s / vl-cmdf - сейчас разговор не об этом
Раньше command (и command-s тоже) возвращало nil независимо от того, была команда выполнена или отменена. vl-cmdf отличалась тем, что в случае успешного выполнения возвращала t, а если команда была прервана пользователем - nil.
Базируясь на этом, можно было спокойно анализировать - что сделал пользователь при выполнении лиспа, и строить дальнейшее поведение своей программы. Но в 2015 версии "лафа" кончилась: vl-cmdf возвращает t независимо ни от чего. То есть информативность функции потеряна (вопрос обсуждался на форуме adn-cis.
Захотелось мне все же сделать свой вызов команды. Да заодно и сделать выполнение "тихим". Вот что получилось:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | (defun _kpblc-cmd-silence (cmd / err sysvar res lastent) ;| * Выполнение команды в "скрытом" режиме * Параметры вызова: cmd исполняемая команда - строка или список * Возвращает t в случае успеха выполнения команды или nil в случае ошибки. * Примеры использования: (_kpblc-cmd-silence "_.regenall") (_kpblc-cmd-silence (list "_.wssave" (getvar "wscurrent") "_y")) (_kpblc-cmd-silence (list "_.circle" pause pause)) |; (if (not (member (type cmd) (list 'str 'list))) (princ (strcat "\nНевозможно выполнить команду " (vl-princ-to-string cmd) " : неопознанный тип")) (if (vl-catch-all-error-p (setq err (vl-catch-all-apply (function (lambda () (setq sysvar (vl-remove nil (mapcar (function (lambda (x / tmp) (if (setq tmp (getvar (car x))) (progn (setvar (car x) (cdr x)) (cons (car x) tmp)) ) ;_ end of if ) ;_ end of lambda ) ;_ end of function '(("sysmon" . 0) ("cmdecho" . 0) ("nomutt" . 1) ("menuecho" . 0)) ) ;_ end of mapcar ) ;_ end of vl-remove lastent (entlast) ) ;_ end of setq (if lastent (setq lastent (entget lastent '("*"))) ) ;_ end of if (cond ((= (type cmd) 'str) (vl-cmdf cmd)) ((= (type cmd) 'list) (apply (function and) (list (vl-cmdf (car cmd)) (apply (function vl-cmdf) (cdr cmd)))) ) ) ;_ end of cond (setq res (cond ((and (not lastent) (entlast)) t) ((not (entlast)) nil) (t (not (equal (entget (entlast) '("*")) lastent))) ) ;_ end of cond ) ;_ end of setq ) ;_ end of lambda ) ;_ end of function ) ;_ end of vl-catch-all-apply ) ;_ end of setq ) ;_ end of vl-catch-all-error-p (progn (setq res nil) (princ (cond ((= (type cmd) 'str) (strcat "\nОшибка выполнения команды " cmd)) ((= (type cmd) 'list) (strcat "\nОшибка выполнения последовательности команд " (strcat (car cmd) (apply (function strcat) (mapcar (function (lambda (x) (strcat " " (vl-princ-to-string x)))) (cdr cmd)) ) ;_ end of apply ) ;_ end of strcat ) ;_ end of strcat ) (t "\nОшибка выполнения команды: неопознанный тип команды") ) ;_ end of cond ) ;_ end of princ ) ;_ end of progn ) ;_ end of if ) ;_ end of if (foreach item sysvar (setvar (car item) (cdr item))) res ) ;_ end of defun |
Так как пользоваться функцией?
Невозможно выполнить команду nil : неопознанный типnil
Ну я же показал примеры вызова:
Отлично!
Прям как горячие пирожки из духовки - уже "запилил" в свой код!
Благодарю!
Тут есть одно "но": код будет обрабатывать только команды создания / модификации примитивов. Команды типа _.ucs, _pan, _zoom, _.pspace и т.п. - т.е. не вносящие изменений в БД чертежа - у меня будут возвращать nil. Но тут я уже ничего поделать не могу.
Можно, конечно, попытаться анализировать набор системных переменных, но я не могу сейчас его составить
Спасибо, взял на вооружение!