AfraLisp Blog

The AutoLisp/Visual Lisp/VBA Resource Website

AfraLisp Blog

Home Newsletter Utter Rubbish Coding Tips AutoCAD Tips Contact Downloads WAUN

Home. Page I. Page II.

Reactors - Page III

Object Reactors, or "VLR-Object-Reactor", fall under general reactor types. They are almost identical in functionality to Drawing and Command reactors except for a couple of things! They need to include a reference to the Object that will be reacted upon, (Crikey, that sounds terrible!!) and the reference to the Object needs to be created before the reactor is called. Let's have a look at the syntax of an Object reactor :

(vlr-object-reactor owners data callback)

The "data" and "callback" arguments, we are familiar with. But what is the "owner" argument? This is an AutoLisp list of Visual Lisp Objects identifying the drawing Objects to be watched. In other words, a reference to the Object that contains the reactor.
The reactor event we are going to use is the ":vlr-modified event", and our Callback function will be named "print-length".
Have a look at the coding for our reactor :

(vlr-object-reactor (list myLine) "Line Reactor" '((:vlr-modified . print-length)))

As I mentioned earlier though, we need to have a reference to the Object before we can call this statement. Consider the following :

(vl-load-com)

;*************

(defun line-draw ()

(setq acadDocument (vla-get-activedocument (vlax-get-acad-object)))

(setq mspace (vla-get-modelspace acadDocument))

(setq apt (getpoint "Specify First Point: "))

(setq pt (getpoint "Specify next point: " apt))

(setq myLine (vla-addline mspace (vlax-3d-point apt)(vlax-3d-point pt)))

(setq lineReactor (vlr-object-reactor (list myLine)
"Line Reactor" '((:vlr-modified . print-length))))

(princ)

);defun

We started off by drawing a line. As the line was created from scratch, and created using Visual Lisp functions, we already have a reference to the line Object. (myLine). We can now safely run our reactor function and attach it to our Line.
"But where is the Callback function?"
Hah, I was waiting for that. We've made the Callback function a separate function for one main reason. If we didn't, every time we ran the application it would prompt us to draw a new line. So, what we have to do now, is link the reactor function to our Callback function so that when our line is modified, only the Callback function is put into motion. The reactor sends three arguments to the Callback function, the notifier-object (our line), the reactor-object (:vlr-modified), and the event parameter-list which in this case is nil.

Here's the coding for the Callback function :

(defun print-length (notifier-object reactor-object parameter-list)

(cond
	((vlax-property-available-p notifier-object "Length")
	 (alert (strcat "The length is now "
                        (rtos (vla-get-length notifier-object)))))
);cond

(princ)

);defun

(princ)

Copy all of this coding into one file and save it as "Line-Draw.Lsp". Now load "Line-Draw.Lsp" and then run (line-draw). Draw a single line when prompted. Now stretch the line so that it's length changes. A dialog will appear displaying the new length of the line :

In essence, this is what happened :

  • We loaded "Line-draw.Lsp" and all functions contained within were placed into memory.
  • We ran (line-draw) which prompted us to draw a line. The reactor was then loaded and linked to both the line Object and the Callback function.
  • As the Callback function "print-length" was also loaded into memory, every time we modify the line Object, the Callback function is processed and the length of the line is displayed.

Did you notice how we checked that our Object had a "Length" Property before continuing? Good idea, as this validation can save lot's of problems.


"But what happens when I close my drawing? Will I lose all my reactors?"
Good questions. Reactors can be transient or persistent. Transient reactors are lost when the drawing closes and this is the default reactor mode. Persistent reactors are saved with the drawing and exist when the drawing is next open.

You can use the "vlr-pers" function to make a reaction persistent. To remove a persistence from a reactor and make it transient, use the "vlr-pers-release" function. To determine whether a reactor is persistent or transient, use the "vlr-pers-p" function. Each function takes the reactor Object as it's only argument :

_$(vlr-pers lineReactor)
#<VLR-Object-Reactor>

If successful "vlr-pers" returns the specified reactor Object.

Note : A reactor is only a link between an event and a Callback function. The Callback function is not part of the reactor, and is normally not part of the drawing. The reactors saved in the drawing are only usable if their associated Callback functions are loaded in AutoCAD.
In other words, if we made our reactor "lineReactor" persistent, we would have to ensure that the Callback function "print-length" was loaded every time the drawing containing our lines with reactors was opened.


If you would like the source coding for all the example in this tutorial, then you can download them from here.     



Home. Page I. Page II.
 
The AutoLisp/Visual Lisp/VBA Resource Website

Copyright 1999-Perpetuity by AfraLisp

All rights reserved.
Information in this document is subject to change without notice.
Site created and maintained by Kenny Ramage

The AutoLisp/Visual Lisp/VBA Resource Website