How to pass arguments to reactor defun?

How to pass arguments to reactor defun?

NVIT
Enthusiast Enthusiast
1,716 Views
11 Replies
Message 1 of 12

How to pass arguments to reactor defun?

NVIT
Enthusiast
Enthusiast

Since I haven't found a way, I use global vars instead: My global var is: #React_globalvar

 

(vlr-editor-reactor nil '((:VLR-commandEnded . FuncName)))

My reactor defun is:
(defun FuncName (CALL CALLBACK / cBNam el en ssBlk) (alert #React_globalvar))


Is there a way to pass arguments to the reactor defun FuncName ?

Would appreciate your help.

 

 

 

 

0 Likes
1,717 Views
11 Replies
Replies (11)
Message 2 of 12

Moshe-A
Mentor
Mentor

@NVIT hi,

 

the following is from the AutoLISP reference:

 

vlr-command-reactor (AutoLISP/ActiveX)
Constructs an editor reactor that notifies of a command event

Supported Platforms: Windows only

Signature
(vlr-command-reactor data callbacks)
data
Type: Integer, Real, String, List, VLA-object, Safearray, Variant, T, or nil

Any AutoLISP data to be associated with the reactor object; otherwise nil if no data is to be associated with the reactor.

 

Cause the format of the callback is fix,  the AutoLISP interpreter must know in advance the arguments that pass, you can not add more arguments but you can pass any data  type at the reactor definition call with data argument

and access it (inside callback) with (vlr-data react) even change it with (vlr-data-set react data) 

data could be a fix value (e.g a string) or any global variable you have.

 

Moshe

 

 

0 Likes
Message 3 of 12

scot-65
Advisor
Advisor
The FuncName section shall only be used to "sniff out" the command (or variable, etc.) in question, and if true, send to a separate function.

To do this, structure it as a COND:
(defun FuncName (CALL CALLBACK / )
(cond
((eq (car CALLBACK) "PLOT") (PlotFunction))
((eq (car CALLBACK) "PUBLISH") (PublishFunction))
((eq (car CALLBACK) "LAYOUT_CONTROL") (LayoutFunction))
(T (princ))
);cond
);end FuncName

This structure will minimize any pauses/delays that may be encountered if not structured this way.

Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 4 of 12

NVIT
Enthusiast
Enthusiast
Thanks for you help, Moshe. I'll need to study that. Basically, I'd like to pass args to the FuncName
0 Likes
Message 5 of 12

NVIT
Enthusiast
Enthusiast
Thanks for your help, Scot. Basically, I'd like to pass args to each PlotFunction, PublishFunction, or LayoutFunction. Can that be done?
0 Likes
Message 6 of 12

Moshe-A
Mentor
Mentor

@NVIT ,

 


@NVIT wrote:
Thanks for your help, Scot. Basically, I'd like to pass args to each PlotFunction, PublishFunction, or LayoutFunction. Can that be done?

Yes you can but it would be global variables  [or wrap it all in a big (c:xxx) ] bare in mind if you accept @scot-65  suggest  (which is very good) you'll still be restricted to using reactor callback limitations which is no pause using (getxxxx) functions, no (command)  calls...

 

Moshe

 

0 Likes
Message 7 of 12

NVIT
Enthusiast
Enthusiast
Per my original post, I am already using global variables, but would like to prevent from doing that by passing it to the reactor function instead.

Per your response, there seems to be no way to do what I originally asked.

Thank you for your help.
0 Likes
Message 8 of 12

doaiena
Collaborator
Collaborator

I'm not sure if this is what you are looking for exactly, but in the set up of the reactor, you can add data to it and/or change it at any point.

I'll give an example with a command reactor.

Quote from autodesk documentation:

(vlr-command-reactor data callbacks)

 

So, you can initialize your reactor with some data attached, or add it at a later point. Just make sure you keep your target reactor in a global variable.

 

 

(defun ReactorFun (reactor lst)
  (if (and (equal (vlr-current-reaction-name) ':vlr-commandWillStart) (equal (car lst) "MOVE"))
    (alert (vl-princ-to-string (vlr-data reactor)))
  )
  (princ)
)

(if (not *CommandReactor*)
  (setq *CommandReactor* (vlr-command-reactor (list 1 2 3) '((:vlr-commandWillStart . ReactorFun))))
)

 

 

In this example I am creating a command reactor with data added to it /a list containging the numbers 1 2 3/. When the "move" command is executed, the contents of that 'data' is printed out in a window.

 

You can retrieve the 'data' contents of a reactor using the '(vlr-data reactorObject)' function. If you want to change the data contents, the function is '(vlr-data-set reactorObject data)'.

 

I don't know your exact use case for wanting to pass additional data to a reactor function, but I'm pretty sure this will do the job.

Message 9 of 12

NVIT
Enthusiast
Enthusiast
Hi doaiena. Thank you for your detailed help. I'll test it. I was trying to abstract the reactor defun, with the idea of using it in other reactors.
0 Likes
Message 10 of 12

Moshe-A
Mentor
Mentor

@NVIT wrote:
Per my original post, I am already using global variables, but would like to prevent from doing that by passing it to the reactor function instead.

Per your response, there seems to be no way to do what I originally asked.

Thank you for your help.

No you can not and i think i explained the reason in message #2

 

the reactor definition must stat global (otherwise it won't be recognized)

the callback definition is fixed (you can add or remove arguments) and it must

stay global (otherwise it won't be recognized)

 

Moshe

 

 

 

 

0 Likes
Message 11 of 12

dbroad
Mentor
Mentor

Perhaps I'm confused but you don't defun a reactor.  You defun a reactor callback.  For vlr-editor reactors, callback functions should be defined with 2 arguments (the reactor itself that is calling the function and information that relates to the reactor.  The best way to learn about what information is passed to callback function monitoring a specific event is to use vlr-trace reactions.  For example:

(vlr-editor-reactor nil '((:vlr-commandended . vlr-trace-reaction)))

Using that as context and looking at vlide's trace window after the line command ends, you would see a display like

 

; Reaction: :VLR-commandEnded; argument list: (#<VLR-Editor-Reactor> ("LINE"))

 

To get to your specific question each reactor can store any information you want to work with in it DATA argument.

For a callback function to get that data, it should use vlr-data.  To store data, it should use VLR-Data-Set

 

For example,  given the above and using a callback defined as

(defun cmdendcback (R L)

   (setq myinfo (vlr-data R)) ;to get information from reactor data.

   (vlr-data-set R L);to save the last command ended list.

)

 

The only global I save is the return value from the construction of the reactor.  

(IF (NULL myeditorreactor)
  (SETQ myeditorreactor (VLR-EDITOR-REACTOR '("just starting")
    '((:VLR-COMMANDENDED .  cmdendcback )))))
Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 12 of 12

Sea-Haven
Mentor
Mentor

This may be a helpful example it has 3 functions that are trapped by a reactor. Load the lisp and type C123 and you will see how it works.

 

; Enter the filet radius as part of a command line entry f100, O234 for offset, c123.45 for circle, P123 for pline width
; original code and methology by Alan H
; assistance and code that worked by Lee-Mac
; OCT 2015
; Edited by Mhupp Sep 2022

((lambda nil
  (vl-load-com)
  (foreach obj (cdar (vlr-reactors :vlr-command-reactor))
    (if (= "fillet-reactor" (vlr-data obj))
      (vlr-remove obj)
    )
  )
  (vlr-command-reactor "fillet-reactor" '((:vlr-unknowncommand . fillet-reactor-callback)))
 )
)

(defun plwid (/ oldwidth)
  (setq oldwidth (getvar 'plinewid))
  (setvar 'plinewid num)
  (vla-sendcommand fillet-reactor-acdoc "_.pline ")
  (setvar 'plinewid oldwidth)
)
(defun filletrad ()
  (setvar 'filletrad num)
  (vla-sendcommand fillet-reactor-acdoc "_.fillet ")
)
(defun makecirc ()
  (setvar 'circlerad num)
  (vla-sendcommand fillet-reactor-acdoc "_.Circle ")
)
(defun offdist ()
  (setvar 'offsetdist num)
  (vla-sendcommand fillet-reactor-acdoc "_.Offset ")
)
(defun fillet-reactor-callback (obj com / num)
  (setq com (car com))
  (cond
    ((and
      (eq (strcase (substr com 1 1)) "F")
      (numberp (setq num (distof (substr com 2))))
      (<= 0.0 num)
     )  ; and
      (filletrad)
    )

    ((and
      (eq (strcase (substr com 1 1)) "C")
      (numberp (setq num (distof (substr com 2))))
      (<= 0.0 num)
     )  ;and
      (makecirc)
    )

    ((and
      (eq (strcase (substr com 1 1)) "O")
      (numberp (setq num (distof (substr com 2))))
      (<= 0.0 num)
     )  ; and
      (offdist)
    )
    ((and
      (eq (strcase (substr com 1 1)) "P")
      (numberp (setq num (distof (substr com 2))))
      (<= 0.0 num)
     )  ; and
      (plwid)
    )
  )     ; master cond
)       ; defun

(or fillet-reactor-acdoc 
    (setq fillet-reactor-acdoc (vla-get-activedocument (vlax-get-acad-object)))
)
0 Likes