Author Topic: OSMODE . . with no magic numbers  (Read 1678 times)

0 Members and 1 Guest are viewing this topic.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2162
  • class keyThumper<T>:ILazy<T>
OSMODE . . with no magic numbers
« on: December 12, 2022, 05:33:53 PM »
My memory isn't as good as it was 40 years ago,  and I don't like magic numbers, so :

Code - Auto/Visual Lisp: [Select]
  1. ;;------------------------------------------------------------------------------------------------
  2. ;; Enum names for osmode values.
  3. (defun kdub:set_Osmode_enums (/ tempprotect)
  4.   (setq tempprotect '(os_none   os_end    os_mid
  5.                       os_cen    os_nod    os_qua
  6.                       os_int    os_ins    os_per
  7.                       os_tan    os_nea    os_clear
  8.                       os_app    os_ext    os_par
  9.                       os_all
  10.                      )
  11.   )
  12.   (eval
  13.     (list 'pragma
  14.           (list 'quote
  15.                 (list (cons 'unprotect-assign tempprotect))
  16.           )
  17.     )
  18.   )
  19.   (setq os_none 0
  20.         os_end 1
  21.         os_mid 2
  22.         os_cen 4
  23.         os_nod 8
  24.         os_qua 16
  25.         os_int 32
  26.         os_ins 64
  27.         os_per 128
  28.         os_tan 256
  29.         os_nea 512
  30.         os_clear 1024
  31.         os_app 2048
  32.         os_ext 4096
  33.         os_par 8192
  34.         os_all 16383
  35.   )
  36.               (list 'quote
  37.                     (list (cons 'protect-assign tempprotect))
  38.               )
  39.         )
  40.   )
  41.   (setq os_tempprotect nil)
  42.   (princ)
  43. )
  44.  

usage :
Code - Auto/Visual Lisp: [Select]
  1. ;|
  2. example :
  3.         (setq osm (getvar 'osmode))
  4.  
  5.         (setvar 'osmode (+ os_int os_cen os_mid os_end) ) ;;-> 39
  6.         (command ".line" pt1 pt2)
  7. |;
  8.  

notice the variable coloring :


« Last Edit: December 12, 2022, 05:43:05 PM by kdub »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

ronjonp

  • Needs a day job
  • Posts: 7535
Re: OSMODE . . with no magic numbers
« Reply #1 on: December 12, 2022, 06:18:31 PM »
Nice idea!

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12937
  • London, England
Re: OSMODE . . with no magic numbers
« Reply #2 on: December 12, 2022, 06:57:27 PM »
Great idea Kerry :-)

Only suggestion I would make would be to have a single list to maintain rather than two, e.g. -
Code - Auto/Visual Lisp: [Select]
  1. ;;------------------------------------------------------------------------------------------------
  2. ;; Enum names for osmode values.
  3. (defun kdub:set_Osmode_enums ( / lst )
  4.     (setq lst
  5.        '(
  6.             (os_none  00000)
  7.             (os_end   00001)
  8.             (os_mid   00002)
  9.             (os_cen   00004)
  10.             (os_nod   00008)
  11.             (os_qua   00016)
  12.             (os_int   00032)
  13.             (os_ins   00064)
  14.             (os_per   00128)
  15.             (os_tan   00256)
  16.             (os_nea   00512)
  17.             (os_clear 01024)
  18.             (os_app   02048)
  19.             (os_ext   04096)
  20.             (os_par   08192)
  21.             (os_all   16383)
  22.         )
  23.     )
  24.     (eval (list 'pragma (list 'quote (list (cons 'unprotect-assign (mapcar 'car lst))))))
  25.     (foreach x lst (apply 'set x))
  26.     (eval (list 'pragma (list 'quote (list (cons 'protect-assign   (mapcar 'car lst))))))
  27.     (princ)
  28. )


BIGAL

  • Swamp Rat
  • Posts: 1459
  • 40 + years of using Autocad
Re: OSMODE . . with no magic numbers
« Reply #3 on: December 12, 2022, 10:53:52 PM »
Nice idea, though osnap, set snaps, then do osmode, get a pencil and paper write down and/or put number in code.
A man who never made a mistake never made anything

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: OSMODE . . with no magic numbers
« Reply #4 on: December 13, 2022, 02:54:16 AM »
No globals:
Code: [Select]
(defun GetOsModeBits (BitLst / OutBit AssLst)
  (setq
    OutBit 0
    AssLst '( ("os_none" .    0)("os_end" .       1)("os_mid" .     2)("os_cen" .     4)("os_nod" .     8)
              ("os_qua" .    16)("os_int" .      32)("os_ins" .    64)("os_per" .   128)("os_tan" .   256)
              ("os_nea" .   512)("os_clear" .  1024)("os_app" .  2048)("os_ext" .  4096)("os_par" .  8192)
              ("os_all" . 16383)
            )
  )
  (foreach ForElm BitLst
    (setq OutBit (+ OutBit (cdr (assoc ForElm AssLst))))
  )
)
Command: (getvar 'osmode)
1

Command: (setvar 'osmode (GetOsModeBits '("os_int" "os_cen" "os_mid" "os_end")))
39

Command: (getvar 'osmode)
39

jlogan02

  • Bull Frog
  • Posts: 327
Re: OSMODE . . with no magic numbers
« Reply #5 on: December 13, 2022, 06:32:17 PM »
Great idea Kerry :-)

Only suggestion I would make would be to have a single list to maintain rather than two, e.g. -
Code - Auto/Visual Lisp: [Select]
  1. ;;------------------------------------------------------------------------------------------------
  2. ;; Enum names for osmode values.
  3. (defun kdub:set_Osmode_enums ( / lst )
  4.     (setq lst
  5.        '(
  6.             (os_none  00000)
  7.             (os_end   00001)
  8.             (os_mid   00002)
  9.             (os_cen   00004)
  10.             (os_nod   00008)
  11.             (os_qua   00016)
  12.             (os_int   00032)
  13.             (os_ins   00064)
  14.             (os_per   00128)
  15.             (os_tan   00256)
  16.             (os_nea   00512)
  17.             (os_clear 01024)
  18.             (os_app   02048)
  19.             (os_ext   04096)
  20.             (os_par   08192)
  21.             (os_all   16383)
  22.         )
  23.     )
  24.     (eval (list 'pragma (list 'quote (list (cons 'unprotect-assign (mapcar 'car lst))))))
  25.     (foreach x lst (apply 'set x))
  26.     (eval (list 'pragma (list 'quote (list (cons 'protect-assign   (mapcar 'car lst))))))
  27.     (princ)
  28. )

Pragam?? Had to look that one up. Am I understanding correctly that it allows access to protected symbols?
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8903
  • AKA Daniel
Re: OSMODE . . with no magic numbers
« Reply #6 on: December 14, 2022, 12:09:30 AM »
No globals:
Code: [Select]
(defun GetOsModeBits (BitLst / OutBit AssLst)
  (setq
    OutBit 0
    AssLst '( ("os_none" .    0)("os_end" .       1)("os_mid" .     2)("os_cen" .     4)("os_nod" .     8)
              ("os_qua" .    16)("os_int" .      32)("os_ins" .    64)("os_per" .   128)("os_tan" .   256)
              ("os_nea" .   512)("os_clear" .  1024)("os_app" .  2048)("os_ext" .  4096)("os_par" .  8192)
              ("os_all" . 16383)
            )
  )
  (foreach ForElm BitLst
    (setq OutBit (+ OutBit (cdr (assoc ForElm AssLst))))
  )
)
Command: (getvar 'osmode)
1

Command: (setvar 'osmode (GetOsModeBits '("os_int" "os_cen" "os_mid" "os_end")))
39

Command: (getvar 'osmode)
39

cool, how about LSH using it's position in the list

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: OSMODE . . with no magic numbers
« Reply #7 on: December 14, 2022, 02:54:00 AM »
No globals:
(defun GetOsModeBits (BitLst / OutBit AssLst) ...
cool, how about LSH using it's position in the list
Code: [Select]
(defun GetOsModeBits2 (BitLst / OutBit OsnLst)
  (setq
    OutBit 0
    OsnLst '("os_none" "os_end" "os_mid" "os_cen"   "os_nod" "os_qua" "os_int" "os_ins"
             "os_per"  "os_tan" "os_nea" "os_clear" "os_app" "os_ext" "os_par"
            )
  )
  (if (member "os_all" BitLst)
    16383
    (foreach ForElm BitLst
      (setq OutBit (+ OutBit (lsh 1 (1- (vl-position ForElm OsnLst)))))
    )
  )
)
Code: [Select]
(GetOsModeBits  '("os_none")) => 0
(GetOsModeBits2 '("os_none")) => 0
(GetOsModeBits  '("os_all")) => 16383
(GetOsModeBits2 '("os_all")) => 16383
(GetOsModeBits  '("os_int" "os_cen" "os_mid" "os_end")) => 39
(GetOsModeBits2 '("os_int" "os_cen" "os_mid" "os_end")) => 39
(GetOsModeBits  '("os_int" "os_nod" "os_cen" "os_app" "os_mid" "os_end")) => 2095
(GetOsModeBits2 '("os_int" "os_nod" "os_cen" "os_app" "os_mid" "os_end")) => 2095

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8903
  • AKA Daniel
Re: OSMODE . . with no magic numbers
« Reply #8 on: December 14, 2022, 03:27:21 AM »
cool!

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2162
  • class keyThumper<T>:ILazy<T>
Re: OSMODE . . with no magic numbers
« Reply #9 on: December 14, 2022, 05:28:54 PM »
@Marc'Antonio Alessi
@Nigel Tufnel

nice solution.

For me, I prefer the option of having the values protected, directly accessible and also be available for intellisense . .

Sometimes it's easy to lose sight of the purpose of code when we chase the 'smart' solution   :|

just noticed, when adding comments to code it is a pain in the arse ensuring they remain valid.
    ( ie immediately the code is changed the comment [ ;;-> 39 ] is no longer applicable )

« Last Edit: December 14, 2022, 05:42:41 PM by kdub »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8903
  • AKA Daniel
Re: OSMODE . . with no magic numbers
« Reply #10 on: December 14, 2022, 06:04:05 PM »
 Yeah, it’s probably best to represent each as an integer

BIGAL

  • Swamp Rat
  • Posts: 1459
  • 40 + years of using Autocad
Re: OSMODE . . with no magic numbers
« Reply #11 on: December 14, 2022, 09:56:55 PM »
Seems a lot of work to me in a lisp just set correct value.

Ok now are you aware you can do transparent set osnaps in a lot of commands ?

eg Line pickpoint '47 pickpoint .......  change in osnaps

For me I have a defun c:47 which is osmode set to 47, 99 is the big one with lots of snaps 1 is end and so on pretty simple to make a few defuns and auto load.
A man who never made a mistake never made anything

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8903
  • AKA Daniel
Re: OSMODE . . with no magic numbers
« Reply #12 on: December 15, 2022, 02:15:45 AM »
Correct code seems to get verbose, things like c:47 are fine in your own personal scripts, but probably not in something you’d write for others to consume.

What might be an interesting topic is how to guarantee the users osmode value will reset, i.e
I hate when my settings are nuked

Code - C: [Select]
  1. class AutoOsMode
  2. {
  3. public:
  4.     AutoOsMode(int mode = 0)
  5.     {
  6.         acedGetVar(_osmode, &old);
  7.         set(mode);
  8.     }
  9.     ~AutoOsMode()
  10.     {
  11.         acedSetVar(_osmode, &old);
  12.     }
  13.     bool set(int mode = 0)
  14.     {
  15.         resbuf buf;
  16.         buf.restype = old.restype;
  17.         buf.resval.rint = mode;
  18.         return acedSetVar(_osmode, &buf) == RTNORM;
  19.     }
  20. private:
  21.     static constexpr auto _osmode{ L"OSMODE" };
  22.     resbuf old;
  23. };
  24.  

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2162
  • class keyThumper<T>:ILazy<T>
Re: OSMODE . . with no magic numbers
« Reply #13 on: December 15, 2022, 04:19:26 AM »
Daniel,

This is how I've been doing it ( in several version iterations ) for more than 30 years.

( from https://www.theswamp.org/index.php?topic=33105.0   and several other places.)

The code methodology for initialisation and restoration is pretty simple so I won't explain it.

Code - Auto/Visual Lisp: [Select]
  1.  
  2. (or kglobal:acadapp (setq kglobal:acadapp (vlax-get-acad-object)))
  3. (or kglobal:activedoc
  4.     (setq kglobal:activedoc (vla-get-activedocument kglobal:acadapp))
  5. )
  6. ;;;------------------------------------------------------------------
  7. ;;;------------------------------------------------------------------
  8. ;;;
  9.  
  10. (defun c:fse () (c:kdub_FlatshotEnts))
  11. ;;;------------------------------------------------------------------
  12. ;;;------------------------------------------------------------------
  13. ;;;
  14. (defun c:kdub_FlatshotEnts (/          *error*
  15.                             ;;
  16.                             ss_Solids  ss1        ent_List   HideObjList
  17.                             wp         marker     flatblock
  18.                            )
  19.   ;;-----------------------------------------------------------
  20.   ;|
  21.         *
  22.         * CodeHimBelonga kwbrown 2010.04.21
  23.         * c:kdub_FlatshotEnts
  24.         * Routine to CREATE 2D representation of all SELECTED 3D SOLID objects
  25.         * in the current view ... or blocks containing solids.
  26.         *
  27. |;;;-----------------------------------------------------------
  28.   (defun *error* (msg) (kdub:on-error msg) (princ))
  29.   ;;-----------------------------------------------------------
  30.   (vla-endundomark kglobal:activedoc)        ;close open group
  31.   (vla-startundomark kglobal:activedoc)      ;start new group
  32.   ;;-----------------------------------------------------------
  33.   (kdub:savesysvar '(("CMDECHO" 0)
  34.                      ("OSMODE" 0)
  35.                      ("expert" 5)
  36.                      ("SNAPANG" 0.00)
  37.                      ("SNAPMODE" 0)
  38.                      ("ORTHOMODE" 1)
  39.                      ("PICKADD" 1)
  40.                      ("PICKBOX" 5)
  41.                      ("INSUNITS" 0)
  42.                      ;; ("BLIPMODE" 1)
  43.                      ;; ("CLAYER")
  44.                      ("SORTENTS" 1)
  45.                     )
  46.   )
  47.   ;;----------------------------------------------------------
  48.   ;; MAIN
  49.   ;;-----------------------------------------------------------
  50.   (Prompt "\nSelect solids to process: ")
  51.   (if (and (setq ss_Solids (SSGET "X" (list (cons 0 "3DSOLID,INSERT"))))
  52.            (setq ss1 (SSGET (list (cons 0 "3DSOLID,INSERT"))))
  53.            (setq ent_List (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1))))
  54.       )
  55.     (progn (foreach ent ent_List (ssdel ent ss_Solids))
  56.            (setq HideObjList (mapcar 'vlax-ename->vla-object
  57.                                      (mapcar 'cadr (ssnamex ss_Solids))
  58.                              )
  59.                  wp          (getvar "VIEWCTR")
  60.                  marker      (kdub:MarkLastEnt)
  61.            )
  62.            (foreach obj HideObjList (vla-Put-Visible obj :vlax-false))
  63.            (vl-cmdf "._FlatShot" wp "" "" "")
  64.            (foreach obj HideObjList (vla-Put-Visible obj :vlax-true))
  65.     )
  66.   )
  67.   (if (setq flatblock (kdub:ss-AfterMarkerEnt marker))
  68.     (vl-cmdf "._Move" flatblock "" wp pause)
  69.   )
  70.   (kdub:restoresysvar)
  71.   (princ)
  72. )
  73. ;;;------------------------------------------------------------------
  74. ;;;------------------------------------------------------------------
  75. ;;;
  76.  
  77.  
  78.  
  79. ;;;------------------------------------------------------------------
  80. ;;;------------------------------------------------------------------
  81. ;;
  82. ;; LIBRARY STUFF
  83. ;;
  84. ;;;------------------------------------------------------------------
  85. ;;;------------------------------------------------------------------
  86. (defun kdub:on-error (msg / tmp)
  87.   ;;----- Cancel any Active Commands -----------------------------
  88.   (while (< 0 (getvar "cmdactive")) (command))
  89.   (setvar "menuecho" 1)
  90.   (vla-endundomark kglobal:activedoc)
  91.   ;;----- Display error message if applicable _-------------------
  92.   (cond
  93.     ((not msg))                              ; no error, do nothing.
  94.     ((member (strcase msg t)                 ; User cancelled.
  95.              '("console break" "function cancelled" "quit / exit abort")
  96.      )
  97.     )
  98.     ((princ (strcat "\nApplication Error: " (itoa (getvar "errno")) " :- " msg))
  99.      ;;----- Display backtrace if in debug mode ---------------------
  100.      (if kglobal:debug_on
  101.        (vl-bt)
  102.      )
  103.     )
  104.   )
  105.   (setvar "errno" 0)
  106.   ;;----- Reset System Variables from global list ----------------
  107.   (kdub:restoresysvar)
  108.   (princ)
  109. )
  110. ;;;------------------------------------------------------------------
  111. ;;;------------------------------------------------------------------
  112. ;;; change sysvar value and save its previous value
  113. (defun kdub:savesysvar (vars_list)
  114.   (foreach item vars_list
  115.     (setq kglobal:sysvarlist (cons (list (car item) (getvar (car item)))
  116.                                    kglobal:sysvarlist
  117.                              )
  118.     )
  119.     (if (cadr item)
  120.       (setvar (car item) (eval (cadr item)))
  121.     )
  122.   )
  123. )
  124. ;;;------------------------------------------------------------------
  125. ;;;------------------------------------------------------------------
  126. ;;;
  127. (defun kdub:restoresysvar ()
  128.   (foreach item kglobal:sysvarlist (setvar (car item) (cadr item)))
  129.   (setq kglobal:sysvarlist nil)
  130.   (princ)
  131. )
  132. ;;;------------------------------------------------------------------
  133. ;;;------------------------------------------------------------------
  134. ;;;
  135. (defun kdub:MarkLastEnt (/ ename returnval)
  136.   (and (setq returnval (entlast))
  137.        (while (setq ename (entnext returnval)) (setq returnval ename))
  138.   )
  139.   returnval
  140. )
  141. ;;;------------------------------------------------------------------
  142. ;;;------------------------------------------------------------------
  143. ;;;
  144. (defun kdub:ss-AfterMarkerEnt (ename / enext ss)
  145.   (cond ((not ename) (ssget "_X"))
  146.         ((setq enext (entnext ename))
  147.          (setq ss (ssadd enext))
  148.          (while (setq enext (entnext enext))
  149.            (if (entget enext)
  150.              (ssadd enext ss)
  151.            )
  152.          )
  153.          ss
  154.         )
  155.   )
  156. )
  157. ;;;------------------------------------------------------------------
  158. ;;;------------------------------------------------------------------
  159. ;;;
  160.  
  161.  
  162. ;|«Visual LISP© Format Options»
  163. (80 2 45 2 nil "end of " 80 70 0 0 0 nil nil nil T)
  164. ;*** DO NOT add text below the comment! ***|;
  165.  

Regards,


added:
One thing to note : the (kdub:restoresysvar) will be called EITHER as the main function terminates OR from the error handler.
« Last Edit: December 15, 2022, 04:28:17 AM by kdub »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8903
  • AKA Daniel
Re: OSMODE . . with no magic numbers
« Reply #14 on: December 15, 2022, 07:17:54 AM »
Very nice code!