Author Topic: Using vlr-sysvar-reactor to update an Xrecord  (Read 2008 times)

0 Members and 1 Guest are viewing this topic.

steve.carson

  • Newt
  • Posts: 108
Using vlr-sysvar-reactor to update an Xrecord
« on: April 14, 2016, 12:57:31 PM »
Hi,

The company I work for (referred to as "MN") has various lisp files to help standardize our drawings. We call them "MN Tools". One of these creates an Xrecord that stores the dimension layer name that gets set to current when adding dimensions. We recently upgraded to 2016 and now there is the system variable "dimlayer". I added a simple setvar to our Tools to update the dimlayer system variable if the user sets or changes the dimension layer through our tools. But I thought it would be nice if the Xrecord would update if the user changed the dimension layer saved in the system variable (through the ribbon or whatever). So I took my first plunge into Reactors and created the code below. It works as I would like, but have read that reactors are sensitive to things, so was hoping somebody with reactor experience could take a look and see if there are any potential problems.

Code - Auto/Visual Lisp: [Select]
  1. ;;Reactor to change the MN dimension layer if the user changes the Autocad system variable "dimlayer"
  2. ;;
  3. ;;Written by: Steve Carson
  4. ;;
  5. ;;04/07/2016
  6. ;;
  7. ;;Thanks to www.afralisp.net for the lesson on Reactors
  8.  
  9.  
  10.  
  11.  
  12.  
  13. ;************************************************************************************
  14. ;Initialize the Reactor
  15.  
  16.  
  17.  
  18. (vlr-sysvar-reactor "Dimlayer Changed" '((:vlr-sysVarChanged . MN:dimlayerchanged)))
  19.  
  20.  
  21. ;************************************************************************************
  22.  
  23.  
  24. ;Callback function
  25.  
  26. (defun MN:dimlayerchanged (calling-reactor Command-Info / DL Xrec)
  27.  
  28.  
  29. (if (= (car Command-Info) "DIMLAYER")
  30.  
  31.     (progn
  32.      
  33.      (setq DL (getvar "dimlayer"))
  34.  
  35.      (if (dictsearch (namedobjdict) "DWGPROPS")
  36.  
  37.        (dictremove (namedobjdict) "DWGPROPS")
  38.  
  39.      )
  40.  
  41.      (setq Xrec (list (cons 0 "XRECORD")
  42.  
  43.                       (cons 100 "AcDbXrecord")
  44.  
  45.                       (cons 1 "DWGPROPS COOKIE")
  46.  
  47.                       (cons 300 (strcat "dimlayer=" DL))
  48.  
  49.                  );list
  50.  
  51.       );setq
  52.  
  53.       (dictadd (namedobjdict) "DWGPROPS" (entmakex Xrec))
  54.  
  55.  
  56.     );progn
  57.    
  58.  
  59. );if
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. );Callback Defun
  67.  

Note that I will update the header to reflect any assistance received in this thread.


Thanks in advance,

Steve

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #1 on: April 14, 2016, 01:18:26 PM »
Here are some suggestions:
Code - Auto/Visual Lisp: [Select]
  1. (   (lambda nil
  2.             (if (= "Dimlayer Changed" (vlr-data rtr)) (vlr-remove rtr))
  3.         )
  4.         (vlr-sysvar-reactor "Dimlayer Changed" '((:vlr-sysvarchanged . MN:dimlayerchanged)))
  5.     )
  6. )
  7. (defun MN:dimlayerchanged ( rtr arg / dim )
  8.     (if (and (= (strcase (car arg)) "DIMLAYER") (setq dim (getvar 'dimlayer)))
  9.         (progn
  10.             (dictremove (namedobjdict) "DWGPROPS")
  11.             (dictadd    (namedobjdict) "DWGPROPS"
  12.                 (entmakex
  13.                     (list
  14.                        '(000 . "XRECORD")
  15.                        '(100 . "AcDbXrecord")
  16.                        '(001 . "DWGPROPS COOKIE")
  17.                         (cons 300 (strcat "dimlayer=" dim))
  18.                     )
  19.                 )
  20.             )
  21.         )
  22.     )
  23.     (princ)
  24. )

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #2 on: April 14, 2016, 01:53:26 PM »
@ Steve:
Why do you remove the dictionary instead of just the xrecord?
What is the meaning of (1 . "DWGPROPS COOKIE")?
It seems that a "DWGPROPS" dictionary was used in older versions of AC. Is it wise to use that name for a custom application?

steve.carson

  • Newt
  • Posts: 108
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #3 on: April 14, 2016, 02:22:34 PM »
Thanks for the suggestions, Lee!
I've learned some new things, just by going through them. I understand that lambda creates an anonymous function, but what is the purpose of using it here?


Thanks,

Steve


steve.carson

  • Newt
  • Posts: 108
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #4 on: April 14, 2016, 02:37:16 PM »
@ Steve:
Why do you remove the dictionary instead of just the xrecord?
What is the meaning of (1 . "DWGPROPS COOKIE")?
It seems that a "DWGPROPS" dictionary was used in older versions of AC. Is it wise to use that name for a custom application?

Hi Roy,

I made the reactor emulate what our current tools do when setting the dimension layer. In all honesty, our tools are old and could definitely benefit from some optimization. When trying to add to, or modify something in our lisp files I sometimes feel like an electrician dealing with this  :laugh: :



JohnK

  • Administrator
  • Seagull
  • Posts: 10646
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #5 on: April 14, 2016, 03:21:09 PM »
Thanks for the suggestions, Lee!
I've learned some new things, just by going through them. I understand that lambda creates an anonymous function, but what is the purpose of using it here?


Thanks,

Steve

Pure trickery I tell you!

Code - Auto/Visual Lisp: [Select]
  1. (   (lambda nil
  2.             (if (= "Dimlayer Changed" (vlr-data rtr)) (vlr-remove rtr))
  3.         )
  4.         (vlr-sysvar-reactor "Dimlayer Changed" '((:vlr-sysvarchanged . MN:dimlayerchanged)))
  5.     )
  6. )

He could have just as easily typed, without the lambda, like this:

Code - Auto/Visual Lisp: [Select]
  1.     (if (= "Dimlayer Changed" (vlr-data rtr)) (vlr-remove rtr)))
  2. (vlr-sysvar-reactor "Dimlayer Changed" '((:vlr-sysvarchanged . MN:dimlayerchanged)))

No, seriously though (joking aside), one would type the lambda to give a cleaner "copy-paste thing" or just signify that "you can make a function out of this code and call it what you want" or for any number of different reasons.

The
Code - Auto/Visual Lisp: [Select]
  1. (lambda ( / ) ...
is an anonymous function.

The
Code - Auto/Visual Lisp: [Select]
  1. ( (lambda ( / ) ...
is like saying: execute this anonymous function (note the extra paren).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

steve.carson

  • Newt
  • Posts: 108
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #6 on: April 14, 2016, 04:19:39 PM »
Thanks John!

Yeah the extra parenthesis threw me for a minute, so I did a test at the command line of
Code - Auto/Visual Lisp: [Select]
  1. (lambda nil (/ 6 2))
and sure enough, it didn't return "3", so I tried
Code - Auto/Visual Lisp: [Select]
  1. ((lambda nil (/ 6 2)))
and that returned 3.



Steve

JohnK

  • Administrator
  • Seagull
  • Posts: 10646
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #7 on: April 14, 2016, 05:10:30 PM »
Thanks John!

Yeah the extra parenthesis threw me for a minute, so I did a test at the command line of
Code - Auto/Visual Lisp: [Select]
  1. (lambda nil (/ 6 2))
and sure enough, it didn't return "3", so I tried
Code - Auto/Visual Lisp: [Select]
  1. ((lambda nil (/ 6 2)))
and that returned 3.



Steve

Extra credit: what is the difference between "(lambda nil" and "(lambda (/)"?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #8 on: April 14, 2016, 05:37:27 PM »
Thanks for the suggestions, Lee!
I've learned some new things, just by going through them. I understand that lambda creates an anonymous function, but what is the purpose of using it here?

You're welcome Steve -

As John notes above, the use of lambda here is not strictly necessary, but I use it purely to add some structure to the code (since the enclosed expressions are part of the same block of code performing a particular task, but don't warrant declaring a separately named defun); also, temporary variables used by such expressions would be declared local to the lambda function to avoid unnecessary globals.

JohnK

  • Administrator
  • Seagull
  • Posts: 10646
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #9 on: April 14, 2016, 05:48:38 PM »
> local to the lambda
But remember to localize; recall the "lexical scoping" discussions I've given.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

ChrisCarlson

  • Guest
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #10 on: April 15, 2016, 08:08:07 AM »
Thanks John!

Yeah the extra parenthesis threw me for a minute, so I did a test at the command line of
Code - Auto/Visual Lisp: [Select]
  1. (lambda nil (/ 6 2))
and sure enough, it didn't return "3", so I tried
Code - Auto/Visual Lisp: [Select]
  1. ((lambda nil (/ 6 2)))
and that returned 3.



Steve

Extra credit: what is the difference between "(lambda nil" and "(lambda (/)"?

Shooting from the hip here but does  (lambda nil) mean it accepts no arguments and saves no variables but (lambda (/)) will?

JohnK

  • Administrator
  • Seagull
  • Posts: 10646
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #11 on: April 15, 2016, 08:38:53 AM »
Extra credit: what is the difference between "(lambda nil" and "(lambda (/)"?
Shooting from the hip here but does  (lambda nil) mean it accepts no arguments and saves no variables but (lambda (/)) will?

Nice but, sorry, no.
(lambda nil ...
is the same as
(lambda ( / ) ...

No arguments and no localization's (the use of `nil' is essentially just shorthand). I don't think it's a good idea to use it in teaching cases because it is no different then the long hand version but it can/does tend to obfuscate a little (users shouldn't just take code and cut and paste; they should know and understand the aspects of the code they're given and even a harmless thing like that can cause confusion for some).

However, that's not to say that using `nil' is bad; the `nil' is a great trick and most definitely worth using sometimes. For example (posting some old code of mine found on a USB) this is some code to create an anonymous function for later execution:

Code - Auto/Visual Lisp: [Select]
  1. (defun hook (func)
  2.   ;; hook
  3.   ;;
  4.   ;; This function will take an argument and turn it into a
  5.   ;; lambda expression to evaluate. (You can assign to a variable
  6.   ;; and exec it at a later time if you wish.)
  7.   ;;
  8.   ;; Ex: (hook '(+ 1 2))
  9.   ;;     > ((LAMBDA nil (+ 1 2)))
  10.   ;;    
  11.   ;; Ex 2: (setq zoom
  12.   ;;            (hook '(vla-zoomextents
  13.   ;;                (vlax-get-acad-object))))
  14.   ;;     > ((LAMBDA nil (vla-ZoomExtents (vlax-get-acad-object))))
  15.   ;;
  16.   ;; By: John K
  17.   ;;    (inspired by something I saw in one of
  18.   ;;     Vladimir Nesterovsky's procedures.)
  19.   ;;
  20.   (list (cons 'lambda (cons nil (list func)))) )


TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

steve.carson

  • Newt
  • Posts: 108
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #12 on: April 15, 2016, 12:02:08 PM »
Thanks for the responses Guys.


(lambda nil ...
is the same as
(lambda ( / ) ...


That's what I always thought, but searched anyways thinking maybe there was some obsure tiny difference at the processor level (or something else way over my head).

My search turned up nil (pun intended).



Steve

JohnK

  • Administrator
  • Seagull
  • Posts: 10646
Re: Using vlr-sysvar-reactor to update an Xrecord
« Reply #13 on: April 15, 2016, 12:17:30 PM »
lol
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org