Reactors
"What the heck is a reactor?
I asked myself exactly the same question when I first came across the
phrase. "It must be another name for an Event", I said to
myself. I was wrong, again!!!
A reactor is an Object you attach to AutoCAD Objects to have AutoCAD
notify your application when a particular event, or events occur.
(Remember, that an AutoCAD Object can be an Object within your drawing,
the drawing itself, or even AutoCAD, the application - just thought I'd
tell you).
This is the general procedure :
- An Event occurs in your drawing.
- AutoCAD notifies the Reaction associated with
that Event.
- The reaction then notifies your application,
known as a callback function, passing to it certain information
applicable to the Event in the form of arguments.
- Your application then does it's thing using the
information passed to it from the Reactor.
So, in simple terms, a Reactor is the
"link" between the Event and the callback function.
Before we get into looking at the different types of
AutoCAD Reactors and Events, let's have a look at a fairly straightforward
Reactor to give you an idea of how simple they can be. Before you start
though, you must ask yourself two questions :
- Before, after or during what Event do you want
your function to occur?
- What do you want your function to do?
For this example, I will answer both these questions
on your behalf.
- "I want my function to run every time a
drawing Save is completed".
- "I want the function to tell me what the
name of the drawing is, and how big the drawing is".
O.K. Looking at the Reactor listings, (Refer to
Visual Lisp Reference), under the Editor Reactor Types, I find a
reactor called "vl-dwg-reactor". This reactor, I am led
to believe, responds to the "Save Complete" event of a drawing,
and returns callback data of a string containing the actual file name used
for the save.
Hey, this is just what we are looking for. Let's order two to take-away.
Enough of this childish wit!!
Let's have a look at the reactor definition and syntax first :
vlr-dwg-reactor - Constructs an
editor reactor object that notifies of a drawing event.
(vlr-dwg-reactor data
callbacks)
Arguments :
data : AutoLisp data to be
associated with the reactor object, or nil, if no data
callbacks : A list of pairs of
the following form :
(event-name . callback_function)
where event-name is one of the symbols
listed in the "DWG reactor events" table, and
callback_function is a symbol representing the function to be called
when the event fires. Each callback function will accept two arguments
:
reactor_object - the VLR object that called the callback
function,
list - a list of extra data elements associated with the
particular event.
I don't know about you? But, whew.........!!!
Right, let's try and put this into simple English. Let's look at the
syntax again :
(vlr-dwg-reactor data
callbacks)
The first part "vlr-dwg-reactor"
is easy. This is the name of the reactor type. This name will be sent to
your call back function.
The first argument "data", is
User Application Data. We usually set this to a reactor name of our
choosing. This way we can distinguish between reactors if an Objects has
multiple reactors attached.
The second argument "callbacks"
is a straightforward list of dotted pairs.
- The first element of the list is the
name of the reactor "event" that will trigger the reactor
and then call your callback function.
- The second element, is the name of your
Callback function.
This is what our reactor function will look like :
(vlr-dwg-reactor "Save
Complete" '((:vlr-savecomplete . savedrawinginfo)))
Or, graphically :
Let's have a look at our Reactor Function in action.
Copy and Paste this coding into the Visual Lisp Editor and save it as
"SaveDrawingInfo.Lsp".
Next Load the application, but DO NOT run it.
(vl-load-com)
;**************************************************************
;setup and intilise the reactor
(vlr-dwg-reactor "Save Complete" '((:vlr-savecomplete . savedrawinginfo)))
;**************************************************************
(defun saveDrawingInfo (calling-reactor commandInfo / dwgname filesize
reactType reactData reactCall
reactEvent reactCallback)
;get the reactor Object
(setq reactInfo calling-reactor
;get the reactor Type
reactType (vl-symbol-name (vlr-type reactInfo))
;get the Application Data
reactData (vlr-data reactInfo)
;get the Callback list
reactCall (car (vlr-reactions reactInfo))
;extract the Event Reactor
reactEvent (vl-symbol-name (car reactCall))
;extract the Callback Function
reactCallback (vl-symbol-name (cdr reactCall))
);setq
;get the Drawing Name
(setq dwgname (cadr commandInfo)
;extract the filesize
filesize (vl-file-size dwgname)
);setq
;display the Drawing Name and Size
(alert (strcat "The file size of " dwgname " is "
(itoa filesize) " bytes."))
;Display the Reactor Information
(alert
(strcat
"A " "\"" reactType "\"" " named " "\"" reactData "\"" "\n"
"was triggered by a " "\"" reactEvent "\"" " event call." "\n"
"Callback Data was passed to the" "\n"
"\"" reactCallback "\"" " call back function."))
(princ)
);defun
;********************************************************
(princ)
;********************************************************
Once the application is loaded, return to AutoCAD and save the drawing.
This dialog will appear :
Followed by this dialog :
Do you notice the "calling-reactor" and
"commandInfo" argument declarations? This information, the
Reactor Object Name and the Event Parameter Information is passed to our
Callback Function from the Reactor.
Clever hey?
On the next Page, we'll have a look at some Drawing
Reactors.
|