TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Peter2 on November 20, 2016, 04:02:49 PM

Title: Best way to keep variables during a session?
Post by: Peter2 on November 20, 2016, 04:02:49 PM
With a colleague I talked about the storing of variables / values during a drawing-session. There are a lot of different ways - simple and less simple ones; inside and outside AutoCAD; some can be used also in other drawing sessions; maybe "good and bad ones" ....

This is why I started this poll and I'm sure it will be interesting for many users:

What's your way? Why this way, and why not another way?

Have a good start into the new week!

Peter
Title: Re: Best way to keep variables during a session?
Post by: kdub_nz on November 20, 2016, 05:14:22 PM
In before Michael ;

It depends ...

Form follows function, so the method changes according to the requirements.
Title: Re: Best way to keep variables during a session?
Post by: MP on November 20, 2016, 05:20:00 PM
lol get out of my head :-D
Title: Re: Best way to keep variables during a session?
Post by: Marc'Antonio Alessi on November 21, 2016, 02:44:10 AM
For a constant use I write values in a lsp file that is loaded into each opened file (many years ago I used setcfg):
Code: [Select]
(setq #CFGDATA '(
("SetUp"
  ("FrmHgt" . 420)
  ("FrmWdt" . 594)
  ("SclDen" . 500)
  ("SclNum" . 1)
  ("UsrBit" . 2)
  ("DwgScl" . 25)
  ("FrmTyp" . "A2")
  ("PrnTyp" . "ISO")
)
("2DPrm"
  ("#AtrQTot" . "$TOTQTY")
  ("#AtrOrdP" . "$PRODORDER")
  ("#AtrMatr" . "$MATERIAL")
  ("#AtrSpes" . "$THICKNESS")
  ("#AtrFint" . "$FINISHING")
  ("#AtrPeso" . "$WEIGHT")
  ("#AtrSvil" . "$DEVELOPMENT")
)
("AssoCustom"
  ("Data_sep" . ".")
  ("ScrEnd" . 0)
  ("UtlMslLst" . "((\"SaveAsType\" . 60))")
  ("FilType" . "Dwg")
  ("ScrMode" . 128)
  ("BitTemp" . 12)
  ("ExpType" . 128)
  ("Smb_name" . "SMB_TRI0")
  ("Smb_txt2" . "B")
  ("Smb_txt1" . "A")
  ("Pdf995Crt" . "C:\\Programmi\\pdf995\\")
  ("AssoExp" . "C:\\ASSO\\_Custom\\xTemp\\")
  ("Smb_car1" . "C:\\Asso_Norm\\")
)
("Asso"
  ("Trial" . 10)
  ("AutoStart" . 4117)
  ("#dwgnm" . "(strcat (getvar \"DWGPREFIX\")(vl-filename-base (getvar \"DWGNAME\")))")
  ("Miscmode" . 2)
  ("AssoLoad" . 1)
)
))
Code: [Select]
; Function: ALE_UtlCfg_GetVal
;
; Version 1.00 - 21/06/2006
;
; Return value of ItmNam in SctNam of DatLst
; if value is nil return DefVal
;
; Example:
; (ALE_UtlCfg_GetVal #CfgData "Section" "Item" "DefaultValue")
;
(defun ALE_UtlCfg_GetVal (DatLst SctNam ItmNam DefVal)
  (cond
    ( (cdr (assoc ItmNam (cdr (assoc SctNam DatLst)))) )
    ( DefVal )
  )
)
For temporary use between different dwg: vl-bb-ref vl-bb-set.
Title: Re: Best way to keep variables during a session?
Post by: irneb on November 21, 2016, 04:53:01 AM
Agreed ... each has its uses. I actually had an issue while voting, since only 5 checks are allowed. I've basically used all of those, including "other". Where other may have been an external file, or a database, usually due to something external to ACad also requiring access to the data.


Globals & black-board are nice to use for things like settings. Since you can have them shared across dwg environments or or only relevant per dwg, sometimes you want one of those or both - reasonably simple to achieve both scenarios. IMO they're pretty much interchangeable and depends how you like to do things.


For keeping data / settings permanent there's also various ways allowing different use cases. Perhaps you want to store some relevant data only pertinent to a specific DWG, in which case a Dwg-Props or Overall Dictionary is adequate. If only to be part of a specific object in that DWG, the both XData and Object-attached-Dictionary is the way. Usually Dictionaries are easier to use if you work with vla functions, otherwise they become a bit cumbersome when working through DXF codes (too many nesting levels).
Title: Re: Best way to keep variables during a session?
Post by: squirreldip on November 22, 2016, 11:34:54 AM
Great suggestions and I've used most of those mentioned.  One of my fav's is using a registry entry:

(vl-registry-read) and (vl-registry-write)

I use these in my road alignment routines so that when reading alignments it always returns to the last folder read from.
Title: Re: Best way to keep variables during a session?
Post by: roy_043 on November 22, 2016, 01:49:27 PM
@irneb:
In BricsCAD, behind the scenes, the blackboard is string-based solution. I don't know if this also applies to AutoCAD. May be worth checking (accuracy of stored reals).
If you want to store enames in dictionaries vanilla functions work better.
Title: Re: Best way to keep variables during a session?
Post by: Marc'Antonio Alessi on November 23, 2016, 06:11:26 AM
@irneb:
In BricsCAD, behind the scenes, the blackboard is string-based solution. ...
I do not understand what you mean by "the blackboard is string-based solution":
Code: [Select]
Bricscad
: (vl-bb-set '##test '((1 . 100.12345678910123456) (2 . "200")))
((1 . 100.123456789101) (2 . "200"))
: (vl-bb-ref '##test)
((1 . 100.123456789101) (2 . "200"))
Code: [Select]
AutoCAD
Comando: (vl-bb-set '##test '((1 . 100.12345678910123456) (2 . "200")))
((1 . 100.123) (2 . "200"))
Comando: (vl-bb-ref '##test)
((1 . 100.123) (2 . "200"))
Title: Re: Best way to keep variables during a session?
Post by: roy_043 on November 23, 2016, 07:54:13 AM
@Marc'Antonio Alessi:
I should have explained better.
I am not saying that the vl-bb-* functions do not work for reals. But the BricsCAD BB algorithm 'internally' translates reals to strings and back. And this is not just an assumption, Torsten Moses has confirmed this in response to a V12 Support Request (SR33961).

Quote from: BricsCAD V12 Release Notes
SR33961 - LISP: precision of double values on Lisp "BlackBoard" was limited to 6, now it is 12 digits.

Test:
Code: [Select]
(setq myReal 0.01234567890123456789)
(vl-bb-set 'myRealBb myReal)
(= myReal (vl-bb-ref 'myRealBb)) => nil
Title: Re: Best way to keep variables during a session?
Post by: irneb on November 23, 2016, 08:31:51 AM
Seems AutoCAD's using true data types fro blackboard:

Code: [Select]
Command: (setq myReal 0.01234567890123456789)
0.0123457
Command: (vl-bb-set 'myRealBb myReal)
0.0123457
Command: (= myReal (vl-bb-ref 'myRealBb))
T


Edit: Does vl-propagate at least work as expected in BC?
Title: Re: Best way to keep variables during a session?
Post by: Marc'Antonio Alessi on November 23, 2016, 10:01:25 AM
@Marc'Antonio Alessi:
I should have explained better.
I am not saying that the vl-bb-* functions do not work for reals. But the BricsCAD BB algorithm 'internally' translates reals to strings and back. And this is not just an assumption, Torsten Moses has confirmed this in response to a V12 Support Request (SR33961).

Quote from: BricsCAD V12 Release Notes
SR33961 - LISP: precision of double values on Lisp "BlackBoard" was limited to 6, now it is 12 digits.

Test:
Code: [Select]
(setq myReal 0.01234567890123456789)
(vl-bb-set 'myRealBb myReal)
(= myReal (vl-bb-ref 'myRealBb)) => nil
Ok thanks, 12 digits maybe is enough?
Title: Re: Best way to keep variables during a session?
Post by: roy_043 on November 23, 2016, 12:35:13 PM
@Marc'Antonio Alessi:
'Maybe' is a good word to use. My point is that in BricsCAD global variables and BB variables cannot be used interchangeably when reals are involved and a very high level of accuracy is required.

@irneb:
Good thinking. In BricsCAD the vl-propagate function has the same issue:

Drawing1:
Code: [Select]
(setq myReal 0.01234567890123456789)
(vl-propagate 'myReal)
(equal myReal 0.01234567890123456789 0) => T

New Drawing2:
Code: [Select]
(equal myReal 0.01234567890123456789 0.00000000000000001) => nil
(equal myReal 0.01234567890123456789 0.0000000000000001) => T
Title: Re: Best way to keep variables during a session?
Post by: irneb on November 24, 2016, 01:49:01 AM
In that case it's a bit of an issue I suppose. Strange that BC only allows text variables between DWGs, would have thought it's rather simple to use any sort of C base type like int/float/double/etc.


But even if forced into text: There are ways to send/receive floating point numbers through string variables without loosing any accuracy, things like base64 encoding jumps to mind, or just hex if you want it as fast as possible (multiplying / diving floating points by powers of 2 do not change their accuracy and each bit can thus be extracted if you don't have direct access to the bits in the number). Even inside of DotNet there's a "round-trip" format for writing floating point numbers to text so that parsing them returns the same number. It should even be possible to do this direct in AutoLisp, though probably a bit inefficient in comparison to direct bit-level access in C/C++/C#/etc.
Title: Re: Best way to keep variables during a session?
Post by: roy_043 on November 24, 2016, 04:42:31 AM
The fact that BricsCAD uses a sting-based format internally for the BB is not that strange. For example a list stored as Ldata (another way to store variables) is also turned into a string. But in that case reals are stored separately to preserve their accuracy. It is strange that BricsCAD does not also do this for the BB and vl-propagate.
Title: Re: Best way to keep variables during a session?
Post by: MP on November 24, 2016, 08:51:46 PM
If one needs to serialize reals with native precision dictionaries and xrecords work fine. Think "dic per app, xrecord per var". One can relatively easily save and restore ints, reals, strings and lists of the previous. The dwg can be an active drawing or one slotted solely for serialization. A drawing defined as the latter with nothing but a hierarchy of custom dictionaries and xrecords opens and is saved surprisingly quick via ODBX. Edit: fixed teh grammars. Cheers.
Title: Re: Best way to keep variables during a session?
Post by: Peter2 on December 06, 2016, 04:44:33 PM
At the end of the poll I want to thank all contributors for their voting and their postings. There are many interesting thinks to learn, and I hope the post is helpful for others too.

Have a fine time!