Реакторы базы данных чертежа

Поигрался тут с реакторами базы чертежа (это которые VLR-AcDb-*). Теоретически нужно было отслеживать появление, удаление и изменение примитива. На тестовом чертеже все было хорошо. А вот при нормальной эксплуатации начались дикие тормоза.

Понятно, что каждый реактор что-то там вызывал и делал. Но меня напрягло, что вызов выполнялся не раз и не два. Написал простенький код (для ради интересу добавил счетчики):

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
(vlr-acdb-reactor "pik-stat-acdb"
                  '((:vlr-objectappended . vlr-acdb-appended)
                    (:vlr-objecterased . vlr-acdb-erased)
                    (:vlr-objectmodified . vlr-acdb-modified)
                    (:vlr-objectreappended . vlr-acdb-reappended)
                    (:vlr-objectunappended . vlr-acdb-unappended)
                    (:vlr-objectunerased . vlr-acdb-unerased)
                    (:vlr-objectopenedformodify . vlr-acdb-openedformodify)
                    )
                  ) ;_ end of vlr-acdb-reactor

(setq append_count 0
      erased_count 0
      modified_count 0
      reappended_count 0
      unappended_count 0
      unerased_count 0
      openedformodify_count 0
      ) ;_ end of setq

(defun vlr-acdb-appended (react data)
  (fun-react-print (cadr data) "appended" (setq append_count (1+ append_count)))
  ) ;_ end of defun

(defun vlr-acdb-erased (react data)
  (fun-react-print (cadr data) "erased" (setq erased_count (1+ erased_count)))
  ) ;_ end of defun

(defun vlr-acdb-modified (react data)
  (fun-react-print (cadr data) "modified" (setq modified_count (1+ modified_count)))
  ) ;_ end of defun

(defun vlr-acdb-reappended (react data)
  (fun-react-print (cadr data) "reappended" (setq reappended_count (1+ reappended_count)))
  ) ;_ end of defun

(defun vlr-acdb-unappended (react data)
  (fun-react-print (cadr data) "unappended" (setq unappended_count (1+ unappended_count)))
  ) ;_ end of defun

(defun vlr-acdb-unerased (react data)
  (fun-react-print (cadr data) "unerased" (setq unerased_count (1+ unerased_count)))
  ) ;_ end of defun

(defun vlr-acdb-openedformodify (react data)
  (fun-react-print (cadr data)
                   "openedForModify"
                   (setq openedformodify_count (1+ openedformodify_count))
                   ) ;_ end of fun-react-print
  ) ;_ end of defun

(defun fun-react-print (ent message count)
  (princ (strcat "\nObject "
                 (cond ((cdr (assoc 5 (entget ent))))
                       (t "<no handle>")
                       ) ;_ end of cond
                 " "
                 message
                 ". Operation count : "
                 (vl-princ-to-string count)
                 ) ;_ end of strcat
         ) ;_ end of princ
  ) ;_ end of defun

Начинаю построение отрезка и...

Лог добавления отрезка
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
69
70
71
72
73
74
75
76
77
78
79
80
Command: _line
Specify first point:
Specify next point or [Undo]:
Object <no handle> openedForModify. Operation count : 1
Object <no handle> openedForModify. Operation count : 2
Object <no handle> openedForModify. Operation count : 3
Object <no handle> openedForModify. Operation count : 4
Object 27F appended. Operation count : 1
Object 27F modified. Operation count : 1
Object <no handle> openedForModify. Operation count : 5
Object <no handle> openedForModify. Operation count : 6
Object <no handle> appended. Operation count : 2
Object <no handle> modified. Operation count : 2
Object 27F modified. Operation count : 3
Object <no handle> openedForModify. Operation count : 7
Object <no handle> openedForModify. Operation count : 8
Object 281 appended. Operation count : 3
Object 281 modified. Operation count : 4
Object <no handle> openedForModify. Operation count : 9
Object <no handle> openedForModify. Operation count : 10
Object 283 appended. Operation count : 4
Object 283 modified. Operation count : 5
Object <no handle> openedForModify. Operation count : 11
Object 284 appended. Operation count : 5
Object 284 modified. Operation count : 6
Object 284 modified. Operation count : 7
Object <no handle> openedForModify. Operation count : 12
Object 285 appended. Operation count : 6
Object 285 modified. Operation count : 8
Object 285 modified. Operation count : 9
Object 282 appended. Operation count : 7
Object 282 modified. Operation count : 10
Object <no handle> openedForModify. Operation count : 13
Object <no handle> openedForModify. Operation count : 14
Object <no handle> openedForModify. Operation count : 15
Object 283 modified. Operation count : 11
Object <no handle> openedForModify. Operation count : 16
Object 283 modified. Operation count : 12
Object <no handle> openedForModify. Operation count : 17
Object <no handle> openedForModify. Operation count : 18
Object <no handle> erased. Operation count : 1
Object <no handle> openedForModify. Operation count : 19
Object <no handle> erased. Operation count : 2
Object <no handle> openedForModify. Operation count : 20
Object <no handle> erased. Operation count : 3
Object <no handle> openedForModify. Operation count : 21
Object 1F modified. Operation count : 13
Object <no handle> openedForModify. Operation count : 22
Object 286 appended. Operation count : 8
Object 286 modified. Operation count : 14
Object <no handle> openedForModify. Operation count : 23
Object 286 modified. Operation count : 15
Specify next point or [Undo]:
Object <no handle> openedForModify. Operation count : 24
Object <no handle> openedForModify. Operation count : 25
Object <no handle> openedForModify. Operation count : 26
Object <no handle> modified. Operation count : 16
Object <no handle> openedForModify. Operation count : 27
Object <no handle> unerased. Operation count : 1
Object <no handle> openedForModify. Operation count : 28
Object <no handle> modified. Operation count : 17
Object <no handle> openedForModify. Operation count : 29
Object 281 unerased. Operation count : 2
Object <no handle> openedForModify. Operation count : 30
Object <no handle> modified. Operation count : 18
Object <no handle> openedForModify. Operation count : 31
Object 282 unerased. Operation count : 3
Object <no handle> openedForModify. Operation count : 32
Object <no handle> openedForModify. Operation count : 33
Object <no handle> openedForModify. Operation count : 34
Object 283 modified. Operation count : 19
Object <no handle> openedForModify. Operation count : 35
Object 283 modified. Operation count : 20
Object <no handle> openedForModify. Operation count : 36
Object <no handle> openedForModify. Operation count : 37
Object <no handle> erased. Operation count : 4
Object <no handle> openedForModify. Operation count : 38
Object <no handle> erased. Operation count : 5
Object <no handle> openedForModify. Operation count : 39
Object <no handle> erased. Operation count : 6
Че, серьезно?!

1
2
3
4
5
6
7
APPEND_COUNT = 8
ERASED_COUNT = 6
MODIFIED_COUNT = 20
OPENEDFORMODIFY_COUNT = 39
REAPPENDED_COUNT = 0
UNAPPENDED_COUNT = 0
UNERASED_COUNT = 3

Ну-ка, а если слой создавать (счетчики сбрасываю):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Command: _.layer
Object 1FF modified. Operation count : 1
Command:
Object <no handle> openedForModify. Operation count : 1
Object <no handle> openedForModify. Operation count : 2
Object <no handle> openedForModify. Operation count : 3
Object 288 appended. Operation count : 1
Object 288 modified. Operation count : 2
Object <no handle> openedForModify. Operation count : 4
Object <no handle> openedForModify. Operation count : 5
Object 289 appended. Operation count : 2
Object 289 modified. Operation count : 3
Object <no handle> openedForModify. Operation count : 6
Object 287 appended. Operation count : 3
Object 287 modified. Operation count : 4
Command:
Object 287 openedForModify. Operation count : 7
Object 287 modified. Operation count : 5

И счетчики:

1
2
3
4
5
6
7
APPEND_COUNT = 3
ERASED_COUNT = 0
MODIFIED_COUNT = 5
OPENEDFORMODIFY_COUNT = 7
REAPPENDED_COUNT = 0
UNAPPENDED_COUNT = 0
UNERASED_COUNT = 0

В тестовом файле объект с хендлом "1FF" - словарь "ACAD_LAYERSTATUS"; "287" - создаваемый слой (я ему еще и цвет заодно поменял), "288" - приложение "AcAecLayerStandard" (что оно тут делает, не очень понял, ну да ладно).
Ну ок, что-то срабатывает при создании объектов (замечу, что и при удалении / восстановлении объектов все так же срабатывает). А вот теперь то, ради чего в общем-то весь сыр-бор и разгорелся: как насчет модификации свойств примитивов? Именно свойств, т.к. перенос примитивов, их поворот, добавление / удаление вершин в полилинии срабатывает "на ура".

Меняем слой отрезка - и в консоли тишина. Тип линии, вес линии, цвет - все мимо! Ну ок, убираю вывод в консоль, заменяю на хранение в списке. И вот там уже видно, что происходит, например, при смене слоя:

Обновленный код
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
(vlr-acdb-reactor "pik-stat-acdb"
                  '((:vlr-objectappended . vlr-acdb-appended)
                    (:vlr-objecterased . vlr-acdb-erased)
                    (:vlr-objectmodified . vlr-acdb-modified)
                    (:vlr-objectreappended . vlr-acdb-reappended)
                    (:vlr-objectunappended . vlr-acdb-unappended)
                    (:vlr-objectunerased . vlr-acdb-unerased)
                    (:vlr-objectopenedformodify . vlr-acdb-openedformodify)
                    )
                  ) ;_ end of vlr-acdb-reactor

(setq append_count 0
      erased_count 0
      modified_count 0
      reappended_count 0
      unappended_count 0
      unerased_count 0
      openedformodify_count 0
      oper_list nil
      ) ;_ end of setq

(defun vlr-acdb-appended (react data)
  (fun-react-print (cadr data) "appended" (setq append_count (1+ append_count)))
  ) ;_ end of defun

(defun vlr-acdb-erased (react data)
  (fun-react-print (cadr data) "erased" (setq erased_count (1+ erased_count)))
  ) ;_ end of defun

(defun vlr-acdb-modified (react data)
  (fun-react-print (cadr data) "modified" (setq modified_count (1+ modified_count)))
  ) ;_ end of defun

(defun vlr-acdb-reappended (react data)
  (fun-react-print (cadr data) "reappended" (setq reappended_count (1+ reappended_count)))
  ) ;_ end of defun

(defun vlr-acdb-unappended (react data)
  (fun-react-print (cadr data) "unappended" (setq unappended_count (1+ unappended_count)))
  ) ;_ end of defun

(defun vlr-acdb-unerased (react data)
  (fun-react-print (cadr data) "unerased" (setq unerased_count (1+ unerased_count)))
  ) ;_ end of defun

(defun vlr-acdb-openedformodify (react data)
  (fun-react-print (cadr data)
                   "openedForModify"
                   (setq openedformodify_count (1+ openedformodify_count))
                   ) ;_ end of fun-react-print
  ) ;_ end of defun

(defun fun-react-print (ent message count)
  (setq oper_list (cons (list (cond ((cdr (assoc 5 (entget ent))))
                                    (t "<no handle>")
                                    ) ;_ end of cond
                              message
                              count
                              ) ;_ end of list
                        oper_list
                        ) ;_ end of cons
        ) ;_ end of setq
  ) ;_ end of defun
1
2
3
4
5
6
7
8
9
10
11
'(("27F" "modified" 5)
  ("<no handle>" "openedForModify" 5)
  ("<no handle>" "modified" 4)
  ("<no handle>" "openedForModify" 4)
  ("<no handle>" "modified" 3)
  ("<no handle>" "openedForModify" 3)
  ("27F" "modified" 2)
  ("<no handle>" "openedForModify" 2)
  ("27F" "modified" 1)
  ("<no handle>" "openedForModify" 1)
  )

К сожалению, пришлось перезапускать ACAD, поэтому хендлы не совпадают.

Тем не менее, некоторые выводы уже можно попытаться сделать: реакторы базы чертежа как-то слишком глубоко копаются, и, прежде чем их начинать применять, крайне желательно не наступить на мои грабли и сначала узнать, кто из наиболее часто вызывается и наименее необходим.

Пока что всерьез думаю отказаться от их использования и обойтись старыми привычными реакторами на команды и системные переменные...



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


Я не робот.