Efficient Variables.
Every variable used in an AutoLisp routine uses up system resources.
You've probably been advised before now, not to use too many SETQ's. LISP,
itself was originally a functional language, without any variables. Here
is a typical example of how we all go about collecting the values required
for our routines.
(setq "oldecho" (getvar "CMDECHO"))
(setq "oldhigh" (getvar "HIGHLIGHT"))
(setq "oldsnap" (getvar "OSMODE"))
(setq pt1 (getpoint "\Enter First Point : "))
(setq pt2 (getpoint "\Enter Second Point : "))
(setq thk (getdist "\Enter Thickness : "))
(setq qty (getint "\Enter Number Required : "))
Programmatically, there is nothing wrong with this coding, except that
seven (7) variables are used, each of which takes up system resources. As
well as this, each variable will need to be declared as Local to prevent a
scattering of loose variables all over the place.
A much better way of storing your variables is to place them in a list.
Here's one way of doing this :
(setq AList (append (list (getvar "CMDECHO")) AList))
(setq AList (append (list (getvar "HIGHLIGHT")) AList))
(setq AList (append (list (getvar "OSMODE")) AList))
(setq AList (append (list (getpoint "\Enter First Point : ")) AList))
(setq AList (append (list (getpoint "\Enter Second Point : ")) AList))
(setq AList (append (list (getdist "\Enter Thickness : ")) AList))
(setq AList (append (list (getint "\Enter Number Required : ")) AList))
If we ran this sequence of coding, the variable AList would
contain something
like this :
(5 10.0 (660.206 391.01 0.0) (411.014 548.932 0.0) 32 1 0)
Now this is a lot better. Every variable stored in one list and only one
variable to declare. To retrieve any of the values, we would simply do the
following :
(setvar "OSMODE" (nth 4 AList))
This, of course would return 32, the value of the Snap that we
previously saved.
The problem with this though, is remembering which value belongs to
what. To achieve this we would need to keep track of the order in which we
passed the values to our list.
Wouldn't it be great if we could pass a label along with each value so
that we could easily retrieve the value by just quoting the label.
By using 'Associative Lists' we can do just that. Have a look at
this :
(setq AList (append (list (cons "OLDECHO" (getvar "CMDECHO"))) AList))
(setq AList (append (list (cons "OLDHIGH" (getvar "HIGHLIGHT"))) AList))
(setq AList (append (list (cons "OLDSNAP" (getvar "OSMODE"))) AList))
(setq AList (append (list (cons "PT1" (getpoint "\Enter First Point : "))) AList))
(setq AList (append (list (cons "PT2" (getpoint "\Enter Second Point : "))) AList))
(setq AList (append (list (cons "THK" (getdist "\Enter Thickness : "))) AList))
(setq AList (append (list (cons "QTY" (getint "\Enter Number Required : "))) AList))
This coding would return something like this :
(("QTY" . 6) ("THK" . 12.0) ("PT2" 809.113 523.118 0.0) ("PT1" 356.314 646.115 0.0)
("OLDSNAP" . 32) ("OLDHIGH" . 1) "OLDECHO" 0)
Now, to retrieve any value from this list, irrespective of it's
position in the list, we would simply do something like this :
(setvar "OSMODE" (cdr (assoc "OLDSNAP" AList)))
This, again would return 32.
Now, by converting the construction of the list, and the retrieving of
values from the list, into functions, we have an elegant and sophisticated
way of storing our variables in an efficient and practical manner.
Following, is an AutoLisp routine that can be used, with just a wee bit of
modification, in any situation to make the storage of your variable much
more efficient :
(defun c:efflist ( / AnItem item MainList)
(setq AnItem (getvar "OSMODE"))
;get the snap setting
(AList "OLDSNAP" AnItem)
;add it to the list
(setq AnItem (getvar "HIGHLIGHT"))
;get the highlight setting
(AList "OLDHIGH" AnItem)
;add it to the list
(setq AnItem (getvar "CMDECHO"))
;get the command echo setting
(AList "OLDECHO" AnItem)
;add it to the list
(setvar "Osmode" 32)
;reset snap to intersection
(setvar "Highlight" 0)
;switch off highlight
(setvar "Cmdecho" 0)
;switch off command echo
(setq AnItem (getpoint "\nSelect First Point : "))
;get the first point
(AList "FirstPoint" AnItem)
;add it to the list
(setq AnItem (getpoint AnItem "\nSelect Second Point : "))
;get the second point
(AList "SecondPoint" AnItem)
;add it to the list
(setq AnItem (getpoint AnItem "\nSelect Third Point : "))
;get the third point
(AList "ThirdPoint" AnItem)
;add it to the list
(setq AnItem (getpoint AnItem "\nSelect Fourth Point : "))
;get the fourth point
(AList "FourthPoint" AnItem)
;add it to the list
(command "Line" (RList "FirstPoint")
(RList "SecondPoint")
(RList "ThirdPoint")
(RList "FourthPoint")
"C"
)
;retrieve all the point values and draw the shape
(setvar "OSMODE" (RList "OLDSNAP"))
;retrieve and reset snap
(setvar "HIGHLIGHT" (RList "OLDHIGH"))
;retrieve and reset highlight
(setvar "CMDECHO" (RList "OLDECHO"))
;retrieve and reset command echo
(princ)
);defun
;This function constructs the list and adds it to the main list
(defun AList (Name Val)
(setq item (list (cons Name Val)))
;construct list
(setq MainList (append item Mainlist))
;add it to the main list
);defun
;This function retrieves the values from the main list
(defun RList (TheName)
(cdr (assoc TheName MainList))
;retrieve value from list
);defun
(princ)
After running this routine, the value of the variable MainList
would look something like this :
(("FourthPoint" 456.598 514.007 0.0) ("ThirdPoint" 676.92 293.827 0.0)
("SecondPoint" 1030.95 526.155 0.0) ("FirstPoint" 576.636 732.669 0.0)
("OLDECHO" . 0) ("OLDHIGH" . 1) ("OLDSNAP" . 32))
|