Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Persistent Variables

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Active Member
    Join Date
    2009-03
    Posts
    63
    Login to Give a bone
    0

    Default Persistent Variables

    So I have an idea I want to kick around, more as a brainstorming of something that I might maybe use someday instead of a problem I'm having right now.

    I haven't slapped anything together yet, more looking into options. I've looked into dictionaries, xrecords, and UserIx, UserRx, and UserSx. Unless I'm misunderstanding something somewhere these are all stored and persistent within an individual DWG (stop me if I'm wrong here). All very useful, but need to be individually defined for each drawing. What I'm looking to do instead is set up some variables that persist across multiple dwgs and sessions, unique to individual users.

    So I have an idea, but it seems cumbersome unless there aren't better options I haven't found. So my thought is to write some functions (save-user-var and call-user-var). The "save-user-var" function would need two arguments passed to it, "var-name" and "var-val", it would then open an ascii file named <var-name>.txt (where <var-name> is the actual persistent variable name) in a certain specially set aside folder for these ascii files. This would serve both to create new files for new variables, and overwrite any previously existing ones without endangering any global variables used by Autocad. The "call-user-var" function would only need the "var-name" argument, search for the file, if no <var-name>.txt file is found then it returns nil, if one is found it opens that folder and returns the read-line from it. It seems like it could bloat that particular folder if overused (though on the flip side its going to be rare to require a variable that needs to exist longer than a single execution of a function much less across multiple sessions). Of course, too, it would hardly matter if that folder did have hundreds of small ascii files, the entire folder would still be smaller then most of my individual dwgs.

    So that's it. Anyone have anything to chime in on? Like I said, this is more to kick around the possibility and not to figure it out for any specific use right now. Off the top of my head I can think of some uses for it to store our seemingly bi-weekly changing client requirements, or say allow for code that can auto-fill certain portions of a title block without having to individualize for each user, only need to do a one-time setup for each user, then it can be accessed by generic code at need.

  2. #2
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL USA
    Posts
    3,658
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Variables can be stored and retrieved across multiple open drawings using the blackboard namespace.
    http://help.autodesk.com/view/ACD/20...E-71D63D2D0A33

  3. #3
    Active Member
    Join Date
    2009-03
    Posts
    63
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Oooo, that's a new one for me. I can already think of some ways to put it to use. However, it doesn't persist beyond the session. So now I have variables that can persist beyond a single session, but are limited to a single drawing each, or variables that can be accessed across multiple open drawings but don't persist beyond the current session. The more I think about it, the more I think what I've got outlined is the only way to go, unless something from the developer has already been implimented. Since I'm looking to have a variable that can do both, it has to have a location its is saved to on disk, not just RAM. I knocked something together last night to see if my idea worked. Seems to so far, as long as the file structure exists.
    Code:
    
    (defun save-user-var ( var-name var-val / var-file )
     (setq var-file (open (STRCAT "C:\\LISP\\PER-VAR\\" var-name ".txt") "w"))
     (write-line var-val var-file)
     (close var-file)
    );defun
    
    (defun call-user-var ( var-name / var-file var-val )
     (if (findfile (strcat "C:\\LISP\\PER-VAR\\" var-name ".txt"))
      (progn
       (setq var-file (open (STRCAT "C:\\LISP\\PER-VAR\\" var-name ".txt") "r"))
       (setq var-val (read-line var-file))
       (close var-file)
      );progn
     );if
     var-val
    );defun
    
    Edit, never mind, needs something to differentiate between variable types. Saves strings great, but I need Integers, Reals, and Lists also
    Last edited by ccalder; 2014-07-22 at 02:38 PM.

  4. #4
    100 Club
    Join Date
    2007-08
    Location
    Rockford, Illinois
    Posts
    161
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Well you can represent those types with string data you just need to specify the type during re-importing the data and apply the appropriate assignment based on the type condition when parsing . How about saving the variable-name/type/value in a (modified) .ini style format with the inclusion of a delimiter between the type and the value like this:

    AVarName01=Integer|6
    AVarName02=List|(0 . LINE)

    I would probably save the file to the user folder.

  5. #5
    Active Member
    Join Date
    2009-03
    Posts
    63
    Login to Give a bone
    0

    Default Re: Persistent Variables

    I was going to try for something exactly like you showed there with the delimiter later when I had a minute, use a conditional with the Type function to get the symbol for the variable type and use vl-princ-to-string to convert the symbol and values to string with a delimiter for saving in the file. I was originally going to go for a single file like you suggest, but I started thinking about the process for changing variables, you would basically have to iterate the file line by line twice, once to find the var name and once more to update and re-write the whole thing line by line. That's when I figured having individual files would save on process and coding. Although, unless it gets really out of control, I'm not looking at a crazy number of lines max, how long could that really take to iterate? especially since its only called once per function, then the value is stored in a local variable for the function to use. Hmmm, could work, and would save on confusing multiple files and special folders. Also, I could regiment it somewhat, force the variable names to something like "UsrVar00" - "UsrVar99" and force them to lines 1-100 of the file. the sub could parse out the line position from the variable name and get right to it, saves process from if-checking every iteration, reject any incorrect variable name. Though maybe not, its hard to keep track of generically named variables especially since these are intended for long haul multiple use scenarios. Still even with if-checking each name, I don't foresee more than a dozen or so, shouldn't be that bad. I'll give that a whirl here in a bit and post up new code.

  6. #6
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL USA
    Posts
    3,658
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Check out: http://www.jtbworld.com/lisp/PersonalMtextSymbols.htm
    It stores string values in the registry that are available afterwards from the Symbols list in Mtext.

    If you explain what these values are for and why you need them stored permanently it might be easier to suggest a solution.

  7. #7
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Quote Originally Posted by ccalder View Post
    I haven't slapped anything together yet, more looking into options. I've looked into dictionaries, xrecords, and UserIx, UserRx, and UserSx. Unless I'm misunderstanding something somewhere these are all stored and persistent within an individual DWG (stop me if I'm wrong here). All very useful, but need to be individually defined for each drawing. What I'm looking to do instead is set up some variables that persist across multiple dwgs and sessions, unique to individual users.
    You've just used logic to justify when an app is 'mature enough' for Registry stored settings; just be mindful to store within active profile if profile-specific, or outside of same if intended to apply to multiple applications.

    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  8. #8
    Active Member
    Join Date
    2009-03
    Posts
    63
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Haha, I don't know if its the years of being told "don't touch that... ever" when it comes to registry settings, but I feel a little out of my league there. I'm still just a small time guy with big time ideas. Still, banged this together and seems to be working.

    Code:
    (vl-load-com)
    
    (defun save-user-var ( var-name var-val / var-file tmp-in re-write rw-chk)
     (if (not (findfile (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt")))
      (progn (setq var-file (open (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt") "w")) (close var-file)))
     (setq var-file (open (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt") "r") tmp-in T re-write "")
     (while (not (= tmp-in nil))
      (setq tmp-in (read-line var-file))
      (cond
       ((and (not (= tmp-in nil)) (= var-name (substr tmp-in 1 (vl-string-search "=" tmp-in))))
        (if (= re-write "")
         (setq re-write (strcat var-name "=" (vl-princ-to-string (type var-val)) "|" (vl-princ-to-string var-val)))
         (setq re-write (strcat re-write "\n" var-name "=" (vl-princ-to-string (type var-val)) "|" (vl-princ-to-string var-val))))
        (setq rw-chk T))
       ((not (= tmp-in nil))
        (if (= re-write "")
         (setq re-write tmp-in)
         (setq re-write (strcat re-write "\n" tmp-in))))
       ((= tmp-in nil) (princ))
      );cond
     );while
     (close var-file)
     (if (= rw-chk T)
      (progn
       (setq var-file (open (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt") "w"))
       (write-line re-write var-file)
       (close var-file)
      );progn
      (progn
       (setq var-file (open (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt") "a"))
       (write-line (strcat var-name "=" (vl-princ-to-string (type var-val)) "|" (vl-princ-to-string var-val)) var-file)
       (close var-file)
      );progn
     );if
    );defun
    
    (defun call-user-var ( var-name / var-file var-val var-type tmp-in )
    (if (findfile (strcat "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt"))
     (progn
      (setq var-file (open (STRCAT "C:\\Users\\" (GETENV "username") "\\Documents\\per-var.txt") "r") tmp-in T)
      (while (not (= tmp-in nil))  
       (setq tmp-in (read-line var-file))
       (if (and (not (= tmp-in nil)) (= var-name (substr tmp-in 1 (vl-string-search "=" tmp-in))))
        (setq var-val tmp-in)
       );if
      );while
      (close var-file)
      (if var-val
       (progn
        (setq var-val (vl-string-subst "" (strcat var-name "=") var-val)
              var-type (substr var-val 1 (vl-string-search "|" var-val))
              var-val (vl-string-subst "" (strcat var-type "|") var-val))
        (cond
         ((= var-type "INT") (setq var-val (atoi var-val)))
         ((= var-type "REAL") (setq var-val (atof var-val)))
         ((= var-type "LIST") (setq var-val (read var-val)))
         ((= var-type "STR") (princ))
        );cond
       );progn
      );if
     );progn
    );if
    var-val
    );defun
    Thanks all for the feedback, I may look into storing within the registry if I end up actually using this for anything. Like I said at the top, this was more a proof-of-concept exorcize for myself, just wanted some thoughts from some folks with more experience than I. To be honest I thought this was gonna get flamed down super quick with a bunch of "you don't, why would you need to?" so the constructive feedback was much appreciated.

  9. #9
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Can you post a sample "per-var.txt" file?
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  10. #10
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Persistent Variables

    Also, in order avoid this resulting from your Save-User-Var sub-function:

    Code:
    _$ (save-user-var "foo" "bar")
    ; error: bad argument type: streamp nil
    _$

    ... Instead of this:

    Code:
    ;; ...
    
      (if
        ;; file doesn't exist
        (not (findfile (STRCAT "C:\\Users\\"
                               (GETENV "username")
                               "\\Documents\\per-var.txt"
                       )
             )
        )
    
         ;; then,
         (progn
    
           ;; open the file for "write"
           (setq var-file (open (STRCAT "C:\\Users\\"
                                        (GETENV "username")
                                        "\\Documents\\per-var.txt"
                                )
                                "w"
                          )
           )
    
           ;; don't write anything to the file
    
           ;; close the file
           (close var-file)
         )
      )
    
      ;; open the file for "read"
      (setq var-file (open (STRCAT "C:\\Users\\"
                                   (GETENV "username")
                                   "\\Documents\\per-var.txt"
                           )
                           "r"
                     )
                     ;; ...
      )
    
    ;; ...

    ... Consider something like:

    Code:
    ;; ...
    
      (setq var-file
             (open
               (setq path (strcat (getenv "userprofile")
                                  "\\Documents\\per-var.txt"
                          )
               )
               (if (findfile path)
                 "r"
                 "w"
               )
             )
      )
      (setq tmp-in T)
      (setq re-write "")
    
    ;; ...
    Last edited by BlackBox; 2014-07-22 at 08:04 PM.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

Page 1 of 2 12 LastLast

Similar Threads

  1. Textures need to be persistent.
    By Wish List System in forum Inventor Wish List
    Replies: 0
    Last Post: 2014-11-16, 09:27 PM
  2. Reactors - Persistent, LData, XData...
    By stusic in forum AutoLISP
    Replies: 5
    Last Post: 2013-05-22, 01:42 PM
  3. Adding persistent custom scales
    By some buddy in forum Revit - Platform
    Replies: 2
    Last Post: 2010-06-28, 03:36 PM
  4. Adding persistent custom scales
    By some buddy in forum Revit - API
    Replies: 2
    Last Post: 2010-06-28, 03:25 PM
  5. AutoCAD-style persistent properties dialog
    By Scott D Davis in forum Revit Architecture - Wish List
    Replies: 0
    Last Post: 2004-10-20, 06:24 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •