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


Комментарии

Есть 5 коммент. к “vl-cmdf, command, command-s и возвращаемые значения”
  1. Евгений пишет:

    Так как пользоваться функцией?

    1
    (_kpblc-cmd-silence (command "_.trim" (vlax-vla-object->ename c_v_line) "" 3_coord ""))

    Невозможно выполнить команду nil : неопознанный типnil

  2. Кулик Алексей aka kpblc пишет:

    Ну я же показал примеры вызова:

    1
    (_kpblc-cmd-silence (list "_.trim" (vlax-vla-object->ename c_v_line) "" 3_coord ""))
  3. Евгений пишет:

    Отлично!
    Прям как горячие пирожки из духовки - уже "запилил" в свой код!
    Благодарю!

  4. Кулик Алексей aka kpblc пишет:

    Тут есть одно "но": код будет обрабатывать только команды создания / модификации примитивов. Команды типа _.ucs, _pan, _zoom, _.pspace и т.п. - т.е. не вносящие изменений в БД чертежа - у меня будут возвращать nil. Но тут я уже ничего поделать не могу.
    Можно, конечно, попытаться анализировать набор системных переменных, но я не могу сейчас его составить :(

  5. Роман пишет:

    Спасибо, взял на вооружение!

Поделитесь своим мнением


Я не робот.