Jump to content

Two reactor issues: missing callback & open for undo


JackStone

Recommended Posts

Hello, my friends.

 

I needed to link the contents of a text to the text override in a dimension. At first I hoped I would be able to do this using fields and DIESEL, but that turned out not to work because I only wanted to copy part of the text to the dimension. Here is an example.

 

image.png.c4c0f520c84449351a784217c0f2589b.png

 

A field would copy the whole green text to the dimension, and that's not what I want. Using DIESEL looks possible (you can wrap a substr DIESEL expression around a field code), but in the end it didn't work because the field code was being immediately evaluated to a string inside the DIESEL expression, so any link to the (green) object was lost right away.

 

So I had to resort to reactors, something I had read about but had never quite used before. I set up a :vlr-modified reactor with the green text as owner and the white dimension as data. I set this reactor to be persistent, as this link needs to continue existing when the drawing is reopened. This is a simplified version of my code:

 

(defun c:testfun  (/
                   reactor)
  (setq reactor (vlr-object-reactor (list rebarText) (list dimension) '((:vlr-modified . &callback))))
  (vlr-pers reactor))


(defun &callback  (#owner
                   #reactor
                   #args
                   /
                   string
                   dimension)
  (setq string    (string-before "%%C" #owner)
        dimension (car (vlr-data #reactor)))
  (copy-rebar-reference string dimension))


(defun copy-rebar-reference  (#string
                              #dimension
                              /
                              refString
                              objName)
  (if (and (objectp #dimension) (not (vlax-erased-p #dimension)))
    (vla-put-textOverride #dimension #string)))

 

There are two issues I need to solve:

 

1. Missing callback function. The drawing containing these reactors will be opened in computers that do not have the LISP code above, most notably they lack the &callback definition. These other computers will not need to use or create a new reactor (they'll just be working on different entities in the drawing), but it would be really good if I could avoid having error messages (i.e. "no function definition: &callback") being spammed in their command line as they edit the drawing. These messages become quite untenable when there are many reactors defined. Is there any way around this?

 

2. "Open for undo" error. Sometimes the green text (source) is actually a multileader. When that is the case an error message saying "Automation Error. Object was open for undo" is displayed when I save the drawing (QSAVE). Why does this happen? Is there any way around this? Each reactor defined using a multileader issues this message, so this also reaches an absurd level of command line spam when many reactors are created.

 

 

I thank you all in advance for the generous help you offer on these Forums. I'm very much open to suggestions that migth go beyond my two questions, since, as I said at the beginning, I'm not at all an expert when it comes to using reactors, so I may be making many mistakes.

 

Best regards,

Jack

 

 

Link to comment
Share on other sites

 

1. First off, when a reactor is triggered, it needs to call a function to execute a series of operation. The function needs to be defined and loaded into the drawing from AutoLISP. So if the other computers don't load the above routine, then the callback function will never be defined and the reactor won't succeed (which will then result in something that you expect would happen, but didn't happen due to an error).

 

         - I would suspect that your colleagues will normally be stretching or modifying properties, but you'll notice that the white dimension will not update when the green one changes (doing it on the other computers that lacks the callback function).

 

2. When doing any sort of certain action in AutoCAD, several reactors are fired even through the simplest of events. That's why the data to the reactor is very important to negate any side effects. If you'd like to trace out the reactors that's called after every action taken in AutoCAD (be it a mouse click, LISP, resizing a window, etc...), you can do it through this:

 

(defun c:traceon ( / xr)
    (foreach x (vlr-types)
	(if (not (vl-some '(lambda (a) (eq (vlr-data a) "Tracing")) (cdar (VLR-reactors x))))
	    (progn
		(setq xr ((eval (read (substr (vl-princ-to-string x) 2)))))
		(vlr-data-set xr "Tracing")
		(foreach x (VLR-Reaction-Names xr) (VLR-Reaction-Set xr x 'VLR-trace-reaction))
		)
	    )
	)
    (princ)
    )

(defun c:traceoff nil
    (foreach x (vlr-reactors)
	(vl-some
	    '(lambda (a)
		 (if (eq (vlr-data a) "Tracing")
		     (progn (vlr-remove a) t)
		     )
		 )
	    (cdr x)
	    )
	)
    (princ)
    )

 

You can use the TRACEON command to set tracing reaction, and then use the TRACEOFF command to remove tracing.

 

Run the test command, save a file, and then go back to LISP, and go to the trace window:

 

 

image.png.607b07d25c6b83703024f5dccf92f5d6.png

 

 

 

 You'll see the type of reactors fired:

 

:VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001bacf3adad8> 2 64 2 "QSAVE"))
:VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001bacf3adad8> 2 64 64 "QSAVE"))
:VLR-commandWillStart; argument list: (#<VLR-Editor-Reactor> ("QSAVE"))
:VLR-commandWillStart; argument list: (#<VLR-Command-Reactor> ("QSAVE"))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69900>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69900>))
:VLR-beginSave; argument list: (#<VLR-Editor-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> "C:\\Users\\ASUS\\OneDrive\\Desktop\\Test.dwg"))
:VLR-beginSave; argument list: (#<VLR-DWG-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> "C:\\Users\\ASUS\\OneDrive\\Desktop\\Test.dwg"))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc699f0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69da0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc699f0>))
:VLR-sysVarWillChange; argument list: (#<VLR-Editor-Reactor> ("NAVBARDISPLAY"))
:VLR-sysVarWillChange; argument list: (#<VLR-SysVar-Reactor> ("NAVBARDISPLAY"))
:VLR-sysVarChanged; argument list: (#<VLR-Editor-Reactor> ("NAVBARDISPLAY" T))
:VLR-sysVarChanged; argument list: (#<VLR-SysVar-Reactor> ("NAVBARDISPLAY" T))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69a20>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69a20>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69860>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62df0>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62df0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62df0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62df0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62df0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62900>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62900>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e10>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e10>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e10>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e10>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e20>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e20>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e20>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e10>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e30>))
:VLR-objectAppended; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e30>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e30>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69a20>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69a20>))
:VLR-sysVarWillChange; argument list: (#<VLR-Editor-Reactor> ("CLAYER"))
:VLR-sysVarWillChange; argument list: (#<VLR-SysVar-Reactor> ("CLAYER"))
:VLR-sysVarChanged; argument list: (#<VLR-Editor-Reactor> ("CLAYER" T))
:VLR-sysVarChanged; argument list: (#<VLR-SysVar-Reactor> ("CLAYER" T))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62900>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62900>))
:VLR-objectErased; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e00>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e30>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62e30>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62de0>))
:VLR-objectErased; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc62dd0>))
:VLR-sysVarWillChange; argument list: (#<VLR-Editor-Reactor> ("NAVBARDISPLAY"))
:VLR-sysVarWillChange; argument list: (#<VLR-SysVar-Reactor> ("NAVBARDISPLAY"))
:VLR-sysVarChanged; argument list: (#<VLR-Editor-Reactor> ("NAVBARDISPLAY" T))
:VLR-sysVarChanged; argument list: (#<VLR-SysVar-Reactor> ("NAVBARDISPLAY" T))
:VLR-undoSubcommandControl; argument list: (#<VLR-Undo-Reactor> (4 2))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69a20>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> <Entity name: 1badfc69ea0>))
:VLR-undoSubcommandControl; argument list: (#<VLR-Undo-Reactor> (4 2))
:VLR-saveComplete; argument list: (#<VLR-Editor-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> "C:\\Users\\ASUS\\OneDrive\\Desktop\\Test.dwg"))
:VLR-saveComplete; argument list: (#<VLR-DWG-Reactor> (#<VLA-OBJECT IAcadDatabase 000001baf0fce5d8> "C:\\Users\\ASUS\\OneDrive\\Desktop\\Test.dwg"))
:VLR-commandEnded; argument list: (#<VLR-Editor-Reactor> ("QSAVE"))
:VLR-commandEnded; argument list: (#<VLR-Command-Reactor> ("QSAVE"))
:VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001bacf3adad8> 64 2 64 "#QSAVE"))
:VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001bacf3adad8> 64 2 2 "#QSAVE"))

 

Now my list may be different to yours because you might have more reactors in your drawing than mine.  But if somewhere along the lines you see a :VLR-Modified that links to your callback function whilst an object is "Modified" inside an Undo, then you'll get your described error, because when undoing, you cannot modify any of the properties until the undo is done.

 

Hopefully it's of a clear explanation.

 

 

Do send a sample file, I will try to help you out.

Edited by Jonathan Handojo
Link to comment
Share on other sites

Hello, Jonathan! Thank you very much for the reply!

 

I did the following:

0. Opened VLIDE

1. Deleted all reactors from my drawing

2. Created a single reactor (using my "test" function)

3. Loaded your code (TRACEON, TRACEOFF)

4. Ran the command "TRACEON"

5. Ran quick save (QS)

 

Then AutoCAD immediately got stuck in an infinite loop, repeating the same messages over and over again on the trace window. Here is a segment of such spam:
 

[...]

; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca600>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca640>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca640>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca680>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca680>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca6c0>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca6c0>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca700>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca700>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca740>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca740>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca800>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca800>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca840>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 0000021e10942c08> <Entity name: 7ff4343ca840>))

[...]

 

Clearly I must be doing something wrong here! Since you so generously offered to take a look at an example, here is my actual source code (I removed non-essential things to shorten it):

 

;; MAIN FUNCTION: call from command line to create reactor
(defun c:CRF  (/
               text                     ; VLA-object: text, multiline text, or multileader
               dim                      ; VLA-object: dimension
               reactor
               *error*)

  (defun *error*  (msg)
    (princ))

  (setq text    (vlax-ename->vla-object (car (entsel))) ; user must select TEXT, MTEXT, or MULTILEADER
        dim     (vlax-ename->vla-object (car (entsel))) ; user must select DIMENSION
        reactor (vlr-object-reactor (list text) (list dim) '((:vlr-modified . &update-rebar-reference))))
  (vlr-pers reactor)
  (copy-rebar-reference text dim)
  (princ))


;; CALLBACK FUNCTION: referenced in reactor
(defun &update-rebar-reference  (#rebarTxtObject
                                 #reactorObject
                                 #parameterList
                                 /
                                 rebarRef
                                 updatedObjects
                                 counter
                                 *error*)

  (defun *error*  (msg)
    (princ))

  (setq rebarRef       (substr (vla-get-textstring #rebarTxtObject)
                               1
                               (vl-string-search "%%C" (vla-get-textstring #rebarTxtObject)))
        updatedObjects (vlr-data #reactorObject)
        counter        0)
  (foreach @object  updatedObjects
    (if (copy-rebar-reference rebarRef @object)
      (setq counter (1+ counter))))
  (princ (strcat "\nREACTOR: " (itoa counter) " objects modified."))
  (princ))


;; ADDITIONAL SUBROUTINE: copies portion of the text from #Source to #Target
(defun copy-rebar-reference  (#Source
                              #Target
                              /
                              objString
                              refString
                              objName)
  (if (= 'VLA-OBJECT (type #Source))
    (progn
      (setq objString (strcase (vla-get-textstring #Source))
            refString (substr objString 1 (vl-string-search "%%C" objString))))
    (setq refString #Source))
  (if (and (objectp #Target) (not (vlax-erased-p #Target)))
    (progn
      (setq objName (strcase (vla-get-objectName #Target)))
      (if (vl-string-search "DIMENSION" objName)
        (progn (vla-put-textOverride #Target refString) T)))))

 

I am also attaching an example drawing, a very stripped down one. If you create a reactor (my c:CRF command) using the TEXT object (layer "03") there is no error message when saving the drawing, but if you use the MULTILEADER object (layer "01") as reactor owner the error appears when issuing QSAVE.

 

 

And again I thank you very much for your assistance!

example_rebar_reactor.dwg

Link to comment
Share on other sites

That spam is because it needs to assess every single drawing in the document for saving. (Or so I think)

 

But I'm not too sure though, because it shouldn't fire your modified function.

 

Try using the following:

 

(defun c:crf ( / *error* activeundo acadobj adoc msp dim hnd txt)
    (defun *error* ( msg )
	(vla-EndUndoMark adoc)
	(if (not (wcmatch (strcase msg T) "*break*,*cancel*,*exit*"))
	    (princ (strcat "Error: " msg))
	    )
	)
    (setq acadobj (vlax-get-acad-object)
	  adoc (vla-get-ActiveDocument acadobj)
	  msp (vla-get-ModelSpace adoc)
	  activeundo nil)
    (if (= 0 (logand 8 (getvar "UNDOCTL"))) (vla-StartUndoMark adoc) (setq activeundo T))
    
    (and
	(setq txt (CRF:GetEntity "\nSelect source text or multileader <exit>: " '("TEXT" "MTEXT" "MULTILEADER")))
	(setq dim (CRF:GetEntity "\nSelect destination dimension <exit>: " '("DIMENSION")))
	(progn
	    (setq hnd (vla-get-ObjectID txt))
	    (if (not
		    (vl-some
			(function
			    (lambda (a / hndd)
				(and
				    (eq (VLR-Data a) hnd)
				    (setq hndd (vla-get-ObjectID dim))
				    (cond
					((vl-some '(lambda (b) (eq (vla-get-ObjectID b) hndd)) (VLR-Owners a)))
					((VLR-Owner-Add a dim))
					)
				    )
				)
			    )
			(cdar (vlr-reactors :VLR-Object-Reactor))
			)
		    )
		(VLR-Object-Reactor (list txt dim) hnd
		    '(
		      (:VLR-modified . CRF:Modified)
		      ;(:VLR-modified . VLR-trace-reaction)
		      (:VLR-erased . CRF:Erased)
		      ;(:VLR-erased . VLR-trace-reaction)
		      (:VLR-unerased . CRF:Unerased)
		      ;(:VLR-unerased . VLR-trace-reaction)
		      )
		    )
		)
	    (if (not
		    (vl-some
			(function
			    (lambda (a)
				(eq (VLR-Data a) "*CRF*")
				)
			    )
			(cdar (vlr-reactors :VLR-Command-Reactor))
			)
		    )
		(VLR-Command-Reactor "*CRF*"
		    '(
		      (:VLR-commandWillStart . CRF:StartUndo)
		      ;(:VLR-commandWillStart . VLR-trace-reaction)
		      (:VLR-commandFailed . CRF:EndUndo)
		      ;(:VLR-commandFailed . VLR-trace-reaction)
		      (:VLR-commandEnded . CRF:EndUndo)
		      ;(:VLR-commandEnded . VLR-trace-reaction)
		      (:VLR-commandCancelled . CRF:EndUndo)
		      ;(:VLR-commandCancelled . VLR-trace-reaction)
		      )
		    )
		)
	    )
	)
    
    (if activeundo nil (vla-EndUndoMark adoc))
    (princ)
    )

(defun CRF:Modified (obj rct lst / dim str)
    (and
	(not *CRF_undo*)
	(not (vlax-erased-p obj))
	(setq dim (vl-remove-if-not '(lambda (a) (and (not (vlax-erased-p a)) (vlax-write-enabled-p a) (wcmatch (vla-get-ObjectName a) "AcDb*Dimension"))) (VLR-Owners rct)))
	(member (vla-get-ObjectName obj) '("AcDbText" "AcDbMText" "AcDbMLeader"))
	(setq str (vla-get-TextString obj))
	(foreach x dim
	    (vla-put-TextOverride x
		
		; String to update on dimension right here
		; str - text string of original source
		
		(substr str 1 (cond ((vl-string-search "%%C" str)) ((strlen str))))
		
		)
	    )
	)
    )

(defun CRF:StartUndo (rct lst)
    (if
	(and
	    (eq (VLR-Data rct) "*CRF*")
	    (member (strcase (car lst)) '("U" "UNDO" "REDO" "MREDO"))
	    )
	(setq *CRF_undo* t)
	)
    )

(defun CRF:EndUndo (rct lst)
    (if
	(and
	    (eq (VLR-Data rct) "*CRF*")
	    (member (strcase (car lst)) '("U" "UNDO" "REDO" "MREDO"))
	    )
	(setq *CRF_undo* nil)
	)
    )

(defun CRF:Erased (obj rct lst)
    (if (eq (vla-get-ObjectID obj) (VLR-Data rct))
	(VLR-Remove rct)
	(VLR-Owner-Remove rct obj)
	)
    )

(defun CRF:Unerased (obj rct lst)
    (if (eq (vla-get-ObjectID obj) (VLR-Data rct))
	(and (not (VLR-added-p rct)) (VLR-Add rct))
	(VLR-Owner-Add rct obj)
	)
    )

(defun CRF:GetEntity (msg typ / ent)
    (while
	(progn
	    (setvar 'errno 0)
	    (setq ent (entsel msg))
	    (cond
		((= (getvar 'errno) 7) (princ "\nNothing selected"))
		((not (setq ent (car ent))) nil)
		((not
		     (vl-some
			 '(lambda (a)
			      (eq (cdr (assoc 0 (entget ent))) a)
			      )
			 typ
			 )
		     )
		 (princ "\nInvalid object")
		 )
		((not (setq ent (vlax-ename->vla-object ent))))
		)
	    )
	)
    ent
    )

(vl-load-com)

 

I've commented out the tracing for the event callbacks. With TRACEON on (and the above trace enabled), simply erasing an object yieds:

 

; Reaction: :VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 2 4 2 "ERASE"))
; Reaction: :VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 2 4 4 "ERASE"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Command-Reactor> ("ERASE"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Editor-Reactor> ("ERASE"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Command-Reactor> ("ERASE"))
; Reaction: :VLR-pickfirstModified; argument list: (#<VLR-Miscellaneous-Reactor> nil)
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d025d0>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-erased; argument list: (#<VLA-OBJECT IAcadDimRotated 00000197a29f3f78> #<VLR-Object-Reactor> nil)
; Reaction: :VLR-modified; argument list: (#<VLA-OBJECT IAcadDimRotated 00000197a29f3f78> #<VLR-Object-Reactor> nil)
; Reaction: :VLR-objectErased; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d025d0>))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Command-Reactor> ("ERASE"))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Editor-Reactor> ("ERASE"))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Command-Reactor> ("ERASE"))
; Reaction: :VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 4 2 4 "#ERASE"))
; Reaction: :VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 4 2 2 "#ERASE"))

And you can see that it fires the :vlr-modified event

 

And undoing yieds:

 

; Reaction: :VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 2 4 2 "U"))
; Reaction: :VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 2 4 4 "U"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Command-Reactor> ("U"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Editor-Reactor> ("U"))
; Reaction: :VLR-commandWillStart; argument list: (#<VLR-Command-Reactor> ("U"))
; Reaction: :VLR-undoSubcommandNumber; argument list: (#<VLR-Undo-Reactor> (0 1))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d025d0>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-unerased; argument list: (#<VLA-OBJECT IAcadDimRotated 00000197a29f3f78> #<VLR-Object-Reactor> nil)
; Reaction: :VLR-modified; argument list: (#<VLA-OBJECT IAcadDimRotated 00000197a29f3f78> #<VLR-Object-Reactor> nil)
; Reaction: :VLR-objectUnErased; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d025d0>))
; Reaction: :VLR-objectOpenedForModify; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-objectModified; argument list: (#<VLR-AcDb-Reactor> (#<VLA-OBJECT IAcadDatabase 000001979c36b218> <Entity name: 19764d024f0>))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Command-Reactor> ("U"))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Editor-Reactor> ("U"))
; Reaction: :VLR-commandEnded; argument list: (#<VLR-Command-Reactor> ("U"))
; Reaction: :VLR-documentLockModeWillChange; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 4 2 4 "#U"))
; Reaction: :VLR-documentLockModeChanged; argument list: (#<VLR-DocManager-Reactor> (#<VLA-OBJECT IAcadDocument 000001976e4fce58> 4 2 2 "#U"))

 

You can make the reactors persistent if you wish to do so.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...